* [PR PATCH] ffmpeg6 split
@ 2023-05-05 13:20 zlice
2023-05-05 13:27 ` [PR PATCH] [Updated] " zlice
` (173 more replies)
0 siblings, 174 replies; 175+ messages in thread
From: zlice @ 2023-05-05 13:20 UTC (permalink / raw)
To: ml
[-- Attachment #1: Type: text/plain, Size: 2794 bytes --]
There is a new pull request by zlice against master on the void-packages repository
https://github.com/zlice/void-packages ffmpeg6-split
https://github.com/void-linux/void-packages/pull/43761
ffmpeg6 split
[ci skip]
#### Testing the changes
- I tested the changes in this PR: **YES**
main testing has been vaapi in Firefox Nightly and enc/dec in Shotcut on Intel A770
#### New package
- This new package conforms to the [package requirements](https://github.com/void-linux/void-packages/blob/master/CONTRIBUTING.md#package-requirements): **YES**
#### Local build testing
- I built this PR locally for my native architecture, **x86_64**
#### Discussion
Continuation of https://github.com/void-linux/void-packages/pull/36315
`libavresample` is deprecated, but marked as a dependency when trying to build other packages and install `ffmpeg`(5). I think the right way to handle this is make a meta package and the add to removals?
##### Commit naming / misc
Commits are 'dirty' right now, running with [gstreamer 1.22.1 updates](https://github.com/void-linux/void-packages/pull/42861) and [Intel OpenCL](https://github.com/void-linux/void-packages/pull/43084). This will also make [intel packages pr](https://github.com/void-linux/void-packages/pull/41132) obsolete.
Maintainer for previous ffmpeg(4) was orphaned, I can put my name in there if that matters, though I don't exactly see myself keeping up on ffmpeg.
This updates QT5 which looks like it is usually hosted by Johnny. Not sure if there's any reason to stay there or these sources are fine.
##### STILL FFMPEG4
These are a mix of emulators, games and/or older packages.
- attract (multiple patches in master)
- audacity (3.2.x should work but void is missing some libs? vst3sdk?)
- ccextractor (master patches? no release)
- vice
- kodi
- mlt
- synfig (mlt)
- tvheadend
- ssr
- spek-alternative
- ppsspp
- olive
- moc
- mediastreamer
- libextractor
- idjc
- hedgewars
- ffmpegthumbnailer
- ffmpegthumbs
- deadbeef
- omxplayer
- qtav (fork has ffmpeg 5 patch - https://github.com/cmguo/QtAV)
- `vlc` (vlc4 will support ffmpeg5, there's a patch to build 3.x with ffmpeg5 but it will lack vaapi)
- `osg` (OpenSceneGraph plus `xine-lib`)
- `ytmdl` ? not sure but it uses `python3-ffmpeg-python` which being 6-8yr old I imagine is ffmpeg4
##### HAVE NOT BUILT YET
- omxplayer (rpi only?)
- kodi (big, but ffmpeg4)
##### UPDATED (for ffmpeg5)
- unpaper: update to 7.0.0.
- guvcview: update to 2.0.8.
- qt5: update to 5.15.8
- qt5-webengine: update to 5.18.13
- shiboken2: revbump for qt5.15.8 (patch)
- python3-pyside2: update to 5.15.8 (patch)
A patch file from https://github.com/void-linux/void-packages/pull/43761.patch is attached
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: github-pr-ffmpeg6-split-43761.patch --]
[-- Type: text/x-diff, Size: 822512 bytes --]
From 6d537689f78de1b6595fed56dcb67c7a180b5fbf Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 19:55:46 -0400
Subject: [PATCH 001/140] ffmpeg: update to 6.0.
---
common/shlibs | 26 +++++---
srcpkgs/ffmpeg/files/altivec.patch | 60 -------------------
.../patches/armv5tel-floating-point.patch | 18 ------
.../workaround-mesa-readeon-vaapi-bug.patch | 28 ---------
srcpkgs/ffmpeg/template | 31 +++++-----
5 files changed, 33 insertions(+), 130 deletions(-)
delete mode 100644 srcpkgs/ffmpeg/files/altivec.patch
delete mode 100644 srcpkgs/ffmpeg/patches/armv5tel-floating-point.patch
delete mode 100644 srcpkgs/ffmpeg/patches/workaround-mesa-readeon-vaapi-bug.patch
diff --git a/common/shlibs b/common/shlibs
index 8c47e79b8c43..d650f2a3045d 100644
--- a/common/shlibs
+++ b/common/shlibs
@@ -390,15 +390,23 @@ libid3tag.so.0 libid3tag-0.15.1b_1
libgif.so.7 giflib-5.1.0_1
libImlib2.so.1 imlib2-1.4.2_1
libmp3lame.so.0 lame-3.98.2_1
-libavdevice.so.58 libavdevice-4.0_1
-libavformat.so.58 libavformat-4.0_1
-libswscale.so.5 libswscale-4.0_1
-libswresample.so.3 libswresample-4.0_1
-libavresample.so.4 libavresample-4.0_1
-libpostproc.so.55 libpostproc-4.0_1
-libavcodec.so.58 libavcodec-4.0_1
-libavutil.so.56 libavutil-4.0_1
-libavfilter.so.7 libavfilter-4.0_1
+libavdevice.so.60 libavdevice-6.0_1
+libavformat.so.60 libavformat-6.0_1
+libswscale.so.7 libswscale-6.0_1
+libswresample.so.4 libswresample-6.0_1
+libpostproc.so.57 libpostproc-6.0_1
+libavcodec.so.60 libavcodec-6.0_1
+libavutil.so.58 libavutil-6.0_1
+libavfilter.so.9 libavfilter-6.0_1
+libavdevice.so.58 libavdevice4-4.0_1
+libavformat.so.58 libavformat4-4.0_1
+libswscale.so.5 libswscale4-4.0_1
+libswresample.so.3 libswresample4-4.0_1
+libavresample.so.4 libavresample4-4.0_1
+libpostproc.so.55 libpostproc4-4.0_1
+libavcodec.so.58 libavcodec4-4.0_1
+libavutil.so.56 libavutil4-4.0_1
+libavfilter.so.7 libavfilter4-4.0_1
libSDL-1.2.so.0 SDL-1.2.14_1
libSDL_image-1.2.so.0 SDL_image-1.2.10_1
libx264.so.157 x264-20190507.2245_1
diff --git a/srcpkgs/ffmpeg/files/altivec.patch b/srcpkgs/ffmpeg/files/altivec.patch
deleted file mode 100644
index 9c5720046332..000000000000
--- a/srcpkgs/ffmpeg/files/altivec.patch
+++ /dev/null
@@ -1,60 +0,0 @@
-revert some altivec specific change on all ppc* except ppc64le*
-
-q66: "We should also throw in a revert of FFmpeg/FFmpeg@3a557c5 but only
-conditionally, for ppc* but not ppc64le* (the new code is valid for
-POWER8 VSX which LE targets as a baseline but not BE)"
-
-
-This reverts commit 3a557c5d88b7b15b5954ba2743febb055549b536.
----
- libswscale/ppc/yuv2rgb_altivec.c | 24 ++++++++++++++++++++----
- 1 file changed, 20 insertions(+), 4 deletions(-)
-
-diff --git a/libswscale/ppc/yuv2rgb_altivec.c b/libswscale/ppc/yuv2rgb_altivec.c
-index 536545293d..c1e2852adb 100644
---- a/libswscale/ppc/yuv2rgb_altivec.c
-+++ b/libswscale/ppc/yuv2rgb_altivec.c
-@@ -305,6 +305,9 @@ static int altivec_ ## name(SwsContext *c, const unsigned char **in, \
- vector signed short R1, G1, B1; \
- vector unsigned char R, G, B; \
- \
-+ const vector unsigned char *y1ivP, *y2ivP, *uivP, *vivP; \
-+ vector unsigned char align_perm; \
-+ \
- vector signed short lCY = c->CY; \
- vector signed short lOY = c->OY; \
- vector signed short lCRV = c->CRV; \
-@@ -335,13 +338,26 @@ static int altivec_ ## name(SwsContext *c, const unsigned char **in, \
- vec_dstst(oute, (0x02000002 | (((w * 3 + 32) / 32) << 16)), 1); \
- \
- for (j = 0; j < w / 16; j++) { \
-- y0 = vec_xl(0, y1i); \
-+ y1ivP = (const vector unsigned char *) y1i; \
-+ y2ivP = (const vector unsigned char *) y2i; \
-+ uivP = (const vector unsigned char *) ui; \
-+ vivP = (const vector unsigned char *) vi; \
-+ \
-+ align_perm = vec_lvsl(0, y1i); \
-+ y0 = (vector unsigned char) \
-+ vec_perm(y1ivP[0], y1ivP[1], align_perm); \
- \
-- y1 = vec_xl(0, y2i); \
-+ align_perm = vec_lvsl(0, y2i); \
-+ y1 = (vector unsigned char) \
-+ vec_perm(y2ivP[0], y2ivP[1], align_perm); \
- \
-- u = (vector signed char) vec_xl(0, ui); \
-+ align_perm = vec_lvsl(0, ui); \
-+ u = (vector signed char) \
-+ vec_perm(uivP[0], uivP[1], align_perm); \
- \
-- v = (vector signed char) vec_xl(0, vi); \
-+ align_perm = vec_lvsl(0, vi); \
-+ v = (vector signed char) \
-+ vec_perm(vivP[0], vivP[1], align_perm); \
- \
- u = (vector signed char) \
- vec_sub(u, \
---
-2.27.0
-
diff --git a/srcpkgs/ffmpeg/patches/armv5tel-floating-point.patch b/srcpkgs/ffmpeg/patches/armv5tel-floating-point.patch
deleted file mode 100644
index 9a55178c74f0..000000000000
--- a/srcpkgs/ffmpeg/patches/armv5tel-floating-point.patch
+++ /dev/null
@@ -1,18 +0,0 @@
---- a/libavfilter/vf_drawtext.c 2017-10-26 21:03:03.000000000 +0200
-+++ b/libavfilter/vf_drawtext.c 2017-11-21 11:06:49.602284422 +0100
-@@ -39,6 +39,15 @@
- #endif
- #include <fenv.h>
-
-+#if (FE_ALL_EXCEPT == 0)
-+/* E.g. ARM soft float does not define these */
-+#define FE_INVALID 0
-+#define FE_DIVBYZERO 0
-+#define FE_OVERFLOW 0
-+#define FE_UNDERFLOW 0
-+#define FE_INEXACT 0
-+#endif
-+
- #if CONFIG_LIBFONTCONFIG
- #include <fontconfig/fontconfig.h>
- #endif
diff --git a/srcpkgs/ffmpeg/patches/workaround-mesa-readeon-vaapi-bug.patch b/srcpkgs/ffmpeg/patches/workaround-mesa-readeon-vaapi-bug.patch
deleted file mode 100644
index 00e3f68a415b..000000000000
--- a/srcpkgs/ffmpeg/patches/workaround-mesa-readeon-vaapi-bug.patch
+++ /dev/null
@@ -1,28 +0,0 @@
-From 811d290844206fc73dc39c3e5b67d5d895baedf8 Mon Sep 17 00:00:00 2001
-From: Rainer Hochecker <fernetmenta@online.de>
-Date: Sat, 26 Jan 2019 19:48:35 +0100
-Subject: [PATCH] avcodec/vaapi_h264: skip decode if pic has no slices
-
-This fixes / workarounds https://bugs.freedesktop.org/show_bug.cgi?id=105368.
-It was hit frequently when watching h264 channels received via DVB-X.
-Corresponding kodi bug: https://github.com/xbmc/xbmc/issues/15704
----
- libavcodec/vaapi_h264.c | 5 +++++
- 1 file changed, 5 insertions(+)
-
-diff --git a/libavcodec/vaapi_h264.c b/libavcodec/vaapi_h264.c
-index 5854587a255..f12fdc457a4 100644
---- a/libavcodec/vaapi_h264.c
-+++ b/libavcodec/vaapi_h264.c
-@@ -317,6 +317,11 @@ static int vaapi_h264_end_frame(AVCodecContext *avctx)
- H264SliceContext *sl = &h->slice_ctx[0];
- int ret;
-
-+ if (pic->nb_slices == 0) {
-+ ret = AVERROR_INVALIDDATA;
-+ goto finish;
-+ }
-+
- ret = ff_vaapi_decode_issue(avctx, pic);
- if (ret < 0)
- goto finish;
diff --git a/srcpkgs/ffmpeg/template b/srcpkgs/ffmpeg/template
index 23a3d5c9967b..3d99e5173697 100644
--- a/srcpkgs/ffmpeg/template
+++ b/srcpkgs/ffmpeg/template
@@ -1,15 +1,15 @@
# Template file for 'ffmpeg'
# audacity also needs to be bumped when a new ffmpeg version bumps libavformat's soname!
pkgname=ffmpeg
-version=4.4.3
-revision=2
+version=6.0
+revision=1
short_desc="Decoding, encoding and streaming software"
maintainer="Orphaned <orphan@voidlinux.org>"
license="GPL-3.0-or-later"
homepage="https://www.ffmpeg.org"
changelog="https://raw.githubusercontent.com/FFmpeg/FFmpeg/master/Changelog"
distfiles="https://www.ffmpeg.org/releases/ffmpeg-${version}.tar.xz"
-checksum=6c5b6c195e61534766a0b5fe16acc919170c883362612816d0a1c7f4f947006e
+checksum=57be87c22d9b49c112b6d24bc67d42508660e6b718b3db89c44e47e289137082
hostmakedepends="pkg-config perl yasm"
makedepends="zlib-devel bzip2-devel freetype-devel alsa-lib-devel libXfixes-devel
@@ -26,12 +26,13 @@ makedepends="zlib-devel bzip2-devel freetype-devel alsa-lib-devel libXfixes-deve
$(vopt_if webp libwebp-devel) $(vopt_if sofa libmysofa-devel)
$(vopt_if drm libdrm-devel) $(vopt_if svtav1 libsvt-av1-devel)
$(vopt_if srt srt-devel) $(vopt_if rist librist-devel)
- $(vopt_if vulkan 'vulkan-loader Vulkan-Headers')
+ $(vopt_if vulkan 'vulkan-loader Vulkan-Headers Vulkan-Tools Vulkan-ValidationLayers')
+ $(vopt_if onevpl 'onevpl onevpl-devel')
$(vopt_if nvenc nv-codec-headers) $(vopt_if nvdec nv-codec-headers)"
depends="ffplay>=${version}_${revision}"
build_options="x265 v4l2 vaapi vdpau vpx fdk_aac aom nvenc sndio pulseaudio
- dav1d zimg webp sofa vulkan drm svtav1 srt rist nvdec"
+ dav1d zimg webp sofa vulkan drm svtav1 srt rist nvdec onevpl"
build_options_default="x265 v4l2 vpx aom sndio pulseaudio dav1d webp vulkan drm srt rist"
desc_option_srt="Enable support for SRT (Secure, Reliable, Transport)"
desc_option_rist="Enable support for RIST (Reliable Internet Stream Transport)"
@@ -39,7 +40,8 @@ desc_option_sofa="Enable support for AES SOFA"
desc_option_webp="Enable support for WebP"
case "$XBPS_TARGET_MACHINE" in
- i686*|x86_64*) build_options_default+=" vaapi vdpau nvenc nvdec";;
+ i686*) build_options_default+=" vaapi vdpau nvenc nvdec";;
+ x86_64*) build_options_default+=" vaapi vdpau nvenc nvdec onevpl";;
ppc64*) build_options_default+=" vaapi vdpau";;
mips*) CFLAGS="-mnan=legacy";;
esac
@@ -114,18 +116,19 @@ do_configure() {
$(vopt_enable x265 libx265) \
$(vopt_enable v4l2 libv4l2) \
$(vopt_enable aom libaom) $(vopt_enable vaapi) $(vopt_enable vdpau) \
- --enable-libbs2b --enable-avresample --enable-libvidstab \
+ --enable-libbs2b --enable-libvidstab \
$(vopt_enable dav1d libdav1d) \
$(vopt_enable zimg libzimg) \
$(vopt_enable webp libwebp) \
$(vopt_enable sofa libmysofa) \
$(vopt_enable vulkan) \
+ $(vopt_enable onevpl libvpl) \
$(vopt_enable drm libdrm) \
$(vopt_enable svtav1 libsvtav1) \
$(vopt_enable srt libsrt) \
$(vopt_enable rist librist) \
- $(vopt_if nvenc '--enable-nvenc') \
- $(vopt_if nvdec '--enable-nvdec')
+ $(vopt_enable nvenc nvenc) \
+ $(vopt_enable nvdec nvdec)
}
do_build() {
make ${makejobs}
@@ -148,10 +151,8 @@ libavdevice_package() {
}
}
libavresample_package() {
- short_desc="FFmpeg audio resampling library"
- pkg_install() {
- vmove "usr/lib/libavresample.so.*"
- }
+ short_desc="Package deprecated, removal needed"
+ build_style=meta
}
libavformat_package() {
short_desc="FFmpeg file format library"
@@ -198,9 +199,9 @@ ffmpeg-devel_package() {
libavfilter>=${version}_${revision}
libpostproc>=${version}_${revision}
libswscale>=${version}_${revision}
- libswresample>=${version}_${revision}
- libavresample>=${version}_${revision}"
+ libswresample>=${version}_${revision}"
short_desc+=" - development files"
+ conflicts="ffmpeg4-devel"
pkg_install() {
vmove usr/include
vmove usr/lib/pkgconfig
From 6f50791cd4cb463c5967e0c1431b987e1146b800 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 19:56:22 -0400
Subject: [PATCH 002/140] New package: ffmpeg4-4.4.3.
---
srcpkgs/ffmpeg4-devel | 1 +
srcpkgs/ffmpeg4/files/altivec.patch | 60 +++++
.../patches/armv5tel-floating-point.patch | 18 ++
.../workaround-mesa-readeon-vaapi-bug.patch | 28 +++
srcpkgs/ffmpeg4/template | 214 ++++++++++++++++++
srcpkgs/libavcodec4 | 1 +
srcpkgs/libavdevice4 | 1 +
srcpkgs/libavfilter4 | 1 +
srcpkgs/libavformat4 | 1 +
srcpkgs/libavresample4 | 1 +
srcpkgs/libavutil4 | 1 +
srcpkgs/libpostproc4 | 1 +
srcpkgs/libswresample4 | 1 +
srcpkgs/libswscale4 | 1 +
14 files changed, 330 insertions(+)
create mode 120000 srcpkgs/ffmpeg4-devel
create mode 100644 srcpkgs/ffmpeg4/files/altivec.patch
create mode 100644 srcpkgs/ffmpeg4/patches/armv5tel-floating-point.patch
create mode 100644 srcpkgs/ffmpeg4/patches/workaround-mesa-readeon-vaapi-bug.patch
create mode 100644 srcpkgs/ffmpeg4/template
create mode 120000 srcpkgs/libavcodec4
create mode 120000 srcpkgs/libavdevice4
create mode 120000 srcpkgs/libavfilter4
create mode 120000 srcpkgs/libavformat4
create mode 120000 srcpkgs/libavresample4
create mode 120000 srcpkgs/libavutil4
create mode 120000 srcpkgs/libpostproc4
create mode 120000 srcpkgs/libswresample4
create mode 120000 srcpkgs/libswscale4
diff --git a/srcpkgs/ffmpeg4-devel b/srcpkgs/ffmpeg4-devel
new file mode 120000
index 000000000000..887f354e7c6b
--- /dev/null
+++ b/srcpkgs/ffmpeg4-devel
@@ -0,0 +1 @@
+ffmpeg4
\ No newline at end of file
diff --git a/srcpkgs/ffmpeg4/files/altivec.patch b/srcpkgs/ffmpeg4/files/altivec.patch
new file mode 100644
index 000000000000..9c5720046332
--- /dev/null
+++ b/srcpkgs/ffmpeg4/files/altivec.patch
@@ -0,0 +1,60 @@
+revert some altivec specific change on all ppc* except ppc64le*
+
+q66: "We should also throw in a revert of FFmpeg/FFmpeg@3a557c5 but only
+conditionally, for ppc* but not ppc64le* (the new code is valid for
+POWER8 VSX which LE targets as a baseline but not BE)"
+
+
+This reverts commit 3a557c5d88b7b15b5954ba2743febb055549b536.
+---
+ libswscale/ppc/yuv2rgb_altivec.c | 24 ++++++++++++++++++++----
+ 1 file changed, 20 insertions(+), 4 deletions(-)
+
+diff --git a/libswscale/ppc/yuv2rgb_altivec.c b/libswscale/ppc/yuv2rgb_altivec.c
+index 536545293d..c1e2852adb 100644
+--- a/libswscale/ppc/yuv2rgb_altivec.c
++++ b/libswscale/ppc/yuv2rgb_altivec.c
+@@ -305,6 +305,9 @@ static int altivec_ ## name(SwsContext *c, const unsigned char **in, \
+ vector signed short R1, G1, B1; \
+ vector unsigned char R, G, B; \
+ \
++ const vector unsigned char *y1ivP, *y2ivP, *uivP, *vivP; \
++ vector unsigned char align_perm; \
++ \
+ vector signed short lCY = c->CY; \
+ vector signed short lOY = c->OY; \
+ vector signed short lCRV = c->CRV; \
+@@ -335,13 +338,26 @@ static int altivec_ ## name(SwsContext *c, const unsigned char **in, \
+ vec_dstst(oute, (0x02000002 | (((w * 3 + 32) / 32) << 16)), 1); \
+ \
+ for (j = 0; j < w / 16; j++) { \
+- y0 = vec_xl(0, y1i); \
++ y1ivP = (const vector unsigned char *) y1i; \
++ y2ivP = (const vector unsigned char *) y2i; \
++ uivP = (const vector unsigned char *) ui; \
++ vivP = (const vector unsigned char *) vi; \
++ \
++ align_perm = vec_lvsl(0, y1i); \
++ y0 = (vector unsigned char) \
++ vec_perm(y1ivP[0], y1ivP[1], align_perm); \
+ \
+- y1 = vec_xl(0, y2i); \
++ align_perm = vec_lvsl(0, y2i); \
++ y1 = (vector unsigned char) \
++ vec_perm(y2ivP[0], y2ivP[1], align_perm); \
+ \
+- u = (vector signed char) vec_xl(0, ui); \
++ align_perm = vec_lvsl(0, ui); \
++ u = (vector signed char) \
++ vec_perm(uivP[0], uivP[1], align_perm); \
+ \
+- v = (vector signed char) vec_xl(0, vi); \
++ align_perm = vec_lvsl(0, vi); \
++ v = (vector signed char) \
++ vec_perm(vivP[0], vivP[1], align_perm); \
+ \
+ u = (vector signed char) \
+ vec_sub(u, \
+--
+2.27.0
+
diff --git a/srcpkgs/ffmpeg4/patches/armv5tel-floating-point.patch b/srcpkgs/ffmpeg4/patches/armv5tel-floating-point.patch
new file mode 100644
index 000000000000..9a55178c74f0
--- /dev/null
+++ b/srcpkgs/ffmpeg4/patches/armv5tel-floating-point.patch
@@ -0,0 +1,18 @@
+--- a/libavfilter/vf_drawtext.c 2017-10-26 21:03:03.000000000 +0200
++++ b/libavfilter/vf_drawtext.c 2017-11-21 11:06:49.602284422 +0100
+@@ -39,6 +39,15 @@
+ #endif
+ #include <fenv.h>
+
++#if (FE_ALL_EXCEPT == 0)
++/* E.g. ARM soft float does not define these */
++#define FE_INVALID 0
++#define FE_DIVBYZERO 0
++#define FE_OVERFLOW 0
++#define FE_UNDERFLOW 0
++#define FE_INEXACT 0
++#endif
++
+ #if CONFIG_LIBFONTCONFIG
+ #include <fontconfig/fontconfig.h>
+ #endif
diff --git a/srcpkgs/ffmpeg4/patches/workaround-mesa-readeon-vaapi-bug.patch b/srcpkgs/ffmpeg4/patches/workaround-mesa-readeon-vaapi-bug.patch
new file mode 100644
index 000000000000..00e3f68a415b
--- /dev/null
+++ b/srcpkgs/ffmpeg4/patches/workaround-mesa-readeon-vaapi-bug.patch
@@ -0,0 +1,28 @@
+From 811d290844206fc73dc39c3e5b67d5d895baedf8 Mon Sep 17 00:00:00 2001
+From: Rainer Hochecker <fernetmenta@online.de>
+Date: Sat, 26 Jan 2019 19:48:35 +0100
+Subject: [PATCH] avcodec/vaapi_h264: skip decode if pic has no slices
+
+This fixes / workarounds https://bugs.freedesktop.org/show_bug.cgi?id=105368.
+It was hit frequently when watching h264 channels received via DVB-X.
+Corresponding kodi bug: https://github.com/xbmc/xbmc/issues/15704
+---
+ libavcodec/vaapi_h264.c | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+diff --git a/libavcodec/vaapi_h264.c b/libavcodec/vaapi_h264.c
+index 5854587a255..f12fdc457a4 100644
+--- a/libavcodec/vaapi_h264.c
++++ b/libavcodec/vaapi_h264.c
+@@ -317,6 +317,11 @@ static int vaapi_h264_end_frame(AVCodecContext *avctx)
+ H264SliceContext *sl = &h->slice_ctx[0];
+ int ret;
+
++ if (pic->nb_slices == 0) {
++ ret = AVERROR_INVALIDDATA;
++ goto finish;
++ }
++
+ ret = ff_vaapi_decode_issue(avctx, pic);
+ if (ret < 0)
+ goto finish;
diff --git a/srcpkgs/ffmpeg4/template b/srcpkgs/ffmpeg4/template
new file mode 100644
index 000000000000..7bc64bb39f41
--- /dev/null
+++ b/srcpkgs/ffmpeg4/template
@@ -0,0 +1,214 @@
+# Template file for 'ffmpeg4'
+# audacity also needs to be bumped when a new ffmpeg version bumps libavformat's soname!
+pkgname=ffmpeg4
+version=4.4.3
+revision=1
+short_desc="Decoding, encoding and streaming software - ffmpeg4 libraries only"
+maintainer="Orphaned <orphan@voidlinux.org>"
+license="GPL-3.0-or-later"
+homepage="https://www.ffmpeg.org"
+changelog="https://raw.githubusercontent.com/FFmpeg/FFmpeg/master/Changelog"
+distfiles="https://www.ffmpeg.org/releases/ffmpeg-${version}.tar.xz"
+checksum=6c5b6c195e61534766a0b5fe16acc919170c883362612816d0a1c7f4f947006e
+
+hostmakedepends="pkg-config perl yasm"
+makedepends="zlib-devel bzip2-devel freetype-devel alsa-lib-devel libXfixes-devel
+ libXext-devel libXvMC-devel libxcb-devel lame-devel libtheora-devel
+ libvorbis-devel x264-devel xvidcore-devel jack-devel SDL2-devel
+ libcdio-paranoia-devel librtmp-devel libmodplug-devel gnutls-devel
+ speex-devel celt-devel harfbuzz-devel libass-devel opus-devel ocl-icd-devel
+ libbs2b-devel libvidstab-devel $(vopt_if pulseaudio pulseaudio-devel)
+ $(vopt_if vaapi libva-devel) $(vopt_if vdpau libvdpau-devel)
+ $(vopt_if x265 x265-devel) $(vopt_if v4l2 v4l-utils-devel)
+ $(vopt_if fdk_aac fdk-aac-devel) $(vopt_if vpx libvpx-devel)
+ $(vopt_if aom libaom-devel) $(vopt_if sndio sndio-devel)
+ $(vopt_if dav1d libdav1d-devel) $(vopt_if zimg zimg-devel)
+ $(vopt_if webp libwebp-devel) $(vopt_if sofa libmysofa-devel)
+ $(vopt_if drm libdrm-devel) $(vopt_if svtav1 libsvt-av1-devel)
+ $(vopt_if srt srt-devel) $(vopt_if rist librist-devel)
+ $(vopt_if vulkan 'vulkan-loader Vulkan-Headers')
+ $(vopt_if nvenc nv-codec-headers) $(vopt_if nvdec nv-codec-headers)"
+
+build_options="x265 v4l2 vaapi vdpau vpx fdk_aac aom nvenc sndio pulseaudio
+ dav1d zimg webp sofa vulkan drm svtav1 srt rist nvdec"
+build_options_default="x265 v4l2 vpx aom sndio pulseaudio dav1d webp vulkan drm srt rist"
+
+desc_option_srt="Enable support for SRT (Secure, Reliable, Transport)"
+desc_option_rist="Enable support for RIST (Reliable Internet Stream Transport)"
+desc_option_sofa="Enable support for AES SOFA"
+desc_option_webp="Enable support for WebP"
+
+case "$XBPS_TARGET_MACHINE" in
+ i686*|x86_64*) build_options_default+=" vaapi vdpau nvenc nvdec";;
+ ppc64*) build_options_default+=" vaapi vdpau";;
+ mips*) CFLAGS="-mnan=legacy";;
+esac
+
+if [ "$XBPS_TARGET_WORDSIZE" != "32" ]; then
+ build_options_default+=" svtav1"
+fi
+
+if [ "$XBPS_TARGET_NO_ATOMIC8" ]; then
+ makedepends+=" libatomic-devel"
+fi
+
+_apply_patch() {
+ local args="$1" pname="$(basename $2)"
+
+ if [ ! -f ".${pname}_done" ]; then
+ patch -N $args -i $2
+ touch .${pname}_done
+ fi
+}
+
+post_patch() {
+ case "$XBPS_TARGET_MACHINE" in
+ ppc64le*) ;;
+ ppc*) _apply_patch -p1 ${FILESDIR}/altivec.patch ;;
+ esac
+}
+
+do_configure() {
+ # Fix gcc on x86_64-musl only
+ if [ "$XBPS_TARGET_MACHINE" = "x86_64-musl" ]; then
+ sed -i configure -e "s;_cflags_speed='-O3';_cflags_speed='-O2';"
+ fi
+
+ if [ "$CROSS_BUILD" ]; then
+ case "$XBPS_TARGET_MACHINE" in
+ arm*) _arch="arm";;
+ aarch64*) _arch="aarch64";;
+ mips*) _arch="mips";;
+ ppc64*) _arch="ppc64";;
+ ppc*) _arch="ppc";;
+ *) _arch="${XBPS_TARGET_MACHINE%%-musl}";;
+ esac
+
+ _args+=" --enable-cross-compile
+ --sysroot=$XBPS_CROSS_BASE
+ --cross-prefix=${XBPS_CROSS_TRIPLET}-
+ --target-os=linux --arch=${_arch}"
+ fi
+
+ case "$XBPS_TARGET_MACHINE" in
+ ppc|ppc-musl) _args+=" --disable-altivec";;
+ esac
+
+ if [ "$XBPS_TARGET_NO_ATOMIC8" ]; then
+ _args+=" --extra-libs=-latomic"
+ fi
+
+ ./configure --prefix=/usr --disable-debug --enable-gpl --enable-gnutls \
+ --disable-stripping \
+ --enable-libcdio --enable-version3 --enable-runtime-cpudetect \
+ --enable-libmp3lame --enable-libvorbis --enable-libxvid \
+ --enable-libx264 $(vopt_enable vpx libvpx) --enable-libtheora \
+ --enable-shared --enable-static --enable-libxcb \
+ $(vopt_enable pulseaudio libpulse) --enable-libfreetype --enable-libmodplug \
+ --enable-libspeex --enable-libcelt --enable-libass \
+ --enable-libopus --enable-librtmp --enable-libjack \
+ $(vopt_if fdk_aac '--enable-nonfree --enable-libfdk-aac') \
+ --disable-libopencore_amrnb --disable-libopencore_amrwb \
+ --disable-libopenjpeg \
+ --enable-postproc --enable-opencl ${_args} \
+ $(vopt_enable x265 libx265) \
+ $(vopt_enable v4l2 libv4l2) \
+ $(vopt_enable aom libaom) $(vopt_enable vaapi) $(vopt_enable vdpau) \
+ --enable-libbs2b --enable-avresample --enable-libvidstab \
+ $(vopt_enable dav1d libdav1d) \
+ $(vopt_enable zimg libzimg) \
+ $(vopt_enable webp libwebp) \
+ $(vopt_enable sofa libmysofa) \
+ $(vopt_enable vulkan) \
+ $(vopt_enable drm libdrm) \
+ $(vopt_enable svtav1 libsvtav1) \
+ $(vopt_enable srt libsrt) \
+ $(vopt_enable rist librist) \
+ $(vopt_if nvenc '--enable-nvenc') \
+ $(vopt_if nvdec '--enable-nvdec')
+}
+do_build() {
+ make ${makejobs}
+ make doc/ff{mpeg,play}.1
+}
+do_install() {
+ make DESTDIR=${DESTDIR} install install-man
+ rm -rf ${DESTDIR}/usr/bin
+}
+
+libavcodec4_package() {
+ short_desc="FFmpeg codec library"
+ pkg_install() {
+ vmove "usr/lib/libavcodec.so.*"
+ }
+}
+libavdevice4_package() {
+ short_desc="FFmpeg device handling library"
+ pkg_install() {
+ vmove "usr/lib/libavdevice.so.*"
+ }
+}
+libavresample4_package() {
+ short_desc="FFmpeg audio resampling library"
+ pkg_install() {
+ vmove "usr/lib/libavresample.so.*"
+ }
+}
+libavformat4_package() {
+ short_desc="FFmpeg file format library"
+ pkg_install() {
+ vmove "usr/lib/libavformat.so.*"
+ }
+}
+libavutil4_package() {
+ short_desc="FFmpeg utility library"
+ pkg_install() {
+ vmove "usr/lib/libavutil.so.*"
+ }
+}
+libavfilter4_package() {
+ short_desc="FFmpeg audio/video filter library"
+ pkg_install() {
+ vmove "usr/lib/libavfilter.so.*"
+ }
+}
+libpostproc4_package() {
+ short_desc="FFmpeg video postprocessing library"
+ pkg_install() {
+ vmove "usr/lib/libpostproc.so.*"
+ }
+}
+libswscale4_package() {
+ short_desc="FFmpeg video scaling library"
+ pkg_install() {
+ vmove "usr/lib/libswscale.so.*"
+ }
+}
+libswresample4_package() {
+ short_desc="FFmpeg video resampling library"
+ pkg_install() {
+ vmove "usr/lib/libswresample.so.*"
+ }
+}
+ffmpeg4-devel_package() {
+ depends="
+ libavcodec4>=${version}_${revision}
+ libavdevice4>=${version}_${revision}
+ libavformat4>=${version}_${revision}
+ libavutil4>=${version}_${revision}
+ libavfilter4>=${version}_${revision}
+ libpostproc4>=${version}_${revision}
+ libswscale4>=${version}_${revision}
+ libswresample4>=${version}_${revision}
+ libavresample4>=${version}_${revision}"
+ short_desc+=" - development files"
+ conflicts="ffmpeg-devel"
+ pkg_install() {
+ vmove usr/include
+ vmove usr/lib/pkgconfig
+ vmove usr/lib/*.a
+ vmove usr/lib/*.so
+ vmove usr/share/ffmpeg/examples
+ vmove usr/share/man/man3
+ }
+}
diff --git a/srcpkgs/libavcodec4 b/srcpkgs/libavcodec4
new file mode 120000
index 000000000000..887f354e7c6b
--- /dev/null
+++ b/srcpkgs/libavcodec4
@@ -0,0 +1 @@
+ffmpeg4
\ No newline at end of file
diff --git a/srcpkgs/libavdevice4 b/srcpkgs/libavdevice4
new file mode 120000
index 000000000000..887f354e7c6b
--- /dev/null
+++ b/srcpkgs/libavdevice4
@@ -0,0 +1 @@
+ffmpeg4
\ No newline at end of file
diff --git a/srcpkgs/libavfilter4 b/srcpkgs/libavfilter4
new file mode 120000
index 000000000000..887f354e7c6b
--- /dev/null
+++ b/srcpkgs/libavfilter4
@@ -0,0 +1 @@
+ffmpeg4
\ No newline at end of file
diff --git a/srcpkgs/libavformat4 b/srcpkgs/libavformat4
new file mode 120000
index 000000000000..887f354e7c6b
--- /dev/null
+++ b/srcpkgs/libavformat4
@@ -0,0 +1 @@
+ffmpeg4
\ No newline at end of file
diff --git a/srcpkgs/libavresample4 b/srcpkgs/libavresample4
new file mode 120000
index 000000000000..887f354e7c6b
--- /dev/null
+++ b/srcpkgs/libavresample4
@@ -0,0 +1 @@
+ffmpeg4
\ No newline at end of file
diff --git a/srcpkgs/libavutil4 b/srcpkgs/libavutil4
new file mode 120000
index 000000000000..887f354e7c6b
--- /dev/null
+++ b/srcpkgs/libavutil4
@@ -0,0 +1 @@
+ffmpeg4
\ No newline at end of file
diff --git a/srcpkgs/libpostproc4 b/srcpkgs/libpostproc4
new file mode 120000
index 000000000000..887f354e7c6b
--- /dev/null
+++ b/srcpkgs/libpostproc4
@@ -0,0 +1 @@
+ffmpeg4
\ No newline at end of file
diff --git a/srcpkgs/libswresample4 b/srcpkgs/libswresample4
new file mode 120000
index 000000000000..887f354e7c6b
--- /dev/null
+++ b/srcpkgs/libswresample4
@@ -0,0 +1 @@
+ffmpeg4
\ No newline at end of file
diff --git a/srcpkgs/libswscale4 b/srcpkgs/libswscale4
new file mode 120000
index 000000000000..887f354e7c6b
--- /dev/null
+++ b/srcpkgs/libswscale4
@@ -0,0 +1 @@
+ffmpeg4
\ No newline at end of file
From b456cf2f2dcb036c8810093de5929d40df8c7c7d Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 19:59:04 -0400
Subject: [PATCH 003/140] opencv: update to 4.7.0.
---
common/shlibs | 104 ++++++++++++++++++++--------------------
srcpkgs/opencv/template | 8 ++--
2 files changed, 56 insertions(+), 56 deletions(-)
diff --git a/common/shlibs b/common/shlibs
index d650f2a3045d..4626cfda810b 100644
--- a/common/shlibs
+++ b/common/shlibs
@@ -2137,58 +2137,58 @@ libcapstone.so.4 capstone-4.0_1
libhavege.so.2 libhaveged-1.9.11_1
libnih.so.1 libnih-1.0.3_1
libnih-dbus.so.1 libnih-1.0.3_1
-libopencv_quality.so.406 libopencv-4.6.0_1
-libopencv_reg.so.406 libopencv-4.6.0_1
-libopencv_surface_matching.so.406 libopencv-4.6.0_1
-libopencv_xphoto.so.406 libopencv-4.6.0_1
-libopencv_freetype.so.406 libopencv-4.6.0_1
-libopencv_fuzzy.so.406 libopencv-4.6.0_1
-libopencv_hfs.so.406 libopencv-4.6.0_1
-libopencv_img_hash.so.406 libopencv-4.6.0_1
-libopencv_line_descriptor.so.406 libopencv-4.6.0_1
-libopencv_saliency.so.406 libopencv-4.6.0_1
-libopencv_structured_light.so.406 libopencv-4.6.0_1
-libopencv_aruco.so.406 libopencv-4.6.0_1
-libopencv_bgsegm.so.406 libopencv-4.6.0_1
-libopencv_bioinspired.so.406 libopencv-4.6.0_1
-libopencv_ccalib.so.406 libopencv-4.6.0_1
-libopencv_face.so.406 libopencv-4.6.0_1
-libopencv_tracking.so.406 libopencv-4.6.0_1
-libopencv_xfeatures2d.so.406 libopencv-4.6.0_1
-libopencv_optflow.so.406 libopencv-4.6.0_1
-libopencv_ximgproc.so.406 libopencv-4.6.0_1
-libopencv_plot.so.406 libopencv-4.6.0_1
-libopencv_text.so.406 libopencv-4.6.0_1
-libopencv_ml.so.406 libopencv-4.6.0_1
-libopencv_objdetect.so.406 libopencv-4.6.0_1
-libopencv_dnn.so.406 libopencv-4.6.0_1
-libopencv_shape.so.406 libopencv-4.6.0_1
-libopencv_stitching.so.406 libopencv-4.6.0_1
-libopencv_photo.so.406 libopencv-4.6.0_1
-libopencv_video.so.406 libopencv-4.6.0_1
-libopencv_calib3d.so.406 libopencv-4.6.0_1
-libopencv_features2d.so.406 libopencv-4.6.0_1
-libopencv_flann.so.406 libopencv-4.6.0_1
-libopencv_highgui.so.406 libopencv-4.6.0_1
-libopencv_videoio.so.406 libopencv-4.6.0_1
-libopencv_imgcodecs.so.406 libopencv-4.6.0_1
-libopencv_imgproc.so.406 libopencv-4.6.0_1
-libopencv_core.so.406 libopencv-4.6.0_1
-libopencv_superres.so.406 libopencv-4.6.0_1
-libopencv_videostab.so.406 libopencv-4.6.0_1
-libopencv_gapi.so.406 libopencv-4.6.0_1
-libopencv_xobjdetect.so.406 libopencv-4.6.0_1
-libopencv_datasets.so.406 libopencv-4.6.0_1
-libopencv_dnn_objdetect.so.406 libopencv-4.6.0_1
-libopencv_dnn_superres.so.406 libopencv-4.6.0_1
-libopencv_dpm.so.406 libopencv-4.6.0_1
-libopencv_phase_unwrapping.so.406 libopencv-4.6.0_1
-libopencv_stereo.so.406 libopencv-4.6.0_1
-libopencv_rapid.so.406 libopencv-4.6.0_1
-libopencv_intensity_transform.so.406 libopencv-4.6.0_1
-libopencv_alphamat.so.406 libopencv-4.6.0_1
-libopencv_barcode.so.406 libopencv-4.6.0_1
-libopencv_mcc.so.406 libopencv-4.6.0_1
+libopencv_quality.so.407 libopencv-4.7.0_1
+libopencv_reg.so.407 libopencv-4.7.0_1
+libopencv_surface_matching.so.407 libopencv-4.7.0_1
+libopencv_xphoto.so.407 libopencv-4.7.0_1
+libopencv_freetype.so.407 libopencv-4.7.0_1
+libopencv_fuzzy.so.407 libopencv-4.7.0_1
+libopencv_hfs.so.407 libopencv-4.7.0_1
+libopencv_img_hash.so.407 libopencv-4.7.0_1
+libopencv_line_descriptor.so.407 libopencv-4.7.0_1
+libopencv_saliency.so.407 libopencv-4.7.0_1
+libopencv_structured_light.so.407 libopencv-4.7.0_1
+libopencv_aruco.so.407 libopencv-4.7.0_1
+libopencv_bgsegm.so.407 libopencv-4.7.0_1
+libopencv_bioinspired.so.407 libopencv-4.7.0_1
+libopencv_ccalib.so.407 libopencv-4.7.0_1
+libopencv_face.so.407 libopencv-4.7.0_1
+libopencv_tracking.so.407 libopencv-4.7.0_1
+libopencv_xfeatures2d.so.407 libopencv-4.7.0_1
+libopencv_optflow.so.407 libopencv-4.7.0_1
+libopencv_ximgproc.so.407 libopencv-4.7.0_1
+libopencv_plot.so.407 libopencv-4.7.0_1
+libopencv_text.so.407 libopencv-4.7.0_1
+libopencv_ml.so.407 libopencv-4.7.0_1
+libopencv_objdetect.so.407 libopencv-4.7.0_1
+libopencv_dnn.so.407 libopencv-4.7.0_1
+libopencv_shape.so.407 libopencv-4.7.0_1
+libopencv_stitching.so.407 libopencv-4.7.0_1
+libopencv_photo.so.407 libopencv-4.7.0_1
+libopencv_video.so.407 libopencv-4.7.0_1
+libopencv_calib3d.so.407 libopencv-4.7.0_1
+libopencv_features2d.so.407 libopencv-4.7.0_1
+libopencv_flann.so.407 libopencv-4.7.0_1
+libopencv_highgui.so.407 libopencv-4.7.0_1
+libopencv_videoio.so.407 libopencv-4.7.0_1
+libopencv_imgcodecs.so.407 libopencv-4.7.0_1
+libopencv_imgproc.so.407 libopencv-4.7.0_1
+libopencv_core.so.407 libopencv-4.7.0_1
+libopencv_superres.so.407 libopencv-4.7.0_1
+libopencv_videostab.so.407 libopencv-4.7.0_1
+libopencv_gapi.so.407 libopencv-4.7.0_1
+libopencv_xobjdetect.so.407 libopencv-4.7.0_1
+libopencv_datasets.so.407 libopencv-4.7.0_1
+libopencv_dnn_objdetect.so.407 libopencv-4.7.0_1
+libopencv_dnn_superres.so.407 libopencv-4.7.0_1
+libopencv_dpm.so.407 libopencv-4.7.0_1
+libopencv_phase_unwrapping.so.407 libopencv-4.7.0_1
+libopencv_stereo.so.407 libopencv-4.7.0_1
+libopencv_rapid.so.407 libopencv-4.7.0_1
+libopencv_intensity_transform.so.407 libopencv-4.7.0_1
+libopencv_alphamat.so.407 libopencv-4.7.0_1
+libopencv_barcode.so.407 libopencv-4.7.0_1
+libopencv_mcc.so.407 libopencv-4.7.0_1
libuniconf.so.4.6 wvstreams-4.6.1_20
libwvbase.so.4.6 wvstreams-4.6.1_20
libwvutils.so.4.6 wvstreams-4.6.1_20
diff --git a/srcpkgs/opencv/template b/srcpkgs/opencv/template
index 69c635b1ad2b..41f3183f1582 100644
--- a/srcpkgs/opencv/template
+++ b/srcpkgs/opencv/template
@@ -1,7 +1,7 @@
# Template file for 'opencv'
pkgname=opencv
-version=4.6.0
-revision=4
+version=4.7.0
+revision=1
create_wrksrc=yes
build_wrksrc=${pkgname}-${version}
build_style=cmake
@@ -24,8 +24,8 @@ homepage="https://opencv.org"
changelog="https://github.com/opencv/opencv/wiki/ChangeLog"
distfiles="https://github.com/opencv/opencv/archive/${version}.tar.gz
https://github.com/opencv/opencv_contrib/archive/${version}.tar.gz>contrib.tar.gz"
-checksum="1ec1cba65f9f20fe5a41fda1586e01c70ea0c9a6d7b67c9e13edf0cfe2239277
- 1777d5fd2b59029cf537e5fd6f8aa68d707075822f90bde683fcde086f85f7a7"
+checksum="8df0079cdbe179748a18d44731af62a245a45ebf5085223dc03133954c662973
+ 42df840cf9055e59d0e22c249cfb19f04743e1bdad113d31b1573d3934d62584"
patch_args="-Np1 -d ${build_wrksrc}"
# tests hang indenfinitely, even with test data included
make_check=no
From 98ba394049b5ff00dbacf97220c2c2692eafc4b1 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 19:59:45 -0400
Subject: [PATCH 004/140] actiona: revbump for opencv-4.7.0
---
srcpkgs/actiona/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/actiona/template b/srcpkgs/actiona/template
index cf5f0b7a2ae6..0d899311e6df 100644
--- a/srcpkgs/actiona/template
+++ b/srcpkgs/actiona/template
@@ -1,7 +1,7 @@
# Template file for 'actiona'
pkgname=actiona
version=3.10.1
-revision=2
+revision=3
build_style=qmake
configure_args="PKGCONFIG_OPENCV=opencv4"
hostmakedepends="pkg-config qt5-plugin-mysql qt5-qmake qt5-host-tools"
From 032bfac6e8d4086b7fa313de4952eaee56405e9f Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 19:59:45 -0400
Subject: [PATCH 005/140] gmic: revbump for opencv-4.7.0
---
srcpkgs/gmic/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/gmic/template b/srcpkgs/gmic/template
index 24a9c7218fdf..0bb4034d5cc8 100644
--- a/srcpkgs/gmic/template
+++ b/srcpkgs/gmic/template
@@ -1,7 +1,7 @@
# Template file for 'gmic'
pkgname=gmic
version=3.1.6
-revision=3
+revision=4
_zart_hash=34ebf6cce0bafb98abe57cec83c4a02cd1abeca0
create_wrksrc=yes
build_wrksrc="src"
From 325d5177879a203290498024126089d270eb12f0 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 19:59:46 -0400
Subject: [PATCH 006/140] qimgv: revbump for opencv-4.7.0
---
srcpkgs/qimgv/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/qimgv/template b/srcpkgs/qimgv/template
index 7eb30db33992..dd341dfe1bfc 100644
--- a/srcpkgs/qimgv/template
+++ b/srcpkgs/qimgv/template
@@ -1,7 +1,7 @@
# Template file for 'qimgv'
pkgname=qimgv
version=1.0.2
-revision=2
+revision=3
build_style=cmake
configure_args="$(vopt_if video -DVIDEO_SUPPORT=ON -DVIDEO_SUPPORT=OFF)
$(vopt_if scale -DOPENCV_SUPPORT=ON -DOPENCV_SUPPORT=OFF)
From 816c3f26e0a7f0a6e6a9e6d2d862d93d389c87d6 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 19:59:46 -0400
Subject: [PATCH 007/140] retroshare: revbump for opencv-4.7.0
---
srcpkgs/retroshare/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/retroshare/template b/srcpkgs/retroshare/template
index 8a0786c21a08..72023fa98b75 100644
--- a/srcpkgs/retroshare/template
+++ b/srcpkgs/retroshare/template
@@ -1,7 +1,7 @@
# Template file for 'retroshare'
pkgname=retroshare
version=0.6.6
-revision=2
+revision=4
build_style=qmake
#XXX broadcast feature requires an ancient udp-discovery-cpp which either needs
# to be fetched+patched (FTBFS) here or packaged :/
From 199f93854a9ac7bd07d23bbd07cf04a19c4f7272 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 19:59:46 -0400
Subject: [PATCH 008/140] siril: revbump for opencv-4.7.0
---
srcpkgs/siril/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/siril/template b/srcpkgs/siril/template
index e88f30fb6178..84332f79d060 100644
--- a/srcpkgs/siril/template
+++ b/srcpkgs/siril/template
@@ -1,7 +1,7 @@
# Template file for 'siril'
pkgname=siril
version=0.9.12
-revision=9
+revision=10
build_style=gnu-configure
hostmakedepends="pkg-config intltool autoconf automake gettext-devel"
makedepends="fftw-devel libconfig-devel libopencv-devel libffms2-devel
From 674f578a40f767aac1cb8add733a22679a88ab68 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 19:59:46 -0400
Subject: [PATCH 009/140] waifu2x-converter-cpp: revbump for opencv-4.7.0
---
srcpkgs/waifu2x-converter-cpp/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/waifu2x-converter-cpp/template b/srcpkgs/waifu2x-converter-cpp/template
index 8c095d0d7bab..aa52d8c981a8 100644
--- a/srcpkgs/waifu2x-converter-cpp/template
+++ b/srcpkgs/waifu2x-converter-cpp/template
@@ -1,7 +1,7 @@
# Template file for 'waifu2x-converter-cpp'
pkgname=waifu2x-converter-cpp
version=5.2.4
-revision=2
+revision=3
build_style=cmake
configure_args="-DINSTALL_MODELS=ON"
hostmakedepends="pkg-config"
From b50a3d189eef2ddf2fe36600d8b3b20082d90b06 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:00:38 -0400
Subject: [PATCH 010/140] vlc: revbump for ffmpeg4-4.4.3
---
srcpkgs/vlc/template | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/srcpkgs/vlc/template b/srcpkgs/vlc/template
index 210762b0a7e2..855ca5238662 100644
--- a/srcpkgs/vlc/template
+++ b/srcpkgs/vlc/template
@@ -1,7 +1,7 @@
# Template file for 'vlc'
pkgname=vlc
version=3.0.18
-revision=3
+revision=4
build_style=gnu-configure
configure_args="--disable-gme --disable-libtar --enable-jack
--enable-live555 --disable-fluidsynth --enable-dvdread
@@ -25,7 +25,7 @@ lib32disabled=yes
hostmakedepends="automake libtool pkg-config flex gettext libgcrypt-devel
live555-devel gettext-devel $(vopt_if lua lua52) $(vopt_if chromecast protobuf)"
makedepends="
- avahi-libs-devel dbus-glib-devel faad2-devel ffmpeg-devel freefont-ttf
+ avahi-libs-devel dbus-glib-devel faad2-devel ffmpeg4-devel freefont-ttf
gnutls-devel jack-devel liba52-devel libass-devel libbluray-devel
libcdio-devel libdca-devel libdvbpsi-devel libdvdnav-devel libmad-devel
libmatroska-devel libmodplug-devel libmpcdec-devel libmpeg2-devel
From 67e074dd1a4376ca7ecad28c6c810ec19b58a17d Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:00:55 -0400
Subject: [PATCH 011/140] osg: revbump for ffmpeg4-4.4.3
---
srcpkgs/osg/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/osg/template b/srcpkgs/osg/template
index a9ebbd287933..755793f7e11b 100644
--- a/srcpkgs/osg/template
+++ b/srcpkgs/osg/template
@@ -8,7 +8,7 @@ build_helper="qemu"
configure_args="-DLIB_POSTFIX="
hostmakedepends="pkg-config xrandr"
makedepends="MesaLib-devel gtkglext-devel libcurl-devel giflib-devel librsvg-devel
- jasper-devel tiff-devel libgdal-devel libgta-devel ffmpeg-devel xine-lib-devel
+ jasper-devel tiff-devel libgdal-devel libgta-devel ffmpeg4-devel xine-lib-devel
SDL2-devel gst-plugins-base1-devel
$(vopt_if openexr libopenexr-devel)
$(vopt_if poppler poppler-glib-devel)
From a02d106ff6726a0ba03d6adac66e5e38e569a99c Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:13 -0400
Subject: [PATCH 012/140] xine-lib: revbump for ffmpeg4-4.4.3
---
srcpkgs/xine-lib/template | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/srcpkgs/xine-lib/template b/srcpkgs/xine-lib/template
index f713eff49b07..ed6194c17d11 100644
--- a/srcpkgs/xine-lib/template
+++ b/srcpkgs/xine-lib/template
@@ -1,6 +1,6 @@
# Template file for 'xine-lib'
pkgname=xine-lib
-version=1.2.12
+version=1.2.13
revision=1
build_style=gnu-configure
configure_args="--disable-vcd --disable-gnomevfs --without-esound --disable-dxr3
@@ -8,7 +8,7 @@ configure_args="--disable-vcd --disable-gnomevfs --without-esound --disable-dxr3
hostmakedepends="automake gettext-devel libtool pkg-config perl"
makedepends="
zlib-devel alsa-lib-devel libxcb-devel libSM-devel libXext-devel libXv-devel
- libXvMC-devel liba52-devel libmad-devel ffmpeg-devel pulseaudio-devel
+ libXvMC-devel liba52-devel libmad-devel ffmpeg4-devel pulseaudio-devel
jack-devel samba-devel libflac-devel libmodplug-devel libmpcdec-devel
speex-devel libtheora-devel libvorbis-devel libdca-devel faad2-devel
libcdio-devel libbluray-devel aalib-devel libcaca-devel libXinerama-devel
@@ -19,7 +19,7 @@ license="GPL-2.0-or-later, LGPL-2.0-or-later"
homepage="http://www.xine-project.org"
changelog="https://sourceforge.net/projects/xine/files/xine-lib/${version}/README.txt/view"
distfiles="${SOURCEFORGE_SITE}/xine/${pkgname}-${version}.tar.xz"
-checksum=d606270468e1540c2a89c0d7f5fdf11e17ecc0c2698cc0bcb1065ff26abee098
+checksum=5f10d6d718a4a51c17ed1b32b031d4f9b80b061e8276535b2be31e5ac4b75e6f
case "$XBPS_TARGET_MACHINE" in
i686-musl)
From 04e6e3455350981602b6bf9cac81e024bda83e72 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:45 -0400
Subject: [PATCH 013/140] QMPlay2: revbump for ffmpeg-6.0
---
srcpkgs/QMPlay2/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/QMPlay2/template b/srcpkgs/QMPlay2/template
index ad73cbb01bae..55284c051161 100644
--- a/srcpkgs/QMPlay2/template
+++ b/srcpkgs/QMPlay2/template
@@ -1,7 +1,7 @@
# Template file for 'QMPlay2'
pkgname=QMPlay2
version=23.02.05
-revision=1
+revision=2
build_style=cmake
hostmakedepends="pkg-config qt5-qmake qt5-host-tools"
makedepends="alsa-lib-devel ffmpeg-devel libass-devel libcdio-devel libgme-devel
From 5fb396a304576e623150439ed6ffe40c1feaceeb Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:45 -0400
Subject: [PATCH 014/140] alsa-plugins: revbump for ffmpeg-6.0
---
srcpkgs/alsa-plugins/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/alsa-plugins/template b/srcpkgs/alsa-plugins/template
index 0bfa6d9fd264..a5708a7d82a8 100644
--- a/srcpkgs/alsa-plugins/template
+++ b/srcpkgs/alsa-plugins/template
@@ -1,7 +1,7 @@
# Template file for 'alsa-plugins'
pkgname=alsa-plugins
version=1.2.7.1
-revision=1
+revision=2
build_style=gnu-configure
configure_args="--disable-maemo-plugin"
hostmakedepends="pkg-config"
From 45b6117de5bc18b8c4ccacc0ba51bf73a79facb9 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:45 -0400
Subject: [PATCH 015/140] arcan: revbump for ffmpeg-6.0
---
srcpkgs/arcan/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/arcan/template b/srcpkgs/arcan/template
index 7be9652eccf3..ccc7df11ceac 100644
--- a/srcpkgs/arcan/template
+++ b/srcpkgs/arcan/template
@@ -2,7 +2,7 @@
# !! keep synced with: acfgfs aclip aloadimage
pkgname=arcan
version=0.6.2.1
-revision=1
+revision=2
create_wrksrc=yes
build_wrksrc=arcan/src
build_style=cmake
From 7d7f17e2bd9358810d2f5323f078acac16b0dbef Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:45 -0400
Subject: [PATCH 016/140] attract: revbump for ffmpeg4-4.4.3
---
srcpkgs/attract/template | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/srcpkgs/attract/template b/srcpkgs/attract/template
index 26144e931a3c..e760bf0d18ae 100644
--- a/srcpkgs/attract/template
+++ b/srcpkgs/attract/template
@@ -1,12 +1,12 @@
# Template file for 'attract'
pkgname=attract
version=2.6.2
-revision=1
+revision=2
build_style=gnu-makefile
make_build_args="VERBOSE=1"
make_use_env=yes
hostmakedepends="pkg-config"
-makedepends="SFML-devel ffmpeg-devel fontconfig-devel glu-devel libarchive-devel
+makedepends="SFML-devel ffmpeg4-devel fontconfig-devel glu-devel libarchive-devel
libcurl-devel libjpeg-turbo-devel xine-lib rapidjson libXrandr-devel"
depends="git"
short_desc="Attract-Mode is a graphical frontend for emulators"
From 2e80b0c920f6311d77a8c4a05982d9476bfb0ba5 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:45 -0400
Subject: [PATCH 017/140] aubio: revbump for ffmpeg-6.0
---
srcpkgs/aubio/patches/ffmpeg5.patch | 25 +++++++++++++++++++++++++
srcpkgs/aubio/template | 2 +-
2 files changed, 26 insertions(+), 1 deletion(-)
create mode 100644 srcpkgs/aubio/patches/ffmpeg5.patch
diff --git a/srcpkgs/aubio/patches/ffmpeg5.patch b/srcpkgs/aubio/patches/ffmpeg5.patch
new file mode 100644
index 000000000000..aace41a6e6d9
--- /dev/null
+++ b/srcpkgs/aubio/patches/ffmpeg5.patch
@@ -0,0 +1,25 @@
+From 8a05420e5dd8c7b8b2447f82dc919765876511b3 Mon Sep 17 00:00:00 2001
+From: Paul Brossier <piem@piem.org>
+Date: Tue, 25 Jan 2022 18:30:27 +0100
+Subject: [PATCH] [source_avcodec] define FF_API_LAVF_AVCTX for libavcodec >
+ 59, thx @berolinux (closes gh-353)
+
+---
+ src/io/source_avcodec.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/src/io/source_avcodec.c b/src/io/source_avcodec.c
+index e0ae93b5..1421bd9a 100644
+--- a/src/io/source_avcodec.c
++++ b/src/io/source_avcodec.c
+@@ -68,6 +68,10 @@
+ #define AUBIO_AVCODEC_MAX_BUFFER_SIZE AV_INPUT_BUFFER_MIN_SIZE
+ #endif
+
++#if LIBAVCODEC_VERSION_MAJOR >= 59
++#define FF_API_LAVF_AVCTX 1
++#endif
++
+ struct _aubio_source_avcodec_t {
+ uint_t hop_size;
+ uint_t samplerate;
diff --git a/srcpkgs/aubio/template b/srcpkgs/aubio/template
index ad1c4b256991..7d875cc02541 100644
--- a/srcpkgs/aubio/template
+++ b/srcpkgs/aubio/template
@@ -1,7 +1,7 @@
# Template file for 'aubio'
pkgname=aubio
version=0.4.9
-revision=1
+revision=2
build_style=waf3
# XXX lash, pure and swig support.
hostmakedepends="pkg-config txt2man"
From 7fb01cc5e73a215422bd72f9fa8b5fc26c7400a1 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:45 -0400
Subject: [PATCH 018/140] audacious-plugins: revbump for ffmpeg-6.0
---
.../audacious-plugins/patches/ffmpeg5.patch | 43 +++++++++++++++++++
srcpkgs/audacious-plugins/template | 2 +-
2 files changed, 44 insertions(+), 1 deletion(-)
create mode 100644 srcpkgs/audacious-plugins/patches/ffmpeg5.patch
diff --git a/srcpkgs/audacious-plugins/patches/ffmpeg5.patch b/srcpkgs/audacious-plugins/patches/ffmpeg5.patch
new file mode 100644
index 000000000000..4e5e34099d71
--- /dev/null
+++ b/srcpkgs/audacious-plugins/patches/ffmpeg5.patch
@@ -0,0 +1,43 @@
+commit 298aa371c56c2f52c25a33d9bdec4918b11cebdc
+Author: tibequadorian <tibequadorian@posteo.de>
+Date: Sat Mar 19 18:40:12 2022 +0100
+
+ audacious-plugins: rebuild against ffmpeg-5.0
+
+diff --git a/srcpkgs/audacious-plugins/patches/ffmpeg-5.0.patch b/srcpkgs/audacious-plugins/patches/ffmpeg-5.0.patch
+new file mode 100644
+index 0000000000..617c11215b
+--- /dev/null
++++ b/srcpkgs/audacious-plugins/patches/ffmpeg-5.0.patch
+@@ -0,0 +1,31 @@
++From f60beb400eeb1e4778bbfd738bc4a4ccef3de539 Mon Sep 17 00:00:00 2001
++From: John Lindgren <john@jlindgren.net>
++Date: Sat, 5 Mar 2022 12:05:34 -0500
++Subject: [PATCH] Fix build with FFmpeg 5.0
++
++---
++ src/ffaudio/ffaudio-core.cc | 4 ++--
++ 1 file changed, 2 insertions(+), 2 deletions(-)
++
++diff --git a/src/ffaudio/ffaudio-core.cc b/src/ffaudio/ffaudio-core.cc
++index 16dc63e3a..a2b95fd6c 100644
++--- a/src/ffaudio/ffaudio-core.cc
+++++ b/src/ffaudio/ffaudio-core.cc
++@@ -274,7 +274,7 @@ static AVInputFormat * get_format_by_content (const char * name, VFSFile & file)
++ AVProbeData d = {name, buf, filled};
++ score = target;
++
++- f = av_probe_input_format2 (& d, true, & score);
+++ f = (AVInputFormat *) av_probe_input_format2 (& d, true, & score);
++ if (f)
++ break;
++
++@@ -347,7 +347,7 @@ static bool find_codec (AVFormatContext * c, CodecInfo * cinfo)
++ #endif
++ if (stream && stream->codecpar && stream->codecpar->codec_type == AVMEDIA_TYPE_AUDIO)
++ {
++- AVCodec * codec = avcodec_find_decoder (stream->codecpar->codec_id);
+++ AVCodec * codec = (AVCodec *) avcodec_find_decoder (stream->codecpar->codec_id);
++
++ if (codec)
++ {
diff --git a/srcpkgs/audacious-plugins/template b/srcpkgs/audacious-plugins/template
index 88cbc1671fc6..beebfae59ed4 100644
--- a/srcpkgs/audacious-plugins/template
+++ b/srcpkgs/audacious-plugins/template
@@ -2,7 +2,7 @@
#Keep in sync with audacious!
pkgname=audacious-plugins
version=4.3.1
-revision=1
+revision=2
build_style=meson
configure_args="$(vopt_bool gtk3 gtk) $(vopt_bool gtk3)
$(vopt_bool qt) $(vopt_bool qt qt6)"
From c8955a13670baa12da2f68c6802e23bf5bdda641 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:45 -0400
Subject: [PATCH 019/140] audacity: revbump for ffmpeg4-4.4.3
---
srcpkgs/audacity/template | 5 ++---
1 file changed, 2 insertions(+), 3 deletions(-)
diff --git a/srcpkgs/audacity/template b/srcpkgs/audacity/template
index d509c0a89407..11e20255685b 100644
--- a/srcpkgs/audacity/template
+++ b/srcpkgs/audacity/template
@@ -1,7 +1,7 @@
# Template file for 'audacity'
pkgname=audacity
version=2.4.1
-revision=2
+revision=3
build_style=gnu-configure
configure_args="--with-ffmpeg=system --with-libsndfile=system --with-expat=system
--with-libsoxr=system --with-lame=system --with-lv2=system ac_cv_path_WX_CONFIG=wx-config-gtk3"
@@ -9,7 +9,7 @@ hostmakedepends="pkg-config cmake gettext libtool m4 which"
makedepends="jack-devel wxWidgets-gtk3-devel gtk+3-devel
libmad-devel soundtouch-devel libsoxr-devel
vamp-plugin-sdk-devel lame-devel libid3tag-devel libflac-devel
- ffmpeg-devel twolame-devel serd-devel lv2 lilv-devel suil-devel"
+ ffmpeg4-devel twolame-devel serd-devel lv2 lilv-devel suil-devel"
depends="desktop-file-utils hicolor-icon-theme"
short_desc="Graphical cross-platform audio editor"
maintainer="Orphaned <orphan@voidlinux.org>"
@@ -33,5 +33,4 @@ post_install() {
vcopy plug-ins /usr/share/audacity
rm ${DESTDIR}/usr/share/doc/audacity/LICENSE.txt
- vlicense LICENSE.txt LICENSE
}
From 145985c0b62ee4b1888332a5be8256d6adcb5dca Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:45 -0400
Subject: [PATCH 020/140] avidemux: revbump for ffmpeg-6.0
---
srcpkgs/avidemux/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/avidemux/template b/srcpkgs/avidemux/template
index 253a0243e225..557285982d2b 100644
--- a/srcpkgs/avidemux/template
+++ b/srcpkgs/avidemux/template
@@ -1,7 +1,7 @@
# Template file for 'avidemux'
pkgname=avidemux
version=2.8.0
-revision=2
+revision=3
# Can't be compiled for aarch64, arm* or mips*
archs="x86_64* i686*"
hostmakedepends="cmake pkg-config qt5-host-tools qt5-devel tar yasm"
From 1b314054810e8de661612ee40015dc043141ae3f Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:45 -0400
Subject: [PATCH 021/140] baresip: revbump for ffmpeg-6.0
---
srcpkgs/baresip/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/baresip/template b/srcpkgs/baresip/template
index f1bd1817048b..b21e22334316 100644
--- a/srcpkgs/baresip/template
+++ b/srcpkgs/baresip/template
@@ -1,7 +1,7 @@
# Template file for 'baresip'
pkgname=baresip
version=2.10.0
-revision=1
+revision=2
build_style=cmake
hostmakedepends="pkg-config glib-devel"
makedepends="libgsm-devel libpng-devel openssl-devel libsndfile-devel
From fd55de773224302a44fb079fe9cf5f0913e9ce94 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:46 -0400
Subject: [PATCH 022/140] blender: revbump for ffmpeg-6.0
---
.../patches/ffmpeg6-compat-blender.patch | 42 +++++++++++++++++++
srcpkgs/blender/template | 2 +-
2 files changed, 43 insertions(+), 1 deletion(-)
create mode 100644 srcpkgs/blender/patches/ffmpeg6-compat-blender.patch
diff --git a/srcpkgs/blender/patches/ffmpeg6-compat-blender.patch b/srcpkgs/blender/patches/ffmpeg6-compat-blender.patch
new file mode 100644
index 000000000000..d51a9c7710cc
--- /dev/null
+++ b/srcpkgs/blender/patches/ffmpeg6-compat-blender.patch
@@ -0,0 +1,42 @@
+--- a/source/blender/blenkernel/intern/writeffmpeg.c 2022-11-08 13:50:16 UTC
++++ b/source/blender/blenkernel/intern/writeffmpeg.c
+@@ -855,7 +855,7 @@ static AVStream *alloc_video_stream(FFMpegContext *con
+ 255);
+ st->avg_frame_rate = av_inv_q(c->time_base);
+
+- if (codec->capabilities & AV_CODEC_CAP_AUTO_THREADS) {
++ if (codec->capabilities & AV_CODEC_CAP_OTHER_THREADS) {
+ c->thread_count = 0;
+ }
+ else {
+--- a/source/blender/imbuf/intern/anim_movie.c 2022-11-04 00:33:07 UTC
++++ b/source/blender/imbuf/intern/anim_movie.c
+@@ -554,7 +554,7 @@ static int startffmpeg(struct anim *anim)
+ avcodec_parameters_to_context(pCodecCtx, video_stream->codecpar);
+ pCodecCtx->workaround_bugs = FF_BUG_AUTODETECT;
+
+- if (pCodec->capabilities & AV_CODEC_CAP_AUTO_THREADS) {
++ if (pCodec->capabilities & AV_CODEC_CAP_OTHER_THREADS) {
+ pCodecCtx->thread_count = 0;
+ }
+ else {
+--- a/source/blender/imbuf/intern/indexer.c 2022-11-04 00:33:07 UTC
++++ b/source/blender/imbuf/intern/indexer.c
+@@ -559,7 +559,7 @@ static struct proxy_output_ctx *alloc_proxy_output_ffm
+ av_dict_set(&codec_opts, "preset", "veryfast", 0);
+ av_dict_set(&codec_opts, "tune", "fastdecode", 0);
+
+- if (rv->codec->capabilities & AV_CODEC_CAP_AUTO_THREADS) {
++ if (rv->codec->capabilities & AV_CODEC_CAP_OTHER_THREADS) {
+ rv->c->thread_count = 0;
+ }
+ else {
+@@ -872,7 +872,7 @@ static IndexBuildContext *index_ffmpeg_create_context(
+ avcodec_parameters_to_context(context->iCodecCtx, context->iStream->codecpar);
+ context->iCodecCtx->workaround_bugs = FF_BUG_AUTODETECT;
+
+- if (context->iCodec->capabilities & AV_CODEC_CAP_AUTO_THREADS) {
++ if (context->iCodec->capabilities & AV_CODEC_CAP_OTHER_THREADS) {
+ context->iCodecCtx->thread_count = 0;
+ }
+ else {
diff --git a/srcpkgs/blender/template b/srcpkgs/blender/template
index 61b42eb2e51e..d18bc88838ff 100644
--- a/srcpkgs/blender/template
+++ b/srcpkgs/blender/template
@@ -1,7 +1,7 @@
# Template file for 'blender'
pkgname=blender
version=3.4.1
-revision=3
+revision=4
archs="x86_64* ppc64*"
build_style="cmake"
pycompile_dirs="/usr/share/blender/${version%.*}/scripts"
From b5178e4e573e5b75627b166200152ee31412c182 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:46 -0400
Subject: [PATCH 023/140] cantata: revbump for ffmpeg-6.0
---
srcpkgs/cantata/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/cantata/template b/srcpkgs/cantata/template
index 4b417d80d5c2..8a90aaa4c07a 100644
--- a/srcpkgs/cantata/template
+++ b/srcpkgs/cantata/template
@@ -1,7 +1,7 @@
# Template file for 'cantata'
pkgname=cantata
version=2.5.0
-revision=1
+revision=2
build_style=cmake
hostmakedepends="pkg-config qt5-qmake qt5-host-tools qt5-tools"
makedepends="qt5-devel qt5-tools-devel qt5-svg-devel qt5-xmlpatterns-devel
From 59259d40817fa204e536d43c7e944132f9beba14 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:46 -0400
Subject: [PATCH 024/140] ccextractor: revbump for ffmpeg4-4.4.3
---
srcpkgs/ccextractor/template | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/srcpkgs/ccextractor/template b/srcpkgs/ccextractor/template
index 9abcd82852b2..6eccad5885af 100644
--- a/srcpkgs/ccextractor/template
+++ b/srcpkgs/ccextractor/template
@@ -1,12 +1,12 @@
# Template file for 'ccextractor'
pkgname=ccextractor
version=0.93
-revision=1
+revision=2
build_wrksrc="linux"
build_style=gnu-configure
configure_args="--enable-ocr --enable-hardsubx"
hostmakedepends="automake pkg-config"
-makedepends="leptonica-devel tesseract-ocr-devel ffmpeg-devel"
+makedepends="leptonica-devel tesseract-ocr-devel ffmpeg4-devel"
short_desc="Extract subtitles from video streams"
maintainer="newbluemoon <blaumolch@mailbox.org>"
license="GPL-2.0-or-later"
From 4300dd323d02bba6a36b8b4a0a1be5ed85f25fdb Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:46 -0400
Subject: [PATCH 025/140] chromaprint: revbump for ffmpeg-6.0
---
srcpkgs/chromaprint/patches/ffmpeg5.patch | 569 ++++++++++++++++++++++
srcpkgs/chromaprint/template | 2 +-
2 files changed, 570 insertions(+), 1 deletion(-)
create mode 100644 srcpkgs/chromaprint/patches/ffmpeg5.patch
diff --git a/srcpkgs/chromaprint/patches/ffmpeg5.patch b/srcpkgs/chromaprint/patches/ffmpeg5.patch
new file mode 100644
index 000000000000..a9fd307a23c8
--- /dev/null
+++ b/srcpkgs/chromaprint/patches/ffmpeg5.patch
@@ -0,0 +1,569 @@
+From 8ccad6937177b1b92e40ab8f4447ea27bac009a7 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Luk=C3=A1=C5=A1=20Lalinsk=C3=BD?= <lalinsky@gmail.com>
+Date: Fri, 4 Nov 2022 21:47:38 +0100
+Subject: [PATCH] Use FFmpeg 5.x (#120)
+
+* Use FFmpeg 5.1.2 for CI builds
+
+* Build on Ubuntu 20.04
+
+* Upgrade code to FFmpeg 5.x APIs
+
+* Only set FFmpeg include dirs if building tools
+
+* No longer needed
+
+* Use ubuntu 20.04
+---
+ .github/workflows/build.yml | 6 +-
+ CMakeLists.txt | 16 --
+ package/build.sh | 4 +-
+ src/audio/ffmpeg_audio_processor.h | 2 -
+ src/audio/ffmpeg_audio_processor_avresample.h | 72 -------
+ src/audio/ffmpeg_audio_processor_swresample.h | 18 +-
+ src/audio/ffmpeg_audio_reader.h | 197 +++++++++---------
+ tests/CMakeLists.txt | 6 +
+ 8 files changed, 122 insertions(+), 199 deletions(-)
+ delete mode 100644 src/audio/ffmpeg_audio_processor_avresample.h
+
+diff --git a/CMakeLists.txt b/CMakeLists.txt
+index f8d6a32..4da2405 100644
+--- a/CMakeLists.txt
++++ b/CMakeLists.txt
+@@ -84,9 +84,6 @@ find_package(FFmpeg)
+ if(FFMPEG_LIBRARIES)
+ cmake_push_check_state(RESET)
+ set(CMAKE_REQUIRED_LIBRARIES ${FFMPEG_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT} -lm)
+- check_function_exists(av_packet_unref HAVE_AV_PACKET_UNREF)
+- check_function_exists(av_frame_alloc HAVE_AV_FRAME_ALLOC)
+- check_function_exists(av_frame_free HAVE_AV_FRAME_FREE)
+ cmake_pop_check_state()
+ endif()
+
+@@ -163,14 +160,11 @@ message(STATUS "Using ${FFT_LIB} for FFT calculations")
+ if(NOT AUDIO_PROCESSOR_LIB)
+ if(FFMPEG_LIBSWRESAMPLE_FOUND)
+ set(AUDIO_PROCESSOR_LIB "swresample")
+- elseif(FFMPEG_LIBAVRESAMPLE_FOUND)
+- set(AUDIO_PROCESSOR_LIB "avresample")
+ endif()
+ endif()
+
+ if(AUDIO_PROCESSOR_LIB STREQUAL "swresample")
+ if(FFMPEG_LIBSWRESAMPLE_FOUND)
+- set(USE_AVRESAMPLE OFF)
+ set(USE_SWRESAMPLE ON)
+ set(AUDIO_PROCESSOR_LIBRARIES ${FFMPEG_LIBSWRESAMPLE_LIBRARIES})
+ set(AUDIO_PROCESSOR_INCLUDE_DIRS ${FFMPEG_LIBSWRESAMPLE_INCLUDE_DIRS})
+@@ -178,16 +172,6 @@ if(AUDIO_PROCESSOR_LIB STREQUAL "swresample")
+ message(FATAL_ERROR "Selected ${AUDIO_PROCESSOR_LIB} for audio processing, but the library is not found")
+ endif()
+ message(STATUS "Using ${AUDIO_PROCESSOR_LIB} for audio conversion")
+-elseif(AUDIO_PROCESSOR_LIB STREQUAL "avresample")
+- if(FFMPEG_LIBAVRESAMPLE_FOUND)
+- set(USE_AVRESAMPLE ON)
+- set(USE_SWRESAMPLE OFF)
+- set(AUDIO_PROCESSOR_LIBRARIES ${FFMPEG_LIBAVRESAMPLE_LIBRARIES})
+- set(AUDIO_PROCESSOR_INCLUDE_DIRS ${FFMPEG_LIBAVRESAMPLE_INCLUDE_DIRS})
+- else()
+- message(FATAL_ERROR "Selected ${AUDIO_PROCESSOR_LIB} for audio processing, but the library is not found")
+- endif()
+- message(STATUS "Using ${AUDIO_PROCESSOR_LIB} for audio conversion")
+ else()
+ message(STATUS "Building without audio conversion support, please install FFmpeg with libswresample")
+ endif()
+diff --git a/package/build.sh b/package/build.sh
+index da631ae..b41d36e 100755
+--- a/package/build.sh
++++ b/package/build.sh
+@@ -7,8 +7,8 @@ set -eux
+
+ BASE_DIR=$(cd $(dirname $0)/.. && pwd)
+
+-FFMPEG_VERSION=4.4.1
+-FFMPEG_BUILD_TAG=v4.4.1-1
++FFMPEG_VERSION=5.1.2
++FFMPEG_BUILD_TAG=v${FFMPEG_VERSION}-1
+
+ TMP_BUILD_DIR=$BASE_DIR/$(mktemp -d build.XXXXXXXX)
+ trap 'rm -rf $TMP_BUILD_DIR' EXIT
+diff --git a/src/audio/ffmpeg_audio_processor.h b/src/audio/ffmpeg_audio_processor.h
+index 7628fc7..39f4f6d 100644
+--- a/src/audio/ffmpeg_audio_processor.h
++++ b/src/audio/ffmpeg_audio_processor.h
+@@ -10,8 +10,6 @@
+
+ #if defined(USE_SWRESAMPLE)
+ #include "audio/ffmpeg_audio_processor_swresample.h"
+-#elif defined(USE_AVRESAMPLE)
+-#include "audio/ffmpeg_audio_processor_avresample.h"
+ #else
+ #error "no audio processing library"
+ #endif
+diff --git a/src/audio/ffmpeg_audio_processor_avresample.h b/src/audio/ffmpeg_audio_processor_avresample.h
+deleted file mode 100644
+index bd85f92..0000000
+--- a/src/audio/ffmpeg_audio_processor_avresample.h
++++ /dev/null
+@@ -1,72 +0,0 @@
+-// Copyright (C) 2016 Lukas Lalinsky
+-// Distributed under the MIT license, see the LICENSE file for details.
+-
+-#ifndef CHROMAPRINT_AUDIO_FFMPEG_AUDIO_PROCESSOR_AVRESAMPLE_H_
+-#define CHROMAPRINT_AUDIO_FFMPEG_AUDIO_PROCESSOR_AVRESAMPLE_H_
+-
+-extern "C" {
+-#include <libavresample/avresample.h>
+-}
+-
+-namespace chromaprint {
+-
+-class FFmpegAudioProcessor {
+-public:
+- FFmpegAudioProcessor() {
+- m_resample_ctx = avresample_alloc_context();
+- }
+-
+- ~FFmpegAudioProcessor() {
+- avresample_free(&m_resample_ctx);
+- }
+-
+- void SetCompatibleMode() {
+- av_opt_set_int(m_resample_ctx, "filter_size", 16, 0);
+- av_opt_set_int(m_resample_ctx, "phase_shift", 8, 0);
+- av_opt_set_int(m_resample_ctx, "linear_interp", 1, 0);
+- av_opt_set_double(m_resample_ctx, "cutoff", 0.8, 0);
+- }
+-
+- void SetInputChannelLayout(int64_t channel_layout) {
+- av_opt_set_int(m_resample_ctx, "in_channel_layout", channel_layout, 0);
+- }
+-
+- void SetInputSampleFormat(AVSampleFormat sample_format) {
+- av_opt_set_int(m_resample_ctx, "in_sample_fmt", sample_format, 0);
+- }
+-
+- void SetInputSampleRate(int sample_rate) {
+- av_opt_set_int(m_resample_ctx, "in_sample_rate", sample_rate, 0);
+- }
+-
+- void SetOutputChannelLayout(int64_t channel_layout) {
+- av_opt_set_int(m_resample_ctx, "out_channel_layout", channel_layout, 0);
+- }
+-
+- void SetOutputSampleFormat(AVSampleFormat sample_format) {
+- av_opt_set_int(m_resample_ctx, "out_sample_fmt", sample_format, 0);
+- }
+-
+- void SetOutputSampleRate(int sample_rate) {
+- av_opt_set_int(m_resample_ctx, "out_sample_fmt", sample_rate, 0);
+- }
+-
+- int Init() {
+- return avresample_open(m_resample_ctx);
+- }
+-
+- int Convert(uint8_t **out, int out_count, const uint8_t **in, int in_count) {
+- return avresample_convert(m_resample_ctx, out, 0, out_count, (uint8_t **) in, 0, in_count);
+- }
+-
+- int Flush(uint8_t **out, int out_count) {
+- return avresample_read(m_resample_ctx, out, out_count);
+- }
+-
+-private:
+- AVAudioResampleContext *m_resample_ctx = nullptr;
+-};
+-
+-}; // namespace chromaprint
+-
+-#endif
+diff --git a/src/audio/ffmpeg_audio_processor_swresample.h b/src/audio/ffmpeg_audio_processor_swresample.h
+index b86266b..b1d4bea 100644
+--- a/src/audio/ffmpeg_audio_processor_swresample.h
++++ b/src/audio/ffmpeg_audio_processor_swresample.h
+@@ -28,30 +28,28 @@ public:
+ av_opt_set_double(m_swr_ctx, "cutoff", 0.8, 0);
+ }
+
+- void SetInputChannelLayout(int64_t channel_layout) {
+- av_opt_set_int(m_swr_ctx, "icl", channel_layout, 0);
+- av_opt_set_int(m_swr_ctx, "ich", av_get_channel_layout_nb_channels(channel_layout), 0);
++ void SetInputChannelLayout(AVChannelLayout *channel_layout) {
++ av_opt_set_int(m_swr_ctx, "in_channel_layout", channel_layout->u.mask, 0);
+ }
+
+ void SetInputSampleFormat(AVSampleFormat sample_format) {
+- av_opt_set_int(m_swr_ctx, "isf", sample_format, 0);
++ av_opt_set_sample_fmt(m_swr_ctx, "in_sample_fmt", sample_format, 0);
+ }
+
+ void SetInputSampleRate(int sample_rate) {
+- av_opt_set_int(m_swr_ctx, "isr", sample_rate, 0);
++ av_opt_set_int(m_swr_ctx, "in_sample_rate", sample_rate, 0);
+ }
+
+- void SetOutputChannelLayout(int64_t channel_layout) {
+- av_opt_set_int(m_swr_ctx, "ocl", channel_layout, 0);
+- av_opt_set_int(m_swr_ctx, "och", av_get_channel_layout_nb_channels(channel_layout), 0);
++ void SetOutputChannelLayout(AVChannelLayout *channel_layout) {
++ av_opt_set_int(m_swr_ctx, "out_channel_layout", channel_layout->u.mask, 0);
+ }
+
+ void SetOutputSampleFormat(AVSampleFormat sample_format) {
+- av_opt_set_int(m_swr_ctx, "osf", sample_format, 0);
++ av_opt_set_sample_fmt(m_swr_ctx, "out_sample_fmt", sample_format, 0);
+ }
+
+ void SetOutputSampleRate(int sample_rate) {
+- av_opt_set_int(m_swr_ctx, "osr", sample_rate, 0);
++ av_opt_set_int(m_swr_ctx, "out_sample_rate", sample_rate, 0);
+ }
+
+ int Init() {
+diff --git a/src/audio/ffmpeg_audio_reader.h b/src/audio/ffmpeg_audio_reader.h
+index 5550164..1c6b346 100644
+--- a/src/audio/ffmpeg_audio_reader.h
++++ b/src/audio/ffmpeg_audio_reader.h
+@@ -62,7 +62,7 @@ public:
+ bool Read(const int16_t **data, size_t *size);
+
+ bool IsOpen() const { return m_opened; }
+- bool IsFinished() const { return m_finished && !m_got_frame; }
++ bool IsFinished() const { return !m_has_more_packets && !m_has_more_frames; }
+
+ std::string GetError() const { return m_error; }
+ int GetErrorCode() const { return m_error_code; }
+@@ -74,20 +74,19 @@ private:
+ uint8_t *m_convert_buffer[1] = { nullptr };
+ int m_convert_buffer_nb_samples = 0;
+
+- AVInputFormat *m_input_fmt = nullptr;
++ const AVInputFormat *m_input_fmt = nullptr;
+ AVDictionary *m_input_opts = nullptr;
+
+ AVFormatContext *m_format_ctx = nullptr;
+ AVCodecContext *m_codec_ctx = nullptr;
+- AVFrame *m_frame = nullptr;
+ int m_stream_index = -1;
+ std::string m_error;
+ int m_error_code = 0;
+- bool m_finished = false;
+ bool m_opened = false;
+- int m_got_frame = 0;
+- AVPacket m_packet;
+- AVPacket m_packet0;
++ bool m_has_more_packets = true;
++ bool m_has_more_frames = true;
++ AVPacket *m_packet = nullptr;
++ AVFrame *m_frame = nullptr;
+
+ int m_output_sample_rate = 0;
+ int m_output_channels = 0;
+@@ -98,19 +97,12 @@ private:
+
+ inline FFmpegAudioReader::FFmpegAudioReader() {
+ av_log_set_level(AV_LOG_QUIET);
+-
+- av_init_packet(&m_packet);
+- m_packet.data = nullptr;
+- m_packet.size = 0;
+-
+- m_packet0 = m_packet;
+ }
+
+ inline FFmpegAudioReader::~FFmpegAudioReader() {
+ Close();
+ av_dict_free(&m_input_opts);
+ av_freep(&m_convert_buffer[0]);
+- av_packet_unref(&m_packet0);
+ }
+
+ inline bool FFmpegAudioReader::SetInputFormat(const char *name) {
+@@ -135,11 +127,10 @@ inline bool FFmpegAudioReader::Open(const std::string &file_name) {
+
+ Close();
+
+- av_init_packet(&m_packet);
+- m_packet.data = nullptr;
+- m_packet.size = 0;
+-
+- m_packet0 = m_packet;
++ m_packet = av_packet_alloc();
++ if (!m_packet) {
++ return false;
++ }
+
+ ret = avformat_open_input(&m_format_ctx, file_name.c_str(), m_input_fmt, &m_input_opts);
+ if (ret < 0) {
+@@ -153,26 +144,31 @@ inline bool FFmpegAudioReader::Open(const std::string &file_name) {
+ return false;
+ }
+
+- AVCodec *codec;
++ const AVCodec *codec;
+ ret = av_find_best_stream(m_format_ctx, AVMEDIA_TYPE_AUDIO, -1, -1, &codec, 0);
+ if (ret < 0) {
+ SetError("Could not find any audio stream in the file", ret);
+ return false;
+ }
+ m_stream_index = ret;
++ auto stream = m_format_ctx->streams[m_stream_index];
+
+- m_codec_ctx = m_format_ctx->streams[m_stream_index]->codec;
++ m_codec_ctx = avcodec_alloc_context3(codec);
+ m_codec_ctx->request_sample_fmt = AV_SAMPLE_FMT_S16;
+
++ ret = avcodec_parameters_to_context(m_codec_ctx, stream->codecpar);
++ if (ret < 0) {
++ SetError("Could not copy the stream parameters", ret);
++ return false;
++ }
++
+ ret = avcodec_open2(m_codec_ctx, codec, nullptr);
+ if (ret < 0) {
+ SetError("Could not open the codec", ret);
+ return false;
+ }
+
+- if (!m_codec_ctx->channel_layout) {
+- m_codec_ctx->channel_layout = av_get_default_channel_layout(m_codec_ctx->channels);
+- }
++ av_dump_format(m_format_ctx, 0, "foo", 0);
+
+ m_frame = av_frame_alloc();
+ if (!m_frame) {
+@@ -183,19 +179,23 @@ inline bool FFmpegAudioReader::Open(const std::string &file_name) {
+ m_output_sample_rate = m_codec_ctx->sample_rate;
+ }
+
+- if (!m_output_channels) {
+- m_output_channels = m_codec_ctx->channels;
++ AVChannelLayout output_channel_layout;
++ if (m_output_channels) {
++ av_channel_layout_default(&output_channel_layout, m_output_channels);
++ } else {
++ m_output_channels = m_codec_ctx->ch_layout.nb_channels;
++ av_channel_layout_default(&output_channel_layout, m_output_channels);
+ }
+
+- if (m_codec_ctx->sample_fmt != AV_SAMPLE_FMT_S16 || m_codec_ctx->channels != m_output_channels || m_codec_ctx->sample_rate != m_output_sample_rate) {
++ if (m_codec_ctx->sample_fmt != AV_SAMPLE_FMT_S16 || m_codec_ctx->ch_layout.nb_channels != m_output_channels || m_codec_ctx->sample_rate != m_output_sample_rate) {
+ m_converter.reset(new FFmpegAudioProcessor());
+ m_converter->SetCompatibleMode();
+ m_converter->SetInputSampleFormat(m_codec_ctx->sample_fmt);
+ m_converter->SetInputSampleRate(m_codec_ctx->sample_rate);
+- m_converter->SetInputChannelLayout(m_codec_ctx->channel_layout);
++ m_converter->SetInputChannelLayout(&(m_codec_ctx->ch_layout));
+ m_converter->SetOutputSampleFormat(AV_SAMPLE_FMT_S16);
+ m_converter->SetOutputSampleRate(m_output_sample_rate);
+- m_converter->SetOutputChannelLayout(av_get_default_channel_layout(m_output_channels));
++ m_converter->SetOutputChannelLayout(&output_channel_layout);
+ auto ret = m_converter->Init();
+ if (ret != 0) {
+ SetError("Could not create an audio converter instance", ret);
+@@ -203,10 +203,11 @@ inline bool FFmpegAudioReader::Open(const std::string &file_name) {
+ }
+ }
+
++ av_channel_layout_uninit(&output_channel_layout);
++
+ m_opened = true;
+- m_finished = false;
+- m_got_frame = 0;
+- m_nb_packets = 0;
++ m_has_more_packets = true;
++ m_has_more_frames = true;
+ m_decode_error = 0;
+
+ return true;
+@@ -214,6 +215,7 @@ inline bool FFmpegAudioReader::Open(const std::string &file_name) {
+
+ inline void FFmpegAudioReader::Close() {
+ av_frame_free(&m_frame);
++ av_packet_free(&m_packet);
+
+ m_stream_index = -1;
+
+@@ -252,91 +254,98 @@ inline bool FFmpegAudioReader::Read(const int16_t **data, size_t *size) {
+ return false;
+ }
+
++ *data = nullptr;
++ *size = 0;
++
+ int ret;
++ bool needs_packet = false;
+ while (true) {
+- while (m_packet.size <= 0) {
+- av_packet_unref(&m_packet0);
+- av_init_packet(&m_packet);
+- m_packet.data = nullptr;
+- m_packet.size = 0;
+- ret = av_read_frame(m_format_ctx, &m_packet);
++ while (needs_packet && m_packet->size == 0) {
++ ret = av_read_frame(m_format_ctx, m_packet);
+ if (ret < 0) {
+ if (ret == AVERROR_EOF) {
+- m_finished = true;
++ needs_packet = false;
++ m_has_more_packets = false;
+ break;
+- } else {
++ }
++ SetError("Error reading from the audio source", ret);
++ return false;
++ }
++ if (m_packet->stream_index == m_stream_index) {
++ needs_packet = false;
++ } else {
++ av_packet_unref(m_packet);
++ }
++ }
++
++ if (m_packet->size != 0) {
++ ret = avcodec_send_packet(m_codec_ctx, m_packet);
++ if (ret < 0) {
++ if (ret != AVERROR(EAGAIN)) {
+ SetError("Error reading from the audio source", ret);
+ return false;
+ }
+- }
+- m_packet0 = m_packet;
+- if (m_packet.stream_index != m_stream_index) {
+- m_packet.data = nullptr;
+- m_packet.size = 0;
+ } else {
+- m_nb_packets++;
++ av_packet_unref(m_packet);
+ }
+ }
+
+- ret = avcodec_decode_audio4(m_codec_ctx, m_frame, &m_got_frame, &m_packet);
++ ret = avcodec_receive_frame(m_codec_ctx, m_frame);
+ if (ret < 0) {
+- if (m_decode_error) {
+- SetError("Error decoding audio frame", m_decode_error);
+- return false;
++ if (ret == AVERROR_EOF) {
++ m_has_more_frames = false;
++ } else if (ret == AVERROR(EAGAIN)) {
++ if (m_has_more_packets) {
++ needs_packet = true;
++ continue;
++ } else {
++ m_has_more_frames = false;
++ }
+ }
+- m_decode_error = ret;
+- m_packet.data = nullptr;
+- m_packet.size = 0;
+- continue;
++ SetError("Error decoding the audio source", ret);
++ return false;
+ }
+
+- break;
+- }
+-
+- m_decode_error = 0;
+-
+- const int decoded = std::min(ret, m_packet.size);
+- m_packet.data += decoded;
+- m_packet.size -= decoded;
+-
+- if (m_got_frame) {
+- if (m_converter) {
+- if (m_frame->nb_samples > m_convert_buffer_nb_samples) {
+- int linsize;
+- av_freep(&m_convert_buffer[0]);
+- m_convert_buffer_nb_samples = std::max(1024 * 8, m_frame->nb_samples);
+- ret = av_samples_alloc(m_convert_buffer, &linsize, m_codec_ctx->channels, m_convert_buffer_nb_samples, AV_SAMPLE_FMT_S16, 1);
+- if (ret < 0) {
+- SetError("Couldn't allocate audio converter buffer", ret);
++ if (m_frame->nb_samples > 0) {
++ if (m_converter) {
++ if (m_frame->nb_samples > m_convert_buffer_nb_samples) {
++ int linsize;
++ av_freep(&m_convert_buffer[0]);
++ m_convert_buffer_nb_samples = std::max(1024 * 8, m_frame->nb_samples);
++ ret = av_samples_alloc(m_convert_buffer, &linsize, m_codec_ctx->ch_layout.nb_channels, m_convert_buffer_nb_samples, AV_SAMPLE_FMT_S16, 1);
++ if (ret < 0) {
++ SetError("Couldn't allocate audio converter buffer", ret);
++ return false;
++ }
++ }
++ auto nb_samples = m_converter->Convert(m_convert_buffer, m_convert_buffer_nb_samples, (const uint8_t **) m_frame->data, m_frame->nb_samples);
++ if (nb_samples < 0) {
++ SetError("Couldn't convert audio", ret);
+ return false;
+ }
+- }
+- auto nb_samples = m_converter->Convert(m_convert_buffer, m_convert_buffer_nb_samples, (const uint8_t **) m_frame->data, m_frame->nb_samples);
+- if (nb_samples < 0) {
+- SetError("Couldn't convert audio", ret);
+- return false;
+- }
+- *data = (const int16_t *) m_convert_buffer[0];
+- *size = nb_samples;
+- } else {
+- *data = (const int16_t *) m_frame->data[0];
+- *size = m_frame->nb_samples;
+- }
+- } else {
+- if (m_finished && m_converter) {
+- auto nb_samples = m_converter->Flush(m_convert_buffer, m_convert_buffer_nb_samples);
+- if (nb_samples < 0) {
+- SetError("Couldn't convert audio", ret);
+- return false;
+- } else if (nb_samples > 0) {
+- m_got_frame = 1;
+ *data = (const int16_t *) m_convert_buffer[0];
+ *size = nb_samples;
++ } else {
++ *data = (const int16_t *) m_frame->data[0];
++ *size = m_frame->nb_samples;
++ }
++ } else {
++ if (m_converter) {
++ if (IsFinished()) {
++ auto nb_samples = m_converter->Flush(m_convert_buffer, m_convert_buffer_nb_samples);
++ if (nb_samples < 0) {
++ SetError("Couldn't convert audio", ret);
++ return false;
++ } else if (nb_samples > 0) {
++ *data = (const int16_t *) m_convert_buffer[0];
++ *size = nb_samples;
++ }
++ }
+ }
+ }
+- }
+
+- return true;
++ return true;
++ }
+ }
+
+ inline void FFmpegAudioReader::SetError(const char *message, int errnum) {
+diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt
+index a2b517b..123e643 100644
+--- a/tests/CMakeLists.txt
++++ b/tests/CMakeLists.txt
+@@ -38,6 +38,12 @@ set(SRCS
+
+ if(BUILD_TOOLS)
+ set(SRCS ${SRCS} ../src/audio/ffmpeg_audio_reader_test.cpp)
++ include_directories(
++ ${FFMPEG_LIBAVFORMAT_INCLUDE_DIRS}
++ ${FFMPEG_LIBAVCODEC_INCLUDE_DIRS}
++ ${FFMPEG_LIBAVUTIL_INCLUDE_DIRS}
++ ${AUDIO_PROCESSOR_INCLUDE_DIRS}
++ )
+ link_libraries(fpcalc_libs)
+ endif()
+
+--
+2.38.1
+
+
diff --git a/srcpkgs/chromaprint/template b/srcpkgs/chromaprint/template
index 7ef7838949f3..1f7bbc70a22c 100644
--- a/srcpkgs/chromaprint/template
+++ b/srcpkgs/chromaprint/template
@@ -1,7 +1,7 @@
# Template file for 'chromaprint'
pkgname=chromaprint
version=1.5.1
-revision=1
+revision=2
build_style=cmake
configure_args="-DBUILD_TOOLS=ON"
make_check_target="check"
From a25f84beadcc55197ebe6f2993098618baa74728 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:46 -0400
Subject: [PATCH 026/140] chromium: revbump for ffmpeg-6.0
---
.../patches/chromium-93-ffmpeg-4.4.patch | 36 --------------
srcpkgs/chromium/patches/ffmpeg5.patch | 47 +++++++++++++++++++
srcpkgs/chromium/template | 2 +-
3 files changed, 48 insertions(+), 37 deletions(-)
delete mode 100644 srcpkgs/chromium/patches/chromium-93-ffmpeg-4.4.patch
create mode 100644 srcpkgs/chromium/patches/ffmpeg5.patch
diff --git a/srcpkgs/chromium/patches/chromium-93-ffmpeg-4.4.patch b/srcpkgs/chromium/patches/chromium-93-ffmpeg-4.4.patch
deleted file mode 100644
index f0ec736f98bc..000000000000
--- a/srcpkgs/chromium/patches/chromium-93-ffmpeg-4.4.patch
+++ /dev/null
@@ -1,36 +0,0 @@
-diff --git a/media/filters/ffmpeg_demuxer.cc b/media/filters/ffmpeg_demuxer.cc
-index ac4713b07268..492a9a37d096 100644
---- a/media/filters/ffmpeg_demuxer.cc
-+++ b/media/filters/ffmpeg_demuxer.cc
-@@ -427,11 +427,11 @@ void FFmpegDemuxerStream::EnqueuePacket(ScopedAVPacket packet) {
- scoped_refptr<DecoderBuffer> buffer;
-
- if (type() == DemuxerStream::TEXT) {
-- size_t id_size = 0;
-+ int id_size = 0;
- uint8_t* id_data = av_packet_get_side_data(
- packet.get(), AV_PKT_DATA_WEBVTT_IDENTIFIER, &id_size);
-
-- size_t settings_size = 0;
-+ int settings_size = 0;
- uint8_t* settings_data = av_packet_get_side_data(
- packet.get(), AV_PKT_DATA_WEBVTT_SETTINGS, &settings_size);
-
-@@ -443,7 +443,7 @@ void FFmpegDemuxerStream::EnqueuePacket(ScopedAVPacket packet) {
- buffer = DecoderBuffer::CopyFrom(packet->data, packet->size,
- side_data.data(), side_data.size());
- } else {
-- size_t side_data_size = 0;
-+ int side_data_size = 0;
- uint8_t* side_data = av_packet_get_side_data(
- packet.get(), AV_PKT_DATA_MATROSKA_BLOCKADDITIONAL, &side_data_size);
-
-@@ -504,7 +504,7 @@ void FFmpegDemuxerStream::EnqueuePacket(ScopedAVPacket packet) {
- packet->size - data_offset);
- }
-
-- size_t skip_samples_size = 0;
-+ int skip_samples_size = 0;
- const uint32_t* skip_samples_ptr =
- reinterpret_cast<const uint32_t*>(av_packet_get_side_data(
- packet.get(), AV_PKT_DATA_SKIP_SAMPLES, &skip_samples_size));
diff --git a/srcpkgs/chromium/patches/ffmpeg5.patch b/srcpkgs/chromium/patches/ffmpeg5.patch
new file mode 100644
index 000000000000..24e2da38e34c
--- /dev/null
+++ b/srcpkgs/chromium/patches/ffmpeg5.patch
@@ -0,0 +1,47 @@
+--- a/media/filters/ffmpeg_demuxer.cc 2023-01-23 17:33:57.366213805 +0200
++++ b/media/filters/ffmpeg_demuxer.cc 2023-01-23 17:43:09.283436983 +0200
+@@ -92,24 +92,12 @@
+
+ static base::TimeDelta ExtractStartTime(AVStream* stream) {
+ // The default start time is zero.
+- base::TimeDelta start_time;
++ base::TimeDelta start_time = kNoTimestamp;
+
+ // First try to use the |start_time| value as is.
+- if (stream->start_time != kNoFFmpegTimestamp)
++ if (stream->start_time != kNoFFmpegTimestamp) // AV_NOPTS_VALUE
+ start_time = ConvertFromTimeBase(stream->time_base, stream->start_time);
+
+- // Next try to use the first DTS value, for codecs where we know PTS == DTS
+- // (excludes all H26x codecs). The start time must be returned in PTS.
+- if (av_stream_get_first_dts(stream) != kNoFFmpegTimestamp &&
+- stream->codecpar->codec_id != AV_CODEC_ID_HEVC &&
+- stream->codecpar->codec_id != AV_CODEC_ID_H264 &&
+- stream->codecpar->codec_id != AV_CODEC_ID_MPEG4) {
+- const base::TimeDelta first_pts =
+- ConvertFromTimeBase(stream->time_base, av_stream_get_first_dts(stream));
+- if (first_pts < start_time)
+- start_time = first_pts;
+- }
+-
+ return start_time;
+ }
+
+@@ -1597,7 +1585,7 @@
+ for (const auto& stream : streams_) {
+ if (!stream || stream->IsEnabled() != enabled)
+ continue;
+- if (av_stream_get_first_dts(stream->av_stream()) == kInvalidPTSMarker)
++ if (stream->av_stream()->start_time == AV_NOPTS_VALUE)
+ continue;
+ if (!lowest_start_time_stream ||
+ stream->start_time() < lowest_start_time_stream->start_time()) {
+@@ -1618,7 +1606,7 @@
+ if (stream->type() != DemuxerStream::VIDEO)
+ continue;
+
+- if (av_stream_get_first_dts(stream->av_stream()) == kInvalidPTSMarker)
++ if (stream->av_stream()->start_time == AV_NOPTS_VALUE)
+ continue;
+
+ if (!stream->IsEnabled())
diff --git a/srcpkgs/chromium/template b/srcpkgs/chromium/template
index e50c739d3ee7..8705f2ef973f 100644
--- a/srcpkgs/chromium/template
+++ b/srcpkgs/chromium/template
@@ -2,7 +2,7 @@
pkgname=chromium
# See https://chromiumdash.appspot.com/releases?platform=Linux for the latest version
version=112.0.5615.49
-revision=1
+revision=2
archs="i686* x86_64* aarch64* armv7l*"
hostmakedepends="
$(vopt_if clang "clang lld llvm15")
From 896ee3463a55901c7c6c1aac5258f8fa49e13295 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:46 -0400
Subject: [PATCH 027/140] cmus: revbump for ffmpeg-6.0
---
srcpkgs/cmus/patches/ffmpeg6.patch | 12 ++++++++++++
srcpkgs/cmus/template | 2 +-
2 files changed, 13 insertions(+), 1 deletion(-)
create mode 100644 srcpkgs/cmus/patches/ffmpeg6.patch
diff --git a/srcpkgs/cmus/patches/ffmpeg6.patch b/srcpkgs/cmus/patches/ffmpeg6.patch
new file mode 100644
index 000000000000..ffa95ab81110
--- /dev/null
+++ b/srcpkgs/cmus/patches/ffmpeg6.patch
@@ -0,0 +1,12 @@
+--- a/ip/ffmpeg.c
++++ b/ip/ffmpeg.c
+@@ -202,9 +202,6 @@ static int ffmpeg_open(struct input_plugin_data *ip_data)
+ break;
+ }
+
+- if (codec->capabilities & AV_CODEC_CAP_TRUNCATED)
+- cc->flags |= AV_CODEC_FLAG_TRUNCATED;
+-
+ if (avcodec_open2(cc, codec, NULL) < 0) {
+ d_print("could not open codec: %d, %s\n", cc->codec_id, avcodec_get_name(cc->codec_id));
+ err = -IP_ERROR_UNSUPPORTED_FILE_TYPE;
diff --git a/srcpkgs/cmus/template b/srcpkgs/cmus/template
index 0fcb424ce336..05b77d0fecae 100644
--- a/srcpkgs/cmus/template
+++ b/srcpkgs/cmus/template
@@ -1,7 +1,7 @@
# Template file for 'cmus'
pkgname=cmus
version=2.10.0
-revision=1
+revision=2
build_style=configure
configure_args="prefix=/usr LD=$CC"
hostmakedepends="pkg-config"
From 49941a66bd74a643b03290a573a7b181a61157f5 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:46 -0400
Subject: [PATCH 028/140] cyanrip: revbump for ffmpeg-6.0
---
srcpkgs/cyanrip/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/cyanrip/template b/srcpkgs/cyanrip/template
index 9796e3461601..5db30e020d17 100644
--- a/srcpkgs/cyanrip/template
+++ b/srcpkgs/cyanrip/template
@@ -1,7 +1,7 @@
# Template file for 'cyanrip'
pkgname=cyanrip
version=0.9.0
-revision=1
+revision=2
build_style=meson
hostmakedepends="pkg-config"
makedepends="ffmpeg-devel libcdio-devel libcdio-paranoia-devel libcurl-devel libmusicbrainz5-devel"
From cfe9a27590ddc6a5bb1b9e294d76f074ebb0cca0 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:46 -0400
Subject: [PATCH 029/140] deadbeef: revbump for ffmpeg4-4.4.3
---
srcpkgs/deadbeef/template | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/srcpkgs/deadbeef/template b/srcpkgs/deadbeef/template
index b664bb1b9bd9..165b3c7b9cad 100644
--- a/srcpkgs/deadbeef/template
+++ b/srcpkgs/deadbeef/template
@@ -1,14 +1,14 @@
# Template file for 'deadbeef'
pkgname=deadbeef
version=1.8.8
-revision=1
+revision=2
create_wrksrc=yes
build_style=gnu-configure
configure_args="--disable-oss --disable-lfm --disable-notify --disable-gtk2"
hostmakedepends="automake libtool gettext gettext-devel intltool pkg-config
yasm clang glib-devel"
makedepends="
- alsa-lib-devel dbus-devel faad2-devel ffmpeg-devel gtk+3-devel imlib2-devel
+ alsa-lib-devel dbus-devel faad2-devel ffmpeg4-devel gtk+3-devel imlib2-devel
jansson-devel libcddb-devel libcdio-devel libcurl-devel libflac-devel
libmad-devel libpng-devel libsamplerate-devel libsndfile-devel libvorbis-devel
libzip-devel mpg123-devel opusfile-devel pulseaudio-devel wavpack-devel"
From e0d905a5fac0324504370f59e9be401db7d5b3bb Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:46 -0400
Subject: [PATCH 030/140] dolphin-emu: revbump for ffmpeg-6.0
---
srcpkgs/dolphin-emu/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/dolphin-emu/template b/srcpkgs/dolphin-emu/template
index 7ea197ceb2a8..7aeb0a5b645e 100644
--- a/srcpkgs/dolphin-emu/template
+++ b/srcpkgs/dolphin-emu/template
@@ -1,7 +1,7 @@
# Template file for 'dolphin-emu'
pkgname=dolphin-emu
version=5.0.16101
-revision=1
+revision=2
_dolphin_commit=8ecfa537a242de74d2e372e30d9d79b14584b2fb
_mgba_commit=40d4c430fc36caeb7ea32fd39624947ed487d2f2
#Version/hash pair can be found at https://dolphin-emu.org/download/
From 7f368372b0a37992f33586451b27e680017caf64 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:46 -0400
Subject: [PATCH 031/140] droidcam-obs-plugin: revbump for ffmpeg-6.0
---
srcpkgs/droidcam-obs-plugin/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/droidcam-obs-plugin/template b/srcpkgs/droidcam-obs-plugin/template
index fc9c9bf6b9d5..fb0480754df4 100644
--- a/srcpkgs/droidcam-obs-plugin/template
+++ b/srcpkgs/droidcam-obs-plugin/template
@@ -1,7 +1,7 @@
# Template file for 'droidcam-obs-plugin'
pkgname=droidcam-obs-plugin
version=2.0.1
-revision=1
+revision=2
build_style=gnu-makefile
make_use_env=yes
make_build_args="ALLOW_STATIC=no"
From c1f67c71ba9baa4e302567e35821387bdf282fcb Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:46 -0400
Subject: [PATCH 032/140] droidcam: revbump for ffmpeg-6.0
---
srcpkgs/droidcam/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/droidcam/template b/srcpkgs/droidcam/template
index 1c3f1b8b1fc6..32a9220b79a4 100644
--- a/srcpkgs/droidcam/template
+++ b/srcpkgs/droidcam/template
@@ -1,7 +1,7 @@
# Template file for 'droidcam'
pkgname=droidcam
version=1.8.2
-revision=2
+revision=3
build_style=gnu-makefile
make_build_args="USBMUXD=-lusbmuxd-2.0 JPEG=-lturbojpeg"
hostmakedepends="pkg-config"
From c86d7439a778ef3ac904490276eb79f0771f53a4 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:46 -0400
Subject: [PATCH 033/140] electron19: revbump for ffmpeg-6.0
---
srcpkgs/electron19/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/electron19/template b/srcpkgs/electron19/template
index 068136be7623..32ce301e730c 100644
--- a/srcpkgs/electron19/template
+++ b/srcpkgs/electron19/template
@@ -1,7 +1,7 @@
# Template file for 'electron19'
pkgname=electron19
version=19.0.8
-revision=2
+revision=3
_nodever=16.14.2
_chromiumver=102.0.5005.125
archs="x86_64* aarch64* ppc64le*"
From 0e91a31d5e892b8d03857bbc0769be09314be4c2 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:47 -0400
Subject: [PATCH 034/140] ffmpegthumbnailer: revbump for ffmpeg4-4.4.3
---
srcpkgs/ffmpegthumbnailer/template | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/srcpkgs/ffmpegthumbnailer/template b/srcpkgs/ffmpegthumbnailer/template
index 039eea7622b3..8546bef3e868 100644
--- a/srcpkgs/ffmpegthumbnailer/template
+++ b/srcpkgs/ffmpegthumbnailer/template
@@ -1,16 +1,16 @@
# Template file for 'ffmpegthumbnailer'
pkgname=ffmpegthumbnailer
version=2.2.2
-revision=1
+revision=2
build_style=cmake
hostmakedepends="pkg-config"
-makedepends="libpng-devel libjpeg-turbo-devel ffmpeg-devel"
-depends="ffmpeg"
+makedepends="libpng-devel libjpeg-turbo-devel ffmpeg4-devel"
+depends="ffmpeg4"
short_desc="Lightweight video thumbnailer"
maintainer="Orphaned <orphan@voidlinux.org>"
license="GPL-2.0-or-later"
-homepage="https://github.com/dirkvdb/${pkgname}"
-distfiles="${homepage}/releases/download/${version}/${pkgname}-${version}.tar.bz2"
+homepage="https://github.com/dirkvdb"
+distfiles="${homepage}/${pkgname}/releases/download/${version}/${pkgname}-${version}.tar.bz2"
checksum=1cb24059c38223f657b300c84dd80491b7040d4b69471c4fea69be862bc99b5b
post_install() {
From b398f64c5d68da8602a69df88ff41f0d1fbaeeec Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:47 -0400
Subject: [PATCH 035/140] ffmpegthumbs: revbump for ffmpeg4-4.4.3
---
srcpkgs/ffmpegthumbs/template | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/srcpkgs/ffmpegthumbs/template b/srcpkgs/ffmpegthumbs/template
index 5f0b9414dada..944a78fbc96c 100644
--- a/srcpkgs/ffmpegthumbs/template
+++ b/srcpkgs/ffmpegthumbs/template
@@ -1,11 +1,11 @@
# Template file for 'ffmpegthumbs'
pkgname=ffmpegthumbs
version=22.12.1
-revision=1
+revision=2
build_style=cmake
hostmakedepends="extra-cmake-modules kcoreaddons kconfig-devel
pkg-config qt5-host-tools qt5-qmake gettext"
-makedepends="qt5-devel kio-devel ffmpeg-devel taglib-devel"
+makedepends="qt5-devel kio-devel ffmpeg4-devel taglib-devel"
short_desc="FFmpeg-based thumbnail creator for video files"
maintainer="Michael Straube <straubem@gmx.de>"
license="GPL-2.0-or-later"
From b15f02b9b062bacc8822f960111d558f1db98500 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:47 -0400
Subject: [PATCH 036/140] ffms2: revbump for ffmpeg-6.0
---
srcpkgs/ffms2/patches/ffmpeg5.patch | 424 ++++++++++++++++++++++++++++
srcpkgs/ffms2/template | 2 +-
2 files changed, 425 insertions(+), 1 deletion(-)
create mode 100644 srcpkgs/ffms2/patches/ffmpeg5.patch
diff --git a/srcpkgs/ffms2/patches/ffmpeg5.patch b/srcpkgs/ffms2/patches/ffmpeg5.patch
new file mode 100644
index 000000000000..1479fabcafcb
--- /dev/null
+++ b/srcpkgs/ffms2/patches/ffmpeg5.patch
@@ -0,0 +1,424 @@
+From 45673149e9a2f5586855ad472e3059084eaa36b1 Mon Sep 17 00:00:00 2001
+From: Derek Buitenhuis <derek.buitenhuis@gmail.com>
+Date: Tue, 4 May 2021 14:41:21 +0100
+Subject: [PATCH] Use auto for AVCodec
+
+The geniuses over at FFmpeg decided to constify this API, so old
+versions of the library will return AVCodec *, while new versions
+of the libary will return const AVCodec *, which, in C++, are not
+OK to convert between.
+
+Rather than use some macro hell in ffmscompat.h, we can work around
+this by using auto.
+
+Gross.
+
+Signed-off-by: Derek Buitenhuis <derek.buitenhuis@gmail.com>
+---
+ src/core/audiosource.cpp | 2 +-
+ src/core/indexing.cpp | 6 +++---
+ src/core/videosource.cpp | 2 +-
+ 3 files changed, 5 insertions(+), 5 deletions(-)
+
+diff --git a/src/core/audiosource.cpp b/src/core/audiosource.cpp
+index e4ce97c..ac09666 100644
+--- a/src/core/audiosource.cpp
++++ b/src/core/audiosource.cpp
+@@ -469,7 +469,7 @@ void FFMS_AudioSource::OpenFile() {
+
+ LAVFOpenFile(SourceFile.c_str(), FormatContext, TrackNumber);
+
+- AVCodec *Codec = avcodec_find_decoder(FormatContext->streams[TrackNumber]->codecpar->codec_id);
++ auto *Codec = avcodec_find_decoder(FormatContext->streams[TrackNumber]->codecpar->codec_id);
+ if (Codec == nullptr)
+ throw FFMS_Exception(FFMS_ERROR_DECODING, FFMS_ERROR_CODEC,
+ "Audio codec not found");
+diff --git a/src/core/indexing.cpp b/src/core/indexing.cpp
+index e547c5a..59fb4e8 100644
+--- a/src/core/indexing.cpp
++++ b/src/core/indexing.cpp
+@@ -384,7 +384,7 @@ FFMS_TrackType FFMS_Indexer::GetTrackType(int Track) {
+ }
+
+ const char *FFMS_Indexer::GetTrackCodec(int Track) {
+- AVCodec *codec = avcodec_find_decoder(FormatContext->streams[Track]->codecpar->codec_id);
++ auto *codec = avcodec_find_decoder(FormatContext->streams[Track]->codecpar->codec_id);
+ return codec ? codec->name : nullptr;
+ }
+
+@@ -402,7 +402,7 @@ FFMS_Index *FFMS_Indexer::DoIndexing() {
+ UseDTS);
+
+ if (IndexMask.count(i) && FormatContext->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
+- AVCodec *VideoCodec = avcodec_find_decoder(FormatContext->streams[i]->codecpar->codec_id);
++ auto *VideoCodec = avcodec_find_decoder(FormatContext->streams[i]->codecpar->codec_id);
+ if (!VideoCodec) {
+ FormatContext->streams[i]->discard = AVDISCARD_ALL;
+ IndexMask.erase(i);
+@@ -433,7 +433,7 @@ FFMS_Index *FFMS_Indexer::DoIndexing() {
+ IndexMask.insert(i);
+ }
+ } else if (IndexMask.count(i) && FormatContext->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) {
+- AVCodec *AudioCodec = avcodec_find_decoder(FormatContext->streams[i]->codecpar->codec_id);
++ auto *AudioCodec = avcodec_find_decoder(FormatContext->streams[i]->codecpar->codec_id);
+ if (AudioCodec == nullptr)
+ throw FFMS_Exception(FFMS_ERROR_CODEC, FFMS_ERROR_UNSUPPORTED,
+ "Audio codec not found");
+diff --git a/src/core/videosource.cpp b/src/core/videosource.cpp
+index b889970..8956c22 100644
+--- a/src/core/videosource.cpp
++++ b/src/core/videosource.cpp
+@@ -171,7 +171,7 @@ FFMS_VideoSource::FFMS_VideoSource(const char *SourceFile, FFMS_Index &Index, in
+
+ LAVFOpenFile(SourceFile, FormatContext, VideoTrack);
+
+- AVCodec *Codec = avcodec_find_decoder(FormatContext->streams[VideoTrack]->codecpar->codec_id);
++ auto *Codec = avcodec_find_decoder(FormatContext->streams[VideoTrack]->codecpar->codec_id);
+ if (Codec == nullptr)
+ throw FFMS_Exception(FFMS_ERROR_DECODING, FFMS_ERROR_CODEC,
+ "Video codec not found");
+--
+2.40.0
+
+From 96cbf38ea9381829a1314f432a2c60495dcefaad Mon Sep 17 00:00:00 2001
+From: Derek Buitenhuis <derek.buitenhuis@gmail.com>
+Date: Tue, 4 May 2021 14:12:41 +0100
+Subject: [PATCH] all: Update AVPacket API usage
+
+AVPackets must all be on the heap now, since it is no longer
+part of the libav* ABI.
+
+Signed-off-by: Derek Buitenhuis <derek.buitenhuis@gmail.com>
+---
+ src/core/audiosource.cpp | 16 ++++++----
+ src/core/indexing.cpp | 63 ++++++++++++++++++++++------------------
+ src/core/indexing.h | 4 +--
+ src/core/utils.cpp | 6 ----
+ src/core/utils.h | 1 -
+ src/core/videosource.cpp | 30 ++++++++++---------
+ 6 files changed, 64 insertions(+), 56 deletions(-)
+
+diff --git a/src/core/audiosource.cpp b/src/core/audiosource.cpp
+index 37cf9ae..e4ce97c 100644
+--- a/src/core/audiosource.cpp
++++ b/src/core/audiosource.cpp
+@@ -285,10 +285,15 @@ FFMS_AudioSource::AudioBlock *FFMS_AudioSource::CacheBlock(CacheIterator &pos) {
+ int FFMS_AudioSource::DecodeNextBlock(CacheIterator *pos) {
+ CurrentFrame = &Frames[PacketNumber];
+
+- AVPacket Packet;
+- if (!ReadPacket(&Packet))
++ AVPacket *Packet = av_packet_alloc();
++ if (!Packet)
++ throw FFMS_Exception(FFMS_ERROR_PARSER, FFMS_ERROR_ALLOCATION_FAILED,
++ "Could not allocate packet.");
++ if (!ReadPacket(Packet)) {
++ av_packet_free(&Packet);
+ throw FFMS_Exception(FFMS_ERROR_PARSER, FFMS_ERROR_UNKNOWN,
+ "ReadPacket unexpectedly failed to read a packet");
++ }
+
+ // ReadPacket may have changed the packet number
+ CurrentFrame = &Frames[PacketNumber];
+@@ -297,8 +302,9 @@ int FFMS_AudioSource::DecodeNextBlock(CacheIterator *pos) {
+ int NumberOfSamples = 0;
+ AudioBlock *CachedBlock = nullptr;
+
+- int Ret = avcodec_send_packet(CodecContext, &Packet);
+- av_packet_unref(&Packet);
++ int Ret = avcodec_send_packet(CodecContext, Packet);
++ av_packet_unref(Packet);
++ av_packet_free(&Packet);
+
+ av_frame_unref(DecodeFrame);
+ Ret = avcodec_receive_frame(CodecContext, DecodeFrame);
+@@ -513,8 +519,6 @@ void FFMS_AudioSource::Seek() {
+ }
+
+ bool FFMS_AudioSource::ReadPacket(AVPacket *Packet) {
+- InitNullPacket(*Packet);
+-
+ while (av_read_frame(FormatContext, Packet) >= 0) {
+ if (Packet->stream_index == TrackNumber) {
+ // Required because not all audio packets, especially in ogg, have a pts. Use the previous valid packet's pts instead.
+diff --git a/src/core/indexing.cpp b/src/core/indexing.cpp
+index 23fb95b..e547c5a 100644
+--- a/src/core/indexing.cpp
++++ b/src/core/indexing.cpp
+@@ -320,7 +320,7 @@ void FFMS_Indexer::CheckAudioProperties(int Track, AVCodecContext *Context) {
+ }
+ }
+
+-void FFMS_Indexer::ParseVideoPacket(SharedAVContext &VideoContext, AVPacket &pkt, int *RepeatPict,
++void FFMS_Indexer::ParseVideoPacket(SharedAVContext &VideoContext, AVPacket *pkt, int *RepeatPict,
+ int *FrameType, bool *Invisible, enum AVPictureStructure *LastPicStruct) {
+ if (VideoContext.Parser) {
+ uint8_t *OB;
+@@ -330,8 +330,8 @@ void FFMS_Indexer::ParseVideoPacket(SharedAVContext &VideoContext, AVPacket &pkt
+ av_parser_parse2(VideoContext.Parser,
+ VideoContext.CodecContext,
+ &OB, &OBSize,
+- pkt.data, pkt.size,
+- pkt.pts, pkt.dts, pkt.pos);
++ pkt->data, pkt->size,
++ pkt->pts, pkt->dts, pkt->pos);
+
+ // H.264 (PAFF) and HEVC may have one field per packet, so we need to track
+ // when we have a full or half frame available, and mark one of them as
+@@ -351,15 +351,15 @@ void FFMS_Indexer::ParseVideoPacket(SharedAVContext &VideoContext, AVPacket &pkt
+
+ *RepeatPict = VideoContext.Parser->repeat_pict;
+ *FrameType = VideoContext.Parser->pict_type;
+- *Invisible = (IncompleteFrame || VideoContext.Parser->repeat_pict < 0 || (pkt.flags & AV_PKT_FLAG_DISCARD));
++ *Invisible = (IncompleteFrame || VideoContext.Parser->repeat_pict < 0 || (pkt->flags & AV_PKT_FLAG_DISCARD));
+ } else {
+- *Invisible = !!(pkt.flags & AV_PKT_FLAG_DISCARD);
++ *Invisible = !!(pkt->flags & AV_PKT_FLAG_DISCARD);
+ }
+
+ if (VideoContext.CodecContext->codec_id == AV_CODEC_ID_VP8)
+- ParseVP8(pkt.data[0], Invisible, FrameType);
++ ParseVP8(pkt->data[0], Invisible, FrameType);
+ else if (VideoContext.CodecContext->codec_id == AV_CODEC_ID_VP9)
+- ParseVP9(pkt.data[0], Invisible, FrameType);
++ ParseVP9(pkt->data[0], Invisible, FrameType);
+ }
+
+ void FFMS_Indexer::Free() {
+@@ -458,32 +458,36 @@ FFMS_Index *FFMS_Indexer::DoIndexing() {
+ }
+ }
+
+- AVPacket Packet;
+- InitNullPacket(Packet);
++ AVPacket *Packet = av_packet_alloc();
++ if (!Packet)
++ throw FFMS_Exception(FFMS_ERROR_CODEC, FFMS_ERROR_ALLOCATION_FAILED,
++ "Could not allocate packet.");
+ std::vector<int64_t> LastValidTS(FormatContext->nb_streams, AV_NOPTS_VALUE);
+
+ int64_t filesize = avio_size(FormatContext->pb);
+ enum AVPictureStructure LastPicStruct = AV_PICTURE_STRUCTURE_UNKNOWN;
+- while (av_read_frame(FormatContext, &Packet) >= 0) {
++ while (av_read_frame(FormatContext, Packet) >= 0) {
+ // Update progress
+ // FormatContext->pb can apparently be NULL when opening images.
+ if (IC && FormatContext->pb) {
+- if ((*IC)(FormatContext->pb->pos, filesize, ICPrivate))
++ if ((*IC)(FormatContext->pb->pos, filesize, ICPrivate)) {
++ av_packet_free(&Packet);
+ throw FFMS_Exception(FFMS_ERROR_CANCELLED, FFMS_ERROR_USER,
+ "Cancelled by user");
++ }
+ }
+- if (!IndexMask.count(Packet.stream_index)) {
+- av_packet_unref(&Packet);
++ if (!IndexMask.count(Packet->stream_index)) {
++ av_packet_unref(Packet);
+ continue;
+ }
+
+- int Track = Packet.stream_index;
++ int Track = Packet->stream_index;
+ FFMS_Track &TrackInfo = (*TrackIndices)[Track];
+- bool KeyFrame = !!(Packet.flags & AV_PKT_FLAG_KEY);
++ bool KeyFrame = !!(Packet->flags & AV_PKT_FLAG_KEY);
+ ReadTS(Packet, LastValidTS[Track], (*TrackIndices)[Track].UseDTS);
+
+ if (FormatContext->streams[Track]->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
+- int64_t PTS = TrackInfo.UseDTS ? Packet.dts : Packet.pts;
++ int64_t PTS = TrackInfo.UseDTS ? Packet->dts : Packet->pts;
+ if (PTS == AV_NOPTS_VALUE) {
+ // VPx alt-refs are output as packets which lack timestmps or durations, since
+ // they are invisible. Currently, the timestamp mangling code in libavformat
+@@ -495,9 +499,11 @@ FFMS_Index *FFMS_Indexer::DoIndexing() {
+ // FFMS2 currently sorts packets by PTS, which will break decoding, otherwise.
+ bool HasAltRefs = (FormatContext->streams[Track]->codecpar->codec_id == AV_CODEC_ID_VP8 ||
+ FormatContext->streams[Track]->codecpar->codec_id == AV_CODEC_ID_VP9);
+- if (Packet.duration == 0 && !HasAltRefs)
++ if (Packet->duration == 0 && !HasAltRefs) {
++ av_packet_free(&Packet);
+ throw FFMS_Exception(FFMS_ERROR_INDEXING, FFMS_ERROR_PARSER,
+ "Invalid packet pts, dts, and duration");
++ }
+
+ if (TrackInfo.empty())
+ PTS = 0;
+@@ -513,7 +519,7 @@ FFMS_Index *FFMS_Indexer::DoIndexing() {
+ ParseVideoPacket(AVContexts[Track], Packet, &RepeatPict, &FrameType, &Invisible, &LastPicStruct);
+
+ TrackInfo.AddVideoFrame(PTS, RepeatPict, KeyFrame,
+- FrameType, Packet.pos, Invisible);
++ FrameType, Packet->pos, Invisible);
+ } else if (FormatContext->streams[Track]->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) {
+ // For video seeking timestamps are used only if all packets have
+ // timestamps, while for audio they're used if any have timestamps,
+@@ -522,28 +528,29 @@ FFMS_Index *FFMS_Indexer::DoIndexing() {
+ TrackInfo.HasTS = true;
+
+ int64_t StartSample = AVContexts[Track].CurrentSample;
+- uint32_t SampleCount = IndexAudioPacket(Track, &Packet, AVContexts[Track], *TrackIndices);
++ uint32_t SampleCount = IndexAudioPacket(Track, Packet, AVContexts[Track], *TrackIndices);
+ TrackInfo.SampleRate = AVContexts[Track].CodecContext->sample_rate;
+
+ TrackInfo.AddAudioFrame(LastValidTS[Track],
+- StartSample, SampleCount, KeyFrame, Packet.pos, Packet.flags & AV_PKT_FLAG_DISCARD);
++ StartSample, SampleCount, KeyFrame, Packet->pos, Packet->flags & AV_PKT_FLAG_DISCARD);
+ }
+
+- if (!(Packet.flags & AV_PKT_FLAG_DISCARD))
+- TrackInfo.LastDuration = Packet.duration;
++ if (!(Packet->flags & AV_PKT_FLAG_DISCARD))
++ TrackInfo.LastDuration = Packet->duration;
+
+- av_packet_unref(&Packet);
++ av_packet_unref(Packet);
+ }
++ av_packet_free(&Packet);
+
+ TrackIndices->Finalize(AVContexts, FormatContext->iformat->name);
+ return TrackIndices.release();
+ }
+
+-void FFMS_Indexer::ReadTS(const AVPacket &Packet, int64_t &TS, bool &UseDTS) {
+- if (!UseDTS && Packet.pts != AV_NOPTS_VALUE)
+- TS = Packet.pts;
++void FFMS_Indexer::ReadTS(const AVPacket *Packet, int64_t &TS, bool &UseDTS) {
++ if (!UseDTS && Packet->pts != AV_NOPTS_VALUE)
++ TS = Packet->pts;
+ if (TS == AV_NOPTS_VALUE)
+ UseDTS = true;
+- if (UseDTS && Packet.dts != AV_NOPTS_VALUE)
+- TS = Packet.dts;
++ if (UseDTS && Packet->dts != AV_NOPTS_VALUE)
++ TS = Packet->dts;
+ }
+diff --git a/src/core/indexing.h b/src/core/indexing.h
+index 3cfc3c3..5c06868 100644
+--- a/src/core/indexing.h
++++ b/src/core/indexing.h
+@@ -80,10 +80,10 @@ private:
+ int64_t Filesize;
+ uint8_t Digest[20];
+
+- void ReadTS(const AVPacket &Packet, int64_t &TS, bool &UseDTS);
++ void ReadTS(const AVPacket *Packet, int64_t &TS, bool &UseDTS);
+ void CheckAudioProperties(int Track, AVCodecContext *Context);
+ uint32_t IndexAudioPacket(int Track, AVPacket *Packet, SharedAVContext &Context, FFMS_Index &TrackIndices);
+- void ParseVideoPacket(SharedAVContext &VideoContext, AVPacket &pkt, int *RepeatPict, int *FrameType, bool *Invisible, enum AVPictureStructure *LastPicStruct);
++ void ParseVideoPacket(SharedAVContext &VideoContext, AVPacket *pkt, int *RepeatPict, int *FrameType, bool *Invisible, enum AVPictureStructure *LastPicStruct);
+ void Free();
+ public:
+ FFMS_Indexer(const char *Filename);
+diff --git a/src/core/utils.cpp b/src/core/utils.cpp
+index ce67533..8a2e997 100644
+--- a/src/core/utils.cpp
++++ b/src/core/utils.cpp
+@@ -62,12 +62,6 @@ void ClearErrorInfo(FFMS_ErrorInfo *ErrorInfo) {
+ }
+ }
+
+-void InitNullPacket(AVPacket &pkt) {
+- av_init_packet(&pkt);
+- pkt.data = nullptr;
+- pkt.size = 0;
+-}
+-
+ void FillAP(FFMS_AudioProperties &AP, AVCodecContext *CTX, FFMS_Track &Frames) {
+ AP.SampleFormat = static_cast<FFMS_SampleFormat>(av_get_packed_sample_fmt(CTX->sample_fmt));
+ AP.BitsPerSample = av_get_bytes_per_sample(CTX->sample_fmt) * 8;
+diff --git a/src/core/utils.h b/src/core/utils.h
+index 9819dc7..003ab79 100644
+--- a/src/core/utils.h
++++ b/src/core/utils.h
+@@ -58,7 +58,6 @@ std::unique_ptr<T> make_unique(Args&&... args) {
+ }
+
+ void ClearErrorInfo(FFMS_ErrorInfo *ErrorInfo);
+-void InitNullPacket(AVPacket &pkt);
+ void FillAP(FFMS_AudioProperties &AP, AVCodecContext *CTX, FFMS_Track &Frames);
+
+ void LAVFOpenFile(const char *SourceFile, AVFormatContext *&FormatContext, int Track);
+diff --git a/src/core/videosource.cpp b/src/core/videosource.cpp
+index 06bd161..b889970 100644
+--- a/src/core/videosource.cpp
++++ b/src/core/videosource.cpp
+@@ -673,30 +673,34 @@ void FFMS_VideoSource::DecodeNextFrame(int64_t &AStartTime, int64_t &Pos) {
+ if (HasPendingDelayedFrames())
+ return;
+
+- AVPacket Packet;
+- InitNullPacket(Packet);
+-
+- while (ReadFrame(&Packet) >= 0) {
+- if (Packet.stream_index != VideoTrack) {
+- av_packet_unref(&Packet);
++ AVPacket *Packet = av_packet_alloc();
++ if (!Packet)
++ throw FFMS_Exception(FFMS_ERROR_DECODING, FFMS_ERROR_ALLOCATION_FAILED,
++ "Could not allocate packet.");
++
++ while (ReadFrame(Packet) >= 0) {
++ if (Packet->stream_index != VideoTrack) {
++ av_packet_unref(Packet);
+ continue;
+ }
+
+ if (AStartTime < 0)
+- AStartTime = Frames.UseDTS ? Packet.dts : Packet.pts;
++ AStartTime = Frames.UseDTS ? Packet->dts : Packet->pts;
+
+ if (Pos < 0)
+- Pos = Packet.pos;
++ Pos = Packet->pos;
+
+- bool FrameFinished = DecodePacket(&Packet);
+- av_packet_unref(&Packet);
+- if (FrameFinished)
++ bool FrameFinished = DecodePacket(Packet);
++ av_packet_unref(Packet);
++ if (FrameFinished) {
++ av_packet_free(&Packet);
+ return;
++ }
+ }
+
+ // Flush final frames
+- InitNullPacket(Packet);
+- DecodePacket(&Packet);
++ DecodePacket(Packet);
++ av_packet_free(&Packet);
+ }
+
+ bool FFMS_VideoSource::SeekTo(int n, int SeekOffset) {
+--
+2.40.0
+
+From bf9e03e9e08534c024e5a744a6437c4aac160201 Mon Sep 17 00:00:00 2001
+From: Derek Buitenhuis <derek.buitenhuis@gmail.com>
+Date: Tue, 4 May 2021 14:20:47 +0100
+Subject: [PATCH 2/3] configure: Remove deprecated API use
+
+Signed-off-by: Derek Buitenhuis <derek.buitenhuis@gmail.com>
+---
+ configure.ac | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/configure.ac b/configure.ac
+index b35ef80bc..d19714d0f 100644
+--- a/configure.ac
++++ b/configure.ac
+@@ -102,10 +102,10 @@ CFLAGS="$_CFLAGS $FFMPEG_CFLAGS"
+
+ AC_DEFUN([TEST_FFMPEG],
+ [AC_LINK_IFELSE([AC_LANG_PROGRAM([[
+- #include <libavcodec/avcodec.h>
++ #include <libavformat/avformat.h>
+ #include <libswscale/swscale.h>
+ ]],[[
+- avcodec_register_all();
++ avformat_network_init();
+ swscale_version();
+ ]])], [eval $1=yes], [eval $1=no])
+ ])
+
diff --git a/srcpkgs/ffms2/template b/srcpkgs/ffms2/template
index 68e8a0c14bce..2acfadac44b3 100644
--- a/srcpkgs/ffms2/template
+++ b/srcpkgs/ffms2/template
@@ -1,7 +1,7 @@
# Template file for 'ffms2'
pkgname=ffms2
version=2.40
-revision=1
+revision=2
build_style=gnu-configure
configure_args="--enable-shared --disable-static"
hostmakedepends="pkg-config autoconf automake libtool"
From f8ba7182faafc779e42cdee475f3cdd8e0f97373 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:47 -0400
Subject: [PATCH 037/140] freerdp: revbump for ffmpeg-6.0
---
.../freerdp/patches/ffmpeg6_aa2cb9aa.patch | 42 +++++++++++++++++++
srcpkgs/freerdp/template | 2 +-
2 files changed, 43 insertions(+), 1 deletion(-)
create mode 100644 srcpkgs/freerdp/patches/ffmpeg6_aa2cb9aa.patch
diff --git a/srcpkgs/freerdp/patches/ffmpeg6_aa2cb9aa.patch b/srcpkgs/freerdp/patches/ffmpeg6_aa2cb9aa.patch
new file mode 100644
index 000000000000..a4324da3a882
--- /dev/null
+++ b/srcpkgs/freerdp/patches/ffmpeg6_aa2cb9aa.patch
@@ -0,0 +1,42 @@
+From aa2cb9aa5ff5562433598ba168a466e0752bca0e Mon Sep 17 00:00:00 2001
+From: akallabeth <akallabeth@posteo.net>
+Date: Tue, 14 Feb 2023 07:48:54 +0100
+Subject: [PATCH] Fixed #8686: Update h264 to use new FFMPEG API
+
+---
+ channels/tsmf/client/ffmpeg/tsmf_ffmpeg.c | 2 ++
+ libfreerdp/codec/h264_ffmpeg.c | 2 ++
+ 2 files changed, 4 insertions(+)
+
+diff --git a/channels/tsmf/client/ffmpeg/tsmf_ffmpeg.c b/channels/tsmf/client/ffmpeg/tsmf_ffmpeg.c
+index 339462d865f..beea80b7a1e 100644
+--- a/channels/tsmf/client/ffmpeg/tsmf_ffmpeg.c
++++ b/channels/tsmf/client/ffmpeg/tsmf_ffmpeg.c
+@@ -239,8 +239,10 @@ static BOOL tsmf_ffmpeg_init_stream(ITSMFDecoder* decoder, const TS_AM_MEDIA_TYP
+ }
+ }
+
++#if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(59, 18, 100)
+ if (mdecoder->codec->capabilities & AV_CODEC_CAP_TRUNCATED)
+ mdecoder->codec_context->flags |= AV_CODEC_FLAG_TRUNCATED;
++#endif
+
+ return TRUE;
+ }
+diff --git a/libfreerdp/codec/h264_ffmpeg.c b/libfreerdp/codec/h264_ffmpeg.c
+index 8a23db2473c..896a333019b 100644
+--- a/libfreerdp/codec/h264_ffmpeg.c
++++ b/libfreerdp/codec/h264_ffmpeg.c
+@@ -615,10 +615,12 @@ static BOOL libavcodec_init(H264_CONTEXT* h264)
+ goto EXCEPTION;
+ }
+
++#if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(59, 18, 100)
+ if (sys->codecDecoder->capabilities & AV_CODEC_CAP_TRUNCATED)
+ {
+ sys->codecDecoderContext->flags |= AV_CODEC_FLAG_TRUNCATED;
+ }
++#endif
+
+ #ifdef WITH_VAAPI
+
diff --git a/srcpkgs/freerdp/template b/srcpkgs/freerdp/template
index 25e8aa9677f0..4d51c8189902 100644
--- a/srcpkgs/freerdp/template
+++ b/srcpkgs/freerdp/template
@@ -1,7 +1,7 @@
# Template file for 'freerdp'
pkgname=freerdp
version=2.10.0
-revision=1
+revision=2
build_style=cmake
configure_args="-DWITH_ALSA=ON -DWITH_CUPS=OFF -DWITH_FFMPEG=ON
-DWITH_GSTREAMER_0_10=OFF -DWITH_GSTREAMER_1_0=OFF -DWITH_JPEG=ON
From 8a1cda0bcf5c5b610e68541ae240384bb4a1136f Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:47 -0400
Subject: [PATCH 038/140] gerbera: revbump for ffmpeg-6.0
---
srcpkgs/gerbera/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/gerbera/template b/srcpkgs/gerbera/template
index ae14f35c767c..2dc0ac0ce03b 100644
--- a/srcpkgs/gerbera/template
+++ b/srcpkgs/gerbera/template
@@ -1,7 +1,7 @@
# Template file for 'gerbera'
pkgname=gerbera
version=1.12.1
-revision=1
+revision=2
build_style=cmake
configure_args="-DWITH_SYSTEMD=0 -DWITH_AVCODEC=1"
hostmakedepends="pkg-config"
From 8d5de4c9cf5b975fe58c6f191c6aeadb07ff9597 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:47 -0400
Subject: [PATCH 039/140] goldendict: revbump for ffmpeg-6.0
---
srcpkgs/goldendict/patches/ffmpeg4.patch | 21 --
srcpkgs/goldendict/patches/ffmpeg5.patch | 232 +++++++++++++++++++++++
srcpkgs/goldendict/template | 2 +-
3 files changed, 233 insertions(+), 22 deletions(-)
delete mode 100644 srcpkgs/goldendict/patches/ffmpeg4.patch
create mode 100644 srcpkgs/goldendict/patches/ffmpeg5.patch
diff --git a/srcpkgs/goldendict/patches/ffmpeg4.patch b/srcpkgs/goldendict/patches/ffmpeg4.patch
deleted file mode 100644
index f045fa27f54b..000000000000
--- a/srcpkgs/goldendict/patches/ffmpeg4.patch
+++ /dev/null
@@ -1,21 +0,0 @@
---- a/ffmpegaudio.cc.orig 2018-05-09 22:16:13.480659958 +0200
-+++ b/ffmpegaudio.cc 2018-05-09 22:16:50.748322790 +0200
-@@ -143,7 +143,7 @@
- return false;
- }
-
-- unsigned char * avioBuffer = ( unsigned char * )av_malloc( kBufferSize + FF_INPUT_BUFFER_PADDING_SIZE );
-+ unsigned char * avioBuffer = ( unsigned char * )av_malloc( kBufferSize + AV_INPUT_BUFFER_PADDING_SIZE );
- if ( !avioBuffer )
- {
- errorString = QObject::tr( "av_malloc() failed." );
-@@ -380,7 +380,7 @@
- }
-
- if ( !Qt4x5::AtomicInt::loadAcquire( isCancelled_ ) &&
-- codecContext_->codec->capabilities & CODEC_CAP_DELAY )
-+ codecContext_->codec->capabilities & AV_CODEC_CAP_DELAY )
- {
- av_init_packet( &packet );
- int gotFrame = 0;
-
diff --git a/srcpkgs/goldendict/patches/ffmpeg5.patch b/srcpkgs/goldendict/patches/ffmpeg5.patch
new file mode 100644
index 000000000000..7cfc98ada368
--- /dev/null
+++ b/srcpkgs/goldendict/patches/ffmpeg5.patch
@@ -0,0 +1,232 @@
+From 03bbe01b79a1f07a6780cb60f23a087104c5d77b Mon Sep 17 00:00:00 2001
+From: Abs62 <ottomann@yandex.ru>
+Date: Fri, 30 Mar 2018 22:53:24 +0300
+Subject: [PATCH] Fix warnings while compile with FFMpeg 3.4.2 (issue #978)
+
+---
+ ffmpegaudio.cc | 68 +++++++++++++++++++++++++++++++++++++++++++++-----
+ 1 file changed, 62 insertions(+), 6 deletions(-)
+
+diff --git a/ffmpegaudio.cc b/ffmpegaudio.cc
+index ed1172bdd..56e8f788e 100644
+--- a/ffmpegaudio.cc
++++ b/ffmpegaudio.cc
+@@ -91,6 +91,7 @@ struct DecoderContext
+ QByteArray audioData_;
+ QDataStream audioDataStream_;
+ AVFormatContext * formatContext_;
++ AVCodec * codec_;
+ AVCodecContext * codecContext_;
+ AVIOContext * avioContext_;
+ AVStream * audioStream_;
+@@ -114,6 +115,7 @@ DecoderContext::DecoderContext( QByteArray const & audioData, QAtomicInt & isCan
+ audioData_( audioData ),
+ audioDataStream_( audioData_ ),
+ formatContext_( NULL ),
++ codec_( NULL ),
+ codecContext_( NULL ),
+ avioContext_( NULL ),
+ audioStream_( NULL ),
+@@ -143,7 +145,11 @@ bool DecoderContext::openCodec( QString & errorString )
+ return false;
+ }
+
++#if LIBAVCODEC_VERSION_MAJOR < 56 || ( LIBAVCODEC_VERSION_MAJOR == 56 && LIBAVCODEC_VERSION_MINOR < 56 )
+ unsigned char * avioBuffer = ( unsigned char * )av_malloc( kBufferSize + FF_INPUT_BUFFER_PADDING_SIZE );
++#else
++ unsigned char * avioBuffer = ( unsigned char * )av_malloc( kBufferSize + AV_INPUT_BUFFER_PADDING_SIZE );
++#endif
+ if ( !avioBuffer )
+ {
+ errorString = QObject::tr( "av_malloc() failed." );
+@@ -186,7 +192,11 @@ bool DecoderContext::openCodec( QString & errorString )
+ // Find audio stream, use the first audio stream if available
+ for ( unsigned i = 0; i < formatContext_->nb_streams; i++ )
+ {
++#if LIBAVCODEC_VERSION_MAJOR < 57 || ( LIBAVCODEC_VERSION_MAJOR == 57 && LIBAVCODEC_VERSION_MINOR < 33 )
+ if ( formatContext_->streams[i]->codec->codec_type == AVMEDIA_TYPE_AUDIO )
++#else
++ if ( formatContext_->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_AUDIO )
++#endif
+ {
+ audioStream_ = formatContext_->streams[i];
+ break;
+@@ -198,22 +208,38 @@ bool DecoderContext::openCodec( QString & errorString )
+ return false;
+ }
+
++#if LIBAVCODEC_VERSION_MAJOR < 57 || ( LIBAVCODEC_VERSION_MAJOR == 57 && LIBAVCODEC_VERSION_MINOR < 33 )
+ codecContext_ = audioStream_->codec;
+- AVCodec * codec = avcodec_find_decoder( codecContext_->codec_id );
+- if ( !codec )
++ codec_ = avcodec_find_decoder( codecContext_->codec_id );
++ if ( !codec_ )
+ {
+ errorString = QObject::tr( "Codec [id: %1] not found." ).arg( codecContext_->codec_id );
+ return false;
+ }
++#else
++ codec_ = avcodec_find_decoder( audioStream_->codecpar->codec_id );
++ if ( !codec_ )
++ {
++ errorString = QObject::tr( "Codec [id: %1] not found." ).arg( audioStream_->codecpar->codec_id );
++ return false;
++ }
++ codecContext_ = avcodec_alloc_context3( codec_ );
++ if ( !codecContext_ )
++ {
++ errorString = QObject::tr( "avcodec_alloc_context3() failed." );
++ return false;
++ }
++ avcodec_parameters_to_context( codecContext_, audioStream_->codecpar );
++#endif
+
+- ret = avcodec_open2( codecContext_, codec, NULL );
++ ret = avcodec_open2( codecContext_, codec_, NULL );
+ if ( ret < 0 )
+ {
+ errorString = QObject::tr( "avcodec_open2() failed: %1." ).arg( avErrorString( ret ) );
+ return false;
+ }
+
+- av_log( NULL, AV_LOG_INFO, "Codec open: %s: channels: %d, rate: %d, format: %s\n", codec->long_name,
++ av_log( NULL, AV_LOG_INFO, "Codec open: %s: channels: %d, rate: %d, format: %s\n", codec_->long_name,
+ codecContext_->channels, codecContext_->sample_rate, av_get_sample_fmt_name( codecContext_->sample_fmt ) );
+ return true;
+ }
+@@ -252,10 +278,13 @@ void DecoderContext::closeCodec()
+
+ // Closing a codec context without prior avcodec_open2() will result in
+ // a crash in ffmpeg
+- if ( audioStream_ && audioStream_->codec && audioStream_->codec->codec )
++ if ( audioStream_ && codecContext_ && codec_ )
+ {
+ audioStream_->discard = AVDISCARD_ALL;
+- avcodec_close( audioStream_->codec );
++ avcodec_close( codecContext_ );
++#if LIBAVCODEC_VERSION_MAJOR > 57 || ( LIBAVCODEC_VERSION_MAJOR == 57 && LIBAVCODEC_VERSION_MINOR >= 33 )
++ avcodec_free_context( &codecContext_ );
++#endif
+ }
+
+ avformat_close_input( &formatContext_ );
+@@ -356,6 +385,7 @@ bool DecoderContext::play( QString & errorString )
+ if ( packet.stream_index == audioStream_->index )
+ {
+ AVPacket pack = packet;
++#if LIBAVCODEC_VERSION_MAJOR < 57 || ( LIBAVCODEC_VERSION_MAJOR == 57 && LIBAVCODEC_VERSION_MINOR < 37 )
+ int gotFrame = 0;
+ do
+ {
+@@ -370,6 +400,19 @@ bool DecoderContext::play( QString & errorString )
+ pack.data += len;
+ }
+ while( pack.size > 0 );
++#else
++ int ret = avcodec_send_packet( codecContext_, &pack );
++ /* read all the output frames (in general there may be any number of them) */
++ while( ret >= 0 )
++ {
++ ret = avcodec_receive_frame( codecContext_, frame);
++
++ if ( Qt4x5::AtomicInt::loadAcquire( isCancelled_ ) || ret < 0 )
++ break;
++
++ playFrame( frame );
++ }
++#endif
+ }
+ // av_free_packet() must be called after each call to av_read_frame()
+ #if LIBAVCODEC_VERSION_MAJOR < 57 || ( LIBAVCODEC_VERSION_MAJOR == 57 && LIBAVCODEC_VERSION_MINOR < 7 )
+@@ -379,6 +422,7 @@ bool DecoderContext::play( QString & errorString )
+ #endif
+ }
+
++#if LIBAVCODEC_VERSION_MAJOR < 57 || ( LIBAVCODEC_VERSION_MAJOR == 57 && LIBAVCODEC_VERSION_MINOR < 37 )
+ if ( !Qt4x5::AtomicInt::loadAcquire( isCancelled_ ) &&
+ codecContext_->codec->capabilities & CODEC_CAP_DELAY )
+ {
+@@ -391,6 +435,18 @@ bool DecoderContext::play( QString & errorString )
+ playFrame( frame );
+ }
+ }
++#else
++ /* flush the decoder */
++ av_init_packet( &packet );
++ int ret = avcodec_send_packet(codecContext_, &packet );
++ while( ret >= 0 )
++ {
++ ret = avcodec_receive_frame(codecContext_, frame);
++ if ( Qt4x5::AtomicInt::loadAcquire( isCancelled_ ) || ret < 0 )
++ break;
++ playFrame( frame );
++ }
++#endif
+
+ #if LIBAVCODEC_VERSION_MAJOR < 54
+ av_free( frame );
+32
+srcpkgs/goldendict/patches/ffmpeg5-2.patch
+Comment on this file
+@@ -0,0 +1,32 @@
+From 966f4a8b78e6324b930e5a50f2bb930bd87e565e Mon Sep 17 00:00:00 2001
+From: Abs62 <ottomann@yandex.ru>
+Date: Fri, 27 Sep 2019 17:00:52 +0300
+Subject: [PATCH] FFmpeg player: Fix some crashes on broken files
+
+---
+ ffmpegaudio.cc | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/ffmpegaudio.cc b/ffmpegaudio.cc
+index 56e8f788e..415fc79cb 100644
+--- a/ffmpegaudio.cc
++++ b/ffmpegaudio.cc
+@@ -51,7 +51,9 @@ AudioService & AudioService::instance()
+
+ AudioService::AudioService()
+ {
++#if LIBAVFORMAT_VERSION_MAJOR < 58 || ( LIBAVFORMAT_VERSION_MAJOR == 58 && LIBAVFORMAT_VERSION_MINOR < 9 )
+ av_register_all();
++#endif
+ ao_initialize();
+ }
+
+@@ -438,6 +440,8 @@ bool DecoderContext::play( QString & errorString )
+ #else
+ /* flush the decoder */
+ av_init_packet( &packet );
++ packet.data = NULL;
++ packet.size = 0;
+ int ret = avcodec_send_packet(codecContext_, &packet );
+ while( ret >= 0 )
+ {
+25
+srcpkgs/goldendict/patches/ffmpeg5-3.patch
+Comment on this file
+@@ -0,0 +1,25 @@
+From 8acb288c9e9bdb3c6bf2e803954dd3b6ac273c05 Mon Sep 17 00:00:00 2001
+From: Liao Junxuan <mikeljx@126.com>
+Date: Sun, 20 Feb 2022 12:28:05 +0800
+Subject: [PATCH] add support for ffmpeg 5.0
+
+---
+ ffmpegaudio.cc | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/ffmpegaudio.cc b/ffmpegaudio.cc
+index d550f4a77..7948d2187 100644
+--- a/ffmpegaudio.cc
++++ b/ffmpegaudio.cc
+@@ -94,7 +94,11 @@ struct DecoderContext
+ QByteArray audioData_;
+ QDataStream audioDataStream_;
+ AVFormatContext * formatContext_;
++#if LIBAVCODEC_VERSION_MAJOR < 59
+ AVCodec * codec_;
++#else
++ const AVCodec * codec_;
++#endif
+ AVCodecContext * codecContext_;
+ AVIOContext * avioContext_;
+ AVStream * audioStream_;
diff --git a/srcpkgs/goldendict/template b/srcpkgs/goldendict/template
index 4544ae710ee6..2ca4185e538a 100644
--- a/srcpkgs/goldendict/template
+++ b/srcpkgs/goldendict/template
@@ -9,7 +9,7 @@ makedepends="tiff-devel qt5-devel libvorbis-devel zlib-devel
libXtst-devel hunspell-devel qt5-tools-devel qt5-declarative-devel
qt5-webkit-devel lzo-devel bzip2-devel libao-devel qt5-svg-devel
libeb-devel qt5-x11extras-devel ffmpeg-devel liblzma-devel"
-short_desc="A feature-rich dictionary lookup program"
+short_desc="Feature-rich dictionary lookup program"
maintainer="John <me@johnnynator.dev>"
license="GPL-3.0-or-later"
homepage="http://goldendict.org/"
From 96aba07c75f8f26cc885e53581ae3c66dd189c9d Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:47 -0400
Subject: [PATCH 040/140] gst-libav: revbump for ffmpeg-6.0
---
srcpkgs/gst-libav/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/gst-libav/template b/srcpkgs/gst-libav/template
index e9a79dc650a5..f082bd211c65 100644
--- a/srcpkgs/gst-libav/template
+++ b/srcpkgs/gst-libav/template
@@ -1,7 +1,7 @@
# Template file for 'gst-libav'
pkgname=gst-libav
version=1.20.3
-revision=1
+revision=2
build_style=meson
hostmakedepends="pkg-config yasm"
makedepends="orc-devel gst-plugins-base1-devel ffmpeg-devel"
From edd46d846c94db43f01bf94f3a339e504cced676 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:47 -0400
Subject: [PATCH 041/140] gst-plugins-bad1: revbump for ffmpeg-6.0
---
srcpkgs/gst-plugins-bad1/template | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/srcpkgs/gst-plugins-bad1/template b/srcpkgs/gst-plugins-bad1/template
index f55f82fd4c77..5a9d5387e0d4 100644
--- a/srcpkgs/gst-plugins-bad1/template
+++ b/srcpkgs/gst-plugins-bad1/template
@@ -1,7 +1,7 @@
# Template file for 'gst-plugins-bad1'
pkgname=gst-plugins-bad1
-version=1.20.3
-revision=3
+version=1.22.1
+revision=2
build_helper="gir"
build_style=meson
configure_args="-Dpackage-origin=https://voidlinux.org -Ddoc=disabled
From 968f4008f3565a806b881a07649b3ca474bff6ca Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:47 -0400
Subject: [PATCH 042/140] gst-rtsp-server: revbump for ffmpeg-6.0
---
srcpkgs/gst-rtsp-server/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/gst-rtsp-server/template b/srcpkgs/gst-rtsp-server/template
index 33cd64ceb95e..8ceea8d34b4b 100644
--- a/srcpkgs/gst-rtsp-server/template
+++ b/srcpkgs/gst-rtsp-server/template
@@ -1,7 +1,7 @@
# Template file for 'gst-rtsp-server'
pkgname=gst-rtsp-server
version=1.20.3
-revision=2
+revision=3
build_style=meson
hostmakedepends="pkg-config python3"
makedepends="glib-devel gst-plugins-bad1-devel gobject-introspection
From 1f3930648b11bdcb3e2538ea2bacc0235364aacb Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:47 -0400
Subject: [PATCH 043/140] guvcview: update to 2.0.8.
---
srcpkgs/guvcview/patches/fix-include.patch | 10 ++++++++++
srcpkgs/guvcview/template | 5 ++---
2 files changed, 12 insertions(+), 3 deletions(-)
create mode 100644 srcpkgs/guvcview/patches/fix-include.patch
diff --git a/srcpkgs/guvcview/patches/fix-include.patch b/srcpkgs/guvcview/patches/fix-include.patch
new file mode 100644
index 000000000000..503c2af3b78c
--- /dev/null
+++ b/srcpkgs/guvcview/patches/fix-include.patch
@@ -0,0 +1,10 @@
+--- a/guvcview/guvcview.c
++++ b/guvcview/guvcview.c
+@@ -28,6 +28,7 @@
+ #include <sys/stat.h>
+ #include <sys/resource.h>
+ #include <errno.h>
++#include <locale.h>
+
+ #include "gview.h"
+ #include "gviewv4l2core.h"
diff --git a/srcpkgs/guvcview/template b/srcpkgs/guvcview/template
index 345cf6006f24..86a7fd619612 100644
--- a/srcpkgs/guvcview/template
+++ b/srcpkgs/guvcview/template
@@ -1,8 +1,7 @@
# Template file for 'guvcview'
pkgname=guvcview
-version=2.0.7
+version=2.0.8
revision=1
-create_wrksrc=yes
build_style=gnu-configure
configure_args="--disable-static --disable-debian-menu"
hostmakedepends="pkg-config intltool autoconf automake libtool glib-devel"
@@ -14,7 +13,7 @@ maintainer="Orphaned <orphan@voidlinux.org>"
license="GPL-3.0-or-later"
homepage="http://guvcview.sourceforge.net/"
distfiles="${SOURCEFORGE_SITE}/${pkgname}/${pkgname}-src-${version}.tar.bz2"
-checksum=f47d51fbd06e44eeaa1a82f4a153c927527c90d94514197a70b2956028cc8ad4
+checksum=a21f4e448286666cf27bafef5290cc953a0a1796b752e5bbe521266dc1230c81
post_patch() {
sed '31a#include <locale.h>' -i guvcview/guvcview.c
From 28aceac5ac8bd39db425db1484974f357fd8e2b7 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:48 -0400
Subject: [PATCH 044/140] handbrake: update to 1.6.1
---
.../patches/fix-missing-x265-link-flag.patch | 11 ++++++-----
.../handbrake/patches/libhb-vpl-include.patch | 15 +++++++++++++++
srcpkgs/handbrake/template | 18 +++++++++++-------
3 files changed, 32 insertions(+), 12 deletions(-)
create mode 100644 srcpkgs/handbrake/patches/libhb-vpl-include.patch
diff --git a/srcpkgs/handbrake/patches/fix-missing-x265-link-flag.patch b/srcpkgs/handbrake/patches/fix-missing-x265-link-flag.patch
index 26db03867a0c..d6bb2eda627a 100644
--- a/srcpkgs/handbrake/patches/fix-missing-x265-link-flag.patch
+++ b/srcpkgs/handbrake/patches/fix-missing-x265-link-flag.patch
@@ -1,14 +1,15 @@
--- a/gtk/configure.ac
+++ b/gtk/configure.ac
@@ -203,7 +203,7 @@
-
+
AM_CONDITIONAL([MINGW], [test "x$mingw_flag" = "xyes"])
-
--HB_LIBS="$HB_LIBS -lhandbrake -lavformat -lavfilter -lavcodec -lavutil -ldav1d -lswresample -lpostproc -ldvdnav -ldvdread -lmp3lame -lvorbis -lvorbisenc -logg -lswscale -ltheoraenc -ltheoradec -lvpx -lz -lbz2 -lbluray -lass -lfontconfig -lfreetype -lxml2 -ljansson -lopus -lspeex -lturbojpeg -llzma -lzimg"
-+HB_LIBS="$HB_LIBS -lhandbrake -lavformat -lavfilter -lavcodec -lavutil -ldav1d -lswresample -lpostproc -ldvdnav -ldvdread -lmp3lame -lvorbis -lvorbisenc -logg -lswscale -ltheoraenc -ltheoradec -lvpx -lz -lbz2 -lbluray -lass -lfontconfig -lfreetype -lxml2 -ljansson -lopus -lspeex -lturbojpeg -llzma -lzimg -ldl"
+
+-HB_LIBS="$HB_LIBS -lhandbrake -lavformat -lavfilter -lavcodec -lavutil -ldav1d -lswresample -lpostproc -ldvdnav -ldvdread -lmp3lame -lvorbis -lvorbisenc -logg -lswscale -ltheoraenc -ltheoradec -lvpx -lz -lbz2 -lbluray -lass -lfontconfig -lfreetype -lxml2 -ljansson -lopus -lspeex -lturbojpeg -llzma -lzimg -lSvtAv1Enc"
++HB_LIBS="$HB_LIBS -lhandbrake -lavformat -lavfilter -lavcodec -lavutil -ldav1d -lswresample -lpostproc -ldvdnav -ldvdread -lmp3lame -lvorbis -lvorbisenc -logg -lswscale -ltheoraenc -ltheoradec -lvpx -lz -lbz2 -lbluray -lass -lfontconfig -lfreetype -lxml2 -ljansson -lopus -lspeex -lturbojpeg -llzma -lzimg -lSvtAv1Enc -ldl"
HB_CPPFLAGS="$HB_CPPFLAGS $HBINC"
-
+
PKG_CHECK_MODULES([x264], [x264], sys_x264=yes, sys_x264=no)
+
--- a/test/module.defs
+++ b/test/module.defs
@@ -69,6 +69,9 @@
diff --git a/srcpkgs/handbrake/patches/libhb-vpl-include.patch b/srcpkgs/handbrake/patches/libhb-vpl-include.patch
new file mode 100644
index 000000000000..298f9f4ab28f
--- /dev/null
+++ b/srcpkgs/handbrake/patches/libhb-vpl-include.patch
@@ -0,0 +1,15 @@
+--- a/libhb/module.defs 2023-01-22 11:36:49.000000000 -0500
++++ b/libhb/module.defs 2023-04-03 22:37:52.395467010 -0400
+@@ -46,11 +46,7 @@
+ LIBHB.GCC.I += $(LIBHB.build/) $(CONTRIB.build/)include
+
+ ifeq (1,$(FEATURE.qsv))
+- ifeq ($(HOST.system),freebsd))
+- LIBHB.GCC.I += $(LOCALBASE)/include/vpl
+- else
+- LIBHB.GCC.I += $(CONTRIB.build/)include/vpl
+- endif
++ LIBHB.GCC.I += /usr/include/vpl
+ endif
+
+ ifneq (,$(filter $(HOST.system),freebsd netbsd openbsd))
diff --git a/srcpkgs/handbrake/template b/srcpkgs/handbrake/template
index ca5e4571e49c..3c2ab8659615 100644
--- a/srcpkgs/handbrake/template
+++ b/srcpkgs/handbrake/template
@@ -1,10 +1,11 @@
# Template file for 'handbrake'
pkgname=handbrake
-version=1.5.1
+version=1.6.1
revision=1
+wrksrc=HandBrake-${version}
build_style=gnu-configure
configure_args="--force --disable-gtk-update-checks --disable-df-fetch --harden
- $(vopt_enable fdk_aac fdk-aac) $(vopt_enable nvenc)"
+ $(vopt_enable fdk_aac fdk-aac) $(vopt_enable nvenc) $(vopt_enable qsv)"
make_build_args="-C ${XBPS_TRIPLET}"
make_install_args="-C ${XBPS_TRIPLET}"
hostmakedepends="automake cmake gettext-devel glib-devel intltool libtool m4 meson nasm pkg-config python3"
@@ -12,8 +13,11 @@ makedepends="bzip2-devel ffmpeg-devel gst-plugins-base1-devel gtk+3-devel
jansson-devel lame-devel libass-devel libbluray-devel libdav1d-devel
libdvdnav-devel libdvdread-devel libgudev-devel libnuma-devel
libsamplerate-devel libtheora-devel libvorbis-devel libvpx-devel libxml2-devel
- opus-devel speex-devel x264-devel x265-devel zimg-devel
+ opus-devel speex-devel x264-devel x265-devel zimg-devel libsvt-av1-devel
$(vopt_if fdk_aac fdk-aac-devel)
+ $(vopt_if qsv libva-devel)
+ $(vopt_if qsv libdrm-devel)
+ $(vopt_if qsv onevpl-devel)
$(vopt_if nvenc nv-codec-headers)"
depends="desktop-file-utils gst-plugins-good1 hicolor-icon-theme"
short_desc="Multithreaded video transcoder"
@@ -21,15 +25,15 @@ maintainer="Enno Boland <gottox@voidlinux.org>"
license="GPL-2.0-only"
homepage="https://handbrake.fr/"
distfiles="https://github.com/HandBrake/HandBrake/releases/download/${version}/HandBrake-${version}-source.tar.bz2"
-checksum=3999fe06d5309c819799a73a968a8ec3840e7840c2b64af8f5cdb7fd8c9430f0
+checksum=94ccfe03db917a91650000c510f7fd53f844da19f19ad4b4be1b8f6bc31a8d4c
nocross=yes
-build_options="fdk_aac nvenc"
+build_options="fdk_aac nvenc qsv"
case "$XBPS_TARGET_MACHINE" in
x86_64*|i686*)
CFLAGS="-msse"
- build_options_default="nvenc"
+ build_options_default="nvenc qsv"
;;
esac
@@ -37,7 +41,7 @@ pre_configure() {
# use system libraries, don't download them
rm -rf contrib/
for module in fdk-aac ffmpeg libbluray libdav1d libdvdnav libdvdread nvenc \
- x265 zimg; do
+ x265 zimg svt-av1 libvpl; do
vsed -i "/MODULES += contrib\/${module}/d" make/include/main.defs
done
}
From de923bdfbde5b1a4c000cd948d5b2a8772c84490 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:48 -0400
Subject: [PATCH 045/140] hedgewars: revbump for ffmpeg4-4.4.3
---
srcpkgs/hedgewars/template | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/srcpkgs/hedgewars/template b/srcpkgs/hedgewars/template
index 419f29b98b44..926fe4fe3e68 100644
--- a/srcpkgs/hedgewars/template
+++ b/srcpkgs/hedgewars/template
@@ -1,13 +1,13 @@
# Template file for 'hedgewars'
pkgname=hedgewars
version=1.0.2
-revision=1
+revision=2
build_style=cmake
configure_args="-DNOSERVER=1 -DDATA_INSTALL_DIR=/usr/share/${pkgname}
-DPHYSFS_SYSTEM=1 -DMINIMAL_FLAGS=1"
make_cmd=make
hostmakedepends="lua51 pkg-config qt5-qmake qt5-host-tools"
-makedepends="ffmpeg-devel lua51-devel physfs-devel qt5-tools-devel SDL2_image-devel
+makedepends="ffmpeg4-devel lua51-devel physfs-devel qt5-tools-devel SDL2_image-devel
SDL2_mixer-devel SDL2_net-devel SDL2_ttf-devel"
depends="libfreeglut"
short_desc="Funny turn-based artillery game, featuring fighting Hedgehogs!"
From 563a3d51126d0e0ec3e65ca1471f2dc40a402ef6 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:48 -0400
Subject: [PATCH 046/140] idjc: revbump for ffmpeg4-4.4.3
---
srcpkgs/idjc/template | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/srcpkgs/idjc/template b/srcpkgs/idjc/template
index df60318b3db9..36a75baf597c 100644
--- a/srcpkgs/idjc/template
+++ b/srcpkgs/idjc/template
@@ -1,11 +1,11 @@
# Template file for 'idjc'
pkgname=idjc
version=0.9.1
-revision=3
+revision=4
build_style=gnu-configure
hostmakedepends="pkg-config git python3 automake gettext-devel libtool"
makedepends="libvorbis-devel libogg-devel jack-devel libsamplerate-devel
- libflac-devel libsndfile-devel mpg123-devel ffmpeg-devel speex-devel
+ libflac-devel libsndfile-devel mpg123-devel ffmpeg4-devel speex-devel
glib-devel pixman-devel lame-devel python3-gobject-devel libshout-idjc-devel
opus-devel twolame-devel python3-mutagen python3-devel"
depends="python3-gobject python3-mutagen desktop-file-utils shared-mime-info python3-dbus jack"
From ae47a462256653492a0847b49eb47cd5e1f3a678 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:48 -0400
Subject: [PATCH 047/140] kfilemetadata5: revbump for ffmpeg-6.0
---
srcpkgs/kfilemetadata5/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/kfilemetadata5/template b/srcpkgs/kfilemetadata5/template
index 8980121fbc69..f662a2043f93 100644
--- a/srcpkgs/kfilemetadata5/template
+++ b/srcpkgs/kfilemetadata5/template
@@ -1,7 +1,7 @@
# Template file for 'kfilemetadata5'
pkgname=kfilemetadata5
version=5.105.0
-revision=1
+revision=2
build_style=cmake
hostmakedepends="kcoreaddons extra-cmake-modules pkg-config qt5-host-tools qt5-qmake
gettext kcoreaddons python3"
From cdbb9f85e235fce9725fe5c9dc07a2e86a4b133c Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:48 -0400
Subject: [PATCH 048/140] kid3: revbump for ffmpeg-6.0
---
srcpkgs/kid3/patches/ffmpeg5.patch | 17 +++++++++++++++++
srcpkgs/kid3/template | 2 +-
2 files changed, 18 insertions(+), 1 deletion(-)
create mode 100644 srcpkgs/kid3/patches/ffmpeg5.patch
diff --git a/srcpkgs/kid3/patches/ffmpeg5.patch b/srcpkgs/kid3/patches/ffmpeg5.patch
new file mode 100644
index 000000000000..135fc50e07c9
--- /dev/null
+++ b/srcpkgs/kid3/patches/ffmpeg5.patch
@@ -0,0 +1,17 @@
+# https://aur.archlinux.org/cgit/aur.git/diff/ffmpeg5.patch?h=kid3-cli&id=12410a74906612e7efc0ec8fbce739b4a0fef7e7
+diff --git a/src/plugins/acoustidimport/ffmpegfingerprintdecoder.cpp b/src/plugins/acoustidimport/ffmpegfingerprintdecoder.cpp
+index e156d424..e12b9abd 100644
+--- a/src/plugins/acoustidimport/ffmpegfingerprintdecoder.cpp
++++ b/src/plugins/acoustidimport/ffmpegfingerprintdecoder.cpp
+@@ -232,7 +232,11 @@ private:
+ friend class Format;
+ friend class Converter;
+ AVCodecContext* m_ptr;
++#if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(59, 0, 0)
+ AVCodec* m_impl;
++#else
++ const AVCodec* m_impl;
++#endif
+ AVFrame* m_frame;
+ bool m_opened;
+ };
diff --git a/srcpkgs/kid3/template b/srcpkgs/kid3/template
index 456206d90e16..f32f9decb0e7 100644
--- a/srcpkgs/kid3/template
+++ b/srcpkgs/kid3/template
@@ -1,7 +1,7 @@
# Template file for 'kid3'
pkgname=kid3
version=3.9.1
-revision=2
+revision=3
build_style=cmake
configure_args="-DWITH_APPS='CLI;$(vopt_if KDE KDE Qt)'
-DWITH_DOCBOOKDIR=/usr/share/xsl/docbook -DWITH_FLAC=$(vopt_if flac ON OFF)
From fcc89c7cdb4043b467ab41050af8dfd0e68dacf1 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:48 -0400
Subject: [PATCH 049/140] kodi: revbump for ffmpeg4-4.4.3
---
srcpkgs/kodi/template | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/srcpkgs/kodi/template b/srcpkgs/kodi/template
index 8057964d78a3..6cc1874be7ba 100644
--- a/srcpkgs/kodi/template
+++ b/srcpkgs/kodi/template
@@ -1,7 +1,7 @@
# Template file for 'kodi'
pkgname=kodi
version=19.4
-revision=6
+revision=7
_codename="Matrix"
build_style=cmake
configure_args="-DWITH_FFMPEG=/usr -DENABLE_LDGOLD=OFF
@@ -54,7 +54,7 @@ makedepends="
libmad-devel fontconfig-devel libXinerama-devel libsamplerate-devel libmms-devel
enca-devel boost-devel libcurl-devel libva-devel libvdpau-devel libass-devel
libbluetooth-devel yajl-devel libplist-devel librtmp-devel tinyxml-devel
- taglib-devel libcap-devel lame-devel libbluray-devel libnfs-devel ffmpeg-devel
+ taglib-devel libcap-devel lame-devel libbluray-devel libnfs-devel ffmpeg4-devel
giflib-devel libxslt-devel gnutls-devel libssh-devel libmicrohttpd-devel
libcec-devel dcadec-devel flatbuffers-devel fmt-devel lcms2-devel
libfstrcmp-devel rapidjson libcdio-paranoia spdlog libwaylandpp-devel
From 345e9511ce2c59a3609c3cfe767722687453bdb1 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:48 -0400
Subject: [PATCH 050/140] kpipewire: revbump for ffmpeg-6.0
---
srcpkgs/kpipewire/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/kpipewire/template b/srcpkgs/kpipewire/template
index 467ab823a5e1..51827f24db9e 100644
--- a/srcpkgs/kpipewire/template
+++ b/srcpkgs/kpipewire/template
@@ -1,7 +1,7 @@
# Template file for 'kpipewire'
pkgname=kpipewire
version=5.27.4
-revision=1
+revision=2
build_style=cmake
hostmakedepends="extra-cmake-modules plasma-wayland-protocols gettext
qt5-qmake qt5-host-tools pkg-config wayland-devel kcoreaddons
From 24053eaa9fc09bc454ee9eb01511621c5c48a44d Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:48 -0400
Subject: [PATCH 051/140] libextractor: revbump for ffmpeg4-4.4.3
---
srcpkgs/libextractor/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/libextractor/template b/srcpkgs/libextractor/template
index ddd4790f93e8..1fb9ca56a96a 100644
--- a/srcpkgs/libextractor/template
+++ b/srcpkgs/libextractor/template
@@ -7,7 +7,7 @@ configure_args="--disable-static"
hostmakedepends="pkg-config"
makedepends="zlib-devel bzip2-devel exiv2-devel tiff-devel libpng-devel
libjpeg-turbo-devel libvorbis-devel libflac-devel giflib-devel libmpeg2-devel
- ffmpeg-devel gtk+3-devel libltdl-devel libarchive-devel file-devel libgsf-devel"
+ ffmpeg4-devel gtk+3-devel libltdl-devel libarchive-devel file-devel libgsf-devel"
short_desc="Library used to extract meta data from files"
maintainer="Martin Riese <grauehaare@gmx.de>"
license="GPL-3.0-or-later"
From 86cb35a9f5c68b3598d5fdf806e541d0d818ea79 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:48 -0400
Subject: [PATCH 052/140] libopenal: revbump for ffmpeg-6.0
---
srcpkgs/libopenal/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/libopenal/template b/srcpkgs/libopenal/template
index 77218f9e539d..3f49ed75a1fd 100644
--- a/srcpkgs/libopenal/template
+++ b/srcpkgs/libopenal/template
@@ -1,7 +1,7 @@
# Template file for 'libopenal'
pkgname=libopenal
version=1.22.2
-revision=1
+revision=2
build_style=cmake
configure_args="-DALSOFT_EXAMPLES=OFF"
hostmakedepends="pkg-config"
From 0320728c9770a94718824c7064e8014dc581b2dd Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:48 -0400
Subject: [PATCH 053/140] libopenshot: revbump for ffmpeg-6.0
---
srcpkgs/libopenshot/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/libopenshot/template b/srcpkgs/libopenshot/template
index db831f69b474..81aa0d7136d9 100644
--- a/srcpkgs/libopenshot/template
+++ b/srcpkgs/libopenshot/template
@@ -1,7 +1,7 @@
# Template file for 'libopenshot'
pkgname=libopenshot
version=0.3.0
-revision=1
+revision=2
build_style=cmake
# Builds fail with Ruby-2.4.1
configure_args="-DENABLE_RUBY=OFF -DUSE_SYSTEM_JSONCPP=ON"
From a8850c66c56b254f339c01730cf536a36e20c851 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:48 -0400
Subject: [PATCH 054/140] loudgain: revbump for ffmpeg-6.0
---
srcpkgs/loudgain/patches/ffmpeg5.patch | 11 +++++++++++
srcpkgs/loudgain/template | 2 +-
2 files changed, 12 insertions(+), 1 deletion(-)
create mode 100644 srcpkgs/loudgain/patches/ffmpeg5.patch
diff --git a/srcpkgs/loudgain/patches/ffmpeg5.patch b/srcpkgs/loudgain/patches/ffmpeg5.patch
new file mode 100644
index 000000000000..16d4510ee98f
--- /dev/null
+++ b/srcpkgs/loudgain/patches/ffmpeg5.patch
@@ -0,0 +1,11 @@
+--- a/src/scan.c 2019-09-06 11:31:19.000000000 -0400
++++ b/src/scan.c 2023-03-23 11:15:40.867968521 -0400
+@@ -69,8 +69,6 @@
+ * It is now useless
+ * https://github.com/FFmpeg/FFmpeg/blob/70d25268c21cbee5f08304da95be1f647c630c15/doc/APIchanges#L86
+ */
+- if (avformat_version() < AV_VERSION_INT(58,9,100))
+- av_register_all();
+
+ av_log_set_callback(scan_av_log);
+
diff --git a/srcpkgs/loudgain/template b/srcpkgs/loudgain/template
index da4f2d56e94c..4d6bf29efb4f 100644
--- a/srcpkgs/loudgain/template
+++ b/srcpkgs/loudgain/template
@@ -1,7 +1,7 @@
# Template file for 'loudgain'
pkgname=loudgain
version=0.6.8
-revision=2
+revision=3
build_style=cmake
hostmakedepends="pkg-config"
makedepends="libebur128-devel taglib-devel ffmpeg-devel"
From 78c33ebcb4b9c30d700461716cffd0a59e480b5c Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:48 -0400
Subject: [PATCH 055/140] mediastreamer: revbump for ffmpeg4-4.4.3
---
srcpkgs/mediastreamer/template | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/srcpkgs/mediastreamer/template b/srcpkgs/mediastreamer/template
index d0e97e858e29..1bde031443a5 100644
--- a/srcpkgs/mediastreamer/template
+++ b/srcpkgs/mediastreamer/template
@@ -1,11 +1,11 @@
# Template file for 'mediastreamer'
pkgname=mediastreamer
version=5.2.6
-revision=1
+revision=2
build_style=cmake
configure_args="-DENABLE_STRICT=0 -DENABLE_UNIT_TESTS=0"
hostmakedepends="python3"
-makedepends="bzrtp-devel ffmpeg-devel glew-devel libXv-devel libsrtp-devel
+makedepends="bzrtp-devel ffmpeg4-devel glew-devel libXv-devel libsrtp-devel
libupnp-devel libvpx-devel mbedtls-devel opus-devel ortp-devel pulseaudio-devel
libtheora-devel speex-devel v4l-utils-devel bcg729-devel bcmatroska2-devel libgsm-devel"
# zxing-cpp-devel (1.2.0 probably not compatible, check again after updaing xzing)
From 74a40808546a46252594896a3a939199ead27675 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:48 -0400
Subject: [PATCH 056/140] mgba: revbump for ffmpeg-6.0
---
srcpkgs/mgba/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/mgba/template b/srcpkgs/mgba/template
index ae0504311eee..d31295a0cd3d 100644
--- a/srcpkgs/mgba/template
+++ b/srcpkgs/mgba/template
@@ -1,7 +1,7 @@
# Template file for 'mgba'
pkgname=mgba
version=0.10.2
-revision=1
+revision=2
build_style=cmake
hostmakedepends="pkg-config qt5-host-tools qt5-qmake desktop-file-utils"
makedepends="SDL2-devel ffmpeg-devel libedit-devel libepoxy-devel libmagick-devel
From b8e1f5567fb37dce052377785069a5e37ac88b0a Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:48 -0400
Subject: [PATCH 057/140] minidlna: revbump for ffmpeg-6.0
---
srcpkgs/minidlna/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/minidlna/template b/srcpkgs/minidlna/template
index e8081b1cbc67..9ee9714861fd 100644
--- a/srcpkgs/minidlna/template
+++ b/srcpkgs/minidlna/template
@@ -1,7 +1,7 @@
# Template file for 'minidlna'
pkgname=minidlna
version=1.3.2
-revision=1
+revision=2
build_style=gnu-configure
configure_args="
--sbindir=/usr/bin
From 4a1c6b28e96b9b4b3a7343688ffb58f6a611050e Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:49 -0400
Subject: [PATCH 058/140] mixxx: revbump for ffmpeg-6.0
---
srcpkgs/mixxx/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/mixxx/template b/srcpkgs/mixxx/template
index 619ddca0d332..4b9ea00d3fb3 100644
--- a/srcpkgs/mixxx/template
+++ b/srcpkgs/mixxx/template
@@ -1,7 +1,7 @@
# Template file for 'mixxx'
pkgname=mixxx
version=2.3.3
-revision=1
+revision=2
build_style=cmake
configure_args="-DCMAKE_BUILD_TYPE=Release"
hostmakedepends="extra-cmake-modules pkg-config protobuf qt5-host-tools qt5-devel"
From 7f23c0e62bcadba7e24ce2e1a3198ee4bfea78fe Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:49 -0400
Subject: [PATCH 059/140] mlt: revbump for ffmpeg4-4.4.3
---
srcpkgs/mlt/template | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/srcpkgs/mlt/template b/srcpkgs/mlt/template
index 8933eb4e7bb9..73353fedafb5 100644
--- a/srcpkgs/mlt/template
+++ b/srcpkgs/mlt/template
@@ -1,14 +1,14 @@
# Template file for 'mlt'
pkgname=mlt
version=6.26.1
-revision=1
+revision=2
build_style=configure
configure_args="--prefix=/usr --libdir=/usr/lib$XBPS_TARGET_WORDSIZE
--enable-gpl --enable-gpl3 --disable-swfdec --without-kde
--swig-languages=python"
hostmakedepends="doxygen pkg-config ladspa-sdk swig python3 which"
# XXX: movit vid.stab
-makedepends="alsa-lib-devel ffmpeg-devel gtk+-devel jack-devel ladspa-sdk
+makedepends="alsa-lib-devel ffmpeg4-devel gtk+-devel jack-devel ladspa-sdk
libexif-devel libsamplerate-devel libxml2-devel sox-devel SDL_image-devel
fftw-devel frei0r-plugins python3-devel pulseaudio-devel movit-devel
libvidstab-devel libatomic-devel"
From 7426dae5d7ab434ea223f0e79fe4b7c6a830ceb9 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:49 -0400
Subject: [PATCH 060/140] moc: revbump for ffmpeg4-4.4.3
---
srcpkgs/moc/template | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/srcpkgs/moc/template b/srcpkgs/moc/template
index c42be650a1d2..d4f0eefbad52 100644
--- a/srcpkgs/moc/template
+++ b/srcpkgs/moc/template
@@ -1,10 +1,10 @@
# Template file for 'moc'
pkgname=moc
version=2.5.2
-revision=6
+revision=7
build_style=gnu-configure
hostmakedepends="pkg-config"
-makedepends="db-devel ncurses-devel libcurl-devel popt-devel ffmpeg-devel
+makedepends="db-devel ncurses-devel libcurl-devel popt-devel ffmpeg4-devel
jack-devel alsa-lib-devel libltdl-devel libflac-devel libvorbis-devel
libmad-devel libmpcdec-devel libmodplug-devel libid3tag-devel faad2-devel
taglib-devel libsndfile-devel wavpack-devel speex-devel libsamplerate-devel
From 8b3ce3fef5898d875463b31509c8794d36fae97f Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:49 -0400
Subject: [PATCH 061/140] motion: revbump for ffmpeg-6.0
---
srcpkgs/motion/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/motion/template b/srcpkgs/motion/template
index 3cf3c3035c5b..7dca12d851e3 100644
--- a/srcpkgs/motion/template
+++ b/srcpkgs/motion/template
@@ -1,7 +1,7 @@
# Template file for 'motion'
pkgname=motion
version=4.5.1
-revision=1
+revision=2
build_style=gnu-configure
hostmakedepends="automake pkg-config gettext-devel tar"
makedepends="ffmpeg-devel libmicrohttpd-devel v4l-utils-devel gettext-devel"
From f46cbaf4c6f4dee663f07532151cf4f778b728eb Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:49 -0400
Subject: [PATCH 062/140] mpv: revbump for ffmpeg-6.0
---
srcpkgs/mpv/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/mpv/template b/srcpkgs/mpv/template
index e163c496c6eb..d4fefbf5e3c7 100644
--- a/srcpkgs/mpv/template
+++ b/srcpkgs/mpv/template
@@ -1,7 +1,7 @@
# Template file for 'mpv'
pkgname=mpv
version=0.35.1
-revision=2
+revision=3
build_style=meson
configure_args="-Dcdda=enabled -Ddvbin=enabled -Ddvdnav=enabled
-Dlibmpv=true -Dcplugins=enabled
From e3b0a90b4158a37fdb4020f4aff351ad675e1979 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:49 -0400
Subject: [PATCH 063/140] musikcube: revbump for ffmpeg-6.0
---
srcpkgs/musikcube/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/musikcube/template b/srcpkgs/musikcube/template
index 4b7930041126..7cd65cf76b77 100644
--- a/srcpkgs/musikcube/template
+++ b/srcpkgs/musikcube/template
@@ -1,7 +1,7 @@
# Template file for 'musikcube'
pkgname=musikcube
version=0.99.4
-revision=1
+revision=2
build_style=cmake
make_cmd=make
configure_args="-DNO_NCURSESW=1"
From d4b795f42b057ed90a2ff99719a8bb8b00bf3cd5 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:49 -0400
Subject: [PATCH 064/140] notcurses: revbump for ffmpeg-6.0
---
srcpkgs/notcurses/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/notcurses/template b/srcpkgs/notcurses/template
index 6dd8a091319f..3110c30c9aff 100644
--- a/srcpkgs/notcurses/template
+++ b/srcpkgs/notcurses/template
@@ -1,7 +1,7 @@
# Template file for 'notcurses'
pkgname=notcurses
version=3.0.9
-revision=1
+revision=2
build_style=cmake
configure_args="-DUSE_STATIC=ON $(vopt_bool man USE_PANDOC)"
hostmakedepends="pkg-config $(vopt_if man pandoc)"
From cba457bf8a12bb55c5c145d9bcc50bc685eadab1 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:49 -0400
Subject: [PATCH 065/140] obs: revbump for ffmpeg-6.0
---
srcpkgs/obs/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/obs/template b/srcpkgs/obs/template
index 89fd11297c3f..3cf49e414bf3 100644
--- a/srcpkgs/obs/template
+++ b/srcpkgs/obs/template
@@ -1,7 +1,7 @@
# Template file for 'obs'
pkgname=obs
version=29.1.0
-revision=1
+revision=2
archs="i686* x86_64* ppc64le* aarch64*"
build_style=cmake
configure_args="-DOBS_VERSION_OVERRIDE=${version} -DENABLE_JACK=ON
From dc07ee177bf1f11a77e38d6d9af319e2b3cc3a79 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:49 -0400
Subject: [PATCH 066/140] olive: revbump for ffmpeg4-4.4.3
---
srcpkgs/olive/template | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/srcpkgs/olive/template b/srcpkgs/olive/template
index 12a46936c990..5c2917b9c512 100644
--- a/srcpkgs/olive/template
+++ b/srcpkgs/olive/template
@@ -1,10 +1,10 @@
# Template file for 'olive'
pkgname=olive
version=0.1.2
-revision=2
+revision=3
build_style=qmake
hostmakedepends="qt5-qmake qt5-host-tools pkg-config"
-makedepends="qt5-devel qt5-multimedia-devel qt5-svg-devel ffmpeg-devel frei0r-plugins"
+makedepends="qt5-devel qt5-multimedia-devel qt5-svg-devel ffmpeg4-devel frei0r-plugins"
short_desc="Non-linear video editor"
maintainer="Orphaned <orphan@voidlinux.org>"
license="GPL-3.0-or-later"
From b43691adbdd8f7326caa228f2e246ddc0e80c550 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:49 -0400
Subject: [PATCH 067/140] omxplayer: revbump for ffmpeg4-4.4.3
---
srcpkgs/omxplayer/template | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/srcpkgs/omxplayer/template b/srcpkgs/omxplayer/template
index e70bf7873d4d..c835103d8789 100644
--- a/srcpkgs/omxplayer/template
+++ b/srcpkgs/omxplayer/template
@@ -1,10 +1,10 @@
# Template file for 'omxplayer'
pkgname=omxplayer
version=20190102
-revision=1
+revision=2
short_desc="Commandline OMX player for the Raspberry Pi"
maintainer="Orphaned <orphan@voidlinux.org>"
-license="GPL-2"
+license="GPL-2-or-later"
homepage="https://github.com/popcornmix/omxplayer"
_commit="f06235cc9690a6d58187514452df8cf8fcdaacec"
@@ -15,7 +15,7 @@ checksum=af2d9450f8947842ea8c401fe9f71eec444013ebbdee29f2ac828c9c493c1329
archs="armv6l* armv7l*"
build_style=gnu-makefile
hostmakedepends="curl pkg-config"
-makedepends="alsa-lib-devel rpi-userland-devel pcre-devel boost-devel freetype-devel ffmpeg-devel dbus-devel"
+makedepends="alsa-lib-devel rpi-userland-devel pcre-devel boost-devel freetype-devel ffmpeg4-devel dbus-devel"
depends="freefont-ttf"
do_build() {
From c181523e510ad21c7ca28b2647415853ae05f127 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:50 -0400
Subject: [PATCH 068/140] openimageio: revbump for ffmpeg-6.0
---
common/shlibs | 2 ++
srcpkgs/openimageio/template | 2 +-
2 files changed, 3 insertions(+), 1 deletion(-)
diff --git a/common/shlibs b/common/shlibs
index 4626cfda810b..d0d328b09ef9 100644
--- a/common/shlibs
+++ b/common/shlibs
@@ -2262,6 +2262,8 @@ libxmp.so.4 libxmp-4.3.7_1
libKF5ThreadWeaver.so.5 threadweaver-5.26.0_1
libOpenImageIO_Util.so.2.4 openimageio-2.4.9.0_1
libOpenImageIO.so.2.4 openimageio-2.4.9.0_1
+libOpenImageIO_Util.so.2.4 openimageio-2.4.8.1_1
+libOpenImageIO.so.2.4 openimageio-2.4.8.1_1
libOpenColorIO.so.2.1 opencolorio-2.1.2_1
libpystring.so.1 pystring-1.1.3_1
libyaml-cpp.so.0.7 yaml-cpp-0.7.0_1
diff --git a/srcpkgs/openimageio/template b/srcpkgs/openimageio/template
index b661bbf7ba57..9b38ace50f7e 100644
--- a/srcpkgs/openimageio/template
+++ b/srcpkgs/openimageio/template
@@ -1,7 +1,7 @@
# Template file for 'openimageio'
pkgname=openimageio
version=2.4.9.0
-revision=2
+revision=3
build_style=cmake
build_helper=qemu
configure_args="-DUSE_QT=0 -DUSE_PYTHON=0 -DOIIO_BUILD_TESTS=0
From 0d93cf026a7b56a3bd6f942c63c71bc4b48b43dd Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:50 -0400
Subject: [PATCH 069/140] openmw: revbump for ffmpeg-6.0
---
srcpkgs/openmw/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/openmw/template b/srcpkgs/openmw/template
index 5251a0283dc1..e3771c7aaf1a 100644
--- a/srcpkgs/openmw/template
+++ b/srcpkgs/openmw/template
@@ -1,7 +1,7 @@
# Template file for 'openmw'
pkgname=openmw
version=0.47.0
-revision=4
+revision=5
build_style=cmake
_recast_commit=e75adf86f91eb3082220085e42dda62679f9a3ea
_bullet_tag=3.17
From 96a94e42a7719eca112174c79402331d7a079615 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:50 -0400
Subject: [PATCH 070/140] openshot: revbump for ffmpeg-6.0
---
srcpkgs/openshot/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/openshot/template b/srcpkgs/openshot/template
index 322717d40abc..c074e0338773 100644
--- a/srcpkgs/openshot/template
+++ b/srcpkgs/openshot/template
@@ -1,7 +1,7 @@
# Template file for 'openshot'
pkgname=openshot
version=3.0.0
-revision=1
+revision=2
build_style=python3-module
hostmakedepends="python3 python3-setuptools"
makedepends="ffmpeg-devel python3-PyQt5"
From 16853b969fd4289d545dc8e8539de5970c4b431e Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:50 -0400
Subject: [PATCH 071/140] opentoonz: revbump for ffmpeg-6.0
---
srcpkgs/opentoonz/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/opentoonz/template b/srcpkgs/opentoonz/template
index ee9f7603f55f..3e81834ca0ed 100644
--- a/srcpkgs/opentoonz/template
+++ b/srcpkgs/opentoonz/template
@@ -1,7 +1,7 @@
# Template file for 'opentoonz'
pkgname=opentoonz
version=1.6.0
-revision=2
+revision=3
build_wrksrc="toonz/sources"
build_style=cmake
make_cmd=make
From bddb16cb1c74d93f687afbdb8306c6f0c35084ba Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:50 -0400
Subject: [PATCH 072/140] pianobar: revbump for ffmpeg-6.0
---
srcpkgs/pianobar/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/pianobar/template b/srcpkgs/pianobar/template
index a9b29e91993f..81efcd122c4d 100644
--- a/srcpkgs/pianobar/template
+++ b/srcpkgs/pianobar/template
@@ -1,7 +1,7 @@
# Template file for 'pianobar'
pkgname=pianobar
version=2022.04.01
-revision=1
+revision=2
build_style=gnu-makefile
make_build_args="V=1"
hostmakedepends="pkg-config"
From 90cae6cbf0b385f4536714f5f2acba544de56f46 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:50 -0400
Subject: [PATCH 073/140] ppsspp: revbump for ffmpeg4-4.4.3
---
srcpkgs/ppsspp/template | 7 +++----
1 file changed, 3 insertions(+), 4 deletions(-)
diff --git a/srcpkgs/ppsspp/template b/srcpkgs/ppsspp/template
index 7984a733d4be..15a42fd2c993 100644
--- a/srcpkgs/ppsspp/template
+++ b/srcpkgs/ppsspp/template
@@ -1,7 +1,7 @@
# Template file for 'ppsspp'
pkgname=ppsspp
version=1.14.4
-revision=1
+revision=2
_glslang_commit=dc11adde23c455a24e13dd54de9b4ede8bdd7db8
_SPIRV_Cross_commit=9acb9ec31f5a8ef80ea6b994bb77be787b08d3d1
_armips_commit=6719edebaae03330ee5441d9b28280672edf00d5
@@ -13,7 +13,7 @@ configure_args="-DHEADLESS=1 -DUSE_SYSTEM_FFMPEG=1 -DUNITTEST=ON
-DUSING_QT_UI=$(vopt_if qt ON OFF) -DUSE_SYSTEM_ZSTD=ON
-DARMIPS_USE_STD_FILESYSTEM=ON"
hostmakedepends="pkg-config python3 $(vopt_if qt qt5-host-tools)"
-makedepends="zlib-devel glew-devel ffmpeg-devel libzip-devel
+makedepends="zlib-devel glew-devel ffmpeg4-devel libzip-devel
snappy-devel rapidjson libpng-devel libzstd-devel
$(vopt_if sdl2 SDL2-devel) $(vopt_if wayland wayland-devel)
$(vopt_if qt 'qt5-devel qt5-multimedia-devel')"
@@ -62,13 +62,12 @@ post_extract() {
mv ${wrksrc}/miniupnp-${_miniupnp_commit} ${wrksrc}/ext/miniupnp
}
-post_patch(){
+post_patch() {
# disable git versioning
vsed -e 's|find_package(Git)|# &|' -i git-version.cmake
}
do_install() {
- vlicense LICENSE.TXT
vinstall icons/icon.svg 644 usr/share/pixmaps ppsspp.svg
vinstall Qt/PPSSPP.desktop 644 usr/share/applications
vbin build/PPSSPPHeadless ppsspp-headless
From cb6988a511ed1a99d34dcc0121889f28cdfcbbe7 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:50 -0400
Subject: [PATCH 074/140] pqiv: revbump for ffmpeg-6.0
---
srcpkgs/pqiv/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/pqiv/template b/srcpkgs/pqiv/template
index 542fc27a2d32..9308d949b6a1 100644
--- a/srcpkgs/pqiv/template
+++ b/srcpkgs/pqiv/template
@@ -1,7 +1,7 @@
# Template file for 'pqiv'
pkgname=pqiv
version=2.12
-revision=1
+revision=2
build_style=gnu-makefile
hostmakedepends="pkg-config"
makedepends="glib-devel gtk+3-devel $(vopt_if ffmpeg ffmpeg-devel)
From c2a2a18c8a5809c68bb764ec475b4131042e7192 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:50 -0400
Subject: [PATCH 075/140] qmmp: revbump for ffmpeg-6.0
---
srcpkgs/qmmp/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/qmmp/template b/srcpkgs/qmmp/template
index 26c661ed16be..a150d7441c7a 100644
--- a/srcpkgs/qmmp/template
+++ b/srcpkgs/qmmp/template
@@ -1,7 +1,7 @@
# Template file for 'qmmp'
pkgname=qmmp
version=1.6.1
-revision=1
+revision=2
build_style=cmake
configure_args="-DUSE_HAL:BOOL=FALSE -DQMMP_DEFAULT_UI:STRING=simple"
hostmakedepends="pkg-config qt5-host-tools qt5-qmake"
From 9057694e1c778a3107703dd582126ca58902dc18 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:50 -0400
Subject: [PATCH 076/140] qt5-webengine: update to 5.15.13
---
.../chromium-media-filters-cpp14.patch | 11 ++
srcpkgs/qt5-webengine/patches/ffmpeg5.patch | 179 ++++++++++++++++++
srcpkgs/qt5-webengine/template | 10 +-
3 files changed, 195 insertions(+), 5 deletions(-)
create mode 100644 srcpkgs/qt5-webengine/patches/chromium-media-filters-cpp14.patch
create mode 100644 srcpkgs/qt5-webengine/patches/ffmpeg5.patch
diff --git a/srcpkgs/qt5-webengine/patches/chromium-media-filters-cpp14.patch b/srcpkgs/qt5-webengine/patches/chromium-media-filters-cpp14.patch
new file mode 100644
index 000000000000..04adc540f2cb
--- /dev/null
+++ b/srcpkgs/qt5-webengine/patches/chromium-media-filters-cpp14.patch
@@ -0,0 +1,11 @@
+--- a/src/3rdparty/chromium/media/filters/BUILD.gn 2023-02-27 13:32:59.000000000 -0500
++++ b/src/3rdparty/chromium/media/filters/BUILD.gn 2023-04-02 17:21:39.204066384 -0400
+@@ -96,6 +96,8 @@
+ "//ui/gfx/geometry:geometry",
+ ]
+
++ cflags_cc = [ "-std=c++14" ]
++
+ libs = []
+
+ if (proprietary_codecs) {
diff --git a/srcpkgs/qt5-webengine/patches/ffmpeg5.patch b/srcpkgs/qt5-webengine/patches/ffmpeg5.patch
new file mode 100644
index 000000000000..ac55e1634423
--- /dev/null
+++ b/srcpkgs/qt5-webengine/patches/ffmpeg5.patch
@@ -0,0 +1,179 @@
+--- a/src/3rdparty/chromium/media/filters/ffmpeg_demuxer.cc 2023-04-02 16:50:57.732547446 -0400
++++ b/src/3rdparty/chromium/media/filters/ffmpeg_demuxer.cc 2023-04-02 16:50:09.486478995 -0400
+@@ -57,6 +57,8 @@
+
+ namespace {
+
++constexpr int64_t kRelativeTsBase = static_cast<int64_t>(0x7ffeffffffffffff);
++
+ void SetAVStreamDiscard(AVStream* stream, AVDiscard discard) {
+ DCHECK(stream);
+ stream->discard = discard;
+@@ -90,24 +92,12 @@
+
+ static base::TimeDelta ExtractStartTime(AVStream* stream) {
+ // The default start time is zero.
+- base::TimeDelta start_time;
++ base::TimeDelta start_time = kNoTimestamp;
+
+ // First try to use the |start_time| value as is.
+ if (stream->start_time != kNoFFmpegTimestamp)
+ start_time = ConvertFromTimeBase(stream->time_base, stream->start_time);
+
+- // Next try to use the first DTS value, for codecs where we know PTS == DTS
+- // (excludes all H26x codecs). The start time must be returned in PTS.
+- if (stream->first_dts != kNoFFmpegTimestamp &&
+- stream->codecpar->codec_id != AV_CODEC_ID_HEVC &&
+- stream->codecpar->codec_id != AV_CODEC_ID_H264 &&
+- stream->codecpar->codec_id != AV_CODEC_ID_MPEG4) {
+- const base::TimeDelta first_pts =
+- ConvertFromTimeBase(stream->time_base, stream->first_dts);
+- if (first_pts < start_time)
+- start_time = first_pts;
+- }
+-
+ return start_time;
+ }
+
+@@ -408,11 +398,11 @@
+ scoped_refptr<DecoderBuffer> buffer;
+
+ if (type() == DemuxerStream::TEXT) {
+- int id_size = 0;
++ size_t id_size = 0;
+ uint8_t* id_data = av_packet_get_side_data(
+ packet.get(), AV_PKT_DATA_WEBVTT_IDENTIFIER, &id_size);
+
+- int settings_size = 0;
++ size_t settings_size = 0;
+ uint8_t* settings_data = av_packet_get_side_data(
+ packet.get(), AV_PKT_DATA_WEBVTT_SETTINGS, &settings_size);
+
+@@ -424,7 +414,7 @@
+ buffer = DecoderBuffer::CopyFrom(packet->data, packet->size,
+ side_data.data(), side_data.size());
+ } else {
+- int side_data_size = 0;
++ size_t side_data_size = 0;
+ uint8_t* side_data = av_packet_get_side_data(
+ packet.get(), AV_PKT_DATA_MATROSKA_BLOCKADDITIONAL, &side_data_size);
+
+@@ -485,7 +475,7 @@
+ packet->size - data_offset);
+ }
+
+- int skip_samples_size = 0;
++ size_t skip_samples_size = 0;
+ const uint32_t* skip_samples_ptr =
+ reinterpret_cast<const uint32_t*>(av_packet_get_side_data(
+ packet.get(), AV_PKT_DATA_SKIP_SAMPLES, &skip_samples_size));
+@@ -1587,6 +1577,8 @@
+ for (const auto& stream : streams_) {
+ if (!stream || stream->IsEnabled() != enabled)
+ continue;
++ if (stream->av_stream()->start_time == AV_NOPTS_VALUE)
++ continue;
+ if (!lowest_start_time_stream ||
+ stream->start_time() < lowest_start_time_stream->start_time()) {
+ lowest_start_time_stream = stream.get();
+@@ -1604,6 +1596,8 @@
+ if (stream && stream->type() == DemuxerStream::VIDEO &&
+ stream->IsEnabled()) {
+ video_stream = stream.get();
++ if (stream->av_stream()->start_time == AV_NOPTS_VALUE)
++ continue;
+ if (video_stream->start_time() <= seek_time) {
+ return video_stream;
+ }
+diff -Naurp qtwebengine-5.15.10.orig/src/3rdparty/chromium/media/ffmpeg/ffmpeg_common.h qtwebengine-5.15.10/src/3rdparty/chromium/media/ffmpeg/ffmpeg_common.h
+--- a/src/3rdparty/chromium/media/ffmpeg/ffmpeg_common.h 2022-05-23 06:38:40.000000000 -0500
++++ b/src/3rdparty/chromium/media/ffmpeg/ffmpeg_common.h 2022-07-11 22:12:47.917192788 -0500
+@@ -29,6 +29,7 @@ extern "C" {
+ #include <libavformat/avformat.h>
+ #include <libavformat/avio.h>
+ #include <libavutil/avutil.h>
++#include <libavutil/channel_layout.h>
+ #include <libavutil/imgutils.h>
+ #include <libavutil/log.h>
+ #include <libavutil/mastering_display_metadata.h>
+diff -Naurp qtwebengine-5.15.10.orig/src/3rdparty/chromium/media/filters/audio_file_reader.cc qtwebengine-5.15.10/src/3rdparty/chromium/media/filters/audio_file_reader.cc
+--- a/src/3rdparty/chromium/media/filters/audio_file_reader.cc 2022-05-23 06:38:40.000000000 -0500
++++ b/src/3rdparty/chromium/media/filters/audio_file_reader.cc 2022-07-11 22:12:47.917192788 -0500
+@@ -85,7 +85,7 @@ bool AudioFileReader::OpenDemuxer() {
+ }
+
+ bool AudioFileReader::OpenDecoder() {
+- AVCodec* codec = avcodec_find_decoder(codec_context_->codec_id);
++ const AVCodec* codec = avcodec_find_decoder(codec_context_->codec_id);
+ if (codec) {
+ // MP3 decodes to S16P which we don't support, tell it to use S16 instead.
+ if (codec_context_->sample_fmt == AV_SAMPLE_FMT_S16P)
+diff -Naurp qtwebengine-5.15.10.orig/src/3rdparty/chromium/media/filters/ffmpeg_audio_decoder.cc qtwebengine-5.15.10/src/3rdparty/chromium/media/filters/ffmpeg_audio_decoder.cc
+--- a/src/3rdparty/chromium/media/filters/ffmpeg_audio_decoder.cc 2022-05-23 06:38:40.000000000 -0500
++++ b/src/3rdparty/chromium/media/filters/ffmpeg_audio_decoder.cc 2022-07-11 22:12:47.917192788 -0500
+@@ -329,7 +329,7 @@ bool FFmpegAudioDecoder::ConfigureDecode
+ }
+ }
+
+- AVCodec* codec = avcodec_find_decoder(codec_context_->codec_id);
++ const AVCodec* codec = avcodec_find_decoder(codec_context_->codec_id);
+ if (!codec ||
+ avcodec_open2(codec_context_.get(), codec, &codec_options) < 0) {
+ DLOG(ERROR) << "Could not initialize audio decoder: "
+diff -Naurp qtwebengine-5.15.10.orig/src/3rdparty/chromium/media/filters/ffmpeg_glue.cc qtwebengine-5.15.10/src/3rdparty/chromium/media/filters/ffmpeg_glue.cc
+--- a/src/3rdparty/chromium/media/filters/ffmpeg_glue.cc 2022-05-23 06:38:40.000000000 -0500
++++ b/src/3rdparty/chromium/media/filters/ffmpeg_glue.cc 2022-07-11 22:12:47.918192779 -0500
+@@ -59,7 +59,6 @@ static int64_t AVIOSeekOperation(void* o
+ }
+
+ void FFmpegGlue::InitializeFFmpeg() {
+- av_register_all();
+ }
+
+ static void LogContainer(bool is_local_file,
+@@ -95,9 +94,6 @@ FFmpegGlue::FFmpegGlue(FFmpegURLProtocol
+ // Enable fast, but inaccurate seeks for MP3.
+ format_context_->flags |= AVFMT_FLAG_FAST_SEEK;
+
+- // Ensures we can read out various metadata bits like vp8 alpha.
+- format_context_->flags |= AVFMT_FLAG_KEEP_SIDE_DATA;
+-
+ // Ensures format parsing errors will bail out. From an audit on 11/2017, all
+ // instances were real failures. Solves bugs like http://crbug.com/710791.
+ format_context_->error_recognition |= AV_EF_EXPLODE;
+diff -Naurp qtwebengine-5.15.10.orig/src/3rdparty/chromium/media/filters/ffmpeg_video_decoder.cc qtwebengine-5.15.10/src/3rdparty/chromium/media/filters/ffmpeg_video_decoder.cc
+--- a/src/3rdparty/chromium/media/filters/ffmpeg_video_decoder.cc 2022-05-23 06:38:40.000000000 -0500
++++ b/src/3rdparty/chromium/media/filters/ffmpeg_video_decoder.cc 2022-07-11 22:12:47.918192779 -0500
+@@ -391,7 +391,7 @@ bool FFmpegVideoDecoder::ConfigureDecode
+ if (decode_nalus_)
+ codec_context_->flags2 |= AV_CODEC_FLAG2_CHUNKS;
+
+- AVCodec* codec = avcodec_find_decoder(codec_context_->codec_id);
++ const AVCodec* codec = avcodec_find_decoder(codec_context_->codec_id);
+ if (!codec || avcodec_open2(codec_context_.get(), codec, NULL) < 0) {
+ ReleaseFFmpegResources();
+ return false;
+diff -Naurp qtwebengine-5.15.10.orig/src/3rdparty/chromium/media/filters/media_file_checker.cc qtwebengine-5.15.10/src/3rdparty/chromium/media/filters/media_file_checker.cc
+--- a/src/3rdparty/chromium/media/filters/media_file_checker.cc 2022-05-23 06:38:40.000000000 -0500
++++ b/src/3rdparty/chromium/media/filters/media_file_checker.cc 2022-07-11 22:12:47.918192779 -0500
+@@ -68,7 +68,7 @@ bool MediaFileChecker::Start(base::TimeD
+ auto context = AVStreamToAVCodecContext(format_context->streams[i]);
+ if (!context)
+ continue;
+- AVCodec* codec = avcodec_find_decoder(cp->codec_id);
++ const AVCodec* codec = avcodec_find_decoder(cp->codec_id);
+ if (codec && avcodec_open2(context.get(), codec, nullptr) >= 0) {
+ auto loop = std::make_unique<FFmpegDecodingLoop>(context.get());
+ stream_contexts[i] = {std::move(context), std::move(loop)};
+diff -Naurp qtwebengine-5.15.10.orig/src/3rdparty/chromium/third_party/webrtc/modules/video_coding/codecs/h264/h264_decoder_impl.cc qtwebengine-5.15.10/src/3rdparty/chromium/third_party/webrtc/modules/video_coding/codecs/h264/h264_decoder_impl.cc
+--- a/src/3rdparty/chromium/third_party/webrtc/modules/video_coding/codecs/h264/h264_decoder_impl.cc 2022-05-23 06:38:40.000000000 -0500
++++ b/src/3rdparty/chromium/third_party/webrtc/modules/video_coding/codecs/h264/h264_decoder_impl.cc 2022-07-11 22:12:47.918192779 -0500
+@@ -203,7 +203,7 @@ int32_t H264DecoderImpl::InitDecode(cons
+ // a pointer |this|.
+ av_context_->opaque = this;
+
+- AVCodec* codec = avcodec_find_decoder(av_context_->codec_id);
++ const AVCodec* codec = avcodec_find_decoder(av_context_->codec_id);
+ if (!codec) {
+ // This is an indication that FFmpeg has not been initialized or it has not
+ // been compiled/initialized with the correct set of codecs.
diff --git a/srcpkgs/qt5-webengine/template b/srcpkgs/qt5-webengine/template
index 0a71484208bc..095ab67701e4 100644
--- a/srcpkgs/qt5-webengine/template
+++ b/srcpkgs/qt5-webengine/template
@@ -1,9 +1,9 @@
# Template file for 'qt5-webengine'
pkgname=qt5-webengine
-version=5.15.11
-revision=2
+version=5.15.13
+revision=1
_version="${version}-lts"
-_chromium_commit=be349eaf62e77955791d7bf29f893f1e8a37daf4
+_chromium_commit=e48df7803c7c98b0b2471c94057d32e44a301ad5
archs="x86_64* i686* armv[67]* ppc64* aarch64*"
create_wrksrc=yes
build_style=qmake
@@ -32,8 +32,8 @@ license="GPL-3.0-or-later, LGPL-3.0-or-later"
homepage="https://qt.io/"
distfiles="https://github.com/qt/qtwebengine/archive/v${_version}.tar.gz
https://github.com/qt/qtwebengine-chromium/archive/${_chromium_commit}.tar.gz"
-checksum="aa7466356c450c5f5870f979b93cd7e7e62da1165c328ffcab1a9928db18ad67
- 6f47ed8ab8cc062411f6f206da6353bc8263d6ed6d6290c689a05c01d91f646b"
+checksum="4b59838ed75ef788b59e1e412535a0e42dd9d311661fdeadb191b581ba815c63
+ a91686562b1d4e8b220e0bbcbab5feb64630e2de974b35ac034bf388af771a6c"
no_generic_pkgconfig_link=yes
build_options="sndio pipewire"
From 8dd8e94477a4f061395dfe7e1e8c5a2ef8a2ab46 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:51 -0400
Subject: [PATCH 077/140] qt5: update to 5.15.8
---
...erywhere-opensource-src-5.15.8-kf5-1.patch | 12913 ++++++++++++++++
srcpkgs/qt5/template | 10 +-
2 files changed, 12919 insertions(+), 4 deletions(-)
create mode 100644 srcpkgs/qt5/patches/qt-everywhere-opensource-src-5.15.8-kf5-1.patch
diff --git a/srcpkgs/qt5/patches/qt-everywhere-opensource-src-5.15.8-kf5-1.patch b/srcpkgs/qt5/patches/qt-everywhere-opensource-src-5.15.8-kf5-1.patch
new file mode 100644
index 000000000000..966c98bcd3bb
--- /dev/null
+++ b/srcpkgs/qt5/patches/qt-everywhere-opensource-src-5.15.8-kf5-1.patch
@@ -0,0 +1,12913 @@
+Submitted By: Pierre Labastie <pierre_dot_labastie_at_neuf_dot_fr>
+Date: 2023-01-05
+Initial Package Version: 5.15.8
+Upstream Status: Applied (according to KDE)
+Origin: KDE patch set
+Description: Patch set maintained by the KDE folks
+see https://dot.kde.org/2021/04/06/announcing-kdes-qt-5-patch-collection
+Patch generated using the procedure in
+https://wiki.linuxfromscratch.org/blfs/ticket/17476#comment:3
+
+Submodule qtbase 4ee4fc18..9cf586d6:
+diff --git a/qtbase/mkspecs/common/android/qplatformdefs.h b/qtbase/mkspecs/common/android/qplatformdefs.h
+index f75bc4093b..2bd59410d4 100644
+--- a/qtbase/mkspecs/common/android/qplatformdefs.h
++++ b/qtbase/mkspecs/common/android/qplatformdefs.h
+@@ -144,11 +144,7 @@
+ #define QT_SIGNAL_ARGS int
+ #define QT_SIGNAL_IGNORE SIG_IGN
+
+-#if defined(__GLIBC__) && (__GLIBC__ >= 2)
+ #define QT_SOCKLEN_T socklen_t
+-#else
+-#define QT_SOCKLEN_T int
+-#endif
+
+ #if defined(_XOPEN_SOURCE) && (_XOPEN_SOURCE >= 500)
+ #define QT_SNPRINTF ::snprintf
+diff --git a/qtbase/mkspecs/features/mac/sdk.mk b/qtbase/mkspecs/features/mac/sdk.mk
+index f30b5830b4..a32ceacb6c 100644
+--- a/qtbase/mkspecs/features/mac/sdk.mk
++++ b/qtbase/mkspecs/features/mac/sdk.mk
+@@ -1,6 +1,6 @@
+
+ ifeq ($(QT_MAC_SDK_NO_VERSION_CHECK),)
+- CHECK_SDK_COMMAND = /usr/bin/xcrun --sdk $(EXPORT_QMAKE_MAC_SDK) -show-sdk-version 2>&1
++ CHECK_SDK_COMMAND = /usr/bin/xcrun --sdk $(EXPORT_QMAKE_MAC_SDK) -show-sdk-version 2>/dev/null
+ CURRENT_MAC_SDK_VERSION := $(shell DEVELOPER_DIR=$(EXPORT_QMAKE_XCODE_DEVELOPER_PATH) $(CHECK_SDK_COMMAND))
+ ifneq ($(CURRENT_MAC_SDK_VERSION),$(EXPORT_QMAKE_MAC_SDK_VERSION))
+ # We don't want to complain about out of date SDK unless the target needs to be remade.
+diff --git a/qtbase/mkspecs/linux-clang/qplatformdefs.h b/qtbase/mkspecs/linux-clang/qplatformdefs.h
+index a818d973f0..c1ab72fbc6 100644
+--- a/qtbase/mkspecs/linux-clang/qplatformdefs.h
++++ b/qtbase/mkspecs/linux-clang/qplatformdefs.h
+@@ -79,14 +79,6 @@
+ #define QT_USE_XOPEN_LFS_EXTENSIONS
+ #include "../common/posix/qplatformdefs.h"
+
+-#undef QT_SOCKLEN_T
+-
+-#if defined(__GLIBC__) && (__GLIBC__ >= 2)
+-#define QT_SOCKLEN_T socklen_t
+-#else
+-#define QT_SOCKLEN_T int
+-#endif
+-
+ #if defined(_XOPEN_SOURCE) && (_XOPEN_SOURCE >= 500)
+ #define QT_SNPRINTF ::snprintf
+ #define QT_VSNPRINTF ::vsnprintf
+diff --git a/qtbase/mkspecs/linux-g++/qplatformdefs.h b/qtbase/mkspecs/linux-g++/qplatformdefs.h
+index 13523f0702..4d2750d9ec 100644
+--- a/qtbase/mkspecs/linux-g++/qplatformdefs.h
++++ b/qtbase/mkspecs/linux-g++/qplatformdefs.h
+@@ -79,14 +79,6 @@
+ #define QT_USE_XOPEN_LFS_EXTENSIONS
+ #include "../common/posix/qplatformdefs.h"
+
+-#undef QT_SOCKLEN_T
+-
+-#if defined(__GLIBC__) && (__GLIBC__ < 2)
+-#define QT_SOCKLEN_T int
+-#else
+-#define QT_SOCKLEN_T socklen_t
+-#endif
+-
+ #if defined(_XOPEN_SOURCE) && (_XOPEN_SOURCE >= 500)
+ #define QT_SNPRINTF ::snprintf
+ #define QT_VSNPRINTF ::vsnprintf
+diff --git a/qtbase/mkspecs/linux-llvm/qplatformdefs.h b/qtbase/mkspecs/linux-llvm/qplatformdefs.h
+index dc750ab1ef..d3cc39b47f 100644
+--- a/qtbase/mkspecs/linux-llvm/qplatformdefs.h
++++ b/qtbase/mkspecs/linux-llvm/qplatformdefs.h
+@@ -80,14 +80,6 @@
+ #define QT_USE_XOPEN_LFS_EXTENSIONS
+ #include "../common/posix/qplatformdefs.h"
+
+-#undef QT_SOCKLEN_T
+-
+-#if defined(__GLIBC__) && (__GLIBC__ >= 2)
+-#define QT_SOCKLEN_T socklen_t
+-#else
+-#define QT_SOCKLEN_T int
+-#endif
+-
+ #if defined(_XOPEN_SOURCE) && (_XOPEN_SOURCE >= 500)
+ #define QT_SNPRINTF ::snprintf
+ #define QT_VSNPRINTF ::vsnprintf
+diff --git a/qtbase/mkspecs/linux-lsb-g++/qplatformdefs.h b/qtbase/mkspecs/linux-lsb-g++/qplatformdefs.h
+index 4c4e53da2a..83baffb3e3 100644
+--- a/qtbase/mkspecs/linux-lsb-g++/qplatformdefs.h
++++ b/qtbase/mkspecs/linux-lsb-g++/qplatformdefs.h
+@@ -85,16 +85,9 @@
+ #include "../common/posix/qplatformdefs.h"
+
+ #undef QT_OPEN_LARGEFILE
+-#undef QT_SOCKLEN_T
+
+ #define QT_OPEN_LARGEFILE 0
+
+-#if defined(__GLIBC__) && (__GLIBC__ >= 2)
+-#define QT_SOCKLEN_T socklen_t
+-#else
+-#define QT_SOCKLEN_T int
+-#endif
+-
+ #ifndef SIOCGIFBRDADDR
+ # define SIOCGIFBRDADDR 0x8919
+ #endif
+diff --git a/qtbase/mkspecs/lynxos-g++/qplatformdefs.h b/qtbase/mkspecs/lynxos-g++/qplatformdefs.h
+index 4339ea2b23..6007af0055 100644
+--- a/qtbase/mkspecs/lynxos-g++/qplatformdefs.h
++++ b/qtbase/mkspecs/lynxos-g++/qplatformdefs.h
+@@ -72,14 +72,6 @@
+
+ #include "../common/posix/qplatformdefs.h"
+
+-#undef QT_SOCKLEN_T
+-
+-#if defined(__GLIBC__) && (__GLIBC__ >= 2)
+-#define QT_SOCKLEN_T socklen_t
+-#else
+-#define QT_SOCKLEN_T int
+-#endif
+-
+ #if defined(_XOPEN_SOURCE) && (_XOPEN_SOURCE >= 500)
+ #define QT_SNPRINTF ::snprintf
+ #define QT_VSNPRINTF ::vsnprintf
+diff --git a/qtbase/src/3rdparty/angle/src/libANGLE/HandleAllocator.cpp b/qtbase/src/3rdparty/angle/src/libANGLE/HandleAllocator.cpp
+index c3c184258f..32af3f8f29 100644
+--- a/qtbase/src/3rdparty/angle/src/libANGLE/HandleAllocator.cpp
++++ b/qtbase/src/3rdparty/angle/src/libANGLE/HandleAllocator.cpp
+@@ -10,6 +10,7 @@
+ #include "libANGLE/HandleAllocator.h"
+
+ #include <algorithm>
++#include <limits>
+
+ #include "common/debug.h"
+
+diff --git a/qtbase/src/3rdparty/forkfd/forkfd_linux.c b/qtbase/src/3rdparty/forkfd/forkfd_linux.c
+index ffe0e9a5e2..b1f5408d11 100644
+--- a/qtbase/src/3rdparty/forkfd/forkfd_linux.c
++++ b/qtbase/src/3rdparty/forkfd/forkfd_linux.c
+@@ -82,7 +82,8 @@ static int sys_clone(unsigned long cloneflags, int *ptid)
+ return syscall(__NR_clone, cloneflags, child_stack, stack_size, ptid, newtls, ctid);
+ #elif defined(__arc__) || defined(__arm__) || defined(__aarch64__) || defined(__mips__) || \
+ defined(__nds32__) || defined(__hppa__) || defined(__powerpc__) || defined(__i386__) || \
+- defined(__x86_64__) || defined(__xtensa__) || defined(__alpha__) || defined(__riscv)
++ defined(__x86_64__) || defined(__xtensa__) || defined(__alpha__) || defined(__riscv) || \
++ defined(__loongarch__)
+ /* ctid and newtls are inverted on CONFIG_CLONE_BACKWARDS architectures,
+ * but since both values are 0, there's no harm. */
+ return syscall(__NR_clone, cloneflags, child_stack, ptid, ctid, newtls);
+diff --git a/qtbase/src/android/jar/src/org/qtproject/qt5/android/QtNative.java b/qtbase/src/android/jar/src/org/qtproject/qt5/android/QtNative.java
+index 5792b5b2f5..2f74750fcf 100644
+--- a/qtbase/src/android/jar/src/org/qtproject/qt5/android/QtNative.java
++++ b/qtbase/src/android/jar/src/org/qtproject/qt5/android/QtNative.java
+@@ -116,6 +116,7 @@ public class QtNative
+ public static QtThread m_qtThread = new QtThread();
+ private static HashMap<String, Uri> m_cachedUris = new HashMap<String, Uri>();
+ private static ArrayList<String> m_knownDirs = new ArrayList<String>();
++ private static final String NoPermissionErrorMessage = "No permissions to open Uri";
+
+ private static final Runnable runPendingCppRunnablesRunnable = new Runnable() {
+ @Override
+@@ -193,11 +194,10 @@ public class QtNative
+ return iterUri;
+ }
+
+- // Android 6 and earlier could still manage to open the file so we can return the
+- // parsed uri here
+- if (Build.VERSION.SDK_INT < 24)
+- return parsedUri;
+- return null;
++ // if we only have transient permissions on uri all the above will fail,
++ // but we will be able to read the file anyway, so continue with uri here anyway
++ // and check for SecurityExceptions later
++ return parsedUri;
+ } catch (SecurityException e) {
+ e.printStackTrace();
+ return null;
+@@ -244,7 +244,7 @@ public class QtNative
+ int error = -1;
+
+ if (uri == null) {
+- Log.e(QtTAG, "openFdForContentUrl(): No permissions to open Uri");
++ Log.e(QtTAG, "openFdForContentUrl(): " + NoPermissionErrorMessage);
+ return error;
+ }
+
+@@ -254,12 +254,13 @@ public class QtNative
+ return fdDesc.detachFd();
+ } catch (FileNotFoundException e) {
+ e.printStackTrace();
+- return error;
+ } catch (IllegalArgumentException e) {
+ Log.e(QtTAG, "openFdForContentUrl(): Invalid Uri");
+ e.printStackTrace();
+- return error;
++ } catch (SecurityException e) {
++ Log.e(QtTAG, NoPermissionErrorMessage);
+ }
++ return error;
+ }
+
+ public static long getSize(Context context, String contentUrl)
+@@ -270,7 +271,7 @@ public class QtNative
+ uri = getUriWithValidPermission(context, contentUrl, "r");
+
+ if (uri == null) {
+- Log.e(QtTAG, "getSize(): No permissions to open Uri");
++ Log.e(QtTAG, NoPermissionErrorMessage);
+ return size;
+ } else if (!m_cachedUris.containsKey(contentUrl)) {
+ m_cachedUris.put(contentUrl, uri);
+@@ -288,12 +289,13 @@ public class QtNative
+ } catch (IllegalArgumentException e) {
+ Log.e(QtTAG, "getSize(): Invalid Uri");
+ e.printStackTrace();
+- return size;
+ } catch (UnsupportedOperationException e) {
+ Log.e(QtTAG, "getSize(): Unsupported operation for given Uri");
+ e.printStackTrace();
+- return size;
++ } catch (SecurityException e) {
++ Log.e(QtTAG, NoPermissionErrorMessage);
+ }
++ return size;
+ }
+
+ public static boolean checkFileExists(Context context, String contentUrl)
+@@ -303,7 +305,7 @@ public class QtNative
+ if (uri == null)
+ uri = getUriWithValidPermission(context, contentUrl, "r");
+ if (uri == null) {
+- Log.e(QtTAG, "checkFileExists(): No permissions to open Uri");
++ Log.e(QtTAG, NoPermissionErrorMessage);
+ return exists;
+ } else {
+ if (!m_cachedUris.containsKey(contentUrl))
+@@ -321,12 +323,13 @@ public class QtNative
+ } catch (IllegalArgumentException e) {
+ Log.e(QtTAG, "checkFileExists(): Invalid Uri");
+ e.printStackTrace();
+- return exists;
+ } catch (UnsupportedOperationException e) {
+ Log.e(QtTAG, "checkFileExists(): Unsupported operation for given Uri");
+ e.printStackTrace();
+- return false;
++ } catch (SecurityException e) {
++ Log.e(QtTAG, NoPermissionErrorMessage);
+ }
++ return exists;
+ }
+
+ public static boolean checkIfWritable(Context context, String contentUrl)
+@@ -344,7 +347,7 @@ public class QtNative
+ uri = getUriWithValidPermission(context, contentUrl, "r");
+ }
+ if (uri == null) {
+- Log.e(QtTAG, "isDir(): No permissions to open Uri");
++ Log.e(QtTAG, NoPermissionErrorMessage);
+ return isDir;
+ } else {
+ if (!m_cachedUris.containsKey(contentUrl))
+@@ -374,12 +377,13 @@ public class QtNative
+ } catch (IllegalArgumentException e) {
+ Log.e(QtTAG, "checkIfDir(): Invalid Uri");
+ e.printStackTrace();
+- return false;
+ } catch (UnsupportedOperationException e) {
+ Log.e(QtTAG, "checkIfDir(): Unsupported operation for given Uri");
+ e.printStackTrace();
+- return false;
++ } catch (SecurityException e) {
++ Log.e(QtTAG, NoPermissionErrorMessage);
+ }
++ return false;
+ }
+ public static String[] listContentsFromTreeUri(Context context, String contentUrl)
+ {
+diff --git a/qtbase/src/concurrent/qtconcurrentreducekernel.h b/qtbase/src/concurrent/qtconcurrentreducekernel.h
+index 8f9a938952..a98dedef2e 100644
+--- a/qtbase/src/concurrent/qtconcurrentreducekernel.h
++++ b/qtbase/src/concurrent/qtconcurrentreducekernel.h
+@@ -212,11 +212,13 @@ public:
+
+ inline bool shouldThrottle()
+ {
++ std::lock_guard<QMutex> locker(mutex);
+ return (resultsMapSize > (ReduceQueueThrottleLimit * threadCount));
+ }
+
+ inline bool shouldStartThread()
+ {
++ std::lock_guard<QMutex> locker(mutex);
+ return (resultsMapSize <= (ReduceQueueStartLimit * threadCount));
+ }
+ };
+diff --git a/qtbase/src/concurrent/qtconcurrentthreadengine.cpp b/qtbase/src/concurrent/qtconcurrentthreadengine.cpp
+index ea6ce3ac42..7f91a2ba68 100644
+--- a/qtbase/src/concurrent/qtconcurrentthreadengine.cpp
++++ b/qtbase/src/concurrent/qtconcurrentthreadengine.cpp
+@@ -176,6 +176,39 @@ void ThreadEngineBase::startSingleThreaded()
+ finish();
+ }
+
++void ThreadEngineBase::startBlocking()
++{
++ start();
++ barrier.acquire();
++ startThreads();
++
++ bool throttled = false;
++#ifndef QT_NO_EXCEPTIONS
++ try {
++#endif
++ while (threadFunction() == ThrottleThread) {
++ if (threadThrottleExit()) {
++ throttled = true;
++ break;
++ }
++ }
++#ifndef QT_NO_EXCEPTIONS
++ } catch (QException &e) {
++ handleException(e);
++ } catch (...) {
++ handleException(QUnhandledException());
++ }
++#endif
++
++ if (throttled == false) {
++ barrier.release();
++ }
++
++ barrier.wait();
++ finish();
++ exceptionStore.throwPossibleException();
++}
++
+ void ThreadEngineBase::startThread()
+ {
+ startThreadInternal();
+diff --git a/qtbase/src/concurrent/qtconcurrentthreadengine.h b/qtbase/src/concurrent/qtconcurrentthreadengine.h
+index 7c30cebdbc..a4c8548cc4 100644
+--- a/qtbase/src/concurrent/qtconcurrentthreadengine.h
++++ b/qtbase/src/concurrent/qtconcurrentthreadengine.h
+@@ -91,6 +91,7 @@ public:
+ ThreadEngineBase();
+ virtual ~ThreadEngineBase();
+ void startSingleThreaded();
++ void startBlocking();
+ void startThread();
+ bool isCanceled();
+ void waitForResume();
+@@ -143,6 +144,15 @@ public:
+ return result();
+ }
+
++ // Runs the user algorithm using multiple threads.
++ // This function blocks until the algorithm is finished,
++ // and then returns the result.
++ T *startBlocking()
++ {
++ ThreadEngineBase::startBlocking();
++ return result();
++ }
++
+ // Runs the user algorithm using multiple threads.
+ // Does not block, returns a future.
+ QFuture<T> startAsynchronously()
+@@ -223,6 +233,13 @@ class ThreadEngineStarter : public ThreadEngineStarterBase<T>
+ public:
+ ThreadEngineStarter(TypedThreadEngine *eng)
+ : Base(eng) { }
++
++ T startBlocking()
++ {
++ T t = *this->threadEngine->startBlocking();
++ delete this->threadEngine;
++ return t;
++ }
+ };
+
+ // Full template specialization where T is void.
+@@ -232,6 +249,12 @@ class ThreadEngineStarter<void> : public ThreadEngineStarterBase<void>
+ public:
+ ThreadEngineStarter(ThreadEngine<void> *_threadEngine)
+ : ThreadEngineStarterBase<void>(_threadEngine) {}
++
++ void startBlocking()
++ {
++ this->threadEngine->startBlocking();
++ delete this->threadEngine;
++ }
+ };
+
+ //! [qtconcurrentthreadengine-1]
+diff --git a/qtbase/src/corelib/animation/qvariantanimation.cpp b/qtbase/src/corelib/animation/qvariantanimation.cpp
+index 98b02f0202..eac1524107 100644
+--- a/qtbase/src/corelib/animation/qvariantanimation.cpp
++++ b/qtbase/src/corelib/animation/qvariantanimation.cpp
+@@ -276,7 +276,9 @@ void QVariantAnimationPrivate::setCurrentValueForProgress(const qreal progress)
+
+ const qreal startProgress = currentInterval.start.first;
+ const qreal endProgress = currentInterval.end.first;
+- const qreal localProgress = (progress - startProgress) / (endProgress - startProgress);
++ const qreal localProgress =
++ qIsNull(progress - startProgress) ? 0.0 // avoid 0/0 below
++ /* else */ : (progress - startProgress) / (endProgress - startProgress);
+
+ QVariant ret = q->interpolated(currentInterval.start.second,
+ currentInterval.end.second,
+diff --git a/qtbase/src/corelib/global/qnamespace.h b/qtbase/src/corelib/global/qnamespace.h
+index ad4150b317..bf19b1627b 100644
+--- a/qtbase/src/corelib/global/qnamespace.h
++++ b/qtbase/src/corelib/global/qnamespace.h
+@@ -1864,7 +1864,7 @@ public:
+ QT_Q_ENUM(TimerType)
+ QT_Q_ENUM(ScrollPhase)
+ QT_Q_ENUM(MouseEventSource)
+- QT_Q_FLAG(MouseEventFlag)
++ QT_Q_FLAG(MouseEventFlags)
+ QT_Q_ENUM(ChecksumType)
+ QT_Q_ENUM(HighDpiScaleFactorRoundingPolicy)
+ QT_Q_ENUM(TabFocusBehavior)
+diff --git a/qtbase/src/corelib/global/qrandom.cpp b/qtbase/src/corelib/global/qrandom.cpp
+index 10672c1f92..25f87c7e6a 100644
+--- a/qtbase/src/corelib/global/qrandom.cpp
++++ b/qtbase/src/corelib/global/qrandom.cpp
+@@ -383,7 +383,6 @@ struct QRandomGenerator::SystemAndGlobalGenerators
+
+ constexpr SystemAndGlobalGenerators g = {};
+ Q_UNUSED(g);
+- Q_STATIC_ASSERT(std::is_literal_type<SystemAndGlobalGenerators>::value);
+ #endif
+ }
+
+diff --git a/qtbase/src/corelib/io/qbuffer.cpp b/qtbase/src/corelib/io/qbuffer.cpp
+index 595fcd2724..032c0ddd4b 100644
+--- a/qtbase/src/corelib/io/qbuffer.cpp
++++ b/qtbase/src/corelib/io/qbuffer.cpp
+@@ -41,6 +41,8 @@
+ #include <QtCore/qmetaobject.h>
+ #include "private/qiodevice_p.h"
+
++#include <limits>
++
+ QT_BEGIN_NAMESPACE
+
+ /** QBufferPrivate **/
+@@ -366,7 +368,9 @@ qint64 QBuffer::size() const
+ bool QBuffer::seek(qint64 pos)
+ {
+ Q_D(QBuffer);
+- if (pos > d->buf->size() && isWritable()) {
++ const auto oldBufSize = d->buf->size();
++ constexpr qint64 MaxSeekPos = (std::numeric_limits<decltype(oldBufSize)>::max)();
++ if (pos <= MaxSeekPos && pos > oldBufSize && isWritable()) {
+ if (seek(d->buf->size())) {
+ const qint64 gapSize = pos - d->buf->size();
+ if (write(QByteArray(gapSize, 0)) != gapSize) {
+@@ -377,7 +381,7 @@ bool QBuffer::seek(qint64 pos)
+ return false;
+ }
+ } else if (pos > d->buf->size() || pos < 0) {
+- qWarning("QBuffer::seek: Invalid pos: %d", int(pos));
++ qWarning("QBuffer::seek: Invalid pos: %lld", pos);
+ return false;
+ }
+ return QIODevice::seek(pos);
+diff --git a/qtbase/src/corelib/io/qfilesystemengine_win.cpp b/qtbase/src/corelib/io/qfilesystemengine_win.cpp
+index 81d3a71986..c86ed1f9b0 100644
+--- a/qtbase/src/corelib/io/qfilesystemengine_win.cpp
++++ b/qtbase/src/corelib/io/qfilesystemengine_win.cpp
+@@ -664,14 +664,14 @@ QFileSystemEntry QFileSystemEngine::absoluteName(const QFileSystemEntry &entry)
+ return QFileSystemEntry(ret, QFileSystemEntry::FromInternalPath());
+ }
+
+-#if defined(Q_CC_MINGW) && WINVER < 0x0602 // Windows 8 onwards
++#if defined(Q_CC_MINGW) && WINVER < 0x0602 && _WIN32_WINNT < _WIN32_WINNT_WIN8 // Windows 8 onwards
+
+ typedef struct _FILE_ID_INFO {
+ ULONGLONG VolumeSerialNumber;
+ FILE_ID_128 FileId;
+ } FILE_ID_INFO, *PFILE_ID_INFO;
+
+-#endif // if defined (Q_CC_MINGW) && WINVER < 0x0602
++#endif // if defined(Q_CC_MINGW) && WINVER < 0x0602 && _WIN32_WINNT < _WIN32_WINNT_WIN8
+
+ // File ID for Windows up to version 7 and FAT32 drives
+ static inline QByteArray fileId(HANDLE handle)
+diff --git a/qtbase/src/corelib/io/qfilesystemwatcher_inotify.cpp b/qtbase/src/corelib/io/qfilesystemwatcher_inotify.cpp
+index 94d9d06bcb..27e0b13b0b 100644
+--- a/qtbase/src/corelib/io/qfilesystemwatcher_inotify.cpp
++++ b/qtbase/src/corelib/io/qfilesystemwatcher_inotify.cpp
+@@ -366,7 +366,9 @@ void QInotifyFileSystemWatcherEngine::readFromInotify()
+ // qDebug("QInotifyFileSystemWatcherEngine::readFromInotify");
+
+ int buffSize = 0;
+- ioctl(inotifyFd, FIONREAD, (char *) &buffSize);
++ if (ioctl(inotifyFd, FIONREAD, (char *) &buffSize) == -1 || buffSize == 0)
++ return;
++
+ QVarLengthArray<char, 4096> buffer(buffSize);
+ buffSize = read(inotifyFd, buffer.data(), buffSize);
+ char *at = buffer.data();
+diff --git a/qtbase/src/corelib/io/qlockfile_win.cpp b/qtbase/src/corelib/io/qlockfile_win.cpp
+index 277f8d4230..38ecef5550 100644
+--- a/qtbase/src/corelib/io/qlockfile_win.cpp
++++ b/qtbase/src/corelib/io/qlockfile_win.cpp
+@@ -48,6 +48,8 @@
+ #include "QtCore/qdebug.h"
+ #include "QtCore/qthread.h"
+
++#include "private/qsystemlibrary_p.h"
++
+ QT_BEGIN_NAMESPACE
+
+ static inline bool fileExists(const wchar_t *fileName)
+@@ -150,7 +152,7 @@ QString QLockFilePrivate::processNameByPid(qint64 pid)
+ #if !defined(Q_OS_WINRT)
+ typedef DWORD (WINAPI *GetModuleFileNameExFunc)(HANDLE, HMODULE, LPTSTR, DWORD);
+
+- HMODULE hPsapi = LoadLibraryA("psapi");
++ HMODULE hPsapi = QSystemLibrary::load(L"psapi");
+ if (!hPsapi)
+ return QString();
+ GetModuleFileNameExFunc qGetModuleFileNameEx = reinterpret_cast<GetModuleFileNameExFunc>(
+diff --git a/qtbase/src/corelib/io/qprocess_unix.cpp b/qtbase/src/corelib/io/qprocess_unix.cpp
+index 50390e57f5..15c8f30745 100644
+--- a/qtbase/src/corelib/io/qprocess_unix.cpp
++++ b/qtbase/src/corelib/io/qprocess_unix.cpp
+@@ -1,7 +1,7 @@
+ /****************************************************************************
+ **
+ ** Copyright (C) 2016 The Qt Company Ltd.
+-** Copyright (C) 2016 Intel Corporation.
++** Copyright (C) 2022 Intel Corporation.
+ ** Contact: https://www.qt.io/licensing/
+ **
+ ** This file is part of the QtCore module of the Qt Toolkit.
+@@ -422,14 +422,15 @@ void QProcessPrivate::startProcess()
+ // Add the program name to the argument list.
+ argv[0] = nullptr;
+ if (!program.contains(QLatin1Char('/'))) {
++ // findExecutable() returns its argument if it's an absolute path,
++ // otherwise it searches $PATH; returns empty if not found (we handle
++ // that case much later)
+ const QString &exeFilePath = QStandardPaths::findExecutable(program);
+- if (!exeFilePath.isEmpty()) {
+- const QByteArray &tmp = QFile::encodeName(exeFilePath);
+- argv[0] = ::strdup(tmp.constData());
+- }
+- }
+- if (!argv[0])
++ const QByteArray &tmp = QFile::encodeName(exeFilePath);
++ argv[0] = ::strdup(tmp.constData());
++ } else {
+ argv[0] = ::strdup(encodedProgramName.constData());
++ }
+
+ // Add every argument to the list
+ for (int i = 0; i < arguments.count(); ++i)
+@@ -983,15 +984,16 @@ bool QProcessPrivate::startDetached(qint64 *pid)
+ envp = _q_dupEnvironment(environment.d.constData()->vars, &envc);
+ }
+
+- QByteArray tmp;
+ if (!program.contains(QLatin1Char('/'))) {
++ // findExecutable() returns its argument if it's an absolute path,
++ // otherwise it searches $PATH; returns empty if not found (we handle
++ // that case much later)
+ const QString &exeFilePath = QStandardPaths::findExecutable(program);
+- if (!exeFilePath.isEmpty())
+- tmp = QFile::encodeName(exeFilePath);
++ const QByteArray &tmp = QFile::encodeName(exeFilePath);
++ argv[0] = ::strdup(tmp.constData());
++ } else {
++ argv[0] = ::strdup(QFile::encodeName(program));
+ }
+- if (tmp.isEmpty())
+- tmp = QFile::encodeName(program);
+- argv[0] = tmp.data();
+
+ if (envp)
+ qt_safe_execve(argv[0], argv, envp);
+diff --git a/qtbase/src/corelib/itemmodels/qabstractitemmodel.cpp b/qtbase/src/corelib/itemmodels/qabstractitemmodel.cpp
+index 3a79c502af..997a634e76 100644
+--- a/qtbase/src/corelib/itemmodels/qabstractitemmodel.cpp
++++ b/qtbase/src/corelib/itemmodels/qabstractitemmodel.cpp
+@@ -3196,9 +3196,8 @@ bool QAbstractItemModel::beginMoveColumns(const QModelIndex &sourceParent, int s
+ destinationChange.needsAdjust = destinationParent.isValid() && destinationParent.row() >= sourceLast && destinationParent.parent() == sourceParent;
+ d->changes.push(destinationChange);
+
+- d->itemsAboutToBeMoved(sourceParent, sourceFirst, sourceLast, destinationParent, destinationChild, Qt::Horizontal);
+-
+ emit columnsAboutToBeMoved(sourceParent, sourceFirst, sourceLast, destinationParent, destinationChild, QPrivateSignal());
++ d->itemsAboutToBeMoved(sourceParent, sourceFirst, sourceLast, destinationParent, destinationChild, Qt::Horizontal);
+ return true;
+ }
+
+@@ -3231,7 +3230,6 @@ void QAbstractItemModel::endMoveColumns()
+ adjustedSource = createIndex(adjustedSource.row(), adjustedSource.column() + numMoved, adjustedSource.internalPointer());
+
+ d->itemsMoved(adjustedSource, removeChange.first, removeChange.last, adjustedDestination, insertChange.first, Qt::Horizontal);
+-
+ emit columnsMoved(adjustedSource, removeChange.first, removeChange.last, adjustedDestination, insertChange.first, QPrivateSignal());
+ }
+
+diff --git a/qtbase/src/corelib/itemmodels/qsortfilterproxymodel.cpp b/qtbase/src/corelib/itemmodels/qsortfilterproxymodel.cpp
+index dc6379d9fb..c5e287ee84 100644
+--- a/qtbase/src/corelib/itemmodels/qsortfilterproxymodel.cpp
++++ b/qtbase/src/corelib/itemmodels/qsortfilterproxymodel.cpp
+@@ -939,8 +939,9 @@ void QSortFilterProxyModelPrivate::insert_source_items(
+ q->beginInsertColumns(proxy_parent, proxy_start, proxy_end);
+ }
+
+- for (int i = 0; i < source_items.size(); ++i)
+- proxy_to_source.insert(proxy_start + i, source_items.at(i));
++ // TODO: use the range QList::insert() overload once it is implemented (QTBUG-58633).
++ proxy_to_source.insert(proxy_start, source_items.size(), 0);
++ std::copy(source_items.cbegin(), source_items.cend(), proxy_to_source.begin() + proxy_start);
+
+ build_source_to_proxy_mapping(proxy_to_source, source_to_proxy);
+
+@@ -3123,8 +3124,9 @@ bool QSortFilterProxyModel::filterAcceptsRow(int source_row, const QModelIndex &
+
+ if (d->filter_data.isEmpty())
+ return true;
++
++ int column_count = d->model->columnCount(source_parent);
+ if (d->filter_column == -1) {
+- int column_count = d->model->columnCount(source_parent);
+ for (int column = 0; column < column_count; ++column) {
+ QModelIndex source_index = d->model->index(source_row, column, source_parent);
+ QString key = d->model->data(source_index, d->filter_role).toString();
+@@ -3133,9 +3135,10 @@ bool QSortFilterProxyModel::filterAcceptsRow(int source_row, const QModelIndex &
+ }
+ return false;
+ }
+- QModelIndex source_index = d->model->index(source_row, d->filter_column, source_parent);
+- if (!source_index.isValid()) // the column may not exist
++
++ if (d->filter_column >= column_count) // the column may not exist
+ return true;
++ QModelIndex source_index = d->model->index(source_row, d->filter_column, source_parent);
+ QString key = d->model->data(source_index, d->filter_role).toString();
+ return d->filter_data.hasMatch(key);
+ }
+diff --git a/qtbase/src/corelib/kernel/qcoreapplication.cpp b/qtbase/src/corelib/kernel/qcoreapplication.cpp
+index ca2864df83..132b2eae52 100644
+--- a/qtbase/src/corelib/kernel/qcoreapplication.cpp
++++ b/qtbase/src/corelib/kernel/qcoreapplication.cpp
+@@ -1157,7 +1157,7 @@ static bool doNotify(QObject *receiver, QEvent *event)
+ bool QCoreApplicationPrivate::sendThroughApplicationEventFilters(QObject *receiver, QEvent *event)
+ {
+ // We can't access the application event filters outside of the main thread (race conditions)
+- Q_ASSERT(receiver->d_func()->threadData.loadRelaxed()->thread.loadAcquire() == mainThread());
++ Q_ASSERT(receiver->d_func()->threadData.loadAcquire()->thread.loadRelaxed() == mainThread());
+
+ if (extraData) {
+ // application event filters are only called for objects in the GUI thread
+diff --git a/qtbase/src/corelib/kernel/qobject.cpp b/qtbase/src/corelib/kernel/qobject.cpp
+index 1eb79138d9..36cd780ee1 100644
+--- a/qtbase/src/corelib/kernel/qobject.cpp
++++ b/qtbase/src/corelib/kernel/qobject.cpp
+@@ -1010,7 +1010,7 @@ QObject::~QObject()
+ emit destroyed(this);
+ }
+
+- if (d->declarativeData) {
++ if (!d->isDeletingChildren && d->declarativeData) {
+ if (static_cast<QAbstractDeclarativeDataImpl*>(d->declarativeData)->ownedByQml1) {
+ if (QAbstractDeclarativeData::destroyed_qml1)
+ QAbstractDeclarativeData::destroyed_qml1(d->declarativeData, this);
+@@ -1580,7 +1580,7 @@ void QObject::moveToThread(QThread *targetThread)
+
+ QThreadData *currentData = QThreadData::current();
+ QThreadData *targetData = targetThread ? QThreadData::get2(targetThread) : nullptr;
+- QThreadData *thisThreadData = d->threadData.loadRelaxed();
++ QThreadData *thisThreadData = d->threadData.loadAcquire();
+ if (!thisThreadData->thread.loadAcquire() && currentData == targetData) {
+ // one exception to the rule: we allow moving objects with no thread affinity to the current thread
+ currentData = d->threadData;
+@@ -2620,7 +2620,7 @@ int QObject::receivers(const char *signal) const
+ if (!d->isSignalConnected(signal_index))
+ return receivers;
+
+- if (d->declarativeData && QAbstractDeclarativeData::receivers) {
++ if (!d->isDeletingChildren && d->declarativeData && QAbstractDeclarativeData::receivers) {
+ receivers += QAbstractDeclarativeData::receivers(d->declarativeData, this,
+ signal_index);
+ }
+diff --git a/qtbase/src/corelib/kernel/qobject_p.h b/qtbase/src/corelib/kernel/qobject_p.h
+index 0b827a52ca..13ffb88999 100644
+--- a/qtbase/src/corelib/kernel/qobject_p.h
++++ b/qtbase/src/corelib/kernel/qobject_p.h
+@@ -444,7 +444,7 @@ inline void QObjectPrivate::checkForIncompatibleLibraryVersion(int version) cons
+
+ inline bool QObjectPrivate::isDeclarativeSignalConnected(uint signal_index) const
+ {
+- return declarativeData && QAbstractDeclarativeData::isSignalConnected
++ return !isDeletingChildren && declarativeData && QAbstractDeclarativeData::isSignalConnected
+ && QAbstractDeclarativeData::isSignalConnected(declarativeData, q_func(), signal_index);
+ }
+
+diff --git a/qtbase/src/corelib/kernel/qtranslator.cpp b/qtbase/src/corelib/kernel/qtranslator.cpp
+index 2812ffb7ea..bc0177c5ec 100644
+--- a/qtbase/src/corelib/kernel/qtranslator.cpp
++++ b/qtbase/src/corelib/kernel/qtranslator.cpp
+@@ -902,7 +902,7 @@ static QString getMessage(const uchar *m, const uchar *end, const char *context,
+ goto end;
+ case Tag_Translation: {
+ int len = read32(m);
+- if (len % 1)
++ if (len & 1)
+ return QString();
+ m += 4;
+ if (!numerus--) {
+diff --git a/qtbase/src/corelib/mimetypes/qmimedatabase.cpp b/qtbase/src/corelib/mimetypes/qmimedatabase.cpp
+index 9de22cef33..ff868a3268 100644
+--- a/qtbase/src/corelib/mimetypes/qmimedatabase.cpp
++++ b/qtbase/src/corelib/mimetypes/qmimedatabase.cpp
+@@ -389,20 +389,23 @@ QMimeType QMimeDatabasePrivate::mimeTypeForFileNameAndData(const QString &fileNa
+ // Disambiguate conflicting extensions (if magic matching found something)
+ if (candidateByData.isValid() && magicAccuracy > 0) {
+ const QString sniffedMime = candidateByData.name();
+- // If the sniffedMime matches a glob match, use it
++ // If the sniffedMime matches a highest-weight glob match, use it
+ if (candidatesByName.m_matchingMimeTypes.contains(sniffedMime)) {
+ *accuracyPtr = 100;
+ return candidateByData;
+ }
+- for (const QString &m : qAsConst(candidatesByName.m_matchingMimeTypes)) {
++ for (const QString &m : qAsConst(candidatesByName.m_allMatchingMimeTypes)) {
+ if (inherits(m, sniffedMime)) {
+ // We have magic + pattern pointing to this, so it's a pretty good match
+ *accuracyPtr = 100;
+ return mimeTypeForName(m);
+ }
+ }
+- *accuracyPtr = magicAccuracy;
+- return candidateByData;
++ if (candidatesByName.m_allMatchingMimeTypes.isEmpty()) {
++ // No glob, use magic
++ *accuracyPtr = magicAccuracy;
++ return candidateByData;
++ }
+ }
+ }
+
+diff --git a/qtbase/src/corelib/mimetypes/qmimeglobpattern.cpp b/qtbase/src/corelib/mimetypes/qmimeglobpattern.cpp
+index a81112d227..fa8f4c545d 100644
+--- a/qtbase/src/corelib/mimetypes/qmimeglobpattern.cpp
++++ b/qtbase/src/corelib/mimetypes/qmimeglobpattern.cpp
+@@ -83,7 +83,10 @@ void QMimeGlobMatchResult::addMatch(const QString &mimeType, int weight, const Q
+ }
+ if (!m_matchingMimeTypes.contains(mimeType)) {
+ m_matchingMimeTypes.append(mimeType);
+- m_allMatchingMimeTypes.append(mimeType);
++ if (replace)
++ m_allMatchingMimeTypes.prepend(mimeType); // highest-weight first
++ else
++ m_allMatchingMimeTypes.append(mimeType);
+ m_knownSuffixLength = knownSuffixLength;
+ }
+ }
+@@ -94,7 +97,7 @@ QMimeGlobPattern::PatternType QMimeGlobPattern::detectPatternType(const QString
+ if (!patternLength)
+ return OtherPattern;
+
+- const bool starCount = pattern.count(QLatin1Char('*')) == 1;
++ const int starCount = pattern.count(QLatin1Char('*'));
+ const bool hasSquareBracket = pattern.indexOf(QLatin1Char('[')) != -1;
+ const bool hasQuestionMark = pattern.indexOf(QLatin1Char('?')) != -1;
+
+@@ -106,10 +109,10 @@ QMimeGlobPattern::PatternType QMimeGlobPattern::detectPatternType(const QString
+ // Patterns like "README*" (well this is currently the only one like that...)
+ if (pattern.at(patternLength - 1) == QLatin1Char('*'))
+ return PrefixPattern;
+- }
+- // Names without any wildcards like "README"
+- if (starCount == 0)
++ } else if (starCount == 0) {
++ // Names without any wildcards like "README"
+ return LiteralPattern;
++ }
+ }
+
+ if (pattern == QLatin1String("[0-9][0-9][0-9].vdr"))
+diff --git a/qtbase/src/corelib/mimetypes/qmimeprovider.cpp b/qtbase/src/corelib/mimetypes/qmimeprovider.cpp
+index 258dddf8cb..4642d0f2d0 100644
+--- a/qtbase/src/corelib/mimetypes/qmimeprovider.cpp
++++ b/qtbase/src/corelib/mimetypes/qmimeprovider.cpp
+@@ -244,15 +244,18 @@ void QMimeBinaryProvider::addFileNameMatches(const QString &fileName, QMimeGlobM
+ const QString lowerFileName = fileName.toLower();
+ // Check literals (e.g. "Makefile")
+ matchGlobList(result, m_cacheFile, m_cacheFile->getUint32(PosLiteralListOffset), fileName);
+- // Check complex globs (e.g. "callgrind.out[0-9]*")
+- matchGlobList(result, m_cacheFile, m_cacheFile->getUint32(PosGlobListOffset), fileName);
+ // Check the very common *.txt cases with the suffix tree
+- const int reverseSuffixTreeOffset = m_cacheFile->getUint32(PosReverseSuffixTreeOffset);
+- const int numRoots = m_cacheFile->getUint32(reverseSuffixTreeOffset);
+- const int firstRootOffset = m_cacheFile->getUint32(reverseSuffixTreeOffset + 4);
+- matchSuffixTree(result, m_cacheFile, numRoots, firstRootOffset, lowerFileName, lowerFileName.length() - 1, false);
++ if (result.m_matchingMimeTypes.isEmpty()) {
++ const int reverseSuffixTreeOffset = m_cacheFile->getUint32(PosReverseSuffixTreeOffset);
++ const int numRoots = m_cacheFile->getUint32(reverseSuffixTreeOffset);
++ const int firstRootOffset = m_cacheFile->getUint32(reverseSuffixTreeOffset + 4);
++ matchSuffixTree(result, m_cacheFile, numRoots, firstRootOffset, lowerFileName, lowerFileName.length() - 1, false);
++ if (result.m_matchingMimeTypes.isEmpty())
++ matchSuffixTree(result, m_cacheFile, numRoots, firstRootOffset, fileName, fileName.length() - 1, true);
++ }
++ // Check complex globs (e.g. "callgrind.out[0-9]*" or "README*")
+ if (result.m_matchingMimeTypes.isEmpty())
+- matchSuffixTree(result, m_cacheFile, numRoots, firstRootOffset, fileName, fileName.length() - 1, true);
++ matchGlobList(result, m_cacheFile, m_cacheFile->getUint32(PosGlobListOffset), fileName);
+ }
+
+ void QMimeBinaryProvider::matchGlobList(QMimeGlobMatchResult &result, CacheFile *cacheFile, int off, const QString &fileName)
+diff --git a/qtbase/src/corelib/serialization/qjsonparser.cpp b/qtbase/src/corelib/serialization/qjsonparser.cpp
+index 17e6f111ab..2e40b6c8fb 100644
+--- a/qtbase/src/corelib/serialization/qjsonparser.cpp
++++ b/qtbase/src/corelib/serialization/qjsonparser.cpp
+@@ -379,10 +379,30 @@ error:
+ return QCborValue();
+ }
+
++// We need to retain the _last_ value for any duplicate keys and we need to deref containers.
++// Therefore the manual implementation of std::unique().
++template<typename Iterator, typename Compare, typename Assign>
++static Iterator customAssigningUniqueLast(Iterator first, Iterator last,
++ Compare compare, Assign assign)
++{
++ first = std::adjacent_find(first, last, compare);
++ if (first == last)
++ return last;
++
++ Iterator result = first;
++ while (++first != last) {
++ if (!compare(*result, *first))
++ ++result;
++ if (result != first)
++ assign(*result, *first);
++ }
++
++ return ++result;
++}
++
+ static void sortContainer(QCborContainerPrivate *container)
+ {
+ using Forward = QJsonPrivate::KeyIterator;
+- using Reverse = std::reverse_iterator<Forward>;
+ using Value = Forward::value_type;
+
+ auto compare = [container](const Value &a, const Value &b)
+@@ -420,17 +440,31 @@ static void sortContainer(QCborContainerPrivate *container)
+ }
+ };
+
+- std::sort(Forward(container->elements.begin()), Forward(container->elements.end()),
+- [&compare](const Value &a, const Value &b) { return compare(a, b) < 0; });
++ // The elements' containers are owned by the outer container, not by the elements themselves.
++ auto move = [](Forward::reference target, Forward::reference source)
++ {
++ QtCbor::Element &targetValue = target.value();
++
++ // If the target has a container, deref it before overwriting, so that we don't leak.
++ if (targetValue.flags & QtCbor::Element::IsContainer)
++ targetValue.container->deref();
++
++ // Do not move, so that we can clear the value afterwards.
++ target = source;
++
++ // Clear the source value, so that we don't store the same container twice.
++ source.value() = QtCbor::Element();
++ };
++
++ std::stable_sort(
++ Forward(container->elements.begin()), Forward(container->elements.end()),
++ [&compare](const Value &a, const Value &b) { return compare(a, b) < 0; });
+
+- // We need to retain the _last_ value for any duplicate keys. Therefore the reverse dance here.
+- auto it = std::unique(Reverse(container->elements.end()), Reverse(container->elements.begin()),
+- [&compare](const Value &a, const Value &b) {
+- return compare(a, b) == 0;
+- }).base().elementsIterator();
++ Forward result = customAssigningUniqueLast(
++ Forward(container->elements.begin()), Forward(container->elements.end()),
++ [&compare](const Value &a, const Value &b) { return compare(a, b) == 0; }, move);
+
+- // The erase from beginning is expensive but hopefully rare.
+- container->elements.erase(container->elements.begin(), it);
++ container->elements.erase(result.elementsIterator(), container->elements.end());
+ }
+
+
+diff --git a/qtbase/src/corelib/serialization/qxmlstream.cpp b/qtbase/src/corelib/serialization/qxmlstream.cpp
+index b2f846544d..7cd457ba3a 100644
+--- a/qtbase/src/corelib/serialization/qxmlstream.cpp
++++ b/qtbase/src/corelib/serialization/qxmlstream.cpp
+@@ -980,7 +980,7 @@ inline uint QXmlStreamReaderPrivate::peekChar()
+ bool QXmlStreamReaderPrivate::scanUntil(const char *str, short tokenToInject)
+ {
+ int pos = textBuffer.size();
+- int oldLineNumber = lineNumber;
++ const auto oldLineNumber = lineNumber;
+
+ uint c;
+ while ((c = getChar()) != StreamEOF) {
+diff --git a/qtbase/src/corelib/text/qstring.cpp b/qtbase/src/corelib/text/qstring.cpp
+index 3e88ab4859..8deeae47bb 100644
+--- a/qtbase/src/corelib/text/qstring.cpp
++++ b/qtbase/src/corelib/text/qstring.cpp
+@@ -12312,7 +12312,7 @@ static qsizetype qLastIndexOf(Haystack haystack0, qsizetype from,
+ const auto needle = needle0.data();
+ const auto *end = haystack;
+ haystack += from;
+- const std::size_t sl_minus_1 = sl - 1;
++ const std::size_t sl_minus_1 = sl ? sl - 1 : 0;
+ const auto *n = needle + sl_minus_1;
+ const auto *h = haystack + sl_minus_1;
+ std::size_t hashNeedle = 0, hashHaystack = 0;
+diff --git a/qtbase/src/corelib/text/qstringiterator_p.h b/qtbase/src/corelib/text/qstringiterator_p.h
+index 219589b6e4..1d0c66cc78 100644
+--- a/qtbase/src/corelib/text/qstringiterator_p.h
++++ b/qtbase/src/corelib/text/qstringiterator_p.h
+@@ -61,6 +61,8 @@ class QStringIterator
+ {
+ QString::const_iterator i, pos, e;
+ Q_STATIC_ASSERT((std::is_same<QString::const_iterator, const QChar *>::value));
++ static bool less(const QChar *lhs, const QChar *rhs) noexcept
++ { return std::less<QString::const_iterator>{}(lhs, rhs); }
+ public:
+ explicit QStringIterator(QStringView string, qsizetype idx = 0)
+ : i(string.begin()),
+@@ -95,7 +97,8 @@ public:
+
+ inline void setPosition(QString::const_iterator position)
+ {
+- Q_ASSERT_X(i <= position && position <= e, Q_FUNC_INFO, "position out of bounds");
++ Q_ASSERT_X(!less(position, i) && !less(e, position),
++ Q_FUNC_INFO, "position out of bounds");
+ pos = position;
+ }
+
+@@ -103,7 +106,7 @@ public:
+
+ inline bool hasNext() const
+ {
+- return pos < e;
++ return less(pos, e);
+ }
+
+ inline void advance()
+@@ -120,16 +123,20 @@ public:
+ {
+ Q_ASSERT_X(hasNext(), Q_FUNC_INFO, "iterator hasn't a next item");
+
+- if (Q_UNLIKELY((pos++)->isHighSurrogate()))
++ if (Q_UNLIKELY((pos++)->isHighSurrogate())) {
++ Q_ASSERT(hasNext() && pos->isLowSurrogate());
+ ++pos;
++ }
+ }
+
+ inline uint peekNextUnchecked() const
+ {
+ Q_ASSERT_X(hasNext(), Q_FUNC_INFO, "iterator hasn't a next item");
+
+- if (Q_UNLIKELY(pos->isHighSurrogate()))
++ if (Q_UNLIKELY(pos->isHighSurrogate())) {
++ Q_ASSERT(less(pos + 1, e) && pos[1].isLowSurrogate());
+ return QChar::surrogateToUcs4(pos[0], pos[1]);
++ }
+
+ return pos->unicode();
+ }
+@@ -155,8 +162,10 @@ public:
+ Q_ASSERT_X(hasNext(), Q_FUNC_INFO, "iterator hasn't a next item");
+
+ const QChar cur = *pos++;
+- if (Q_UNLIKELY(cur.isHighSurrogate()))
++ if (Q_UNLIKELY(cur.isHighSurrogate())) {
++ Q_ASSERT(hasNext() && pos->isLowSurrogate());
+ return QChar::surrogateToUcs4(cur, *pos++);
++ }
+ return cur.unicode();
+ }
+
+@@ -166,7 +175,7 @@ public:
+
+ const QChar uc = *pos++;
+ if (Q_UNLIKELY(uc.isSurrogate())) {
+- if (Q_LIKELY(uc.isHighSurrogate() && pos < e && pos->isLowSurrogate()))
++ if (Q_LIKELY(uc.isHighSurrogate() && hasNext() && pos->isLowSurrogate()))
+ return QChar::surrogateToUcs4(uc, *pos++);
+ return invalidAs;
+ }
+@@ -178,7 +187,7 @@ public:
+
+ inline bool hasPrevious() const
+ {
+- return pos > i;
++ return less(i, pos);
+ }
+
+ inline void recede()
+@@ -196,16 +205,20 @@ public:
+ {
+ Q_ASSERT_X(hasPrevious(), Q_FUNC_INFO, "iterator hasn't a previous item");
+
+- if (Q_UNLIKELY((--pos)->isLowSurrogate()))
++ if (Q_UNLIKELY((--pos)->isLowSurrogate())) {
++ Q_ASSERT(hasPrevious() && pos[-1].isHighSurrogate());
+ --pos;
++ }
+ }
+
+ inline uint peekPreviousUnchecked() const
+ {
+ Q_ASSERT_X(hasPrevious(), Q_FUNC_INFO, "iterator hasn't a previous item");
+
+- if (Q_UNLIKELY(pos[-1].isLowSurrogate()))
++ if (Q_UNLIKELY(pos[-1].isLowSurrogate())) {
++ Q_ASSERT(less(i + 1, pos) && pos[-2].isHighSurrogate());
+ return QChar::surrogateToUcs4(pos[-2], pos[-1]);
++ }
+ return pos[-1].unicode();
+ }
+
+@@ -230,8 +243,10 @@ public:
+ Q_ASSERT_X(hasPrevious(), Q_FUNC_INFO, "iterator hasn't a previous item");
+
+ const QChar cur = *--pos;
+- if (Q_UNLIKELY(cur.isLowSurrogate()))
++ if (Q_UNLIKELY(cur.isLowSurrogate())) {
++ Q_ASSERT(hasPrevious() && pos[-1].isHighSurrogate());
+ return QChar::surrogateToUcs4(*--pos, cur);
++ }
+ return cur.unicode();
+ }
+
+@@ -241,7 +256,7 @@ public:
+
+ const QChar uc = *--pos;
+ if (Q_UNLIKELY(uc.isSurrogate())) {
+- if (Q_LIKELY(uc.isLowSurrogate() && pos > i && pos[-1].isHighSurrogate()))
++ if (Q_LIKELY(uc.isLowSurrogate() && hasPrevious() && pos[-1].isHighSurrogate()))
+ return QChar::surrogateToUcs4(*--pos, uc);
+ return invalidAs;
+ }
+diff --git a/qtbase/src/corelib/thread/qfutex_p.h b/qtbase/src/corelib/thread/qfutex_p.h
+index f287b752d7..e294537787 100644
+--- a/qtbase/src/corelib/thread/qfutex_p.h
++++ b/qtbase/src/corelib/thread/qfutex_p.h
+@@ -52,6 +52,7 @@
+ //
+
+ #include <qglobal.h>
++#include <QtCore/qtsan_impl.h>
+
+ QT_BEGIN_NAMESPACE
+
+@@ -106,16 +107,13 @@ namespace QtLinuxFutex {
+ inline int _q_futex(int *addr, int op, int val, quintptr val2 = 0,
+ int *addr2 = nullptr, int val3 = 0) noexcept
+ {
+- // A futex call ensures total ordering on the futex words
+- // (in either success or failure of the call). Instruct TSAN accordingly,
+- // as TSAN does not understand the futex(2) syscall.
+- _q_tsan_release(addr, addr2);
++ QtTsan::futexRelease(addr, addr2);
+
+ // we use __NR_futex because some libcs (like Android's bionic) don't
+ // provide SYS_futex etc.
+ int result = syscall(__NR_futex, addr, op | FUTEX_PRIVATE_FLAG, val, val2, addr2, val3);
+
+- _q_tsan_acquire(addr, addr2);
++ QtTsan::futexAcquire(addr, addr2);
+
+ return result;
+ }
+diff --git a/qtbase/src/corelib/thread/qmutex.cpp b/qtbase/src/corelib/thread/qmutex.cpp
+index 310d1cb14f..7097122d8e 100644
+--- a/qtbase/src/corelib/thread/qmutex.cpp
++++ b/qtbase/src/corelib/thread/qmutex.cpp
+@@ -152,6 +152,7 @@ public:
+
+ /*!
+ \enum QMutex::RecursionMode
++ \obsolete Use QRecursiveMutex to create a recursive mutex.
+
+ \value Recursive In this mode, a thread can lock the same mutex
+ multiple times and the mutex won't be unlocked
+@@ -173,6 +174,7 @@ public:
+
+ /*!
+ Constructs a new mutex. The mutex is created in an unlocked state.
++ \obsolete Use QRecursiveMutex to create a recursive mutex.
+
+ If \a mode is QMutex::Recursive, a thread can lock the same mutex
+ multiple times and the mutex won't be unlocked until a
+@@ -197,7 +199,7 @@ QMutex::QMutex(RecursionMode mode)
+ QMutex::~QMutex()
+ {
+ QMutexData *d = d_ptr.loadRelaxed();
+- if (isRecursive()) {
++ if (QBasicMutex::isRecursive()) {
+ delete static_cast<QRecursiveMutexPrivate *>(d);
+ } else if (d) {
+ #ifndef QT_LINUX_FUTEX
+diff --git a/qtbase/src/corelib/thread/qmutex.h b/qtbase/src/corelib/thread/qmutex.h
+index 73c9e00663..1bae573a03 100644
+--- a/qtbase/src/corelib/thread/qmutex.h
++++ b/qtbase/src/corelib/thread/qmutex.h
+@@ -42,6 +42,7 @@
+
+ #include <QtCore/qglobal.h>
+ #include <QtCore/qatomic.h>
++#include <QtCore/qtsan_impl.h>
+ #include <new>
+
+ #if __has_include(<chrono>)
+@@ -77,19 +78,37 @@ public:
+
+ // BasicLockable concept
+ inline void lock() QT_MUTEX_LOCK_NOEXCEPT {
++ QtTsan::mutexPreLock(this, 0u);
++
+ if (!fastTryLock())
+ lockInternal();
++
++ QtTsan::mutexPostLock(this, 0u, 0);
+ }
+
+ // BasicLockable concept
+ inline void unlock() noexcept {
+ Q_ASSERT(d_ptr.loadRelaxed()); //mutex must be locked
++
++ QtTsan::mutexPreUnlock(this, 0u);
++
+ if (!fastTryUnlock())
+ unlockInternal();
++
++ QtTsan::mutexPostUnlock(this, 0u);
+ }
+
+ bool tryLock() noexcept {
+- return fastTryLock();
++ unsigned tsanFlags = QtTsan::TryLock;
++ QtTsan::mutexPreLock(this, tsanFlags);
++
++ const bool success = fastTryLock();
++
++ if (!success)
++ tsanFlags |= QtTsan::TryLockFailed;
++ QtTsan::mutexPostLock(this, tsanFlags, 0);
++
++ return success;
+ }
+
+ // Lockable concept
+@@ -134,8 +153,16 @@ public:
+ #else
+ QMutex() { d_ptr.storeRelaxed(nullptr); }
+ #endif
++#if QT_DEPRECATED_SINCE(5,15)
+ enum RecursionMode { NonRecursive, Recursive };
++ QT_DEPRECATED_VERSION_X(5, 15, "Use QRecursiveMutex instead of a recursive QMutex")
+ explicit QMutex(RecursionMode mode);
++
++ QT_DEPRECATED_VERSION_X(5, 15, "Use QRecursiveMutex instead of a recursive QMutex")
++ bool isRecursive() const noexcept
++ { return QBasicMutex::isRecursive(); }
++#endif
++
+ ~QMutex();
+
+ // BasicLockable concept
+@@ -166,9 +193,6 @@ public:
+ }
+ #endif
+
+- bool isRecursive() const noexcept
+- { return QBasicMutex::isRecursive(); }
+-
+ private:
+ Q_DISABLE_COPY(QMutex)
+ friend class QMutexLocker;
+diff --git a/qtbase/src/corelib/thread/qreadwritelock.cpp b/qtbase/src/corelib/thread/qreadwritelock.cpp
+index 8c28507d5a..9dd8503116 100644
+--- a/qtbase/src/corelib/thread/qreadwritelock.cpp
++++ b/qtbase/src/corelib/thread/qreadwritelock.cpp
+@@ -155,7 +155,7 @@ QReadWriteLock::QReadWriteLock(RecursionMode recursionMode)
+ */
+ QReadWriteLock::~QReadWriteLock()
+ {
+- auto d = d_ptr.loadRelaxed();
++ auto d = d_ptr.loadAcquire();
+ if (isUncontendedLocked(d)) {
+ qWarning("QReadWriteLock: destroying locked QReadWriteLock");
+ return;
+@@ -445,7 +445,7 @@ void QReadWriteLock::unlock()
+ /*! \internal Helper for QWaitCondition::wait */
+ QReadWriteLock::StateForWaitCondition QReadWriteLock::stateForWaitCondition() const
+ {
+- QReadWriteLockPrivate *d = d_ptr.loadRelaxed();
++ QReadWriteLockPrivate *d = d_ptr.loadAcquire();
+ switch (quintptr(d) & StateMask) {
+ case StateLockedForRead: return LockedForRead;
+ case StateLockedForWrite: return LockedForWrite;
+@@ -453,6 +453,7 @@ QReadWriteLock::StateForWaitCondition QReadWriteLock::stateForWaitCondition() co
+
+ if (!d)
+ return Unlocked;
++ const auto lock = qt_scoped_lock(d->mutex);
+ if (d->writerCount > 1)
+ return RecursivelyLocked;
+ else if (d->writerCount == 1)
+diff --git a/qtbase/src/corelib/thread/qsemaphore.cpp b/qtbase/src/corelib/thread/qsemaphore.cpp
+index 1d01fc1b28..3ecdee3747 100644
+--- a/qtbase/src/corelib/thread/qsemaphore.cpp
++++ b/qtbase/src/corelib/thread/qsemaphore.cpp
+@@ -354,7 +354,12 @@ void QSemaphore::release(int n)
+ quintptr nn = unsigned(n);
+ if (futexHasWaiterCount)
+ nn |= quint64(nn) << 32; // token count replicated in high word
+- quintptr prevValue = u.fetchAndAddRelease(nn);
++ quintptr prevValue = u.loadRelaxed();
++ quintptr newValue;
++ do { // loop just to ensure the operations are done atomically
++ newValue = prevValue + nn;
++ newValue &= (futexNeedsWakeAllBit - 1);
++ } while (!u.testAndSetRelease(prevValue, newValue, prevValue));
+ if (futexNeedsWake(prevValue)) {
+ #ifdef FUTEX_OP
+ if (futexHasWaiterCount) {
+@@ -376,7 +381,6 @@ void QSemaphore::release(int n)
+ quint32 oparg = 0;
+ quint32 cmp = FUTEX_OP_CMP_NE;
+ quint32 cmparg = 0;
+- u.fetchAndAndRelease(futexNeedsWakeAllBit - 1);
+ futexWakeOp(*futexLow32(&u), n, INT_MAX, *futexHigh32(&u), FUTEX_OP(op, oparg, cmp, cmparg));
+ return;
+ }
+@@ -388,7 +392,6 @@ void QSemaphore::release(int n)
+ // its acquisition anyway, so it has to wait;
+ // 2) it did not see the new counter value, in which case its
+ // futexWait will fail.
+- u.fetchAndAndRelease(futexNeedsWakeAllBit - 1);
+ if (futexHasWaiterCount) {
+ futexWakeAll(*futexLow32(&u));
+ futexWakeAll(*futexHigh32(&u));
+diff --git a/qtbase/src/corelib/thread/qthread_p.h b/qtbase/src/corelib/thread/qthread_p.h
+index b2d1628e6e..f32f6f0460 100644
+--- a/qtbase/src/corelib/thread/qthread_p.h
++++ b/qtbase/src/corelib/thread/qthread_p.h
+@@ -174,7 +174,7 @@ public:
+ int returnCode;
+
+ uint stackSize;
+- QThread::Priority priority;
++ std::underlying_type<QThread::Priority>::type priority;
+
+ static QThread *threadForId(int id);
+
+@@ -213,6 +213,13 @@ public:
+ QCoreApplication::instance()->postEvent(q_ptr, new QEvent(QEvent::Quit));
+ }
+ }
++
++#ifndef Q_OS_INTEGRITY
++private:
++ // Used in QThread(Private)::start to avoid racy access to QObject::objectName,
++ // unset afterwards. On INTEGRITY we set the thread name before starting it.
++ QString objectName;
++#endif
+ };
+
+ #else // QT_CONFIG(thread)
+diff --git a/qtbase/src/corelib/thread/qthread_unix.cpp b/qtbase/src/corelib/thread/qthread_unix.cpp
+index 56a8e0a038..610117a640 100644
+--- a/qtbase/src/corelib/thread/qthread_unix.cpp
++++ b/qtbase/src/corelib/thread/qthread_unix.cpp
+@@ -169,8 +169,7 @@ static void set_thread_data(QThreadData *data)
+
+ static void clear_thread_data()
+ {
+- currentThreadData = nullptr;
+- pthread_setspecific(current_thread_data_key, nullptr);
++ set_thread_data(nullptr);
+ }
+
+ template <typename T>
+@@ -296,7 +295,7 @@ void *QThreadPrivate::start(void *arg)
+ QMutexLocker locker(&thr->d_func()->mutex);
+
+ // do we need to reset the thread priority?
+- if (int(thr->d_func()->priority) & ThreadPriorityResetFlag) {
++ if (thr->d_func()->priority & ThreadPriorityResetFlag) {
+ thr->d_func()->setPriority(QThread::Priority(thr->d_func()->priority & ~ThreadPriorityResetFlag));
+ }
+
+@@ -316,10 +315,10 @@ void *QThreadPrivate::start(void *arg)
+ // Sets the name of the current thread. We can only do this
+ // when the thread is starting, as we don't have a cross
+ // platform way of setting the name of an arbitrary thread.
+- if (Q_LIKELY(thr->objectName().isEmpty()))
++ if (Q_LIKELY(thr->d_func()->objectName.isEmpty()))
+ setCurrentThreadName(thr->metaObject()->className());
+ else
+- setCurrentThreadName(thr->objectName().toLocal8Bit());
++ setCurrentThreadName(std::exchange(thr->d_func()->objectName, {}).toLocal8Bit());
+ }
+ #endif
+
+@@ -671,7 +670,7 @@ void QThread::start(Priority priority)
+ // could not set scheduling hints, fallback to inheriting them
+ // we'll try again from inside the thread
+ pthread_attr_setinheritsched(&attr, PTHREAD_INHERIT_SCHED);
+- d->priority = Priority(priority | ThreadPriorityResetFlag);
++ d->priority = static_cast<std::underlying_type<QThread::Priority>::type>(priority) | ThreadPriorityResetFlag;
+ }
+ break;
+ }
+@@ -702,7 +701,10 @@ void QThread::start(Priority priority)
+ pthread_attr_setthreadname(&attr, metaObject()->className());
+ else
+ pthread_attr_setthreadname(&attr, objectName().toLocal8Bit());
++#else
++ d->objectName = objectName();
+ #endif
++
+ pthread_t threadId;
+ int code = pthread_create(&threadId, &attr, QThreadPrivate::start, this);
+ if (code == EPERM) {
+diff --git a/qtbase/src/corelib/thread/qthread_win.cpp b/qtbase/src/corelib/thread/qthread_win.cpp
+index bc70e3178a..4e76972498 100644
+--- a/qtbase/src/corelib/thread/qthread_win.cpp
++++ b/qtbase/src/corelib/thread/qthread_win.cpp
+@@ -394,10 +394,9 @@ unsigned int __stdcall QT_ENSURE_STACK_ALIGNED_FOR_SSE QThreadPrivate::start(voi
+
+ #if !defined(QT_NO_DEBUG) && defined(Q_CC_MSVC) && !defined(Q_OS_WINRT)
+ // sets the name of the current thread.
+- QByteArray objectName = thr->objectName().toLocal8Bit();
+- qt_set_thread_name(HANDLE(-1),
+- objectName.isEmpty() ?
+- thr->metaObject()->className() : objectName.constData());
++ qt_set_thread_name(HANDLE(-1), thr->d_func()->objectName.isEmpty()
++ ? thr->metaObject()->className()
++ : std::exchange(thr->d_func()->objectName, {}).toLocal8Bit().constData());
+ #endif
+
+ emit thr->started(QThread::QPrivateSignal());
+@@ -503,6 +502,7 @@ void QThread::start(Priority priority)
+ if (d->running)
+ return;
+
++ d->objectName = objectName();
+ d->running = true;
+ d->finished = false;
+ d->exited = false;
+@@ -548,7 +548,7 @@ void QThread::start(Priority priority)
+
+ int prio;
+ d->priority = priority;
+- switch (d->priority) {
++ switch (priority) {
+ case IdlePriority:
+ prio = THREAD_PRIORITY_IDLE;
+ break;
+@@ -686,7 +686,7 @@ void QThreadPrivate::setPriority(QThread::Priority threadPriority)
+
+ int prio;
+ priority = threadPriority;
+- switch (priority) {
++ switch (threadPriority) {
+ case QThread::IdlePriority:
+ prio = THREAD_PRIORITY_IDLE;
+ break;
+diff --git a/qtbase/src/corelib/thread/qtsan_impl.h b/qtbase/src/corelib/thread/qtsan_impl.h
+new file mode 100644
+index 0000000000..580a738b91
+--- /dev/null
++++ b/qtbase/src/corelib/thread/qtsan_impl.h
+@@ -0,0 +1,115 @@
++/****************************************************************************
++**
++** Copyright (C) 2017 Intel Corporation.
++** Copyright (C) 2022 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Giuseppe D'Angelo <giuseppe.dangelo@kdab.com>
++** Contact: https://www.qt.io/licensing/
++**
++** This file is part of the QtCore module of the Qt Toolkit.
++**
++** $QT_BEGIN_LICENSE:LGPL$
++** Commercial License Usage
++** Licensees holding valid commercial Qt licenses may use this file in
++** accordance with the commercial license agreement provided with the
++** Software or, alternatively, in accordance with the terms contained in
++** a written agreement between you and The Qt Company. For licensing terms
++** and conditions see https://www.qt.io/terms-conditions. For further
++** information use the contact form at https://www.qt.io/contact-us.
++**
++** GNU Lesser General Public License Usage
++** Alternatively, this file may be used under the terms of the GNU Lesser
++** General Public License version 3 as published by the Free Software
++** Foundation and appearing in the file LICENSE.LGPL3 included in the
++** packaging of this file. Please review the following information to
++** ensure the GNU Lesser General Public License version 3 requirements
++** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
++**
++** GNU General Public License Usage
++** Alternatively, this file may be used under the terms of the GNU
++** General Public License version 2.0 or (at your option) the GNU General
++** Public license version 3 or any later version approved by the KDE Free
++** Qt Foundation. The licenses are as published by the Free Software
++** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
++** included in the packaging of this file. Please review the following
++** information to ensure the GNU General Public License requirements will
++** be met: https://www.gnu.org/licenses/gpl-2.0.html and
++** https://www.gnu.org/licenses/gpl-3.0.html.
++**
++** $QT_END_LICENSE$
++**
++****************************************************************************/
++
++#ifndef QTSAN_IMPL_H
++#define QTSAN_IMPL_H
++
++#include <QtCore/qglobal.h>
++
++#if (__has_feature(thread_sanitizer) || defined(__SANITIZE_THREAD__)) && __has_include(<sanitizer/tsan_interface.h>)
++# define QT_BUILDING_UNDER_TSAN
++# include <sanitizer/tsan_interface.h>
++#endif
++
++QT_BEGIN_NAMESPACE
++
++namespace QtTsan {
++#ifdef QT_BUILDING_UNDER_TSAN
++inline void futexAcquire(void *addr, void *addr2 = nullptr)
++{
++ // A futex call ensures total ordering on the futex words
++ // (in either success or failure of the call). Instruct TSAN accordingly,
++ // as TSAN does not understand the futex(2) syscall (or equivalent).
++ ::__tsan_acquire(addr);
++ if (addr2)
++ ::__tsan_acquire(addr2);
++}
++
++inline void futexRelease(void *addr, void *addr2 = nullptr)
++{
++ if (addr2)
++ ::__tsan_release(addr2);
++ ::__tsan_release(addr);
++}
++
++inline void mutexPreLock(void *addr, unsigned flags)
++{
++ ::__tsan_mutex_pre_lock(addr, flags);
++}
++
++inline void mutexPostLock(void *addr, unsigned flags, int recursion)
++{
++ ::__tsan_mutex_post_lock(addr, flags, recursion);
++}
++
++inline void mutexPreUnlock(void *addr, unsigned flags)
++{
++ ::__tsan_mutex_pre_unlock(addr, flags);
++}
++
++inline void mutexPostUnlock(void *addr, unsigned flags)
++{
++ ::__tsan_mutex_post_unlock(addr, flags);
++}
++
++enum : unsigned {
++ MutexWriteReentrant = ::__tsan_mutex_write_reentrant,
++ TryLock = ::__tsan_mutex_try_lock,
++ TryLockFailed = ::__tsan_mutex_try_lock_failed,
++};
++#else
++inline void futexAcquire(void *, void * = nullptr) {}
++inline void futexRelease(void *, void * = nullptr) {}
++
++enum : unsigned {
++ MutexWriteReentrant,
++ TryLock,
++ TryLockFailed,
++};
++inline void mutexPreLock(void *, unsigned) {}
++inline void mutexPostLock(void *, unsigned, int) {}
++inline void mutexPreUnlock(void *, unsigned) {}
++inline void mutexPostUnlock(void *, unsigned) {}
++#endif // QT_BUILDING_UNDER_TSAN
++} // namespace QtTsan
++
++QT_END_NAMESPACE
++
++#endif // QTSAN_IMPL_H
+diff --git a/qtbase/src/corelib/thread/qwaitcondition_unix.cpp b/qtbase/src/corelib/thread/qwaitcondition_unix.cpp
+index 88b058f410..0f1da4dc9b 100644
+--- a/qtbase/src/corelib/thread/qwaitcondition_unix.cpp
++++ b/qtbase/src/corelib/thread/qwaitcondition_unix.cpp
+@@ -213,7 +213,7 @@ bool QWaitCondition::wait(QMutex *mutex, QDeadlineTimer deadline)
+ {
+ if (! mutex)
+ return false;
+- if (mutex->isRecursive()) {
++ if (static_cast<QBasicMutex *>(mutex)->isRecursive()) {
+ qWarning("QWaitCondition: cannot wait on recursive mutexes");
+ return false;
+ }
+diff --git a/qtbase/src/corelib/time/qdatetime.cpp b/qtbase/src/corelib/time/qdatetime.cpp
+index ec12569e3f..2c0b098079 100644
+--- a/qtbase/src/corelib/time/qdatetime.cpp
++++ b/qtbase/src/corelib/time/qdatetime.cpp
+@@ -43,6 +43,7 @@
+ #if QT_CONFIG(datetimeparser)
+ #include "private/qdatetimeparser_p.h"
+ #endif
++#include <private/qnumeric_p.h>
+
+ #include "qdatastream.h"
+ #include "qset.h"
+@@ -1429,9 +1430,11 @@ QDate QDate::addDays(qint64 ndays) const
+ if (isNull())
+ return QDate();
+
+- // Due to limits on minJd() and maxJd() we know that any overflow
+- // will be invalid and caught by fromJulianDay().
+- return fromJulianDay(jd + ndays);
++ qint64 r;
++ if (Q_UNLIKELY(add_overflow(jd, ndays, &r)))
++ return QDate();
++ else
++ return fromJulianDay(r);
+ }
+
+ /*!
+diff --git a/qtbase/src/corelib/time/qtimezone.cpp b/qtbase/src/corelib/time/qtimezone.cpp
+index 0309e43e52..3d451696a1 100644
+--- a/qtbase/src/corelib/time/qtimezone.cpp
++++ b/qtbase/src/corelib/time/qtimezone.cpp
+@@ -1,6 +1,6 @@
+ /****************************************************************************
+ **
+-** Copyright (C) 2013 John Layt <jlayt@kde.org>
++** Copyright (C) 2020 John Layt <jlayt@kde.org>
+ ** Contact: https://www.qt.io/licensing/
+ **
+ ** This file is part of the QtCore module of the Qt Toolkit.
+@@ -975,9 +975,15 @@ QList<QByteArray> QTimeZone::windowsIdToIanaIds(const QByteArray &windowsId,
+ }
+
+ #ifndef QT_NO_DATASTREAM
++// Invalid, as an IANA ID: too long, starts with - and has other invalid characters in it
++static inline QString invalidId() { return QStringLiteral("-No Time Zone Specified!"); }
++
+ QDataStream &operator<<(QDataStream &ds, const QTimeZone &tz)
+ {
+- tz.d->serialize(ds);
++ if (tz.isValid())
++ tz.d->serialize(ds);
++ else
++ ds << invalidId();
+ return ds;
+ }
+
+@@ -985,7 +991,9 @@ QDataStream &operator>>(QDataStream &ds, QTimeZone &tz)
+ {
+ QString ianaId;
+ ds >> ianaId;
+- if (ianaId == QLatin1String("OffsetFromUtc")) {
++ if (ianaId == invalidId()) {
++ tz = QTimeZone();
++ } else if (ianaId == QLatin1String("OffsetFromUtc")) {
+ int utcOffset;
+ QString name;
+ QString abbreviation;
+diff --git a/qtbase/src/corelib/time/qtimezoneprivate_tz.cpp b/qtbase/src/corelib/time/qtimezoneprivate_tz.cpp
+index b1611d7ddb..a7a6a72ccf 100644
+--- a/qtbase/src/corelib/time/qtimezoneprivate_tz.cpp
++++ b/qtbase/src/corelib/time/qtimezoneprivate_tz.cpp
+@@ -42,6 +42,7 @@
+ #include "qtimezone.h"
+ #include "qtimezoneprivate_p.h"
+ #include "private/qlocale_tools_p.h"
++#include "private/qlocking_p.h"
+
+ #include <QtCore/QDataStream>
+ #include <QtCore/QDateTime>
+@@ -62,6 +63,10 @@
+
+ QT_BEGIN_NAMESPACE
+
++#if QT_CONFIG(icu)
++static QBasicMutex s_icu_mutex;
++#endif
++
+ /*
+ Private
+
+@@ -670,6 +675,9 @@ QTzTimeZonePrivate::~QTzTimeZonePrivate()
+
+ QTzTimeZonePrivate *QTzTimeZonePrivate::clone() const
+ {
++#if QT_CONFIG(icu)
++ const auto lock = qt_scoped_lock(s_icu_mutex);
++#endif
+ return new QTzTimeZonePrivate(*this);
+ }
+
+@@ -913,12 +921,14 @@ QString QTzTimeZonePrivate::displayName(qint64 atMSecsSinceEpoch,
+ const QLocale &locale) const
+ {
+ #if QT_CONFIG(icu)
++ auto lock = qt_unique_lock(s_icu_mutex);
+ if (!m_icu)
+ m_icu = new QIcuTimeZonePrivate(m_id);
+ // TODO small risk may not match if tran times differ due to outdated files
+ // TODO Some valid TZ names are not valid ICU names, use translation table?
+ if (m_icu->isValid())
+ return m_icu->displayName(atMSecsSinceEpoch, nameType, locale);
++ lock.unlock();
+ #else
+ Q_UNUSED(nameType)
+ Q_UNUSED(locale)
+@@ -932,12 +942,14 @@ QString QTzTimeZonePrivate::displayName(QTimeZone::TimeType timeType,
+ const QLocale &locale) const
+ {
+ #if QT_CONFIG(icu)
++ auto lock = qt_unique_lock(s_icu_mutex);
+ if (!m_icu)
+ m_icu = new QIcuTimeZonePrivate(m_id);
+ // TODO small risk may not match if tran times differ due to outdated files
+ // TODO Some valid TZ names are not valid ICU names, use translation table?
+ if (m_icu->isValid())
+ return m_icu->displayName(timeType, nameType, locale);
++ lock.unlock();
+ #else
+ Q_UNUSED(timeType)
+ Q_UNUSED(nameType)
+diff --git a/qtbase/src/corelib/tools/qarraydata.h b/qtbase/src/corelib/tools/qarraydata.h
+index dcd95924c1..d01739e7e6 100644
+--- a/qtbase/src/corelib/tools/qarraydata.h
++++ b/qtbase/src/corelib/tools/qarraydata.h
+@@ -42,6 +42,7 @@
+
+ #include <QtCore/qrefcount.h>
+ #include <string.h>
++#include <cstdint>
+
+ QT_BEGIN_NAMESPACE
+
+@@ -58,14 +59,14 @@ struct Q_CORE_EXPORT QArrayData
+ {
+ Q_ASSERT(size == 0
+ || offset < 0 || size_t(offset) >= sizeof(QArrayData));
+- return reinterpret_cast<char *>(this) + offset;
++ return reinterpret_cast<void *> (reinterpret_cast<uintptr_t>(this) + offset);
+ }
+
+ const void *data() const
+ {
+ Q_ASSERT(size == 0
+ || offset < 0 || size_t(offset) >= sizeof(QArrayData));
+- return reinterpret_cast<const char *>(this) + offset;
++ return reinterpret_cast<void *> (reinterpret_cast<uintptr_t>(this) + offset);
+ }
+
+ // This refers to array data mutability, not "header data" represented by
+diff --git a/qtbase/src/corelib/tools/qfreelist_p.h b/qtbase/src/corelib/tools/qfreelist_p.h
+index 5ba23b344b..9974102136 100644
+--- a/qtbase/src/corelib/tools/qfreelist_p.h
++++ b/qtbase/src/corelib/tools/qfreelist_p.h
+@@ -161,7 +161,7 @@ class QFreeList
+ return i;
+ x -= size;
+ }
+- Q_ASSERT(false);
++ Q_UNREACHABLE();
+ return -1;
+ }
+
+diff --git a/qtbase/src/corelib/tools/qversionnumber.h b/qtbase/src/corelib/tools/qversionnumber.h
+index d43b86ba51..2843f2b043 100644
+--- a/qtbase/src/corelib/tools/qversionnumber.h
++++ b/qtbase/src/corelib/tools/qversionnumber.h
+@@ -273,10 +273,10 @@ public:
+
+ Q_REQUIRED_RESULT Q_CORE_EXPORT QString toString() const;
+ #if QT_STRINGVIEW_LEVEL < 2
+- Q_REQUIRED_RESULT Q_CORE_EXPORT static Q_DECL_PURE_FUNCTION QVersionNumber fromString(const QString &string, int *suffixIndex = nullptr);
++ Q_REQUIRED_RESULT Q_CORE_EXPORT static QVersionNumber fromString(const QString &string, int *suffixIndex = nullptr);
+ #endif
+- Q_REQUIRED_RESULT Q_CORE_EXPORT static Q_DECL_PURE_FUNCTION QVersionNumber fromString(QLatin1String string, int *suffixIndex = nullptr);
+- Q_REQUIRED_RESULT Q_CORE_EXPORT static Q_DECL_PURE_FUNCTION QVersionNumber fromString(QStringView string, int *suffixIndex = nullptr);
++ Q_REQUIRED_RESULT Q_CORE_EXPORT static QVersionNumber fromString(QLatin1String string, int *suffixIndex = nullptr);
++ Q_REQUIRED_RESULT Q_CORE_EXPORT static QVersionNumber fromString(QStringView string, int *suffixIndex = nullptr);
+
+ private:
+ #ifndef QT_NO_DATASTREAM
+diff --git a/qtbase/src/dbus/qdbusintegrator.cpp b/qtbase/src/dbus/qdbusintegrator.cpp
+index 5b66ce971b..28a3b0ffea 100644
+--- a/qtbase/src/dbus/qdbusintegrator.cpp
++++ b/qtbase/src/dbus/qdbusintegrator.cpp
+@@ -1135,7 +1135,13 @@ void QDBusConnectionPrivate::closeConnection()
+ }
+ }
+
+- qDeleteAll(pendingCalls);
++ for (auto it = pendingCalls.begin(); it != pendingCalls.end(); ++it) {
++ auto call = *it;
++ if (!call->ref.deref()) {
++ delete call;
++ }
++ }
++ pendingCalls.clear();
+
+ // Disconnect all signals from signal hooks and from the object tree to
+ // avoid QObject::destroyed being sent to dbus daemon thread which has
+@@ -2584,6 +2590,11 @@ QDBusConnectionPrivate::findMetaObject(const QString &service, const QString &pa
+ if (mo)
+ return mo;
+ }
++ if (path.isEmpty()) {
++ error = QDBusError(QDBusError::InvalidObjectPath, QLatin1String("Object path cannot be empty"));
++ lastError = error;
++ return nullptr;
++ }
+
+ // introspect the target object
+ QDBusMessage msg = QDBusMessage::createMethodCall(service, path,
+diff --git a/qtbase/src/dbus/qdbusmetaobject.cpp b/qtbase/src/dbus/qdbusmetaobject.cpp
+index 5265568f42..7e9f0f1acc 100644
+--- a/qtbase/src/dbus/qdbusmetaobject.cpp
++++ b/qtbase/src/dbus/qdbusmetaobject.cpp
+@@ -210,6 +210,9 @@ QDBusMetaObjectGenerator::findType(const QByteArray &signature,
+ } else if (signature == "a{ss}") {
+ result.name = "QMap<QString,QString>";
+ type = qMetaTypeId<QMap<QString, QString> >();
++ } else if (signature == "aay") {
++ result.name = "QByteArrayList";
++ type = qMetaTypeId<QByteArrayList>();
+ } else {
+ result.name = "{D-Bus type \"" + signature + "\"}";
+ type = registerComplexDBusType(result.name);
+diff --git a/qtbase/src/gui/accessible/qaccessible.cpp b/qtbase/src/gui/accessible/qaccessible.cpp
+index d705bfccb5..0caf3c808c 100644
+--- a/qtbase/src/gui/accessible/qaccessible.cpp
++++ b/qtbase/src/gui/accessible/qaccessible.cpp
+@@ -54,6 +54,7 @@
+ #include <QtCore/qdebug.h>
+ #include <QtCore/qloggingcategory.h>
+ #include <QtCore/qmetaobject.h>
++#include <QtCore/private/qmetaobject_p.h>
+ #include <QtCore/qhash.h>
+ #include <private/qfactoryloader_p.h>
+
+@@ -681,6 +682,25 @@ QAccessibleInterface *QAccessible::queryAccessibleInterface(QObject *object)
+ // Create a QAccessibleInterface for the object class. Start by the most
+ // derived class and walk up the class hierarchy.
+ const QMetaObject *mo = object->metaObject();
++ const auto *objectPriv = QObjectPrivate::get(object);
++ /*
++ We do not want to cache each and every QML metaobject (Button_QMLTYPE_124,
++ Button_QMLTYPE_125, etc.). Those dynamic metaobjects shouldn't have an
++ accessible interface in any case. Instead, we start the whole checking
++ with the first non-dynamic meta-object. To avoid potential regressions
++ in other areas of Qt that also use dynamic metaobjects, we only do this
++ for objects that are QML-related (approximated by checking whether they
++ have ddata set).
++ */
++ const bool qmlRelated = !objectPriv->isDeletingChildren &&
++ objectPriv->declarativeData;
++ while (qmlRelated && mo) {
++ auto mop = QMetaObjectPrivate::get(mo);
++ if (!mop || !(mop->flags & DynamicMetaObject))
++ break;
++
++ mo = mo->superClass();
++ };
+ while (mo) {
+ const QString cn = QLatin1String(mo->className());
+
+@@ -696,14 +716,15 @@ QAccessibleInterface *QAccessible::queryAccessibleInterface(QObject *object)
+ // Find a QAccessiblePlugin (factory) for the class name. If there's
+ // no entry in the cache try to create it using the plugin loader.
+ if (!qAccessiblePlugins()->contains(cn)) {
++ QAccessiblePlugin *factory = nullptr; // 0 means "no plugin found". This is cached as well.
+ const int index = loader()->indexOf(cn);
+- if (index != -1) {
+- QAccessiblePlugin *factory = qobject_cast<QAccessiblePlugin *>(loader()->instance(index));
+- qAccessiblePlugins()->insert(cn, factory);
+- }
++ if (index != -1)
++ factory = qobject_cast<QAccessiblePlugin *>(loader()->instance(index));
++ qAccessiblePlugins()->insert(cn, factory);
+ }
+
+ // At this point the cache should contain a valid factory pointer or 0:
++ Q_ASSERT(qAccessiblePlugins()->contains(cn));
+ QAccessiblePlugin *factory = qAccessiblePlugins()->value(cn);
+ if (factory) {
+ QAccessibleInterface *result = factory->create(cn, object);
+diff --git a/qtbase/src/gui/configure.json b/qtbase/src/gui/configure.json
+index 1f08795c57..12c95742d2 100644
+--- a/qtbase/src/gui/configure.json
++++ b/qtbase/src/gui/configure.json
+@@ -834,7 +834,8 @@
+ "// embedded devices, are not intended to be used together with X. EGL support",
+ "// has to be disabled in plugins like xcb in this case since the native display,",
+ "// window and pixmap types will be different than what an X-based platform",
+- "// plugin would expect."
++ "// plugin would expect.",
++ "#define USE_X11"
+ ],
+ "include": [ "EGL/egl.h", "X11/Xlib.h" ],
+ "main": [
+diff --git a/qtbase/src/gui/image/qbmphandler.cpp b/qtbase/src/gui/image/qbmphandler.cpp
+index 96f1e8cb1d..0e73bbbdb0 100644
+--- a/qtbase/src/gui/image/qbmphandler.cpp
++++ b/qtbase/src/gui/image/qbmphandler.cpp
+@@ -150,16 +150,42 @@ static QDataStream &operator<<(QDataStream &s, const BMP_INFOHDR &bi)
+ return s;
+ }
+
+-static int calc_shift(uint mask)
++static uint calc_shift(uint mask)
+ {
+- int result = 0;
+- while (mask && !(mask & 1)) {
++ uint result = 0;
++ while ((mask >= 0x100) || (!(mask & 1) && mask)) {
+ result++;
+ mask >>= 1;
+ }
+ return result;
+ }
+
++static uint calc_scale(uint low_mask)
++{
++ uint result = 8;
++ while (low_mask && result) {
++ result--;
++ low_mask >>= 1;
++ }
++ return result;
++}
++
++static inline uint apply_scale(uint value, uint scale)
++{
++ if (!(scale & 0x07)) // return immediately if scale == 8 or 0
++ return value;
++
++ uint filled = 8 - scale;
++ uint result = value << scale;
++
++ do {
++ result |= result >> filled;
++ filled <<= 1;
++ } while (filled < 8);
++
++ return result;
++}
++
+ static bool read_dib_fileheader(QDataStream &s, BMP_FILEHDR &bf)
+ {
+ // read BMP file header
+@@ -222,14 +248,14 @@ static bool read_dib_body(QDataStream &s, const BMP_INFOHDR &bi, qint64 offset,
+ uint green_mask = 0;
+ uint blue_mask = 0;
+ uint alpha_mask = 0;
+- int red_shift = 0;
+- int green_shift = 0;
+- int blue_shift = 0;
+- int alpha_shift = 0;
+- int red_scale = 0;
+- int green_scale = 0;
+- int blue_scale = 0;
+- int alpha_scale = 0;
++ uint red_shift = 0;
++ uint green_shift = 0;
++ uint blue_shift = 0;
++ uint alpha_shift = 0;
++ uint red_scale = 0;
++ uint green_scale = 0;
++ uint blue_scale = 0;
++ uint alpha_scale = 0;
+
+ if (!d->isSequential())
+ d->seek(startpos + BMP_FILEHDR_SIZE + bi.biSize); // goto start of colormap or masks
+@@ -308,19 +334,19 @@ static bool read_dib_body(QDataStream &s, const BMP_INFOHDR &bi, qint64 offset,
+ red_shift = calc_shift(red_mask);
+ if (((red_mask >> red_shift) + 1) == 0)
+ return false;
+- red_scale = 256 / ((red_mask >> red_shift) + 1);
++ red_scale = calc_scale(red_mask >> red_shift);
+ green_shift = calc_shift(green_mask);
+ if (((green_mask >> green_shift) + 1) == 0)
+ return false;
+- green_scale = 256 / ((green_mask >> green_shift) + 1);
++ green_scale = calc_scale(green_mask >> green_shift);
+ blue_shift = calc_shift(blue_mask);
+ if (((blue_mask >> blue_shift) + 1) == 0)
+ return false;
+- blue_scale = 256 / ((blue_mask >> blue_shift) + 1);
++ blue_scale = calc_scale(blue_mask >> blue_shift);
+ alpha_shift = calc_shift(alpha_mask);
+ if (((alpha_mask >> alpha_shift) + 1) == 0)
+ return false;
+- alpha_scale = 256 / ((alpha_mask >> alpha_shift) + 1);
++ alpha_scale = calc_scale(alpha_mask >> alpha_shift);
+ } else if (comp == BMP_RGB && (nbits == 24 || nbits == 32)) {
+ blue_mask = 0x000000ff;
+ green_mask = 0x0000ff00;
+@@ -328,17 +354,15 @@ static bool read_dib_body(QDataStream &s, const BMP_INFOHDR &bi, qint64 offset,
+ blue_shift = 0;
+ green_shift = 8;
+ red_shift = 16;
+- blue_scale = green_scale = red_scale = 1;
++ blue_scale = green_scale = red_scale = 0;
+ } else if (comp == BMP_RGB && nbits == 16) {
+ blue_mask = 0x001f;
+ green_mask = 0x03e0;
+ red_mask = 0x7c00;
+ blue_shift = 0;
+- green_shift = 2;
+- red_shift = 7;
+- red_scale = 1;
+- green_scale = 1;
+- blue_scale = 8;
++ green_shift = 5;
++ red_shift = 10;
++ blue_scale = green_scale = red_scale = 3;
+ }
+
+ #if 0
+@@ -544,10 +568,10 @@ static bool read_dib_body(QDataStream &s, const BMP_INFOHDR &bi, qint64 offset,
+ c |= *(uchar*)(b+2)<<16;
+ if (nbits > 24)
+ c |= *(uchar*)(b+3)<<24;
+- *p++ = qRgba(((c & red_mask) >> red_shift) * red_scale,
+- ((c & green_mask) >> green_shift) * green_scale,
+- ((c & blue_mask) >> blue_shift) * blue_scale,
+- transp ? ((c & alpha_mask) >> alpha_shift) * alpha_scale : 0xff);
++ *p++ = qRgba(apply_scale((c & red_mask) >> red_shift, red_scale),
++ apply_scale((c & green_mask) >> green_shift, green_scale),
++ apply_scale((c & blue_mask) >> blue_shift, blue_scale),
++ transp ? apply_scale((c & alpha_mask) >> alpha_shift, alpha_scale) : 0xff);
+ b += nbits/8;
+ }
+ }
+diff --git a/qtbase/src/gui/image/qimage.cpp b/qtbase/src/gui/image/qimage.cpp
+index 7152ac1607..0df772564c 100644
+--- a/qtbase/src/gui/image/qimage.cpp
++++ b/qtbase/src/gui/image/qimage.cpp
+@@ -4694,6 +4694,8 @@ QImage QImage::smoothScaled(int w, int h) const {
+ static QImage rotated90(const QImage &image)
+ {
+ QImage out(image.height(), image.width(), image.format());
++ if (out.isNull())
++ return out;
+ copyMetadata(&out, image);
+ if (image.colorCount() > 0)
+ out.setColorTable(image.colorTable());
+@@ -4722,6 +4724,8 @@ static QImage rotated180(const QImage &image)
+ return image.mirrored(true, true);
+
+ QImage out(image.width(), image.height(), image.format());
++ if (out.isNull())
++ return out;
+ copyMetadata(&out, image);
+ if (image.colorCount() > 0)
+ out.setColorTable(image.colorTable());
+@@ -4734,6 +4738,8 @@ static QImage rotated180(const QImage &image)
+ static QImage rotated270(const QImage &image)
+ {
+ QImage out(image.height(), image.width(), image.format());
++ if (out.isNull())
++ return out;
+ copyMetadata(&out, image);
+ if (image.colorCount() > 0)
+ out.setColorTable(image.colorTable());
+diff --git a/qtbase/src/gui/kernel/qcursor.cpp b/qtbase/src/gui/kernel/qcursor.cpp
+index d6ccaff8ed..455088241c 100644
+--- a/qtbase/src/gui/kernel/qcursor.cpp
++++ b/qtbase/src/gui/kernel/qcursor.cpp
+@@ -251,7 +251,8 @@ void QCursor::setPos(QScreen *screen, int x, int y)
+ {
+ if (screen) {
+ if (QPlatformCursor *cursor = screen->handle()->cursor()) {
+- const QPoint devicePos = QHighDpi::toNativePixels(QPoint(x, y), screen);
++ const QPoint pos(x, y);
++ const QPoint devicePos = QHighDpi::toNativePixels(pos, screen->virtualSiblingAt(pos));
+ // Need to check, since some X servers generate null mouse move
+ // events, causing looping in applications which call setPos() on
+ // every mouse move event.
+diff --git a/qtbase/src/gui/kernel/qhighdpiscaling.cpp b/qtbase/src/gui/kernel/qhighdpiscaling.cpp
+index 9bbf2773a9..3ac4a4d8b6 100644
+--- a/qtbase/src/gui/kernel/qhighdpiscaling.cpp
++++ b/qtbase/src/gui/kernel/qhighdpiscaling.cpp
+@@ -580,9 +580,8 @@ void QHighDpiScaling::setScreenFactor(QScreen *screen, qreal factor)
+ else
+ qNamedScreenScaleFactors()->insert(name, factor);
+
+- // hack to force re-evaluation of screen geometry
+ if (screen->handle())
+- screen->d_func()->setPlatformScreen(screen->handle()); // updates geometries based on scale factor
++ screen->d_func()->updateLogicalDpi();
+ }
+
+ QPoint QHighDpiScaling::mapPositionToNative(const QPoint &pos, const QPlatformScreen *platformScreen)
+diff --git a/qtbase/src/gui/kernel/qkeysequence.cpp b/qtbase/src/gui/kernel/qkeysequence.cpp
+index a75b8ef920..4f2d294739 100644
+--- a/qtbase/src/gui/kernel/qkeysequence.cpp
++++ b/qtbase/src/gui/kernel/qkeysequence.cpp
+@@ -701,6 +701,10 @@ static const struct {
+ { Qt::Key_TouchpadToggle, QT_TRANSLATE_NOOP("QShortcut", "Touchpad Toggle") },
+ { Qt::Key_TouchpadOn, QT_TRANSLATE_NOOP("QShortcut", "Touchpad On") },
+ { Qt::Key_TouchpadOff, QT_TRANSLATE_NOOP("QShortcut", "Touchpad Off") },
++ { Qt::Key_Shift, QT_TRANSLATE_NOOP("QShortcut", "Shift") },
++ { Qt::Key_Control, QT_TRANSLATE_NOOP("QShortcut", "Control") },
++ { Qt::Key_Alt, QT_TRANSLATE_NOOP("QShortcut", "Alt") },
++ { Qt::Key_Meta, QT_TRANSLATE_NOOP("QShortcut", "Meta") },
+
+ };
+ static Q_CONSTEXPR int numKeyNames = sizeof keyname / sizeof *keyname;
+diff --git a/qtbase/src/gui/kernel/qplatformservices.cpp b/qtbase/src/gui/kernel/qplatformservices.cpp
+index fdc6a6c4aa..ac47f98c5d 100644
+--- a/qtbase/src/gui/kernel/qplatformservices.cpp
++++ b/qtbase/src/gui/kernel/qplatformservices.cpp
+@@ -55,6 +55,19 @@ QT_BEGIN_NAMESPACE
+ \brief The QPlatformServices provides the backend for desktop-related functionality.
+ */
+
++/*!
++ \enum QPlatformServices::Capability
++
++ Capabilities are used to determine a specific platform service's availability.
++
++ \value ColorPickingFromScreen The platform natively supports color picking from screen.
++ This capability indicates that the platform supports "opaque" color picking, where the
++ platform implements a complete user experience for color picking and outputs a color.
++ This is in contrast to the application implementing the color picking user experience
++ (taking care of showing a cross hair, instructing the platform integration to obtain
++ the color at a given pixel, etc.). The related service function is pickColor().
++ */
++
+ QPlatformServices::QPlatformServices()
+ { }
+
+@@ -85,5 +98,16 @@ QByteArray QPlatformServices::desktopEnvironment() const
+ return QByteArray("UNKNOWN");
+ }
+
++QPlatformServiceColorPicker *QPlatformServices::colorPicker(QWindow *parent)
++{
++ Q_UNUSED(parent);
++ return nullptr;
++}
++
++bool QPlatformServices::hasCapability(Capability capability) const
++{
++ Q_UNUSED(capability)
++ return false;
++}
+
+ QT_END_NAMESPACE
+diff --git a/qtbase/src/gui/kernel/qplatformservices.h b/qtbase/src/gui/kernel/qplatformservices.h
+index 5de96cfa7d..a8b2a4ce71 100644
+--- a/qtbase/src/gui/kernel/qplatformservices.h
++++ b/qtbase/src/gui/kernel/qplatformservices.h
+@@ -50,16 +50,32 @@
+ //
+
+ #include <QtGui/qtguiglobal.h>
++#include <QtCore/qobject.h>
+
+ QT_BEGIN_NAMESPACE
+
+ class QUrl;
++class QWindow;
++
++class Q_GUI_EXPORT QPlatformServiceColorPicker : public QObject
++{
++ Q_OBJECT
++public:
++ using QObject::QObject;
++ virtual void pickColor() = 0;
++Q_SIGNALS:
++ void colorPicked(const QColor &color);
++};
+
+ class Q_GUI_EXPORT QPlatformServices
+ {
+ public:
+ Q_DISABLE_COPY_MOVE(QPlatformServices)
+
++ enum Capability {
++ ColorPicking,
++ };
++
+ QPlatformServices();
+ virtual ~QPlatformServices() { }
+
+@@ -67,6 +83,10 @@ public:
+ virtual bool openDocument(const QUrl &url);
+
+ virtual QByteArray desktopEnvironment() const;
++
++ virtual bool hasCapability(Capability capability) const;
++
++ virtual QPlatformServiceColorPicker *colorPicker(QWindow *parent = nullptr);
+ };
+
+ QT_END_NAMESPACE
+diff --git a/qtbase/src/gui/kernel/qplatformtheme.cpp b/qtbase/src/gui/kernel/qplatformtheme.cpp
+index 71521c0339..2325873245 100644
+--- a/qtbase/src/gui/kernel/qplatformtheme.cpp
++++ b/qtbase/src/gui/kernel/qplatformtheme.cpp
+@@ -163,6 +163,8 @@ QT_BEGIN_NAMESPACE
+
+ \value ShowShortcutsInContextMenus (bool) Whether to display shortcut key sequences in context menus.
+
++ \value ButtonPressKeys (QList<Qt::Key>) A list of keys that can be used to press buttons via keyboard input.
++
+ \sa themeHint(), QStyle::pixelMetric()
+ */
+
+@@ -563,6 +565,8 @@ QVariant QPlatformTheme::defaultThemeHint(ThemeHint hint)
+ }
+ case MouseQuickSelectionThreshold:
+ return QVariant(10);
++ case ButtonPressKeys:
++ return QVariant::fromValue(QList<Qt::Key>({ Qt::Key_Space, Qt::Key_Select }));
+ }
+ return QVariant();
+ }
+diff --git a/qtbase/src/gui/kernel/qplatformtheme.h b/qtbase/src/gui/kernel/qplatformtheme.h
+index 3185fc4541..7e6c9d5740 100644
+--- a/qtbase/src/gui/kernel/qplatformtheme.h
++++ b/qtbase/src/gui/kernel/qplatformtheme.h
+@@ -120,7 +120,8 @@ public:
+ TouchDoubleTapDistance,
+ ShowShortcutsInContextMenus,
+ IconFallbackSearchPaths,
+- MouseQuickSelectionThreshold
++ MouseQuickSelectionThreshold,
++ ButtonPressKeys
+ };
+
+ enum DialogType {
+diff --git a/qtbase/src/gui/kernel/qscreen.cpp b/qtbase/src/gui/kernel/qscreen.cpp
+index 8e0eb35116..5d172a58dd 100644
+--- a/qtbase/src/gui/kernel/qscreen.cpp
++++ b/qtbase/src/gui/kernel/qscreen.cpp
+@@ -77,6 +77,12 @@ QScreen::QScreen(QPlatformScreen *screen)
+ d->setPlatformScreen(screen);
+ }
+
++void QScreenPrivate::updateLogicalDpi()
++{
++ logicalDpi = QPlatformScreen::overrideDpi(platformScreen->logicalDpi());
++ updateGeometriesWithSignals(); // updates geometries based on scale factor
++}
++
+ void QScreenPrivate::updateGeometriesWithSignals()
+ {
+ const QRect oldGeometry = geometry;
+diff --git a/qtbase/src/gui/kernel/qscreen_p.h b/qtbase/src/gui/kernel/qscreen_p.h
+index 7da542c25e..e50fc3190b 100644
+--- a/qtbase/src/gui/kernel/qscreen_p.h
++++ b/qtbase/src/gui/kernel/qscreen_p.h
+@@ -70,6 +70,7 @@ public:
+ geometry = platformScreen->deviceIndependentGeometry();
+ availableGeometry = QHighDpi::fromNative(platformScreen->availableGeometry(), QHighDpiScaling::factor(platformScreen), geometry.topLeft());
+ }
++ void updateLogicalDpi();
+
+ void updatePrimaryOrientation();
+ void updateGeometriesWithSignals();
+diff --git a/qtbase/src/gui/painting/qblendfunctions_p.h b/qtbase/src/gui/painting/qblendfunctions_p.h
+index 080da98ec4..6997d62b3c 100644
+--- a/qtbase/src/gui/painting/qblendfunctions_p.h
++++ b/qtbase/src/gui/painting/qblendfunctions_p.h
+@@ -246,25 +246,32 @@ void qt_transform_image_rasterize(DestT *destPixels, int dbpl,
+ int dudx, int dvdx, int dudy, int dvdy, int u0, int v0,
+ Blender blender)
+ {
+- int fromY = qMax(qRound(topY), clip.top());
+- int toY = qMin(qRound(bottomY), clip.top() + clip.height());
++ qint64 fromY = qMax(qRound(topY), clip.top());
++ qint64 toY = qMin(qRound(bottomY), clip.top() + clip.height());
+ if (fromY >= toY)
+ return;
+
+ qreal leftSlope = (bottomLeft.x - topLeft.x) / (bottomLeft.y - topLeft.y);
+ qreal rightSlope = (bottomRight.x - topRight.x) / (bottomRight.y - topRight.y);
+- int dx_l = int(leftSlope * 0x10000);
+- int dx_r = int(rightSlope * 0x10000);
+- int x_l = int((topLeft.x + (qreal(0.5) + fromY - topLeft.y) * leftSlope + qreal(0.5)) * 0x10000);
+- int x_r = int((topRight.x + (qreal(0.5) + fromY - topRight.y) * rightSlope + qreal(0.5)) * 0x10000);
+-
+- int fromX, toX, x1, x2, u, v, i, ii;
++ qint64 dx_l = qint64(leftSlope * 0x10000);
++ qint64 dx_r = qint64(rightSlope * 0x10000);
++ qint64 x_l = qint64((topLeft.x + (qreal(0.5) + fromY - topLeft.y) * leftSlope + qreal(0.5)) * 0x10000);
++ qint64 x_r = qint64((topRight.x + (qreal(0.5) + fromY - topRight.y) * rightSlope + qreal(0.5)) * 0x10000);
++
++ qint64 sourceRectTop = qint64(sourceRect.top());
++ qint64 sourceRectLeft = qint64(sourceRect.left());
++ qint64 sourceRectWidth = qint64(sourceRect.width());
++ qint64 sourceRectHeight = qint64(sourceRect.height());
++ qint64 clipLeft = qint64(clip.left());
++ qint64 clipWidth = qint64(clip.width());
++
++ qint64 fromX, toX, x1, x2, u, v, i, ii;
+ DestT *line;
+- for (int y = fromY; y < toY; ++y) {
++ for (qint64 y = fromY; y < toY; ++y) {
+ line = reinterpret_cast<DestT *>(reinterpret_cast<uchar *>(destPixels) + y * dbpl);
+
+- fromX = qMax(x_l >> 16, clip.left());
+- toX = qMin(x_r >> 16, clip.left() + clip.width());
++ fromX = qMax(x_l >> 16, clipLeft);
++ toX = qMin(x_r >> 16, clipLeft + clipWidth);
+ if (fromX < toX) {
+ // Because of rounding, we can get source coordinates outside the source image.
+ // Clamp these coordinates to the source rect to avoid segmentation fault and
+@@ -275,10 +282,10 @@ void qt_transform_image_rasterize(DestT *destPixels, int dbpl,
+ u = x1 * dudx + y * dudy + u0;
+ v = x1 * dvdx + y * dvdy + v0;
+ for (; x1 < toX; ++x1) {
+- int uu = u >> 16;
+- int vv = v >> 16;
+- if (uu >= sourceRect.left() && uu < sourceRect.left() + sourceRect.width()
+- && vv >= sourceRect.top() && vv < sourceRect.top() + sourceRect.height()) {
++ qint64 uu = u >> 16;
++ qint64 vv = v >> 16;
++ if (uu >= sourceRectLeft && uu < sourceRectLeft + sourceRectWidth
++ && vv >= sourceRectTop && vv < sourceRectTop + sourceRectHeight) {
+ break;
+ }
+ u += dudx;
+@@ -290,10 +297,10 @@ void qt_transform_image_rasterize(DestT *destPixels, int dbpl,
+ u = (x2 - 1) * dudx + y * dudy + u0;
+ v = (x2 - 1) * dvdx + y * dvdy + v0;
+ for (; x2 > x1; --x2) {
+- int uu = u >> 16;
+- int vv = v >> 16;
+- if (uu >= sourceRect.left() && uu < sourceRect.left() + sourceRect.width()
+- && vv >= sourceRect.top() && vv < sourceRect.top() + sourceRect.height()) {
++ qint64 uu = u >> 16;
++ qint64 vv = v >> 16;
++ if (uu >= sourceRectLeft && uu < sourceRectLeft + sourceRectWidth
++ && vv >= sourceRectTop && vv < sourceRectTop + sourceRectHeight) {
+ break;
+ }
+ u -= dudx;
+@@ -308,8 +315,8 @@ void qt_transform_image_rasterize(DestT *destPixels, int dbpl,
+ // Beginning of the scan line, with per-pixel checks.
+ i = x1 - fromX;
+ while (i) {
+- int uu = qBound(sourceRect.left(), u >> 16, sourceRect.left() + sourceRect.width() - 1);
+- int vv = qBound(sourceRect.top(), v >> 16, sourceRect.top() + sourceRect.height() - 1);
++ qint64 uu = qBound(sourceRectLeft, u >> 16, sourceRectLeft + sourceRectWidth - 1);
++ qint64 vv = qBound(sourceRectTop, v >> 16, sourceRectTop + sourceRectHeight - 1);
+ blender.write(line, reinterpret_cast<const SrcT *>(reinterpret_cast<const uchar *>(srcPixels) + vv * sbpl)[uu]);
+ u += dudx;
+ v += dvdx;
+@@ -348,8 +355,8 @@ void qt_transform_image_rasterize(DestT *destPixels, int dbpl,
+ // End of the scan line, with per-pixel checks.
+ i = toX - x2;
+ while (i) {
+- int uu = qBound(sourceRect.left(), u >> 16, sourceRect.left() + sourceRect.width() - 1);
+- int vv = qBound(sourceRect.top(), v >> 16, sourceRect.top() + sourceRect.height() - 1);
++ qint64 uu = qBound(sourceRectLeft, u >> 16, sourceRectLeft + sourceRectWidth - 1);
++ qint64 vv = qBound(sourceRectTop, v >> 16, sourceRectTop + sourceRectHeight - 1);
+ blender.write(line, reinterpret_cast<const SrcT *>(reinterpret_cast<const uchar *>(srcPixels) + vv * sbpl)[uu]);
+ u += dudx;
+ v += dvdx;
+diff --git a/qtbase/src/gui/painting/qcolortrclut_p.h b/qtbase/src/gui/painting/qcolortrclut_p.h
+index 76a6a60803..24fd522e6c 100644
+--- a/qtbase/src/gui/painting/qcolortrclut_p.h
++++ b/qtbase/src/gui/painting/qcolortrclut_p.h
+@@ -118,6 +118,7 @@ public:
+ return QRgba64::fromRgba64(r, g, b, qAlpha(rgb32) * 257);
+ #endif
+ }
++ QRgba64 toLinear64(QRgba64) const = delete;
+
+ QRgb toLinear(QRgb rgb32) const
+ {
+diff --git a/qtbase/src/gui/painting/qdrawhelper.cpp b/qtbase/src/gui/painting/qdrawhelper.cpp
+index a61793508a..5ba2d277b7 100644
+--- a/qtbase/src/gui/painting/qdrawhelper.cpp
++++ b/qtbase/src/gui/painting/qdrawhelper.cpp
+@@ -6091,7 +6091,7 @@ static inline void alphargbblend_argb32(quint32 *dst, uint coverage, const QRgba
+ static inline void rgbBlendPixel(QRgba64 &dst, int coverage, QRgba64 slinear, const QColorTrcLut *colorProfile)
+ {
+ // Do a gammacorrected RGB alphablend...
+- const QRgba64 dlinear = colorProfile ? colorProfile->toLinear64(dst) : dst;
++ const QRgba64 dlinear = colorProfile ? colorProfile->toLinear(dst) : dst;
+
+ QRgba64 blend = rgbBlend(dlinear, slinear, coverage);
+
+diff --git a/qtbase/src/gui/painting/qpaintengine_raster.cpp b/qtbase/src/gui/painting/qpaintengine_raster.cpp
+index 283923de52..f08eb9cbee 100644
+--- a/qtbase/src/gui/painting/qpaintengine_raster.cpp
++++ b/qtbase/src/gui/painting/qpaintengine_raster.cpp
+@@ -560,31 +560,6 @@ void QRasterPaintEngine::updateMatrix(const QTransform &matrix)
+ QRasterPaintEngineState *s = state();
+ // FALCON: get rid of this line, see drawImage call below.
+ s->matrix = matrix;
+- QTransform::TransformationType txop = s->matrix.type();
+-
+- switch (txop) {
+-
+- case QTransform::TxNone:
+- s->flags.int_xform = true;
+- break;
+-
+- case QTransform::TxTranslate:
+- s->flags.int_xform = qreal(int(s->matrix.dx())) == s->matrix.dx()
+- && qreal(int(s->matrix.dy())) == s->matrix.dy();
+- break;
+-
+- case QTransform::TxScale:
+- s->flags.int_xform = qreal(int(s->matrix.dx())) == s->matrix.dx()
+- && qreal(int(s->matrix.dy())) == s->matrix.dy()
+- && qreal(int(s->matrix.m11())) == s->matrix.m11()
+- && qreal(int(s->matrix.m22())) == s->matrix.m22();
+- break;
+-
+- default: // shear / perspective...
+- s->flags.int_xform = false;
+- break;
+- }
+-
+ s->flags.tx_noshear = qt_scaleForTransform(s->matrix, &s->txscale);
+
+ ensureOutlineMapper();
+@@ -617,7 +592,6 @@ QRasterPaintEngineState::QRasterPaintEngineState()
+ flags.bilinear = false;
+ flags.legacy_rounding = false;
+ flags.fast_text = true;
+- flags.int_xform = true;
+ flags.tx_noshear = true;
+ flags.fast_images = true;
+
+@@ -1793,7 +1767,7 @@ void QRasterPaintEngine::fill(const QVectorPath &path, const QBrush &brush)
+ QRectF cpRect = path.controlPointRect();
+ const QRectF pathDeviceRect = s->matrix.mapRect(cpRect);
+ // Skip paths that by conservative estimates are completely outside the paint device.
+- if (!pathDeviceRect.intersects(QRectF(d->deviceRect)))
++ if (!pathDeviceRect.intersects(QRectF(d->deviceRect)) || !pathDeviceRect.isValid())
+ return;
+
+ ProcessSpans blend = d->getBrushFunc(pathDeviceRect, &s->brushData);
+diff --git a/qtbase/src/gui/painting/qpaintengine_raster_p.h b/qtbase/src/gui/painting/qpaintengine_raster_p.h
+index 089aadc3f7..bf7363d5aa 100644
+--- a/qtbase/src/gui/painting/qpaintengine_raster_p.h
++++ b/qtbase/src/gui/painting/qpaintengine_raster_p.h
+@@ -111,7 +111,6 @@ public:
+ uint bilinear : 1;
+ uint legacy_rounding : 1;
+ uint fast_text : 1;
+- uint int_xform : 1;
+ uint tx_noshear : 1;
+ uint fast_images : 1;
+ };
+diff --git a/qtbase/src/gui/painting/qpainterpath.cpp b/qtbase/src/gui/painting/qpainterpath.cpp
+index f9544a3241..d80fafeaf1 100644
+--- a/qtbase/src/gui/painting/qpainterpath.cpp
++++ b/qtbase/src/gui/painting/qpainterpath.cpp
+@@ -1253,7 +1253,7 @@ void QPainterPath::addText(const QPointF &point, const QFont &f, const QString &
+
+ if (si.analysis.flags < QScriptAnalysis::TabOrObject) {
+ QGlyphLayout glyphs = eng->shapedGlyphs(&si);
+- QFontEngine *fe = f.d->engineForScript(si.analysis.script);
++ QFontEngine *fe = eng->fontEngine(si);
+ Q_ASSERT(fe);
+ fe->addOutlineToPath(x, y, glyphs, this,
+ si.analysis.bidiLevel % 2
+diff --git a/qtbase/src/gui/painting/qpathclipper_p.h b/qtbase/src/gui/painting/qpathclipper_p.h
+index 9444a87b71..18f64c5e8c 100644
+--- a/qtbase/src/gui/painting/qpathclipper_p.h
++++ b/qtbase/src/gui/painting/qpathclipper_p.h
+@@ -156,7 +156,7 @@ public:
+ int vertex(Direction direction) const;
+
+ private:
+- int m_next[2][2];
++ int m_next[2][2] = { { -1, -1 }, { -1, -1 } };
+ };
+
+ class QPathSegments
+@@ -296,10 +296,6 @@ inline QPathEdge::QPathEdge(int a, int b)
+ , angle(0)
+ , invAngle(0)
+ {
+- m_next[0][0] = -1;
+- m_next[1][0] = -1;
+- m_next[0][0] = -1;
+- m_next[1][0] = -1;
+ }
+
+ inline int QPathEdge::next(Traversal traversal, Direction direction) const
+diff --git a/qtbase/src/gui/painting/qpdf.cpp b/qtbase/src/gui/painting/qpdf.cpp
+index 3066744f1b..2c8d3c3b53 100644
+--- a/qtbase/src/gui/painting/qpdf.cpp
++++ b/qtbase/src/gui/painting/qpdf.cpp
+@@ -2760,6 +2760,8 @@ int QPdfEnginePrivate::addBrushPattern(const QTransform &m, bool *specifyColor,
+ return gradientBrush(brush, matrix, gStateObject);
+ }
+
++ matrix = brush.transform() * matrix;
++
+ if ((!brush.isOpaque() && brush.style() < Qt::LinearGradientPattern) || opacity != 1.0)
+ *gStateObject = addConstantAlphaObject(qRound(brush.color().alpha() * opacity),
+ qRound(pen.color().alpha() * opacity));
+diff --git a/qtbase/src/gui/painting/qstroker.cpp b/qtbase/src/gui/painting/qstroker.cpp
+index cb5d395e80..3b6357a893 100644
+--- a/qtbase/src/gui/painting/qstroker.cpp
++++ b/qtbase/src/gui/painting/qstroker.cpp
+@@ -1182,6 +1182,7 @@ void QDashStroker::processCurrentSubpath()
+ // Check if the entire line should be clipped away or simplified
+ bool clipIt = clipping && !lineIntersectsRect(prev, e, clip_tl, clip_br);
+ bool skipDashing = elen * invSumLength > repetitionLimit();
++ int maxDashes = dashCount;
+ if (skipDashing || clipIt) {
+ // Cut away full dash sequences.
+ elen -= std::floor(elen * invSumLength) * sumLength;
+@@ -1196,7 +1197,7 @@ void QDashStroker::processCurrentSubpath()
+ pos = estop; // move pos to next path element
+ done = true;
+ } else { // Dash is on this line
+- pos = dpos + estart;
++ pos = --maxDashes > 0 ? dpos + estart : estop;
+ done = pos >= estop;
+ if (++idash >= dashCount)
+ idash = 0;
+diff --git a/qtbase/src/gui/painting/qt_attribution.json b/qtbase/src/gui/painting/qt_attribution.json
+index 7b16e8c211..0e87d30aa2 100644
+--- a/qtbase/src/gui/painting/qt_attribution.json
++++ b/qtbase/src/gui/painting/qt_attribution.json
+@@ -10,7 +10,7 @@
+ "Homepage": "http://www.freetype.org",
+ "License": "Freetype Project License or GNU General Public License v2.0 only",
+ "LicenseId": "FTL or GPL-2.0",
+- "LicenseFile": "../../3rdparty/freetype/docs/LICENSE.TXT",
++ "LicenseFile": "../../3rdparty/freetype/LICENSE.TXT",
+ "Copyright": "Copyright 2000-2016 by David Turner, Robert Wilhelm, and Werner Lemberg."
+ },
+ {
+diff --git a/qtbase/src/gui/rhi/qshader_p_p.h b/qtbase/src/gui/rhi/qshader_p_p.h
+index ec9d25971f..4a5a7a6d51 100644
+--- a/qtbase/src/gui/rhi/qshader_p_p.h
++++ b/qtbase/src/gui/rhi/qshader_p_p.h
+@@ -68,13 +68,13 @@ struct Q_GUI_EXPORT QShaderPrivate
+ {
+ }
+
+- QShaderPrivate(const QShaderPrivate *other)
++ QShaderPrivate(const QShaderPrivate &other)
+ : ref(1),
+- qsbVersion(other->qsbVersion),
+- stage(other->stage),
+- desc(other->desc),
+- shaders(other->shaders),
+- bindings(other->bindings)
++ qsbVersion(other.qsbVersion),
++ stage(other.stage),
++ desc(other.desc),
++ shaders(other.shaders),
++ bindings(other.bindings)
+ {
+ }
+
+diff --git a/qtbase/src/gui/rhi/qshaderdescription_p_p.h b/qtbase/src/gui/rhi/qshaderdescription_p_p.h
+index ec2b0b6b4c..3da33a8a2b 100644
+--- a/qtbase/src/gui/rhi/qshaderdescription_p_p.h
++++ b/qtbase/src/gui/rhi/qshaderdescription_p_p.h
+@@ -63,16 +63,16 @@ struct Q_GUI_EXPORT QShaderDescriptionPrivate
+ localSize[0] = localSize[1] = localSize[2] = 0;
+ }
+
+- QShaderDescriptionPrivate(const QShaderDescriptionPrivate *other)
++ QShaderDescriptionPrivate(const QShaderDescriptionPrivate &other)
+ : ref(1),
+- inVars(other->inVars),
+- outVars(other->outVars),
+- uniformBlocks(other->uniformBlocks),
+- pushConstantBlocks(other->pushConstantBlocks),
+- storageBlocks(other->storageBlocks),
+- combinedImageSamplers(other->combinedImageSamplers),
+- storageImages(other->storageImages),
+- localSize(other->localSize)
++ inVars(other.inVars),
++ outVars(other.outVars),
++ uniformBlocks(other.uniformBlocks),
++ pushConstantBlocks(other.pushConstantBlocks),
++ storageBlocks(other.storageBlocks),
++ combinedImageSamplers(other.combinedImageSamplers),
++ storageImages(other.storageImages),
++ localSize(other.localSize)
+ {
+ }
+
+diff --git a/qtbase/src/gui/text/qfontdatabase.cpp b/qtbase/src/gui/text/qfontdatabase.cpp
+index a657a8c516..4fc0100958 100644
+--- a/qtbase/src/gui/text/qfontdatabase.cpp
++++ b/qtbase/src/gui/text/qfontdatabase.cpp
+@@ -983,7 +983,7 @@ QFontEngine *loadSingleEngine(int script,
+ if (style->key.stretch != 0 && request.stretch != 0
+ && (request.styleName.isEmpty() || request.styleName != style->styleName)) {
+ def.stretch = (request.stretch * 100 + style->key.stretch / 2) / style->key.stretch;
+- } else {
++ } else if (request.stretch == QFont::AnyStretch) {
+ def.stretch = 100;
+ }
+
+diff --git a/qtbase/src/gui/text/qtextdocumentlayout.cpp b/qtbase/src/gui/text/qtextdocumentlayout.cpp
+index f3e6ea2100..72267e9380 100644
+--- a/qtbase/src/gui/text/qtextdocumentlayout.cpp
++++ b/qtbase/src/gui/text/qtextdocumentlayout.cpp
+@@ -2123,7 +2123,7 @@ void QTextDocumentLayoutPrivate::drawListItem(const QPointF &offset, QPainter *p
+ {
+ Q_Q(const QTextDocumentLayout);
+ const QTextBlockFormat blockFormat = bl.blockFormat();
+- const QTextCharFormat charFormat = QTextCursor(bl).charFormat();
++ const QTextCharFormat charFormat = bl.charFormat();
+ QFont font(charFormat.font());
+ if (q->paintDevice())
+ font = QFont(font, q->paintDevice());
+diff --git a/qtbase/src/gui/text/qtextengine.cpp b/qtbase/src/gui/text/qtextengine.cpp
+index ce4abac472..a6c66e5d2d 100644
+--- a/qtbase/src/gui/text/qtextengine.cpp
++++ b/qtbase/src/gui/text/qtextengine.cpp
+@@ -1,6 +1,6 @@
+ /****************************************************************************
+ **
+-** Copyright (C) 2016 The Qt Company Ltd.
++** Copyright (C) 2021 The Qt Company Ltd.
+ ** Contact: https://www.qt.io/licensing/
+ **
+ ** This file is part of the QtGui module of the Qt Toolkit.
+@@ -1565,6 +1565,12 @@ void QTextEngine::shapeText(int item) const
+ // Overwrite with 0 token to indicate failure
+ QGlyphLayout g = availableGlyphs(&si);
+ g.glyphs[0] = 0;
++ g.attributes[0].clusterStart = true;
++
++ ushort *log_clusters = logClusters(&si);
++ for (int i = 0; i < itemLength; ++i)
++ log_clusters[i] = 0;
++
+ return;
+ }
+
+diff --git a/qtbase/src/gui/util/qdesktopservices.cpp b/qtbase/src/gui/util/qdesktopservices.cpp
+index fbb63a9408..4d5fafaaa7 100644
+--- a/qtbase/src/gui/util/qdesktopservices.cpp
++++ b/qtbase/src/gui/util/qdesktopservices.cpp
+@@ -54,6 +54,8 @@
+ #include <qpa/qplatformintegration.h>
+ #include <qdir.h>
+
++#include <QtCore/private/qlocking_p.h>
++
+ QT_BEGIN_NAMESPACE
+
+ class QOpenUrlHandlerRegistry : public QObject
+@@ -81,6 +83,7 @@ Q_GLOBAL_STATIC(QOpenUrlHandlerRegistry, handlerRegistry)
+
+ void QOpenUrlHandlerRegistry::handlerDestroyed(QObject *handler)
+ {
++ const auto lock = qt_scoped_lock(mutex);
+ HandlerHash::Iterator it = handlers.begin();
+ while (it != handlers.end()) {
+ if (it->receiver == handler) {
+@@ -294,7 +297,8 @@ void QDesktopServices::setUrlHandler(const QString &scheme, QObject *receiver, c
+ h.name = method;
+ registry->handlers.insert(scheme.toLower(), h);
+ QObject::connect(receiver, SIGNAL(destroyed(QObject*)),
+- registry, SLOT(handlerDestroyed(QObject*)));
++ registry, SLOT(handlerDestroyed(QObject*)),
++ Qt::DirectConnection);
+ }
+
+ /*!
+diff --git a/qtbase/src/gui/util/qpkmhandler.cpp b/qtbase/src/gui/util/qpkmhandler.cpp
+index e0c3b75efe..3414f9d8ba 100644
+--- a/qtbase/src/gui/util/qpkmhandler.cpp
++++ b/qtbase/src/gui/util/qpkmhandler.cpp
+@@ -57,7 +57,7 @@ struct PkmType
+ quint32 bytesPerBlock;
+ };
+
+-static PkmType typeMap[5] = {
++static constexpr PkmType typeMap[5] = {
+ { 0x8D64, 8 }, // GL_ETC1_RGB8_OES
+ { 0x9274, 8 }, // GL_COMPRESSED_RGB8_ETC2
+ { 0, 0 }, // unused (obsolete)
+diff --git a/qtbase/src/network/access/qnetworkreplyfileimpl.cpp b/qtbase/src/network/access/qnetworkreplyfileimpl.cpp
+index b6be93147a..6e69b4c4d3 100644
+--- a/qtbase/src/network/access/qnetworkreplyfileimpl.cpp
++++ b/qtbase/src/network/access/qnetworkreplyfileimpl.cpp
+@@ -89,9 +89,10 @@ QNetworkReplyFileImpl::QNetworkReplyFileImpl(QNetworkAccessManager *manager, con
+ // we handle only local files
+ QString msg = QCoreApplication::translate("QNetworkAccessFileBackend", "Request for opening non-local file %1").arg(url.toString());
+ setError(QNetworkReply::ProtocolInvalidOperationError, msg);
++ setFinished(true); // We're finished, will emit finished() after ctor is done.
+ QMetaObject::invokeMethod(this, "errorOccurred", Qt::QueuedConnection,
+ Q_ARG(QNetworkReply::NetworkError, QNetworkReply::ProtocolInvalidOperationError));
+- fileOpenFinished(false);
++ QMetaObject::invokeMethod(this, [this](){ fileOpenFinished(false); }, Qt::QueuedConnection);
+ return;
+ }
+ #endif
+diff --git a/qtbase/src/network/access/qnetworkreplyimpl.cpp b/qtbase/src/network/access/qnetworkreplyimpl.cpp
+index bcdf6ee2f1..3b6deb82bd 100644
+--- a/qtbase/src/network/access/qnetworkreplyimpl.cpp
++++ b/qtbase/src/network/access/qnetworkreplyimpl.cpp
+@@ -680,7 +680,7 @@ void QNetworkReplyImplPrivate::appendDownstreamData(QIODevice *data)
+ // read until EOF from data
+ if (Q_UNLIKELY(copyDevice)) {
+ qCritical("QNetworkReplyImpl: copy from QIODevice already in progress -- "
+- "backend probly needs to be fixed");
++ "backend probably needs to be fixed");
+ return;
+ }
+
+diff --git a/qtbase/src/network/kernel/qauthenticator.cpp b/qtbase/src/network/kernel/qauthenticator.cpp
+index d9fe7bc47b..ccd04b294a 100644
+--- a/qtbase/src/network/kernel/qauthenticator.cpp
++++ b/qtbase/src/network/kernel/qauthenticator.cpp
+@@ -50,6 +50,7 @@
+ #include <qstring.h>
+ #include <qdatetime.h>
+ #include <qrandom.h>
++#include "private/qsystemlibrary_p.h"
+
+ #ifdef Q_OS_WIN
+ #include <qmutex.h>
+@@ -1563,7 +1564,7 @@ static bool q_SSPI_library_load()
+
+ // Initialize security interface
+ if (pSecurityFunctionTable == nullptr) {
+- securityDLLHandle = LoadLibrary(L"secur32.dll");
++ securityDLLHandle = QSystemLibrary::load(L"secur32");
+ if (securityDLLHandle != nullptr) {
+ INIT_SECURITY_INTERFACE pInitSecurityInterface =
+ reinterpret_cast<INIT_SECURITY_INTERFACE>(
+diff --git a/qtbase/src/network/kernel/qhostinfo_unix.cpp b/qtbase/src/network/kernel/qhostinfo_unix.cpp
+index 9b0a2ee669..73679c9ef1 100644
+--- a/qtbase/src/network/kernel/qhostinfo_unix.cpp
++++ b/qtbase/src/network/kernel/qhostinfo_unix.cpp
+@@ -122,7 +122,6 @@ static QFunctionPointer resolveSymbol(QLibrary &lib, const char *sym)
+
+ LibResolv::LibResolv()
+ {
+- QLibrary lib;
+ #ifdef LIBRESOLV_SO
+ lib.setFileName(QStringLiteral(LIBRESOLV_SO));
+ if (!lib.load())
+diff --git a/qtbase/src/network/socket/qsocks5socketengine.cpp b/qtbase/src/network/socket/qsocks5socketengine.cpp
+index 3a046fd116..97fadca0b3 100644
+--- a/qtbase/src/network/socket/qsocks5socketengine.cpp
++++ b/qtbase/src/network/socket/qsocks5socketengine.cpp
+@@ -1296,7 +1296,7 @@ void QSocks5SocketEnginePrivate::_q_udpSocketReadNotification()
+ int pos = 0;
+ const char *buf = inBuf.constData();
+ if (inBuf.size() < 4) {
+- QSOCKS5_D_DEBUG << "bugus udp data, discarding";
++ QSOCKS5_D_DEBUG << "bogus udp data, discarding";
+ return;
+ }
+ QSocks5RevivedDatagram datagram;
+diff --git a/qtbase/src/network/ssl/qsslcontext_openssl.cpp b/qtbase/src/network/ssl/qsslcontext_openssl.cpp
+index c9f202f573..c992da9d8e 100644
+--- a/qtbase/src/network/ssl/qsslcontext_openssl.cpp
++++ b/qtbase/src/network/ssl/qsslcontext_openssl.cpp
+@@ -409,7 +409,7 @@ init_context:
+ break;
+ case QSsl::DtlsV1_0OrLater:
+ minVersion = DTLS1_VERSION;
+- maxVersion = DTLS_MAX_VERSION;
++ maxVersion = 0;
+ break;
+ case QSsl::DtlsV1_2:
+ minVersion = DTLS1_2_VERSION;
+@@ -417,7 +417,7 @@ init_context:
+ break;
+ case QSsl::DtlsV1_2OrLater:
+ minVersion = DTLS1_2_VERSION;
+- maxVersion = DTLS_MAX_VERSION;
++ maxVersion = 0;
+ break;
+ case QSsl::TlsV1_3OrLater:
+ #ifdef TLS1_3_VERSION
+@@ -455,7 +455,7 @@ init_context:
+ }
+
+ // Enable bug workarounds.
+- long options = QSslSocketBackendPrivate::setupOpenSslOptions(configuration.protocol(), configuration.d->sslOptions);
++ qssloptions options = QSslSocketBackendPrivate::setupOpenSslOptions(configuration.protocol(), configuration.d->sslOptions);
+ q_SSL_CTX_set_options(sslContext->ctx, options);
+
+ // Tell OpenSSL to release memory early
+diff --git a/qtbase/src/network/ssl/qssldiffiehellmanparameters_openssl.cpp b/qtbase/src/network/ssl/qssldiffiehellmanparameters_openssl.cpp
+index aaf8741130..b58935372c 100644
+--- a/qtbase/src/network/ssl/qssldiffiehellmanparameters_openssl.cpp
++++ b/qtbase/src/network/ssl/qssldiffiehellmanparameters_openssl.cpp
+@@ -59,57 +59,6 @@
+
+ QT_BEGIN_NAMESPACE
+
+-#ifdef OPENSSL_NO_DEPRECATED_3_0
+-
+-static int q_DH_check(DH *dh, int *status)
+-{
+- // DH_check was first deprecated in OpenSSL 3.0.0, as low-level
+- // API; the EVP_PKEY family of functions was advised as an alternative.
+- // As of now EVP_PKEY_params_check ends up calling ... DH_check,
+- // which is good enough.
+-
+- Q_ASSERT(dh);
+- Q_ASSERT(status);
+-
+- EVP_PKEY *key = q_EVP_PKEY_new();
+- if (!key) {
+- qCWarning(lcSsl, "EVP_PKEY_new failed");
+- QSslSocketBackendPrivate::logAndClearErrorQueue();
+- return 0;
+- }
+- const auto keyDeleter = qScopeGuard([key](){
+- q_EVP_PKEY_free(key);
+- });
+- if (!q_EVP_PKEY_set1_DH(key, dh)) {
+- qCWarning(lcSsl, "EVP_PKEY_set1_DH failed");
+- QSslSocketBackendPrivate::logAndClearErrorQueue();
+- return 0;
+- }
+-
+- EVP_PKEY_CTX *keyCtx = q_EVP_PKEY_CTX_new(key, nullptr);
+- if (!keyCtx) {
+- qCWarning(lcSsl, "EVP_PKEY_CTX_new failed");
+- QSslSocketBackendPrivate::logAndClearErrorQueue();
+- return 0;
+- }
+- const auto ctxDeleter = qScopeGuard([keyCtx]{
+- q_EVP_PKEY_CTX_free(keyCtx);
+- });
+-
+- const int result = q_EVP_PKEY_param_check(keyCtx);
+- QSslSocketBackendPrivate::logAndClearErrorQueue();
+- // Note: unlike DH_check, we cannot obtain the 'status',
+- // if the 'result' is 0 (actually the result is 1 only
+- // if this 'status' was 0). We could probably check the
+- // errors from the error queue, but it's not needed anyway
+- // - see the 'isSafeDH' below, how it returns immediately
+- // on 0.
+- Q_UNUSED(status)
+-
+- return result;
+-}
+-#endif // OPENSSL_NO_DEPRECATED_3_0
+-
+ static bool isSafeDH(DH *dh)
+ {
+ int status = 0;
+diff --git a/qtbase/src/network/ssl/qsslsocket_openssl.cpp b/qtbase/src/network/ssl/qsslsocket_openssl.cpp
+index 37fad2a68f..8f6858c867 100644
+--- a/qtbase/src/network/ssl/qsslsocket_openssl.cpp
++++ b/qtbase/src/network/ssl/qsslsocket_openssl.cpp
+@@ -550,9 +550,9 @@ static void q_loadCiphersForConnection(SSL *connection, QList<QSslCipher> &ciphe
+ // Defined in qsslsocket.cpp
+ void q_setDefaultDtlsCiphers(const QList<QSslCipher> &ciphers);
+
+-long QSslSocketBackendPrivate::setupOpenSslOptions(QSsl::SslProtocol protocol, QSsl::SslOptions sslOptions)
++qssloptions QSslSocketBackendPrivate::setupOpenSslOptions(QSsl::SslProtocol protocol, QSsl::SslOptions sslOptions)
+ {
+- long options;
++ qssloptions options;
+ if (protocol == QSsl::TlsV1SslV3)
+ options = SSL_OP_ALL|SSL_OP_NO_SSLv2|SSL_OP_NO_SSLv3;
+ else if (protocol == QSsl::SecureProtocols)
+diff --git a/qtbase/src/network/ssl/qsslsocket_openssl_p.h b/qtbase/src/network/ssl/qsslsocket_openssl_p.h
+index 4103de23e8..5547589256 100644
+--- a/qtbase/src/network/ssl/qsslsocket_openssl_p.h
++++ b/qtbase/src/network/ssl/qsslsocket_openssl_p.h
+@@ -107,6 +107,12 @@
+
+ QT_BEGIN_NAMESPACE
+
++#if defined(OPENSSL_VERSION_MAJOR) && OPENSSL_VERSION_MAJOR >= 3
++typedef uint64_t qssloptions;
++#else
++typedef unsigned long qssloptions;
++#endif
++
+ struct QSslErrorEntry {
+ int code;
+ int depth;
+@@ -171,7 +177,7 @@ public:
+ QVector<QSslError> ocspErrors;
+ QByteArray ocspResponseDer;
+
+- Q_AUTOTEST_EXPORT static long setupOpenSslOptions(QSsl::SslProtocol protocol, QSsl::SslOptions sslOptions);
++ Q_AUTOTEST_EXPORT static qssloptions setupOpenSslOptions(QSsl::SslProtocol protocol, QSsl::SslOptions sslOptions);
+ static QSslCipher QSslCipher_from_SSL_CIPHER(const SSL_CIPHER *cipher);
+ static QList<QSslCertificate> STACKOFX509_to_QSslCertificates(STACK_OF(X509) *x509);
+ static QList<QSslError> verify(const QList<QSslCertificate> &certificateChain, const QString &hostName);
+diff --git a/qtbase/src/network/ssl/qsslsocket_openssl_symbols.cpp b/qtbase/src/network/ssl/qsslsocket_openssl_symbols.cpp
+index e53fb279f0..459ccd0b19 100644
+--- a/qtbase/src/network/ssl/qsslsocket_openssl_symbols.cpp
++++ b/qtbase/src/network/ssl/qsslsocket_openssl_symbols.cpp
+@@ -148,7 +148,6 @@ DEFINEFUNC(int, EVP_PKEY_up_ref, EVP_PKEY *a, a, return 0, return)
+ DEFINEFUNC2(EVP_PKEY_CTX *, EVP_PKEY_CTX_new, EVP_PKEY *pkey, pkey, ENGINE *e, e, return nullptr, return)
+ DEFINEFUNC(int, EVP_PKEY_param_check, EVP_PKEY_CTX *ctx, ctx, return 0, return)
+ DEFINEFUNC(void, EVP_PKEY_CTX_free, EVP_PKEY_CTX *ctx, ctx, return, return)
+-DEFINEFUNC(int, EVP_PKEY_base_id, EVP_PKEY *a, a, return NID_undef, return)
+ DEFINEFUNC(int, RSA_bits, RSA *a, a, return 0, return)
+ DEFINEFUNC(int, DSA_bits, DSA *a, a, return 0, return)
+ DEFINEFUNC(int, OPENSSL_sk_num, OPENSSL_STACK *a, a, return -1, return)
+@@ -158,7 +157,7 @@ DEFINEFUNC2(void, OPENSSL_sk_push, OPENSSL_STACK *a, a, void *b, b, return, DUMM
+ DEFINEFUNC(void, OPENSSL_sk_free, OPENSSL_STACK *a, a, return, DUMMYARG)
+ DEFINEFUNC2(void *, OPENSSL_sk_value, OPENSSL_STACK *a, a, int b, b, return nullptr, return)
+ DEFINEFUNC(int, SSL_session_reused, SSL *a, a, return 0, return)
+-DEFINEFUNC2(unsigned long, SSL_CTX_set_options, SSL_CTX *ctx, ctx, unsigned long op, op, return 0, return)
++DEFINEFUNC2(qssloptions, SSL_CTX_set_options, SSL_CTX *ctx, ctx, qssloptions op, op, return 0, return)
+ DEFINEFUNC(int, SSL_CTX_get_security_level, const SSL_CTX *ctx, ctx, return -1, return)
+ DEFINEFUNC2(void, SSL_CTX_set_security_level, SSL_CTX *ctx, ctx, int level, level, return, return)
+ #ifdef TLS1_3_VERSION
+@@ -371,7 +370,15 @@ DEFINEFUNC(const SSL_CIPHER *, SSL_get_current_cipher, SSL *a, a, return nullptr
+ DEFINEFUNC(int, SSL_version, const SSL *a, a, return 0, return)
+ DEFINEFUNC2(int, SSL_get_error, SSL *a, a, int b, b, return -1, return)
+ DEFINEFUNC(STACK_OF(X509) *, SSL_get_peer_cert_chain, SSL *a, a, return nullptr, return)
++
++#if defined(OPENSSL_VERSION_MAJOR) && OPENSSL_VERSION_MAJOR >= 3
++DEFINEFUNC(X509 *, SSL_get1_peer_certificate, SSL *a, a, return nullptr, return)
++DEFINEFUNC(int, EVP_PKEY_get_base_id, const EVP_PKEY *pkey, pkey, return -1, return)
++#else
+ DEFINEFUNC(X509 *, SSL_get_peer_certificate, SSL *a, a, return nullptr, return)
++DEFINEFUNC(int, EVP_PKEY_base_id, EVP_PKEY *a, a, return NID_undef, return)
++#endif // OPENSSL_VERSION_MAJOR >= 3
++
+ DEFINEFUNC(long, SSL_get_verify_result, const SSL *a, a, return -1, return)
+ DEFINEFUNC(SSL *, SSL_new, SSL_CTX *a, a, return nullptr, return)
+ DEFINEFUNC(SSL_CTX *, SSL_get_SSL_CTX, SSL *a, a, return nullptr, return)
+@@ -492,9 +499,7 @@ DEFINEFUNC(DH *, DH_new, DUMMYARG, DUMMYARG, return nullptr, return)
+ DEFINEFUNC(void, DH_free, DH *dh, dh, return, DUMMYARG)
+ DEFINEFUNC3(DH *, d2i_DHparams, DH**a, a, const unsigned char **pp, pp, long length, length, return nullptr, return)
+ DEFINEFUNC2(int, i2d_DHparams, DH *a, a, unsigned char **p, p, return -1, return)
+-#ifndef OPENSSL_NO_DEPRECATED_3_0
+ DEFINEFUNC2(int, DH_check, DH *dh, dh, int *codes, codes, return 0, return)
+-#endif // OPENSSL_NO_DEPRECATED_3_0
+ DEFINEFUNC3(BIGNUM *, BN_bin2bn, const unsigned char *s, s, int len, len, BIGNUM *ret, ret, return nullptr, return)
+
+ #ifndef OPENSSL_NO_EC
+@@ -868,7 +873,6 @@ bool q_resolveOpenSslSymbols()
+ RESOLVEFUNC(EVP_PKEY_CTX_new)
+ RESOLVEFUNC(EVP_PKEY_param_check)
+ RESOLVEFUNC(EVP_PKEY_CTX_free)
+- RESOLVEFUNC(EVP_PKEY_base_id)
+ RESOLVEFUNC(RSA_bits)
+ RESOLVEFUNC(OPENSSL_sk_new_null)
+ RESOLVEFUNC(OPENSSL_sk_push)
+@@ -1107,7 +1111,15 @@ bool q_resolveOpenSslSymbols()
+ RESOLVEFUNC(SSL_version)
+ RESOLVEFUNC(SSL_get_error)
+ RESOLVEFUNC(SSL_get_peer_cert_chain)
++
++#if defined(OPENSSL_VERSION_MAJOR) && OPENSSL_VERSION_MAJOR >= 3
++ RESOLVEFUNC(SSL_get1_peer_certificate)
++ RESOLVEFUNC(EVP_PKEY_get_base_id)
++#else
+ RESOLVEFUNC(SSL_get_peer_certificate)
++ RESOLVEFUNC(EVP_PKEY_base_id)
++#endif // OPENSSL_VERSION_MAJOR >= 3
++
+ RESOLVEFUNC(SSL_get_verify_result)
+ RESOLVEFUNC(SSL_new)
+ RESOLVEFUNC(SSL_get_SSL_CTX)
+@@ -1206,9 +1218,7 @@ bool q_resolveOpenSslSymbols()
+ RESOLVEFUNC(DH_free)
+ RESOLVEFUNC(d2i_DHparams)
+ RESOLVEFUNC(i2d_DHparams)
+-#ifndef OPENSSL_NO_DEPRECATED_3_0
+ RESOLVEFUNC(DH_check)
+-#endif // OPENSSL_NO_DEPRECATED_3_0
+ RESOLVEFUNC(BN_bin2bn)
+
+ #ifndef OPENSSL_NO_EC
+diff --git a/qtbase/src/network/ssl/qsslsocket_openssl_symbols_p.h b/qtbase/src/network/ssl/qsslsocket_openssl_symbols_p.h
+index 95e8897a3b..27aeffa18a 100644
+--- a/qtbase/src/network/ssl/qsslsocket_openssl_symbols_p.h
++++ b/qtbase/src/network/ssl/qsslsocket_openssl_symbols_p.h
+@@ -237,7 +237,6 @@ Q_AUTOTEST_EXPORT int q_EVP_PKEY_up_ref(EVP_PKEY *a);
+ EVP_PKEY_CTX *q_EVP_PKEY_CTX_new(EVP_PKEY *pkey, ENGINE *e);
+ void q_EVP_PKEY_CTX_free(EVP_PKEY_CTX *ctx);
+ int q_EVP_PKEY_param_check(EVP_PKEY_CTX *ctx);
+-int q_EVP_PKEY_base_id(EVP_PKEY *a);
+ int q_RSA_bits(RSA *a);
+ Q_AUTOTEST_EXPORT int q_OPENSSL_sk_num(OPENSSL_STACK *a);
+ Q_AUTOTEST_EXPORT void q_OPENSSL_sk_pop_free(OPENSSL_STACK *a, void (*b)(void *));
+@@ -246,7 +245,7 @@ Q_AUTOTEST_EXPORT void q_OPENSSL_sk_push(OPENSSL_STACK *st, void *data);
+ Q_AUTOTEST_EXPORT void q_OPENSSL_sk_free(OPENSSL_STACK *a);
+ Q_AUTOTEST_EXPORT void * q_OPENSSL_sk_value(OPENSSL_STACK *a, int b);
+ int q_SSL_session_reused(SSL *a);
+-unsigned long q_SSL_CTX_set_options(SSL_CTX *ctx, unsigned long op);
++qssloptions q_SSL_CTX_set_options(SSL_CTX *ctx, qssloptions op);
+ int q_OPENSSL_init_ssl(uint64_t opts, const OPENSSL_INIT_SETTINGS *settings);
+ size_t q_SSL_get_client_random(SSL *a, unsigned char *out, size_t outlen);
+ size_t q_SSL_SESSION_get_master_key(const SSL_SESSION *session, unsigned char *out, size_t outlen);
+@@ -510,7 +509,6 @@ const SSL_CIPHER *q_SSL_get_current_cipher(SSL *a);
+ int q_SSL_version(const SSL *a);
+ int q_SSL_get_error(SSL *a, int b);
+ STACK_OF(X509) *q_SSL_get_peer_cert_chain(SSL *a);
+-X509 *q_SSL_get_peer_certificate(SSL *a);
+ long q_SSL_get_verify_result(const SSL *a);
+ SSL *q_SSL_new(SSL_CTX *a);
+ SSL_CTX *q_SSL_get_SSL_CTX(SSL *a);
+@@ -582,10 +580,7 @@ DH *q_DH_new();
+ void q_DH_free(DH *dh);
+ DH *q_d2i_DHparams(DH **a, const unsigned char **pp, long length);
+ int q_i2d_DHparams(DH *a, unsigned char **p);
+-
+-#ifndef OPENSSL_NO_DEPRECATED_3_0
+ int q_DH_check(DH *dh, int *codes);
+-#endif // OPENSSL_NO_DEPRECATED_3_0
+
+ BIGNUM *q_BN_bin2bn(const unsigned char *s, int len, BIGNUM *ret);
+ #define q_SSL_CTX_set_tmp_dh(ctx, dh) q_SSL_CTX_ctrl((ctx), SSL_CTRL_SET_TMP_DH, 0, (char *)dh)
+@@ -754,6 +749,17 @@ void q_CRYPTO_free(void *str, const char *file, int line);
+ int q_SSL_CTX_get_security_level(const SSL_CTX *ctx);
+ void q_SSL_CTX_set_security_level(SSL_CTX *ctx, int level);
+
++// Here we have the ones that make difference between OpenSSL pre/post v3:
++#if defined(OPENSSL_VERSION_MAJOR) && OPENSSL_VERSION_MAJOR >= 3
++X509 *q_SSL_get1_peer_certificate(SSL *a);
++#define q_SSL_get_peer_certificate q_SSL_get1_peer_certificate
++int q_EVP_PKEY_get_base_id(const EVP_PKEY *pkey);
++#define q_EVP_PKEY_base_id q_EVP_PKEY_get_base_id
++#else
++X509 *q_SSL_get_peer_certificate(SSL *a);
++int q_EVP_PKEY_base_id(EVP_PKEY *a);
++#endif // OPENSSL_VERSION_MAJOR >= 3
++
+ QT_END_NAMESPACE
+
+ #endif
+diff --git a/qtbase/src/platformsupport/eglconvenience/qt_egl_p.h b/qtbase/src/platformsupport/eglconvenience/qt_egl_p.h
+index bf37d07fd8..dbd42fb799 100644
+--- a/qtbase/src/platformsupport/eglconvenience/qt_egl_p.h
++++ b/qtbase/src/platformsupport/eglconvenience/qt_egl_p.h
+@@ -61,7 +61,11 @@
+ # if !defined(Q_OS_INTEGRITY)
+ # define WIN_INTERFACE_CUSTOM // NV
+ # endif // Q_OS_INTEGRITY
+-#endif // QT_EGL_NO_X11
++#else // QT_EGL_NO_X11
++// If one has an eglplatform.h with https://github.com/KhronosGroup/EGL-Registry/pull/130
++// that needs USE_X11 to be defined.
++# define USE_X11
++#endif
+
+ #ifdef QT_EGL_WAYLAND
+ # define WAYLAND // NV
+diff --git a/qtbase/src/platformsupport/fontdatabases/fontconfig/qfontconfigdatabase.cpp b/qtbase/src/platformsupport/fontdatabases/fontconfig/qfontconfigdatabase.cpp
+index 159b490ce0..00aa80cd58 100644
+--- a/qtbase/src/platformsupport/fontdatabases/fontconfig/qfontconfigdatabase.cpp
++++ b/qtbase/src/platformsupport/fontdatabases/fontconfig/qfontconfigdatabase.cpp
+@@ -567,6 +567,8 @@ void QFontconfigDatabase::populateFontDatabase()
+ fonts = FcFontList(nullptr, pattern, os);
+ FcObjectSetDestroy(os);
+ FcPatternDestroy(pattern);
++ if (!fonts)
++ return;
+ }
+
+ for (int i = 0; i < fonts->nfont; i++)
+diff --git a/qtbase/src/platformsupport/input/xkbcommon/qxkbcommon.cpp b/qtbase/src/platformsupport/input/xkbcommon/qxkbcommon.cpp
+index b713c19447..7cb9a8c79a 100644
+--- a/qtbase/src/platformsupport/input/xkbcommon/qxkbcommon.cpp
++++ b/qtbase/src/platformsupport/input/xkbcommon/qxkbcommon.cpp
+@@ -95,6 +95,7 @@ static constexpr const auto KeyTbl = qMakeArray(
+ Xkb2Qt<XKB_KEY_Clear, Qt::Key_Delete>,
+ Xkb2Qt<XKB_KEY_Pause, Qt::Key_Pause>,
+ Xkb2Qt<XKB_KEY_Print, Qt::Key_Print>,
++ Xkb2Qt<XKB_KEY_Sys_Req, Qt::Key_SysReq>,
+ Xkb2Qt<0x1005FF60, Qt::Key_SysReq>, // hardcoded Sun SysReq
+ Xkb2Qt<0x1007ff00, Qt::Key_SysReq>, // hardcoded X386 SysReq
+
+@@ -471,7 +472,7 @@ QVector<xkb_keysym_t> QXkbCommon::toKeysym(QKeyEvent *event)
+ } else if (event->modifiers() & Qt::KeypadModifier) {
+ if (qtKey >= Qt::Key_0 && qtKey <= Qt::Key_9)
+ keysyms.append(XKB_KEY_KP_0 + (qtKey - Qt::Key_0));
+- } else if (isLatin(qtKey) && event->text().isUpper()) {
++ } else if (isLatin1(qtKey) && event->text().isUpper()) {
+ keysyms.append(qtKey);
+ }
+
+@@ -523,7 +524,7 @@ int QXkbCommon::keysymToQtKey(xkb_keysym_t keysym, Qt::KeyboardModifiers modifie
+ // With standard shortcuts we should prefer a latin character, this is
+ // for checks like "some qkeyevent == QKeySequence::Copy" to work even
+ // when using for example 'russian' keyboard layout.
+- if (!QXkbCommon::isLatin(keysym)) {
++ if (!QXkbCommon::isLatin1(keysym)) {
+ xkb_keysym_t latinKeysym = QXkbCommon::lookupLatinKeysym(state, code);
+ if (latinKeysym != XKB_KEY_NoSymbol)
+ keysym = latinKeysym;
+@@ -546,7 +547,7 @@ static int keysymToQtKey_internal(xkb_keysym_t keysym, Qt::KeyboardModifiers mod
+ } else if (keysym >= XKB_KEY_KP_0 && keysym <= XKB_KEY_KP_9) {
+ // numeric keypad keys
+ qtKey = Qt::Key_0 + (keysym - XKB_KEY_KP_0);
+- } else if (QXkbCommon::isLatin(keysym)) {
++ } else if (QXkbCommon::isLatin1(keysym)) {
+ qtKey = QXkbCommon::qxkbcommon_xkb_keysym_to_upper(keysym);
+ } else {
+ // check if we have a direct mapping
+@@ -678,7 +679,7 @@ QList<int> QXkbCommon::possibleKeys(xkb_state *state, const QKeyEvent *event,
+ Qt::KeyboardModifiers neededMods = ModsTbl[i];
+ if ((modifiers & neededMods) == neededMods) {
+ if (i == 8) {
+- if (isLatin(baseQtKey))
++ if (isLatin1(baseQtKey))
+ continue;
+ // add a latin key as a fall back key
+ sym = lookupLatinKeysym(state, keycode);
+@@ -733,7 +734,7 @@ void QXkbCommon::verifyHasLatinLayout(xkb_keymap *keymap)
+ for (xkb_layout_index_t layout = 0; layout < layoutCount; ++layout) {
+ for (xkb_keycode_t code = minKeycode; code < maxKeycode; ++code) {
+ xkb_keymap_key_get_syms_by_level(keymap, code, layout, 0, &keysyms);
+- if (keysyms && isLatin(keysyms[0]))
++ if (keysyms && isLatin1(keysyms[0]))
+ nrLatinKeys++;
+ if (nrLatinKeys > 10) // arbitrarily chosen threshold
+ return;
+@@ -766,7 +767,7 @@ xkb_keysym_t QXkbCommon::lookupLatinKeysym(xkb_state *state, xkb_keycode_t keyco
+ xkb_level_index_t level = xkb_state_key_get_level(state, keycode, layout);
+ if (xkb_keymap_key_get_syms_by_level(keymap, keycode, layout, level, &syms) != 1)
+ continue;
+- if (isLatin(syms[0])) {
++ if (isLatin1(syms[0])) {
+ sym = syms[0];
+ break;
+ }
+diff --git a/qtbase/src/platformsupport/input/xkbcommon/qxkbcommon_p.h b/qtbase/src/platformsupport/input/xkbcommon/qxkbcommon_p.h
+index 561eae03db..8389bd8f5a 100644
+--- a/qtbase/src/platformsupport/input/xkbcommon/qxkbcommon_p.h
++++ b/qtbase/src/platformsupport/input/xkbcommon/qxkbcommon_p.h
+@@ -94,8 +94,8 @@ public:
+ static void verifyHasLatinLayout(xkb_keymap *keymap);
+ static xkb_keysym_t lookupLatinKeysym(xkb_state *state, xkb_keycode_t keycode);
+
+- static bool isLatin(xkb_keysym_t sym) {
+- return ((sym >= 'a' && sym <= 'z') || (sym >= 'A' && sym <= 'Z'));
++ static bool isLatin1(xkb_keysym_t sym) {
++ return sym <= 0xff;
+ }
+ static bool isKeypad(xkb_keysym_t sym) {
+ return sym >= XKB_KEY_KP_Space && sym <= XKB_KEY_KP_9;
+diff --git a/qtbase/src/platformsupport/kmsconvenience/qkmsdevice.cpp b/qtbase/src/platformsupport/kmsconvenience/qkmsdevice.cpp
+index 8cd7f9b368..406f84663f 100644
+--- a/qtbase/src/platformsupport/kmsconvenience/qkmsdevice.cpp
++++ b/qtbase/src/platformsupport/kmsconvenience/qkmsdevice.cpp
+@@ -318,7 +318,7 @@ QPlatformScreen *QKmsDevice::createScreenForConnector(drmModeResPtr resources,
+
+ if (current < 0 && crtc_mode.clock != 0) {
+ modes << crtc_mode;
+- current = mode.size() - 1;
++ current = modes.size() - 1;
+ }
+
+ if (configuration == OutputConfigCurrent)
+diff --git a/qtbase/src/platformsupport/linuxaccessibility/atspiadaptor.cpp b/qtbase/src/platformsupport/linuxaccessibility/atspiadaptor.cpp
+index 9153fd20bb..255ea5e33e 100644
+--- a/qtbase/src/platformsupport/linuxaccessibility/atspiadaptor.cpp
++++ b/qtbase/src/platformsupport/linuxaccessibility/atspiadaptor.cpp
+@@ -194,6 +194,9 @@ QString AtSpiAdaptor::introspect(const QString &path) const
+ " <arg direction=\"out\" type=\"(so)\"/>\n"
+ " <annotation value=\"QSpiObjectReference\" name=\"org.qtproject.QtDBus.QtTypeName.Out0\"/>\n"
+ " </method>\n"
++ " <method name=\"GetAccessibleId\">\n"
++ " <arg direction=\"out\" type=\"s\"/>\n"
++ " </method>\n"
+ " </interface>\n"
+ );
+
+@@ -913,8 +916,17 @@ void AtSpiAdaptor::notify(QAccessibleEvent *event)
+ }
+ case QAccessible::NameChanged: {
+ if (sendObject || sendObject_property_change || sendObject_property_change_accessible_name) {
+- QString path = pathForInterface(event->accessibleInterface());
+- QVariantList args = packDBusSignalArguments(QLatin1String("accessible-name"), 0, 0, variantForPath(path));
++ QAccessibleInterface *iface = event->accessibleInterface();
++ if (!iface) {
++ qCDebug(lcAccessibilityAtspi,
++ "NameChanged event from invalid accessible.");
++ return;
++ }
++
++ QString path = pathForInterface(iface);
++ QVariantList args = packDBusSignalArguments(
++ QLatin1String("accessible-name"), 0, 0,
++ QVariant::fromValue(QDBusVariant(iface->text(QAccessible::Name))));
+ sendDBusSignal(path, QLatin1String(ATSPI_DBUS_INTERFACE_EVENT_OBJECT),
+ QLatin1String("PropertyChange"), args);
+ }
+@@ -922,8 +934,17 @@ void AtSpiAdaptor::notify(QAccessibleEvent *event)
+ }
+ case QAccessible::DescriptionChanged: {
+ if (sendObject || sendObject_property_change || sendObject_property_change_accessible_description) {
+- QString path = pathForInterface(event->accessibleInterface());
+- QVariantList args = packDBusSignalArguments(QLatin1String("accessible-description"), 0, 0, variantForPath(path));
++ QAccessibleInterface *iface = event->accessibleInterface();
++ if (!iface) {
++ qCDebug(lcAccessibilityAtspi,
++ "DescriptionChanged event from invalid accessible.");
++ return;
++ }
++
++ QString path = pathForInterface(iface);
++ QVariantList args = packDBusSignalArguments(
++ QLatin1String("accessible-description"), 0, 0,
++ QVariant::fromValue(QDBusVariant(iface->text(QAccessible::Description))));
+ sendDBusSignal(path, QLatin1String(ATSPI_DBUS_INTERFACE_EVENT_OBJECT),
+ QLatin1String("PropertyChange"), args);
+ }
+@@ -1038,7 +1059,9 @@ void AtSpiAdaptor::notify(QAccessibleEvent *event)
+ // Combo Box with AT-SPI likes to be special
+ // It requires a name-change to update caches and then selection-changed
+ QString path = pathForInterface(iface);
+- QVariantList args1 = packDBusSignalArguments(QLatin1String("accessible-name"), 0, 0, variantForPath(path));
++ QVariantList args1 = packDBusSignalArguments(
++ QLatin1String("accessible-name"), 0, 0,
++ QVariant::fromValue(QDBusVariant(iface->text(QAccessible::Name))));
+ sendDBusSignal(path, QLatin1String(ATSPI_DBUS_INTERFACE_EVENT_OBJECT),
+ QLatin1String("PropertyChange"), args1);
+ QVariantList args2 = packDBusSignalArguments(QString(), 0, 0, QVariant::fromValue(QDBusVariant(QVariant(0))));
+@@ -1358,6 +1381,26 @@ void AtSpiAdaptor::registerApplication()
+ delete registry;
+ }
+
++namespace {
++QString accessibleIdForAccessible(QAccessibleInterface *accessible)
++{
++ QString result;
++ while (accessible) {
++ if (!result.isEmpty())
++ result.prepend(QLatin1Char('.'));
++ if (auto obj = accessible->object()) {
++ const QString name = obj->objectName();
++ if (!name.isEmpty())
++ result.prepend(name);
++ else
++ result.prepend(QString::fromUtf8(obj->metaObject()->className()));
++ }
++ accessible = accessible->parent();
++ }
++ return result;
++}
++} // namespace
++
+ // Accessible
+ bool AtSpiAdaptor::accessibleInterface(QAccessibleInterface *interface, const QString &function, const QDBusMessage &message, const QDBusConnection &connection)
+ {
+@@ -1441,6 +1484,9 @@ bool AtSpiAdaptor::accessibleInterface(QAccessibleInterface *interface, const QS
+ children << ref;
+ }
+ connection.send(message.createReply(QVariant::fromValue(children)));
++ } else if (function == QLatin1String("GetAccessibleId")) {
++ sendReply(connection, message,
++ QVariant::fromValue(QDBusVariant(accessibleIdForAccessible(interface))));
+ } else {
+ qCDebug(lcAccessibilityAtspi) << "WARNING: AtSpiAdaptor::accessibleInterface does not implement " << function << message.path();
+ return false;
+diff --git a/qtbase/src/platformsupport/linuxaccessibility/dbusconnection.cpp b/qtbase/src/platformsupport/linuxaccessibility/dbusconnection.cpp
+index 45ddc8e496..cc734abc63 100644
+--- a/qtbase/src/platformsupport/linuxaccessibility/dbusconnection.cpp
++++ b/qtbase/src/platformsupport/linuxaccessibility/dbusconnection.cpp
+@@ -69,6 +69,21 @@ QT_BEGIN_NAMESPACE
+ DBusConnection::DBusConnection(QObject *parent)
+ : QObject(parent), m_a11yConnection(QString()), m_enabled(false)
+ {
++ // If the bus is explicitly set via env var it overrides everything else.
++ QByteArray addressEnv = qgetenv("AT_SPI_BUS_ADDRESS");
++ if (!addressEnv.isEmpty()) {
++ // Only connect on next loop run, connections to our enabled signal are
++ // only established after the ctor returns.
++ QMetaObject::invokeMethod(
++ this,
++ [this, addressEnv] {
++ m_enabled = true;
++ connectA11yBus(QString::fromLocal8Bit(addressEnv));
++ },
++ Qt::QueuedConnection);
++ return;
++ }
++
+ // Start monitoring if "org.a11y.Bus" is registered as DBus service.
+ QDBusConnection c = QDBusConnection::sessionBus();
+ if (!c.isConnected()) {
+diff --git a/qtbase/src/platformsupport/services/genericunix/qgenericunixservices.cpp b/qtbase/src/platformsupport/services/genericunix/qgenericunixservices.cpp
+index 1a3cab275d..2abe039126 100644
+--- a/qtbase/src/platformsupport/services/genericunix/qgenericunixservices.cpp
++++ b/qtbase/src/platformsupport/services/genericunix/qgenericunixservices.cpp
+@@ -51,6 +51,9 @@
+ #include <QtCore/QStandardPaths>
+ #include <QtCore/QUrl>
+
++#include <QtGui/QGuiApplication>
++#include <QtGui/QWindow>
++
+ #if QT_CONFIG(dbus)
+ // These QtCore includes are needed for xdg-desktop-portal support
+ #include <QtCore/private/qcore_unix_p.h>
+@@ -58,6 +61,8 @@
+ #include <QtCore/QFileInfo>
+ #include <QtCore/QUrlQuery>
+
++#include <QtGui/QColor>
++
+ #include <QtDBus/QDBusConnection>
+ #include <QtDBus/QDBusMessage>
+ #include <QtDBus/QDBusPendingCall>
+@@ -142,6 +147,8 @@ static inline bool detectWebBrowser(const QByteArray &desktop,
+ }
+
+ if (desktop == QByteArray("KDE")) {
++ if (checkExecutable(QStringLiteral("kde-open5"), browser))
++ return true;
+ // Konqueror launcher
+ if (checkExecutable(QStringLiteral("kfmclient"), browser)) {
+ browser->append(QLatin1String(" exec"));
+@@ -296,8 +303,135 @@ static inline QDBusMessage xdgDesktopPortalSendEmail(const QUrl &url)
+
+ return QDBusConnection::sessionBus().call(message);
+ }
++
++namespace {
++struct XDGDesktopColor
++{
++ double r = 0;
++ double g = 0;
++ double b = 0;
++
++ QColor toQColor() const
++ {
++ constexpr auto rgbMax = 255;
++ return { static_cast<int>(r * rgbMax), static_cast<int>(g * rgbMax),
++ static_cast<int>(b * rgbMax) };
++ }
++};
++
++const QDBusArgument &operator>>(const QDBusArgument &argument, XDGDesktopColor &myStruct)
++{
++ argument.beginStructure();
++ argument >> myStruct.r >> myStruct.g >> myStruct.b;
++ argument.endStructure();
++ return argument;
++}
++
++class XdgDesktopPortalColorPicker : public QPlatformServiceColorPicker
++{
++ Q_OBJECT
++public:
++ XdgDesktopPortalColorPicker(const QString &parentWindowId, QWindow *parent)
++ : QPlatformServiceColorPicker(parent), m_parentWindowId(parentWindowId)
++ {
++ }
++
++ void pickColor() override
++ {
++ // DBus signature:
++ // PickColor (IN s parent_window,
++ // IN a{sv} options
++ // OUT o handle)
++ // Options:
++ // handle_token (s) - A string that will be used as the last element of the @handle.
++
++ QDBusMessage message = QDBusMessage::createMethodCall(
++ QStringLiteral("org.freedesktop.portal.Desktop"), QStringLiteral("/org/freedesktop/portal/desktop"),
++ QStringLiteral("org.freedesktop.portal.Screenshot"), QStringLiteral("PickColor"));
++ message << m_parentWindowId << QVariantMap();
++
++ QDBusPendingCall pendingCall = QDBusConnection::sessionBus().asyncCall(message);
++ auto watcher = new QDBusPendingCallWatcher(pendingCall, this);
++ connect(watcher, &QDBusPendingCallWatcher::finished, this,
++ [this](QDBusPendingCallWatcher *watcher) {
++ watcher->deleteLater();
++ QDBusPendingReply<QDBusObjectPath> reply = *watcher;
++ if (reply.isError()) {
++ qWarning("DBus call to pick color failed: %s",
++ qPrintable(reply.error().message()));
++ Q_EMIT colorPicked({});
++ } else {
++ QDBusConnection::sessionBus().connect(
++ QStringLiteral("org.freedesktop.portal.Desktop"), reply.value().path(),
++ QStringLiteral("org.freedesktop.portal.Request"), QStringLiteral("Response"), this,
++ // clang-format off
++ SLOT(gotColorResponse(uint,QVariantMap))
++ // clang-format on
++ );
++ }
++ });
++ }
++
++private Q_SLOTS:
++ void gotColorResponse(uint result, const QVariantMap &map)
++ {
++ if (result != 0)
++ return;
++ XDGDesktopColor color{};
++ map.value(QStringLiteral("color")).value<QDBusArgument>() >> color;
++ Q_EMIT colorPicked(color.toQColor());
++ deleteLater();
++ }
++
++private:
++ const QString m_parentWindowId;
++};
++} // namespace
++
+ #endif // QT_CONFIG(dbus)
+
++QGenericUnixServices::QGenericUnixServices()
++{
++#if QT_CONFIG(dbus)
++ if (qEnvironmentVariableIntValue("QT_NO_XDG_DESKTOP_PORTAL") > 0) {
++ return;
++ }
++ QDBusMessage message = QDBusMessage::createMethodCall(
++ QStringLiteral("org.freedesktop.portal.Desktop"), QStringLiteral("/org/freedesktop/portal/desktop"),
++ QStringLiteral("org.freedesktop.DBus.Properties"), QStringLiteral("Get"));
++ message << QStringLiteral("org.freedesktop.portal.Screenshot")
++ << QStringLiteral("version");
++
++ QDBusPendingCall pendingCall = QDBusConnection::sessionBus().asyncCall(message);
++ auto watcher = new QDBusPendingCallWatcher(pendingCall);
++ QObject::connect(watcher, &QDBusPendingCallWatcher::finished, watcher,
++ [this](QDBusPendingCallWatcher *watcher) {
++ watcher->deleteLater();
++ QDBusPendingReply<QVariant> reply = *watcher;
++ if (!reply.isError() && reply.value().toUInt() >= 2)
++ m_hasScreenshotPortalWithColorPicking = true;
++ });
++
++#endif
++}
++
++QPlatformServiceColorPicker *QGenericUnixServices::colorPicker(QWindow *parent)
++{
++#if QT_CONFIG(dbus)
++ // Make double sure that we are in a wayland environment. In particular check
++ // WAYLAND_DISPLAY so also XWayland apps benefit from portal-based color picking.
++ // Outside wayland we'll rather rely on other means than the XDG desktop portal.
++ if (!qEnvironmentVariableIsEmpty("WAYLAND_DISPLAY")
++ || QGuiApplication::platformName().startsWith(QLatin1String("wayland"))) {
++ return new XdgDesktopPortalColorPicker(portalWindowIdentifier(parent), parent);
++ }
++ return nullptr;
++#else
++ Q_UNUSED(parent);
++ return nullptr;
++#endif
++}
++
+ QByteArray QGenericUnixServices::desktopEnvironment() const
+ {
+ static const QByteArray result = detectDesktopEnvironment();
+@@ -352,6 +486,8 @@ bool QGenericUnixServices::openDocument(const QUrl &url)
+ }
+
+ #else
++QGenericUnixServices::QGenericUnixServices() = default;
++
+ QByteArray QGenericUnixServices::desktopEnvironment() const
+ {
+ return QByteArrayLiteral("UNKNOWN");
+@@ -371,6 +507,30 @@ bool QGenericUnixServices::openDocument(const QUrl &url)
+ return false;
+ }
+
++QPlatformServiceColorPicker *QGenericUnixServices::colorPicker(QWindow *parent)
++{
++ Q_UNUSED(parent);
++ return nullptr;
++}
++
+ #endif // QT_NO_MULTIPROCESS
+
++QString QGenericUnixServices::portalWindowIdentifier(QWindow *window)
++{
++ if (QGuiApplication::platformName() == QLatin1String("xcb"))
++ return QStringLiteral("x11:") + QString::number(window->winId(), 16);
++ return QString();
++}
++
++bool QGenericUnixServices::hasCapability(Capability capability) const
++{
++ switch (capability) {
++ case Capability::ColorPicking:
++ return m_hasScreenshotPortalWithColorPicking;
++ }
++ return false;
++}
++
+ QT_END_NAMESPACE
++
++#include "qgenericunixservices.moc"
+diff --git a/qtbase/src/platformsupport/services/genericunix/qgenericunixservices_p.h b/qtbase/src/platformsupport/services/genericunix/qgenericunixservices_p.h
+index 8ac3de6f03..30924e64bd 100644
+--- a/qtbase/src/platformsupport/services/genericunix/qgenericunixservices_p.h
++++ b/qtbase/src/platformsupport/services/genericunix/qgenericunixservices_p.h
+@@ -59,16 +59,21 @@ QT_BEGIN_NAMESPACE
+ class QGenericUnixServices : public QPlatformServices
+ {
+ public:
+- QGenericUnixServices() {}
++ QGenericUnixServices();
+
+ QByteArray desktopEnvironment() const override;
+
++ bool hasCapability(Capability capability) const override;
+ bool openUrl(const QUrl &url) override;
+ bool openDocument(const QUrl &url) override;
++ QPlatformServiceColorPicker *colorPicker(QWindow *parent = nullptr) override;
++
++ virtual QString portalWindowIdentifier(QWindow *window);
+
+ private:
+ QString m_webBrowser;
+ QString m_documentLauncher;
++ bool m_hasScreenshotPortalWithColorPicking = false;
+ };
+
+ QT_END_NAMESPACE
+diff --git a/qtbase/src/platformsupport/themes/genericunix/dbusmenu/qdbusmenuconnection.cpp b/qtbase/src/platformsupport/themes/genericunix/dbusmenu/qdbusmenuconnection.cpp
+index 09470bccc6..cc7c7d4d8a 100644
+--- a/qtbase/src/platformsupport/themes/genericunix/dbusmenu/qdbusmenuconnection.cpp
++++ b/qtbase/src/platformsupport/themes/genericunix/dbusmenu/qdbusmenuconnection.cpp
+@@ -69,6 +69,7 @@ const QString MenuBarPath = QLatin1String("/MenuBar");
+ */
+ QDBusMenuConnection::QDBusMenuConnection(QObject *parent, const QString &serviceName)
+ : QObject(parent)
++ , m_serviceName(serviceName)
+ , m_connection(serviceName.isNull() ? QDBusConnection::sessionBus()
+ : QDBusConnection::connectToBus(QDBusConnection::SessionBus, serviceName))
+ , m_dbusWatcher(new QDBusServiceWatcher(StatusNotifierWatcherService, m_connection, QDBusServiceWatcher::WatchForRegistration, this))
+@@ -83,6 +84,12 @@ QDBusMenuConnection::QDBusMenuConnection(QObject *parent, const QString &service
+ #endif
+ }
+
++QDBusMenuConnection::~QDBusMenuConnection()
++{
++ if (!m_serviceName.isEmpty() && m_connection.isConnected())
++ QDBusConnection::disconnectFromBus(m_serviceName);
++}
++
+ void QDBusMenuConnection::dbusError(const QDBusError &error)
+ {
+ qWarning() << "QDBusTrayIcon encountered a D-Bus error:" << error;
+@@ -105,13 +112,7 @@ void QDBusMenuConnection::unregisterTrayIconMenu(QDBusTrayIcon *item)
+
+ bool QDBusMenuConnection::registerTrayIcon(QDBusTrayIcon *item)
+ {
+- bool success = connection().registerService(item->instanceId());
+- if (!success) {
+- qWarning() << "failed to register service" << item->instanceId();
+- return false;
+- }
+-
+- success = connection().registerObject(StatusNotifierItemPath, item);
++ bool success = connection().registerObject(StatusNotifierItemPath, item);
+ if (!success) {
+ unregisterTrayIcon(item);
+ qWarning() << "failed to register" << item->instanceId() << StatusNotifierItemPath;
+@@ -126,21 +127,18 @@ bool QDBusMenuConnection::registerTrayIcon(QDBusTrayIcon *item)
+
+ bool QDBusMenuConnection::registerTrayIconWithWatcher(QDBusTrayIcon *item)
+ {
++ Q_UNUSED(item);
+ QDBusMessage registerMethod = QDBusMessage::createMethodCall(
+ StatusNotifierWatcherService, StatusNotifierWatcherPath, StatusNotifierWatcherService,
+ QLatin1String("RegisterStatusNotifierItem"));
+- registerMethod.setArguments(QVariantList() << item->instanceId());
++ registerMethod.setArguments(QVariantList() << m_connection.baseService());
+ return m_connection.callWithCallback(registerMethod, this, SIGNAL(trayIconRegistered()), SLOT(dbusError(QDBusError)));
+ }
+
+-bool QDBusMenuConnection::unregisterTrayIcon(QDBusTrayIcon *item)
++void QDBusMenuConnection::unregisterTrayIcon(QDBusTrayIcon *item)
+ {
+ unregisterTrayIconMenu(item);
+ connection().unregisterObject(StatusNotifierItemPath);
+- bool success = connection().unregisterService(item->instanceId());
+- if (!success)
+- qWarning() << "failed to unregister service" << item->instanceId();
+- return success;
+ }
+ #endif // QT_NO_SYSTEMTRAYICON
+
+diff --git a/qtbase/src/platformsupport/themes/genericunix/dbusmenu/qdbusmenuconnection_p.h b/qtbase/src/platformsupport/themes/genericunix/dbusmenu/qdbusmenuconnection_p.h
+index f484795fbb..97bdfabb85 100644
+--- a/qtbase/src/platformsupport/themes/genericunix/dbusmenu/qdbusmenuconnection_p.h
++++ b/qtbase/src/platformsupport/themes/genericunix/dbusmenu/qdbusmenuconnection_p.h
+@@ -70,6 +70,7 @@ class QDBusMenuConnection : public QObject
+
+ public:
+ QDBusMenuConnection(QObject *parent = nullptr, const QString &serviceName = QString());
++ ~QDBusMenuConnection();
+ QDBusConnection connection() const { return m_connection; }
+ QDBusServiceWatcher *dbusWatcher() const { return m_dbusWatcher; }
+ bool isStatusNotifierHostRegistered() const { return m_statusNotifierHostRegistered; }
+@@ -78,7 +79,7 @@ public:
+ void unregisterTrayIconMenu(QDBusTrayIcon *item);
+ bool registerTrayIcon(QDBusTrayIcon *item);
+ bool registerTrayIconWithWatcher(QDBusTrayIcon *item);
+- bool unregisterTrayIcon(QDBusTrayIcon *item);
++ void unregisterTrayIcon(QDBusTrayIcon *item);
+ #endif // QT_NO_SYSTEMTRAYICON
+
+ Q_SIGNALS:
+@@ -90,6 +91,7 @@ private Q_SLOTS:
+ void dbusError(const QDBusError &error);
+
+ private:
++ QString m_serviceName;
+ QDBusConnection m_connection;
+ QDBusServiceWatcher *m_dbusWatcher;
+ bool m_statusNotifierHostRegistered;
+diff --git a/qtbase/src/platformsupport/themes/genericunix/dbustray/qdbustrayicon.cpp b/qtbase/src/platformsupport/themes/genericunix/dbustray/qdbustrayicon.cpp
+index bede70975a..76bfec5e5a 100644
+--- a/qtbase/src/platformsupport/themes/genericunix/dbustray/qdbustrayicon.cpp
++++ b/qtbase/src/platformsupport/themes/genericunix/dbustray/qdbustrayicon.cpp
+@@ -71,8 +71,12 @@ Q_LOGGING_CATEGORY(qLcTray, "qt.qpa.tray")
+ static QString iconTempPath()
+ {
+ QString tempPath = QStandardPaths::writableLocation(QStandardPaths::RuntimeLocation);
+- if (!tempPath.isEmpty())
++ if (!tempPath.isEmpty()) {
++ QString flatpakId = qEnvironmentVariable("FLATPAK_ID");
++ if (!flatpakId.isEmpty() && QFileInfo::exists(QLatin1String("/.flatpak-info")))
++ tempPath += QLatin1String("/app/") + flatpakId;
+ return tempPath;
++ }
+
+ tempPath = QStandardPaths::writableLocation(QStandardPaths::GenericCacheLocation);
+
+diff --git a/qtbase/src/platformsupport/themes/genericunix/qgenericunixthemes.cpp b/qtbase/src/platformsupport/themes/genericunix/qgenericunixthemes.cpp
+index cb1b39db64..6e01af052c 100644
+--- a/qtbase/src/platformsupport/themes/genericunix/qgenericunixthemes.cpp
++++ b/qtbase/src/platformsupport/themes/genericunix/qgenericunixthemes.cpp
+@@ -755,6 +755,9 @@ QVariant QGnomeTheme::themeHint(QPlatformTheme::ThemeHint hint) const
+ return QVariant(QChar(0x2022));
+ case QPlatformTheme::UiEffects:
+ return QVariant(int(HoverEffect));
++ case QPlatformTheme::ButtonPressKeys:
++ return QVariant::fromValue(
++ QList<Qt::Key>({ Qt::Key_Space, Qt::Key_Return, Qt::Key_Enter, Qt::Key_Select }));
+ default:
+ break;
+ }
+diff --git a/qtbase/src/plugins/platforms/eglfs/api/qeglfscursor.cpp b/qtbase/src/plugins/platforms/eglfs/api/qeglfscursor.cpp
+index 98e05195ee..1e92f43dec 100644
+--- a/qtbase/src/plugins/platforms/eglfs/api/qeglfscursor.cpp
++++ b/qtbase/src/plugins/platforms/eglfs/api/qeglfscursor.cpp
+@@ -343,8 +343,7 @@ void QEglFSCursor::paintOnScreen()
+ // screens are siblings of each other. When not enabled, the sibling list
+ // only contains m_screen itself.
+ for (QPlatformScreen *screen : m_screen->virtualSiblings()) {
+- if (screen->geometry().contains(cr.topLeft().toPoint() + m_cursor.hotSpot)
+- && QOpenGLContext::currentContext()->screen() == screen->screen())
++ if (screen->geometry().contains(cr.topLeft().toPoint() + m_cursor.hotSpot))
+ {
+ cr.translate(-screen->geometry().topLeft());
+ const QSize screenSize = screen->geometry().size();
+@@ -468,11 +467,12 @@ void QEglFSCursor::draw(const QRectF &r)
+ {
+ StateSaver stateSaver;
+
+- QEglFSCursorData &gfx = static_cast<QEglFSContext*>(QOpenGLContext::currentContext()->handle())->cursorData;
+- if (!gfx.program) {
+- // one time initialization
++ // one time initialization
++ if (!QOpenGLFunctions::d_ptr)
+ initializeOpenGLFunctions();
+
++ QEglFSCursorData &gfx = static_cast<QEglFSContext*>(QOpenGLContext::currentContext()->handle())->cursorData;
++ if (!gfx.program) {
+ createShaderPrograms();
+
+ if (!gfx.atlasTexture) {
+diff --git a/qtbase/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmseventreader.cpp b/qtbase/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmseventreader.cpp
+index 645a0ae2e9..3e0e406f1a 100644
+--- a/qtbase/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmseventreader.cpp
++++ b/qtbase/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmseventreader.cpp
+@@ -179,7 +179,7 @@ void QEglFSKmsEventReader::create(QEglFSKmsDevice *device)
+
+ m_device = device;
+
+- qCDebug(qLcEglfsKmsDebug, "Initalizing event reader for device %p fd %d",
++ qCDebug(qLcEglfsKmsDebug, "Initializing event reader for device %p fd %d",
+ m_device, m_device->fd());
+
+ m_thread = new QEglFSKmsEventReaderThread(m_device->fd());
+diff --git a/qtbase/src/plugins/platforms/offscreen/qoffscreenintegration.cpp b/qtbase/src/plugins/platforms/offscreen/qoffscreenintegration.cpp
+index 141fb68a23..d4294d425a 100644
+--- a/qtbase/src/plugins/platforms/offscreen/qoffscreenintegration.cpp
++++ b/qtbase/src/plugins/platforms/offscreen/qoffscreenintegration.cpp
+@@ -122,11 +122,13 @@ QOffscreenIntegration::QOffscreenIntegration()
+ #endif
+ m_services.reset(new QPlatformServices);
+
+- QWindowSystemInterface::handleScreenAdded(new QOffscreenScreen);
++ m_screen = new QOffscreenScreen;
++ QWindowSystemInterface::handleScreenAdded(m_screen);
+ }
+
+ QOffscreenIntegration::~QOffscreenIntegration()
+ {
++ QWindowSystemInterface::handleScreenRemoved(m_screen);
+ }
+
+ void QOffscreenIntegration::initialize()
+diff --git a/qtbase/src/plugins/platforms/offscreen/qoffscreenintegration.h b/qtbase/src/plugins/platforms/offscreen/qoffscreenintegration.h
+index 0ea90f6c2f..fe00fde07c 100644
+--- a/qtbase/src/plugins/platforms/offscreen/qoffscreenintegration.h
++++ b/qtbase/src/plugins/platforms/offscreen/qoffscreenintegration.h
+@@ -84,6 +84,7 @@ protected:
+ #endif
+ QScopedPointer<QPlatformInputContext> m_inputContext;
+ QScopedPointer<QPlatformServices> m_services;
++ QPlatformScreen *m_screen;
+ mutable QScopedPointer<QPlatformNativeInterface> m_nativeInterface;
+ };
+
+diff --git a/qtbase/src/plugins/platforms/windows/qwindowsglcontext.cpp b/qtbase/src/plugins/platforms/windows/qwindowsglcontext.cpp
+index 6fa5a8a2b3..1f49f0aefd 100644
+--- a/qtbase/src/plugins/platforms/windows/qwindowsglcontext.cpp
++++ b/qtbase/src/plugins/platforms/windows/qwindowsglcontext.cpp
+@@ -48,6 +48,7 @@
+ #include <qpa/qplatformnativeinterface.h>
+ #include <QtPlatformHeaders/qwglnativecontext.h>
+
++#include <private/qsystemlibrary_p.h>
+ #include <algorithm>
+
+ #include <wingdi.h>
+@@ -162,19 +163,25 @@ QFunctionPointer QWindowsOpengl32DLL::resolve(const char *name)
+
+ bool QWindowsOpengl32DLL::init(bool softwareRendering)
+ {
+- const QByteArray opengl32 = QByteArrayLiteral("opengl32.dll");
+- const QByteArray swopengl = QByteArrayLiteral("opengl32sw.dll");
++ const QByteArray opengl32 = QByteArrayLiteral("opengl32");
++ const QByteArray swopengl = QByteArrayLiteral("opengl32sw");
++ bool useSystemLib = false;
+
+ QByteArray openglDll = qgetenv("QT_OPENGL_DLL");
+- if (openglDll.isEmpty())
++ if (openglDll.isEmpty()) {
+ openglDll = softwareRendering ? swopengl : opengl32;
++ useSystemLib = !softwareRendering;
++ }
+
+ openglDll = openglDll.toLower();
+ m_nonOpengl32 = openglDll != opengl32;
+
+ qCDebug(lcQpaGl) << "Qt: Using WGL and OpenGL from" << openglDll;
+
+- m_lib = ::LoadLibraryA(openglDll.constData());
++ if (useSystemLib)
++ m_lib = QSystemLibrary::load((wchar_t*)(QString::fromLatin1(openglDll).utf16()));
++ else
++ m_lib = LoadLibraryA(openglDll.constData());
+ if (!m_lib) {
+ qErrnoWarning(::GetLastError(), "Failed to load %s", openglDll.constData());
+ return false;
+@@ -184,7 +191,7 @@ bool QWindowsOpengl32DLL::init(bool softwareRendering)
+ // Load opengl32.dll always. GDI functions like ChoosePixelFormat do
+ // GetModuleHandle for opengl32.dll and behave differently (and call back into
+ // opengl32) when the module is present. This is fine for dummy contexts and windows.
+- ::LoadLibraryA("opengl32.dll");
++ QSystemLibrary::load(L"opengl32");
+ }
+
+ wglCreateContext = reinterpret_cast<HGLRC (WINAPI *)(HDC)>(resolve("wglCreateContext"));
+diff --git a/qtbase/src/plugins/platforms/windows/qwindowsopengltester.cpp b/qtbase/src/plugins/platforms/windows/qwindowsopengltester.cpp
+index d7d186e804..9eb4011bf2 100644
+--- a/qtbase/src/plugins/platforms/windows/qwindowsopengltester.cpp
++++ b/qtbase/src/plugins/platforms/windows/qwindowsopengltester.cpp
+@@ -49,6 +49,7 @@
+ #include <QtCore/qstandardpaths.h>
+ #include <QtCore/qlibraryinfo.h>
+ #include <QtCore/qhash.h>
++#include <private/qsystemlibrary_p.h>
+
+ #ifndef QT_NO_OPENGL
+ #include <private/qopengl_p.h>
+@@ -396,7 +397,7 @@ bool QWindowsOpenGLTester::testDesktopGL()
+
+ // Test #1: Load opengl32.dll and try to resolve an OpenGL 2 function.
+ // This will typically fail on systems that do not have a real OpenGL driver.
+- lib = LoadLibraryA("opengl32.dll");
++ lib = QSystemLibrary::load(L"opengl32");
+ if (lib) {
+ CreateContext = reinterpret_cast<CreateContextType>(
+ reinterpret_cast<QFunctionPointer>(::GetProcAddress(lib, "wglCreateContext")));
+diff --git a/qtbase/src/plugins/platforms/xcb/nativepainting/qtessellator.cpp b/qtbase/src/plugins/platforms/xcb/nativepainting/qtessellator.cpp
+index 1afa00cfc9..118af6ce73 100644
+--- a/qtbase/src/plugins/platforms/xcb/nativepainting/qtessellator.cpp
++++ b/qtbase/src/plugins/platforms/xcb/nativepainting/qtessellator.cpp
+@@ -41,6 +41,7 @@
+
+ #include <QRect>
+ #include <QList>
++#include <QMap>
+ #include <QDebug>
+
+ #include <qmath.h>
+diff --git a/qtbase/src/plugins/platforms/xcb/qxcbconnection.cpp b/qtbase/src/plugins/platforms/xcb/qxcbconnection.cpp
+index 9e2a37a6a1..e6e175a118 100644
+--- a/qtbase/src/plugins/platforms/xcb/qxcbconnection.cpp
++++ b/qtbase/src/plugins/platforms/xcb/qxcbconnection.cpp
+@@ -488,12 +488,12 @@ void QXcbConnection::printXcbError(const char *message, xcb_generic_error_t *err
+ uint clamped_error_code = qMin<uint>(error->error_code, (sizeof(xcb_errors) / sizeof(xcb_errors[0])) - 1);
+ uint clamped_major_code = qMin<uint>(error->major_code, (sizeof(xcb_protocol_request_codes) / sizeof(xcb_protocol_request_codes[0])) - 1);
+
+- qCWarning(lcQpaXcb, "%s: %d (%s), sequence: %d, resource id: %d, major code: %d (%s), minor code: %d",
+- message,
+- int(error->error_code), xcb_errors[clamped_error_code],
+- int(error->sequence), int(error->resource_id),
+- int(error->major_code), xcb_protocol_request_codes[clamped_major_code],
+- int(error->minor_code));
++ qCDebug(lcQpaXcb, "%s: %d (%s), sequence: %d, resource id: %d, major code: %d (%s), minor code: %d",
++ message,
++ int(error->error_code), xcb_errors[clamped_error_code],
++ int(error->sequence), int(error->resource_id),
++ int(error->major_code), xcb_protocol_request_codes[clamped_major_code],
++ int(error->minor_code));
+ }
+
+ static Qt::MouseButtons translateMouseButtons(int s)
+@@ -702,6 +702,8 @@ void QXcbConnection::handleXcbEvent(xcb_generic_event_t *event)
+ QXcbVirtualDesktop *virtualDesktop = virtualDesktopForRootWindow(propertyNotify->window);
+ if (virtualDesktop)
+ virtualDesktop->updateWorkArea();
++ } else if (propertyNotify->atom == atom(QXcbAtom::_NET_SUPPORTED)) {
++ m_wmSupport->updateNetWMAtoms();
+ } else {
+ HANDLE_PLATFORM_WINDOW_EVENT(xcb_property_notify_event_t, window, handlePropertyNotifyEvent);
+ }
+@@ -750,7 +752,7 @@ void QXcbConnection::handleXcbEvent(xcb_generic_event_t *event)
+ case XCB_XKB_NEW_KEYBOARD_NOTIFY: {
+ xcb_xkb_new_keyboard_notify_event_t *ev = &xkb_event->new_keyboard_notify;
+ if (ev->changed & XCB_XKB_NKN_DETAIL_KEYCODES)
+- m_keyboard->updateKeymap(ev);
++ m_keyboard->updateKeymap();
+ break;
+ }
+ default:
+diff --git a/qtbase/src/plugins/platforms/xcb/qxcbintegration.cpp b/qtbase/src/plugins/platforms/xcb/qxcbintegration.cpp
+index 76869ced60..02d2eebb56 100644
+--- a/qtbase/src/plugins/platforms/xcb/qxcbintegration.cpp
++++ b/qtbase/src/plugins/platforms/xcb/qxcbintegration.cpp
+@@ -274,8 +274,7 @@ QPlatformWindow *QXcbIntegration::createForeignWindow(QWindow *window, WId nativ
+ #ifndef QT_NO_OPENGL
+ QPlatformOpenGLContext *QXcbIntegration::createPlatformOpenGLContext(QOpenGLContext *context) const
+ {
+- QXcbScreen *screen = static_cast<QXcbScreen *>(context->screen()->handle());
+- QXcbGlIntegration *glIntegration = screen->connection()->glIntegration();
++ QXcbGlIntegration *glIntegration = defaultConnection()->glIntegration();
+ if (!glIntegration) {
+ qWarning("QXcbIntegration: Cannot create platform OpenGL context, neither GLX nor EGL are enabled");
+ return nullptr;
+diff --git a/qtbase/src/plugins/platforms/xcb/qxcbkeyboard.cpp b/qtbase/src/plugins/platforms/xcb/qxcbkeyboard.cpp
+index efecd7e2d1..e8286381a2 100644
+--- a/qtbase/src/plugins/platforms/xcb/qxcbkeyboard.cpp
++++ b/qtbase/src/plugins/platforms/xcb/qxcbkeyboard.cpp
+@@ -365,17 +365,6 @@ void QXcbKeyboard::updateKeymap(xcb_mapping_notify_event_t *event)
+ updateKeymap();
+ }
+
+-void QXcbKeyboard::updateKeymap(xcb_xkb_new_keyboard_notify_event_t *event)
+-{
+- if (!event)
+- return;
+-
+- if (event->deviceID != event->oldDeviceID)
+- m_config = false;
+-
+- updateKeymap();
+-}
+-
+ void QXcbKeyboard::updateKeymap()
+ {
+ KeysymModifierMap keysymMods;
+@@ -383,6 +372,8 @@ void QXcbKeyboard::updateKeymap()
+ keysymMods = keysymsToModifiers();
+ updateModifiers(keysymMods);
+
++ m_config = true;
++
+ if (!m_xkbContext) {
+ m_xkbContext.reset(xkb_context_new(XKB_CONTEXT_NO_DEFAULT_INCLUDES));
+ if (!m_xkbContext) {
+@@ -398,13 +389,8 @@ void QXcbKeyboard::updateKeymap()
+ if (connection()->hasXKB()) {
+ m_xkbKeymap.reset(xkb_x11_keymap_new_from_device(m_xkbContext.get(), xcb_connection(),
+ core_device_id, XKB_KEYMAP_COMPILE_NO_FLAGS));
+- if (m_xkbKeymap) {
+- if (m_config)
+- m_xkbState.reset(xkb_state_new(m_xkbKeymap.get()));
+- else
+- m_xkbState.reset(xkb_x11_state_new_from_device(m_xkbKeymap.get(), xcb_connection(), core_device_id));
+-
+- }
++ if (m_xkbKeymap)
++ m_xkbState.reset(xkb_x11_state_new_from_device(m_xkbKeymap.get(), xcb_connection(), core_device_id));
+ } else {
+ m_xkbKeymap.reset(keymapFromCore(keysymMods));
+ if (m_xkbKeymap)
+@@ -425,8 +411,6 @@ void QXcbKeyboard::updateKeymap()
+ updateXKBMods();
+
+ QXkbCommon::verifyHasLatinLayout(m_xkbKeymap.get());
+-
+- m_config = true;
+ }
+
+ QList<int> QXcbKeyboard::possibleKeys(const QKeyEvent *event) const
+diff --git a/qtbase/src/plugins/platforms/xcb/qxcbkeyboard.h b/qtbase/src/plugins/platforms/xcb/qxcbkeyboard.h
+index b652c85fe3..0ee08aeff2 100644
+--- a/qtbase/src/plugins/platforms/xcb/qxcbkeyboard.h
++++ b/qtbase/src/plugins/platforms/xcb/qxcbkeyboard.h
+@@ -69,7 +69,6 @@ public:
+
+ Qt::KeyboardModifiers translateModifiers(int s) const;
+ void updateKeymap(xcb_mapping_notify_event_t *event);
+- void updateKeymap(xcb_xkb_new_keyboard_notify_event_t *event);
+ void updateKeymap();
+ QList<int> possibleKeys(const QKeyEvent *event) const;
+
+diff --git a/qtbase/src/plugins/platforms/xcb/qxcbwindow.cpp b/qtbase/src/plugins/platforms/xcb/qxcbwindow.cpp
+index ffda7b6a57..863e961f4c 100644
+--- a/qtbase/src/plugins/platforms/xcb/qxcbwindow.cpp
++++ b/qtbase/src/plugins/platforms/xcb/qxcbwindow.cpp
+@@ -564,11 +564,6 @@ void QXcbWindow::setGeometry(const QRect &rect)
+ {
+ QPlatformWindow::setGeometry(rect);
+
+- if (shouldDeferTask(Task::SetGeometry)) {
+- m_deferredGeometry = rect;
+- return;
+- }
+-
+ propagateSizeHints();
+
+ QXcbScreen *currentScreen = xcbScreen();
+@@ -693,9 +688,6 @@ void QXcbWindow::setVisible(bool visible)
+
+ void QXcbWindow::show()
+ {
+- if (shouldDeferTask(Task::Map))
+- return;
+-
+ if (window()->isTopLevel()) {
+
+ // update WM_NORMAL_HINTS
+@@ -706,7 +698,7 @@ void QXcbWindow::show()
+ if (isTransient(window())) {
+ const QWindow *tp = window()->transientParent();
+ if (tp && tp->handle())
+- transientXcbParent = static_cast<const QXcbWindow *>(tp->handle())->winId();
++ transientXcbParent = tp->handle()->winId();
+ // Default to client leader if there is no transient parent, else modal dialogs can
+ // be hidden by their parents.
+ if (!transientXcbParent)
+@@ -746,10 +738,6 @@ void QXcbWindow::show()
+
+ void QXcbWindow::hide()
+ {
+- if (shouldDeferTask(Task::Unmap))
+- return;
+-
+- m_wmStateValid = false;
+ xcb_unmap_window(xcb_connection(), m_window);
+
+ // send synthetic UnmapNotify event according to icccm 4.1.4
+@@ -909,9 +897,6 @@ QXcbWindow::NetWmStates QXcbWindow::netWmStates()
+
+ void QXcbWindow::setWindowFlags(Qt::WindowFlags flags)
+ {
+- if (shouldDeferTask(Task::SetWindowFlags))
+- return;
+-
+ Qt::WindowType type = static_cast<Qt::WindowType>(int(flags & Qt::WindowType_Mask));
+
+ if (type == Qt::ToolTip)
+@@ -941,8 +926,6 @@ void QXcbWindow::setWindowFlags(Qt::WindowFlags flags)
+
+ setTransparentForMouseEvents(flags & Qt::WindowTransparentForInput);
+ updateDoesNotAcceptFocus(flags & Qt::WindowDoesNotAcceptFocus);
+-
+- m_isWmManagedWindow = !(flags & Qt::X11BypassWindowManagerHint);
+ }
+
+ void QXcbWindow::setMotifWmHints(Qt::WindowFlags flags)
+@@ -1142,9 +1125,6 @@ void QXcbWindow::setWindowState(Qt::WindowStates state)
+ if (state == m_windowState)
+ return;
+
+- if (shouldDeferTask(Task::SetWindowState))
+- return;
+-
+ // unset old state
+ if (m_windowState & Qt::WindowMinimized)
+ xcb_map_window(xcb_connection(), m_window);
+@@ -1350,6 +1330,12 @@ void QXcbWindow::setWindowIcon(const QIcon &icon)
+ }
+
+ if (!icon_data.isEmpty()) {
++ // Ignore icon exceeding maximum xcb request length
++ if (icon_data.size() > xcb_get_maximum_request_length(xcb_connection())) {
++ qWarning("Ignoring window icon: Size %llu exceeds maximum xcb request length %u.",
++ icon_data.size(), xcb_get_maximum_request_length(xcb_connection()));
++ return;
++ }
+ xcb_change_property(xcb_connection(),
+ XCB_PROP_MODE_REPLACE,
+ m_window,
+@@ -1639,7 +1625,7 @@ void QXcbWindow::setWmWindowType(QXcbWindowFunctions::WmWindowTypes types, Qt::W
+ break;
+ }
+
+- if ((flags & Qt::FramelessWindowHint) && !(type & QXcbWindowFunctions::KdeOverride)) {
++ if ((flags & Qt::FramelessWindowHint) && !(types & QXcbWindowFunctions::KdeOverride)) {
+ // override netwm type - quick and easy for KDE noborder
+ atoms.append(atom(QXcbAtom::_KDE_NET_WM_WINDOW_TYPE_OVERRIDE));
+ }
+@@ -1894,10 +1880,6 @@ void QXcbWindow::handleUnmapNotifyEvent(const xcb_unmap_notify_event_t *event)
+ if (event->window == m_window) {
+ m_mapped = false;
+ QWindowSystemInterface::handleExposeEvent(window(), QRegion());
+- if (!m_isWmManagedWindow || parent()) {
+- m_wmStateValid = true;
+- handleDeferredTasks();
+- }
+ }
+ }
+
+@@ -2212,98 +2194,30 @@ void QXcbWindow::handleLeaveNotifyEvent(const xcb_leave_notify_event_t *event)
+ handleLeaveNotifyEvent(event->root_x, event->root_y, event->mode, event->detail, event->time);
+ }
+
+-bool QXcbWindow::shouldDeferTask(Task task)
+-{
+- if (m_wmStateValid)
+- return false;
+-
+- m_deferredTasks.append(task);
+- return true;
+-}
+-
+-void QXcbWindow::handleDeferredTasks()
+-{
+- Q_ASSERT(m_wmStateValid == true);
+- if (m_deferredTasks.isEmpty())
+- return;
+-
+- bool map = false;
+- bool unmap = false;
+-
+- QVector<Task> tasks;
+- for (auto taskIt = m_deferredTasks.rbegin(); taskIt != m_deferredTasks.rend(); ++taskIt) {
+- if (!tasks.contains(*taskIt))
+- tasks.prepend(*taskIt);
+- }
+-
+- for (Task task : tasks) {
+- switch (task) {
+- case Task::Map:
+- map = true;
+- unmap = false;
+- break;
+- case Task::Unmap:
+- unmap = true;
+- map = false;
+- break;
+- case Task::SetGeometry:
+- setGeometry(m_deferredGeometry);
+- break;
+- case Task::SetWindowFlags:
+- setWindowFlags(window()->flags());
+- break;
+- case Task::SetWindowState:
+- setWindowState(window()->windowState());
+- break;
+- }
+- }
+- m_deferredTasks.clear();
+-
+- if (map) {
+- Q_ASSERT(unmap == false);
+- show();
+- }
+- if (unmap) {
+- Q_ASSERT(map == false);
+- hide();
+- }
+-}
+-
+ void QXcbWindow::handlePropertyNotifyEvent(const xcb_property_notify_event_t *event)
+ {
+ connection()->setTime(event->time);
+
+- const bool wmStateChanged = event->atom == atom(QXcbAtom::WM_STATE);
+- const bool netWmStateChanged = event->atom == atom(QXcbAtom::_NET_WM_STATE);
+- if (netWmStateChanged || wmStateChanged) {
+- if (wmStateChanged && !m_wmStateValid && m_isWmManagedWindow) {
+- // ICCCM 4.1.4
+- // Clients that want to re-use a client window (e.g. by mapping it again)
+- // after withdrawing it must wait for the withdrawal to be complete before
+- // proceeding. The preferred method for doing this is for clients to wait for
+- // a window manager to update or remove the WM_STATE property.
+- m_wmStateValid = true;
+- handleDeferredTasks();
+- }
+- if (event->state == XCB_PROPERTY_DELETE)
++ const bool propertyDeleted = event->state == XCB_PROPERTY_DELETE;
++
++ if (event->atom == atom(QXcbAtom::_NET_WM_STATE) || event->atom == atom(QXcbAtom::WM_STATE)) {
++ if (propertyDeleted)
+ return;
+
+- if (wmStateChanged) {
++ Qt::WindowStates newState = Qt::WindowNoState;
++
++ if (event->atom == atom(QXcbAtom::WM_STATE)) { // WM_STATE: Quick check for 'Minimize'.
+ auto reply = Q_XCB_REPLY(xcb_get_property, xcb_connection(),
+ 0, m_window, atom(QXcbAtom::WM_STATE),
+ XCB_ATOM_ANY, 0, 1024);
+ if (reply && reply->format == 32 && reply->type == atom(QXcbAtom::WM_STATE)) {
+- auto data = static_cast<const quint32 *>(xcb_get_property_value(reply.get()));
+- if (reply->length != 0) {
+- const bool changedToWithdrawn = data[0] == XCB_ICCCM_WM_STATE_WITHDRAWN;
+- const bool changedToIconic = data[0] == XCB_ICCCM_WM_STATE_ICONIC;
+- m_minimized = changedToIconic || (changedToWithdrawn && m_minimized);
+- }
++ const quint32 *data = (const quint32 *)xcb_get_property_value(reply.get());
++ if (reply->length != 0)
++ m_minimized = (data[0] == XCB_ICCCM_WM_STATE_ICONIC
++ || (data[0] == XCB_ICCCM_WM_STATE_WITHDRAWN && m_minimized));
+ }
+ }
+
+- // _NET_WM_STATE handling
+- Qt::WindowStates newState = Qt::WindowNoState;
+ const NetWmStates states = netWmStates();
+ // _NET_WM_STATE_HIDDEN should be set by the Window Manager to indicate that a window would
+ // not be visible on the screen if its desktop/viewport were active and its coordinates were
+@@ -2325,6 +2239,7 @@ void QXcbWindow::handlePropertyNotifyEvent(const xcb_property_notify_event_t *ev
+ if ((m_windowState & Qt::WindowMinimized) && connection()->mouseGrabber() == this)
+ connection()->setMouseGrabber(nullptr);
+ }
++ return;
+ } else if (event->atom == atom(QXcbAtom::_NET_FRAME_EXTENTS)) {
+ m_dirtyFrameMargins = true;
+ }
+diff --git a/qtbase/src/plugins/platforms/xcb/qxcbwindow.h b/qtbase/src/plugins/platforms/xcb/qxcbwindow.h
+index 55af9279b1..6f5c1f5ed9 100644
+--- a/qtbase/src/plugins/platforms/xcb/qxcbwindow.h
++++ b/qtbase/src/plugins/platforms/xcb/qxcbwindow.h
+@@ -74,14 +74,6 @@ public:
+
+ Q_DECLARE_FLAGS(NetWmStates, NetWmState)
+
+- enum Task {
+- Map,
+- Unmap,
+- SetGeometry,
+- SetWindowFlags,
+- SetWindowState
+- };
+-
+ QXcbWindow(QWindow *window);
+ ~QXcbWindow();
+
+@@ -151,9 +143,6 @@ public:
+
+ QXcbWindow *toWindow() override;
+
+- bool shouldDeferTask(Task task);
+- void handleDeferredTasks();
+-
+ void handleMouseEvent(xcb_timestamp_t time, const QPoint &local, const QPoint &global,
+ Qt::KeyboardModifiers modifiers, QEvent::Type type, Qt::MouseEventSource source);
+
+@@ -292,11 +281,6 @@ protected:
+ int m_swapInterval = -1;
+
+ qreal m_sizeHintsScaleFactor = 1.0;
+-
+- bool m_wmStateValid = true;
+- QVector<Task> m_deferredTasks;
+- bool m_isWmManagedWindow = true;
+- QRect m_deferredGeometry;
+ };
+
+ class QXcbForeignWindow : public QXcbWindow
+diff --git a/qtbase/src/plugins/platformthemes/gtk3/qgtk3menu.cpp b/qtbase/src/plugins/platformthemes/gtk3/qgtk3menu.cpp
+index d9d117faeb..640b49daa0 100644
+--- a/qtbase/src/plugins/platformthemes/gtk3/qgtk3menu.cpp
++++ b/qtbase/src/plugins/platformthemes/gtk3/qgtk3menu.cpp
+@@ -85,6 +85,7 @@ QGtk3MenuItem::QGtk3MenuItem()
+ m_checkable(false),
+ m_checked(false),
+ m_enabled(true),
++ m_exclusive(false),
+ m_underline(false),
+ m_invalid(true),
+ m_menu(nullptr),
+diff --git a/qtbase/src/plugins/platformthemes/xdgdesktopportal/qxdgdesktopportalfiledialog.cpp b/qtbase/src/plugins/platformthemes/xdgdesktopportal/qxdgdesktopportalfiledialog.cpp
+index 0048bbc1e6..396e7f6d1c 100644
+--- a/qtbase/src/plugins/platformthemes/xdgdesktopportal/qxdgdesktopportalfiledialog.cpp
++++ b/qtbase/src/plugins/platformthemes/xdgdesktopportal/qxdgdesktopportalfiledialog.cpp
+@@ -102,15 +102,12 @@ const QDBusArgument &operator >>(const QDBusArgument &arg, QXdgDesktopPortalFile
+ class QXdgDesktopPortalFileDialogPrivate
+ {
+ public:
+- QXdgDesktopPortalFileDialogPrivate(QPlatformFileDialogHelper *nativeFileDialog)
++ QXdgDesktopPortalFileDialogPrivate(QPlatformFileDialogHelper *nativeFileDialog, uint fileChooserPortalVersion)
+ : nativeFileDialog(nativeFileDialog)
++ , fileChooserPortalVersion(fileChooserPortalVersion)
+ { }
+
+- WId winId = 0;
+- bool directoryMode = false;
+- bool modal = false;
+- bool multipleFiles = false;
+- bool saveFile = false;
++ QEventLoop loop;
+ QString acceptLabel;
+ QString directory;
+ QString title;
+@@ -121,19 +118,27 @@ public:
+ QString selectedMimeTypeFilter;
+ QString selectedNameFilter;
+ QStringList selectedFiles;
+- QPlatformFileDialogHelper *nativeFileDialog = nullptr;
++ std::unique_ptr<QPlatformFileDialogHelper> nativeFileDialog;
++ uint fileChooserPortalVersion = 0;
++ bool failedToOpen = false;
++ bool directoryMode = false;
++ bool multipleFiles = false;
++ bool saveFile = false;
+ };
+
+-QXdgDesktopPortalFileDialog::QXdgDesktopPortalFileDialog(QPlatformFileDialogHelper *nativeFileDialog)
++QXdgDesktopPortalFileDialog::QXdgDesktopPortalFileDialog(QPlatformFileDialogHelper *nativeFileDialog, uint fileChooserPortalVersion)
+ : QPlatformFileDialogHelper()
+- , d_ptr(new QXdgDesktopPortalFileDialogPrivate(nativeFileDialog))
++ , d_ptr(new QXdgDesktopPortalFileDialogPrivate(nativeFileDialog, fileChooserPortalVersion))
+ {
+ Q_D(QXdgDesktopPortalFileDialog);
+
+ if (d->nativeFileDialog) {
+- connect(d->nativeFileDialog, SIGNAL(accept()), this, SIGNAL(accept()));
+- connect(d->nativeFileDialog, SIGNAL(reject()), this, SIGNAL(reject()));
++ connect(d->nativeFileDialog.get(), SIGNAL(accept()), this, SIGNAL(accept()));
++ connect(d->nativeFileDialog.get(), SIGNAL(reject()), this, SIGNAL(reject()));
+ }
++
++ d->loop.connect(this, SIGNAL(accept()), SLOT(quit()));
++ d->loop.connect(this, SIGNAL(reject()), SLOT(quit()));
+ }
+
+ QXdgDesktopPortalFileDialog::~QXdgDesktopPortalFileDialog()
+@@ -177,7 +182,7 @@ void QXdgDesktopPortalFileDialog::initializeDialog()
+ setDirectory(options()->initialDirectory());
+ }
+
+-void QXdgDesktopPortalFileDialog::openPortal()
++void QXdgDesktopPortalFileDialog::openPortal(Qt::WindowFlags windowFlags, Qt::WindowModality windowModality, QWindow *parent)
+ {
+ Q_D(QXdgDesktopPortalFileDialog);
+
+@@ -185,13 +190,13 @@ void QXdgDesktopPortalFileDialog::openPortal()
+ QLatin1String("/org/freedesktop/portal/desktop"),
+ QLatin1String("org.freedesktop.portal.FileChooser"),
+ d->saveFile ? QLatin1String("SaveFile") : QLatin1String("OpenFile"));
+- QString parentWindowId = QLatin1String("x11:") + QString::number(d->winId, 16);
++ QString parentWindowId = QLatin1String("x11:") + QString::number(parent ? parent->winId() : 0, 16);
+
+ QVariantMap options;
+ if (!d->acceptLabel.isEmpty())
+ options.insert(QLatin1String("accept_label"), d->acceptLabel);
+
+- options.insert(QLatin1String("modal"), d->modal);
++ options.insert(QLatin1String("modal"), windowModality != Qt::NonModal);
+ options.insert(QLatin1String("multiple"), d->multipleFiles);
+ options.insert(QLatin1String("directory"), d->directoryMode);
+
+@@ -290,10 +295,18 @@ void QXdgDesktopPortalFileDialog::openPortal()
+
+ QDBusPendingCall pendingCall = QDBusConnection::sessionBus().asyncCall(message);
+ QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(pendingCall);
+- connect(watcher, &QDBusPendingCallWatcher::finished, this, [this] (QDBusPendingCallWatcher *watcher) {
++ connect(watcher, &QDBusPendingCallWatcher::finished, this, [=] (QDBusPendingCallWatcher *watcher) {
+ QDBusPendingReply<QDBusObjectPath> reply = *watcher;
+- if (reply.isError()) {
+- Q_EMIT reject();
++ // Any error means the dialog is not shown and we need to fallback
++ d->failedToOpen = reply.isError();
++ if (d->failedToOpen) {
++ if (d->nativeFileDialog) {
++ d->nativeFileDialog->show(windowFlags, windowModality, parent);
++ if (d->loop.isRunning())
++ d->nativeFileDialog->exec();
++ } else {
++ Q_EMIT reject();
++ }
+ } else {
+ QDBusConnection::sessionBus().connect(nullptr,
+ reply.value().path(),
+@@ -302,6 +315,7 @@ void QXdgDesktopPortalFileDialog::openPortal()
+ this,
+ SLOT(gotResponse(uint,QVariantMap)));
+ }
++ watcher->deleteLater();
+ });
+ }
+
+@@ -326,7 +340,7 @@ QUrl QXdgDesktopPortalFileDialog::directory() const
+ {
+ Q_D(const QXdgDesktopPortalFileDialog);
+
+- if (d->nativeFileDialog && (options()->fileMode() == QFileDialogOptions::Directory || options()->fileMode() == QFileDialogOptions::DirectoryOnly))
++ if (d->nativeFileDialog && useNativeFileDialog())
+ return d->nativeFileDialog->directory();
+
+ return d->directory;
+@@ -348,7 +362,7 @@ QList<QUrl> QXdgDesktopPortalFileDialog::selectedFiles() const
+ {
+ Q_D(const QXdgDesktopPortalFileDialog);
+
+- if (d->nativeFileDialog && (options()->fileMode() == QFileDialogOptions::Directory || options()->fileMode() == QFileDialogOptions::DirectoryOnly))
++ if (d->nativeFileDialog && useNativeFileDialog())
+ return d->nativeFileDialog->selectedFiles();
+
+ QList<QUrl> files;
+@@ -403,16 +417,13 @@ void QXdgDesktopPortalFileDialog::exec()
+ {
+ Q_D(QXdgDesktopPortalFileDialog);
+
+- if (d->nativeFileDialog && (options()->fileMode() == QFileDialogOptions::Directory || options()->fileMode() == QFileDialogOptions::DirectoryOnly)) {
++ if (d->nativeFileDialog && useNativeFileDialog()) {
+ d->nativeFileDialog->exec();
+ return;
+ }
+
+ // HACK we have to avoid returning until we emit that the dialog was accepted or rejected
+- QEventLoop loop;
+- loop.connect(this, SIGNAL(accept()), SLOT(quit()));
+- loop.connect(this, SIGNAL(reject()), SLOT(quit()));
+- loop.exec();
++ d->loop.exec();
+ }
+
+ void QXdgDesktopPortalFileDialog::hide()
+@@ -429,13 +440,10 @@ bool QXdgDesktopPortalFileDialog::show(Qt::WindowFlags windowFlags, Qt::WindowMo
+
+ initializeDialog();
+
+- d->modal = windowModality != Qt::NonModal;
+- d->winId = parent ? parent->winId() : 0;
+-
+- if (d->nativeFileDialog && (options()->fileMode() == QFileDialogOptions::Directory || options()->fileMode() == QFileDialogOptions::DirectoryOnly))
++ if (d->nativeFileDialog && useNativeFileDialog(OpenFallback))
+ return d->nativeFileDialog->show(windowFlags, windowModality, parent);
+
+- openPortal();
++ openPortal(windowFlags, windowModality, parent);
+
+ return true;
+ }
+@@ -465,4 +473,21 @@ void QXdgDesktopPortalFileDialog::gotResponse(uint response, const QVariantMap &
+ }
+ }
+
++bool QXdgDesktopPortalFileDialog::useNativeFileDialog(QXdgDesktopPortalFileDialog::FallbackType fallbackType) const
++{
++ Q_D(const QXdgDesktopPortalFileDialog);
++
++ if (d->failedToOpen && fallbackType != OpenFallback)
++ return true;
++
++ if (d->fileChooserPortalVersion < 3) {
++ if (options()->fileMode() == QFileDialogOptions::Directory)
++ return true;
++ else if (options()->fileMode() == QFileDialogOptions::DirectoryOnly)
++ return true;
++ }
++
++ return false;
++}
++
+ QT_END_NAMESPACE
+diff --git a/qtbase/src/plugins/platformthemes/xdgdesktopportal/qxdgdesktopportalfiledialog_p.h b/qtbase/src/plugins/platformthemes/xdgdesktopportal/qxdgdesktopportalfiledialog_p.h
+index 4f4de96ecf..65e22a5cf2 100644
+--- a/qtbase/src/plugins/platformthemes/xdgdesktopportal/qxdgdesktopportalfiledialog_p.h
++++ b/qtbase/src/plugins/platformthemes/xdgdesktopportal/qxdgdesktopportalfiledialog_p.h
+@@ -51,6 +51,11 @@ class QXdgDesktopPortalFileDialog : public QPlatformFileDialogHelper
+ Q_OBJECT
+ Q_DECLARE_PRIVATE(QXdgDesktopPortalFileDialog)
+ public:
++ enum FallbackType {
++ GenericFallback,
++ OpenFallback
++ };
++
+ enum ConditionType : uint {
+ GlobalPattern = 0,
+ MimeType = 1
+@@ -69,7 +74,7 @@ public:
+ };
+ typedef QVector<Filter> FilterList;
+
+- QXdgDesktopPortalFileDialog(QPlatformFileDialogHelper *nativeFileDialog = nullptr);
++ QXdgDesktopPortalFileDialog(QPlatformFileDialogHelper *nativeFileDialog = nullptr, uint fileChooserPortalVersion = 0);
+ ~QXdgDesktopPortalFileDialog();
+
+ bool defaultNameFilterDisables() const override;
+@@ -92,7 +97,8 @@ private Q_SLOTS:
+
+ private:
+ void initializeDialog();
+- void openPortal();
++ void openPortal(Qt::WindowFlags windowFlags, Qt::WindowModality windowModality, QWindow *parent);
++ bool useNativeFileDialog(FallbackType fallbackType = GenericFallback) const;
+
+ QScopedPointer<QXdgDesktopPortalFileDialogPrivate> d_ptr;
+ };
+diff --git a/qtbase/src/plugins/platformthemes/xdgdesktopportal/qxdgdesktopportaltheme.cpp b/qtbase/src/plugins/platformthemes/xdgdesktopportal/qxdgdesktopportaltheme.cpp
+index fb324afbd8..b809503122 100644
+--- a/qtbase/src/plugins/platformthemes/xdgdesktopportal/qxdgdesktopportaltheme.cpp
++++ b/qtbase/src/plugins/platformthemes/xdgdesktopportal/qxdgdesktopportaltheme.cpp
+@@ -111,6 +111,7 @@ QXdgDesktopPortalTheme::QXdgDesktopPortalTheme()
+ if (reply.isValid()) {
+ d->fileChooserPortalVersion = reply.value().toUInt();
+ }
++ watcher->deleteLater();
+ });
+ }
+
+@@ -152,11 +153,12 @@ QPlatformDialogHelper* QXdgDesktopPortalTheme::createPlatformDialogHelper(Dialog
+ {
+ Q_D(const QXdgDesktopPortalTheme);
+
+- if (type == FileDialog) {
++ if (type == FileDialog && d->fileChooserPortalVersion) {
+ // Older versions of FileChooser portal don't support opening directories, therefore we fallback
+ // to native file dialog opened inside the sandbox to open a directory.
+- if (d->fileChooserPortalVersion < 3 && d->baseTheme->usePlatformNativeDialog(type))
+- return new QXdgDesktopPortalFileDialog(static_cast<QPlatformFileDialogHelper*>(d->baseTheme->createPlatformDialogHelper(type)));
++ if (d->baseTheme->usePlatformNativeDialog(type))
++ return new QXdgDesktopPortalFileDialog(static_cast<QPlatformFileDialogHelper*>(d->baseTheme->createPlatformDialogHelper(type)),
++ d->fileChooserPortalVersion);
+
+ return new QXdgDesktopPortalFileDialog;
+ }
+diff --git a/qtbase/src/plugins/printsupport/cups/qcupsprintengine.cpp b/qtbase/src/plugins/printsupport/cups/qcupsprintengine.cpp
+index 43d5e119ad..1f9cbc4565 100644
+--- a/qtbase/src/plugins/printsupport/cups/qcupsprintengine.cpp
++++ b/qtbase/src/plugins/printsupport/cups/qcupsprintengine.cpp
+@@ -89,8 +89,10 @@ void QCupsPrintEngine::setProperty(PrintEnginePropertyKey key, const QVariant &v
+ break;
+ case PPK_Duplex: {
+ QPrint::DuplexMode mode = QPrint::DuplexMode(value.toInt());
+- if (mode != d->duplex && d->m_printDevice.supportedDuplexModes().contains(mode))
++ if (d->m_printDevice.supportedDuplexModes().contains(mode)) {
+ d->duplex = mode;
++ d->duplexRequestedExplicitly = true;
++ }
+ break;
+ }
+ case PPK_PrinterName:
+@@ -277,9 +279,12 @@ void QCupsPrintEnginePrivate::changePrinter(const QString &newPrinter)
+ m_printDevice.swap(printDevice);
+ printerName = m_printDevice.id();
+
+- // Check if new printer supports current settings, otherwise us defaults
+- if (duplex != QPrint::DuplexAuto && !m_printDevice.supportedDuplexModes().contains(duplex))
++ // in case a duplex value was explicitly set, check if new printer supports current value,
++ // otherwise use device default
++ if (!duplexRequestedExplicitly || !m_printDevice.supportedDuplexModes().contains(duplex)) {
+ duplex = m_printDevice.defaultDuplexMode();
++ duplexRequestedExplicitly = false;
++ }
+ QPrint::ColorMode colorMode = grayscale ? QPrint::GrayScale : QPrint::Color;
+ if (!m_printDevice.supportedColorModes().contains(colorMode))
+ grayscale = m_printDevice.defaultColorMode() == QPrint::GrayScale;
+diff --git a/qtbase/src/plugins/printsupport/cups/qcupsprintengine_p.h b/qtbase/src/plugins/printsupport/cups/qcupsprintengine_p.h
+index c021b0c643..8f81fe478d 100644
+--- a/qtbase/src/plugins/printsupport/cups/qcupsprintengine_p.h
++++ b/qtbase/src/plugins/printsupport/cups/qcupsprintengine_p.h
+@@ -100,6 +100,7 @@ private:
+ QStringList cupsOptions;
+ QString cupsTempFile;
+ QPrint::DuplexMode duplex;
++ bool duplexRequestedExplicitly = false;
+ };
+
+ QT_END_NAMESPACE
+diff --git a/qtbase/src/plugins/sqldrivers/ibase/qsql_ibase.cpp b/qtbase/src/plugins/sqldrivers/ibase/qsql_ibase.cpp
+index 67e7154fa6..40876152e5 100644
+--- a/qtbase/src/plugins/sqldrivers/ibase/qsql_ibase.cpp
++++ b/qtbase/src/plugins/sqldrivers/ibase/qsql_ibase.cpp
+@@ -817,7 +817,7 @@ bool QIBaseResultPrivate::writeArray(int column, const QList<QVariant> &list)
+ ba.resize(int(bufLen));
+
+ if (list.size() > arraySize) {
+- error = QLatin1String("Array size missmatch: size of %1 is %2, size of provided list is %3");
++ error = QLatin1String("Array size mismatch: size of %1 is %2, size of provided list is %3");
+ error = error.arg(QLatin1String(sqlname)).arg(arraySize).arg(list.size());
+ q->setLastError(QSqlError(error, QLatin1String(""), QSqlError::StatementError));
+ return false;
+diff --git a/qtbase/src/plugins/sqldrivers/mysql/qsql_mysql.cpp b/qtbase/src/plugins/sqldrivers/mysql/qsql_mysql.cpp
+index 7ca055eea2..6bc9d46755 100644
+--- a/qtbase/src/plugins/sqldrivers/mysql/qsql_mysql.cpp
++++ b/qtbase/src/plugins/sqldrivers/mysql/qsql_mysql.cpp
+@@ -223,7 +223,7 @@ public:
+ struct QMyField
+ {
+ char *outField = nullptr;
+- MYSQL_FIELD *myField = nullptr;
++ const MYSQL_FIELD *myField = nullptr;
+ QMetaType::Type type = QMetaType::UnknownType;
+ my_bool nullIndicator = false;
+ ulong bufLength = 0ul;
+@@ -361,7 +361,7 @@ static bool qIsInteger(int t)
+ void QMYSQLResultPrivate::bindBlobs()
+ {
+ int i;
+- MYSQL_FIELD *fieldInfo;
++ const MYSQL_FIELD *fieldInfo;
+ MYSQL_BIND *bind;
+
+ for(i = 0; i < fields.count(); ++i) {
+@@ -379,7 +379,6 @@ void QMYSQLResultPrivate::bindBlobs()
+ bool QMYSQLResultPrivate::bindInValues()
+ {
+ MYSQL_BIND *bind;
+- char *field;
+ int i = 0;
+
+ if (!meta)
+@@ -392,35 +391,34 @@ bool QMYSQLResultPrivate::bindInValues()
+ inBinds = new MYSQL_BIND[fields.size()];
+ memset(inBinds, 0, fields.size() * sizeof(MYSQL_BIND));
+
+- MYSQL_FIELD *fieldInfo;
++ const MYSQL_FIELD *fieldInfo;
+
+ while((fieldInfo = mysql_fetch_field(meta))) {
++ bind = &inBinds[i];
++
+ QMyField &f = fields[i];
+ f.myField = fieldInfo;
+-
++ bind->buffer_length = f.bufLength = fieldInfo->length + 1;
++ bind->buffer_type = fieldInfo->type;
+ f.type = qDecodeMYSQLType(fieldInfo->type, fieldInfo->flags);
+ if (qIsBlob(fieldInfo->type)) {
+ // the size of a blob-field is available as soon as we call
+ // mysql_stmt_store_result()
+ // after mysql_stmt_exec() in QMYSQLResult::exec()
+- fieldInfo->length = 0;
++ bind->buffer_length = f.bufLength = 0;
+ hasBlobs = true;
+ } else if (qIsInteger(f.type)) {
+- fieldInfo->length = 8;
++ bind->buffer_length = f.bufLength = 8;
+ } else {
+- fieldInfo->type = MYSQL_TYPE_STRING;
++ bind->buffer_type = MYSQL_TYPE_STRING;
+ }
+- bind = &inBinds[i];
+- field = new char[fieldInfo->length + 1];
+- memset(field, 0, fieldInfo->length + 1);
+
+- bind->buffer_type = fieldInfo->type;
+- bind->buffer = field;
+- bind->buffer_length = f.bufLength = fieldInfo->length + 1;
+ bind->is_null = &f.nullIndicator;
+ bind->length = &f.bufLength;
+ bind->is_unsigned = fieldInfo->flags & UNSIGNED_FLAG ? 1 : 0;
+- f.outField=field;
++
++ char *field = new char[bind->buffer_length + 1]{};
++ bind->buffer = f.outField = field;
+
+ ++i;
+ }
+@@ -1369,20 +1367,20 @@ bool QMYSQLDriver::open(const QString& db,
+ }
+
+ #if MYSQL_VERSION_ID >= 50007
+- if (mysql_get_client_version() >= 50503 && mysql_get_server_version(d->mysql) >= 50503) {
+- // force the communication to be utf8mb4 (only utf8mb4 supports 4-byte characters)
+- mysql_set_character_set(d->mysql, "utf8mb4");
++ // force the communication to be utf8mb4 (only utf8mb4 supports 4-byte characters)
++ if (mysql_set_character_set(d->mysql, "utf8mb4")) {
++ // this failed, try forcing it to utf (BMP only)
++ if (mysql_set_character_set(d->mysql, "utf8"))
++ qWarning() << "MySQL: Unable to set the client character set to utf8.";
+ #if QT_CONFIG(textcodec)
+- d->tc = QTextCodec::codecForName("UTF-8");
++ else
++ d->tc = codec(d->mysql);
+ #endif
+- } else
+- {
+- // force the communication to be utf8
+- mysql_set_character_set(d->mysql, "utf8");
++ }
+ #if QT_CONFIG(textcodec)
+- d->tc = codec(d->mysql);
++ else
++ d->tc = QTextCodec::codecForName("UTF-8");
+ #endif
+- }
+ #endif // MYSQL_VERSION_ID >= 50007
+
+ d->preparedQuerysEnabled = checkPreparedQueries(d->mysql);
+diff --git a/qtbase/src/printsupport/dialogs/images/print-24.png b/qtbase/src/printsupport/dialogs/images/printer-24.png
+similarity index 100%
+rename from src/printsupport/dialogs/images/print-24.png
+rename to src/printsupport/dialogs/images/printer-24.png
+diff --git a/qtbase/src/printsupport/dialogs/images/print-32.png b/qtbase/src/printsupport/dialogs/images/printer-32.png
+similarity index 100%
+rename from src/printsupport/dialogs/images/print-32.png
+rename to src/printsupport/dialogs/images/printer-32.png
+diff --git a/qtbase/src/printsupport/dialogs/images/view-page-sided-24.png b/qtbase/src/printsupport/dialogs/images/view-pages-facing-24.png
+similarity index 100%
+rename from src/printsupport/dialogs/images/view-page-sided-24.png
+rename to src/printsupport/dialogs/images/view-pages-facing-24.png
+diff --git a/qtbase/src/printsupport/dialogs/images/view-page-sided-32.png b/qtbase/src/printsupport/dialogs/images/view-pages-facing-32.png
+similarity index 100%
+rename from src/printsupport/dialogs/images/view-page-sided-32.png
+rename to src/printsupport/dialogs/images/view-pages-facing-32.png
+diff --git a/qtbase/src/printsupport/dialogs/images/view-page-multi-24.png b/qtbase/src/printsupport/dialogs/images/view-pages-overview-24.png
+similarity index 100%
+rename from src/printsupport/dialogs/images/view-page-multi-24.png
+rename to src/printsupport/dialogs/images/view-pages-overview-24.png
+diff --git a/qtbase/src/printsupport/dialogs/images/view-page-multi-32.png b/qtbase/src/printsupport/dialogs/images/view-pages-overview-32.png
+similarity index 100%
+rename from src/printsupport/dialogs/images/view-page-multi-32.png
+rename to src/printsupport/dialogs/images/view-pages-overview-32.png
+diff --git a/qtbase/src/printsupport/dialogs/images/view-page-one-24.png b/qtbase/src/printsupport/dialogs/images/view-pages-single-24.png
+similarity index 100%
+rename from src/printsupport/dialogs/images/view-page-one-24.png
+rename to src/printsupport/dialogs/images/view-pages-single-24.png
+diff --git a/qtbase/src/printsupport/dialogs/images/view-page-one-32.png b/qtbase/src/printsupport/dialogs/images/view-pages-single-32.png
+similarity index 100%
+rename from src/printsupport/dialogs/images/view-page-one-32.png
+rename to src/printsupport/dialogs/images/view-pages-single-32.png
+diff --git a/qtbase/src/printsupport/dialogs/images/fit-page-24.png b/qtbase/src/printsupport/dialogs/images/zoom-fit-page-24.png
+similarity index 100%
+rename from src/printsupport/dialogs/images/fit-page-24.png
+rename to src/printsupport/dialogs/images/zoom-fit-page-24.png
+diff --git a/qtbase/src/printsupport/dialogs/images/fit-page-32.png b/qtbase/src/printsupport/dialogs/images/zoom-fit-page-32.png
+similarity index 100%
+rename from src/printsupport/dialogs/images/fit-page-32.png
+rename to src/printsupport/dialogs/images/zoom-fit-page-32.png
+diff --git a/qtbase/src/printsupport/dialogs/images/fit-width-24.png b/qtbase/src/printsupport/dialogs/images/zoom-fit-width-24.png
+similarity index 100%
+rename from src/printsupport/dialogs/images/fit-width-24.png
+rename to src/printsupport/dialogs/images/zoom-fit-width-24.png
+diff --git a/qtbase/src/printsupport/dialogs/images/fit-width-32.png b/qtbase/src/printsupport/dialogs/images/zoom-fit-width-32.png
+similarity index 100%
+rename from src/printsupport/dialogs/images/fit-width-32.png
+rename to src/printsupport/dialogs/images/zoom-fit-width-32.png
+diff --git a/qtbase/src/printsupport/dialogs/qpagesetupdialog_unix.cpp b/qtbase/src/printsupport/dialogs/qpagesetupdialog_unix.cpp
+index 78e5b8d1ef..2a28516719 100644
+--- a/qtbase/src/printsupport/dialogs/qpagesetupdialog_unix.cpp
++++ b/qtbase/src/printsupport/dialogs/qpagesetupdialog_unix.cpp
+@@ -532,6 +532,7 @@ void QPageSetupWidget::updateWidget()
+ void QPageSetupWidget::setupPrinter() const
+ {
+ m_printer->setPageLayout(m_pageLayout);
++ m_printer->setPageOrientation(m_pageLayout.orientation());
+ #if QT_CONFIG(cups)
+ QCUPSSupport::PagesPerSheet pagesPerSheet = qvariant_cast<QCUPSSupport::PagesPerSheet>(m_ui.pagesPerSheetCombo->currentData()
+ );
+diff --git a/qtbase/src/printsupport/dialogs/qprintdialog.qrc b/qtbase/src/printsupport/dialogs/qprintdialog.qrc
+index 5a579baa55..10b8e1d341 100644
+--- a/qtbase/src/printsupport/dialogs/qprintdialog.qrc
++++ b/qtbase/src/printsupport/dialogs/qprintdialog.qrc
+@@ -1,9 +1,9 @@
+ <!DOCTYPE RCC><RCC version="1.0">
+ <qresource prefix="/qt-project.org/dialogs/qprintpreviewdialog">
+-<file>images/fit-page-24.png</file>
+-<file>images/fit-page-32.png</file>
+-<file>images/fit-width-24.png</file>
+-<file>images/fit-width-32.png</file>
++<file>images/zoom-fit-page-24.png</file>
++<file>images/zoom-fit-page-32.png</file>
++<file>images/zoom-fit-width-24.png</file>
++<file>images/zoom-fit-width-32.png</file>
+ <file>images/go-first-24.png</file>
+ <file>images/go-first-32.png</file>
+ <file>images/go-last-24.png</file>
+@@ -18,14 +18,14 @@
+ <file>images/layout-portrait-32.png</file>
+ <file>images/page-setup-24.png</file>
+ <file>images/page-setup-32.png</file>
+-<file>images/print-24.png</file>
+-<file>images/print-32.png</file>
+-<file>images/view-page-multi-24.png</file>
+-<file>images/view-page-multi-32.png</file>
+-<file>images/view-page-one-24.png</file>
+-<file>images/view-page-one-32.png</file>
+-<file>images/view-page-sided-24.png</file>
+-<file>images/view-page-sided-32.png</file>
++<file>images/printer-24.png</file>
++<file>images/printer-32.png</file>
++<file>images/view-pages-overview-24.png</file>
++<file>images/view-pages-overview-32.png</file>
++<file>images/view-pages-single-24.png</file>
++<file>images/view-pages-single-32.png</file>
++<file>images/view-pages-facing-24.png</file>
++<file>images/view-pages-facing-32.png</file>
+ <file>images/zoom-in-24.png</file>
+ <file>images/zoom-in-32.png</file>
+ <file>images/zoom-out-24.png</file>
+diff --git a/qtbase/src/printsupport/dialogs/qprintdialog_unix.cpp b/qtbase/src/printsupport/dialogs/qprintdialog_unix.cpp
+index c5b845f4ec..5a5ba1d0a8 100644
+--- a/qtbase/src/printsupport/dialogs/qprintdialog_unix.cpp
++++ b/qtbase/src/printsupport/dialogs/qprintdialog_unix.cpp
+@@ -702,13 +702,14 @@ void QPrintDialogPrivate::selectPrinter(const QPrinter::OutputFormat outputForma
+ else
+ options.grayscale->setChecked(true);
+
+- // keep duplex value explicitly set by user, if any, and selected printer supports it;
+- // use device default otherwise
++ // duplex priorities to be as follows:
++ // 1) a user-selected duplex value in the dialog has highest prority
++ // 2) duplex value set in the QPrinter
+ QPrint::DuplexMode duplex;
+ if (explicitDuplexMode != QPrint::DuplexAuto && supportedDuplexMode.contains(explicitDuplexMode))
+ duplex = explicitDuplexMode;
+ else
+- duplex = top->d->m_currentPrintDevice.defaultDuplexMode();
++ duplex = static_cast<QPrint::DuplexMode>(p->duplex());
+ switch (duplex) {
+ case QPrint::DuplexNone:
+ options.noDuplex->setChecked(true); break;
+@@ -1242,10 +1243,10 @@ void QUnixPrintWidgetPrivate::_q_printerChanged(int index)
+ QString filename = widget.filename->text();
+ widget.filename->setText(filename);
+ widget.lOutput->setEnabled(true);
+- if (optionsPane)
+- optionsPane->selectPrinter(QPrinter::PdfFormat);
+ printer->setOutputFormat(QPrinter::PdfFormat);
+ m_currentPrintDevice = QPrintDevice();
++ if (optionsPane)
++ optionsPane->selectPrinter(QPrinter::PdfFormat);
+ return;
+ }
+ }
+diff --git a/qtbase/src/printsupport/dialogs/qprintpreviewdialog.cpp b/qtbase/src/printsupport/dialogs/qprintpreviewdialog.cpp
+index 39575d5f57..23b7e89538 100644
+--- a/qtbase/src/printsupport/dialogs/qprintpreviewdialog.cpp
++++ b/qtbase/src/printsupport/dialogs/qprintpreviewdialog.cpp
+@@ -352,7 +352,7 @@ void QPrintPreviewDialogPrivate::init(QPrinter *_printer)
+ static inline void qt_setupActionIcon(QAction *action, QLatin1String name)
+ {
+ QLatin1String imagePrefix(":/qt-project.org/dialogs/qprintpreviewdialog/images/");
+- QIcon icon;
++ QIcon icon = QIcon::fromTheme(name);
+ icon.addFile(imagePrefix + name + QLatin1String("-24.png"), QSize(24, 24));
+ icon.addFile(imagePrefix + name + QLatin1String("-32.png"), QSize(32, 32));
+ action->setIcon(icon);
+@@ -383,8 +383,8 @@ void QPrintPreviewDialogPrivate::setupActions()
+ fitPageAction->setObjectName(QLatin1String("fitPageAction"));
+ fitWidthAction->setCheckable(true);
+ fitPageAction->setCheckable(true);
+- qt_setupActionIcon(fitWidthAction, QLatin1String("fit-width"));
+- qt_setupActionIcon(fitPageAction, QLatin1String("fit-page"));
++ qt_setupActionIcon(fitWidthAction, QLatin1String("zoom-fit-width"));
++ qt_setupActionIcon(fitPageAction, QLatin1String("zoom-fit-page"));
+ QObject::connect(fitGroup, SIGNAL(triggered(QAction*)), q, SLOT(_q_fit(QAction*)));
+
+ // Zoom
+@@ -410,9 +410,9 @@ void QPrintPreviewDialogPrivate::setupActions()
+ singleModeAction = modeGroup->addAction(QCoreApplication::translate("QPrintPreviewDialog", "Show single page"));
+ facingModeAction = modeGroup->addAction(QCoreApplication::translate("QPrintPreviewDialog", "Show facing pages"));
+ overviewModeAction = modeGroup->addAction(QCoreApplication::translate("QPrintPreviewDialog", "Show overview of all pages"));
+- qt_setupActionIcon(singleModeAction, QLatin1String("view-page-one"));
+- qt_setupActionIcon(facingModeAction, QLatin1String("view-page-sided"));
+- qt_setupActionIcon(overviewModeAction, QLatin1String("view-page-multi"));
++ qt_setupActionIcon(singleModeAction, QLatin1String("view-pages-single"));
++ qt_setupActionIcon(facingModeAction, QLatin1String("view-pages-facing"));
++ qt_setupActionIcon(overviewModeAction, QLatin1String("view-pages-overview"));
+ singleModeAction->setObjectName(QLatin1String("singleModeAction"));
+ facingModeAction->setObjectName(QLatin1String("facingModeAction"));
+ overviewModeAction->setObjectName(QLatin1String("overviewModeAction"));
+@@ -426,7 +426,7 @@ void QPrintPreviewDialogPrivate::setupActions()
+ printerGroup = new QActionGroup(q);
+ printAction = printerGroup->addAction(QCoreApplication::translate("QPrintPreviewDialog", "Print"));
+ pageSetupAction = printerGroup->addAction(QCoreApplication::translate("QPrintPreviewDialog", "Page setup"));
+- qt_setupActionIcon(printAction, QLatin1String("print"));
++ qt_setupActionIcon(printAction, QLatin1String("printer"));
+ qt_setupActionIcon(pageSetupAction, QLatin1String("page-setup"));
+ QObject::connect(printAction, SIGNAL(triggered(bool)), q, SLOT(_q_print()));
+ QObject::connect(pageSetupAction, SIGNAL(triggered(bool)), q, SLOT(_q_pageSetup()));
+diff --git a/qtbase/src/sql/kernel/qsqlquery.cpp b/qtbase/src/sql/kernel/qsqlquery.cpp
+index 32c6166c79..60afef10c3 100644
+--- a/qtbase/src/sql/kernel/qsqlquery.cpp
++++ b/qtbase/src/sql/kernel/qsqlquery.cpp
+@@ -1,6 +1,6 @@
+ /****************************************************************************
+ **
+-** Copyright (C) 2016 The Qt Company Ltd.
++** Copyright (C) 2022 The Qt Company Ltd.
+ ** Contact: https://www.qt.io/licensing/
+ **
+ ** This file is part of the QtSql module of the Qt Toolkit.
+@@ -377,6 +377,10 @@ bool QSqlQuery::exec(const QString& query)
+ QElapsedTimer t;
+ t.start();
+ #endif
++ if (!driver()) {
++ qWarning("QSqlQuery::exec: called before driver has been set up");
++ return false;
++ }
+ if (d->ref.loadRelaxed() != 1) {
+ bool fo = isForwardOnly();
+ *this = QSqlQuery(driver()->createResult());
+diff --git a/qtbase/src/testlib/qabstractitemmodeltester.cpp b/qtbase/src/testlib/qabstractitemmodeltester.cpp
+index 8efb9c53d4..ce062f66d7 100644
+--- a/qtbase/src/testlib/qabstractitemmodeltester.cpp
++++ b/qtbase/src/testlib/qabstractitemmodeltester.cpp
+@@ -454,7 +454,7 @@ void QAbstractItemModelTesterPrivate::parent()
+
+ // Common error test #2, make sure that a second level index has a parent
+ // that is the first level index.
+- if (model->rowCount(topIndex) > 0) {
++ if (model->rowCount(topIndex) > 0 && model->columnCount(topIndex) > 0) {
+ QModelIndex childIndex = model->index(0, 0, topIndex);
+ MODELTESTER_VERIFY(childIndex.isValid());
+ MODELTESTER_COMPARE(model->parent(childIndex), topIndex);
+diff --git a/qtbase/src/testlib/qasciikey.cpp b/qtbase/src/testlib/qasciikey.cpp
+index 9a308da2bc..93498b256f 100644
+--- a/qtbase/src/testlib/qasciikey.cpp
++++ b/qtbase/src/testlib/qasciikey.cpp
+@@ -498,6 +498,11 @@ char QTest::keyToAscii(Qt::Key key)
+ case Qt::Key_LaunchE : return 0; // = 0x10b0,
+ case Qt::Key_LaunchF : return 0; // = 0x10b1,
+
++ // Keypad navigation keys
++ case Qt::Key_Select : return 0; // = 0x01010000
++ case Qt::Key_Yes : return 0; // = 0x01010001
++ case Qt::Key_No : return 0; // = 0x01010002
++
+ default: QTEST_ASSERT(false); return 0;
+ }
+ }
+diff --git a/qtbase/src/testlib/qtestresult.cpp b/qtbase/src/testlib/qtestresult.cpp
+index 88028aac6e..2e89930776 100644
+--- a/qtbase/src/testlib/qtestresult.cpp
++++ b/qtbase/src/testlib/qtestresult.cpp
+@@ -251,7 +251,8 @@ bool QTestResult::verify(bool statement, const char *statementStr,
+ {
+ QTEST_ASSERT(statementStr);
+
+- char msg[1024] = {'\0'};
++ char msg[1024];
++ msg[0] = '\0';
+
+ if (QTestLog::verboseLevel() >= 2) {
+ qsnprintf(msg, 1024, "QVERIFY(%s)", statementStr);
+@@ -309,7 +310,8 @@ static bool compareHelper(bool success, const char *failureMsg,
+ bool hasValues = true)
+ {
+ const size_t maxMsgLen = 1024;
+- char msg[maxMsgLen] = {'\0'};
++ char msg[maxMsgLen];
++ msg[0] = '\0';
+
+ QTEST_ASSERT(expected);
+ QTEST_ASSERT(actual);
+diff --git a/qtbase/src/widgets/dialogs/qcolordialog.cpp b/qtbase/src/widgets/dialogs/qcolordialog.cpp
+index 4247731275..cb325be85c 100644
+--- a/qtbase/src/widgets/dialogs/qcolordialog.cpp
++++ b/qtbase/src/widgets/dialogs/qcolordialog.cpp
+@@ -78,7 +78,10 @@
+ #include "qwindow.h"
+
+ #include "private/qdialog_p.h"
++#include "private/qguiapplication_p.h"
+
++#include <qpa/qplatformservices.h>
++#include <qpa/qplatformintegration.h>
+ #include <algorithm>
+
+ QT_BEGIN_NAMESPACE
+@@ -1611,6 +1614,20 @@ void QColorDialogPrivate::_q_newStandard(int r, int c)
+ void QColorDialogPrivate::_q_pickScreenColor()
+ {
+ Q_Q(QColorDialog);
++
++ auto *platformServices = QGuiApplicationPrivate::platformIntegration()->services();
++ if (platformServices->hasCapability(QPlatformServices::Capability::ColorPicking)) {
++ if (auto *colorPicker = platformServices->colorPicker(q->windowHandle())) {
++ q->connect(colorPicker, &QPlatformServiceColorPicker::colorPicked, q,
++ [q, colorPicker](const QColor &color) {
++ colorPicker->deleteLater();
++ q->setCurrentColor(color);
++ });
++ colorPicker->pickColor();
++ return;
++ }
++ }
++
+ if (!colorPickingEventFilter)
+ colorPickingEventFilter = new QColorPickingEventFilter(this, q);
+ q->installEventFilter(colorPickingEventFilter);
+diff --git a/qtbase/src/widgets/itemviews/qabstractitemdelegate.cpp b/qtbase/src/widgets/itemviews/qabstractitemdelegate.cpp
+index e120817edc..8ea36b5427 100644
+--- a/qtbase/src/widgets/itemviews/qabstractitemdelegate.cpp
++++ b/qtbase/src/widgets/itemviews/qabstractitemdelegate.cpp
+@@ -400,12 +400,7 @@ bool QAbstractItemDelegate::helpEvent(QHelpEvent *event,
+ const QString tooltip = index.isValid() ?
+ d->textForRole(Qt::ToolTipRole, index.data(Qt::ToolTipRole), option.locale, precision) :
+ QString();
+- QRect rect;
+- if (index.isValid()) {
+- const QRect r = view->visualRect(index);
+- rect = QRect(view->mapToGlobal(r.topLeft()), r.size());
+- }
+- QToolTip::showText(he->globalPos(), tooltip, view, rect);
++ QToolTip::showText(he->globalPos(), tooltip, view->viewport(), option.rect);
+ event->setAccepted(!tooltip.isEmpty());
+ break;
+ }
+diff --git a/qtbase/src/widgets/itemviews/qlistview.cpp b/qtbase/src/widgets/itemviews/qlistview.cpp
+index 2b34476642..eebfaa030e 100644
+--- a/qtbase/src/widgets/itemviews/qlistview.cpp
++++ b/qtbase/src/widgets/itemviews/qlistview.cpp
+@@ -3386,6 +3386,7 @@ void QIconModeViewBase::updateContentsSize()
+ */
+ void QListView::currentChanged(const QModelIndex ¤t, const QModelIndex &previous)
+ {
++ QAbstractItemView::currentChanged(current, previous);
+ #ifndef QT_NO_ACCESSIBILITY
+ if (QAccessible::isActive()) {
+ if (current.isValid()) {
+@@ -3396,7 +3397,6 @@ void QListView::currentChanged(const QModelIndex ¤t, const QModelIndex &pr
+ }
+ }
+ #endif
+- QAbstractItemView::currentChanged(current, previous);
+ }
+
+ /*!
+diff --git a/qtbase/src/widgets/itemviews/qtableview.cpp b/qtbase/src/widgets/itemviews/qtableview.cpp
+index 934ac581b2..f79bb24249 100644
+--- a/qtbase/src/widgets/itemviews/qtableview.cpp
++++ b/qtbase/src/widgets/itemviews/qtableview.cpp
+@@ -1013,6 +1013,7 @@ void QTableViewPrivate::drawCell(QPainter *painter, const QStyleOptionViewItem &
+ int QTableViewPrivate::widthHintForIndex(const QModelIndex &index, int hint, const QStyleOptionViewItem &option) const
+ {
+ Q_Q(const QTableView);
++ const int oldHint = hint;
+ QWidget *editor = editorForIndex(index).widget.data();
+ if (editor && persistent.contains(editor)) {
+ hint = qMax(hint, editor->sizeHint().width());
+@@ -1021,6 +1022,17 @@ int QTableViewPrivate::widthHintForIndex(const QModelIndex &index, int hint, con
+ hint = qBound(min, hint, max);
+ }
+ hint = qMax(hint, q->itemDelegate(index)->sizeHint(option, index).width());
++
++ if (hasSpans()) {
++ auto span = spans.spanAt(index.column(), index.row());
++ if (span && span->m_left == index.column() && span->m_top == index.row()) {
++ // spans are screwed up when sections are moved
++ const auto left = logicalColumn(span->m_left);
++ for (int i = 1; i <= span->width(); ++i)
++ hint -= q->columnWidth(visualColumn(left + i));
++ }
++ hint = std::max(hint, oldHint);
++ }
+ return hint;
+ }
+
+@@ -1053,6 +1065,11 @@ int QTableViewPrivate::heightHintForIndex(const QModelIndex &index, int hint, QS
+ option.rect.setHeight(height);
+ option.rect.setX(q->columnViewportPosition(index.column()));
+ option.rect.setWidth(q->columnWidth(index.column()));
++ if (hasSpans()) {
++ auto span = spans.spanAt(index.column(), index.row());
++ if (span && span->m_left == index.column() && span->m_top == index.row())
++ option.rect.setWidth(std::max(option.rect.width(), visualSpanRect(*span).width()));
++ }
+ // 1px less space when grid is shown (see drawCell)
+ if (showGrid)
+ option.rect.setWidth(option.rect.width() - 1);
+diff --git a/qtbase/src/widgets/kernel/qaction.h b/qtbase/src/widgets/kernel/qaction.h
+index 258a1ea0a0..737c1e8285 100644
+--- a/qtbase/src/widgets/kernel/qaction.h
++++ b/qtbase/src/widgets/kernel/qaction.h
+@@ -81,7 +81,7 @@ class Q_WIDGETS_EXPORT QAction : public QObject
+ Q_PROPERTY(MenuRole menuRole READ menuRole WRITE setMenuRole NOTIFY changed)
+ Q_PROPERTY(bool iconVisibleInMenu READ isIconVisibleInMenu WRITE setIconVisibleInMenu NOTIFY changed)
+ Q_PROPERTY(bool shortcutVisibleInContextMenu READ isShortcutVisibleInContextMenu WRITE setShortcutVisibleInContextMenu NOTIFY changed)
+- Q_PROPERTY(Priority priority READ priority WRITE setPriority)
++ Q_PROPERTY(Priority priority READ priority WRITE setPriority NOTIFY changed)
+
+ public:
+ // note this is copied into qplatformmenu.h, which must stay in sync
+diff --git a/qtbase/src/widgets/kernel/qwidget.cpp b/qtbase/src/widgets/kernel/qwidget.cpp
+index 9eba1e001e..26f6d27e18 100644
+--- a/qtbase/src/widgets/kernel/qwidget.cpp
++++ b/qtbase/src/widgets/kernel/qwidget.cpp
+@@ -5296,7 +5296,7 @@ void QWidgetPrivate::drawWidget(QPaintDevice *pdev, const QRegion &rgn, const QP
+ QWidgetEffectSourcePrivate *sourced = static_cast<QWidgetEffectSourcePrivate *>
+ (source->d_func());
+ if (!sourced->context) {
+- const QRegion effectRgn(rgn.boundingRect());
++ const QRegion effectRgn((flags & UseEffectRegionBounds) ? rgn.boundingRect() : rgn);
+ QWidgetPaintContext context(pdev, effectRgn, offset, flags, sharedPainter, repaintManager);
+ sourced->context = &context;
+ if (!sharedPainter) {
+@@ -5328,6 +5328,7 @@ void QWidgetPrivate::drawWidget(QPaintDevice *pdev, const QRegion &rgn, const QP
+ }
+ }
+ #endif // QT_CONFIG(graphicseffect)
++ flags = flags & ~UseEffectRegionBounds;
+
+ const bool alsoOnScreen = flags & DrawPaintOnScreen;
+ const bool recursive = flags & DrawRecursive;
+diff --git a/qtbase/src/widgets/kernel/qwidget_p.h b/qtbase/src/widgets/kernel/qwidget_p.h
+index eef6b8fa2c..c432f4b5d5 100644
+--- a/qtbase/src/widgets/kernel/qwidget_p.h
++++ b/qtbase/src/widgets/kernel/qwidget_p.h
+@@ -229,7 +229,8 @@ public:
+ DontSubtractOpaqueChildren = 0x10,
+ DontDrawOpaqueChildren = 0x20,
+ DontDrawNativeChildren = 0x40,
+- DontSetCompositionMode = 0x80
++ DontSetCompositionMode = 0x80,
++ UseEffectRegionBounds = 0x100
+ };
+ Q_DECLARE_FLAGS(DrawWidgetFlags, DrawWidgetFlag)
+ Q_FLAG(DrawWidgetFlags)
+diff --git a/qtbase/src/widgets/kernel/qwidgetrepaintmanager.cpp b/qtbase/src/widgets/kernel/qwidgetrepaintmanager.cpp
+index 02880b34da..0d44e1326d 100644
+--- a/qtbase/src/widgets/kernel/qwidgetrepaintmanager.cpp
++++ b/qtbase/src/widgets/kernel/qwidgetrepaintmanager.cpp
+@@ -1018,7 +1018,8 @@ void QWidgetRepaintManager::paintAndFlush()
+
+ // Paint the rest with composition.
+ if (repaintAllWidgets || !dirtyCopy.isEmpty()) {
+- QWidgetPrivate::DrawWidgetFlags flags = QWidgetPrivate::DrawAsRoot | QWidgetPrivate::DrawRecursive;
++ QWidgetPrivate::DrawWidgetFlags flags = QWidgetPrivate::DrawAsRoot | QWidgetPrivate::DrawRecursive
++ | QWidgetPrivate::UseEffectRegionBounds;
+ tlw->d_func()->drawWidget(store->paintDevice(), dirtyCopy, QPoint(), flags, nullptr, this);
+ }
+
+diff --git a/qtbase/src/widgets/styles/qfusionstyle.cpp b/qtbase/src/widgets/styles/qfusionstyle.cpp
+index f4345d97c4..962912c838 100644
+--- a/qtbase/src/widgets/styles/qfusionstyle.cpp
++++ b/qtbase/src/widgets/styles/qfusionstyle.cpp
+@@ -1772,14 +1772,6 @@ void QFusionStyle::drawControl(ControlElement element, const QStyleOption *optio
+ proxy()->drawControl(CE_PushButtonLabel, &subopt, painter, widget);
+ }
+ break;
+- case CE_PushButtonLabel:
+- if (const QStyleOptionButton *button = qstyleoption_cast<const QStyleOptionButton *>(option)) {
+- QStyleOptionButton b(*button);
+- // no PM_ButtonShiftHorizontal and PM_ButtonShiftVertical for fusion style
+- b.state &= ~(State_On | State_Sunken);
+- QCommonStyle::drawControl(element, &b, painter, widget);
+- }
+- break;
+ case CE_MenuBarEmptyArea:
+ painter->save();
+ {
+diff --git a/qtbase/src/widgets/util/qcompleter.cpp b/qtbase/src/widgets/util/qcompleter.cpp
+index 18b24063d8..ef7207a8a3 100644
+--- a/qtbase/src/widgets/util/qcompleter.cpp
++++ b/qtbase/src/widgets/util/qcompleter.cpp
+@@ -1120,6 +1120,8 @@ void QCompleter::setModel(QAbstractItemModel *model)
+ {
+ Q_D(QCompleter);
+ QAbstractItemModel *oldModel = d->proxy->sourceModel();
++ if (oldModel == model)
++ return;
+ #if QT_CONFIG(filesystemmodel)
+ if (qobject_cast<const QFileSystemModel *>(oldModel))
+ setCompletionRole(Qt::EditRole); // QTBUG-54642, clear FileNameRole set by QFileSystemModel
+diff --git a/qtbase/src/widgets/widgets/qabstractbutton.cpp b/qtbase/src/widgets/widgets/qabstractbutton.cpp
+index a128b23950..dc40bf62fb 100644
+--- a/qtbase/src/widgets/widgets/qabstractbutton.cpp
++++ b/qtbase/src/widgets/widgets/qabstractbutton.cpp
+@@ -56,6 +56,7 @@
+ #ifndef QT_NO_ACCESSIBILITY
+ #include "qaccessible.h"
+ #endif
++#include <qpa/qplatformtheme.h>
+
+ #include <algorithm>
+
+@@ -1076,19 +1077,19 @@ void QAbstractButton::keyPressEvent(QKeyEvent *e)
+ {
+ Q_D(QAbstractButton);
+ bool next = true;
+- switch (e->key()) {
+- case Qt::Key_Enter:
+- case Qt::Key_Return:
+- e->ignore();
+- break;
+- case Qt::Key_Select:
+- case Qt::Key_Space:
+- if (!e->isAutoRepeat()) {
+- setDown(true);
+- repaint();
+- d->emitPressed();
+- }
+- break;
++
++ const auto key = static_cast<Qt::Key>(e->key());
++ const auto buttonPressKeys = QGuiApplicationPrivate::platformTheme()
++ ->themeHint(QPlatformTheme::ButtonPressKeys)
++ .value<QList<Qt::Key>>();
++ if (buttonPressKeys.contains(key) && !e->isAutoRepeat()) {
++ setDown(true);
++ repaint();
++ d->emitPressed();
++ return;
++ }
++
++ switch (key) {
+ case Qt::Key_Up:
+ next = false;
+ Q_FALLTHROUGH();
+@@ -1153,15 +1154,15 @@ void QAbstractButton::keyReleaseEvent(QKeyEvent *e)
+ if (!e->isAutoRepeat())
+ d->repeatTimer.stop();
+
+- switch (e->key()) {
+- case Qt::Key_Select:
+- case Qt::Key_Space:
+- if (!e->isAutoRepeat() && d->down)
+- d->click();
+- break;
+- default:
+- e->ignore();
++ const auto buttonPressKeys = QGuiApplicationPrivate::platformTheme()
++ ->themeHint(QPlatformTheme::ButtonPressKeys)
++ .value<QList<Qt::Key>>();
++ if (buttonPressKeys.contains(static_cast<Qt::Key>(e->key())) && !e->isAutoRepeat() && d->down) {
++ d->click();
++ return;
+ }
++
++ e->ignore();
+ }
+
+ /*!\reimp
+diff --git a/qtbase/src/widgets/widgets/qcombobox.cpp b/qtbase/src/widgets/widgets/qcombobox.cpp
+index 7a496c27e0..0a3d96647b 100644
+--- a/qtbase/src/widgets/widgets/qcombobox.cpp
++++ b/qtbase/src/widgets/widgets/qcombobox.cpp
+@@ -3352,7 +3352,23 @@ void QComboBox::keyPressEvent(QKeyEvent *e)
+
+ Move move = NoMove;
+ int newIndex = currentIndex();
+- switch (e->key()) {
++
++ bool pressLikeButton = !d->lineEdit;
++#ifdef QT_KEYPAD_NAVIGATION
++ pressLikeButton |= QApplicationPrivate::keypadNavigationEnabled() && !hasEditFocus();
++#endif
++ auto key = static_cast<Qt::Key>(e->key());
++ if (pressLikeButton) {
++ const auto buttonPressKeys = QGuiApplicationPrivate::platformTheme()
++ ->themeHint(QPlatformTheme::ButtonPressKeys)
++ .value<QList<Qt::Key>>();
++ if (buttonPressKeys.contains(key)) {
++ showPopup();
++ return;
++ }
++ }
++
++ switch (key) {
+ case Qt::Key_Up:
+ if (e->modifiers() & Qt::ControlModifier)
+ break; // pass to line edit for auto completion
+@@ -3394,26 +3410,11 @@ void QComboBox::keyPressEvent(QKeyEvent *e)
+ return;
+ }
+ break;
+- case Qt::Key_Space:
+- if (!d->lineEdit) {
+- showPopup();
+- return;
+- }
+- break;
+- case Qt::Key_Enter:
+- case Qt::Key_Return:
+ case Qt::Key_Escape:
+ if (!d->lineEdit)
+ e->ignore();
+ break;
+ #ifdef QT_KEYPAD_NAVIGATION
+- case Qt::Key_Select:
+- if (QApplicationPrivate::keypadNavigationEnabled()
+- && (!hasEditFocus() || !d->lineEdit)) {
+- showPopup();
+- return;
+- }
+- break;
+ case Qt::Key_Left:
+ case Qt::Key_Right:
+ if (QApplicationPrivate::keypadNavigationEnabled() && !hasEditFocus())
+diff --git a/qtbase/src/widgets/widgets/qdatetimeedit_p.h b/qtbase/src/widgets/widgets/qdatetimeedit_p.h
+index d36b6f8f9a..e0df5b5158 100644
+--- a/qtbase/src/widgets/widgets/qdatetimeedit_p.h
++++ b/qtbase/src/widgets/widgets/qdatetimeedit_p.h
+@@ -1,6 +1,6 @@
+ /****************************************************************************
+ **
+-** Copyright (C) 2018 The Qt Company Ltd.
++** Copyright (C) 2021 The Qt Company Ltd.
+ ** Contact: https://www.qt.io/licensing/
+ **
+ ** This file is part of the QtWidgets module of the Qt Toolkit.
+diff --git a/qtbase/src/widgets/widgets/qgroupbox.cpp b/qtbase/src/widgets/widgets/qgroupbox.cpp
+index 02a0bed325..3f3eccc370 100644
+--- a/qtbase/src/widgets/widgets/qgroupbox.cpp
++++ b/qtbase/src/widgets/widgets/qgroupbox.cpp
+@@ -54,6 +54,8 @@
+ #include "qaccessible.h"
+ #endif
+ #include <private/qwidget_p.h>
++#include <private/qguiapplication_p.h>
++#include <qpa/qplatformtheme.h>
+
+ #include "qdebug.h"
+
+@@ -360,7 +362,10 @@ bool QGroupBox::event(QEvent *e)
+ return true;
+ case QEvent::KeyPress: {
+ QKeyEvent *k = static_cast<QKeyEvent*>(e);
+- if (!k->isAutoRepeat() && (k->key() == Qt::Key_Select || k->key() == Qt::Key_Space)) {
++ const auto buttonPressKeys = QGuiApplicationPrivate::platformTheme()
++ ->themeHint(QPlatformTheme::ButtonPressKeys)
++ .value<QList<Qt::Key>>();
++ if (!k->isAutoRepeat() && buttonPressKeys.contains(static_cast<Qt::Key>(k->key()))) {
+ d->pressedControl = QStyle::SC_GroupBoxCheckBox;
+ update(style()->subControlRect(QStyle::CC_GroupBox, &box, QStyle::SC_GroupBoxCheckBox, this));
+ return true;
+@@ -369,7 +374,10 @@ bool QGroupBox::event(QEvent *e)
+ }
+ case QEvent::KeyRelease: {
+ QKeyEvent *k = static_cast<QKeyEvent*>(e);
+- if (!k->isAutoRepeat() && (k->key() == Qt::Key_Select || k->key() == Qt::Key_Space)) {
++ const auto buttonPressKeys = QGuiApplicationPrivate::platformTheme()
++ ->themeHint(QPlatformTheme::ButtonPressKeys)
++ .value<QList<Qt::Key>>();
++ if (!k->isAutoRepeat() && buttonPressKeys.contains(static_cast<Qt::Key>(k->key()))) {
+ bool toggle = (d->pressedControl == QStyle::SC_GroupBoxLabel
+ || d->pressedControl == QStyle::SC_GroupBoxCheckBox);
+ d->pressedControl = QStyle::SC_None;
+diff --git a/qtbase/src/widgets/widgets/qlabel.cpp b/qtbase/src/widgets/widgets/qlabel.cpp
+index 30ff80cbb0..cf2605c17c 100644
+--- a/qtbase/src/widgets/widgets/qlabel.cpp
++++ b/qtbase/src/widgets/widgets/qlabel.cpp
+@@ -421,9 +421,6 @@ void QLabel::setPixmap(const QPixmap &pixmap)
+ d->pixmap = new QPixmap(pixmap);
+ }
+
+- if (d->pixmap->depth() == 1 && !d->pixmap->mask())
+- d->pixmap->setMask(*((QBitmap *)d->pixmap));
+-
+ d->updateLabel();
+ }
+
+diff --git a/qtbase/src/widgets/widgets/qtoolbararealayout.cpp b/qtbase/src/widgets/widgets/qtoolbararealayout.cpp
+index 493c094cc1..d5f4b59017 100644
+--- a/qtbase/src/widgets/widgets/qtoolbararealayout.cpp
++++ b/qtbase/src/widgets/widgets/qtoolbararealayout.cpp
+@@ -1367,7 +1367,7 @@ bool QToolBarAreaLayout::restoreState(QDataStream &stream, const QList<QToolBar*
+ item.widgetItem = new QWidgetItemV2(toolBar);
+ toolBar->setOrientation(floating ? ((shown & 2) ? Qt::Vertical : Qt::Horizontal) : dock.o);
+ toolBar->setVisible(shown & 1);
+- toolBar->d_func()->setWindowState(floating, true, rect);
++ toolBar->d_func()->setWindowState(floating, false, rect);
+
+ item.preferredSize = item.size;
+ line.toolBarItems.append(item);
+diff --git a/qtbase/tests/auto/concurrent/qtconcurrentiteratekernel/tst_qtconcurrentiteratekernel.cpp b/qtbase/tests/auto/concurrent/qtconcurrentiteratekernel/tst_qtconcurrentiteratekernel.cpp
+index 212c0a2e13..3c77b1ba0b 100644
+--- a/qtbase/tests/auto/concurrent/qtconcurrentiteratekernel/tst_qtconcurrentiteratekernel.cpp
++++ b/qtbase/tests/auto/concurrent/qtconcurrentiteratekernel/tst_qtconcurrentiteratekernel.cpp
+@@ -126,8 +126,7 @@ public:
+
+ void tst_QtConcurrentIterateKernel::instantiate()
+ {
+- auto future = startThreadEngine(new PrintFor(0, 40)).startAsynchronously();
+- future.waitForFinished();
++ startThreadEngine(new PrintFor(0, 40)).startBlocking();
+ QCOMPARE(iterations.loadRelaxed(), 40);
+ }
+
+@@ -166,10 +165,8 @@ void tst_QtConcurrentIterateKernel::stresstest()
+ const int times = 50;
+ for (int i = 0; i < times; ++i) {
+ counter.storeRelaxed(0);
+- // ThreadEngine will delete f when it finishes
+- auto f = new CountFor(0, iterations);
+- auto future = f->startAsynchronously();
+- future.waitForFinished();
++ CountFor f(0, iterations);
++ f.startBlocking();
+ QCOMPARE(counter.loadRelaxed(), iterations);
+ }
+ }
+@@ -177,11 +174,8 @@ void tst_QtConcurrentIterateKernel::stresstest()
+ void tst_QtConcurrentIterateKernel::noIterations()
+ {
+ const int times = 20000;
+- for (int i = 0; i < times; ++i) {
+- auto future = startThreadEngine(new IterateKernel<TestIterator, void>(0, 0))
+- .startAsynchronously();
+- future.waitForFinished();
+- }
++ for (int i = 0; i < times; ++i)
++ startThreadEngine(new IterateKernel<TestIterator, void>(0, 0)).startBlocking();
+ }
+
+ QMutex threadsMutex;
+@@ -236,10 +230,8 @@ void tst_QtConcurrentIterateKernel::throttling()
+
+ threads.clear();
+
+- // ThreadEngine will delete f when it finishes
+- auto f = new ThrottleFor(0, totalIterations);
+- auto future = f->startAsynchronously();
+- future.waitForFinished();
++ ThrottleFor f(0, totalIterations);
++ f.startBlocking();
+
+ QCOMPARE(iterations.loadRelaxed(), totalIterations);
+
+diff --git a/qtbase/tests/auto/concurrent/qtconcurrentthreadengine/tst_qtconcurrentthreadengine.cpp b/qtbase/tests/auto/concurrent/qtconcurrentthreadengine/tst_qtconcurrentthreadengine.cpp
+index ac7be7acdd..81bc64c8d9 100644
+--- a/qtbase/tests/auto/concurrent/qtconcurrentthreadengine/tst_qtconcurrentthreadengine.cpp
++++ b/qtbase/tests/auto/concurrent/qtconcurrentthreadengine/tst_qtconcurrentthreadengine.cpp
+@@ -65,9 +65,16 @@ public:
+
+ void tst_QtConcurrentThreadEngine::runDirectly()
+ {
+- PrintUser *engine = new PrintUser();
+- QFuture<void> f = engine->startAsynchronously();
+- f.waitForFinished();
++ {
++ PrintUser engine;
++ engine.startSingleThreaded();
++ engine.startBlocking();
++ }
++ {
++ PrintUser *engine = new PrintUser();
++ QFuture<void> f = engine->startAsynchronously();
++ f.waitForFinished();
++ }
+ }
+
+ class StringResultUser : public ThreadEngine<QString>
+@@ -99,10 +106,8 @@ public:
+
+ void tst_QtConcurrentThreadEngine::result()
+ {
+- // ThreadEngine will delete 'engine' when it finishes
+- auto engine = new StringResultUser();
+- auto future = engine->startAsynchronously();
+- QCOMPARE(future.result(), QString("Foo"));
++ StringResultUser engine;
++ QCOMPARE(*engine.startBlocking(), QString("Foo"));
+ }
+
+ class VoidResultUser : public ThreadEngine<void>
+@@ -128,9 +133,17 @@ public:
+
+ void tst_QtConcurrentThreadEngine::runThroughStarter()
+ {
+- ThreadEngineStarter<QString> starter = startThreadEngine(new StringResultUser());
+- QFuture<QString> f = starter.startAsynchronously();
+- QCOMPARE(f.result(), QString("Foo"));
++ {
++ ThreadEngineStarter<QString> starter = startThreadEngine(new StringResultUser());
++ QFuture<QString> f = starter.startAsynchronously();
++ QCOMPARE(f.result(), QString("Foo"));
++ }
++
++ {
++ ThreadEngineStarter<QString> starter = startThreadEngine(new StringResultUser());
++ QString str = starter.startBlocking();
++ QCOMPARE(str, QString("Foo"));
++ }
+ }
+
+ class CancelUser : public ThreadEngine<void>
+@@ -213,6 +226,12 @@ void tst_QtConcurrentThreadEngine::throttle()
+ f.waitForFinished();
+ QCOMPARE(count.loadRelaxed(), 0);
+ }
++
++ for (int i = 0; i < repeats; ++i) {
++ ThrottleAlwaysUser t;
++ t.startBlocking();
++ QCOMPARE(count.loadRelaxed(), 0);
++ }
+ }
+
+ QSet<QThread *> threads;
+@@ -249,17 +268,35 @@ void tst_QtConcurrentThreadEngine::threadCount()
+ {
+ const int repeats = 10;
+ for (int i = 0; i < repeats; ++i) {
++ ThreadCountUser t;
++ t.startBlocking();
++ int count = threads.count();
++ int count_expected = QThreadPool::globalInstance()->maxThreadCount() + 1; // +1 for the main thread.
++ if (count != count_expected)
++ QEXPECT_FAIL("", "QTBUG-23333", Abort);
++ QCOMPARE(count, count_expected);
++
+ (new ThreadCountUser())->startAsynchronously().waitForFinished();
+- const auto count = threads.count();
+- const auto maxThreadCount = QThreadPool::globalInstance()->maxThreadCount();
+- QVERIFY(count <= maxThreadCount);
+- QVERIFY(!threads.contains(QThread::currentThread()));
++ count = threads.count();
++ count_expected = QThreadPool::globalInstance()->maxThreadCount();
++ if (count != count_expected)
++ QEXPECT_FAIL("", "QTBUG-23333", Abort);
++ QCOMPARE(count, count_expected);
+ }
+
+ // Set the finish flag immediately, this should give us one thread only.
+ for (int i = 0; i < repeats; ++i) {
++ ThreadCountUser t(true /*finishImmediately*/);
++ t.startBlocking();
++ int count = threads.count();
++ if (count != 1)
++ QEXPECT_FAIL("", "QTBUG-23333", Abort);
++ QCOMPARE(count, 1);
++
+ (new ThreadCountUser(true /*finishImmediately*/))->startAsynchronously().waitForFinished();
+- const auto count = threads.count();
++ count = threads.count();
++ if (count != 1)
++ QEXPECT_FAIL("", "QTBUG-23333", Abort);
+ QCOMPARE(count, 1);
+ QVERIFY(!threads.contains(QThread::currentThread()));
+ }
+@@ -400,6 +437,7 @@ public:
+
+ void tst_QtConcurrentThreadEngine::exceptions()
+ {
++ // Asynchronous mode:
+ {
+ bool caught = false;
+ try {
+@@ -412,6 +450,32 @@ void tst_QtConcurrentThreadEngine::exceptions()
+ QVERIFY2(caught, "did not get exception");
+ }
+
++ // Blocking mode:
++ // test throwing the exception from a worker thread.
++ {
++ bool caught = false;
++ try {
++ QtConcurrentExceptionThrower e(QThread::currentThread());
++ e.startBlocking();
++ } catch (const QException &) {
++ caught = true;
++ }
++ QVERIFY2(caught, "did not get exception");
++ }
++
++ // test throwing the exception from the main thread (different code path)
++ {
++ bool caught = false;
++ try {
++ QtConcurrentExceptionThrower e(0);
++ e.startBlocking();
++ } catch (const QException &) {
++ caught = true;
++ }
++ QVERIFY2(caught, "did not get exception");
++ }
++
++ // Asynchronous mode:
+ {
+ bool caught = false;
+ try {
+@@ -423,6 +487,31 @@ void tst_QtConcurrentThreadEngine::exceptions()
+ }
+ QVERIFY2(caught, "did not get exception");
+ }
++
++ // Blocking mode:
++ // test throwing the exception from a worker thread.
++ {
++ bool caught = false;
++ try {
++ UnrelatedExceptionThrower e(QThread::currentThread());
++ e.startBlocking();
++ } catch (const QUnhandledException &) {
++ caught = true;
++ }
++ QVERIFY2(caught, "did not get exception");
++ }
++
++ // test throwing the exception from the main thread (different code path)
++ {
++ bool caught = false;
++ try {
++ UnrelatedExceptionThrower e(0);
++ e.startBlocking();
++ } catch (const QUnhandledException &) {
++ caught = true;
++ }
++ QVERIFY2(caught, "did not get exception");
++ }
+ }
+
+ #endif
+diff --git a/qtbase/tests/auto/corelib/io/qbuffer/tst_qbuffer.cpp b/qtbase/tests/auto/corelib/io/qbuffer/tst_qbuffer.cpp
+index 4968742110..f4c3fb711d 100644
+--- a/qtbase/tests/auto/corelib/io/qbuffer/tst_qbuffer.cpp
++++ b/qtbase/tests/auto/corelib/io/qbuffer/tst_qbuffer.cpp
+@@ -42,6 +42,7 @@ private slots:
+ void writeBlock_data();
+ void writeBlock();
+ void seek();
++ void invalidSeeks();
+ void seekTest_data();
+ void seekTest();
+ void read_rawdata();
+@@ -286,6 +287,29 @@ void tst_QBuffer::seek()
+ QCOMPARE(buffer.size(), pos);
+ }
+
++void tst_QBuffer::invalidSeeks()
++{
++ if constexpr (sizeof(qsizetype) == sizeof(qint64)) {
++ // sizeof(qsizetype) == sizeof(qint64), so +1 would overflow
++ QSKIP("This is a 32-bit-only test.");
++ } else {
++ QBuffer buffer;
++ buffer.open(QIODevice::WriteOnly);
++ QCOMPARE(buffer.buffer().size(), qsizetype(0));
++ QCOMPARE(buffer.pos(), qint64(0));
++ constexpr qint64 MaxQByteArrayCapacity = (std::numeric_limits<qsizetype>::max)();
++ // this should fail fast, not after trying to allocate nearly 2 GiB of data,
++ // potentially crashing in the process:
++ QVERIFY(!buffer.seek(2 * MaxQByteArrayCapacity - 1));
++ QCOMPARE(buffer.buffer().size(), qsizetype(0));
++ QCOMPARE(buffer.pos(), qint64(0));
++ // ditto:
++ QVERIFY(!buffer.seek(MaxQByteArrayCapacity + 1));
++ QCOMPARE(buffer.buffer().size(), qsizetype(0));
++ QCOMPARE(buffer.pos(), qint64(0));
++ }
++}
++
+ void tst_QBuffer::seekTest_data()
+ {
+ writeBlock_data();
+diff --git a/qtbase/tests/auto/corelib/io/qiodevice/tst_qiodevice.cpp b/qtbase/tests/auto/corelib/io/qiodevice/tst_qiodevice.cpp
+index da5327594c..4a04e0f7c6 100644
+--- a/qtbase/tests/auto/corelib/io/qiodevice/tst_qiodevice.cpp
++++ b/qtbase/tests/auto/corelib/io/qiodevice/tst_qiodevice.cpp
+@@ -561,7 +561,8 @@ protected:
+ qint64 readData(char *data, qint64 maxSize) override
+ {
+ maxSize = qMin(maxSize, qint64(buf->size() - offset));
+- memcpy(data, buf->constData() + offset, maxSize);
++ if (maxSize > 0)
++ memcpy(data, buf->constData() + offset, maxSize);
+ offset += maxSize;
+ return maxSize;
+ }
+@@ -604,13 +605,15 @@ protected:
+ qint64 readData(char *data, qint64 maxSize) override
+ {
+ maxSize = qMin(maxSize, qint64(buf.size() - pos()));
+- memcpy(data, buf.constData() + pos(), maxSize);
++ if (maxSize > 0)
++ memcpy(data, buf.constData() + pos(), maxSize);
+ return maxSize;
+ }
+ qint64 writeData(const char *data, qint64 maxSize) override
+ {
+ maxSize = qMin(maxSize, qint64(buf.size() - pos()));
+- memcpy(buf.data() + pos(), data, maxSize);
++ if (maxSize > 0)
++ memcpy(buf.data() + pos(), data, maxSize);
+ return maxSize;
+ }
+
+diff --git a/qtbase/tests/auto/corelib/io/qprocess/tst_qprocess.cpp b/qtbase/tests/auto/corelib/io/qprocess/tst_qprocess.cpp
+index db60bead64..f345a44414 100644
+--- a/qtbase/tests/auto/corelib/io/qprocess/tst_qprocess.cpp
++++ b/qtbase/tests/auto/corelib/io/qprocess/tst_qprocess.cpp
+@@ -1,7 +1,8 @@
+ /****************************************************************************
+ **
+ ** Copyright (C) 2021 The Qt Company Ltd.
+-** Copyright (C) 2020 Intel Corporation.
++** Copyright (C) 2020 The Qt Company Ltd.
++** Copyright (C) 2022 Intel Corporation.
+ ** Contact: https://www.qt.io/licensing/
+ **
+ ** This file is part of the test suite of the Qt Toolkit.
+@@ -150,6 +151,8 @@ private slots:
+ void startStopStartStopBuffers();
+ void processEventsInAReadyReadSlot_data();
+ void processEventsInAReadyReadSlot();
++ void startFromCurrentWorkingDir_data();
++ void startFromCurrentWorkingDir();
+
+ // keep these at the end, since they use lots of processes and sometimes
+ // caused obscure failures to occur in tests that followed them (esp. on the Mac)
+@@ -2731,5 +2734,94 @@ void tst_QProcess::finishProcessBeforeReadingDone_deprecated()
+
+ #endif
+
++enum class ChdirMode {
++ None = 0,
++ InParent,
++ InChild
++};
++Q_DECLARE_METATYPE(ChdirMode)
++
++void tst_QProcess::startFromCurrentWorkingDir_data()
++{
++ qRegisterMetaType<ChdirMode>();
++ QTest::addColumn<QString>("programPrefix");
++ QTest::addColumn<ChdirMode>("chdirMode");
++ QTest::addColumn<bool>("success");
++
++ constexpr bool IsWindows = true
++#ifdef Q_OS_UNIX
++ && false
++#endif
++ ;
++
++ // baseline: trying to execute the directory, this can't possibly succeed!
++ QTest::newRow("plain-same-cwd") << QString() << ChdirMode::None << false;
++
++ // cross-platform behavior: neither OS searches the setWorkingDirectory()
++ // dir without "./"
++ QTest::newRow("plain-child-chdir") << QString() << ChdirMode::InChild << false;
++
++ // cross-platform behavior: both OSes search the parent's CWD with "./"
++ QTest::newRow("prefixed-parent-chdir") << "./" << ChdirMode::InParent << true;
++
++ // opposite behaviors: Windows searches the parent's CWD and Unix searches
++ // the child's with "./"
++ QTest::newRow("prefixed-child-chdir") << "./" << ChdirMode::InChild << !IsWindows;
++
++ // Windows searches the parent's CWD without "./"
++ QTest::newRow("plain-parent-chdir") << QString() << ChdirMode::InParent << IsWindows;
++}
++
++void tst_QProcess::startFromCurrentWorkingDir()
++{
++ QFETCH(QString, programPrefix);
++ QFETCH(ChdirMode, chdirMode);
++ QFETCH(bool, success);
++
++ QProcess process;
++ qRegisterMetaType<QProcess::ProcessError>();
++ QSignalSpy errorSpy(&process, &QProcess::errorOccurred);
++ QVERIFY(errorSpy.isValid());
++
++ // both the dir name and the executable name
++ const QString target = QStringLiteral("testProcessNormal");
++ process.setProgram(programPrefix + target);
++
++#ifdef Q_OS_UNIX
++ // Reset PATH, to be sure it doesn't contain . or the empty path.
++ // We can't do this on Windows because DLLs are searched in PATH
++ // and Windows always searches "." anyway.
++ auto restoreEnv = qScopeGuard([old = qgetenv("PATH")] {
++ qputenv("PATH", old);
++ });
++ qputenv("PATH", "/");
++#endif
++
++ switch (chdirMode) {
++ case ChdirMode::InParent: {
++ auto restoreCwd = qScopeGuard([old = QDir::currentPath()] {
++ QDir::setCurrent(old);
++ });
++ QVERIFY(QDir::setCurrent(target));
++ process.start();
++ break;
++ }
++ case ChdirMode::InChild:
++ process.setWorkingDirectory(target);
++ Q_FALLTHROUGH();
++ case ChdirMode::None:
++ process.start();
++ break;
++ }
++
++ QCOMPARE(process.waitForStarted(), success);
++ QCOMPARE(errorSpy.count(), int(!success));
++ if (success) {
++ QVERIFY(process.waitForFinished());
++ } else {
++ QCOMPARE(process.error(), QProcess::FailedToStart);
++ }
++}
++
+ QTEST_MAIN(tst_QProcess)
+ #include "tst_qprocess.moc"
+diff --git a/qtbase/tests/auto/corelib/itemmodels/qconcatenatetablesproxymodel/tst_qconcatenatetablesproxymodel.cpp b/qtbase/tests/auto/corelib/itemmodels/qconcatenatetablesproxymodel/tst_qconcatenatetablesproxymodel.cpp
+index e1ea7a4552..90972caa57 100644
+--- a/qtbase/tests/auto/corelib/itemmodels/qconcatenatetablesproxymodel/tst_qconcatenatetablesproxymodel.cpp
++++ b/qtbase/tests/auto/corelib/itemmodels/qconcatenatetablesproxymodel/tst_qconcatenatetablesproxymodel.cpp
+@@ -117,6 +117,7 @@ private Q_SLOTS:
+ void shouldPropagateDropAfterLastRow_data();
+ void shouldPropagateDropAfterLastRow();
+ void qtbug91788();
++ void qtbug91878();
+
+ private:
+ QStandardItemModel mod;
+@@ -843,6 +844,22 @@ void tst_QConcatenateTablesProxyModel::qtbug91788()
+ QCOMPARE(proxyConcat.columnCount(), 0);
+ }
+
++void tst_QConcatenateTablesProxyModel::qtbug91878()
++{
++ QStandardItemModel m;
++ m.setRowCount(4);
++ m.setColumnCount(4);
++
++ QConcatenateTablesProxyModel pm;
++ QSortFilterProxyModel proxyFilter;
++ proxyFilter.setSourceModel(&pm);
++ proxyFilter.setFilterFixedString("something");
++ pm.addSourceModel(&m); // This should not assert
++
++ QCOMPARE(pm.columnCount(), 4);
++ QCOMPARE(pm.rowCount(), 4);
++}
++
+ QTEST_GUILESS_MAIN(tst_QConcatenateTablesProxyModel)
+
+ #include "tst_qconcatenatetablesproxymodel.moc"
+diff --git a/qtbase/tests/auto/corelib/kernel/qobject/tst_qobject.cpp b/qtbase/tests/auto/corelib/kernel/qobject/tst_qobject.cpp
+index 9bd66c0835..ed4a0bae5d 100644
+--- a/qtbase/tests/auto/corelib/kernel/qobject/tst_qobject.cpp
++++ b/qtbase/tests/auto/corelib/kernel/qobject/tst_qobject.cpp
+@@ -158,6 +158,7 @@ private slots:
+ void nullReceiver();
+ void functorReferencesConnection();
+ void disconnectDisconnects();
++ void declarativeData();
+ };
+
+ struct QObjectCreatedOnShutdown
+@@ -7679,5 +7680,81 @@ void tst_QObject::disconnectDisconnects()
+ Q_STATIC_ASSERT(QtPrivate::HasQ_OBJECT_Macro<tst_QObject>::Value);
+ Q_STATIC_ASSERT(!QtPrivate::HasQ_OBJECT_Macro<SiblingDeleter>::Value);
+
++#ifdef QT_BUILD_INTERNAL
++/*
++ Since QObjectPrivate stores the declarativeData pointer in a union with the pointer
++ to the currently destroyed child, calls to the QtDeclarative handlers need to be
++ correctly guarded. QTBUG-105286
++*/
++namespace QtDeclarative {
++static QAbstractDeclarativeData *theData;
++
++static void destroyed(QAbstractDeclarativeData *data, QObject *)
++{
++ QCOMPARE(data, theData);
++}
++static void signalEmitted(QAbstractDeclarativeData *data, QObject *, int, void **)
++{
++ QCOMPARE(data, theData);
++}
++// we can't use QCOMPARE in the next two functions, as they don't return void
++static int receivers(QAbstractDeclarativeData *data, const QObject *, int)
++{
++ QTest::qCompare(data, theData, "data", "theData", __FILE__, __LINE__);
++ return 0;
++}
++static bool isSignalConnected(QAbstractDeclarativeData *data, const QObject *, int)
++{
++ QTest::qCompare(data, theData, "data", "theData", __FILE__, __LINE__);
++ return true;
++}
++
++class Object : public QObject
++{
++ Q_OBJECT
++public:
++ using QObject::QObject;
++ ~Object()
++ {
++ if (Object *p = static_cast<Object *>(parent()))
++ p->emitSignal();
++ }
++
++ void emitSignal()
++ {
++ emit theSignal();
++ }
++
++signals:
++ void theSignal();
++};
++
++}
++#endif
++
++void tst_QObject::declarativeData()
++{
++#ifdef QT_BUILD_INTERNAL
++ QScopedValueRollback destroyed(QAbstractDeclarativeData::destroyed,
++ QtDeclarative::destroyed);
++ QScopedValueRollback signalEmitted(QAbstractDeclarativeData::signalEmitted,
++ QtDeclarative::signalEmitted);
++ QScopedValueRollback receivers(QAbstractDeclarativeData::receivers,
++ QtDeclarative::receivers);
++ QScopedValueRollback isSignalConnected(QAbstractDeclarativeData::isSignalConnected,
++ QtDeclarative::isSignalConnected);
++
++ QtDeclarative::Object p;
++ QObjectPrivate *priv = QObjectPrivate::get(&p);
++ priv->declarativeData = QtDeclarative::theData = new QAbstractDeclarativeData;
++
++ connect(&p, &QtDeclarative::Object::theSignal, &p, []{
++ });
++
++ QtDeclarative::Object *child = new QtDeclarative::Object;
++ child->setParent(&p);
++#endif
++}
++
+ QTEST_MAIN(tst_QObject)
+ #include "tst_qobject.moc"
+diff --git a/qtbase/tests/auto/corelib/mimetypes/qmimedatabase/tst_qmimedatabase.cpp b/qtbase/tests/auto/corelib/mimetypes/qmimedatabase/tst_qmimedatabase.cpp
+index 0ea422ecbc..1a3256534b 100644
+--- a/qtbase/tests/auto/corelib/mimetypes/qmimedatabase/tst_qmimedatabase.cpp
++++ b/qtbase/tests/auto/corelib/mimetypes/qmimedatabase/tst_qmimedatabase.cpp
+@@ -70,15 +70,15 @@ static inline QString testSuiteWarning()
+
+ QString result;
+ QTextStream str(&result);
+- str << "\nCannot find the shared-mime-info test suite\nstarting from: "
++ str << "\nCannot find the shared-mime-info test suite\nin the parent of: "
+ << QDir::toNativeSeparators(QDir::currentPath()) << "\n"
+ "cd " << QDir::toNativeSeparators(QStringLiteral("tests/auto/corelib/mimetypes/qmimedatabase")) << "\n"
+- "wget http://cgit.freedesktop.org/xdg/shared-mime-info/snapshot/Release-1-10.zip\n"
+- "unzip Release-1-10.zip\n";
++ "wget https://gitlab.freedesktop.org/xdg/shared-mime-info/-/archive/2.1/shared-mime-info-2.1.zip\n"
++ "unzip shared-mime-info-2.1.zip\n";
+ #ifdef Q_OS_WIN
+- str << "mkdir testfiles\nxcopy /s Release-1-10 s-m-i\n";
++ str << "mkdir testfiles\nxcopy /s shared-mime-info-2.1 s-m-i\n";
+ #else
+- str << "ln -s Release-1-10 s-m-i\n";
++ str << "ln -s shared-mime-info-2.1 s-m-i\n";
+ #endif
+ return result;
+ }
+@@ -154,7 +154,7 @@ void tst_QMimeDatabase::initTestCase()
+ QVERIFY2(copyResourceFile(xmlFileName, xmlTargetFileName, &errorMessage), qPrintable(errorMessage));
+ #endif
+
+- m_testSuite = QFINDTESTDATA("s-m-i/tests");
++ m_testSuite = QFINDTESTDATA("s-m-i/tests/mime-detection");
+ if (m_testSuite.isEmpty())
+ qWarning("%s", qPrintable(testSuiteWarning()));
+
+@@ -611,7 +611,7 @@ void tst_QMimeDatabase::allMimeTypes()
+ QVERIFY(!lst.isEmpty());
+
+ // Hardcoding this is the only way to check both providers find the same number of mimetypes.
+- QCOMPARE(lst.count(), 779);
++ QCOMPARE(lst.count(), 811);
+
+ foreach (const QMimeType &mime, lst) {
+ const QString name = mime.name();
+@@ -631,10 +631,9 @@ void tst_QMimeDatabase::suffixes_data()
+
+ QTest::newRow("mimetype with a single pattern") << "application/pdf" << "*.pdf" << "pdf";
+ QTest::newRow("mimetype with multiple patterns") << "application/x-kpresenter" << "*.kpr;*.kpt" << "kpr";
+- QTest::newRow("jpeg") << "image/jpeg" << "*.jpe;*.jpg;*.jpeg" << "jpeg";
+- //if (KMimeType::sharedMimeInfoVersion() > KDE_MAKE_VERSION(0, 60, 0)) {
+- QTest::newRow("mimetype with many patterns") << "application/vnd.wordperfect" << "*.wp;*.wp4;*.wp5;*.wp6;*.wpd;*.wpp" << "wp";
+- //}
++ // The preferred suffix for image/jpeg is *.jpg, as per https://bugs.kde.org/show_bug.cgi?id=176737
++ QTest::newRow("jpeg") << "image/jpeg" << "*.jpe;*.jpg;*.jpeg" << "jpg";
++ QTest::newRow("mimetype with many patterns") << "application/vnd.wordperfect" << "*.wp;*.wp4;*.wp5;*.wp6;*.wpd;*.wpp" << "wp";
+ QTest::newRow("oasis text mimetype") << "application/vnd.oasis.opendocument.text" << "*.odt" << "odt";
+ QTest::newRow("oasis presentation mimetype") << "application/vnd.oasis.opendocument.presentation" << "*.odp" << "odp";
+ QTest::newRow("mimetype with multiple patterns") << "text/plain" << "*.asc;*.txt;*,v" << "txt";
+diff --git a/qtbase/tests/auto/corelib/serialization/json/tst_qtjson.cpp b/qtbase/tests/auto/corelib/serialization/json/tst_qtjson.cpp
+index 3e58dd03cc..c8f82ef5d5 100644
+--- a/qtbase/tests/auto/corelib/serialization/json/tst_qtjson.cpp
++++ b/qtbase/tests/auto/corelib/serialization/json/tst_qtjson.cpp
+@@ -176,6 +176,8 @@ private Q_SLOTS:
+ void fromToVariantConversions_data();
+ void fromToVariantConversions();
+
++ void noLeakOnNameClash();
++
+ private:
+ QString testDataDir;
+ };
+@@ -3685,5 +3687,23 @@ void tst_QtJson::fromToVariantConversions()
+ }
+ }
+
++void tst_QtJson::noLeakOnNameClash()
++{
++ QJsonDocument doc = QJsonDocument::fromJson("{\"\":{\"\":0},\"\":0}");
++ QVERIFY(!doc.isNull());
++ const QJsonObject obj = doc.object();
++
++ // Removed the duplicate key.
++ QCOMPARE(obj.length(), 1);
++
++ // Retained the last of the duplicates.
++ const QJsonValue val = obj.begin().value();
++ QVERIFY(val.isDouble());
++ QCOMPARE(val.toDouble(), 0.0);
++
++ // It should not leak.
++ // In particular it should not forget to deref the container for the inner object.
++}
++
+ QTEST_MAIN(tst_QtJson)
+ #include "tst_qtjson.moc"
+diff --git a/qtbase/tests/auto/corelib/time/qtimezone/tst_qtimezone.cpp b/qtbase/tests/auto/corelib/time/qtimezone/tst_qtimezone.cpp
+index a59b58d57f..241c3e84ac 100644
+--- a/qtbase/tests/auto/corelib/time/qtimezone/tst_qtimezone.cpp
++++ b/qtbase/tests/auto/corelib/time/qtimezone/tst_qtimezone.cpp
+@@ -63,6 +63,7 @@ private slots:
+ void isValidId_data();
+ void isValidId();
+ void malformed();
++ void serialize();
+ // Backend tests
+ void utcTest();
+ void icuTest();
+@@ -947,6 +948,33 @@ void tst_QTimeZone::malformed()
+ barf.offsetFromUtc(now);
+ }
+
++void tst_QTimeZone::serialize()
++{
++ int parts = 0;
++#ifndef QT_NO_DEBUG_STREAM
++ qDebug() << QTimeZone(); // to verify no crash
++ parts++;
++#endif
++#ifndef QT_NO_DATASTREAM
++ QByteArray blob;
++ {
++ QDataStream stream(&blob, QIODevice::WriteOnly);
++ stream << QTimeZone("Europe/Oslo") << QTimeZone(420) << QTimeZone() << qint64(-1);
++ }
++ QDataStream stream(&blob, QIODevice::ReadOnly);
++ QTimeZone invalid, offset, oslo;
++ qint64 minusone;
++ stream >> oslo >> offset >> invalid >> minusone;
++ QCOMPARE(oslo, QTimeZone("Europe/Oslo"));
++ QCOMPARE(offset, QTimeZone(420));
++ QVERIFY(!invalid.isValid());
++ QCOMPARE(minusone, qint64(-1));
++ parts++;
++#endif
++ if (!parts)
++ QSKIP("No serialization enabled");
++}
++
+ void tst_QTimeZone::utcTest()
+ {
+ #ifdef QT_BUILD_INTERNAL
+diff --git a/qtbase/tests/auto/dbus/qdbusinterface/tst_qdbusinterface.cpp b/qtbase/tests/auto/dbus/qdbusinterface/tst_qdbusinterface.cpp
+index 05480c6dd2..70f4c75756 100644
+--- a/qtbase/tests/auto/dbus/qdbusinterface/tst_qdbusinterface.cpp
++++ b/qtbase/tests/auto/dbus/qdbusinterface/tst_qdbusinterface.cpp
+@@ -324,6 +324,13 @@ void tst_QDBusInterface::notValid()
+
+ QVERIFY(!interface.isValid());
+ QVERIFY(!QMetaObject::invokeMethod(&interface, "ListNames", Qt::DirectConnection));
++
++ // With a connection, but empty/null service and path specified
++ QDBusConnection con = QDBusConnection::sessionBus();
++ QVERIFY(con.isConnected());
++ QDBusInterface iface({}, {}, {}, con);
++ QVERIFY(!iface.isValid());
++ QVERIFY(!QMetaObject::invokeMethod(&interface, "ListNames", Qt::DirectConnection));
+ }
+
+ void tst_QDBusInterface::notValidDerived()
+diff --git a/qtbase/tests/auto/gui/kernel/qkeysequence/tst_qkeysequence.cpp b/qtbase/tests/auto/gui/kernel/qkeysequence/tst_qkeysequence.cpp
+index 874468c954..04ceb4ab65 100644
+--- a/qtbase/tests/auto/gui/kernel/qkeysequence/tst_qkeysequence.cpp
++++ b/qtbase/tests/auto/gui/kernel/qkeysequence/tst_qkeysequence.cpp
+@@ -507,6 +507,10 @@ void tst_QKeySequence::toStringFromKeycode_data()
+ QTest::newRow("Ctrl+Alt+Num+Del") << QKeySequence(Qt::ControlModifier | Qt::AltModifier | Qt::KeypadModifier | Qt::Key_Delete) << "Ctrl+Alt+Num+Del";
+ QTest::newRow("Ctrl+Ins") << QKeySequence(Qt::ControlModifier | Qt::Key_Insert) << "Ctrl+Ins";
+ QTest::newRow("Ctrl+Num+Ins(1)") << QKeySequence(Qt::Key_Insert | Qt::KeypadModifier | Qt::ControlModifier) << "Ctrl+Num+Ins";
++ QTest::newRow("Ctrl") << QKeySequence(Qt::Key_Control) << "Control";
++ QTest::newRow("Alt") << QKeySequence(Qt::Key_Alt) << "Alt";
++ QTest::newRow("Shift") << QKeySequence(Qt::Key_Shift) << "Shift";
++ QTest::newRow("Meta") << QKeySequence(Qt::Key_Meta) << "Meta";
+ }
+
+ void tst_QKeySequence::toStringFromKeycode()
+diff --git a/qtbase/tests/auto/gui/text/qfontdatabase/tst_qfontdatabase.cpp b/qtbase/tests/auto/gui/text/qfontdatabase/tst_qfontdatabase.cpp
+index 15e0ecadaa..b4eca74283 100644
+--- a/qtbase/tests/auto/gui/text/qfontdatabase/tst_qfontdatabase.cpp
++++ b/qtbase/tests/auto/gui/text/qfontdatabase/tst_qfontdatabase.cpp
+@@ -81,6 +81,8 @@ private slots:
+ void registerOpenTypePreferredNamesSystem();
+ void registerOpenTypePreferredNamesApplication();
+
++ void stretchRespected();
++
+ private:
+ QString m_ledFont;
+ QString m_testFont;
+@@ -355,6 +357,28 @@ static QString testString()
+ return QStringLiteral("foo bar");
+ }
+
++void tst_QFontDatabase::stretchRespected()
++{
++ int italicId = QFontDatabase::addApplicationFont(m_testFontItalic);
++ QVERIFY(italicId != -1);
++
++ QVERIFY(!QFontDatabase::applicationFontFamilies(italicId).isEmpty());
++
++ QString italicFontName = QFontDatabase::applicationFontFamilies(italicId).first();
++
++ QFont italicFont = QFontDatabase().font(italicFontName,
++ QString::fromLatin1("Italic"), 14);
++ QVERIFY(italicFont.italic());
++
++ QFont italicStretchedFont = italicFont;
++ italicStretchedFont.setStretch( 400 );
++
++ QVERIFY(QFontMetricsF(italicFont).horizontalAdvance(QStringLiteral("foobar")) <
++ QFontMetricsF(italicStretchedFont).horizontalAdvance(QStringLiteral("foobar")));
++
++ QFontDatabase::removeApplicationFont(italicId);
++}
++
+ void tst_QFontDatabase::condensedFontWidthNoFontMerging()
+ {
+ int regularFontId = QFontDatabase::addApplicationFont(m_testFont);
+diff --git a/qtbase/tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp b/qtbase/tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp
+index 3d4a094c43..b423e11a99 100644
+--- a/qtbase/tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp
++++ b/qtbase/tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp
+@@ -281,6 +281,7 @@ private Q_SLOTS:
+ void ioGetFromFileSpecial();
+ void ioGetFromFile_data();
+ void ioGetFromFile();
++ void ioGetFromFileUrl();
+ void ioGetFromFtp_data();
+ void ioGetFromFtp();
+ void ioGetFromFtpWithReuse();
+@@ -3300,6 +3301,18 @@ void tst_QNetworkReply::ioGetFromFile()
+ QCOMPARE(reader.data, data);
+ }
+
++void tst_QNetworkReply::ioGetFromFileUrl()
++{
++ // This immediately fails on non-windows platforms:
++ QNetworkRequest request(QUrl("file://unc-server/some/path"));
++ QNetworkReplyPtr reply(manager.get(request));
++ QSignalSpy finishedSpy(reply.get(), &QNetworkReply::finished);
++ // QTBUG-105618: This would, on non-Windows platforms, never happen because the signal
++ // was emitted before the constructor finished, leaving no chance at all to connect to the
++ // signal
++ QVERIFY(finishedSpy.wait());
++}
++
+ void tst_QNetworkReply::ioGetFromFtp_data()
+ {
+ QTest::addColumn<QString>("fileName");
+diff --git a/qtbase/tests/auto/network/ssl/qsslsocket/certs/fluke.cert b/qtbase/tests/auto/network/ssl/qsslsocket/certs/fluke.cert
+index 069fa6b341..4cc4d9a5ea 100644
+--- a/qtbase/tests/auto/network/ssl/qsslsocket/certs/fluke.cert
++++ b/qtbase/tests/auto/network/ssl/qsslsocket/certs/fluke.cert
+@@ -1,75 +1,34 @@
+-Certificate:
+- Data:
+- Version: 3 (0x2)
+- Serial Number: 0 (0x0)
+- Signature Algorithm: sha1WithRSAEncryption
+- Issuer: C=NO, ST=Oslo, L=Nydalen, O=Nokia Corporation and/or its subsidiary(-ies), OU=Development, CN=fluke.troll.no/emailAddress=ahanssen@trolltech.com
+- Validity
+- Not Before: Dec 4 01:10:32 2007 GMT
+- Not After : Apr 21 01:10:32 2035 GMT
+- Subject: C=NO, ST=Oslo, O=Nokia Corporation and/or its subsidiary(-ies), OU=Development, CN=fluke.troll.no
+- Subject Public Key Info:
+- Public Key Algorithm: rsaEncryption
+- RSA Public Key: (1024 bit)
+- Modulus (1024 bit):
+- 00:a7:c8:a0:4a:c4:19:05:1b:66:ba:32:e2:d2:f1:
+- 1c:6f:17:82:e4:39:2e:01:51:90:db:04:34:32:11:
+- 21:c2:0d:6f:59:d8:53:90:54:3f:83:8f:a9:d3:b3:
+- d5:ee:1a:9b:80:ae:c3:25:c9:5e:a5:af:4b:60:05:
+- aa:a0:d1:91:01:1f:ca:04:83:e3:58:1c:99:32:45:
+- 84:70:72:58:03:98:4a:63:8b:41:f5:08:49:d2:91:
+- 02:60:6b:e4:64:fe:dd:a0:aa:74:08:e9:34:4c:91:
+- 5f:12:3d:37:4d:54:2c:ad:7f:5b:98:60:36:02:8c:
+- 3b:f6:45:f3:27:6a:9b:94:9d
+- Exponent: 65537 (0x10001)
+- X509v3 extensions:
+- X509v3 Basic Constraints:
+- CA:FALSE
+- Netscape Comment:
+- OpenSSL Generated Certificate
+- X509v3 Subject Key Identifier:
+- 21:85:04:3D:23:01:66:E5:F7:9F:1A:84:24:8A:AF:0A:79:F4:E5:AC
+- X509v3 Authority Key Identifier:
+- DirName:/C=NO/ST=Oslo/L=Nydalen/O=Nokia Corporation and/or its subsidiary(-ies)/OU=Development/CN=fluke.troll.no/emailAddress=ahanssen@trolltech.com
+- serial:8E:A8:B4:E8:91:B7:54:2E
+-
+- Signature Algorithm: sha1WithRSAEncryption
+- 6d:57:5f:d1:05:43:f0:62:05:ec:2a:71:a5:dc:19:08:f2:c4:
+- a6:bd:bb:25:d9:ca:89:01:0e:e4:cf:1f:c1:8c:c8:24:18:35:
+- 53:59:7b:c0:43:b4:32:e6:98:b2:a6:ef:15:05:0b:48:5f:e1:
+- a0:0c:97:a9:a1:77:d8:35:18:30:bc:a9:8f:d3:b7:54:c7:f1:
+- a9:9e:5d:e6:19:bf:f6:3c:5b:2b:d8:e4:3e:62:18:88:8b:d3:
+- 24:e1:40:9b:0c:e6:29:16:62:ab:ea:05:24:70:36:aa:55:93:
+- ef:02:81:1b:23:10:a2:04:eb:56:95:75:fc:f8:94:b1:5d:42:
+- c5:3f:36:44:85:5d:3a:2e:90:46:8a:a2:b9:6f:87:ae:0c:15:
+- 40:19:31:90:fc:3b:25:bb:ae:f1:66:13:0d:85:90:d9:49:34:
+- 8f:f2:5d:f9:7a:db:4d:5d:27:f6:76:9d:35:8c:06:a6:4c:a3:
+- b1:b2:b6:6f:1d:d7:a3:00:fd:72:eb:9e:ea:44:a1:af:21:34:
+- 7d:c7:42:e2:49:91:19:8b:c0:ad:ba:82:80:a8:71:70:f4:35:
+- 31:91:63:84:20:95:e9:60:af:64:8b:cc:ff:3d:8a:76:74:3d:
+- c8:55:6d:e4:8e:c3:2b:1c:e8:42:18:ae:9f:e6:6b:9c:34:06:
+- ec:6a:f2:c3
+ -----BEGIN CERTIFICATE-----
+-MIIEEzCCAvugAwIBAgIBADANBgkqhkiG9w0BAQUFADCBnDELMAkGA1UEBhMCTk8x
+-DTALBgNVBAgTBE9zbG8xEDAOBgNVBAcTB055ZGFsZW4xFjAUBgNVBAoTDVRyb2xs
+-dGVjaCBBU0ExFDASBgNVBAsTC0RldmVsb3BtZW50MRcwFQYDVQQDEw5mbHVrZS50
+-cm9sbC5ubzElMCMGCSqGSIb3DQEJARYWYWhhbnNzZW5AdHJvbGx0ZWNoLmNvbTAe
+-Fw0wNzEyMDQwMTEwMzJaFw0zNTA0MjEwMTEwMzJaMGMxCzAJBgNVBAYTAk5PMQ0w
+-CwYDVQQIEwRPc2xvMRYwFAYDVQQKEw1Ucm9sbHRlY2ggQVNBMRQwEgYDVQQLEwtE
+-ZXZlbG9wbWVudDEXMBUGA1UEAxMOZmx1a2UudHJvbGwubm8wgZ8wDQYJKoZIhvcN
+-AQEBBQADgY0AMIGJAoGBAKfIoErEGQUbZroy4tLxHG8XguQ5LgFRkNsENDIRIcIN
+-b1nYU5BUP4OPqdOz1e4am4CuwyXJXqWvS2AFqqDRkQEfygSD41gcmTJFhHByWAOY
+-SmOLQfUISdKRAmBr5GT+3aCqdAjpNEyRXxI9N01ULK1/W5hgNgKMO/ZF8ydqm5Sd
+-AgMBAAGjggEaMIIBFjAJBgNVHRMEAjAAMCwGCWCGSAGG+EIBDQQfFh1PcGVuU1NM
+-IEdlbmVyYXRlZCBDZXJ0aWZpY2F0ZTAdBgNVHQ4EFgQUIYUEPSMBZuX3nxqEJIqv
+-Cnn05awwgbsGA1UdIwSBszCBsKGBoqSBnzCBnDELMAkGA1UEBhMCTk8xDTALBgNV
+-BAgTBE9zbG8xEDAOBgNVBAcTB055ZGFsZW4xFjAUBgNVBAoTDVRyb2xsdGVjaCBB
+-U0ExFDASBgNVBAsTC0RldmVsb3BtZW50MRcwFQYDVQQDEw5mbHVrZS50cm9sbC5u
+-bzElMCMGCSqGSIb3DQEJARYWYWhhbnNzZW5AdHJvbGx0ZWNoLmNvbYIJAI6otOiR
+-t1QuMA0GCSqGSIb3DQEBBQUAA4IBAQBtV1/RBUPwYgXsKnGl3BkI8sSmvbsl2cqJ
+-AQ7kzx/BjMgkGDVTWXvAQ7Qy5piypu8VBQtIX+GgDJepoXfYNRgwvKmP07dUx/Gp
+-nl3mGb/2PFsr2OQ+YhiIi9Mk4UCbDOYpFmKr6gUkcDaqVZPvAoEbIxCiBOtWlXX8
+-+JSxXULFPzZEhV06LpBGiqK5b4euDBVAGTGQ/Dslu67xZhMNhZDZSTSP8l35ettN
+-XSf2dp01jAamTKOxsrZvHdejAP1y657qRKGvITR9x0LiSZEZi8CtuoKAqHFw9DUx
+-kWOEIJXpYK9ki8z/PYp2dD3IVW3kjsMrHOhCGK6f5mucNAbsavLD
++MIIF6zCCA9OgAwIBAgIUfo9amJtJGWqWE6f+SkAO85zkGr4wDQYJKoZIhvcNAQEL
++BQAwgYMxCzAJBgNVBAYTAk5PMQ0wCwYDVQQIDARPc2xvMQ0wCwYDVQQHDARPc2xv
++MRcwFQYDVQQKDA5UaGUgUXQgQ29tcGFueTEMMAoGA1UECwwDUiZEMRIwEAYDVQQD
++DAlIMiBUZXN0ZXIxGzAZBgkqhkiG9w0BCQEWDG1pbmltaUBxdC5pbzAgFw0yMDEw
++MjYxMjAxMzFaGA8yMTIwMTAwMjEyMDEzMVowgYMxCzAJBgNVBAYTAk5PMQ0wCwYD
++VQQIDARPc2xvMQ0wCwYDVQQHDARPc2xvMRcwFQYDVQQKDA5UaGUgUXQgQ29tcGFu
++eTEMMAoGA1UECwwDUiZEMRIwEAYDVQQDDAlIMiBUZXN0ZXIxGzAZBgkqhkiG9w0B
++CQEWDG1pbmltaUBxdC5pbzCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIB
++AOiUp5+E4blouKH7q+rVNR8NoYX2XkBW+q+rpy1zu5ssRSzbqxAjDx9dkht7Qlnf
++VlDT00JvpOWdeuPon5915edQRsY4Unl6mKH29ra3OtUa1/yCJXsGVJTKCj7k4Bxb
++5mZzb/fTlZntMLdTIBMfUbw62FKir1WjKIcJ9fCoG8JaGeKVO4Rh5p0ezd4UUUId
++r1BXl5Nqdqy2vTMsEDnjOsD3egkv8I2SKN4O6n/C3wWYpMOWYZkGoZiKz7rJs/i/
++ez7bsV7JlwdzTlhpJzkcOSVFBP6JlEOxTNNxZ1wtKy7PtZGmsSSATq2e6+bw38Ae
++Op0XnzzqcGjtDDofBmT7OFzZWjS9VZS6+DOOe2QHWle1nCHcHyH4ku6IRlsr9xkR
++NAIlOfnvHHxqJUenoeaZ4oQDjCBKS1KXygJO/tL7BLTQVn/xK1EmPvKNnjzWk4tR
++PnibUhhs5635qpOU/YPqFBh1JjVruZbsWcDAhRcew0uxONXOa9E+4lttQ9ySYa1A
++LvWqJuAX7gu2BsBMLyqfm811YnA7CIFMyO+HlqmkLFfv5L/xIRAXR7l26YGO0VwX
++CGjMfz4NVPMMke4nB7qa9NkpXQBQKMms3Qzd5JW0Hy9Ruj5O8GPcFZmV0twjd1uJ
++PD/cAjkWLaXjdNsJ16QWc2nghQRS6HYqKRX6j+CXOxupAgMBAAGjUzBRMB0GA1Ud
++DgQWBBRSCOU58j9NJZkMamt623qyCrhN3TAfBgNVHSMEGDAWgBRSCOU58j9NJZkM
++amt623qyCrhN3TAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEBCwUAA4ICAQCq
++q4jxsWeNDv5Nq14hJtF9HB+ZL64zcZtRjJP1YgNs0QppKICmjPOL2nIMGmI/jKrs
++0eGAL/9XXNVHPxm1OPOncvimMMmU6emZfpMdEtTfKP43+Pg9HgKRjLoQp406vGeQ
++8ki/mbBhrItVPgEm3tu2AFA02XTYi+YxCI9kRZLGkM3FbgtOuTLPl0Z9y+kiPc9F
++uCSC03anBEqv+vDSI8+wODymQ/IJ3Jyz1lxIRDfp4qAekmy0jU2c91VOHHEmOmqq
++kqygGFRdwbe99m9yP63r6q0b5K3X2UnJ6bns0hmTwThYwpVPXLU8jdaTddbMukN2
++/Ef96Tsw8nWOEOPMySHOTIPgwyZRp26b0kA9EmhLwOP401SxXVQCmSRmtwNagmtg
++jJKmZoYBN+//D45ibK8z6Q0oOm9P+Whf/uUXehcRxBxyV3xz7k0wKGQbHj/ddwcy
++IUoIN4lrAlib+lK170kTKN352PDmrpo2gmIzPEsfurKAIMSelDl6H+kih16BtZ8y
++Nz6fh9Soqrg3OSAware8pxV7k51crBMoPLN78KoRV8MFCK4K7Fddq4rRISq6hiXq
++r1nsjoEPuKM9huprmZVZe9t5YcDa2I+wb3IiE3uwpZbAdaLDyQ5n6F/qpsiIkZXn
++gtcF7oqpG5oYrwCcZ53y/ezUgUg7PlSz2XwAGvQtgg==
+ -----END CERTIFICATE-----
+diff --git a/qtbase/tests/auto/network/ssl/qsslsocket/certs/fluke.key b/qtbase/tests/auto/network/ssl/qsslsocket/certs/fluke.key
+index 9d1664d609..337ce541a6 100644
+--- a/qtbase/tests/auto/network/ssl/qsslsocket/certs/fluke.key
++++ b/qtbase/tests/auto/network/ssl/qsslsocket/certs/fluke.key
+@@ -1,15 +1,52 @@
+------BEGIN RSA PRIVATE KEY-----
+-MIICXAIBAAKBgQCnyKBKxBkFG2a6MuLS8RxvF4LkOS4BUZDbBDQyESHCDW9Z2FOQ
+-VD+Dj6nTs9XuGpuArsMlyV6lr0tgBaqg0ZEBH8oEg+NYHJkyRYRwclgDmEpji0H1
+-CEnSkQJga+Rk/t2gqnQI6TRMkV8SPTdNVCytf1uYYDYCjDv2RfMnapuUnQIDAQAB
+-AoGANFzLkanTeSGNFM0uttBipFT9F4a00dqHz6JnO7zXAT26I5r8sU1pqQBb6uLz
+-/+Qz5Zwk8RUAQcsMRgJetuPQUb0JZjF6Duv24hNazqXBCu7AZzUenjafwmKC/8ri
+-KpX3fTwqzfzi//FKGgbXQ80yykSSliDL3kn/drATxsLCgQECQQDXhEFWLJ0vVZ1s
+-1Ekf+3NITE+DR16X+LQ4W6vyEHAjTbaNWtcTKdAWLA2l6N4WAAPYSi6awm+zMxx4
+-VomVTsjdAkEAx0z+e7natLeFcrrq8pbU+wa6SAP1VfhQWKitxL1e7u/QO90NCpxE
+-oQYKzMkmmpOOFjQwEMAy1dvFMbm4LHlewQJAC/ksDBaUcQHHqjktCtrUb8rVjAyW
+-A8lscckeB2fEYyG5J6dJVaY4ClNOOs5yMDS2Afk1F6H/xKvtQ/5CzInA/QJATDub
+-K+BPU8jO9q+gpuIi3VIZdupssVGmCgObVCHLakG4uO04y9IyPhV9lA9tALtoIf4c
+-VIvv5fWGXBrZ48kZAQJBAJmVCdzQxd9LZI5vxijUCj5EI4e+x5DRqVUvyP8KCZrC
+-AiNyoDP85T+hBZaSXK3aYGpVwelyj3bvo1GrTNwNWLw=
+------END RSA PRIVATE KEY-----
++-----BEGIN PRIVATE KEY-----
++MIIJQgIBADANBgkqhkiG9w0BAQEFAASCCSwwggkoAgEAAoICAQDolKefhOG5aLih
+++6vq1TUfDaGF9l5AVvqvq6ctc7ubLEUs26sQIw8fXZIbe0JZ31ZQ09NCb6TlnXrj
++6J+fdeXnUEbGOFJ5epih9va2tzrVGtf8giV7BlSUygo+5OAcW+Zmc2/305WZ7TC3
++UyATH1G8OthSoq9VoyiHCfXwqBvCWhnilTuEYeadHs3eFFFCHa9QV5eTanastr0z
++LBA54zrA93oJL/CNkijeDup/wt8FmKTDlmGZBqGYis+6ybP4v3s+27FeyZcHc05Y
++aSc5HDklRQT+iZRDsUzTcWdcLSsuz7WRprEkgE6tnuvm8N/AHjqdF5886nBo7Qw6
++HwZk+zhc2Vo0vVWUuvgzjntkB1pXtZwh3B8h+JLuiEZbK/cZETQCJTn57xx8aiVH
++p6HmmeKEA4wgSktSl8oCTv7S+wS00FZ/8StRJj7yjZ481pOLUT54m1IYbOet+aqT
++lP2D6hQYdSY1a7mW7FnAwIUXHsNLsTjVzmvRPuJbbUPckmGtQC71qibgF+4LtgbA
++TC8qn5vNdWJwOwiBTMjvh5appCxX7+S/8SEQF0e5dumBjtFcFwhozH8+DVTzDJHu
++Jwe6mvTZKV0AUCjJrN0M3eSVtB8vUbo+TvBj3BWZldLcI3dbiTw/3AI5Fi2l43Tb
++CdekFnNp4IUEUuh2KikV+o/glzsbqQIDAQABAoICAFw1q6tr5I48vY7DF+rXsuLn
++5ZUWE1IQ6fzB4lr72nJv/9EEGnMgYzt9PpMUsD6vdCpBgS2C0+6RHArFzJtNA+RM
++iHLIG7K7702veyr/xBx/MwiSlMeMv/XpkFxVI6E6skMGG2s3AMXxKvJTy5CpRx+I
++eQFyLG+Ya1X2lgJes/q+/CpAHkOjCOpcLySQC5NZ74q734V7nSdmn+Zs3tYEh+O/
++eiuwTP/j5b38Te5vVTqDxTciJPmljmXLCwa0N100lWlbcpvw8qbqiTI2Jm3XCbUE
++AzHjW9vmrF3cRS1fXxKFGShw3SRqlkbxjfeWoi8qDPUBS4m8LOr8qG9Wo5Nfon0z
++zLP4bci3zHDvVcaaZrrsUBs/yZbg+Dgka1DmX7ekmeccr2yTdKDFgPupYUyxVbTl
++a9ZLJysjFD7rgBv1ZclHonLp6Vbm+ZoTqvteo4ikAy6L9RtBWJ23XEK34PkP/+c5
++2vWZaOrnjSeBHbFce8cdJSxqWpP+eSCI5I9XbDrYFIsQ/gqKgtzDKy2ihJ2Y8STL
++yO4hyFPFjxc+Gg4/P2PpmT5CY2ty44M0BWs+JGW96CJPrrplf2lmQUQJj5LZY66X
++Z/4C9L7ZYtKZ+bs5SvU46yWugAvQZX22Xm9xLXWyVXRdx3bj+3M3fDnF9di/zdbh
++CgLx7oWPNrXc7FCajnn9AoIBAQD5FMYwRpw9NWT9WDxQwx+cSI4Icbd88ByTW63S
++LzeRwZA0J9/SfwO+aBRupzc9GkGXCiZcGMw3AGsCtig8yFlw8E5KnzN7KlftDMnM
++9NUxxzlR8VwKyLnZfG7sDTl057ZlUujnqhmt/F8F7dIy7FVO1dE/8nngA+FYTCOG
++UZdGjwyBDlDM0JJdUWGY3xslutcpCDN5mzSTKjy9drMvImAshRawxRF6WBpn7vr2
++nC6vciqfx1Mzx1vyk0Jm0ilaydDdLMADjt/iL4Nkr0BEs4k+UzQiKDwp8gu7abQ1
++eBfxd9Iar4htQa2I1Ewl6P01G/q+ZYwgHhJ9RVn4AxQXefILAoIBAQDvCouORdQX
++C8wsyp7MwXlF/3NQeNN5/+B2mhbxrBOf7PmMCXLnkRWcjwJtzypWFqJ0sqai/2+0
++bqbMcjX5maT8stT2shl3zXe/Ejt2e3TBYpc1tyuses8Kb5BMU8hu6tTd3G2CMXpD
++dT6DVemJZCTtwj9aBNIxSizvlgMolJnCpzhPnlfHSI6E+g3m/LTTo3HwbjMSw/Uq
++irgjOpI2wSBB6LZPSgjvfcYPRyWUk16L4A5uSX0cADnovDFLa5/h0wJvN/OoCSQg
++rLCXG5E18EyL5Wc58BCY1ZvxmjG3lQtgPxYu2Jwc36R/y/JKlxW5suER5ZNpbbD4
++uOyTt2VxMQ2bAoIBAQC5+MzRFqdo/AjfL5Y5JrbfVTzXCTDa09xCGd16ZU60QTWN
+++4ed/r+o1sUKqUcRFB2MzEM/2DQBjQpZB/CbEWvWa1XJWXxypXbowveZU+QqOnmN
++uQvj8WLyA3o+PNF9e9QvauwCrHpn8VpxbtPWuaYoKnUFreFZZQxHhPGxRBIS2JOZ
++eDrT8ZaWnkCkh1AZp5smQ71LOprSlmKrg4jd1GjCVMxQR5N5KXbtyv0OTCZ/UFqK
++2aRBsMPyJgkaBChkZPLRcKwc+/wlQRx1fHQb14DNTApMxoXFO7eOwqmOkpAt9iyl
++SBIwoS0UUI5ab88+bBmXNvKcuFdNuQ4nowTJUn9pAoIBADMNkILBXSvS5DeIyuO2
++Sp1tkoZUV+5NfPY3sMDK3KIibaW/+t+EOBZo4L7tKQCb8vRzl21mmsfxfgRaPDbj
++3r3tv9g0b4YLxxBy52pFscj/soXRai17SS7UZwA2QK+XzgDYbDcLNC6mIsTQG4Gx
++dsWk3/zs3KuUSQaehmwrWK+fIUK38c1pLK8v7LoxrLkqxlHwZ04RthHw8KTthH7X
++Pnl1J0LF8CSeOyfWLSuPUfkT0GEzptnNHpEbaHfQM6R6eaGhVJPF6AZme4y6YYgg
++m2ihhSt1n0XVEWpHYWjxFy3mK2mz75unFC4LM+NEY2p2zuUQoCw7NjnY3QYrfCnx
++rRMCggEAXeXsMSLFjjyuoL7iKbAxo52HD/P0fBoy58LyRcwfNVr0lvYan4pYEx+o
++KijIh9K16PqXZXKMA9v003B+ulmF8bJ7SddCZ5NGvnFhUTDe4DdTKgp2RuwQ3Bsc
++3skPIDbhVETyOLCtys34USHrq8U/0DlGY3eLRfxw9GnbKxSBGa/KEu/qQLPNUo50
++7xHZDg7GKeC3kqNJeqKM9rkp0VzIGkEnaD9127LeNDmERDfftxJzFoC/THvUBLfU
++6Sus2ZYwRE8VFvKC30Q45t/c54X3IuhYvAuiCuTmyfE4ruyzyOwKzhUkeeLq1APX
++g0veFbyfzlJ0q8qzD/iffqqIa2ZSmQ==
++-----END PRIVATE KEY-----
+diff --git a/qtbase/tests/auto/other/qaccessibilitylinux/tst_qaccessibilitylinux.cpp b/qtbase/tests/auto/other/qaccessibilitylinux/tst_qaccessibilitylinux.cpp
+index 7ba3715e13..752aa122f6 100644
+--- a/qtbase/tests/auto/other/qaccessibilitylinux/tst_qaccessibilitylinux.cpp
++++ b/qtbase/tests/auto/other/qaccessibilitylinux/tst_qaccessibilitylinux.cpp
+@@ -179,6 +179,7 @@ void tst_QAccessibilityLinux::initTestCase()
+ QVERIFY(!address.isEmpty());
+
+ m_window = new AccessibleTestWindow();
++ m_window->setObjectName("mainWindow"_L1);
+ m_window->show();
+
+ QVERIFY(QTest::qWaitForWindowExposed(m_window));
+@@ -236,8 +237,11 @@ bool hasState(QDBusInterface *interface, AtspiStateType state)
+ void tst_QAccessibilityLinux::testLabel()
+ {
+ QLabel *l = new QLabel(m_window);
++ l->setObjectName("theObjectName"_L1);
+ l->setText("Hello A11y");
+ m_window->addWidget(l);
++ auto a11yEmpty = new QLabel(m_window);
++ m_window->addWidget(l);
+
+ // Application
+ QCOMPARE(getParent(mainWindow), QLatin1String(ATSPI_DBUS_PATH_ROOT));
+@@ -249,6 +253,8 @@ void tst_QAccessibilityLinux::testLabel()
+ QCOMPARE(getChildren(labelInterface).count(), 0);
+ QCOMPARE(labelInterface->call(QDBus::Block, "GetRoleName").arguments().first().toString(), QLatin1String("label"));
+ QCOMPARE(labelInterface->call(QDBus::Block, "GetRole").arguments().first().toUInt(), 29u);
++ QCOMPARE(labelInterface->call(QDBus::Block, "GetAccessibleId").arguments().first().toString(),
++ QLatin1String("mainWindow.theObjectName"));
+ QCOMPARE(getParent(labelInterface), mainWindow->path());
+ QVERIFY(!hasState(labelInterface, ATSPI_STATE_EDITABLE));
+ QVERIFY(hasState(labelInterface, ATSPI_STATE_READ_ONLY));
+@@ -256,7 +262,12 @@ void tst_QAccessibilityLinux::testLabel()
+ l->setText("New text");
+ QCOMPARE(labelInterface->property("Name").toString(), l->text());
+
++ auto *a11yEmptyInterface = getInterface(children.at(1), "org.a11y.atspi.Accessible");
++ QCOMPARE(a11yEmptyInterface->call(QDBus::Block, "GetAccessibleId").arguments().first().toString(),
++ QLatin1String("mainWindow.QLabel"));
++
+ m_window->clearChildren();
++ delete a11yEmptyInterface;
+ delete labelInterface;
+ }
+
+diff --git a/qtbase/tests/auto/sql/kernel/qsqlquery/tst_qsqlquery.cpp b/qtbase/tests/auto/sql/kernel/qsqlquery/tst_qsqlquery.cpp
+index 76df61c892..6d6d65b791 100644
+--- a/qtbase/tests/auto/sql/kernel/qsqlquery/tst_qsqlquery.cpp
++++ b/qtbase/tests/auto/sql/kernel/qsqlquery/tst_qsqlquery.cpp
+@@ -1,6 +1,6 @@
+ /****************************************************************************
+ **
+-** Copyright (C) 2016 The Qt Company Ltd.
++** Copyright (C) 2022 The Qt Company Ltd.
+ ** Contact: https://www.qt.io/licensing/
+ **
+ ** This file is part of the test suite of the Qt Toolkit.
+@@ -68,6 +68,8 @@ private slots:
+ void query_exec();
+ void execErrorRecovery_data() { generic_data(); }
+ void execErrorRecovery();
++ void prematureExec_data() { generic_data(); }
++ void prematureExec();
+ void first_data() { generic_data(); }
+ void first();
+ void next_data() { generic_data(); }
+@@ -2770,6 +2772,35 @@ void tst_QSqlQuery::execErrorRecovery()
+ QVERIFY_SQL( q, exec() );
+ }
+
++void tst_QSqlQuery::prematureExec()
++{
++ QFETCH(QString, dbName);
++ // We only want the engine name, for addDatabase():
++ int cut = dbName.indexOf(QChar('@'));
++ if (cut < 0)
++ QSKIP("Failed to parse database type out of name");
++ dbName.truncate(cut);
++ cut = dbName.indexOf(QChar('_'));
++ if (cut >= 0)
++ dbName = dbName.mid(cut + 1);
++
++ auto db = QSqlDatabase::addDatabase(dbName);
++ QSqlQuery q(db);
++
++ QTest::ignoreMessage(QtWarningMsg,
++ "QSqlDatabasePrivate::removeDatabase: connection "
++ "'qt_sql_default_connection' is still in use, all "
++ "queries will cease to work.");
++ QTest::ignoreMessage(QtWarningMsg,
++ "QSqlDatabasePrivate::addDatabase: duplicate connection name "
++ "'qt_sql_default_connection', old connection removed.");
++ auto otherDb = QSqlDatabase::addDatabase(dbName);
++
++ QTest::ignoreMessage(QtWarningMsg, "QSqlQuery::exec: called before driver has been set up");
++ // QTBUG-100037: shouldn't crash !
++ QVERIFY(!q.exec("select stuff from TheVoid"));
++}
++
+ void tst_QSqlQuery::lastInsertId()
+ {
+ QFETCH( QString, dbName );
+diff --git a/qtbase/tests/auto/testlib/qabstractitemmodeltester/tst_qabstractitemmodeltester.cpp b/qtbase/tests/auto/testlib/qabstractitemmodeltester/tst_qabstractitemmodeltester.cpp
+index 4aa3f8d60b..d2050a61aa 100644
+--- a/qtbase/tests/auto/testlib/qabstractitemmodeltester/tst_qabstractitemmodeltester.cpp
++++ b/qtbase/tests/auto/testlib/qabstractitemmodeltester/tst_qabstractitemmodeltester.cpp
+@@ -115,6 +115,10 @@ void tst_QAbstractItemModelTester::standardItemModelZeroColumns()
+ // QTBUG-92886
+ model.insertRows(0, 5);
+ model.removeRows(1, 2);
++
++ const QModelIndex parentIndex = model.index(0, 0);
++ model.insertRows(0, 5, parentIndex);
++ model.removeRows(1, 2, parentIndex);
+ }
+
+ void tst_QAbstractItemModelTester::testInsertThroughProxy()
+diff --git a/qtbase/tests/auto/tools/moc/allmocs_baseline_in.json b/qtbase/tests/auto/tools/moc/allmocs_baseline_in.json
+index 12a4a22a19..ce518e78fb 100644
+--- a/qtbase/tests/auto/tools/moc/allmocs_baseline_in.json
++++ b/qtbase/tests/auto/tools/moc/allmocs_baseline_in.json
+@@ -668,50 +668,6 @@
+ "inputFile": "task192552.h",
+ "outputRevision": 67
+ },
+- {
+- "classes": [
+- {
+- "className": "InlineSlotsWithThrowDeclaration",
+- "object": true,
+- "qualifiedClassName": "InlineSlotsWithThrowDeclaration",
+- "slots": [
+- {
+- "access": "public",
+- "name": "a",
+- "returnType": "void"
+- },
+- {
+- "access": "public",
+- "name": "b",
+- "returnType": "void"
+- },
+- {
+- "access": "public",
+- "name": "c",
+- "returnType": "void"
+- },
+- {
+- "access": "public",
+- "name": "d",
+- "returnType": "void"
+- },
+- {
+- "access": "public",
+- "name": "e",
+- "returnType": "void"
+- }
+- ],
+- "superClasses": [
+- {
+- "access": "public",
+- "name": "QObject"
+- }
+- ]
+- }
+- ],
+- "inputFile": "task189996.h",
+- "outputRevision": 67
+- },
+ {
+ "classes": [
+ {
+diff --git a/qtbase/tests/auto/tools/moc/moc.pro b/qtbase/tests/auto/tools/moc/moc.pro
+index c324b3a8cd..4aceb78dc0 100644
+--- a/qtbase/tests/auto/tools/moc/moc.pro
++++ b/qtbase/tests/auto/tools/moc/moc.pro
+@@ -15,7 +15,7 @@ cross_compile: DEFINES += MOC_CROSS_COMPILED
+ HEADERS += using-namespaces.h no-keywords.h task87883.h c-comments.h backslash-newlines.h oldstyle-casts.h \
+ slots-with-void-template.h qinvokable.h namespaced-flags.h trigraphs.h \
+ escapes-in-string-literals.h cstyle-enums.h qprivateslots.h gadgetwithnoenums.h \
+- dir-in-include-path.h single_function_keyword.h task192552.h task189996.h \
++ dir-in-include-path.h single_function_keyword.h task192552.h \
+ task234909.h task240368.h pure-virtual-signals.h cxx11-enums.h \
+ cxx11-final-classes.h \
+ cxx11-explicit-override-control.h \
+diff --git a/qtbase/tests/auto/tools/moc/task189996.h b/qtbase/tests/auto/tools/moc/task189996.h
+deleted file mode 100644
+index f94a051b3a..0000000000
+--- a/qtbase/tests/auto/tools/moc/task189996.h
++++ /dev/null
+@@ -1,47 +0,0 @@
+-/****************************************************************************
+-**
+-** Copyright (C) 2016 The Qt Company Ltd.
+-** Contact: https://www.qt.io/licensing/
+-**
+-** This file is part of the test suite of the Qt Toolkit.
+-**
+-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+-** Commercial License Usage
+-** Licensees holding valid commercial Qt licenses may use this file in
+-** accordance with the commercial license agreement provided with the
+-** Software or, alternatively, in accordance with the terms contained in
+-** a written agreement between you and The Qt Company. For licensing terms
+-** and conditions see https://www.qt.io/terms-conditions. For further
+-** information use the contact form at https://www.qt.io/contact-us.
+-**
+-** GNU General Public License Usage
+-** Alternatively, this file may be used under the terms of the GNU
+-** General Public License version 3 as published by the Free Software
+-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+-** included in the packaging of this file. Please review the following
+-** information to ensure the GNU General Public License requirements will
+-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+-**
+-** $QT_END_LICENSE$
+-**
+-****************************************************************************/
+-// inline functions can have throw declarations
+-
+-#ifndef TASK189996_H
+-#define TASK189996_H
+-
+-#include <QObject>
+-
+-class InlineSlotsWithThrowDeclaration : public QObject
+-{
+- Q_OBJECT
+-
+-public slots:
+- void a() throw() { }
+- void b() const throw() { }
+- void c() throw();
+- void d() throw(int) { }
+- void e() const throw(int,double) { }
+-};
+-
+-#endif
+diff --git a/qtbase/tests/auto/tools/moc/tst_moc.cpp b/qtbase/tests/auto/tools/moc/tst_moc.cpp
+index c716aead21..15dd9e41e5 100644
+--- a/qtbase/tests/auto/tools/moc/tst_moc.cpp
++++ b/qtbase/tests/auto/tools/moc/tst_moc.cpp
+@@ -631,7 +631,6 @@ public:
+ private slots:
+ void initTestCase();
+
+- void slotWithException() throw(MyStruct);
+ void dontStripNamespaces();
+ void oldStyleCasts();
+ void warnOnExtraSignalSlotQualifiaction();
+@@ -673,7 +672,6 @@ private slots:
+ void templateGtGt();
+ void qprivateslots();
+ void qprivateproperties();
+- void inlineSlotsWithThrowDeclaration();
+ void warnOnPropertyWithoutREAD();
+ void constructors();
+ void typenameWithUnsigned();
+@@ -784,12 +782,6 @@ void tst_Moc::initTestCase()
+ #endif
+ }
+
+-void tst_Moc::slotWithException() throw(MyStruct)
+-{
+- // be happy
+- QVERIFY(true);
+-}
+-
+ void tst_Moc::dontStripNamespaces()
+ {
+ Sender sender;
+@@ -824,7 +816,7 @@ void tst_Moc::oldStyleCasts()
+
+ QStringList args;
+ args << "-c" << "-x" << "c++" << "-Wold-style-cast" << "-I" << "."
+- << "-I" << qtIncludePath << "-o" << "/dev/null" << "-fPIC" << "-std=c++11" << "-";
++ << "-I" << qtIncludePath << "-o" << "/dev/null" << "-fPIC" << "-std=c++1z" << "-";
+ proc.start("gcc", args);
+ QVERIFY(proc.waitForStarted());
+ proc.write(mocOut);
+@@ -894,7 +886,7 @@ void tst_Moc::inputFileNameWithDotsButNoExtension()
+
+ QStringList args;
+ args << "-c" << "-x" << "c++" << "-I" << ".."
+- << "-I" << qtIncludePath << "-o" << "/dev/null" << "-fPIC" << "-std=c++11" << "-";
++ << "-I" << qtIncludePath << "-o" << "/dev/null" << "-fPIC" << "-std=c++1z" << "-";
+ proc.start("gcc", args);
+ QVERIFY(proc.waitForStarted());
+ proc.write(mocOut);
+@@ -1174,7 +1166,7 @@ void tst_Moc::ignoreOptionClashes()
+ QStringList gccArgs;
+ gccArgs << "-c" << "-x" << "c++" << "-I" << ".."
+ << "-I" << qtIncludePath << "-I" << includeDir << "-o" << "/dev/null"
+- << "-fPIC" << "-std=c++11" << "-";
++ << "-fPIC" << "-std=c++1z" << "-";
+ proc.start("gcc", gccArgs);
+ QVERIFY(proc.waitForStarted());
+ proc.write(mocOut);
+@@ -1593,21 +1585,6 @@ void tst_Moc::qprivateproperties()
+
+ }
+
+-#include "task189996.h"
+-
+-void InlineSlotsWithThrowDeclaration::c() throw() {}
+-
+-void tst_Moc::inlineSlotsWithThrowDeclaration()
+-{
+- InlineSlotsWithThrowDeclaration tst;
+- const QMetaObject *mobj = tst.metaObject();
+- QVERIFY(mobj->indexOfSlot("a()") != -1);
+- QVERIFY(mobj->indexOfSlot("b()") != -1);
+- QVERIFY(mobj->indexOfSlot("c()") != -1);
+- QVERIFY(mobj->indexOfSlot("d()") != -1);
+- QVERIFY(mobj->indexOfSlot("e()") != -1);
+-}
+-
+ void tst_Moc::warnOnPropertyWithoutREAD()
+ {
+ #ifdef MOC_CROSS_COMPILED
+@@ -1869,7 +1846,7 @@ void tst_Moc::notifyError()
+
+ QStringList args;
+ args << "-c" << "-x" << "c++" << "-I" << "."
+- << "-I" << qtIncludePath << "-o" << "/dev/null" << "-fPIC" << "-std=c++11" << "-";
++ << "-I" << qtIncludePath << "-o" << "/dev/null" << "-fPIC" << "-std=c++1z" << "-";
+ proc.start("gcc", args);
+ QVERIFY(proc.waitForStarted());
+ proc.write(mocOut);
+diff --git a/qtbase/tests/auto/widgets/itemviews/qheaderview/tst_qheaderview.cpp b/qtbase/tests/auto/widgets/itemviews/qheaderview/tst_qheaderview.cpp
+index c355ee9665..88c09de8e0 100644
+--- a/qtbase/tests/auto/widgets/itemviews/qheaderview/tst_qheaderview.cpp
++++ b/qtbase/tests/auto/widgets/itemviews/qheaderview/tst_qheaderview.cpp
+@@ -251,6 +251,7 @@ private slots:
+ void testResetCachedSizeHint();
+ void statusTips();
+ void testRemovingColumnsViaLayoutChanged();
++ void testModelMovingColumns();
+
+ protected:
+ void setupTestData(bool use_reset_model = false);
+@@ -360,6 +361,12 @@ public:
+ endRemoveColumns();
+ }
+
++ void moveColumn(int from, int to)
++ {
++ beginMoveColumns(QModelIndex(), from, from, QModelIndex(), to);
++ endMoveColumns();
++ }
++
+ void cleanup()
+ {
+ emit layoutAboutToBeChanged();
+@@ -3627,5 +3634,18 @@ void tst_QHeaderView::testRemovingColumnsViaLayoutChanged()
+ // The main point of this test is that the section-size restoring code didn't go out of bounds.
+ }
+
++void tst_QHeaderView::testModelMovingColumns()
++{
++ QtTestModel model(10, 10);
++ QHeaderView hv(Qt::Horizontal);
++ hv.setModel(&model);
++ hv.resizeSections(QHeaderView::ResizeToContents);
++ hv.show();
++
++ QPersistentModelIndex index3 = model.index(0, 3);
++ model.moveColumn(3, 1);
++ QCOMPARE(index3.column(), 1);
++}
++
+ QTEST_MAIN(tst_QHeaderView)
+ #include "tst_qheaderview.moc"
+diff --git a/qtbase/tests/auto/widgets/itemviews/qtableview/tst_qtableview.cpp b/qtbase/tests/auto/widgets/itemviews/qtableview/tst_qtableview.cpp
+index 761357b252..06bb706074 100644
+--- a/qtbase/tests/auto/widgets/itemviews/qtableview/tst_qtableview.cpp
++++ b/qtbase/tests/auto/widgets/itemviews/qtableview/tst_qtableview.cpp
+@@ -397,6 +397,7 @@ private slots:
+ void checkHeaderMinSize();
+
+ void resizeToContents();
++ void resizeToContentsSpans();
+
+ void tabFocus();
+ void bigModel();
+@@ -3721,6 +3722,70 @@ void tst_QTableView::resizeToContents()
+
+ }
+
++
++class SpanModel : public QAbstractTableModel
++{
++public:
++ SpanModel(bool sectionsMoved)
++ : _sectionsMoved(sectionsMoved)
++ {}
++ int columnCount(const QModelIndex & = {}) const override { return 2; }
++ int rowCount(const QModelIndex & = {}) const override { return 1; }
++ QVariant data(const QModelIndex &idx, int role = Qt::DisplayRole) const override
++ {
++ if (role != Qt::DisplayRole)
++ return QVariant();
++ const int col = _sectionsMoved ? 1 - idx.column() : idx.column();
++ if (col == 0)
++ return "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.";
++ return QVariant();
++ }
++private:
++ bool _sectionsMoved;
++};
++
++
++void tst_QTableView::resizeToContentsSpans()
++{
++ SpanModel model1(false);
++ SpanModel model2(true);
++ QTableView view1, view2, view3;
++ view1.setModel(&model1);
++ view2.setModel(&model2);
++ view2.horizontalHeader()->moveSection(0, 1);
++ view3.setModel(&model1);
++
++ view1.setSpan(0, 0, 1, 2);
++ view2.setSpan(0, 1, 1, 2);
++ view1.show();
++ view2.show();
++ view3.show();
++ QVERIFY(QTest::qWaitForWindowExposed(&view1));
++ QVERIFY(QTest::qWaitForWindowExposed(&view2));
++ QVERIFY(QTest::qWaitForWindowExposed(&view3));
++ view1.setColumnWidth(0, 100);
++ view1.setColumnWidth(1, 100);
++ view2.setColumnWidth(0, 100);
++ view2.setColumnWidth(1, 100);
++ view3.setColumnWidth(0, 200);
++
++ view1.resizeRowToContents(0);
++ view2.resizeRowToContents(0);
++ view3.resizeRowToContents(0);
++ QCOMPARE(view1.rowHeight(0), view3.rowHeight(0));
++ QCOMPARE(view2.rowHeight(0), view3.rowHeight(0));
++
++ view3.resizeColumnToContents(0);
++ view3.resizeRowToContents(0);
++ // height should be only 1 text line for easy testing
++ view1.setRowHeight(0, view3.verticalHeader()->sectionSize(0));
++ view2.setRowHeight(0, view3.verticalHeader()->sectionSize(0));
++ view1.resizeColumnToContents(0);
++ view2.resizeColumnToContents(1);
++ QCOMPARE(view1.columnWidth(0), view3.columnWidth(0) - view1.columnWidth(1));
++ QCOMPARE(view2.columnWidth(0), view3.columnWidth(0) - view2.columnWidth(1));
++}
++
+ QT_BEGIN_NAMESPACE
+ extern bool Q_WIDGETS_EXPORT qt_tab_all_widgets(); // qapplication.cpp
+ QT_END_NAMESPACE
+diff --git a/qtbase/tests/auto/widgets/kernel/qapplication/tst_qapplication.cpp b/qtbase/tests/auto/widgets/kernel/qapplication/tst_qapplication.cpp
+index a3b8ef78d8..4955cebd5d 100644
+--- a/qtbase/tests/auto/widgets/kernel/qapplication/tst_qapplication.cpp
++++ b/qtbase/tests/auto/widgets/kernel/qapplication/tst_qapplication.cpp
+@@ -1498,7 +1498,7 @@ void tst_QApplication::desktopSettingsAware()
+ environment += QLatin1String("QT_MAC_DISABLE_FOREGROUND_APPLICATION_TRANSFORM=1");
+ testProcess.setEnvironment(environment);
+ #endif
+- testProcess.start("desktopsettingsaware_helper");
++ testProcess.start("./desktopsettingsaware_helper");
+ QVERIFY2(testProcess.waitForStarted(),
+ qPrintable(QString::fromLatin1("Cannot start 'desktopsettingsaware_helper': %1").arg(testProcess.errorString())));
+ QVERIFY(testProcess.waitForFinished(10000));
+@@ -2452,7 +2452,7 @@ void tst_QApplication::qtbug_12673()
+ #if QT_CONFIG(process)
+ QProcess testProcess;
+ QStringList arguments;
+- testProcess.start("modal_helper", arguments);
++ testProcess.start("./modal_helper", arguments);
+ QVERIFY2(testProcess.waitForStarted(),
+ qPrintable(QString::fromLatin1("Cannot start 'modal_helper': %1").arg(testProcess.errorString())));
+ QVERIFY(testProcess.waitForFinished(20000));
+diff --git a/qtbase/tests/auto/widgets/widgets/qabstractbutton/tst_qabstractbutton.cpp b/qtbase/tests/auto/widgets/widgets/qabstractbutton/tst_qabstractbutton.cpp
+index eb108a40de..dca5528c1b 100644
+--- a/qtbase/tests/auto/widgets/widgets/qabstractbutton/tst_qabstractbutton.cpp
++++ b/qtbase/tests/auto/widgets/widgets/qabstractbutton/tst_qabstractbutton.cpp
+@@ -41,6 +41,7 @@
+
+ #include <private/qguiapplication_p.h>
+ #include <qpa/qplatformintegration.h>
++#include <qpa/qplatformtheme.h>
+
+ class tst_QAbstractButton : public QObject
+ {
+@@ -76,6 +77,8 @@ private slots:
+ void keyNavigation();
+ #endif
+
++ void buttonPressKeys();
++
+ protected slots:
+ void onClicked();
+ void onToggled( bool on );
+@@ -269,7 +272,13 @@ void tst_QAbstractButton::setAutoRepeat()
+ QCOMPARE(press_count, click_count);
+ QVERIFY(click_count > 1);
+ break;
+- case 4:
++ case 4: {
++ const auto buttonPressKeys = QGuiApplicationPrivate::platformTheme()
++ ->themeHint(QPlatformTheme::ButtonPressKeys)
++ .value<QList<Qt::Key>>();
++ if (buttonPressKeys.contains(Qt::Key_Enter)) {
++ QSKIP("platform theme has Key_Enter in ButtonPressKeys");
++ }
+ // check that pressing ENTER has no effect when autorepeat is false
+ testWidget->setDown( false );
+ testWidget->setAutoRepeat( false );
+@@ -286,7 +295,14 @@ void tst_QAbstractButton::setAutoRepeat()
+
+ QVERIFY( click_count == 0 );
+ break;
+- case 5:
++ }
++ case 5: {
++ const auto buttonPressKeys = QGuiApplicationPrivate::platformTheme()
++ ->themeHint(QPlatformTheme::ButtonPressKeys)
++ .value<QList<Qt::Key>>();
++ if (buttonPressKeys.contains(Qt::Key_Enter)) {
++ QSKIP("platform theme has Key_Enter in ButtonPressKeys");
++ }
+ // check that pressing ENTER has no effect when autorepeat is true
+ testWidget->setDown( false );
+ testWidget->setAutoRepeat( true );
+@@ -304,6 +320,7 @@ void tst_QAbstractButton::setAutoRepeat()
+
+ QVERIFY( click_count == 0 );
+ break;
++ }
+ case 6:
+ // verify autorepeat is off by default.
+ MyButton tmp( 0);
+@@ -651,5 +668,16 @@ void tst_QAbstractButton::keyNavigation()
+ }
+ #endif
+
++void tst_QAbstractButton::buttonPressKeys()
++{
++ const auto buttonPressKeys = QGuiApplicationPrivate::platformTheme()
++ ->themeHint(QPlatformTheme::ButtonPressKeys)
++ .value<QList<Qt::Key>>();
++ for (int i = 0; i < buttonPressKeys.length(); ++i) {
++ QTest::keyClick(testWidget, buttonPressKeys[i]);
++ QCOMPARE(click_count, i + 1);
++ }
++}
++
+ QTEST_MAIN(tst_QAbstractButton)
+ #include "tst_qabstractbutton.moc"
+diff --git a/qtbase/tests/auto/widgets/widgets/qcombobox/tst_qcombobox.cpp b/qtbase/tests/auto/widgets/widgets/qcombobox/tst_qcombobox.cpp
+index 32437050f5..46b5af6d63 100644
+--- a/qtbase/tests/auto/widgets/widgets/qcombobox/tst_qcombobox.cpp
++++ b/qtbase/tests/auto/widgets/widgets/qcombobox/tst_qcombobox.cpp
+@@ -168,6 +168,7 @@ private slots:
+ void checkMenuItemPosWhenStyleSheetIsSet();
+ void checkEmbeddedLineEditWhenStyleSheetIsSet();
+ void propagateStyleChanges();
++ void buttonPressKeys();
+
+ private:
+ PlatformInputContext m_platformInputContext;
+@@ -1682,6 +1683,16 @@ void tst_QComboBox::setModel()
+ QCOMPARE(box.rootModelIndex(), rootModelIndex);
+ box.setModel(box.model());
+ QCOMPARE(box.rootModelIndex(), rootModelIndex);
++
++ // check that setting the same model as the completer's doesn't crash
++ QCompleter *completer = new QCompleter(&box);
++ box.setEditable(true);
++ box.setCompleter(completer);
++ auto *listModel = new QStringListModel({ "one", "two" }, completer);
++ completer->setModel(listModel);
++ QCOMPARE(listModel->rowCount(), 2); // make sure it wasn't deleted
++ box.setModel(listModel);
++ QCOMPARE(listModel->rowCount(), 2); // make sure it wasn't deleted
+ }
+
+ void tst_QComboBox::setCustomModelAndView()
+@@ -3632,5 +3643,24 @@ void tst_QComboBox::propagateStyleChanges()
+ QVERIFY(frameStyle.inquired);
+ }
+
++void tst_QComboBox::buttonPressKeys()
++{
++ QComboBox comboBox;
++ comboBox.setEditable(false);
++ comboBox.addItem(QString::number(1));
++ comboBox.addItem(QString::number(2));
++ const auto buttonPressKeys = QGuiApplicationPrivate::platformTheme()
++ ->themeHint(QPlatformTheme::ButtonPressKeys)
++ .value<QList<Qt::Key>>();
++ for (int i = 0; i < buttonPressKeys.length(); ++i) {
++ QTest::keyClick(&comboBox, buttonPressKeys[i]);
++ // On some platforms, a window will not be immediately visible,
++ // but take some event-loop iterations to complete.
++ // Using QTRY_VERIFY to deal with that.
++ QTRY_VERIFY(comboBox.view()->isVisible());
++ comboBox.hidePopup();
++ }
++}
++
+ QTEST_MAIN(tst_QComboBox)
+ #include "tst_qcombobox.moc"
+diff --git a/qtbase/tests/auto/widgets/widgets/qcommandlinkbutton/qcommandlinkbutton.pro b/qtbase/tests/auto/widgets/widgets/qcommandlinkbutton/qcommandlinkbutton.pro
+index be3cfcd104..c228fdfcca 100644
+--- a/qtbase/tests/auto/widgets/widgets/qcommandlinkbutton/qcommandlinkbutton.pro
++++ b/qtbase/tests/auto/widgets/widgets/qcommandlinkbutton/qcommandlinkbutton.pro
+@@ -1,6 +1,6 @@
+ CONFIG += testcase
+ TARGET = tst_qcommandlinkbutton
+-QT += widgets testlib
++QT += widgets testlib gui-private
+ SOURCES += tst_qcommandlinkbutton.cpp
+
+
+diff --git a/qtbase/tests/auto/widgets/widgets/qcommandlinkbutton/tst_qcommandlinkbutton.cpp b/qtbase/tests/auto/widgets/widgets/qcommandlinkbutton/tst_qcommandlinkbutton.cpp
+index 0044d33c66..4cf06296e4 100644
+--- a/qtbase/tests/auto/widgets/widgets/qcommandlinkbutton/tst_qcommandlinkbutton.cpp
++++ b/qtbase/tests/auto/widgets/widgets/qcommandlinkbutton/tst_qcommandlinkbutton.cpp
+@@ -40,6 +40,9 @@
+ #include <QGridLayout>
+ #include <QPainter>
+
++#include <private/qguiapplication_p.h>
++#include <qpa/qplatformtheme.h>
++
+ class tst_QCommandLinkButton : public QObject
+ {
+ Q_OBJECT
+@@ -223,6 +226,13 @@ void tst_QCommandLinkButton::setAutoRepeat()
+ // check that pressing ENTER has no effect
+ resetCounters();
+ testWidget->setDown( false );
++ // Skip after reset if ButtonPressKeys has Key_Enter
++ const auto buttonPressKeys = QGuiApplicationPrivate::platformTheme()
++ ->themeHint(QPlatformTheme::ButtonPressKeys)
++ .value<QList<Qt::Key>>();
++ if (buttonPressKeys.contains(Qt::Key_Enter)) {
++ return;
++ }
+ testWidget->setAutoRepeat( false );
+ QTest::keyPress( testWidget, Qt::Key_Enter );
+
+@@ -255,6 +265,14 @@ void tst_QCommandLinkButton::pressed()
+ QCOMPARE( press_count, (uint)1 );
+ QCOMPARE( release_count, (uint)1 );
+
++ // Skip if ButtonPressKeys has Key_Enter
++ const auto buttonPressKeys = QGuiApplicationPrivate::platformTheme()
++ ->themeHint(QPlatformTheme::ButtonPressKeys)
++ .value<QList<Qt::Key>>();
++ if (buttonPressKeys.contains(Qt::Key_Enter)) {
++ return;
++ }
++
+ QTest::keyPress( testWidget,Qt::Key_Enter );
+ QCOMPARE( press_count, (uint)1 );
+ QCOMPARE( release_count, (uint)1 );
+diff --git a/qtbase/tests/auto/widgets/widgets/qgroupbox/qgroupbox.pro b/qtbase/tests/auto/widgets/widgets/qgroupbox/qgroupbox.pro
+index 4a5e76ff65..a235fa1fac 100644
+--- a/qtbase/tests/auto/widgets/widgets/qgroupbox/qgroupbox.pro
++++ b/qtbase/tests/auto/widgets/widgets/qgroupbox/qgroupbox.pro
+@@ -1,6 +1,6 @@
+ CONFIG += testcase
+ TARGET = tst_qgroupbox
+-QT += widgets testlib
++QT += widgets testlib gui-private
+ SOURCES += tst_qgroupbox.cpp
+
+
+diff --git a/qtbase/tests/auto/widgets/widgets/qgroupbox/tst_qgroupbox.cpp b/qtbase/tests/auto/widgets/widgets/qgroupbox/tst_qgroupbox.cpp
+index 4fb5d262ca..d8d7562b73 100644
+--- a/qtbase/tests/auto/widgets/widgets/qgroupbox/tst_qgroupbox.cpp
++++ b/qtbase/tests/auto/widgets/widgets/qgroupbox/tst_qgroupbox.cpp
+@@ -35,6 +35,9 @@
+ #include <QRadioButton>
+ #include <QDialog>
+
++#include <private/qguiapplication_p.h>
++#include <qpa/qplatformtheme.h>
++
+ #include "qgroupbox.h"
+
+ class tst_QGroupBox : public QObject
+@@ -69,6 +72,7 @@ private slots:
+ void propagateFocus();
+ void task_QTBUG_19170_ignoreMouseReleaseEvent();
+ void task_QTBUG_15519_propagateMouseEvents();
++ void buttonPressKeys();
+
+ private:
+ bool checked;
+@@ -610,6 +614,20 @@ void tst_QGroupBox::task_QTBUG_15519_propagateMouseEvents()
+ QCOMPARE(parent.mouseMoved, true);
+ }
+
++void tst_QGroupBox::buttonPressKeys()
++{
++ QGroupBox groupBox;
++ groupBox.setCheckable(true);
++ QSignalSpy clickedSpy(&groupBox, &QGroupBox::clicked);
++ const auto buttonPressKeys = QGuiApplicationPrivate::platformTheme()
++ ->themeHint(QPlatformTheme::ButtonPressKeys)
++ .value<QList<Qt::Key>>();
++ for (int i = 0; i < buttonPressKeys.length(); ++i) {
++ QTest::keyClick(&groupBox, buttonPressKeys[i]);
++ QCOMPARE(clickedSpy.length(), i + 1);
++ }
++}
++
+ void tst_QGroupBox::sendMouseMoveEvent(QWidget *widget, const QPoint &localPos)
+ {
+ // Send a MouseMove event without actually moving the pointer
+diff --git a/qtbase/tests/auto/widgets/widgets/qpushbutton/qpushbutton.pro b/qtbase/tests/auto/widgets/widgets/qpushbutton/qpushbutton.pro
+index 353ad06ca2..e55f6148f2 100644
+--- a/qtbase/tests/auto/widgets/widgets/qpushbutton/qpushbutton.pro
++++ b/qtbase/tests/auto/widgets/widgets/qpushbutton/qpushbutton.pro
+@@ -1,6 +1,6 @@
+ CONFIG += testcase
+ TARGET = tst_qpushbutton
+-QT += widgets testlib
++QT += widgets testlib gui-private
+ SOURCES += tst_qpushbutton.cpp
+
+
+diff --git a/qtbase/tests/auto/widgets/widgets/qpushbutton/tst_qpushbutton.cpp b/qtbase/tests/auto/widgets/widgets/qpushbutton/tst_qpushbutton.cpp
+index e818514a79..4043e9326a 100644
+--- a/qtbase/tests/auto/widgets/widgets/qpushbutton/tst_qpushbutton.cpp
++++ b/qtbase/tests/auto/widgets/widgets/qpushbutton/tst_qpushbutton.cpp
+@@ -41,6 +41,9 @@
+ #include <QStyleFactory>
+ #include <QTabWidget>
+
++#include <private/qguiapplication_p.h>
++#include <qpa/qplatformtheme.h>
++
+ class tst_QPushButton : public QObject
+ {
+ Q_OBJECT
+@@ -212,6 +215,13 @@ void tst_QPushButton::autoRepeat()
+ // check that pressing ENTER has no effect
+ resetCounters();
+ testWidget->setDown( false );
++ // Skip after reset if ButtonPressKeys has Key_Enter
++ const auto buttonPressKeys = QGuiApplicationPrivate::platformTheme()
++ ->themeHint(QPlatformTheme::ButtonPressKeys)
++ .value<QList<Qt::Key>>();
++ if (buttonPressKeys.contains(Qt::Key_Enter)) {
++ return;
++ }
+ testWidget->setAutoRepeat( false );
+ QTest::keyPress( testWidget, Qt::Key_Enter );
+
+@@ -247,6 +257,14 @@ void tst_QPushButton::pressed()
+ QCOMPARE( press_count, (uint)1 );
+ QCOMPARE( release_count, (uint)1 );
+
++ // Skip if ButtonPressKeys has Key_Enter
++ const auto buttonPressKeys = QGuiApplicationPrivate::platformTheme()
++ ->themeHint(QPlatformTheme::ButtonPressKeys)
++ .value<QList<Qt::Key>>();
++ if (buttonPressKeys.contains(Qt::Key_Enter)) {
++ return;
++ }
++
+ QTest::keyPress( testWidget,Qt::Key_Enter );
+ QCOMPARE( press_count, (uint)1 );
+ QCOMPARE( release_count, (uint)1 );
+diff --git a/qtbase/tests/manual/rhi/cubemap_render/buildshader.bat b/qtbase/tests/manual/rhi/cubemap_render/buildshader.bat
+old mode 100755
+new mode 100644
+Submodule qtconnectivity e957d481..056294c0:
+diff --git a/qtconnectivity/src/bluetooth/bluez/hcimanager.cpp b/qtconnectivity/src/bluetooth/bluez/hcimanager.cpp
+index e2635fae..a8b8e3b9 100644
+--- a/qtconnectivity/src/bluetooth/bluez/hcimanager.cpp
++++ b/qtconnectivity/src/bluetooth/bluez/hcimanager.cpp
+@@ -563,9 +563,11 @@ void HciManager::handleHciAclPacket(const quint8 *data, int size)
+
+ void HciManager::handleLeMetaEvent(const quint8 *data)
+ {
+- // Spec v4.2, Vol 2, part E, 7.7.65ff
++ // Spec v5.3, Vol 4, part E, 7.7.65.*
+ switch (*data) {
+- case 0x1: {
++ case 0x1: // HCI_LE_Connection_Complete
++ case 0xA: // HCI_LE_Enhanced_Connection_Complete
++ {
+ const quint16 handle = bt_get_le16(data + 2);
+ emit connectionComplete(handle);
+ break;
+diff --git a/qtconnectivity/src/bluetooth/qbluetoothservicediscoveryagent_bluez.cpp b/qtconnectivity/src/bluetooth/qbluetoothservicediscoveryagent_bluez.cpp
+index 6a93143b..4a18cfc7 100644
+--- a/qtconnectivity/src/bluetooth/qbluetoothservicediscoveryagent_bluez.cpp
++++ b/qtconnectivity/src/bluetooth/qbluetoothservicediscoveryagent_bluez.cpp
+@@ -320,7 +320,10 @@ void QBluetoothServiceDiscoveryAgentPrivate::_q_finishSdpScan(QBluetoothServiceD
+ for (const QBluetoothUuid &id : serviceClassUuids) {
+ if (id.minimumSize() == 16) {
+ serviceInfo.setServiceUuid(id);
+- serviceInfo.setServiceName(QBluetoothServiceDiscoveryAgent::tr("Custom Service"));
++ if (serviceInfo.serviceName().isEmpty()) {
++ serviceInfo.setServiceName(
++ QBluetoothServiceDiscoveryAgent::tr("Custom Service"));
++ }
+ QBluetoothServiceInfo::Sequence modSeq =
+ serviceInfo.attribute(QBluetoothServiceInfo::ServiceClassIds).value<QBluetoothServiceInfo::Sequence>();
+ modSeq.removeOne(QVariant::fromValue(id));
+@@ -334,8 +337,10 @@ void QBluetoothServiceDiscoveryAgentPrivate::_q_finishSdpScan(QBluetoothServiceD
+ qCDebug(QT_BT_BLUEZ) << "Discovered services" << discoveredDevices.at(0).address().toString()
+ << serviceInfo.serviceName() << serviceInfo.serviceUuid()
+ << ">>>" << serviceInfo.serviceClassUuids();
+-
+- emit q->serviceDiscovered(serviceInfo);
++ // Use queued connection to allow us finish the service looping; the application
++ // might call stop() when it has detected the service-of-interest.
++ QMetaObject::invokeMethod(q, "serviceDiscovered", Qt::QueuedConnection,
++ Q_ARG(QBluetoothServiceInfo, serviceInfo));
+ }
+ }
+ }
+diff --git a/qtconnectivity/src/bluetooth/qbluetoothsocket.cpp b/qtconnectivity/src/bluetooth/qbluetoothsocket.cpp
+index e4d85447..aadd4755 100644
+--- a/qtconnectivity/src/bluetooth/qbluetoothsocket.cpp
++++ b/qtconnectivity/src/bluetooth/qbluetoothsocket.cpp
+@@ -593,7 +593,7 @@ void QBluetoothSocket::setSocketState(QBluetoothSocket::SocketState state)
+ bool QBluetoothSocket::canReadLine() const
+ {
+ Q_D(const QBluetoothSocketBase);
+- return d->canReadLine();
++ return d->canReadLine() || QIODevice::canReadLine();
+ }
+
+ /*!
+diff --git a/qtconnectivity/src/bluetooth/qbluetoothsocket_bluezdbus.cpp b/qtconnectivity/src/bluetooth/qbluetoothsocket_bluezdbus.cpp
+index 084aa958..d6aa17a7 100644
+--- a/qtconnectivity/src/bluetooth/qbluetoothsocket_bluezdbus.cpp
++++ b/qtconnectivity/src/bluetooth/qbluetoothsocket_bluezdbus.cpp
+@@ -284,6 +284,10 @@ void QBluetoothSocketPrivateBluezDBus::connectToService(
+ return;
+ }
+
++ if (service.socketProtocol() != QBluetoothServiceInfo::Protocol::UnknownProtocol)
++ socketType = service.socketProtocol();
++ qCDebug(QT_BT_BLUEZ) << "Socket protocol used:" << socketType;
++
+ connectToService(service.device().address(), targetService, openMode);
+ }
+
+diff --git a/qtconnectivity/tests/auto/qbluetoothsocket/tst_qbluetoothsocket.cpp b/qtconnectivity/tests/auto/qbluetoothsocket/tst_qbluetoothsocket.cpp
+index 05bc1a0f..a7b5ef1f 100644
+--- a/qtconnectivity/tests/auto/qbluetoothsocket/tst_qbluetoothsocket.cpp
++++ b/qtconnectivity/tests/auto/qbluetoothsocket/tst_qbluetoothsocket.cpp
+@@ -142,7 +142,7 @@ void tst_QBluetoothSocket::initTestCase()
+ qDebug() << "Starting discovery";
+
+ sda->setUuidFilter(QBluetoothUuid(QString(TEST_SERVICE_UUID)));
+- sda->start(QBluetoothServiceDiscoveryAgent::MinimalDiscovery);
++ sda->start(QBluetoothServiceDiscoveryAgent::FullDiscovery);
+
+ for (int connectTime = MaxConnectTime; !done_discovery && connectTime > 0; connectTime -= 1000)
+ QTest::qWait(1000);
+Submodule qtdeclarative f5701f0d..8defe7bf:
+diff --git a/qtdeclarative/src/qml/common/qqmljsfixedpoolarray_p.h b/qtdeclarative/src/qml/common/qqmljsfixedpoolarray_p.h
+index b65b994d6c..15a8cd6878 100644
+--- a/qtdeclarative/src/qml/common/qqmljsfixedpoolarray_p.h
++++ b/qtdeclarative/src/qml/common/qqmljsfixedpoolarray_p.h
+@@ -86,7 +86,7 @@ public:
+ if (QTypeInfo<T>::isComplex) {
+ for (int i = 0; i < count; ++i)
+ new (data + i) T(vector.at(i));
+- } else {
++ } else if (count) {
+ memcpy(data, static_cast<const void*>(vector.constData()), count * sizeof(T));
+ }
+ }
+diff --git a/qtdeclarative/src/qml/jsruntime/qv4qobjectwrapper.cpp b/qtdeclarative/src/qml/jsruntime/qv4qobjectwrapper.cpp
+index e57cdd8278..94613598af 100644
+--- a/qtdeclarative/src/qml/jsruntime/qv4qobjectwrapper.cpp
++++ b/qtdeclarative/src/qml/jsruntime/qv4qobjectwrapper.cpp
+@@ -1145,8 +1145,7 @@ void Heap::QObjectWrapper::markObjects(Heap::Base *that, QV4::MarkStack *markSta
+ void QObjectWrapper::destroyObject(bool lastCall)
+ {
+ Heap::QObjectWrapper *h = d();
+- if (!h->internalClass)
+- return; // destroyObject already got called
++ Q_ASSERT(h->internalClass);
+
+ if (h->object()) {
+ QQmlData *ddata = QQmlData::get(h->object(), false);
+@@ -1176,7 +1175,7 @@ void QObjectWrapper::destroyObject(bool lastCall)
+ }
+ }
+
+- h->~Data();
++ h->destroy();
+ }
+
+
+diff --git a/qtdeclarative/src/qml/memory/qv4mm.cpp b/qtdeclarative/src/qml/memory/qv4mm.cpp
+index 06caf04e5a..da149a67c4 100644
+--- a/qtdeclarative/src/qml/memory/qv4mm.cpp
++++ b/qtdeclarative/src/qml/memory/qv4mm.cpp
+@@ -981,7 +981,7 @@ void MemoryManager::sweep(bool lastSweep, ClassDestroyStatsCallback classCountPt
+
+ if (MultiplyWrappedQObjectMap *multiplyWrappedQObjects = engine->m_multiplyWrappedQObjects) {
+ for (MultiplyWrappedQObjectMap::Iterator it = multiplyWrappedQObjects->begin(); it != multiplyWrappedQObjects->end();) {
+- if (!it.value().isNullOrUndefined())
++ if (it.value().isNullOrUndefined())
+ it = multiplyWrappedQObjects->erase(it);
+ else
+ ++it;
+diff --git a/qtdeclarative/src/qmlmodels/qqmldelegatemodel.cpp b/qtdeclarative/src/qmlmodels/qqmldelegatemodel.cpp
+index 2079a8ed04..a577cb2351 100644
+--- a/qtdeclarative/src/qmlmodels/qqmldelegatemodel.cpp
++++ b/qtdeclarative/src/qmlmodels/qqmldelegatemodel.cpp
+@@ -389,6 +389,12 @@ void QQmlDelegateModelPrivate::connectToAbstractItemModel()
+ q, QQmlDelegateModel, SLOT(_q_rowsRemoved(QModelIndex,int,int)));
+ qmlobject_connect(aim, QAbstractItemModel, SIGNAL(rowsAboutToBeRemoved(QModelIndex,int,int)),
+ q, QQmlDelegateModel, SLOT(_q_rowsAboutToBeRemoved(QModelIndex,int,int)));
++ qmlobject_connect(aim, QAbstractItemModel, SIGNAL(columnsInserted(QModelIndex,int,int)),
++ q, QQmlDelegateModel, SLOT(_q_columnsInserted(QModelIndex,int,int)));
++ qmlobject_connect(aim, QAbstractItemModel, SIGNAL(columnsRemoved(QModelIndex,int,int)),
++ q, QQmlDelegateModel, SLOT(_q_columnsRemoved(QModelIndex,int,int)));
++ qmlobject_connect(aim, QAbstractItemModel, SIGNAL(columnsMoved(QModelIndex,int,int,QModelIndex,int)),
++ q, QQmlDelegateModel, SLOT(_q_columnsMoved(QModelIndex,int,int,QModelIndex,int)));
+ qmlobject_connect(aim, QAbstractItemModel, SIGNAL(dataChanged(QModelIndex,QModelIndex,QVector<int>)),
+ q, QQmlDelegateModel, SLOT(_q_dataChanged(QModelIndex,QModelIndex,QVector<int>)));
+ qmlobject_connect(aim, QAbstractItemModel, SIGNAL(rowsMoved(QModelIndex,int,int,QModelIndex,int)),
+@@ -413,6 +419,12 @@ void QQmlDelegateModelPrivate::disconnectFromAbstractItemModel()
+ q, SLOT(_q_rowsAboutToBeRemoved(QModelIndex,int,int)));
+ QObject::disconnect(aim, SIGNAL(rowsRemoved(QModelIndex,int,int)),
+ q, SLOT(_q_rowsRemoved(QModelIndex,int,int)));
++ QObject::disconnect(aim, SIGNAL(columnsInserted(QModelIndex,int,int)), q,
++ SLOT(_q_columnsInserted(QModelIndex,int,int)));
++ QObject::disconnect(aim, SIGNAL(columnsRemoved(QModelIndex,int,int)), q,
++ SLOT(_q_columnsRemoved(QModelIndex,int,int)));
++ QObject::disconnect(aim, SIGNAL(columnsMoved(QModelIndex,int,int,QModelIndex,int)), q,
++ SLOT(_q_columnsMoved(QModelIndex,int,int,QModelIndex,int)));
+ QObject::disconnect(aim, SIGNAL(dataChanged(QModelIndex,QModelIndex,QVector<int>)),
+ q, SLOT(_q_dataChanged(QModelIndex,QModelIndex,QVector<int>)));
+ QObject::disconnect(aim, SIGNAL(rowsMoved(QModelIndex,int,int,QModelIndex,int)),
+@@ -1973,6 +1985,38 @@ void QQmlDelegateModel::_q_rowsMoved(
+ }
+ }
+
++void QQmlDelegateModel::_q_columnsInserted(const QModelIndex &parent, int begin, int end)
++{
++ Q_D(QQmlDelegateModel);
++ Q_UNUSED(end);
++ if (parent == d->m_adaptorModel.rootIndex && begin == 0) {
++ // mark all items as changed
++ _q_itemsChanged(0, d->m_count, QVector<int>());
++ }
++}
++
++void QQmlDelegateModel::_q_columnsRemoved(const QModelIndex &parent, int begin, int end)
++{
++ Q_D(QQmlDelegateModel);
++ Q_UNUSED(end);
++ if (parent == d->m_adaptorModel.rootIndex && begin == 0) {
++ // mark all items as changed
++ _q_itemsChanged(0, d->m_count, QVector<int>());
++ }
++}
++
++void QQmlDelegateModel::_q_columnsMoved(const QModelIndex &parent, int start, int end,
++ const QModelIndex &destination, int column)
++{
++ Q_D(QQmlDelegateModel);
++ Q_UNUSED(end);
++ if ((parent == d->m_adaptorModel.rootIndex && start == 0)
++ || (destination == d->m_adaptorModel.rootIndex && column == 0)) {
++ // mark all items as changed
++ _q_itemsChanged(0, d->m_count, QVector<int>());
++ }
++}
++
+ void QQmlDelegateModel::_q_dataChanged(const QModelIndex &begin, const QModelIndex &end, const QVector<int> &roles)
+ {
+ Q_D(QQmlDelegateModel);
+diff --git a/qtdeclarative/src/qmlmodels/qqmldelegatemodel_p.h b/qtdeclarative/src/qmlmodels/qqmldelegatemodel_p.h
+index 8aab4badca..d140bfbaaf 100644
+--- a/qtdeclarative/src/qmlmodels/qqmldelegatemodel_p.h
++++ b/qtdeclarative/src/qmlmodels/qqmldelegatemodel_p.h
+@@ -152,6 +152,9 @@ private Q_SLOTS:
+ void _q_itemsMoved(int from, int to, int count);
+ void _q_modelReset();
+ void _q_rowsInserted(const QModelIndex &,int,int);
++ void _q_columnsInserted(const QModelIndex &, int, int);
++ void _q_columnsRemoved(const QModelIndex &, int, int);
++ void _q_columnsMoved(const QModelIndex &, int, int, const QModelIndex &, int);
+ void _q_rowsAboutToBeRemoved(const QModelIndex &parent, int begin, int end);
+ void _q_rowsRemoved(const QModelIndex &,int,int);
+ void _q_rowsMoved(const QModelIndex &, int, int, const QModelIndex &, int);
+diff --git a/qtdeclarative/src/quick/accessible/qaccessiblequickitem.cpp b/qtdeclarative/src/quick/accessible/qaccessiblequickitem.cpp
+index 85719fdc80..78e2ab302c 100644
+--- a/qtdeclarative/src/quick/accessible/qaccessiblequickitem.cpp
++++ b/qtdeclarative/src/quick/accessible/qaccessiblequickitem.cpp
+@@ -46,6 +46,7 @@
+ #include "QtQuick/private/qquicktextinput_p.h"
+ #include "QtQuick/private/qquickaccessibleattached_p.h"
+ #include "QtQuick/qquicktextdocument.h"
++#include "QtQuick/qquickrendercontrol.h"
+ QT_BEGIN_NAMESPACE
+
+ #if QT_CONFIG(accessibility)
+@@ -57,7 +58,19 @@ QAccessibleQuickItem::QAccessibleQuickItem(QQuickItem *item)
+
+ QWindow *QAccessibleQuickItem::window() const
+ {
+- return item()->window();
++ QQuickWindow *window = item()->window();
++
++ // For QQuickWidget the above window will be the offscreen QQuickWindow,
++ // which is not a part of the accessibility tree. Detect this case and
++ // return the window for the QQuickWidget instead.
++ if (window && !window->handle()) {
++ if (QQuickRenderControl *renderControl = QQuickWindowPrivate::get(window)->renderControl) {
++ if (QWindow *renderWindow = renderControl->renderWindow(nullptr))
++ return renderWindow;
++ }
++ }
++
++ return window;
+ }
+
+ int QAccessibleQuickItem::childCount() const
+@@ -113,19 +126,15 @@ QAccessibleInterface *QAccessibleQuickItem::childAt(int x, int y) const
+ QAccessibleInterface *QAccessibleQuickItem::parent() const
+ {
+ QQuickItem *parent = item()->parentItem();
+- QQuickWindow *window = item()->window();
+- QQuickItem *ci = window ? window->contentItem() : nullptr;
++ QQuickWindow *itemWindow = item()->window();
++ QQuickItem *ci = itemWindow ? itemWindow->contentItem() : nullptr;
+ while (parent && !QQuickItemPrivate::get(parent)->isAccessible && parent != ci)
+ parent = parent->parentItem();
+
+ if (parent) {
+ if (parent == ci) {
+- // Jump out to the scene widget if the parent is the root item.
+- // There are two root items, QQuickWindow::rootItem and
+- // QQuickView::declarativeRoot. The former is the true root item,
+- // but is not a part of the accessibility tree. Check if we hit
+- // it here and return an interface for the scene instead.
+- return QAccessible::queryAccessibleInterface(window);
++ // Jump out to the window if the parent is the root item
++ return QAccessible::queryAccessibleInterface(window());
+ } else {
+ while (parent && !parent->d_func()->isAccessible)
+ parent = parent->parentItem();
+@@ -188,7 +197,7 @@ QAccessible::State QAccessibleQuickItem::state() const
+ QRect viewRect_ = viewRect();
+ QRect itemRect = rect();
+
+- if (viewRect_.isNull() || itemRect.isNull() || !item()->window() || !item()->window()->isVisible() ||!item()->isVisible() || qFuzzyIsNull(item()->opacity()))
++ if (viewRect_.isNull() || itemRect.isNull() || !window() || !window()->isVisible() ||!item()->isVisible() || qFuzzyIsNull(item()->opacity()))
+ state.invisible = true;
+ if (!viewRect_.intersects(itemRect))
+ state.offscreen = true;
+@@ -201,6 +210,10 @@ QAccessible::State QAccessibleQuickItem::state() const
+ if (role() == QAccessible::EditableText)
+ if (auto ti = qobject_cast<QQuickTextInput *>(item()))
+ state.passwordEdit = ti->echoMode() != QQuickTextInput::Normal;
++ if (!item()->isEnabled()) {
++ state.focusable = false;
++ state.disabled = true;
++ }
+ return state;
+ }
+
+diff --git a/qtdeclarative/src/quick/accessible/qaccessiblequickview_p.h b/qtdeclarative/src/quick/accessible/qaccessiblequickview_p.h
+index 39ffcaf39c..8baa01330c 100644
+--- a/qtdeclarative/src/quick/accessible/qaccessiblequickview_p.h
++++ b/qtdeclarative/src/quick/accessible/qaccessiblequickview_p.h
+@@ -58,7 +58,7 @@ QT_BEGIN_NAMESPACE
+
+ #if QT_CONFIG(accessibility)
+
+-class QAccessibleQuickWindow : public QAccessibleObject
++class Q_QUICK_EXPORT QAccessibleQuickWindow : public QAccessibleObject
+ {
+ public:
+ QAccessibleQuickWindow(QQuickWindow *object);
+diff --git a/qtdeclarative/src/quick/items/qquickdrag.cpp b/qtdeclarative/src/quick/items/qquickdrag.cpp
+index 8321fcfeed..383078b3b9 100644
+--- a/qtdeclarative/src/quick/items/qquickdrag.cpp
++++ b/qtdeclarative/src/quick/items/qquickdrag.cpp
+@@ -481,7 +481,9 @@ void QQuickDragAttached::setKeys(const QStringList &keys)
+ \qmlattachedproperty stringlist QtQuick::Drag::mimeData
+ \since 5.2
+
+- This property holds a map of mimeData that is used during startDrag.
++ This property holds a map from mime type to data that is used during startDrag.
++ The mime data needs to be a \c string, or an \c ArrayBuffer with the data encoded
++ according to the mime type.
+ */
+
+ QVariantMap QQuickDragAttached::mimeData() const
+@@ -766,8 +768,12 @@ Qt::DropAction QQuickDragAttachedPrivate::startDrag(Qt::DropActions supportedAct
+ QDrag *drag = new QDrag(source ? source : q);
+ QMimeData *mimeData = new QMimeData();
+
+- for (auto it = externalMimeData.cbegin(), end = externalMimeData.cend(); it != end; ++it)
+- mimeData->setData(it.key(), it.value().toString().toUtf8());
++ for (auto it = externalMimeData.cbegin(), end = externalMimeData.cend(); it != end; ++it) {
++ if (static_cast<QMetaType::Type>(it.value().type()) == QMetaType::QByteArray)
++ mimeData->setData(it.key(), it.value().toByteArray());
++ else
++ mimeData->setData(it.key(), it.value().toString().toUtf8());
++ }
+
+ drag->setMimeData(mimeData);
+ if (pixmapLoader.isReady()) {
+diff --git a/qtdeclarative/src/quick/items/qquickitem.cpp b/qtdeclarative/src/quick/items/qquickitem.cpp
+index 75f1457816..dec0ae19ae 100644
+--- a/qtdeclarative/src/quick/items/qquickitem.cpp
++++ b/qtdeclarative/src/quick/items/qquickitem.cpp
+@@ -59,6 +59,7 @@
+ #include <QtCore/private/qnumeric_p.h>
+ #include <QtGui/qpa/qplatformtheme.h>
+ #include <QtCore/qloggingcategory.h>
++#include <QtCore/private/qduplicatetracker_p.h>
+
+ #include <private/qqmlglobal_p.h>
+ #include <private/qqmlengine_p.h>
+@@ -2326,6 +2327,7 @@ QQuickItem::QQuickItem(QQuickItemPrivate &dd, QQuickItem *parent)
+ QQuickItem::~QQuickItem()
+ {
+ Q_D(QQuickItem);
++ d->inDestructor = true;
+
+ if (d->windowRefCount > 1)
+ d->windowRefCount = 1; // Make sure window is set to null in next call to derefWindow().
+@@ -2526,6 +2528,7 @@ QQuickItem* QQuickItemPrivate::nextPrevItemInTabFocusChain(QQuickItem *item, boo
+ QQuickItem *current = item;
+ qCDebug(DBG_FOCUS) << "QQuickItemPrivate::nextPrevItemInTabFocusChain: startItem:" << startItem;
+ qCDebug(DBG_FOCUS) << "QQuickItemPrivate::nextPrevItemInTabFocusChain: firstFromItem:" << firstFromItem;
++ QDuplicateTracker<QQuickItem *> cycleDetector;
+ do {
+ qCDebug(DBG_FOCUS) << "QQuickItemPrivate::nextPrevItemInTabFocusChain: current:" << current;
+ qCDebug(DBG_FOCUS) << "QQuickItemPrivate::nextPrevItemInTabFocusChain: from:" << from;
+@@ -2592,7 +2595,10 @@ QQuickItem* QQuickItemPrivate::nextPrevItemInTabFocusChain(QQuickItem *item, boo
+ // traversed all of the chain (by compare the [current] item with [startItem])
+ // Since the [startItem] might be promoted to its parent if it is invisible,
+ // we still have to check [current] item with original start item
+- if ((current == startItem || current == originalStartItem) && from == firstFromItem) {
++ // We might also run into a cycle before we reach firstFromItem again
++ // but note that we have to ignore current if we are meant to skip it
++ if (((current == startItem || current == originalStartItem) && from == firstFromItem) ||
++ (!skip && cycleDetector.hasSeen(current))) {
+ // wrapped around, avoid endless loops
+ if (item == contentItem) {
+ qCDebug(DBG_FOCUS) << "QQuickItemPrivate::nextPrevItemInTabFocusChain: looped, return contentItem";
+@@ -2689,9 +2695,8 @@ void QQuickItem::setParentItem(QQuickItem *parentItem)
+
+ const bool wasVisible = isVisible();
+ op->removeChild(this);
+- if (wasVisible) {
++ if (wasVisible && !op->inDestructor)
+ emit oldParentItem->visibleChildrenChanged();
+- }
+ } else if (d->window) {
+ QQuickWindowPrivate::get(d->window)->parentlessItems.remove(this);
+ }
+@@ -2768,8 +2773,9 @@ void QQuickItem::setParentItem(QQuickItem *parentItem)
+
+ d->itemChange(ItemParentHasChanged, d->parentItem);
+
+- emit parentChanged(d->parentItem);
+- if (isVisible() && d->parentItem)
++ if (!d->inDestructor)
++ emit parentChanged(d->parentItem);
++ if (isVisible() && d->parentItem && !QQuickItemPrivate::get(d->parentItem)->inDestructor)
+ emit d->parentItem->visibleChildrenChanged();
+ }
+
+@@ -2965,7 +2971,8 @@ void QQuickItemPrivate::removeChild(QQuickItem *child)
+
+ itemChange(QQuickItem::ItemChildRemovedChange, child);
+
+- emit q->childrenChanged();
++ if (!inDestructor)
++ emit q->childrenChanged();
+ }
+
+ void QQuickItemPrivate::refWindow(QQuickWindow *c)
+@@ -3194,6 +3201,7 @@ QQuickItemPrivate::QQuickItemPrivate()
+ , touchEnabled(false)
+ #endif
+ , hasCursorHandler(false)
++ , inDestructor(false)
+ , dirtyAttributes(0)
+ , nextDirtyItem(nullptr)
+ , prevDirtyItem(nullptr)
+@@ -5120,6 +5128,13 @@ void QQuickItem::componentComplete()
+ d->addToDirtyList();
+ QQuickWindowPrivate::get(d->window)->dirtyItem(this);
+ }
++
++#if QT_CONFIG(accessibility)
++ if (d->isAccessible && d->effectiveVisible) {
++ QAccessibleEvent ev(this, QAccessible::ObjectShow);
++ QAccessible::updateAccessibility(&ev);
++ }
++#endif
+ }
+
+ QQuickStateGroup *QQuickItemPrivate::_states()
+@@ -6106,9 +6121,11 @@ bool QQuickItemPrivate::setEffectiveVisibleRecur(bool newEffectiveVisible)
+ QAccessible::updateAccessibility(&ev);
+ }
+ #endif
+- emit q->visibleChanged();
+- if (childVisibilityChanged)
+- emit q->visibleChildrenChanged();
++ if (!inDestructor) {
++ emit q->visibleChanged();
++ if (childVisibilityChanged)
++ emit q->visibleChildrenChanged();
++ }
+
+ return true; // effective visibility DID change
+ }
+@@ -6157,6 +6174,15 @@ void QQuickItemPrivate::setEffectiveEnableRecur(QQuickItem *scope, bool newEffec
+ }
+
+ itemChange(QQuickItem::ItemEnabledHasChanged, effectiveEnable);
++#if QT_CONFIG(accessibility)
++ if (isAccessible) {
++ QAccessible::State changedState;
++ changedState.disabled = true;
++ changedState.focusable = true;
++ QAccessibleStateChangeEvent ev(q, changedState);
++ QAccessible::updateAccessibility(&ev);
++ }
++#endif
+ emit q->enabledChanged();
+ }
+
+diff --git a/qtdeclarative/src/quick/items/qquickitem_p.h b/qtdeclarative/src/quick/items/qquickitem_p.h
+index 841d91bb40..ade8fb61f2 100644
+--- a/qtdeclarative/src/quick/items/qquickitem_p.h
++++ b/qtdeclarative/src/quick/items/qquickitem_p.h
+@@ -472,6 +472,7 @@ public:
+ bool replayingPressEvent:1;
+ bool touchEnabled:1;
+ bool hasCursorHandler:1;
++ quint32 inDestructor:1; // has entered ~QQuickItem
+
+ enum DirtyType {
+ TransformOrigin = 0x00000001,
+diff --git a/qtdeclarative/src/quick/items/qquickitemview.cpp b/qtdeclarative/src/quick/items/qquickitemview.cpp
+index 010a0152e1..f8ad168a17 100644
+--- a/qtdeclarative/src/quick/items/qquickitemview.cpp
++++ b/qtdeclarative/src/quick/items/qquickitemview.cpp
+@@ -1785,7 +1785,7 @@ void QQuickItemViewPrivate::refill(qreal from, qreal to)
+
+ do {
+ bufferPause.stop();
+- if (currentChanges.hasPendingChanges() || bufferedChanges.hasPendingChanges()) {
++ if (currentChanges.hasPendingChanges() || bufferedChanges.hasPendingChanges() || currentChanges.active) {
+ currentChanges.reset();
+ bufferedChanges.reset();
+ releaseVisibleItems(reusableFlag);
+diff --git a/qtdeclarative/src/quick/items/qquickmousearea_p_p.h b/qtdeclarative/src/quick/items/qquickmousearea_p_p.h
+index fba383e268..0d63618622 100644
+--- a/qtdeclarative/src/quick/items/qquickmousearea_p_p.h
++++ b/qtdeclarative/src/quick/items/qquickmousearea_p_p.h
+@@ -61,7 +61,6 @@ QT_BEGIN_NAMESPACE
+
+ class QQuickMouseEvent;
+ class QQuickMouseArea;
+-class QQuickPointerMask;
+ class QQuickMouseAreaPrivate : public QQuickItemPrivate
+ {
+ Q_DECLARE_PUBLIC(QQuickMouseArea)
+@@ -100,7 +99,6 @@ public:
+ #if QT_CONFIG(quick_draganddrop)
+ QQuickDrag *drag;
+ #endif
+- QPointer<QQuickPointerMask> mask;
+ QPointF startScene;
+ QPointF targetStartPos;
+ QPointF lastPos;
+diff --git a/qtdeclarative/src/quick/items/qquicktext.cpp b/qtdeclarative/src/quick/items/qquicktext.cpp
+index 6230186933..e823ca1095 100644
+--- a/qtdeclarative/src/quick/items/qquicktext.cpp
++++ b/qtdeclarative/src/quick/items/qquicktext.cpp
+@@ -2168,7 +2168,7 @@ void QQuickText::resetMaximumLineCount()
+ <img src="" align="top,middle,bottom" width="" height=""> - inline images
+ <ol type="">, <ul type=""> and <li> - ordered and unordered lists
+ <pre></pre> - preformatted
+- > < &
++ > < & " '
+ \endcode
+
+ \c Text.StyledText parser is strict, requiring tags to be correctly nested.
+diff --git a/qtdeclarative/src/quick/scenegraph/qsgrhidistancefieldglyphcache.cpp b/qtdeclarative/src/quick/scenegraph/qsgrhidistancefieldglyphcache.cpp
+index eb4db0f85e..2325a2665b 100644
+--- a/qtdeclarative/src/quick/scenegraph/qsgrhidistancefieldglyphcache.cpp
++++ b/qtdeclarative/src/quick/scenegraph/qsgrhidistancefieldglyphcache.cpp
+@@ -446,7 +446,7 @@ bool QSGRhiDistanceFieldGlyphCache::loadPregeneratedCache(const QRawFont &font)
+
+ const char *textureRecord = allocatorData;
+ for (int i = 0; i < textureCount; ++i, textureRecord += Qtdf::TextureRecordSize) {
+- if (textureRecord + Qtdf::TextureRecordSize > qtdfTableEnd) {
++ if (qtdfTableEnd - textureRecord < Qtdf::TextureRecordSize) {
+ qWarning("qtdf table too small in font '%s'.",
+ qPrintable(font.familyName()));
+ return false;
+@@ -462,7 +462,7 @@ bool QSGRhiDistanceFieldGlyphCache::loadPregeneratedCache(const QRawFont &font)
+
+ const char *glyphRecord = textureRecord;
+ for (quint32 i = 0; i < glyphCount; ++i, glyphRecord += Qtdf::GlyphRecordSize) {
+- if (glyphRecord + Qtdf::GlyphRecordSize > qtdfTableEnd) {
++ if (qtdfTableEnd - glyphRecord < Qtdf:: GlyphRecordSize) {
+ qWarning("qtdf table too small in font '%s'.",
+ qPrintable(font.familyName()));
+ return false;
+@@ -512,8 +512,8 @@ bool QSGRhiDistanceFieldGlyphCache::loadPregeneratedCache(const QRawFont &font)
+
+ int width = texInfo->allocatedArea.width();
+ int height = texInfo->allocatedArea.height();
+- qint64 size = width * height;
+- if (reinterpret_cast<const char *>(textureData + size) > qtdfTableEnd) {
++ qint64 size = qint64(width) * height;
++ if (qtdfTableEnd - reinterpret_cast<const char *>(textureData) < size) {
+ qWarning("qtdf table too small in font '%s'.",
+ qPrintable(font.familyName()));
+ return false;
+diff --git a/qtdeclarative/src/quick/util/qquickstyledtext.cpp b/qtdeclarative/src/quick/util/qquickstyledtext.cpp
+index d531fc9205..a25af90414 100644
+--- a/qtdeclarative/src/quick/util/qquickstyledtext.cpp
++++ b/qtdeclarative/src/quick/util/qquickstyledtext.cpp
+@@ -564,6 +564,8 @@ void QQuickStyledTextPrivate::parseEntity(const QChar *&ch, const QString &textI
+ textOut += QChar(60);
+ else if (entity == QLatin1String("amp"))
+ textOut += QChar(38);
++ else if (entity == QLatin1String("apos"))
++ textOut += QChar(39);
+ else if (entity == QLatin1String("quot"))
+ textOut += QChar(34);
+ else if (entity == QLatin1String("nbsp"))
+diff --git a/qtdeclarative/src/quickwidgets/qaccessiblequickwidget.cpp b/qtdeclarative/src/quickwidgets/qaccessiblequickwidget.cpp
+new file mode 100644
+index 0000000000..8a1c901880
+--- /dev/null
++++ b/qtdeclarative/src/quickwidgets/qaccessiblequickwidget.cpp
+@@ -0,0 +1,110 @@
++/****************************************************************************
++**
++** Copyright (C) 2021 The Qt Company Ltd.
++** Contact: https://www.qt.io/licensing/
++**
++** This file is part of the QtQuick module of the Qt Toolkit.
++**
++** $QT_BEGIN_LICENSE:LGPL$
++** Commercial License Usage
++** Licensees holding valid commercial Qt licenses may use this file in
++** accordance with the commercial license agreement provided with the
++** Software or, alternatively, in accordance with the terms contained in
++** a written agreement between you and The Qt Company. For licensing terms
++** and conditions see https://www.qt.io/terms-conditions. For further
++** information use the contact form at https://www.qt.io/contact-us.
++**
++** GNU Lesser General Public License Usage
++** Alternatively, this file may be used under the terms of the GNU Lesser
++** General Public License version 3 as published by the Free Software
++** Foundation and appearing in the file LICENSE.LGPL3 included in the
++** packaging of this file. Please review the following information to
++** ensure the GNU Lesser General Public License version 3 requirements
++** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
++**
++** GNU General Public License Usage
++** Alternatively, this file may be used under the terms of the GNU
++** General Public License version 2.0 or (at your option) the GNU General
++** Public license version 3 or any later version approved by the KDE Free
++** Qt Foundation. The licenses are as published by the Free Software
++** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
++** included in the packaging of this file. Please review the following
++** information to ensure the GNU General Public License requirements will
++** be met: https://www.gnu.org/licenses/gpl-2.0.html and
++** https://www.gnu.org/licenses/gpl-3.0.html.
++**
++** $QT_END_LICENSE$
++**
++****************************************************************************/
++
++#include "qaccessiblequickwidget_p.h"
++
++#include "qquickwidget_p.h"
++
++QT_BEGIN_NAMESPACE
++
++#if QT_CONFIG(accessibility)
++
++QAccessibleQuickWidget::QAccessibleQuickWidget(QQuickWidget* widget)
++: QAccessibleWidget(widget)
++, m_accessibleWindow(QQuickWidgetPrivate::get(widget)->offscreenWindow)
++{
++ // NOTE: m_accessibleWindow is a QAccessibleQuickWindow, and not a
++ // QAccessibleQuickWidgetOffscreenWindow (defined below). This means
++ // it will return the Quick item child interfaces, which is what's needed here
++ // (unlike QAccessibleQuickWidgetOffscreenWindow, which will report 0 children).
++}
++
++QAccessibleInterface *QAccessibleQuickWidget::child(int index) const
++{
++ return m_accessibleWindow.child(index);
++}
++
++int QAccessibleQuickWidget::childCount() const
++{
++ return m_accessibleWindow.childCount();
++}
++
++int QAccessibleQuickWidget::indexOfChild(const QAccessibleInterface *iface) const
++{
++ return m_accessibleWindow.indexOfChild(iface);
++}
++
++QAccessibleInterface *QAccessibleQuickWidget::childAt(int x, int y) const
++{
++ return m_accessibleWindow.childAt(x, y);
++}
++
++QAccessibleQuickWidgetOffscreenWindow::QAccessibleQuickWidgetOffscreenWindow(QQuickWindow *window)
++:QAccessibleQuickWindow(window)
++{
++
++}
++
++QAccessibleInterface *QAccessibleQuickWidgetOffscreenWindow::child(int index) const
++{
++ Q_UNUSED(index);
++ return nullptr;
++}
++
++int QAccessibleQuickWidgetOffscreenWindow::childCount() const
++{
++ return 0;
++}
++
++int QAccessibleQuickWidgetOffscreenWindow::indexOfChild(const QAccessibleInterface *iface) const
++{
++ Q_UNUSED(iface);
++ return -1;
++}
++
++QAccessibleInterface *QAccessibleQuickWidgetOffscreenWindow::QAccessibleQuickWidgetOffscreenWindow::childAt(int x, int y) const
++{
++ Q_UNUSED(x);
++ Q_UNUSED(y);
++ return nullptr;
++}
++
++#endif // accessibility
++
++QT_END_NAMESPACE
+diff --git a/qtdeclarative/src/quickwidgets/qaccessiblequickwidget_p.h b/qtdeclarative/src/quickwidgets/qaccessiblequickwidget_p.h
+new file mode 100644
+index 0000000000..7c2ab930e0
+--- /dev/null
++++ b/qtdeclarative/src/quickwidgets/qaccessiblequickwidget_p.h
+@@ -0,0 +1,95 @@
++/****************************************************************************
++**
++** Copyright (C) 2021 The Qt Company Ltd.
++** Contact: https://www.qt.io/licensing/
++**
++** This file is part of the QtQuick module of the Qt Toolkit.
++**
++** $QT_BEGIN_LICENSE:LGPL$
++** Commercial License Usage
++** Licensees holding valid commercial Qt licenses may use this file in
++** accordance with the commercial license agreement provided with the
++** Software or, alternatively, in accordance with the terms contained in
++** a written agreement between you and The Qt Company. For licensing terms
++** and conditions see https://www.qt.io/terms-conditions. For further
++** information use the contact form at https://www.qt.io/contact-us.
++**
++** GNU Lesser General Public License Usage
++** Alternatively, this file may be used under the terms of the GNU Lesser
++** General Public License version 3 as published by the Free Software
++** Foundation and appearing in the file LICENSE.LGPL3 included in the
++** packaging of this file. Please review the following information to
++** ensure the GNU Lesser General Public License version 3 requirements
++** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
++**
++** GNU General Public License Usage
++** Alternatively, this file may be used under the terms of the GNU
++** General Public License version 2.0 or (at your option) the GNU General
++** Public license version 3 or any later version approved by the KDE Free
++** Qt Foundation. The licenses are as published by the Free Software
++** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
++** included in the packaging of this file. Please review the following
++** information to ensure the GNU General Public License requirements will
++** be met: https://www.gnu.org/licenses/gpl-2.0.html and
++** https://www.gnu.org/licenses/gpl-3.0.html.
++**
++** $QT_END_LICENSE$
++**
++****************************************************************************/
++
++#ifndef QACCESSIBLEQUICKWIDGET_H
++#define QACCESSIBLEQUICKWIDGET_H
++
++//
++// W A R N I N G
++// -------------
++//
++// This file is not part of the Qt API. It exists purely as an
++// implementation detail. This header file may change from version to
++// version without notice, or even be removed.
++//
++// We mean it.
++//
++
++#include "qquickwidget.h"
++#include <QtWidgets/qaccessiblewidget.h>
++
++#include <private/qaccessiblequickview_p.h>
++
++QT_BEGIN_NAMESPACE
++
++#if QT_CONFIG(accessibility)
++
++// These classes implement the QQuickWiget accessibility switcharoo,
++// where the child items of the QQuickWidgetOffscreenWindow are reported
++// as child accessible interfaces of the QAccessibleQuickWidget.
++class QAccessibleQuickWidget: public QAccessibleWidget
++{
++public:
++ QAccessibleQuickWidget(QQuickWidget* widget);
++
++ QAccessibleInterface *child(int index) const override;
++ int childCount() const override;
++ int indexOfChild(const QAccessibleInterface *iface) const override;
++ QAccessibleInterface *childAt(int x, int y) const override;
++
++private:
++ QAccessibleQuickWindow m_accessibleWindow;
++ Q_DISABLE_COPY(QAccessibleQuickWidget)
++};
++
++class QAccessibleQuickWidgetOffscreenWindow: public QAccessibleQuickWindow
++{
++public:
++ QAccessibleQuickWidgetOffscreenWindow(QQuickWindow *window);
++ QAccessibleInterface *child(int index) const override;
++ int childCount() const override;
++ int indexOfChild(const QAccessibleInterface *iface) const override;
++ QAccessibleInterface *childAt(int x, int y) const override;
++};
++
++#endif // accessibility
++
++QT_END_NAMESPACE
++
++#endif
+diff --git a/qtdeclarative/src/quickwidgets/qaccessiblequickwidgetfactory.cpp b/qtdeclarative/src/quickwidgets/qaccessiblequickwidgetfactory.cpp
+new file mode 100644
+index 0000000000..7ba88a1769
+--- /dev/null
++++ b/qtdeclarative/src/quickwidgets/qaccessiblequickwidgetfactory.cpp
+@@ -0,0 +1,60 @@
++/****************************************************************************
++**
++** Copyright (C) 2021 The Qt Company Ltd.
++** Contact: https://www.qt.io/licensing/
++**
++** This file is part of the QtQuick module of the Qt Toolkit.
++**
++** $QT_BEGIN_LICENSE:LGPL$
++** Commercial License Usage
++** Licensees holding valid commercial Qt licenses may use this file in
++** accordance with the commercial license agreement provided with the
++** Software or, alternatively, in accordance with the terms contained in
++** a written agreement between you and The Qt Company. For licensing terms
++** and conditions see https://www.qt.io/terms-conditions. For further
++** information use the contact form at https://www.qt.io/contact-us.
++**
++** GNU Lesser General Public License Usage
++** Alternatively, this file may be used under the terms of the GNU Lesser
++** General Public License version 3 as published by the Free Software
++** Foundation and appearing in the file LICENSE.LGPL3 included in the
++** packaging of this file. Please review the following information to
++** ensure the GNU Lesser General Public License version 3 requirements
++** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
++**
++** GNU General Public License Usage
++** Alternatively, this file may be used under the terms of the GNU
++** General Public License version 2.0 or (at your option) the GNU General
++** Public license version 3 or any later version approved by the KDE Free
++** Qt Foundation. The licenses are as published by the Free Software
++** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
++** included in the packaging of this file. Please review the following
++** information to ensure the GNU General Public License requirements will
++** be met: https://www.gnu.org/licenses/gpl-2.0.html and
++** https://www.gnu.org/licenses/gpl-3.0.html.
++**
++** $QT_END_LICENSE$
++**
++****************************************************************************/
++
++#include "qaccessiblequickwidgetfactory_p.h"
++#include "qaccessiblequickwidget_p.h"
++
++QT_BEGIN_NAMESPACE
++
++#if QT_CONFIG(accessibility)
++
++QAccessibleInterface *qAccessibleQuickWidgetFactory(const QString &classname, QObject *object)
++{
++ if (classname == QLatin1String("QQuickWidget")) {
++ return new QAccessibleQuickWidget(qobject_cast<QQuickWidget *>(object));
++ } else if (classname == QLatin1String("QQuickWidgetOffscreenWindow")) {
++ return new QAccessibleQuickWidgetOffscreenWindow(qobject_cast<QQuickWindow *>(object));
++ }
++ return 0;
++}
++
++#endif // accessibility
++
++QT_END_NAMESPACE
++
+diff --git a/qtdeclarative/src/quickwidgets/qaccessiblequickwidgetfactory_p.h b/qtdeclarative/src/quickwidgets/qaccessiblequickwidgetfactory_p.h
+new file mode 100644
+index 0000000000..8c63b09f81
+--- /dev/null
++++ b/qtdeclarative/src/quickwidgets/qaccessiblequickwidgetfactory_p.h
+@@ -0,0 +1,66 @@
++/****************************************************************************
++**
++** Copyright (C) 2021 The Qt Company Ltd.
++** Contact: https://www.qt.io/licensing/
++**
++** This file is part of the QtQuick module of the Qt Toolkit.
++**
++** $QT_BEGIN_LICENSE:LGPL$
++** Commercial License Usage
++** Licensees holding valid commercial Qt licenses may use this file in
++** accordance with the commercial license agreement provided with the
++** Software or, alternatively, in accordance with the terms contained in
++** a written agreement between you and The Qt Company. For licensing terms
++** and conditions see https://www.qt.io/terms-conditions. For further
++** information use the contact form at https://www.qt.io/contact-us.
++**
++** GNU Lesser General Public License Usage
++** Alternatively, this file may be used under the terms of the GNU Lesser
++** General Public License version 3 as published by the Free Software
++** Foundation and appearing in the file LICENSE.LGPL3 included in the
++** packaging of this file. Please review the following information to
++** ensure the GNU Lesser General Public License version 3 requirements
++** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
++**
++** GNU General Public License Usage
++** Alternatively, this file may be used under the terms of the GNU
++** General Public License version 2.0 or (at your option) the GNU General
++** Public license version 3 or any later version approved by the KDE Free
++** Qt Foundation. The licenses are as published by the Free Software
++** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
++** included in the packaging of this file. Please review the following
++** information to ensure the GNU General Public License requirements will
++** be met: https://www.gnu.org/licenses/gpl-2.0.html and
++** https://www.gnu.org/licenses/gpl-3.0.html.
++**
++** $QT_END_LICENSE$
++**
++****************************************************************************/
++
++#include <QtGui/qaccessible.h>
++
++#ifndef QACCESSIBLEQUICKWIDGETFACTORY_H
++#define QACCESSIBLEQUICKWIDGETFACTORY_H
++
++//
++// W A R N I N G
++// -------------
++//
++// This file is not part of the Qt API. It exists purely as an
++// implementation detail. This header file may change from version to
++// version without notice, or even be removed.
++//
++// We mean it.
++//
++
++QT_BEGIN_NAMESPACE
++
++#if QT_CONFIG(accessibility)
++
++QAccessibleInterface *qAccessibleQuickWidgetFactory(const QString &classname, QObject *object);
++
++#endif
++
++QT_END_NAMESPACE
++
++#endif
+diff --git a/qtdeclarative/src/quickwidgets/qquickwidget.cpp b/qtdeclarative/src/quickwidgets/qquickwidget.cpp
+index 39780f8de3..9c97b43518 100644
+--- a/qtdeclarative/src/quickwidgets/qquickwidget.cpp
++++ b/qtdeclarative/src/quickwidgets/qquickwidget.cpp
+@@ -39,6 +39,7 @@
+
+ #include "qquickwidget.h"
+ #include "qquickwidget_p.h"
++#include "qaccessiblequickwidgetfactory_p.h"
+
+ #include "private/qquickwindow_p.h"
+ #include "private/qquickitem_p.h"
+@@ -75,9 +76,16 @@
+
+ QT_BEGIN_NAMESPACE
+
++QQuickWidgetOffscreenWindow::QQuickWidgetOffscreenWindow(QQuickWindowPrivate &dd, QQuickRenderControl *control)
++:QQuickWindow(dd, control)
++{
++ setTitle(QString::fromLatin1("Offscreen"));
++ setObjectName(QString::fromLatin1("QQuickOffScreenWindow"));
++}
++
+ // override setVisble to prevent accidental offscreen window being created
+ // by base class.
+-class QQuickOffcreenWindowPrivate: public QQuickWindowPrivate {
++class QQuickWidgetOffscreenWindowPrivate: public QQuickWindowPrivate {
+ public:
+ void setVisible(bool visible) override {
+ Q_Q(QWindow);
+@@ -105,9 +113,8 @@ void QQuickWidgetPrivate::init(QQmlEngine* e)
+ Q_Q(QQuickWidget);
+
+ renderControl = new QQuickWidgetRenderControl(q);
+- offscreenWindow = new QQuickWindow(*new QQuickOffcreenWindowPrivate(),renderControl);
+- offscreenWindow->setTitle(QString::fromLatin1("Offscreen"));
+- offscreenWindow->setObjectName(QString::fromLatin1("QQuickOffScreenWindow"));
++ offscreenWindow = new QQuickWidgetOffscreenWindow(*new QQuickWidgetOffscreenWindowPrivate(), renderControl);
++ offscreenWindow->setScreen(q->screen());
+ // Do not call create() on offscreenWindow.
+
+ // Check if the Software Adaptation is being used
+@@ -138,6 +145,10 @@ void QQuickWidgetPrivate::init(QQmlEngine* e)
+ QWidget::connect(offscreenWindow, &QQuickWindow::focusObjectChanged, q, &QQuickWidget::propagateFocusObjectChanged);
+ QObject::connect(renderControl, SIGNAL(renderRequested()), q, SLOT(triggerUpdate()));
+ QObject::connect(renderControl, SIGNAL(sceneChanged()), q, SLOT(triggerUpdate()));
++
++#if QT_CONFIG(accessibility)
++ QAccessible::installFactory(&qAccessibleQuickWidgetFactory);
++#endif
+ }
+
+ void QQuickWidgetPrivate::ensureEngine() const
+@@ -901,9 +912,7 @@ void QQuickWidgetPrivate::createContext()
+
+ context = new QOpenGLContext;
+ context->setFormat(offscreenWindow->requestedFormat());
+- const QWindow *win = q->window()->windowHandle();
+- if (win && win->screen())
+- context->setScreen(win->screen());
++ context->setScreen(q->screen());
+ QOpenGLContext *shareContext = qt_gl_global_share_context();
+ if (!shareContext)
+ shareContext = QWidgetPrivate::get(q->window())->shareContext();
+@@ -1520,19 +1529,16 @@ bool QQuickWidget::event(QEvent *e)
+ d->handleWindowChange();
+ break;
+
+- case QEvent::ScreenChangeInternal:
+- if (QWindow *window = this->window()->windowHandle()) {
+- QScreen *newScreen = window->screen();
+-
+- if (d->offscreenWindow)
+- d->offscreenWindow->setScreen(newScreen);
+- if (d->offscreenSurface)
+- d->offscreenSurface->setScreen(newScreen);
++ case QEvent::ScreenChangeInternal: {
++ QScreen *newScreen = screen();
++ if (d->offscreenWindow)
++ d->offscreenWindow->setScreen(newScreen);
++ if (d->offscreenSurface)
++ d->offscreenSurface->setScreen(newScreen);
+ #if QT_CONFIG(opengl)
+- if (d->context)
+- d->context->setScreen(newScreen);
++ if (d->context)
++ d->context->setScreen(newScreen);
+ #endif
+- }
+
+ if (d->useSoftwareRenderer
+ #if QT_CONFIG(opengl)
+@@ -1545,7 +1551,7 @@ bool QQuickWidget::event(QEvent *e)
+ d->render(true);
+ }
+ break;
+-
++ }
+ case QEvent::Show:
+ case QEvent::Move:
+ d->updatePosition();
+diff --git a/qtdeclarative/src/quickwidgets/qquickwidget_p.h b/qtdeclarative/src/quickwidgets/qquickwidget_p.h
+index 881f7f9220..1a946bcc71 100644
+--- a/qtdeclarative/src/quickwidgets/qquickwidget_p.h
++++ b/qtdeclarative/src/quickwidgets/qquickwidget_p.h
+@@ -148,6 +148,14 @@ public:
+ bool forceFullUpdate;
+ };
+
++class QQuickWidgetOffscreenWindow: public QQuickWindow
++{
++ Q_OBJECT
++
++public:
++ QQuickWidgetOffscreenWindow(QQuickWindowPrivate &dd, QQuickRenderControl *control);
++};
++
+ QT_END_NAMESPACE
+
+ #endif // QQuickWidget_P_H
+diff --git a/qtdeclarative/src/quickwidgets/quickwidgets.pro b/qtdeclarative/src/quickwidgets/quickwidgets.pro
+index 2438e577ae..85d156b8a3 100644
+--- a/qtdeclarative/src/quickwidgets/quickwidgets.pro
++++ b/qtdeclarative/src/quickwidgets/quickwidgets.pro
+@@ -7,9 +7,13 @@ DEFINES += QT_NO_URL_CAST_FROM_STRING QT_NO_INTEGER_EVENT_COORDINATES QT_NO_FO
+ HEADERS += \
+ qquickwidget.h \
+ qquickwidget_p.h \
+- qtquickwidgetsglobal.h
++ qtquickwidgetsglobal.h \
++ qaccessiblequickwidget_p.h \
++ qaccessiblequickwidgetfactory_p.h
+
+ SOURCES += \
+- qquickwidget.cpp
++ qquickwidget.cpp \
++ qaccessiblequickwidget.cpp \
++ qaccessiblequickwidgetfactory.cpp
+
+ load(qt_module)
+diff --git a/qtdeclarative/tests/auto/qml/qjsengine/tst_qjsengine.cpp b/qtdeclarative/tests/auto/qml/qjsengine/tst_qjsengine.cpp
+index 3b7d74df63..b75bf820d5 100644
+--- a/qtdeclarative/tests/auto/qml/qjsengine/tst_qjsengine.cpp
++++ b/qtdeclarative/tests/auto/qml/qjsengine/tst_qjsengine.cpp
+@@ -102,6 +102,7 @@ private slots:
+ void valueConversion_RegularExpression();
+ void castWithMultipleInheritance();
+ void collectGarbage();
++ void collectGarbageNestedWrappersTwoEngines();
+ void gcWithNestedDataStructure();
+ void stacktrace();
+ void numberParsing_data();
+@@ -1809,6 +1810,44 @@ void tst_QJSEngine::collectGarbage()
+ QVERIFY(ptr.isNull());
+ }
+
++class TestObjectContainer : public QObject
++{
++ Q_OBJECT
++ Q_PROPERTY(QObject *dummy MEMBER m_dummy CONSTANT)
++
++public:
++ TestObjectContainer() : m_dummy(new QObject(this)) {}
++
++private:
++ QObject *m_dummy;
++};
++
++void tst_QJSEngine::collectGarbageNestedWrappersTwoEngines()
++{
++ QJSEngine engine1;
++ QJSEngine engine2;
++
++ TestObjectContainer container;
++ QQmlEngine::setObjectOwnership(&container, QQmlEngine::CppOwnership);
++
++ engine1.globalObject().setProperty("foobar", engine1.newQObject(&container));
++ engine2.globalObject().setProperty("foobar", engine2.newQObject(&container));
++
++ engine1.evaluate("foobar.dummy.baz = 42");
++ engine2.evaluate("foobar.dummy.baz = 43");
++
++ QCOMPARE(engine1.evaluate("foobar.dummy.baz").toInt(), 42);
++ QCOMPARE(engine2.evaluate("foobar.dummy.baz").toInt(), 43);
++
++ engine1.collectGarbage();
++ engine2.collectGarbage();
++
++ // The GC should not collect dummy object wrappers neither in engine1 nor engine2, we
++ // verify that by checking whether the baz property still has its previous value.
++ QCOMPARE(engine1.evaluate("foobar.dummy.baz").toInt(), 42);
++ QCOMPARE(engine2.evaluate("foobar.dummy.baz").toInt(), 43);
++}
++
+ void tst_QJSEngine::gcWithNestedDataStructure()
+ {
+ // The GC must be able to traverse deeply nested objects, otherwise this
+diff --git a/qtdeclarative/tests/auto/qml/qqmldelegatemodel/data/redrawUponColumnChange.qml b/qtdeclarative/tests/auto/qml/qqmldelegatemodel/data/redrawUponColumnChange.qml
+new file mode 100644
+index 0000000000..206133bb39
+--- /dev/null
++++ b/qtdeclarative/tests/auto/qml/qqmldelegatemodel/data/redrawUponColumnChange.qml
+@@ -0,0 +1,11 @@
++import QtQuick 2.8
++
++ListView {
++ id: root
++ width: 200
++ height: 200
++
++ delegate: Text {
++ text: display
++ }
++}
+diff --git a/qtdeclarative/tests/auto/qml/qqmldelegatemodel/tst_qqmldelegatemodel.cpp b/qtdeclarative/tests/auto/qml/qqmldelegatemodel/tst_qqmldelegatemodel.cpp
+index 35f1e2c94d..1722447830 100644
+--- a/qtdeclarative/tests/auto/qml/qqmldelegatemodel/tst_qqmldelegatemodel.cpp
++++ b/qtdeclarative/tests/auto/qml/qqmldelegatemodel/tst_qqmldelegatemodel.cpp
+@@ -27,6 +27,8 @@
+ ****************************************************************************/
+
+ #include <QtTest/qtest.h>
++#include <QtCore/QConcatenateTablesProxyModel>
++#include <QtGui/QStandardItemModel>
+ #include <QtQml/qqmlcomponent.h>
+ #include <QtQmlModels/private/qqmldelegatemodel_p.h>
+ #include <QtQuick/qquickview.h>
+@@ -47,6 +49,7 @@ private slots:
+ void filterOnGroup_removeWhenCompleted();
+ void qtbug_86017();
+ void contextAccessedByHandler();
++ void redrawUponColumnChange();
+ };
+
+ class AbstractItemModel : public QAbstractItemModel
+@@ -186,6 +189,30 @@ void tst_QQmlDelegateModel::contextAccessedByHandler()
+ QVERIFY(root->property("works").toBool());
+ }
+
++void tst_QQmlDelegateModel::redrawUponColumnChange()
++{
++ QStandardItemModel m1;
++ m1.appendRow({
++ new QStandardItem("Banana"),
++ new QStandardItem("Coconut"),
++ });
++
++ QQuickView view(testFileUrl("redrawUponColumnChange.qml"));
++ QCOMPARE(view.status(), QQuickView::Ready);
++ view.show();
++ QQuickItem *root = view.rootObject();
++ root->setProperty("model", QVariant::fromValue<QObject *>(&m1));
++
++ QObject *item = root->property("currentItem").value<QObject *>();
++ QVERIFY(item);
++ QCOMPARE(item->property("text").toString(), "Banana");
++
++ QVERIFY(root);
++ m1.removeColumn(0);
++
++ QCOMPARE(item->property("text").toString(), "Coconut");
++}
++
+ QTEST_MAIN(tst_QQmlDelegateModel)
+
+ #include "tst_qqmldelegatemodel.moc"
+diff --git a/qtdeclarative/tests/auto/qml/qv4mm/tst_qv4mm.cpp b/qtdeclarative/tests/auto/qml/qv4mm/tst_qv4mm.cpp
+index 5d635aa63b..824fd89e5b 100644
+--- a/qtdeclarative/tests/auto/qml/qv4mm/tst_qv4mm.cpp
++++ b/qtdeclarative/tests/auto/qml/qv4mm/tst_qv4mm.cpp
+@@ -76,10 +76,10 @@ void tst_qv4mm::multiWrappedQObjects()
+ QCOMPARE(engine1.memoryManager->m_pendingFreedObjectWrapperValue.size(), 1);
+ QCOMPARE(engine2.memoryManager->m_pendingFreedObjectWrapperValue.size(), 0);
+
+- // Moves the additional WeakValue from m_multiplyWrappedQObjects to
+- // m_pendingFreedObjectWrapperValue. It's still alive after all.
++ // The additional WeakValue from m_multiplyWrappedQObjects hasn't been moved
++ // to m_pendingFreedObjectWrapperValue yet. It's still alive after all.
+ engine1.memoryManager->runGC();
+- QCOMPARE(engine1.memoryManager->m_pendingFreedObjectWrapperValue.size(), 2);
++ QCOMPARE(engine1.memoryManager->m_pendingFreedObjectWrapperValue.size(), 1);
+
+ // engine2 doesn't own the object as engine1 was the first to wrap it above.
+ // Therefore, no effect here.
+diff --git a/qtdeclarative/tests/auto/quick/qquickitem2/data/activeFocusOnTab_infiniteLoop3.qml b/qtdeclarative/tests/auto/quick/qquickitem2/data/activeFocusOnTab_infiniteLoop3.qml
+new file mode 100644
+index 0000000000..889e480f3b
+--- /dev/null
++++ b/qtdeclarative/tests/auto/quick/qquickitem2/data/activeFocusOnTab_infiniteLoop3.qml
+@@ -0,0 +1,13 @@
++import QtQuick 2.6
++
++Item {
++ visible: true
++ Item {
++ visible: false
++ Item {
++ objectName: "hiddenChild"
++ activeFocusOnTab: true
++ focus: true
++ }
++ }
++}
+diff --git a/qtdeclarative/tests/auto/quick/qquickitem2/tst_qquickitem.cpp b/qtdeclarative/tests/auto/quick/qquickitem2/tst_qquickitem.cpp
+index c8f251dbe1..c8ef36ee68 100644
+--- a/qtdeclarative/tests/auto/quick/qquickitem2/tst_qquickitem.cpp
++++ b/qtdeclarative/tests/auto/quick/qquickitem2/tst_qquickitem.cpp
+@@ -67,6 +67,7 @@ private slots:
+ void activeFocusOnTab10();
+ void activeFocusOnTab_infiniteLoop_data();
+ void activeFocusOnTab_infiniteLoop();
++ void activeFocusOnTab_infiniteLoopControls();
+
+ void nextItemInFocusChain();
+ void nextItemInFocusChain2();
+@@ -1057,6 +1058,17 @@ void tst_QQuickItem::activeFocusOnTab_infiniteLoop()
+ QCOMPARE(item, window->rootObject());
+ }
+
++
++void tst_QQuickItem::activeFocusOnTab_infiniteLoopControls()
++{
++ auto source = testFileUrl("activeFocusOnTab_infiniteLoop3.qml");
++ QScopedPointer<QQuickView>window(new QQuickView());
++ window->setSource(source);
++ window->show();
++ QVERIFY(window->errors().isEmpty());
++ QTest::keyClick(window.get(), Qt::Key_Tab); // should not hang
++}
++
+ void tst_QQuickItem::nextItemInFocusChain()
+ {
+ if (!qt_tab_all_widgets())
+Submodule qtdoc c0c7bf07...79d6ef69:
+Submodule qtimageformats 2dcf2899..abe44c0f:
+diff --git a/qtimageformats/src/plugins/imageformats/icns/qicnshandler.cpp b/qtimageformats/src/plugins/imageformats/icns/qicnshandler.cpp
+index dde783c..1bf9074 100644
+--- a/qtimageformats/src/plugins/imageformats/icns/qicnshandler.cpp
++++ b/qtimageformats/src/plugins/imageformats/icns/qicnshandler.cpp
+@@ -462,8 +462,12 @@ static bool parseIconEntryInfo(ICNSEntry &icon)
+ if (isIconCompressed(icon))
+ return true;
+ // Icon depth:
+- if (!depth.isEmpty())
+- icon.depth = ICNSEntry::Depth(depth.toUInt());
++ if (!depth.isEmpty()) {
++ const uint depthUInt = depth.toUInt();
++ if (depthUInt > 32)
++ return false;
++ icon.depth = ICNSEntry::Depth(depthUInt);
++ }
+ // Try mono if depth not found
+ if (icon.depth == ICNSEntry::DepthUnknown)
+ icon.depth = ICNSEntry::DepthMono;
+@@ -515,6 +519,9 @@ static bool parseIconEntryInfo(ICNSEntry &icon)
+ }
+ icon.height = icon.width;
+ }
++ // Sanity check
++ if (icon.width == 0 || icon.width > 4096)
++ return false;
+ return true;
+ }
+
+@@ -685,7 +692,7 @@ bool QICNSHandler::canRead() const
+ bool QICNSHandler::read(QImage *outImage)
+ {
+ QImage img;
+- if (!ensureScanned()) {
++ if (!ensureScanned() || m_currentIconIndex >= m_icons.size()) {
+ qWarning("QICNSHandler::read(): The device wasn't parsed properly!");
+ return false;
+ }
+@@ -892,7 +899,7 @@ bool QICNSHandler::scanDevice()
+ return false;
+
+ const qint64 blockDataOffset = device()->pos();
+- if (!isBlockHeaderValid(blockHeader)) {
++ if (!isBlockHeaderValid(blockHeader, ICNSBlockHeaderSize + filelength - blockDataOffset)) {
+ qWarning("QICNSHandler::scanDevice(): Failed, bad header at pos %s. OSType \"%s\", length %u",
+ QByteArray::number(blockDataOffset).constData(),
+ nameFromOSType(blockHeader.ostype).constData(), blockHeader.length);
+@@ -927,11 +934,14 @@ bool QICNSHandler::scanDevice()
+ case ICNSBlockHeader::TypeOdrp:
+ // Icns container seems to have an embedded icon variant container
+ // Let's start a scan for entries
+- while (device()->pos() < nextBlockOffset) {
++ while (!stream.atEnd() && device()->pos() < nextBlockOffset) {
+ ICNSBlockHeader icon;
+ stream >> icon;
++ if (stream.status() != QDataStream::Ok)
++ return false;
+ // Check for incorrect variant entry header and stop scan
+- if (!isBlockHeaderValid(icon, blockDataLength))
++ quint64 remaining = blockDataLength - (device()->pos() - blockDataOffset);
++ if (!isBlockHeaderValid(icon, ICNSBlockHeaderSize + remaining))
+ break;
+ if (!addEntry(icon, device()->pos(), blockHeader.ostype))
+ return false;
+@@ -1003,7 +1013,7 @@ bool QICNSHandler::scanDevice()
+ break;
+ }
+ }
+- return true;
++ return (m_icons.size() > 0);
+ }
+
+ const ICNSEntry &QICNSHandler::getIconMask(const ICNSEntry &icon) const
+diff --git a/qtimageformats/src/plugins/imageformats/jp2/qjp2handler.cpp b/qtimageformats/src/plugins/imageformats/jp2/qjp2handler.cpp
+index 5082023..cb34374 100644
+--- a/qtimageformats/src/plugins/imageformats/jp2/qjp2handler.cpp
++++ b/qtimageformats/src/plugins/imageformats/jp2/qjp2handler.cpp
+@@ -43,6 +43,7 @@
+ #include "qimage.h"
+ #include "qvariant.h"
+ #include "qcolor.h"
++#include "qimagereader.h"
+
+ #include <jasper/jasper.h>
+ #include <math.h> // for pow
+@@ -333,16 +334,46 @@ private:
+ Jpeg2000JasperReader::Jpeg2000JasperReader(QIODevice *iod, SubFormat format)
+ : jasperOk(true), ioDevice(iod), format(format), hasAlpha(false)
+ {
++#if JAS_VERSION_MAJOR < 3
+ if (jas_init()) {
+ jasperOk = false;
+ qDebug("Jasper Library initialization failed");
+ }
++#else
++ jas_conf_clear();
++#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
++ jas_conf_set_max_mem_usage(QImageReader::allocationLimit() * 1024 * 1024);
++#else
++ // 128MB seems to be enough.
++ jas_conf_set_max_mem_usage(128 * 1024 * 1024);
++#endif
++ if (jas_init_library()) {
++ jasperOk = false;
++ qDebug("Jasper library initialization failed");
++ }
++ if (jas_init_thread()) {
++ jas_cleanup_library();
++ jasperOk = false;
++ qDebug("Jasper thread initialization failed");
++ }
++#endif
+ }
+
+ Jpeg2000JasperReader::~Jpeg2000JasperReader()
+ {
++#if JAS_VERSION_MAJOR < 3
+ if (jasperOk)
+ jas_cleanup();
++#else
++ if (jasperOk) {
++ if (jas_cleanup_thread()) {
++ qDebug("Jasper thread cleanup failed");
++ }
++ if (jas_cleanup_library()) {
++ qDebug("Jasper library cleanup failed");
++ }
++ }
++#endif
+ }
+
+ /*! \internal
+@@ -857,7 +888,7 @@ bool Jpeg2000JasperReader::write(const QImage &image, int quality)
+ }
+
+ // Open an empty jasper stream that grows automatically
+- jas_stream_t * memory_stream = jas_stream_memopen(0, -1);
++ jas_stream_t * memory_stream = jas_stream_memopen(0, 0);
+
+ // Jasper wants a non-const string.
+ char *str = qstrdup(jasperFormatString.toLatin1().constData());
+diff --git a/qtimageformats/src/plugins/imageformats/tiff/qtiffhandler.cpp b/qtimageformats/src/plugins/imageformats/tiff/qtiffhandler.cpp
+index 1386750..ac8956c 100644
+--- a/qtimageformats/src/plugins/imageformats/tiff/qtiffhandler.cpp
++++ b/qtimageformats/src/plugins/imageformats/tiff/qtiffhandler.cpp
+@@ -361,6 +361,8 @@ bool QTiffHandler::read(QImage *image)
+ }
+
+ TIFF *const tiff = d->tiff;
++ if (TIFFIsTiled(tiff) && TIFFTileSize64(tiff) > uint64_t(image->sizeInBytes())) // Corrupt image
++ return false;
+ const quint32 width = d->size.width();
+ const quint32 height = d->size.height();
+
+diff --git a/qtimageformats/src/plugins/imageformats/webp/qwebphandler.cpp b/qtimageformats/src/plugins/imageformats/webp/qwebphandler.cpp
+index 82d38cb..d02eb05 100644
+--- a/qtimageformats/src/plugins/imageformats/webp/qwebphandler.cpp
++++ b/qtimageformats/src/plugins/imageformats/webp/qwebphandler.cpp
+@@ -45,6 +45,7 @@
+ #include <qdebug.h>
+ #include <qpainter.h>
+ #include <qvariant.h>
++#include <QtEndian>
+
+ static const int riffHeaderSize = 12; // RIFF_HEADER_SIZE from webp/format_constants.h
+
+@@ -102,21 +103,23 @@ bool QWebpHandler::ensureScanned() const
+
+ m_scanState = ScanError;
+
+- if (device()->isSequential()) {
+- qWarning() << "Sequential devices are not supported";
++ QWebpHandler *that = const_cast<QWebpHandler *>(this);
++ const int headerBytesNeeded = sizeof(WebPBitstreamFeatures);
++ QByteArray header = device()->peek(headerBytesNeeded);
++ if (header.size() < headerBytesNeeded)
+ return false;
+- }
+
+- qint64 oldPos = device()->pos();
+- device()->seek(0);
+-
+- QWebpHandler *that = const_cast<QWebpHandler *>(this);
+- QByteArray header = device()->peek(sizeof(WebPBitstreamFeatures));
++ // We do no random access during decoding, just a readAll() of the whole image file. So if
++ // if it is all available already, we can accept a sequential device. The riff header contains
++ // the file size minus 8 bytes header
++ qint64 byteSize = qFromLittleEndian<quint32>(header.constData() + 4);
++ if (device()->isSequential() && device()->bytesAvailable() < byteSize + 8) {
++ qWarning() << "QWebpHandler: Insufficient data available in sequential device";
++ return false;
++ }
+ if (WebPGetFeatures((const uint8_t*)header.constData(), header.size(), &(that->m_features)) == VP8_STATUS_OK) {
+ if (m_features.has_animation) {
+ // For animation, we have to read and scan whole file to determine loop count and images count
+- device()->seek(oldPos);
+-
+ if (that->ensureDemuxer()) {
+ that->m_loop = WebPDemuxGetI(m_demuxer, WEBP_FF_LOOP_COUNT);
+ that->m_frameCount = WebPDemuxGetI(m_demuxer, WEBP_FF_FRAME_COUNT);
+@@ -126,17 +129,13 @@ bool QWebpHandler::ensureScanned() const
+ if (that->m_features.has_alpha)
+ that->m_composited->fill(Qt::transparent);
+
+- // We do not reset device position since we have read in all data
+ m_scanState = ScanSuccess;
+- return true;
+ }
+ } else {
+ m_scanState = ScanSuccess;
+ }
+ }
+
+- device()->seek(oldPos);
+-
+ return m_scanState == ScanSuccess;
+ }
+
+@@ -159,7 +158,7 @@ bool QWebpHandler::ensureDemuxer()
+
+ bool QWebpHandler::read(QImage *image)
+ {
+- if (!ensureScanned() || device()->isSequential() || !ensureDemuxer())
++ if (!ensureScanned() || !ensureDemuxer())
+ return false;
+
+ QRect prevFrameRect;
+Submodule qtlocation 98a5c511..f991e28c:
+diff --git a/qtlocation/src/location/configure.json b/qtlocation/src/location/configure.json
+index 6d01a9a3..d1e623a1 100644
+--- a/qtlocation/src/location/configure.json
++++ b/qtlocation/src/location/configure.json
+@@ -9,7 +9,7 @@
+ "label": "Qt.labs.location experimental QML plugin",
+ "purpose": "Provides experimental QtLocation QML types",
+ "section": "Location",
+- "condition": "config.opengl",
++ "condition": "features.opengl",
+ "output": [ "privateFeature" ]
+ },
+ "geoservices_osm": {
+diff --git a/qtlocation/src/location/labs/qsg/qgeomapobjectqsgsupport.cpp b/qtlocation/src/location/labs/qsg/qgeomapobjectqsgsupport.cpp
+index a978573d..11e1466f 100644
+--- a/qtlocation/src/location/labs/qsg/qgeomapobjectqsgsupport.cpp
++++ b/qtlocation/src/location/labs/qsg/qgeomapobjectqsgsupport.cpp
+@@ -158,7 +158,7 @@ void QGeoMapObjectQSGSupport::updateMapObjects(QSGNode *root, QQuickWindow *wind
+ if (!root)
+ return;
+
+- if (m_mapObjectsRootNode && m_mapObjectsRootNode->parent())
++ if (m_mapObjectsRootNode && !m_mapObjectsRootNode->parent())
+ root->appendChildNode(m_mapObjectsRootNode.get());
+
+ if (!m_mapObjectsRootNode) {
+diff --git a/qtlocation/src/plugins/geoservices/esri/geocodingmanagerengine_esri.cpp b/qtlocation/src/plugins/geoservices/esri/geocodingmanagerengine_esri.cpp
+index 5a40467e..d123c6a8 100644
+--- a/qtlocation/src/plugins/geoservices/esri/geocodingmanagerengine_esri.cpp
++++ b/qtlocation/src/plugins/geoservices/esri/geocodingmanagerengine_esri.cpp
+@@ -59,8 +59,10 @@ QT_BEGIN_NAMESPACE
+ static const QString kPrefixEsri(QStringLiteral("esri."));
+ static const QString kParamUserAgent(kPrefixEsri + QStringLiteral("useragent"));
+
+-static const QString kUrlGeocode(QStringLiteral("http://geocode.arcgis.com/arcgis/rest/services/World/GeocodeServer/findAddressCandidates"));
+-static const QString kUrlReverseGeocode(QStringLiteral("http://geocode.arcgis.com/arcgis/rest/services/World/GeocodeServer/reverseGeocode"));
++static const QString kUrlGeocode(QStringLiteral("https://geocode.arcgis.com/arcgis/rest/services/"
++ "World/GeocodeServer/findAddressCandidates"));
++static const QString kUrlReverseGeocode(QStringLiteral(
++ "https://geocode.arcgis.com/arcgis/rest/services/World/GeocodeServer/reverseGeocode"));
+
+ static QString addressToQuery(const QGeoAddress &address)
+ {
+diff --git a/qtlocation/src/plugins/geoservices/esri/georoutejsonparser_esri.cpp b/qtlocation/src/plugins/geoservices/esri/georoutejsonparser_esri.cpp
+index 17492d94..96c12b1b 100644
+--- a/qtlocation/src/plugins/geoservices/esri/georoutejsonparser_esri.cpp
++++ b/qtlocation/src/plugins/geoservices/esri/georoutejsonparser_esri.cpp
+@@ -46,7 +46,8 @@
+
+ QT_BEGIN_NAMESPACE
+
+-// JSON reference: http://resources.arcgis.com/en/help/arcgis-rest-api/#/Route_service_with_synchronous_execution/02r300000036000000/
++// JSON reference:
++// https://resources.arcgis.com/en/help/arcgis-rest-api/#/Route_service_with_synchronous_execution/02r300000036000000/
+
+ static const QString kErrorMessage(QStringLiteral("Error %1: %2."));
+ static const QString kErrorJson(QStringLiteral("Error: invalide JSON document."));
+diff --git a/qtlocation/src/plugins/geoservices/esri/georoutereply_esri.cpp b/qtlocation/src/plugins/geoservices/esri/georoutereply_esri.cpp
+index 8cadfb29..92b6bb13 100644
+--- a/qtlocation/src/plugins/geoservices/esri/georoutereply_esri.cpp
++++ b/qtlocation/src/plugins/geoservices/esri/georoutereply_esri.cpp
+@@ -44,7 +44,8 @@
+
+ QT_BEGIN_NAMESPACE
+
+-// JSON reference: http://resources.arcgis.com/en/help/arcgis-rest-api/#/Route_service_with_synchronous_execution/02r300000036000000/
++// JSON reference:
++// https://resources.arcgis.com/en/help/arcgis-rest-api/#/Route_service_with_synchronous_execution/02r300000036000000/
+
+ GeoRouteReplyEsri::GeoRouteReplyEsri(QNetworkReply *reply, const QGeoRouteRequest &request,
+ QObject *parent) :
+diff --git a/qtlocation/src/plugins/geoservices/esri/georoutingmanagerengine_esri.cpp b/qtlocation/src/plugins/geoservices/esri/georoutingmanagerengine_esri.cpp
+index 0e6bc2c7..ed613f4b 100644
+--- a/qtlocation/src/plugins/geoservices/esri/georoutingmanagerengine_esri.cpp
++++ b/qtlocation/src/plugins/geoservices/esri/georoutingmanagerengine_esri.cpp
+@@ -48,7 +48,8 @@ static const QString kPrefixEsri(QStringLiteral("esri."));
+ static const QString kParamUserAgent(kPrefixEsri + QStringLiteral("useragent"));
+ static const QString kParamToken(kPrefixEsri + QStringLiteral("token"));
+
+-static const QString kUrlRouting(QStringLiteral("http://route.arcgis.com/arcgis/rest/services/World/Route/NAServer/Route_World/solve"));
++static const QString kUrlRouting(QStringLiteral(
++ "https://route.arcgis.com/arcgis/rest/services/World/Route/NAServer/Route_World/solve"));
+
+ GeoRoutingManagerEngineEsri::GeoRoutingManagerEngineEsri(const QVariantMap ¶meters,
+ QGeoServiceProvider::Error *error,
+@@ -70,7 +71,8 @@ GeoRoutingManagerEngineEsri::~GeoRoutingManagerEngineEsri()
+ {
+ }
+
+-// REST reference: http://resources.arcgis.com/en/help/arcgis-rest-api/index.html#//02r300000036000000
++// REST reference:
++// https://resources.arcgis.com/en/help/arcgis-rest-api/index.html#//02r300000036000000
+
+ QGeoRouteReply *GeoRoutingManagerEngineEsri::calculateRoute(const QGeoRouteRequest &request)
+ {
+@@ -125,7 +127,7 @@ void GeoRoutingManagerEngineEsri::replyError(QGeoRouteReply::Error errorCode, co
+ QString GeoRoutingManagerEngineEsri::preferedDirectionLangage()
+ {
+ // list of supported langages is defined in:
+- // http://resources.arcgis.com/en/help/arcgis-rest-api/index.html#//02r300000036000000
++ // https://resources.arcgis.com/en/help/arcgis-rest-api/index.html#//02r300000036000000
+ const QStringList supportedLanguages = {
+ "ar", // Generate directions in Arabic
+ "cs", // Generate directions in Czech
+diff --git a/qtlocation/src/plugins/geoservices/esri/geotiledmappingmanagerengine_esri.cpp b/qtlocation/src/plugins/geoservices/esri/geotiledmappingmanagerengine_esri.cpp
+index 5d15835d..24148f95 100644
+--- a/qtlocation/src/plugins/geoservices/esri/geotiledmappingmanagerengine_esri.cpp
++++ b/qtlocation/src/plugins/geoservices/esri/geotiledmappingmanagerengine_esri.cpp
+@@ -230,7 +230,8 @@ QGeoMap *GeoTiledMappingManagerEngineEsri::createMap()
+ // ${y} = Y
+ // ${token} = Token
+
+-// template = 'http://services.arcgisonline.com/ArcGIS/rest/services/World_Topo_Map/MapServer/tile/{{z}}/{{y}}/{{x}}.png'
++// template =
++// 'https://services.arcgisonline.com/ArcGIS/rest/services/World_Topo_Map/MapServer/tile/{{z}}/{{y}}/{{x}}.png'
+
+ bool GeoTiledMappingManagerEngineEsri::initializeMapSources(QGeoServiceProvider::Error *error,
+ QString *errorString,
+diff --git a/qtlocation/src/plugins/geoservices/esri/maps.json b/qtlocation/src/plugins/geoservices/esri/maps.json
+index 8167ae7d..862e087d 100644
+--- a/qtlocation/src/plugins/geoservices/esri/maps.json
++++ b/qtlocation/src/plugins/geoservices/esri/maps.json
+@@ -6,8 +6,8 @@
+ "description": "ArcGIS Online World Street Map",
+ "mobile": true,
+ "night": false,
+- "url": "http://services.arcgisonline.com/ArcGIS/rest/services/World_Street_Map/MapServer",
+- "copyrightText": "© <a href='http://www.arcgis.com/home/item.html?id=3b93337983e9436f8db950e38a8629af'>Esri</a> contributors"
++ "url": "https://services.arcgisonline.com/ArcGIS/rest/services/World_Street_Map/MapServer",
++ "copyrightText": "© <a href='https://www.arcgis.com/home/item.html?id=3b93337983e9436f8db950e38a8629af'>Esri</a> contributors"
+ },
+
+ {
+@@ -16,8 +16,8 @@
+ "": "ArcGIS Online World Imagery",
+ "mobile": true,
+ "night": false,
+- "url": "http://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer",
+- "copyrightText": "© <a href='http://www.arcgis.com/home/item.html?id=10df2279f9684e4a9f6a7f08febac2a9'>Esri</a> contributors"
++ "url": "https://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer",
++ "copyrightText": "© <a href='https://www.arcgis.com/home/item.html?id=10df2279f9684e4a9f6a7f08febac2a9'>Esri</a> contributors"
+ },
+
+ {
+@@ -26,8 +26,8 @@
+ "description": "ArcGIS Online World Terrain Base",
+ "mobile": false,
+ "night": false,
+- "url": "http://server.arcgisonline.com/ArcGIS/rest/services/World_Terrain_Base/MapServer",
+- "copyrightText": "© <a href='http://www.arcgis.com/home/item.html?id=c61ad8ab017d49e1a82f580ee1298931'>Esri</a> contributors"
++ "url": "https://server.arcgisonline.com/ArcGIS/rest/services/World_Terrain_Base/MapServer",
++ "copyrightText": "© <a href='https://www.arcgis.com/home/item.html?id=c61ad8ab017d49e1a82f580ee1298931'>Esri</a> contributors"
+ },
+
+ {
+@@ -36,8 +36,8 @@
+ "description": "ArcGIS Online World Topography",
+ "mobile": true,
+ "night": false,
+- "url": "http://server.arcgisonline.com/ArcGIS/rest/services/World_Topo_Map/MapServer",
+- "copyrightText": "© <a href='http://www.arcgis.com/home/item.html?id=30e5fe3149c34df1ba922e6f5bbf808f'>Esri</a> contributors"
++ "url": "https://server.arcgisonline.com/ArcGIS/rest/services/World_Topo_Map/MapServer",
++ "copyrightText": "© <a href='https://www.arcgis.com/home/item.html?id=30e5fe3149c34df1ba922e6f5bbf808f'>Esri</a> contributors"
+ },
+
+ {
+@@ -46,8 +46,8 @@
+ "description": "This map presents land cover and detailed topographic maps for the United States.",
+ "mobile": true,
+ "night": false,
+- "url": "http://services.arcgisonline.com/ArcGIS/rest/services/USA_Topo_Maps/MapServer",
+- "copyrightText": "© <a href='http://www.arcgis.com/home/item.html?id=99cd5fbd98934028802b4f797c4b1732'>Esri</a> contributors"
++ "url": "https://services.arcgisonline.com/ArcGIS/rest/services/USA_Topo_Maps/MapServer",
++ "copyrightText": "© <a href='https://www.arcgis.com/home/item.html?id=99cd5fbd98934028802b4f797c4b1732'>Esri</a> contributors"
+ },
+
+ {
+@@ -56,8 +56,8 @@
+ "description": "National Geographic World Map",
+ "mobile": false,
+ "night": false,
+- "url": "http://services.arcgisonline.com/ArcGIS/rest/services/NatGeo_World_Map/MapServer",
+- "copyrightText": "© <a href='http://www.arcgis.com/home/item.html?id=b9b1b422198944fbbd5250b3241691b6'>Esri</a> contributors"
++ "url": "https://services.arcgisonline.com/ArcGIS/rest/services/NatGeo_World_Map/MapServer",
++ "copyrightText": "© <a href='https://www.arcgis.com/home/item.html?id=b9b1b422198944fbbd5250b3241691b6'>Esri</a> contributors"
+ },
+
+ {
+@@ -66,8 +66,8 @@
+ "description": "Thematic content providing a neutral background with minimal colors",
+ "mobile": true,
+ "night": false,
+- "url": "http://services.arcgisonline.com/ArcGIS/rest/services/Canvas/World_Light_Gray_Base/MapServer",
+- "copyrightText": "© <a href='http://www.arcgis.com/home/item.html?id=ed712cb1db3e4bae9e85329040fb9a49'>Esri</a> contributors"
++ "url": "https://services.arcgisonline.com/ArcGIS/rest/services/Canvas/World_Light_Gray_Base/MapServer",
++ "copyrightText": "© <a href='https://www.arcgis.com/home/item.html?id=ed712cb1db3e4bae9e85329040fb9a49'>Esri</a> contributors"
+ },
+
+ {
+@@ -76,8 +76,8 @@
+ "description": "Natural Earth physical map for the world",
+ "mobile": false,
+ "night": false,
+- "url": "http://server.arcgisonline.com/ArcGIS/rest/services/World_Physical_Map/MapServer",
+- "copyrightText": "© <a href='http://www.arcgis.com/home/item.html?id=c4ec722a1cd34cf0a23904aadf8923a0'>Esri</a> contributors"
++ "url": "https://server.arcgisonline.com/ArcGIS/rest/services/World_Physical_Map/MapServer",
++ "copyrightText": "© <a href='https://www.arcgis.com/home/item.html?id=c4ec722a1cd34cf0a23904aadf8923a0'>Esri</a> contributors"
+ },
+
+ {
+@@ -86,8 +86,8 @@
+ "description": "Portrays surface elevation as shaded relief",
+ "mobile": false,
+ "night": false,
+- "url": "http://server.arcgisonline.com/ArcGIS/rest/services/World_Shaded_Relief/MapServer",
+- "copyrightText": "© <a href='http://www.arcgis.com/home/item.html?id=9c5370d0b54f4de1b48a3792d7377ff2'>Esri</a> contributors"
++ "url": "https://server.arcgisonline.com/ArcGIS/rest/services/World_Shaded_Relief/MapServer",
++ "copyrightText": "© <a href='https://www.arcgis.com/home/item.html?id=9c5370d0b54f4de1b48a3792d7377ff2'>Esri</a> contributors"
+ },
+
+ {
+@@ -96,8 +96,8 @@
+ "description": "This map is designed to be used as a basemap by marine GIS professionals and as a reference map by anyone interested in ocean data",
+ "mobile": false,
+ "night": false,
+- "url": "http://server.arcgisonline.com/arcgis/rest/services/Ocean/World_Ocean_Base/MapServer",
+- "copyrightText": "© <a href='http://www.arcgis.com/home/item.html?id=1e126e7520f9466c9ca28b8f28b5e500'>Esri</a> contributors"
++ "url": "https://server.arcgisonline.com/arcgis/rest/services/Ocean/World_Ocean_Base/MapServer",
++ "copyrightText": "© <a href='https://www.arcgis.com/home/item.html?id=1e126e7520f9466c9ca28b8f28b5e500'>Esri</a> contributors"
+ },
+
+ {
+@@ -106,8 +106,8 @@
+ "description": "Thematic content providing a neutral background with minimal colors",
+ "mobile": false,
+ "night": true,
+- "url": "http://services.arcgisonline.com/ArcGIS/rest/services/Canvas/World_Dark_Gray_Base/MapServer",
+- "copyrightText": "© <a href='http://www.arcgis.com/home/item.html?id=a284a9b99b3446a3910d4144a50990f6'>Esri</a> contributors"
++ "url": "https://services.arcgisonline.com/ArcGIS/rest/services/Canvas/World_Dark_Gray_Base/MapServer",
++ "copyrightText": "© <a href='https://www.arcgis.com/home/item.html?id=a284a9b99b3446a3910d4144a50990f6'>Esri</a> contributors"
+ },
+
+ {
+@@ -116,8 +116,8 @@
+ "description": "DeLorme’s topographic basemap is a seamless global data set that portrays transportation, hydrography, jurisdiction boundaries, and major geographic features",
+ "mobile": false,
+ "night": false,
+- "url": "http://server.arcgisonline.com/ArcGIS/rest/services/Specialty/DeLorme_World_Base_Map/MapServer",
+- "copyrightText": "© <a href='http://www.arcgis.com/home/item.html?id=b165c3df453e4be6b5ac4fdb241effbe'>Esri</a> contributors"
++ "url": "https://server.arcgisonline.com/ArcGIS/rest/services/Specialty/DeLorme_World_Base_Map/MapServer",
++ "copyrightText": "© <a href='https://www.arcgis.com/home/item.html?id=b165c3df453e4be6b5ac4fdb241effbe'>Esri</a> contributors"
+ }
+ ]
+ }
+diff --git a/qtlocation/src/plugins/geoservices/esri/placemanagerengine_esri.cpp b/qtlocation/src/plugins/geoservices/esri/placemanagerengine_esri.cpp
+index 3858ddf5..af66f28e 100644
+--- a/qtlocation/src/plugins/geoservices/esri/placemanagerengine_esri.cpp
++++ b/qtlocation/src/plugins/geoservices/esri/placemanagerengine_esri.cpp
+@@ -63,8 +63,10 @@ static const QString kCountriesKey(QStringLiteral("detailedCountries"));
+ static const QString kLocalizedNamesKey(QStringLiteral("localizedNames"));
+ static const QString kMaxLocationsKey(QStringLiteral("maxLocations"));
+
+-static const QUrl kUrlGeocodeServer("http://geocode.arcgis.com/arcgis/rest/services/World/GeocodeServer?f=pjson");
+-static const QUrl kUrlFindAddressCandidates("http://geocode.arcgis.com/arcgis/rest/services/World/GeocodeServer/findAddressCandidates");
++static const QUrl kUrlGeocodeServer(
++ "https://geocode.arcgis.com/arcgis/rest/services/World/GeocodeServer?f=pjson");
++static const QUrl kUrlFindAddressCandidates("https://geocode.arcgis.com/arcgis/rest/services/World/"
++ "GeocodeServer/findAddressCandidates");
+
+ PlaceManagerEngineEsri::PlaceManagerEngineEsri(const QVariantMap ¶meters, QGeoServiceProvider::Error *error,
+ QString *errorString) :
+Submodule qtmultimedia f0344079..0d7cc33a:
+diff --git a/qtmultimedia/src/plugins/pulseaudio/qaudioinput_pulse.cpp b/qtmultimedia/src/plugins/pulseaudio/qaudioinput_pulse.cpp
+index 2b5325132..b68b4af1b 100644
+--- a/qtmultimedia/src/plugins/pulseaudio/qaudioinput_pulse.cpp
++++ b/qtmultimedia/src/plugins/pulseaudio/qaudioinput_pulse.cpp
+@@ -402,6 +402,8 @@ int QPulseAudioInput::bytesReady() const
+
+ qint64 QPulseAudioInput::read(char *data, qint64 len)
+ {
++ Q_ASSERT(data != nullptr || len == 0);
++
+ m_bytesAvailable = checkBytesReady();
+
+ setError(QAudio::NoError);
+@@ -411,7 +413,8 @@ qint64 QPulseAudioInput::read(char *data, qint64 len)
+
+ if (!m_pullMode && !m_tempBuffer.isEmpty()) {
+ readBytes = qMin(static_cast<int>(len), m_tempBuffer.size());
+- memcpy(data, m_tempBuffer.constData(), readBytes);
++ if (readBytes)
++ memcpy(data, m_tempBuffer.constData(), readBytes);
+ m_totalTimeValue += readBytes;
+
+ if (readBytes < m_tempBuffer.size()) {
+@@ -502,9 +505,10 @@ qint64 QPulseAudioInput::read(char *data, qint64 len)
+
+ void QPulseAudioInput::applyVolume(const void *src, void *dest, int len)
+ {
++ Q_ASSERT((src && dest) || len == 0);
+ if (m_volume < 1.f)
+ QAudioHelperInternal::qMultiplySamples(m_volume, m_format, src, dest, len);
+- else
++ else if (len)
+ memcpy(dest, src, len);
+ }
+
+Submodule qtpim 02efef5e...f9a8f0fc (commits not present)
+Submodule qtquick3d b85cf622..47defc8b:
+diff --git a/qtquick3d/src/plugins/assetimporters/assimp/assimp.pro b/qtquick3d/src/plugins/assetimporters/assimp/assimp.pro
+index ca5c499e..174a075b 100644
+--- a/qtquick3d/src/plugins/assetimporters/assimp/assimp.pro
++++ b/qtquick3d/src/plugins/assetimporters/assimp/assimp.pro
+@@ -10,7 +10,7 @@ QT_FOR_CONFIG += assetimporters-private
+ include($$OUT_PWD/../qtassetimporters-config.pri)
+
+ qtConfig(system-assimp):!if(cross_compile:host_build) {
+- QMAKE_USE_PRIVATE += assimp
++ QMAKE_USE_PRIVATE += quick3d-assimp
+ } else {
+ include(../../../3rdparty/assimp/assimp.pri)
+ }
+Submodule qtquickcontrols2 3a657dc0..56ce8233:
+diff --git a/qtquickcontrols2/src/imports/platform/widgets/qwidgetplatformmenu.cpp b/qtquickcontrols2/src/imports/platform/widgets/qwidgetplatformmenu.cpp
+index e5fe734f7..e36922775 100644
+--- a/qtquickcontrols2/src/imports/platform/widgets/qwidgetplatformmenu.cpp
++++ b/qtquickcontrols2/src/imports/platform/widgets/qwidgetplatformmenu.cpp
+@@ -38,6 +38,7 @@
+ #include "qwidgetplatformmenuitem_p.h"
+
+ #include <QtGui/qwindow.h>
++#include <QtGui/private/qhighdpiscaling_p.h>
+ #include <QtWidgets/qmenu.h>
+ #include <QtWidgets/qaction.h>
+
+@@ -145,7 +146,7 @@ void QWidgetPlatformMenu::showPopup(const QWindow *window, const QRect &targetRe
+
+ QPoint targetPos = targetRect.bottomLeft();
+ if (window)
+- targetPos = window->mapToGlobal(targetPos);
++ targetPos = window->mapToGlobal(QHighDpi::fromNativeLocalPosition(targetPos, window));
+
+ const QWidgetPlatformMenuItem *widgetItem = qobject_cast<const QWidgetPlatformMenuItem *>(item);
+ m_menu->popup(targetPos, widgetItem ? widgetItem->action() : nullptr);
+diff --git a/qtquickcontrols2/src/quicktemplates2/qquickabstractbutton.cpp b/qtquickcontrols2/src/quicktemplates2/qquickabstractbutton.cpp
+index 950e4e099..b81fbea0b 100644
+--- a/qtquickcontrols2/src/quicktemplates2/qquickabstractbutton.cpp
++++ b/qtquickcontrols2/src/quicktemplates2/qquickabstractbutton.cpp
+@@ -387,6 +387,17 @@ void QQuickAbstractButtonPrivate::itemImplicitHeightChanged(QQuickItem *item)
+ emit q->implicitIndicatorHeightChanged();
+ }
+
++void QQuickAbstractButtonPrivate::itemDestroyed(QQuickItem *item)
++{
++ Q_Q(QQuickAbstractButton);
++ QQuickControlPrivate::itemDestroyed(item);
++ if (item == indicator) {
++ indicator = nullptr;
++ emit q->implicitIndicatorWidthChanged();
++ emit q->implicitIndicatorHeightChanged();
++ }
++}
++
+ QQuickAbstractButton *QQuickAbstractButtonPrivate::findCheckedButton() const
+ {
+ Q_Q(const QQuickAbstractButton);
+@@ -1176,6 +1187,12 @@ QAccessible::Role QQuickAbstractButton::accessibleRole() const
+ }
+ return QAccessible::Button;
+ }
++
++void QQuickAbstractButton::accessiblePressAction()
++{
++ Q_D(QQuickAbstractButton);
++ d->trigger();
++}
+ #endif
+
+ QT_END_NAMESPACE
+diff --git a/qtquickcontrols2/src/quicktemplates2/qquickabstractbutton_p.h b/qtquickcontrols2/src/quicktemplates2/qquickabstractbutton_p.h
+index 0fa48980e..ab66220d0 100644
+--- a/qtquickcontrols2/src/quicktemplates2/qquickabstractbutton_p.h
++++ b/qtquickcontrols2/src/quicktemplates2/qquickabstractbutton_p.h
+@@ -209,6 +209,7 @@ protected:
+ #if QT_CONFIG(accessibility)
+ void accessibilityActiveChanged(bool active) override;
+ QAccessible::Role accessibleRole() const override;
++ Q_INVOKABLE void accessiblePressAction();
+ #endif
+
+ private:
+diff --git a/qtquickcontrols2/src/quicktemplates2/qquickabstractbutton_p_p.h b/qtquickcontrols2/src/quicktemplates2/qquickabstractbutton_p_p.h
+index 9291c1a87..b729720f2 100644
+--- a/qtquickcontrols2/src/quicktemplates2/qquickabstractbutton_p_p.h
++++ b/qtquickcontrols2/src/quicktemplates2/qquickabstractbutton_p_p.h
+@@ -109,6 +109,7 @@ public:
+
+ void itemImplicitWidthChanged(QQuickItem *item) override;
+ void itemImplicitHeightChanged(QQuickItem *item) override;
++ void itemDestroyed(QQuickItem *item) override;
+
+ // copied from qabstractbutton.cpp
+ static const int AUTO_REPEAT_DELAY = 300;
+diff --git a/qtquickcontrols2/src/quicktemplates2/qquickaction.cpp b/qtquickcontrols2/src/quicktemplates2/qquickaction.cpp
+index 2041e7741..8610cdfae 100644
+--- a/qtquickcontrols2/src/quicktemplates2/qquickaction.cpp
++++ b/qtquickcontrols2/src/quicktemplates2/qquickaction.cpp
+@@ -145,7 +145,7 @@ int QQuickActionPrivate::ShortcutEntry::shortcutId() const
+
+ void QQuickActionPrivate::ShortcutEntry::grab(const QKeySequence &shortcut, bool enabled)
+ {
+- if (shortcut.isEmpty())
++ if (shortcut.isEmpty() || m_shortcutId)
+ return;
+
+ Qt::ShortcutContext context = Qt::WindowShortcut; // TODO
+diff --git a/qtquickcontrols2/src/quicktemplates2/qquickcontainer.cpp b/qtquickcontrols2/src/quicktemplates2/qquickcontainer.cpp
+index f38c2b09c..6eed2a024 100644
+--- a/qtquickcontrols2/src/quicktemplates2/qquickcontainer.cpp
++++ b/qtquickcontrols2/src/quicktemplates2/qquickcontainer.cpp
+@@ -225,6 +225,7 @@ void QQuickContainerPrivate::cleanup()
+ QObject::disconnect(contentModel, &QQmlObjectModel::countChanged, q, &QQuickContainer::countChanged);
+ QObject::disconnect(contentModel, &QQmlObjectModel::childrenChanged, q, &QQuickContainer::contentChildrenChanged);
+ delete contentModel;
++ contentModel = nullptr;
+ }
+
+ QQuickItem *QQuickContainerPrivate::itemAt(int index) const
+@@ -436,7 +437,7 @@ void QQuickContainerPrivate::contentChildren_clear(QQmlListProperty<QQuickItem>
+ void QQuickContainerPrivate::updateContentWidth()
+ {
+ Q_Q(QQuickContainer);
+- if (hasContentWidth || qFuzzyCompare(contentWidth, implicitContentWidth))
++ if (hasContentWidth || qFuzzyCompare(contentWidth, implicitContentWidth) || !contentModel)
+ return;
+
+ contentWidth = implicitContentWidth;
+@@ -446,7 +447,7 @@ void QQuickContainerPrivate::updateContentWidth()
+ void QQuickContainerPrivate::updateContentHeight()
+ {
+ Q_Q(QQuickContainer);
+- if (hasContentHeight || qFuzzyCompare(contentHeight, implicitContentHeight))
++ if (hasContentHeight || qFuzzyCompare(contentHeight, implicitContentHeight) || !contentModel)
+ return;
+
+ contentHeight = implicitContentHeight;
+diff --git a/qtquickcontrols2/src/quicktemplates2/qquickcontrol.cpp b/qtquickcontrols2/src/quicktemplates2/qquickcontrol.cpp
+index bbbd0e622..1f4b47343 100644
+--- a/qtquickcontrols2/src/quicktemplates2/qquickcontrol.cpp
++++ b/qtquickcontrols2/src/quicktemplates2/qquickcontrol.cpp
+@@ -845,6 +845,13 @@ void QQuickControlPrivate::executeBackground(bool complete)
+ quickCompleteDeferred(q, backgroundName(), background);
+ }
+
++/*
++ \internal
++
++ Hides an item that was replaced by a newer one, rather than
++ deleting it, as the item is typically created in QML and hence
++ we don't own it.
++*/
+ void QQuickControlPrivate::hideOldItem(QQuickItem *item)
+ {
+ if (!item)
+@@ -863,6 +870,29 @@ void QQuickControlPrivate::hideOldItem(QQuickItem *item)
+ #endif
+ }
+
++/*
++ \internal
++
++ Named "unhide" because it's used for cases where an item
++ that was previously hidden by \l hideOldItem() wants to be
++ shown by a control again, such as a ScrollBar in ScrollView.
++*/
++void QQuickControlPrivate::unhideOldItem(QQuickControl *control, QQuickItem *item)
++{
++ Q_ASSERT(item);
++ qCDebug(lcItemManagement) << "unhiding old item" << item;
++
++ item->setVisible(true);
++ item->setParentItem(control);
++
++#if QT_CONFIG(accessibility)
++ // Add the item back in to the accessibility tree.
++ QQuickAccessibleAttached *accessible = accessibleAttached(item);
++ if (accessible)
++ accessible->setIgnored(false);
++#endif
++}
++
+ void QQuickControlPrivate::updateBaselineOffset()
+ {
+ Q_Q(QQuickControl);
+diff --git a/qtquickcontrols2/src/quicktemplates2/qquickcontrol_p_p.h b/qtquickcontrols2/src/quicktemplates2/qquickcontrol_p_p.h
+index 8e979079e..a6e624c91 100644
+--- a/qtquickcontrols2/src/quicktemplates2/qquickcontrol_p_p.h
++++ b/qtquickcontrols2/src/quicktemplates2/qquickcontrol_p_p.h
+@@ -173,6 +173,7 @@ public:
+ virtual void executeBackground(bool complete = false);
+
+ static void hideOldItem(QQuickItem *item);
++ static void unhideOldItem(QQuickControl *control, QQuickItem *item);
+
+ void updateBaselineOffset();
+
+diff --git a/qtquickcontrols2/src/quicktemplates2/qquickdialogbuttonbox.cpp b/qtquickcontrols2/src/quicktemplates2/qquickdialogbuttonbox.cpp
+index e6db14eb5..6197d1547 100644
+--- a/qtquickcontrols2/src/quicktemplates2/qquickdialogbuttonbox.cpp
++++ b/qtquickcontrols2/src/quicktemplates2/qquickdialogbuttonbox.cpp
+@@ -237,7 +237,7 @@ static QRectF alignedRect(Qt::LayoutDirection direction, Qt::Alignment alignment
+ void QQuickDialogButtonBoxPrivate::resizeContent()
+ {
+ Q_Q(QQuickDialogButtonBox);
+- if (!contentItem)
++ if (!contentItem || !contentModel)
+ return;
+
+ QRectF geometry = q->boundingRect().adjusted(q->leftPadding(), q->topPadding(), -q->rightPadding(), -q->bottomPadding());
+@@ -322,6 +322,9 @@ void QQuickDialogButtonBoxPrivate::updateLayout()
+ qreal QQuickDialogButtonBoxPrivate::getContentWidth() const
+ {
+ Q_Q(const QQuickDialogButtonBox);
++ if (!contentModel)
++ return 0;
++
+ const int count = contentModel->count();
+ const qreal totalSpacing = qMax(0, count - 1) * spacing;
+ qreal totalWidth = totalSpacing;
+@@ -341,6 +344,9 @@ qreal QQuickDialogButtonBoxPrivate::getContentWidth() const
+ qreal QQuickDialogButtonBoxPrivate::getContentHeight() const
+ {
+ Q_Q(const QQuickDialogButtonBox);
++ if (!contentModel)
++ return 0;
++
+ const int count = contentModel->count();
+ qreal maxHeight = 0;
+ for (int i = 0; i < count; ++i) {
+diff --git a/qtquickcontrols2/src/quicktemplates2/qquickoverlay.cpp b/qtquickcontrols2/src/quicktemplates2/qquickoverlay.cpp
+index 91bd59184..0ce518f84 100644
+--- a/qtquickcontrols2/src/quicktemplates2/qquickoverlay.cpp
++++ b/qtquickcontrols2/src/quicktemplates2/qquickoverlay.cpp
+@@ -399,8 +399,11 @@ void QQuickOverlay::itemChange(ItemChange change, const ItemChangeData &data)
+ Q_D(QQuickOverlay);
+ QQuickItem::itemChange(change, data);
+
+- if (change == ItemChildAddedChange || change == ItemChildRemovedChange)
++ if (change == ItemChildAddedChange || change == ItemChildRemovedChange) {
+ setVisible(!d->allDrawers.isEmpty() || !childItems().isEmpty());
++ if (data.item->parent() == d->mouseGrabberPopup)
++ d->setMouseGrabberPopup(nullptr);
++ }
+ }
+
+ void QQuickOverlay::geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry)
+diff --git a/qtquickcontrols2/src/quicktemplates2/qquickscrollbar.cpp b/qtquickcontrols2/src/quicktemplates2/qquickscrollbar.cpp
+index 4e2f509db..1c4b308cd 100644
+--- a/qtquickcontrols2/src/quicktemplates2/qquickscrollbar.cpp
++++ b/qtquickcontrols2/src/quicktemplates2/qquickscrollbar.cpp
+@@ -797,6 +797,14 @@ void QQuickScrollBarAttachedPrivate::initHorizontal()
+ if (parent && parent == flickable->parentItem())
+ horizontal->stackAfter(flickable);
+
++ // If a scroll bar was previously hidden (due to e.g. setting a new contentItem
++ // on a ScrollView), we need to make sure that we un-hide it.
++ // We don't bother checking if the item is actually the old one, because
++ // if it's not, all of the things the function does (setting parent, visibility, etc.)
++ // should be no-ops anyway.
++ if (auto control = qobject_cast<QQuickControl*>(q_ptr->parent()))
++ QQuickControlPrivate::unhideOldItem(control, horizontal);
++
+ layoutHorizontal();
+ horizontal->setSize(area->property("widthRatio").toReal());
+ horizontal->setPosition(area->property("xPosition").toReal());
+@@ -818,6 +826,9 @@ void QQuickScrollBarAttachedPrivate::initVertical()
+ if (parent && parent == flickable->parentItem())
+ vertical->stackAfter(flickable);
+
++ if (auto control = qobject_cast<QQuickControl*>(q_ptr->parent()))
++ QQuickControlPrivate::unhideOldItem(control, vertical);
++
+ layoutVertical();
+ vertical->setSize(area->property("heightRatio").toReal());
+ vertical->setPosition(area->property("yPosition").toReal());
+diff --git a/qtquickcontrols2/tests/auto/controls/data/tst_scrollview.qml b/qtquickcontrols2/tests/auto/controls/data/tst_scrollview.qml
+index 0e8b08352..cd4931184 100644
+--- a/qtquickcontrols2/tests/auto/controls/data/tst_scrollview.qml
++++ b/qtquickcontrols2/tests/auto/controls/data/tst_scrollview.qml
+@@ -576,4 +576,51 @@ TestCase {
+ verify(newHorizontalScrollBar.visible)
+ verify(!oldHorizontalScrollBar.visible)
+ }
++
++ Component {
++ id: bindingToContentItemAndStandaloneFlickable
++
++ Item {
++ width: 200
++ height: 200
++
++ property alias scrollView: scrollView
++
++ ScrollView {
++ id: scrollView
++ anchors.fill: parent
++ contentItem: listView
++
++ property Item someBinding: contentItem
++ }
++ ListView {
++ id: listView
++ model: 10
++ delegate: ItemDelegate {
++ text: modelData
++ width: listView.width
++ }
++ }
++ }
++ }
++
++ // Tests that scroll bars show up for a ScrollView where
++ // - its contentItem is declared as a standalone, separate item
++ // - there is a binding to contentItem (which causes a default Flickable to be created)
++ function test_bindingToContentItemAndStandaloneFlickable() {
++ let root = createTemporaryObject(bindingToContentItemAndStandaloneFlickable, testCase)
++ verify(root)
++
++ let control = root.scrollView
++ let verticalScrollBar = control.ScrollBar.vertical
++ let horizontalScrollBar = control.ScrollBar.horizontal
++ compare(verticalScrollBar.parent, control)
++ compare(horizontalScrollBar.parent, control)
++ verify(verticalScrollBar.visible)
++ verify(horizontalScrollBar.visible)
++
++ mouseDrag(verticalScrollBar, verticalScrollBar.width / 2, verticalScrollBar.height / 2, 0, 50)
++ verify(verticalScrollBar.active)
++ verify(horizontalScrollBar.active)
++ }
+ }
+diff --git a/qtquickcontrols2/tests/auto/controls/data/tst_switch.qml b/qtquickcontrols2/tests/auto/controls/data/tst_switch.qml
+index b3fab41ca..10b6baa02 100644
+--- a/qtquickcontrols2/tests/auto/controls/data/tst_switch.qml
++++ b/qtquickcontrols2/tests/auto/controls/data/tst_switch.qml
+@@ -608,4 +608,27 @@ TestCase {
+ mouseClick(control.indicator)
+ verify(control.activeFocus)
+ }
++
++ Component {
++ id: deletionOrder1
++ Item {
++ Image { id: innerImage }
++ Switch { indicator: innerImage }
++ }
++ }
++
++ Component {
++ id: deletionOrder2
++ Item {
++ Switch { indicator: innerImage }
++ Image { id: innerImage }
++ }
++ }
++
++ function test_deletionOrder() {
++ var control1 = createTemporaryObject(deletionOrder1, testCase)
++ verify(control1)
++ var control2 = createTemporaryObject(deletionOrder2, testCase)
++ verify(control2)
++ }
+ }
+diff --git a/qtquickcontrols2/tests/auto/qquickpopup/data/releaseAfterExitTransition.qml b/qtquickcontrols2/tests/auto/qquickpopup/data/releaseAfterExitTransition.qml
+new file mode 100644
+index 000000000..9e4598b9f
+--- /dev/null
++++ b/qtquickcontrols2/tests/auto/qquickpopup/data/releaseAfterExitTransition.qml
+@@ -0,0 +1,78 @@
++/****************************************************************************
++**
++** Copyright (C) 2021 The Qt Company Ltd.
++** Contact: https://www.qt.io/licensing/
++**
++** This file is part of the test suite of the Qt Toolkit.
++**
++** $QT_BEGIN_LICENSE:BSD$
++** Commercial License Usage
++** Licensees holding valid commercial Qt licenses may use this file in
++** accordance with the commercial license agreement provided with the
++** Software or, alternatively, in accordance with the terms contained in
++** a written agreement between you and The Qt Company. For licensing terms
++** and conditions see https://www.qt.io/terms-conditions. For further
++** information use the contact form at https://www.qt.io/contact-us.
++**
++** BSD License Usage
++** Alternatively, you may use this file under the terms of the BSD license
++** as follows:
++**
++** "Redistribution and use in source and binary forms, with or without
++** modification, are permitted provided that the following conditions are
++** met:
++** * Redistributions of source code must retain the above copyright
++** notice, this list of conditions and the following disclaimer.
++** * Redistributions in binary form must reproduce the above copyright
++** notice, this list of conditions and the following disclaimer in
++** the documentation and/or other materials provided with the
++** distribution.
++** * Neither the name of The Qt Company Ltd nor the names of its
++** contributors may be used to endorse or promote products derived
++** from this software without specific prior written permission.
++**
++**
++** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
++** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
++** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
++** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
++** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
++** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
++** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
++** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
++** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
++** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
++** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
++**
++** $QT_END_LICENSE$
++**
++****************************************************************************/
++
++import QtQuick 2.15
++import QtQuick.Controls 2.15
++
++ApplicationWindow {
++ id: window
++ width: 400
++ height: 400
++ title: "releaseAfterExitTransition"
++
++ property alias popup: popup
++ property alias modalPopup: modalPopup
++
++ Popup {
++ id: popup
++ y: parent.height - height
++ width: 50
++ height: 50
++ }
++
++ Popup {
++ id: modalPopup
++ modal: true
++ y: parent.height - height
++ width: 50
++ height: 50
++ exit: Transition { PauseAnimation { duration: 100 } }
++ }
++}
+diff --git a/qtquickcontrols2/tests/auto/qquickpopup/tst_qquickpopup.cpp b/qtquickcontrols2/tests/auto/qquickpopup/tst_qquickpopup.cpp
+index 54952d128..3d50e2dd4 100644
+--- a/qtquickcontrols2/tests/auto/qquickpopup/tst_qquickpopup.cpp
++++ b/qtquickcontrols2/tests/auto/qquickpopup/tst_qquickpopup.cpp
+@@ -100,6 +100,7 @@ private slots:
+ void invisibleToolTipOpen();
+ void centerInOverlayWithinStackViewItem();
+ void destroyDuringExitTransition();
++ void releaseAfterExitTransition();
+ };
+
+ void tst_QQuickPopup::initTestCase()
+@@ -1575,6 +1576,34 @@ void tst_QQuickPopup::destroyDuringExitTransition()
+ QVERIFY(!button->isDown());
+ }
+
++void tst_QQuickPopup::releaseAfterExitTransition()
++{
++ QQuickApplicationHelper helper(this, "releaseAfterExitTransition.qml");
++ QVERIFY2(helper.ready, helper.failureMessage());
++
++ QQuickWindow *window = helper.window;
++ window->show();
++ QVERIFY(QTest::qWaitForWindowActive(window));
++
++ QQuickOverlay *overlay = QQuickOverlay::overlay(window);
++ QQuickPopup *modalPopup = window->property("modalPopup").value<QQuickPopup *>();
++ QQuickPopup *popup = window->property("popup").value<QQuickPopup *>();
++
++ modalPopup->open();
++ QTRY_VERIFY(modalPopup->isOpened());
++
++ QTest::mousePress(window, Qt::LeftButton, Qt::NoModifier, QPoint(1, 1));
++ // wait until the transition is finished and the overlay hides itself
++ QTRY_VERIFY(!overlay->isVisible());
++ QTest::mouseRelease(window, Qt::LeftButton, Qt::NoModifier, QPoint(1, 1));
++
++ popup->open();
++ QTRY_VERIFY(popup->isOpened());
++ QTest::mouseClick(window, Qt::LeftButton, Qt::NoModifier, QPoint(1, 1));
++ QTRY_VERIFY(!popup->isOpened());
++}
++
++
+ QTEST_QUICKCONTROLS_MAIN(tst_QQuickPopup)
+
+ #include "tst_qquickpopup.moc"
+Submodule qtscript 5be95f96...4d8e4bd2 (commits not present)
+Submodule qtspeech 17fc9fde..255845e2:
+diff --git a/qtspeech/src/plugins/tts/speechdispatcher/qtexttospeech_speechd.cpp b/qtspeech/src/plugins/tts/speechdispatcher/qtexttospeech_speechd.cpp
+index 6eb74b8..bcc7dd1 100644
+--- a/qtspeech/src/plugins/tts/speechdispatcher/qtexttospeech_speechd.cpp
++++ b/qtspeech/src/plugins/tts/speechdispatcher/qtexttospeech_speechd.cpp
+@@ -357,7 +357,9 @@ QVector<QLocale> QTextToSpeechEngineSpeechd::availableLocales() const
+
+ QVector<QVoice> QTextToSpeechEngineSpeechd::availableVoices() const
+ {
+- return m_voices.values(m_currentLocale.name()).toVector();
++ QList<QVoice> resultList = m_voices.values(m_currentLocale.name());
++ std::reverse(resultList.begin(), resultList.end());
++ return resultList.toVector();
+ }
+
+ // We have no way of knowing our own client_id since speech-dispatcher seems to be incomplete
+Submodule qtsvg 0c05780e..a7a0f249:
+diff --git a/qtsvg/src/plugins/imageformats/svg/qsvgiohandler.cpp b/qtsvg/src/plugins/imageformats/svg/qsvgiohandler.cpp
+index 561e77e..12e0574 100644
+--- a/qtsvg/src/plugins/imageformats/svg/qsvgiohandler.cpp
++++ b/qtsvg/src/plugins/imageformats/svg/qsvgiohandler.cpp
+@@ -191,6 +191,8 @@ bool QSvgIOHandler::read(QImage *image)
+ }
+ }
+ if (!finalSize.isEmpty()) {
++ if (qMax(finalSize.width(), finalSize.height()) > 0xffff)
++ return false; // Assume corrupted file
+ image->fill(d->backColor.rgba());
+ QPainter p(image);
+ d->r.render(&p, bounds);
+diff --git a/qtsvg/src/svg/qsvghandler.cpp b/qtsvg/src/svg/qsvghandler.cpp
+index a5f877f..8dda563 100644
+--- a/qtsvg/src/svg/qsvghandler.cpp
++++ b/qtsvg/src/svg/qsvghandler.cpp
+@@ -1393,9 +1393,10 @@ static void parseFont(QSvgNode *node,
+ case FontSizeNone:
+ break;
+ case FontSizeValue: {
+- QSvgHandler::LengthType dummy; // should always be pixel size
+- fontStyle->setSize(qMin(parseLength(attributes.fontSize, dummy, handler),
+- qreal(0xffff)));
++ QSvgHandler::LengthType type;
++ qreal fs = parseLength(attributes.fontSize, type, handler);
++ fs = convertToPixels(fs, true, type);
++ fontStyle->setSize(qMin(fs, qreal(0xffff)));
+ }
+ break;
+ default:
+@@ -2513,6 +2514,8 @@ static bool parseAnimateTransformNode(QSvgNode *parent,
+ ++s;
+ }
+ }
++ if (vals.count() % 3 != 0)
++ return false;
+
+ bool ok = true;
+ int begin = parseClockValue(beginStr, &ok);
+@@ -2576,6 +2579,8 @@ static QSvgNode *createCircleNode(QSvgNode *parent,
+ qreal ncx = toDouble(cx);
+ qreal ncy = toDouble(cy);
+ qreal nr = toDouble(r);
++ if (nr < 0.0)
++ return nullptr;
+
+ QRectF rect(ncx-nr, ncy-nr, nr*2, nr*2);
+ QSvgNode *circle = new QSvgCircle(parent, rect);
+@@ -3046,15 +3051,16 @@ static QSvgStyleProperty *createRadialGradientNode(QSvgNode *node,
+
+ qreal ncx = 0.5;
+ qreal ncy = 0.5;
+- qreal nr = 0.5;
+ if (!cx.isEmpty())
+ ncx = toDouble(cx);
+ if (!cy.isEmpty())
+ ncy = toDouble(cy);
++
++ qreal nr = 0.0;
+ if (!r.isEmpty())
+ nr = toDouble(r);
+- if (nr < 0.5)
+- nr = 0.5;
++ if (nr <= 0.0)
++ return nullptr;
+
+ qreal nfx = ncx;
+ if (!fx.isEmpty())
+@@ -3350,7 +3356,9 @@ static QSvgNode *createTextNode(QSvgNode *parent,
+ //### editable and rotate not handled
+ QSvgHandler::LengthType type;
+ qreal nx = parseLength(x, type, handler);
++ nx = convertToPixels(nx, true, type);
+ qreal ny = parseLength(y, type, handler);
++ ny = convertToPixels(ny, true, type);
+
+ QSvgNode *text = new QSvgText(parent, QPointF(nx, ny));
+ return text;
+@@ -3691,9 +3699,7 @@ void QSvgHandler::parse()
+ case QXmlStreamReader::EndElement:
+ endElement(xml->name());
+ ++remainingUnfinishedElements;
+- // if we are using somebody else's qxmlstreamreader
+- // we should not read until the end of the stream
+- done = !m_ownsReader && (xml->name() == QLatin1String("svg"));
++ done = (xml->name() == QLatin1String("svg"));
+ break;
+ case QXmlStreamReader::Characters:
+ characters(xml->text());
+diff --git a/qtsvg/src/svg/qsvgstructure.cpp b/qtsvg/src/svg/qsvgstructure.cpp
+index b89608b..89c9e4e 100644
+--- a/qtsvg/src/svg/qsvgstructure.cpp
++++ b/qtsvg/src/svg/qsvgstructure.cpp
+@@ -255,9 +255,13 @@ inline static bool isSupportedSvgFeature(const QString &str)
+ };
+
+ if (str.length() <= MAX_WORD_LENGTH && str.length() >= MIN_WORD_LENGTH) {
++ const char16_t unicode44 = str.at(44).unicode();
++ const char16_t unicode45 = str.at(45).unicode();
++ if (unicode44 >= sizeof(asso_values) || unicode45 >= sizeof(asso_values))
++ return false;
+ const int key = str.length()
+- + asso_values[str.at(45).unicode()]
+- + asso_values[str.at(44).unicode()];
++ + asso_values[unicode45]
++ + asso_values[unicode44];
+ if (key <= MAX_HASH_VALUE && key >= 0)
+ return str == QLatin1String(wordlist[key]);
+ }
+diff --git a/qtsvg/src/svg/qsvgtinydocument.cpp b/qtsvg/src/svg/qsvgtinydocument.cpp
+index 63d0797..19e7154 100644
+--- a/qtsvg/src/svg/qsvgtinydocument.cpp
++++ b/qtsvg/src/svg/qsvgtinydocument.cpp
+@@ -433,8 +433,16 @@ void QSvgTinyDocument::draw(QPainter *p, QSvgExtraStates &)
+ draw(p);
+ }
+
++static bool isValidMatrix(const QTransform &transform)
++{
++ qreal determinant = transform.determinant();
++ return qIsFinite(determinant);
++}
++
+ void QSvgTinyDocument::mapSourceToTarget(QPainter *p, const QRectF &targetRect, const QRectF &sourceRect)
+ {
++ QTransform oldTransform = p->worldTransform();
++
+ QRectF target = targetRect;
+ if (target.isEmpty()) {
+ QPaintDevice *dev = p->device();
+@@ -487,6 +495,9 @@ void QSvgTinyDocument::mapSourceToTarget(QPainter *p, const QRectF &targetRect,
+ }
+ #endif
+ }
++
++ if (!isValidMatrix(p->worldTransform()))
++ p->setWorldTransform(oldTransform);
+ }
+
+ QRectF QSvgTinyDocument::boundsOnElement(const QString &id) const
+diff --git a/qtsvg/tests/auto/qsvgrenderer/tst_qsvgrenderer.cpp b/qtsvg/tests/auto/qsvgrenderer/tst_qsvgrenderer.cpp
+index 36c76ec..db71e02 100644
+--- a/qtsvg/tests/auto/qsvgrenderer/tst_qsvgrenderer.cpp
++++ b/qtsvg/tests/auto/qsvgrenderer/tst_qsvgrenderer.cpp
+@@ -86,6 +86,8 @@ private slots:
+ void oss_fuzz_23731();
+ void oss_fuzz_24131();
+ void oss_fuzz_24738();
++ void illegalAnimateTransform_data();
++ void illegalAnimateTransform();
+
+ #ifndef QT_NO_COMPRESS
+ void testGzLoading();
+@@ -1646,5 +1648,22 @@ void tst_QSvgRenderer::oss_fuzz_24738()
+ QSvgRenderer().load(QByteArray("<svg><path d=\"a 2 1e-212.....\">"));
+ }
+
++void tst_QSvgRenderer::illegalAnimateTransform_data()
++{
++ QTest::addColumn<QByteArray>("svg");
++
++ QTest::newRow("case1") << QByteArray("<svg><animateTransform type=\"rotate\" begin=\"1\" dur=\"2\" values=\"8,0,5,0\">");
++ QTest::newRow("case2") << QByteArray("<svg><animateTransform type=\"rotate\" begin=\"1\" dur=\"2\" values=\"1,2\">");
++ QTest::newRow("case3") << QByteArray("<svg><animateTransform type=\"rotate\" begin=\"1\" dur=\"2\" from=\".. 5 2\" to=\"f\">");
++ QTest::newRow("case4") << QByteArray("<svg><animateTransform type=\"scale\" begin=\"1\" dur=\"2\" by=\"--,..\">");
++}
++
++void tst_QSvgRenderer::illegalAnimateTransform()
++{
++ QFETCH(QByteArray, svg);
++ QSvgRenderer renderer;
++ QVERIFY(!renderer.load(svg)); // also shouldn't assert
++}
++
+ QTEST_MAIN(tst_QSvgRenderer)
+ #include "tst_qsvgrenderer.moc"
+Submodule qttools 6914f7c8..090e526e:
+diff --git a/qttools/src/assistant/qhelpgenerator/helpgenerator.cpp b/qttools/src/assistant/qhelpgenerator/helpgenerator.cpp
+index feab1e2d5..cbfb82507 100644
+--- a/qttools/src/assistant/qhelpgenerator/helpgenerator.cpp
++++ b/qttools/src/assistant/qhelpgenerator/helpgenerator.cpp
+@@ -445,7 +445,9 @@ bool HelpGeneratorPrivate::insertFiles(const QStringList &files, const QString &
+ if (filterSetId < 0)
+ return false;
+ ++filterSetId;
+- for (int attId : qAsConst(filterAtts)) {
++ QList<int> attValues = filterAtts.values();
++ std::sort(attValues.begin(), attValues.end());
++ for (int attId : qAsConst(attValues)) {
+ m_query->prepare(QLatin1String("INSERT INTO FileAttributeSetTable "
+ "VALUES(?, ?)"));
+ m_query->bindValue(0, filterSetId);
+Submodule qtwayland dfb0129c..2904e1b3:
+diff --git a/qtwayland/src/client/configure.json b/qtwayland/src/client/configure.json
+index 2f424580..29222357 100644
+--- a/qtwayland/src/client/configure.json
++++ b/qtwayland/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/qtwayland/src/client/global/qwaylandclientextension.cpp b/qtwayland/src/client/global/qwaylandclientextension.cpp
+index 125b1e19..edccfe63 100644
+--- a/qtwayland/src/client/global/qwaylandclientextension.cpp
++++ b/qtwayland/src/client/global/qwaylandclientextension.cpp
+@@ -74,7 +74,10 @@ void QWaylandClientExtensionPrivate::handleRegistryGlobal(void *data, ::wl_regis
+ void QWaylandClientExtension::addRegistryListener()
+ {
+ Q_D(QWaylandClientExtension);
+- d->waylandIntegration->display()->addRegistryListener(&QWaylandClientExtensionPrivate::handleRegistryGlobal, this);
++ if (!d->registered) {
++ d->waylandIntegration->display()->addRegistryListener(&QWaylandClientExtensionPrivate::handleRegistryGlobal, this);
++ d->registered = true;
++ }
+ }
+
+ QWaylandClientExtension::QWaylandClientExtension(const int ver)
+@@ -88,6 +91,13 @@ QWaylandClientExtension::QWaylandClientExtension(const int ver)
+ QMetaObject::invokeMethod(this, "addRegistryListener", Qt::QueuedConnection);
+ }
+
++QWaylandClientExtension::~QWaylandClientExtension()
++{
++ Q_D(QWaylandClientExtension);
++ if (d->registered && !QCoreApplication::closingDown())
++ d->waylandIntegration->display()->removeListener(&QWaylandClientExtensionPrivate::handleRegistryGlobal, this);
++}
++
+ QtWaylandClient::QWaylandIntegration *QWaylandClientExtension::integration() const
+ {
+ Q_D(const QWaylandClientExtension);
+diff --git a/qtwayland/src/client/global/qwaylandclientextension.h b/qtwayland/src/client/global/qwaylandclientextension.h
+index 98272e57..5bd28398 100644
+--- a/qtwayland/src/client/global/qwaylandclientextension.h
++++ b/qtwayland/src/client/global/qwaylandclientextension.h
+@@ -63,6 +63,7 @@ class Q_WAYLAND_CLIENT_EXPORT QWaylandClientExtension : public QObject
+ Q_PROPERTY(bool active READ isActive NOTIFY activeChanged)
+ public:
+ QWaylandClientExtension(const int version);
++ ~QWaylandClientExtension();
+
+ QtWaylandClient::QWaylandIntegration *integration() const;
+ int version() const;
+diff --git a/qtwayland/src/client/global/qwaylandclientextension_p.h b/qtwayland/src/client/global/qwaylandclientextension_p.h
+index 69cc46a0..9091efbe 100644
+--- a/qtwayland/src/client/global/qwaylandclientextension_p.h
++++ b/qtwayland/src/client/global/qwaylandclientextension_p.h
+@@ -68,6 +68,7 @@ public:
+ QtWaylandClient::QWaylandIntegration *waylandIntegration = nullptr;
+ int version = -1;
+ bool active = false;
++ bool registered = false;
+ };
+
+ class Q_WAYLAND_CLIENT_EXPORT QWaylandClientExtensionTemplatePrivate : public QWaylandClientExtensionPrivate
+diff --git a/qtwayland/src/client/qwaylanddatadevice.cpp b/qtwayland/src/client/qwaylanddatadevice.cpp
+index 7e2e3308..e3e60ed5 100644
+--- a/qtwayland/src/client/qwaylanddatadevice.cpp
++++ b/qtwayland/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,7 +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::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;
+@@ -152,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;
+ }
+@@ -162,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();
+ }
+ }
+
+@@ -186,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,
+@@ -197,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()
+@@ -235,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());
+
+@@ -246,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)
+
+@@ -277,14 +296,10 @@ void QWaylandDataDevice::selectionSourceCancelled()
+ #if QT_CONFIG(draganddrop)
+ void QWaylandDataDevice::dragSourceCancelled()
+ {
++ static_cast<QWaylandDrag *>(QGuiApplicationPrivate::platformIntegration()->drag())->finishDrag();
+ 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));
+@@ -297,6 +312,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/qtwayland/src/client/qwaylanddatadevice_p.h b/qtwayland/src/client/qwaylanddatadevice_p.h
+index 16c3ad28..801dcc2c 100644
+--- a/qtwayland/src/client/qwaylanddatadevice_p.h
++++ b/qtwayland/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/qtwayland/src/client/qwaylanddatadevicemanager.cpp b/qtwayland/src/client/qwaylanddatadevicemanager.cpp
+index 35d67307..6dc4f77f 100644
+--- a/qtwayland/src/client/qwaylanddatadevicemanager.cpp
++++ b/qtwayland/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/qtwayland/src/client/qwaylanddatadevicemanager_p.h b/qtwayland/src/client/qwaylanddatadevicemanager_p.h
+index bd05c0fb..510d9be4 100644
+--- a/qtwayland/src/client/qwaylanddatadevicemanager_p.h
++++ b/qtwayland/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/qtwayland/src/client/qwaylanddataoffer.cpp b/qtwayland/src/client/qwaylanddataoffer.cpp
+index 2297e8a1..fe0ea8c9 100644
+--- a/qtwayland/src/client/qwaylanddataoffer.cpp
++++ b/qtwayland/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)
+ {
+@@ -163,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");
+diff --git a/qtwayland/src/client/qwaylanddataoffer_p.h b/qtwayland/src/client/qwaylanddataoffer_p.h
+index 9cf1483c..6f667398 100644
+--- a/qtwayland/src/client/qwaylanddataoffer_p.h
++++ b/qtwayland/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/qtwayland/src/client/qwaylanddatasource.cpp b/qtwayland/src/client/qwaylanddatasource.cpp
+index f45122fb..5599cbd4 100644
+--- a/qtwayland/src/client/qwaylanddatasource.cpp
++++ b/qtwayland/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/qtwayland/src/client/qwaylanddatasource_p.h b/qtwayland/src/client/qwaylanddatasource_p.h
+index 25afff79..96f07bc3 100644
+--- a/qtwayland/src/client/qwaylanddatasource_p.h
++++ b/qtwayland/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/qtwayland/src/client/qwaylanddisplay.cpp b/qtwayland/src/client/qwaylanddisplay.cpp
+index f10c1f79..c01e238b 100644
+--- a/qtwayland/src/client/qwaylanddisplay.cpp
++++ b/qtwayland/src/client/qwaylanddisplay.cpp
+@@ -85,10 +85,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)
+@@ -158,17 +351,16 @@ 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)
+ {
++ if (m_eventThread)
++ m_eventThread->stop();
++
++ if (m_frameEventQueueThread)
++ m_frameEventQueueThread->stop();
++
+ if (mSyncCallback)
+ wl_callback_destroy(mSyncCallback);
+
+@@ -187,6 +379,21 @@ 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
++// 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()
+@@ -203,98 +410,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
+@@ -345,7 +491,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));
+@@ -354,7 +500,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));
+@@ -369,6 +515,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));
+@@ -427,6 +575,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;
+ }
+@@ -452,9 +607,10 @@ void QWaylandDisplay::addRegistryListener(RegistryListener listener, void *data)
+
+ void QWaylandDisplay::removeListener(RegistryListener listener, void *data)
+ {
+- std::remove_if(mRegistryListeners.begin(), mRegistryListeners.end(), [=](Listener l){
++ auto iter = std::remove_if(mRegistryListeners.begin(), mRegistryListeners.end(), [=](Listener l){
+ return (l.listener == listener && l.data == data);
+ });
++ mRegistryListeners.erase(iter, mRegistryListeners.end());
+ }
+
+ uint32_t QWaylandDisplay::currentTimeMillisec()
+@@ -467,50 +623,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
+@@ -574,14 +689,10 @@ void QWaylandDisplay::handleKeyboardFocusChanged(QWaylandInputDevice *inputDevic
+ if (mLastKeyboardFocus == keyboardFocus)
+ return;
+
+- if (mWaylandIntegration->mShellIntegration) {
+- mWaylandIntegration->mShellIntegration->handleKeyboardFocusChanged(keyboardFocus, mLastKeyboardFocus);
+- } else {
+- if (keyboardFocus)
+- handleWindowActivated(keyboardFocus);
+- if (mLastKeyboardFocus)
+- handleWindowDeactivated(mLastKeyboardFocus);
+- }
++ if (keyboardFocus)
++ handleWindowActivated(keyboardFocus);
++ if (mLastKeyboardFocus)
++ handleWindowDeactivated(mLastKeyboardFocus);
+
+ mLastKeyboardFocus = keyboardFocus;
+ }
+@@ -600,6 +711,19 @@ void QWaylandDisplay::handleWaylandSync()
+ QWindow *activeWindow = mActiveWindows.empty() ? nullptr : mActiveWindows.last()->window();
+ if (activeWindow != QGuiApplication::focusWindow())
+ QWindowSystemInterface::handleWindowActivated(activeWindow);
++
++ if (!activeWindow) {
++ if (lastInputDevice()) {
++#if QT_CONFIG(clipboard)
++ if (auto *dataDevice = lastInputDevice()->dataDevice())
++ dataDevice->invalidateSelectionOffer();
++#endif
++#if QT_CONFIG(wayland_client_primary_selection)
++ if (auto *device = lastInputDevice()->primarySelectionDevice())
++ device->invalidateSelectionOffer();
++#endif
++ }
++ }
+ }
+
+ const wl_callback_listener QWaylandDisplay::syncCallbackListener = {
+@@ -626,6 +750,13 @@ QWaylandInputDevice *QWaylandDisplay::defaultInputDevice() const
+ return mInputDevices.isEmpty() ? 0 : mInputDevices.first();
+ }
+
++bool QWaylandDisplay::isKeyboardAvailable() const
++{
++ return std::any_of(
++ mInputDevices.constBegin(), mInputDevices.constEnd(),
++ [this](const QWaylandInputDevice *device) { return device->keyboard() != nullptr; });
++}
++
+ #if QT_CONFIG(cursor)
+
+ QWaylandCursor *QWaylandDisplay::waylandCursor()
+@@ -652,4 +783,6 @@ QWaylandCursorTheme *QWaylandDisplay::loadCursorTheme(const QString &name, int p
+
+ } // namespace QtWaylandClient
+
++#include "qwaylanddisplay.moc"
++
+ QT_END_NAMESPACE
+diff --git a/qtwayland/src/client/qwaylanddisplay_p.h b/qtwayland/src/client/qwaylanddisplay_p.h
+index 3b092bc8..42bc661d 100644
+--- a/qtwayland/src/client/qwaylanddisplay_p.h
++++ b/qtwayland/src/client/qwaylanddisplay_p.h
+@@ -109,6 +109,7 @@ class QWaylandSurface;
+ class QWaylandShellIntegration;
+ class QWaylandCursor;
+ class QWaylandCursorTheme;
++class EventThread;
+
+ typedef void (*RegistryListener)(void *data,
+ struct wl_registry *registry,
+@@ -120,15 +121,11 @@ 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;
+
++ void initialize();
++
+ #if QT_CONFIG(xkbcommon)
+ struct xkb_context *xkbContext() const { return mXkbContext.get(); }
+ #endif
+@@ -210,11 +207,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();
+@@ -237,6 +234,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;
+@@ -273,11 +273,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/qtwayland/src/client/qwaylanddnd.cpp b/qtwayland/src/client/qwaylanddnd.cpp
+index 6535aa16..7c53f5fa 100644
+--- a/qtwayland/src/client/qwaylanddnd.cpp
++++ b/qtwayland/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
+@@ -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)
+@@ -103,33 +106,41 @@ 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);
++
++ if (drag())
++ drag()->deleteLater();
++}
++
++bool QWaylandDrag::ownsDragObject() const
++{
++ return true;
+ }
+
+ }
+diff --git a/qtwayland/src/client/qwaylanddnd_p.h b/qtwayland/src/client/qwaylanddnd_p.h
+index 474fe2ab..46f629ac 100644
+--- a/qtwayland/src/client/qwaylanddnd_p.h
++++ b/qtwayland/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;
+@@ -82,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;
+diff --git a/qtwayland/src/client/qwaylandinputdevice.cpp b/qtwayland/src/client/qwaylandinputdevice.cpp
+index 613fe862..4b90de84 100644
+--- a/qtwayland/src/client/qwaylandinputdevice.cpp
++++ b/qtwayland/src/client/qwaylandinputdevice.cpp
+@@ -685,6 +685,11 @@ public:
+
+ void QWaylandInputDevice::Pointer::pointer_leave(uint32_t time, struct wl_surface *surface)
+ {
++ invalidateFocus();
++ mButtons = Qt::NoButton;
++
++ mParent->mTime = time;
++
+ // The event may arrive after destroying the window, indicated by
+ // a null surface.
+ if (!surface)
+@@ -696,11 +701,6 @@ void QWaylandInputDevice::Pointer::pointer_leave(uint32_t time, struct wl_surfac
+
+ if (!QWaylandWindow::mouseGrab())
+ setFrameEvent(new LeaveEvent(window, mSurfacePos, mGlobalPos));
+-
+- invalidateFocus();
+- mButtons = Qt::NoButton;
+-
+- mParent->mTime = time;
+ }
+
+ class MotionEvent : public QWaylandPointerEvent
+@@ -1300,14 +1300,6 @@ void QWaylandInputDevice::Keyboard::handleFocusDestroyed()
+ void QWaylandInputDevice::Keyboard::handleFocusLost()
+ {
+ mFocus = nullptr;
+-#if QT_CONFIG(clipboard)
+- if (auto *dataDevice = mParent->dataDevice())
+- dataDevice->invalidateSelectionOffer();
+-#endif
+-#if QT_CONFIG(wayland_client_primary_selection)
+- if (auto *device = mParent->primarySelectionDevice())
+- device->invalidateSelectionOffer();
+-#endif
+ mParent->mQDisplay->handleKeyboardFocusChanged(mParent);
+ mRepeatTimer.stop();
+ }
+@@ -1396,6 +1388,7 @@ void QWaylandInputDevice::Touch::touch_cancel()
+ if (touchExt)
+ touchExt->touchCanceled();
+
++ mFocus = nullptr;
+ QWindowSystemInterface::handleTouchCancelEvent(nullptr, mParent->mTouchDevice);
+ }
+
+diff --git a/qtwayland/src/client/qwaylandintegration.cpp b/qtwayland/src/client/qwaylandintegration.cpp
+index c53ccb78..54861600 100644
+--- a/qtwayland/src/client/qwaylandintegration.cpp
++++ b/qtwayland/src/client/qwaylandintegration.cpp
+@@ -125,6 +125,9 @@ QWaylandIntegration::QWaylandIntegration()
+ #endif
+
+ reconfigureInputContext();
++
++ QWaylandWindow::fixedToplevelPositions =
++ !qEnvironmentVariableIsSet("QT_WAYLAND_DISABLE_FIXED_POSITIONS");
+ }
+
+ QWaylandIntegration::~QWaylandIntegration()
+@@ -192,14 +195,18 @@ QAbstractEventDispatcher *QWaylandIntegration::createEventDispatcher() const
+
+ void QWaylandIntegration::initialize()
+ {
++ mDisplay->initEventThread();
++
++ // 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()));
+
+- 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()));
+-
+ // Qt does not support running with no screens
+ mDisplay->ensureScreen();
+ }
+@@ -262,6 +269,14 @@ QWaylandDisplay *QWaylandIntegration::display() const
+ return mDisplay.data();
+ }
+
++Qt::KeyboardModifiers QWaylandIntegration::queryKeyboardModifiers() const
++{
++ if (auto *seat = mDisplay->currentInputDevice()) {
++ return seat->modifiers();
++ }
++ return Qt::NoModifier;
++}
++
+ QList<int> QWaylandIntegration::possibleKeys(const QKeyEvent *event) const
+ {
+ if (auto *seat = mDisplay->currentInputDevice())
+@@ -479,7 +494,7 @@ void QWaylandIntegration::reconfigureInputContext()
+ }
+ #endif
+
+- qCDebug(lcQpaWayland) << "using input method:" << inputContext()->metaObject()->className();
++ qCDebug(lcQpaWayland) << "using input method:" << (inputContext() ? inputContext()->metaObject()->className() : "<none>");
+ }
+
+ QWaylandShellIntegration *QWaylandIntegration::createShellIntegration(const QString &integrationName)
+diff --git a/qtwayland/src/client/qwaylandintegration_p.h b/qtwayland/src/client/qwaylandintegration_p.h
+index ff70ae25..73b80658 100644
+--- a/qtwayland/src/client/qwaylandintegration_p.h
++++ b/qtwayland/src/client/qwaylandintegration_p.h
+@@ -107,6 +107,8 @@ public:
+
+ QWaylandDisplay *display() const;
+
++ Qt::KeyboardModifiers queryKeyboardModifiers() const override;
++
+ QList<int> possibleKeys(const QKeyEvent *event) const override;
+
+ QStringList themeNames() const override;
+diff --git a/qtwayland/src/client/qwaylandprimaryselectionv1.cpp b/qtwayland/src/client/qwaylandprimaryselectionv1.cpp
+index 832f9678..ea508771 100644
+--- a/qtwayland/src/client/qwaylandprimaryselectionv1.cpp
++++ b/qtwayland/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)
+diff --git a/qtwayland/src/client/qwaylandscreen.cpp b/qtwayland/src/client/qwaylandscreen.cpp
+index 6cb337de..5537dafd 100644
+--- a/qtwayland/src/client/qwaylandscreen.cpp
++++ b/qtwayland/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))
+@@ -72,7 +72,7 @@ QWaylandScreen::QWaylandScreen(QWaylandDisplay *waylandDisplay, int version, uin
+ qCWarning(lcQpaWayland) << "wl_output done event not supported by compositor,"
+ << "QScreen may not work correctly";
+ mWaylandDisplay->forceRoundTrip(); // Give the compositor a chance to send geometry etc.
+- mOutputDone = true; // Fake the done event
++ mProcessedEvents |= OutputDoneEvent; // Fake the done event
+ maybeInitialize();
+ }
+ }
+@@ -81,16 +81,29 @@ 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
++{
++ uint ret = OutputDoneEvent;
++
++ if (mWaylandDisplay->xdgOutputManager()) {
++ ret |= XdgOutputNameEvent;
++
++ if (mWaylandDisplay->xdgOutputManager()->version() < 3)
++ ret |= XdgOutputDoneEvent;
++ }
++ return ret;
+ }
+
+ void QWaylandScreen::maybeInitialize()
+ {
+ Q_ASSERT(!mInitialized);
+
+- if (!mOutputDone)
+- return;
+-
+- if (mWaylandDisplay->xdgOutputManager() && !mXdgOutputDone)
++ const uint requiredEvents = this->requiredEvents();
++ if ((mProcessedEvents & requiredEvents) != requiredEvents)
+ return;
+
+ mInitialized = true;
+@@ -276,9 +289,8 @@ void QWaylandScreen::output_scale(int32_t factor)
+
+ void QWaylandScreen::output_done()
+ {
+- mOutputDone = true;
+- if (zxdg_output_v1::isInitialized() && mWaylandDisplay->xdgOutputManager()->version() >= 3)
+- mXdgOutputDone = true;
++ mProcessedEvents |= OutputDoneEvent;
++
+ if (mInitialized) {
+ updateOutputProperties();
+ if (zxdg_output_v1::isInitialized())
+@@ -339,7 +351,7 @@ void QWaylandScreen::zxdg_output_v1_done()
+ if (Q_UNLIKELY(mWaylandDisplay->xdgOutputManager()->version() >= 3))
+ qWarning(lcQpaWayland) << "zxdg_output_v1.done received on version 3 or newer, this is most likely a bug in the compositor";
+
+- mXdgOutputDone = true;
++ mProcessedEvents |= XdgOutputDoneEvent;
+ if (mInitialized)
+ updateXdgOutputProperties();
+ else
+@@ -348,7 +360,11 @@ void QWaylandScreen::zxdg_output_v1_done()
+
+ void QWaylandScreen::zxdg_output_v1_name(const QString &name)
+ {
++ if (Q_UNLIKELY(mInitialized))
++ qWarning(lcQpaWayland) << "zxdg_output_v1.name received after output has been initialized, this is most likely a bug in the compositor";
++
+ mOutputName = name;
++ mProcessedEvents |= XdgOutputNameEvent;
+ }
+
+ void QWaylandScreen::updateXdgOutputProperties()
+diff --git a/qtwayland/src/client/qwaylandscreen_p.h b/qtwayland/src/client/qwaylandscreen_p.h
+index df1c94f2..050cfdc0 100644
+--- a/qtwayland/src/client/qwaylandscreen_p.h
++++ b/qtwayland/src/client/qwaylandscreen_p.h
+@@ -116,6 +116,13 @@ public:
+ static QWaylandScreen *fromWlOutput(::wl_output *output);
+
+ private:
++ enum Event : uint {
++ XdgOutputDoneEvent = 0x1,
++ OutputDoneEvent = 0x2,
++ XdgOutputNameEvent = 0x4,
++ };
++ uint requiredEvents() const;
++
+ void output_mode(uint32_t flags, int width, int height, int refresh) override;
+ void output_geometry(int32_t x, int32_t y,
+ int32_t width, int32_t height,
+@@ -148,8 +155,7 @@ private:
+ QSize mPhysicalSize;
+ QString mOutputName;
+ Qt::ScreenOrientation m_orientation = Qt::PrimaryOrientation;
+- bool mOutputDone = false;
+- bool mXdgOutputDone = false;
++ uint mProcessedEvents = 0;
+ bool mInitialized = false;
+
+ #if QT_CONFIG(cursor)
+diff --git a/qtwayland/src/client/qwaylandshmbackingstore.cpp b/qtwayland/src/client/qwaylandshmbackingstore.cpp
+index dc7ff670..41cffdf7 100644
+--- a/qtwayland/src/client/qwaylandshmbackingstore.cpp
++++ b/qtwayland/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
+@@ -74,8 +78,10 @@ QWaylandShmBuffer::QWaylandShmBuffer(QWaylandDisplay *display,
+ int alloc = stride * size.height();
+ int fd = -1;
+
+-#ifdef SYS_memfd_create
+- fd = syscall(SYS_memfd_create, "wayland-shm", MFD_CLOEXEC);
++#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);
+ #endif
+
+ QScopedPointer<QFile> filePointer;
+diff --git a/qtwayland/src/client/qwaylandwindow.cpp b/qtwayland/src/client/qwaylandwindow.cpp
+index cb82857a..fb2c59dc 100644
+--- a/qtwayland/src/client/qwaylandwindow.cpp
++++ b/qtwayland/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,9 +94,6 @@ QWaylandWindow::QWaylandWindow(QWindow *window, QWaylandDisplay *display)
+
+ QWaylandWindow::~QWaylandWindow()
+ {
+- mDisplay->destroyFrameQueue(mFrameQueue);
+- mDisplay->handleWindowDestroyed(this);
+-
+ delete mWindowDecoration;
+
+ if (mSurface)
+@@ -243,6 +239,7 @@ bool QWaylandWindow::shouldCreateSubSurface() const
+
+ void QWaylandWindow::reset()
+ {
++ closeChildPopups();
+ delete mShellSurface;
+ mShellSurface = nullptr;
+ delete mSubSurfaceWindow;
+@@ -255,17 +252,22 @@ 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();
+ mQueuedBuffer = nullptr;
++
++ mDisplay->handleWindowDestroyed(this);
+ }
+
+ QWaylandWindow *QWaylandWindow::fromWlSurface(::wl_surface *surface)
+@@ -351,19 +353,25 @@ 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()) {
+ 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());
+@@ -374,7 +382,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)
+@@ -399,21 +407,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);
+@@ -433,10 +426,7 @@ void QWaylandWindow::setVisible(bool visible)
+ lastVisible = visible;
+
+ if (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
+@@ -444,7 +434,6 @@ void QWaylandWindow::setVisible(bool visible)
+ // QWaylandShmBackingStore::beginPaint().
+ } else {
+ sendExposeEvent(QRect());
+- closePopups(this);
+ reset();
+ }
+ }
+@@ -556,12 +545,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();
+
+@@ -583,7 +572,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)
+@@ -619,8 +612,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();
+@@ -635,42 +634,53 @@ 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);
+- 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();
+
+ // 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;
+- };
++ 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();
++ };
+
++ 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();
+ }
+
+ 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";
+@@ -868,6 +878,17 @@ bool QWaylandWindow::createDecoration()
+ subsurf->set_position(pos.x() + m.left(), pos.y() + m.top());
+ }
+ sendExposeEvent(QRect(QPoint(), geometry().size()));
++
++ // This is a special case where the buffer is recreated, but since
++ // the content rect remains the same, the widgets remain the same
++ // size and are not redrawn, leaving the new buffer empty. As a simple
++ // work-around, we trigger a full extra update whenever the client-side
++ // window decorations are toggled while the window is showing.
++ // Note: createDecoration() is sometimes called from the render thread
++ // of Qt Quick. This is essentially wrong and could potentially cause problems,
++ // but until the underlying issue has been fixed, we have to use invokeMethod()
++ // here to avoid asserts.
++ QMetaObject::invokeMethod(window(), &QWindow::requestUpdate);
+ }
+
+ return mWindowDecoration;
+@@ -1023,6 +1044,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) {
+@@ -1094,10 +1122,18 @@ bool QWaylandWindow::setMouseGrabEnabled(bool grab)
+ return true;
+ }
+
++Qt::WindowStates QWaylandWindow::windowStates() const
++{
++ return mLastReportedWindowStates;
++}
++
+ void QWaylandWindow::handleWindowStatesChanged(Qt::WindowStates states)
+ {
+ createDecoration();
+- QWindowSystemInterface::handleWindowStateChanged(window(), states, mLastReportedWindowStates);
++ Qt::WindowStates statesWithoutActive = states & ~Qt::WindowActive;
++ Qt::WindowStates lastStatesWithoutActive = mLastReportedWindowStates & ~Qt::WindowActive;
++ QWindowSystemInterface::handleWindowStateChanged(window(), statesWithoutActive,
++ lastStatesWithoutActive);
+ mLastReportedWindowStates = states;
+ }
+
+@@ -1139,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()
+@@ -1160,8 +1201,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
+@@ -1174,7 +1218,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);
+ }
+@@ -1185,19 +1234,18 @@ void QWaylandWindow::requestUpdate()
+ void QWaylandWindow::handleUpdate()
+ {
+ qCDebug(lcWaylandBackingstore) << "handleUpdate" << QThread::currentThread();
++
+ // TODO: Should sync subsurfaces avoid requesting frame callbacks?
+ QReadLocker lock(&mSurfaceLock);
+ if (!mSurface)
+ return;
+
+- if (mFrameCallback) {
+- wl_callback_destroy(mFrameCallback);
+- mFrameCallback = nullptr;
+- }
++ QMutexLocker locker(&mFrameSyncMutex);
++ if (mWaitingForFrameCallback)
++ return;
+
+- 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);
++ 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);
+@@ -1207,6 +1255,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);
+@@ -1267,6 +1317,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/qtwayland/src/client/qwaylandwindow_p.h b/qtwayland/src/client/qwaylandwindow_p.h
+index 01337cff..2f219d8c 100644
+--- a/qtwayland/src/client/qwaylandwindow_p.h
++++ b/qtwayland/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;
+@@ -148,6 +151,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;
+@@ -206,6 +210,10 @@ public:
+ void handleUpdate();
+ void deliverUpdateRequest() override;
+
++ void addChildPopup(QWaylandWindow* child);
++ void removeChildPopup(QWaylandWindow* child);
++ void closeChildPopups();
++
+ public slots:
+ void applyConfigure();
+
+@@ -215,7 +223,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;
+@@ -225,13 +237,14 @@ protected:
+ Qt::MouseButtons mMousePressedInContentArea = Qt::NoButton;
+
+ 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;
+- QWaylandDisplay::FrameQueue mFrameQueue;
++ 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;
+
+ // True when we have called deliverRequestUpdate, but the client has not yet attached a new buffer
+@@ -261,6 +274,8 @@ protected:
+ QWaylandBuffer *mQueuedBuffer = nullptr;
+ QRegion mQueuedBufferDamage;
+
++ QList<QPointer<QWaylandWindow>> mChildPopups;
++
+ private:
+ void setGeometry_helper(const QRect &rect);
+ void initWindow();
+@@ -283,12 +298,10 @@ private:
+ QRect mLastExposeGeometry;
+
+ static const wl_callback_listener callbackListener;
+- void handleFrameCallback();
++ void handleFrameCallback(struct ::wl_callback* callback);
+
+ static QWaylandWindow *mMouseGrab;
+
+- mutable QReadWriteLock mSurfaceLock;
+-
+ friend class QWaylandSubSurface;
+ };
+
+diff --git a/qtwayland/src/client/shellintegration/qwaylandshellintegration_p.h b/qtwayland/src/client/shellintegration/qwaylandshellintegration_p.h
+index ccad0048..4cc9b3b8 100644
+--- a/qtwayland/src/client/shellintegration/qwaylandshellintegration_p.h
++++ b/qtwayland/src/client/shellintegration/qwaylandshellintegration_p.h
+@@ -73,11 +73,10 @@ public:
+ return true;
+ }
+ virtual QWaylandShellSurface *createShellSurface(QWaylandWindow *window) = 0;
++ // kept for binary compat with layer-shell-qt
+ virtual void handleKeyboardFocusChanged(QWaylandWindow *newFocus, QWaylandWindow *oldFocus) {
+- if (newFocus)
+- m_display->handleWindowActivated(newFocus);
+- if (oldFocus)
+- m_display->handleWindowDeactivated(oldFocus);
++ Q_UNUSED(newFocus);
++ Q_UNUSED(oldFocus);
+ }
+ virtual void *nativeResourceForWindow(const QByteArray &resource, QWindow *window) {
+ Q_UNUSED(resource);
+diff --git a/qtwayland/src/compositor/configure.json b/qtwayland/src/compositor/configure.json
+index bcfd5215..da95d07b 100644
+--- a/qtwayland/src/compositor/configure.json
++++ b/qtwayland/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"
+ }
+ },
+
+diff --git a/qtwayland/src/hardwareintegration/client/wayland-egl/qwaylandeglwindow.cpp b/qtwayland/src/hardwareintegration/client/wayland-egl/qwaylandeglwindow.cpp
+index 7889f575..64140672 100644
+--- a/qtwayland/src/hardwareintegration/client/wayland-egl/qwaylandeglwindow.cpp
++++ b/qtwayland/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>
+@@ -124,6 +125,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();
+@@ -131,14 +133,16 @@ void QWaylandEglWindow::updateSurface(bool create)
+ if (!disableResizeCheck) {
+ wl_egl_window_get_attached_size(m_waylandEglWindow, ¤t_width, ¤t_height);
+ }
+- if (disableResizeCheck || (current_width != sizeWithMargins.width() || current_height != sizeWithMargins.height())) {
++ if (disableResizeCheck || (current_width != sizeWithMargins.width() || current_height != sizeWithMargins.height()) || m_requestedSize != sizeWithMargins) {
+ wl_egl_window_resize(m_waylandEglWindow, sizeWithMargins.width(), sizeWithMargins.height(), mOffset.x(), mOffset.y());
++ m_requestedSize = sizeWithMargins;
+ mOffset = QPoint();
+
+ 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;
+ }
+
+ if (!m_eglSurface && m_waylandEglWindow && create) {
+diff --git a/qtwayland/src/hardwareintegration/client/wayland-egl/qwaylandeglwindow.h b/qtwayland/src/hardwareintegration/client/wayland-egl/qwaylandeglwindow.h
+index 5b1f4d56..0079dfef 100644
+--- a/qtwayland/src/hardwareintegration/client/wayland-egl/qwaylandeglwindow.h
++++ b/qtwayland/src/hardwareintegration/client/wayland-egl/qwaylandeglwindow.h
+@@ -88,6 +88,7 @@ private:
+ mutable QOpenGLFramebufferObject *m_contentFBO = nullptr;
+
+ QSurfaceFormat m_format;
++ QSize m_requestedSize;
+ };
+
+ }
+diff --git a/qtwayland/src/hardwareintegration/compositor/linux-dmabuf-unstable-v1/linuxdmabuf.h b/qtwayland/src/hardwareintegration/compositor/linux-dmabuf-unstable-v1/linuxdmabuf.h
+index 56a710c3..c6a8b6c6 100644
+--- a/qtwayland/src/hardwareintegration/compositor/linux-dmabuf-unstable-v1/linuxdmabuf.h
++++ b/qtwayland/src/hardwareintegration/compositor/linux-dmabuf-unstable-v1/linuxdmabuf.h
+@@ -41,6 +41,8 @@
+ #include <QtCore/QTextStream>
+ #include <QtGui/QOpenGLTexture>
+
++#include <array>
++
+ #include <EGL/egl.h>
+ #include <EGL/eglext.h>
+
+diff --git a/qtwayland/src/plugins/decorations/bradient/main.cpp b/qtwayland/src/plugins/decorations/bradient/main.cpp
+index e75fda3c..fa885143 100644
+--- a/qtwayland/src/plugins/decorations/bradient/main.cpp
++++ b/qtwayland/src/plugins/decorations/bradient/main.cpp
+@@ -164,13 +164,10 @@ void QWaylandBradientDecoration::paint(QPaintDevice *device)
+ // Window icon
+ QIcon icon = waylandWindow()->windowIcon();
+ if (!icon.isNull()) {
+- QPixmap pixmap = icon.pixmap(QSize(128, 128));
+- QPixmap scaled = pixmap.scaled(22, 22, Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
+-
+ QRectF iconRect(0, 0, 22, 22);
+- p.drawPixmap(iconRect.adjusted(margins().left() + BUTTON_SPACING, 4,
+- margins().left() + BUTTON_SPACING, 4),
+- scaled, iconRect);
++ iconRect.adjust(margins().left() + BUTTON_SPACING, 4,
++ margins().left() + BUTTON_SPACING, 4),
++ icon.paint(&p, iconRect.toRect());
+ }
+
+ // Window title
+diff --git a/qtwayland/src/plugins/shellintegration/xdg-shell-v5/qwaylandxdgpopupv5.cpp b/qtwayland/src/plugins/shellintegration/xdg-shell-v5/qwaylandxdgpopupv5.cpp
+index 85d25e3c..60bdd491 100644
+--- a/qtwayland/src/plugins/shellintegration/xdg-shell-v5/qwaylandxdgpopupv5.cpp
++++ b/qtwayland/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/qtwayland/src/plugins/shellintegration/xdg-shell-v5/qwaylandxdgpopupv5_p.h b/qtwayland/src/plugins/shellintegration/xdg-shell-v5/qwaylandxdgpopupv5_p.h
+index 7494f6a6..d85f130b 100644
+--- a/qtwayland/src/plugins/shellintegration/xdg-shell-v5/qwaylandxdgpopupv5_p.h
++++ b/qtwayland/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/qtwayland/src/plugins/shellintegration/xdg-shell-v5/qwaylandxdgshellv5.cpp b/qtwayland/src/plugins/shellintegration/xdg-shell-v5/qwaylandxdgshellv5.cpp
+index 7e242c4a..def8452a 100644
+--- a/qtwayland/src/plugins/shellintegration/xdg-shell-v5/qwaylandxdgshellv5.cpp
++++ b/qtwayland/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/qtwayland/src/plugins/shellintegration/xdg-shell-v5/qwaylandxdgshellv5integration.cpp b/qtwayland/src/plugins/shellintegration/xdg-shell-v5/qwaylandxdgshellv5integration.cpp
+index 4e25949f..cfc60939 100644
+--- a/qtwayland/src/plugins/shellintegration/xdg-shell-v5/qwaylandxdgshellv5integration.cpp
++++ b/qtwayland/src/plugins/shellintegration/xdg-shell-v5/qwaylandxdgshellv5integration.cpp
+@@ -85,13 +85,6 @@ QWaylandShellSurface *QWaylandXdgShellV5Integration::createShellSurface(QWayland
+ return m_xdgShell->createXdgSurface(window);
+ }
+
+-void QWaylandXdgShellV5Integration::handleKeyboardFocusChanged(QWaylandWindow *newFocus, QWaylandWindow *oldFocus) {
+- if (newFocus && qobject_cast<QWaylandXdgPopupV5 *>(newFocus->shellSurface()))
+- m_display->handleWindowActivated(newFocus);
+- if (oldFocus && qobject_cast<QWaylandXdgPopupV5 *>(oldFocus->shellSurface()))
+- m_display->handleWindowDeactivated(oldFocus);
+-}
+-
+ }
+
+ QT_END_NAMESPACE
+diff --git a/qtwayland/src/plugins/shellintegration/xdg-shell-v5/qwaylandxdgshellv5integration_p.h b/qtwayland/src/plugins/shellintegration/xdg-shell-v5/qwaylandxdgshellv5integration_p.h
+index ce6bdb9e..aed88670 100644
+--- a/qtwayland/src/plugins/shellintegration/xdg-shell-v5/qwaylandxdgshellv5integration_p.h
++++ b/qtwayland/src/plugins/shellintegration/xdg-shell-v5/qwaylandxdgshellv5integration_p.h
+@@ -67,7 +67,6 @@ public:
+ QWaylandXdgShellV5Integration() {}
+ bool initialize(QWaylandDisplay *display) override;
+ QWaylandShellSurface *createShellSurface(QWaylandWindow *window) override;
+- void handleKeyboardFocusChanged(QWaylandWindow *newFocus, QWaylandWindow *oldFocus) override;
+
+ private:
+ QScopedPointer<QWaylandXdgShellV5> m_xdgShell;
+diff --git a/qtwayland/src/plugins/shellintegration/xdg-shell-v6/qwaylandxdgshellv6.cpp b/qtwayland/src/plugins/shellintegration/xdg-shell-v6/qwaylandxdgshellv6.cpp
+index 8c371661..151c78e3 100644
+--- a/qtwayland/src/plugins/shellintegration/xdg-shell-v6/qwaylandxdgshellv6.cpp
++++ b/qtwayland/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/qtwayland/src/plugins/shellintegration/xdg-shell-v6/qwaylandxdgshellv6integration.cpp b/qtwayland/src/plugins/shellintegration/xdg-shell-v6/qwaylandxdgshellv6integration.cpp
+index 03164316..e8da8ba1 100644
+--- a/qtwayland/src/plugins/shellintegration/xdg-shell-v6/qwaylandxdgshellv6integration.cpp
++++ b/qtwayland/src/plugins/shellintegration/xdg-shell-v6/qwaylandxdgshellv6integration.cpp
+@@ -68,20 +68,6 @@ QWaylandShellSurface *QWaylandXdgShellV6Integration::createShellSurface(QWayland
+ return m_xdgShell->getXdgSurface(window);
+ }
+
+-void QWaylandXdgShellV6Integration::handleKeyboardFocusChanged(QWaylandWindow *newFocus, QWaylandWindow *oldFocus)
+-{
+- if (newFocus) {
+- auto *xdgSurface = qobject_cast<QWaylandXdgSurfaceV6 *>(newFocus->shellSurface());
+- if (xdgSurface && !xdgSurface->handlesActiveState())
+- m_display->handleWindowActivated(newFocus);
+- }
+- if (oldFocus && qobject_cast<QWaylandXdgSurfaceV6 *>(oldFocus->shellSurface())) {
+- auto *xdgSurface = qobject_cast<QWaylandXdgSurfaceV6 *>(oldFocus->shellSurface());
+- if (xdgSurface && !xdgSurface->handlesActiveState())
+- m_display->handleWindowDeactivated(oldFocus);
+- }
+-}
+-
+ }
+
+ QT_END_NAMESPACE
+diff --git a/qtwayland/src/plugins/shellintegration/xdg-shell-v6/qwaylandxdgshellv6integration_p.h b/qtwayland/src/plugins/shellintegration/xdg-shell-v6/qwaylandxdgshellv6integration_p.h
+index 261f8cbb..c1bcd5c6 100644
+--- a/qtwayland/src/plugins/shellintegration/xdg-shell-v6/qwaylandxdgshellv6integration_p.h
++++ b/qtwayland/src/plugins/shellintegration/xdg-shell-v6/qwaylandxdgshellv6integration_p.h
+@@ -65,7 +65,6 @@ public:
+ QWaylandXdgShellV6Integration() {}
+ bool initialize(QWaylandDisplay *display) override;
+ QWaylandShellSurface *createShellSurface(QWaylandWindow *window) override;
+- void handleKeyboardFocusChanged(QWaylandWindow *newFocus, QWaylandWindow *oldFocus) override;
+
+ private:
+ QScopedPointer<QWaylandXdgShellV6> m_xdgShell;
+diff --git a/qtwayland/src/plugins/shellintegration/xdg-shell/qwaylandxdgshell.cpp b/qtwayland/src/plugins/shellintegration/xdg-shell/qwaylandxdgshell.cpp
+index f3e3c330..fa6d5808 100644
+--- a/qtwayland/src/plugins/shellintegration/xdg-shell/qwaylandxdgshell.cpp
++++ b/qtwayland/src/plugins/shellintegration/xdg-shell/qwaylandxdgshell.cpp
+@@ -67,11 +67,6 @@ QWaylandXdgSurface::Toplevel::Toplevel(QWaylandXdgSurface *xdgSurface)
+
+ QWaylandXdgSurface::Toplevel::~Toplevel()
+ {
+- if (m_applied.states & Qt::WindowActive) {
+- QWaylandWindow *window = m_xdgSurface->window();
+- window->display()->handleWindowDeactivated(window);
+- }
+-
+ // The protocol spec requires that the decoration object is deleted before xdg_toplevel.
+ delete m_decoration;
+ m_decoration = nullptr;
+@@ -85,16 +80,15 @@ void QWaylandXdgSurface::Toplevel::applyConfigure()
+ if (!(m_applied.states & (Qt::WindowMaximized|Qt::WindowFullScreen)))
+ 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)
++ && !m_xdgSurface->m_window->display()->isKeyboardAvailable())
+ 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)
++ && !m_xdgSurface->m_window->display()->isKeyboardAvailable())
+ m_xdgSurface->m_window->display()->handleWindowDeactivated(m_xdgSurface->m_window);
+
+- // TODO: none of the other plugins send WindowActive either, but is it on purpose?
+- Qt::WindowStates statesWithoutActive = m_pending.states & ~Qt::WindowActive;
+-
+- m_xdgSurface->m_window->handleWindowStatesChanged(statesWithoutActive);
++ m_xdgSurface->m_window->handleWindowStatesChanged(m_pending.states);
+
+ if (m_pending.size.isEmpty()) {
+ // An empty size in the configure means it's up to the client to choose the size
+@@ -105,8 +99,6 @@ void QWaylandXdgSurface::Toplevel::applyConfigure()
+ m_xdgSurface->m_window->resizeFromApplyConfigure(m_pending.size);
+ }
+
+- m_xdgSurface->setSizeHints();
+-
+ m_applied = m_pending;
+ qCDebug(lcQpaWayland) << "Applied pending xdg_toplevel configure event:" << m_applied.size << m_applied.states;
+ }
+@@ -203,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()
+@@ -216,10 +213,24 @@ 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
++ QWindow *leave = nullptr;
++ if (m_xdgSurface && m_xdgSurface->window())
++ leave = m_xdgSurface->window()->window();
++ QWindowSystemInterface::handleLeaveEvent(leave);
++
++ if (QWindow *enter = QGuiApplication::topLevelAt(QCursor::pos()))
++ QWindowSystemInterface::handleEnterEvent(enter, enter->mapFromGlobal(QCursor::pos()), QCursor::pos());
+ }
+ }
+
+@@ -257,6 +268,7 @@ QWaylandXdgSurface::QWaylandXdgSurface(QWaylandXdgShell *shell, ::xdg_surface *s
+ m_toplevel->set_parent(parentXdgSurface->m_toplevel->object());
+ }
+ }
++ setSizeHints();
+ }
+
+ QWaylandXdgSurface::~QWaylandXdgSurface()
+@@ -400,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
+@@ -414,8 +424,9 @@ void QWaylandXdgSurface::setPopup(QWaylandWindow *parent)
+ positioner->set_anchor(QtWayland::xdg_positioner::anchor_top_left);
+ positioner->set_gravity(QtWayland::xdg_positioner::gravity_bottom_right);
+ positioner->set_size(m_window->geometry().width(), m_window->geometry().height());
+- m_popup = new Popup(this, parentXdgSurface, positioner);
++ m_popup = new Popup(this, parent, positioner);
+ positioner->destroy();
++
+ delete positioner;
+ }
+
+@@ -437,6 +448,23 @@ void QWaylandXdgSurface::setGrabPopup(QWaylandWindow *parent, QWaylandInputDevic
+ }
+ setPopup(parent);
+ m_popup->grab(device, serial);
++
++ // Synthesize Qt enter/leave events for popup
++ if (!parent)
++ return;
++ QWindow *current = QGuiApplication::topLevelAt(QCursor::pos());
++ QWindow *leave = parent->window();
++ if (current != leave)
++ return;
++
++ QWindowSystemInterface::handleLeaveEvent(leave);
++
++ QWindow *enter = nullptr;
++ if (m_popup && m_popup->m_xdgSurface && m_popup->m_xdgSurface->window())
++ enter = m_popup->m_xdgSurface->window()->window();
++
++ if (enter)
++ QWindowSystemInterface::handleEnterEvent(enter, enter->mapFromGlobal(QCursor::pos()), QCursor::pos());
+ }
+
+ void QWaylandXdgSurface::xdg_surface_configure(uint32_t serial)
+diff --git a/qtwayland/src/plugins/shellintegration/xdg-shell/qwaylandxdgshell_p.h b/qtwayland/src/plugins/shellintegration/xdg-shell/qwaylandxdgshell_p.h
+index 96785205..4b518f0a 100644
+--- a/qtwayland/src/plugins/shellintegration/xdg-shell/qwaylandxdgshell_p.h
++++ b/qtwayland/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/qtwayland/src/plugins/shellintegration/xdg-shell/qwaylandxdgshellintegration.cpp b/qtwayland/src/plugins/shellintegration/xdg-shell/qwaylandxdgshellintegration.cpp
+index 8769d971..da0dd6a7 100644
+--- a/qtwayland/src/plugins/shellintegration/xdg-shell/qwaylandxdgshellintegration.cpp
++++ b/qtwayland/src/plugins/shellintegration/xdg-shell/qwaylandxdgshellintegration.cpp
+@@ -69,20 +69,6 @@ QWaylandShellSurface *QWaylandXdgShellIntegration::createShellSurface(QWaylandWi
+ return m_xdgShell->getXdgSurface(window);
+ }
+
+-void QWaylandXdgShellIntegration::handleKeyboardFocusChanged(QWaylandWindow *newFocus, QWaylandWindow *oldFocus)
+-{
+- if (newFocus) {
+- auto *xdgSurface = qobject_cast<QWaylandXdgSurface *>(newFocus->shellSurface());
+- if (xdgSurface && !xdgSurface->handlesActiveState())
+- m_display->handleWindowActivated(newFocus);
+- }
+- if (oldFocus && qobject_cast<QWaylandXdgSurface *>(oldFocus->shellSurface())) {
+- auto *xdgSurface = qobject_cast<QWaylandXdgSurface *>(oldFocus->shellSurface());
+- if (xdgSurface && !xdgSurface->handlesActiveState())
+- m_display->handleWindowDeactivated(oldFocus);
+- }
+-}
+-
+ }
+
+ QT_END_NAMESPACE
+diff --git a/qtwayland/src/plugins/shellintegration/xdg-shell/qwaylandxdgshellintegration_p.h b/qtwayland/src/plugins/shellintegration/xdg-shell/qwaylandxdgshellintegration_p.h
+index b6caa6c9..2f929f98 100644
+--- a/qtwayland/src/plugins/shellintegration/xdg-shell/qwaylandxdgshellintegration_p.h
++++ b/qtwayland/src/plugins/shellintegration/xdg-shell/qwaylandxdgshellintegration_p.h
+@@ -65,7 +65,6 @@ public:
+ QWaylandXdgShellIntegration() {}
+ bool initialize(QWaylandDisplay *display) override;
+ QWaylandShellSurface *createShellSurface(QWaylandWindow *window) override;
+- void handleKeyboardFocusChanged(QWaylandWindow *newFocus, QWaylandWindow *oldFocus) override;
+
+ private:
+ QScopedPointer<QWaylandXdgShell> m_xdgShell;
+diff --git a/qtwayland/src/shared/qwaylandinputmethodeventbuilder.cpp b/qtwayland/src/shared/qwaylandinputmethodeventbuilder.cpp
+index 526d0ef4..f50ccf30 100644
+--- a/qtwayland/src/shared/qwaylandinputmethodeventbuilder.cpp
++++ b/qtwayland/src/shared/qwaylandinputmethodeventbuilder.cpp
+@@ -39,7 +39,10 @@
+
+ #include "qwaylandinputmethodeventbuilder_p.h"
+
++#include <QBrush>
++#include <QGuiApplication>
+ #include <QInputMethod>
++#include <QPalette>
+ #include <QTextCharFormat>
+
+ #ifdef QT_BUILD_WAYLANDCOMPOSITOR_LIB
+@@ -81,32 +84,38 @@ void QWaylandInputMethodEventBuilder::addPreeditStyling(uint32_t index, uint32_t
+ QTextCharFormat format;
+
+ switch (style) {
+- case 0:
+- case 1:
++ case ZWP_TEXT_INPUT_V2_PREEDIT_STYLE_NONE:
++ break;
++ case ZWP_TEXT_INPUT_V2_PREEDIT_STYLE_DEFAULT:
++ case ZWP_TEXT_INPUT_V2_PREEDIT_STYLE_UNDERLINE:
+ format.setFontUnderline(true);
+ format.setUnderlineStyle(QTextCharFormat::SingleUnderline);
+ m_preeditStyles.append(QInputMethodEvent::Attribute(QInputMethodEvent::TextFormat, index, length, format));
+ break;
+- case 2:
+- case 3:
++ case ZWP_TEXT_INPUT_V2_PREEDIT_STYLE_ACTIVE:
++ case ZWP_TEXT_INPUT_V2_PREEDIT_STYLE_INACTIVE:
+ format.setFontWeight(QFont::Bold);
+ format.setFontUnderline(true);
+ format.setUnderlineStyle(QTextCharFormat::SingleUnderline);
+ m_preeditStyles.append(QInputMethodEvent::Attribute(QInputMethodEvent::TextFormat, index, length, format));
+ break;
+- case 4:
+- format.setFontUnderline(true);
+- format.setUnderlineStyle(QTextCharFormat::SingleUnderline);
+- m_preeditStyles.append(QInputMethodEvent::Attribute(QInputMethodEvent::TextFormat, index, length, format));
++ case ZWP_TEXT_INPUT_V2_PREEDIT_STYLE_HIGHLIGHT:
++ case ZWP_TEXT_INPUT_V2_PREEDIT_STYLE_SELECTION:
++ {
++ format.setFontUnderline(true);
++ format.setUnderlineStyle(QTextCharFormat::SingleUnderline);
++ QPalette palette = qApp->palette();
++ format.setBackground(QBrush(palette.color(QPalette::Active, QPalette::Highlight)));
++ format.setForeground(QBrush(palette.color(QPalette::Active, QPalette::HighlightedText)));
++ m_preeditStyles.append(QInputMethodEvent::Attribute(QInputMethodEvent::TextFormat, index, length, format));
++ }
+ break;
+- case 5:
++ case ZWP_TEXT_INPUT_V2_PREEDIT_STYLE_INCORRECT:
+ format.setFontUnderline(true);
+ format.setUnderlineStyle(QTextCharFormat::WaveUnderline);
+ format.setUnderlineColor(QColor(Qt::red));
+ m_preeditStyles.append(QInputMethodEvent::Attribute(QInputMethodEvent::TextFormat, index, length, format));
+ break;
+-// case QtWayland::wl_text_input::preedit_style_selection:
+-// case QtWayland::wl_text_input::preedit_style_none:
+ default:
+ break;
+ }
+@@ -153,7 +162,7 @@ QInputMethodEvent QWaylandInputMethodEventBuilder::buildPreedit(const QString &t
+
+ if (m_preeditCursor < 0) {
+ attributes.append(QInputMethodEvent::Attribute(QInputMethodEvent::Cursor, 0, 0, QVariant()));
+- } else if (m_preeditCursor > 0) {
++ } else {
+ attributes.append(QInputMethodEvent::Attribute(QInputMethodEvent::Cursor, indexFromWayland(text, m_preeditCursor), 1, QVariant()));
+ }
+
+diff --git a/qtwayland/src/shared/qwaylandmimehelper.cpp b/qtwayland/src/shared/qwaylandmimehelper.cpp
+index a5fdd34d..e2fe1928 100644
+--- a/qtwayland/src/shared/qwaylandmimehelper.cpp
++++ b/qtwayland/src/shared/qwaylandmimehelper.cpp
+@@ -60,7 +60,7 @@ QByteArray QWaylandMimeHelper::getByteArray(QMimeData *mimeData, const QString &
+ buf.open(QIODevice::ReadWrite);
+ QByteArray fmt = "BMP";
+ if (mimeType.startsWith(QLatin1String("image/"))) {
+- QByteArray imgFmt = mimeType.mid(6).toUpper().toLatin1();
++ QByteArray imgFmt = mimeType.mid(6).toLower().toLatin1();
+ if (QImageWriter::supportedImageFormats().contains(imgFmt))
+ fmt = imgFmt;
+ }
+@@ -74,7 +74,7 @@ QByteArray QWaylandMimeHelper::getByteArray(QMimeData *mimeData, const QString &
+ QList<QUrl> urls = mimeData->urls();
+ for (int i = 0; i < urls.count(); ++i) {
+ content.append(urls.at(i).toEncoded());
+- content.append('\n');
++ content.append("\r\n");
+ }
+ } else {
+ content = mimeData->data(mimeType);
+diff --git a/qtwayland/tests/auto/client/datadevicev1/tst_datadevicev1.cpp b/qtwayland/tests/auto/client/datadevicev1/tst_datadevicev1.cpp
+index 1568b3b9..067410d0 100644
+--- a/qtwayland/tests/auto/client/datadevicev1/tst_datadevicev1.cpp
++++ b/qtwayland/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:
+diff --git a/qtwayland/tests/auto/client/seatv5/tst_seatv5.cpp b/qtwayland/tests/auto/client/seatv5/tst_seatv5.cpp
+index 9312c2e5..2ea382f1 100644
+--- a/qtwayland/tests/auto/client/seatv5/tst_seatv5.cpp
++++ b/qtwayland/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, Qt::TouchPointPressed);
++ QCOMPARE(e.touchPoints.length(), 1);
++ QCOMPARE(e.touchPoints.first().pos(), 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/qtwayland/tests/auto/client/shared/corecompositor.cpp b/qtwayland/tests/auto/client/shared/corecompositor.cpp
+index 5c6c83ba..fa9b7662 100644
+--- a/qtwayland/tests/auto/client/shared/corecompositor.cpp
++++ b/qtwayland/tests/auto/client/shared/corecompositor.cpp
+@@ -27,6 +27,7 @@
+ ****************************************************************************/
+
+ #include "corecompositor.h"
++#include <thread>
+
+ namespace MockCompositor {
+
+diff --git a/qtwayland/tests/auto/client/shared/coreprotocol.cpp b/qtwayland/tests/auto/client/shared/coreprotocol.cpp
+index 0d988521..d1a2e7cb 100644
+--- a/qtwayland/tests/auto/client/shared/coreprotocol.cpp
++++ b/qtwayland/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/qtwayland/tests/auto/client/shared/coreprotocol.h b/qtwayland/tests/auto/client/shared/coreprotocol.h
+index a1af137a..210d8ddb 100644
+--- a/qtwayland/tests/auto/client/shared/coreprotocol.h
++++ b/qtwayland/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)
+ {}
+@@ -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;
+ };
+diff --git a/qtwayland/tests/auto/client/shared_old/mockcompositor.cpp b/qtwayland/tests/auto/client/shared_old/mockcompositor.cpp
+index a415cbf5..b1d3d07d 100644
+--- a/qtwayland/tests/auto/client/shared_old/mockcompositor.cpp
++++ b/qtwayland/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/qtwayland/tests/auto/client/shared_old/mocksurface.cpp b/qtwayland/tests/auto/client/shared_old/mocksurface.cpp
+index e9df5f90..c3246e4a 100644
+--- a/qtwayland/tests/auto/client/shared_old/mocksurface.cpp
++++ b/qtwayland/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/qtwayland/tests/auto/client/shared_old/mocksurface.h b/qtwayland/tests/auto/client/shared_old/mocksurface.h
+index 949dc23d..d176837e 100644
+--- a/qtwayland/tests/auto/client/shared_old/mocksurface.h
++++ b/qtwayland/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;
+diff --git a/qtwayland/tests/auto/client/surface/tst_surface.cpp b/qtwayland/tests/auto/client/surface/tst_surface.cpp
+index 95e4e609..60c672ce 100644
+--- a/qtwayland/tests/auto/client/surface/tst_surface.cpp
++++ b/qtwayland/tests/auto/client/surface/tst_surface.cpp
+@@ -129,6 +129,10 @@ void tst_surface::waitForFrameCallbackGl()
+ // Make sure we follow frame callbacks for some frames
+ for (int i = 0; i < 5; ++i) {
+ xdgPingAndWaitForPong(); // Make sure things have happened on the client
++ if (!qEnvironmentVariableIntValue("QT_WAYLAND_DISABLE_WINDOWDECORATION") && i == 0) {
++ QCOMPARE(bufferSpy.count(), 1);
++ bufferSpy.removeFirst();
++ }
+ exec([&] {
+ QVERIFY(bufferSpy.empty()); // Make sure no extra buffers have arrived
+ QVERIFY(!xdgToplevel()->surface()->m_waitingFrameCallbacks.empty());
+diff --git a/qtwayland/tests/auto/client/xdgshell/tst_xdgshell.cpp b/qtwayland/tests/auto/client/xdgshell/tst_xdgshell.cpp
+index 2277bbb8..747875b4 100644
+--- a/qtwayland/tests/auto/client/xdgshell/tst_xdgshell.cpp
++++ b/qtwayland/tests/auto/client/xdgshell/tst_xdgshell.cpp
+@@ -31,6 +31,7 @@
+ #include <QtGui/QOpenGLWindow>
+ #include <QtGui/qpa/qplatformnativeinterface.h>
+ #include <QtWaylandClient/private/wayland-wayland-client-protocol.h>
++#include <QtWaylandClient/private/qwaylandwindow_p.h>
+
+ using namespace MockCompositor;
+
+@@ -45,6 +46,7 @@ private slots:
+ void configureStates();
+ void popup();
+ void tooltipOnPopup();
++ void tooltipAndSiblingPopup();
+ void switchPopups();
+ void hidePopupParent();
+ void pongs();
+@@ -138,6 +140,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();
+@@ -154,9 +157,12 @@ void tst_xdgshell::configureStates()
+ // 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
+
+-// QEXPECT_FAIL("", "configure has already been acked, we shouldn't have to wait for isActive", Continue);
+-// QVERIFY(window.isActive());
+- QTRY_VERIFY(window.isActive()); // Just make sure it eventually get's set correctly
++ // window.windowstate() is driven by keyboard focus, however for decorations we want to follow
++ // XDGShell this is internal to QtWayland so it is queried directly
++ auto waylandWindow = static_cast<QtWaylandClient::QWaylandWindow *>(window.handle());
++ Q_ASSERT(waylandWindow);
++ QTRY_VERIFY(waylandWindow->windowStates().testFlag(
++ Qt::WindowActive)); // Just make sure it eventually get's set correctly
+
+ const QSize screenSize(640, 480);
+ const uint maximizedSerial = exec([=] {
+@@ -186,6 +192,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()
+@@ -340,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()
+ {
+@@ -505,7 +598,7 @@ void tst_xdgshell::minMaxSize()
+ window.show();
+ QCOMPOSITOR_TRY_VERIFY(xdgToplevel());
+
+- exec([=] { xdgToplevel()->sendCompleteConfigure(); });
++ // we don't roundtrip with our configuration the initial commit should be correct
+
+ QCOMPOSITOR_TRY_COMPARE(xdgToplevel()->m_committed.minSize, QSize(100, 100));
+ QCOMPOSITOR_TRY_COMPARE(xdgToplevel()->m_committed.maxSize, QSize(1000, 1000));
+Submodule qtwebchannel 618422ee..f8949655:
+diff --git a/qtwebchannel/src/webchannel/qmetaobjectpublisher.cpp b/qtwebchannel/src/webchannel/qmetaobjectpublisher.cpp
+index 536eb5c..898d769 100644
+--- a/qtwebchannel/src/webchannel/qmetaobjectpublisher.cpp
++++ b/qtwebchannel/src/webchannel/qmetaobjectpublisher.cpp
+@@ -186,8 +186,6 @@ Q_DECLARE_TYPEINFO(OverloadResolutionCandidate, Q_MOVABLE_TYPE);
+ QMetaObjectPublisher::QMetaObjectPublisher(QWebChannel *webChannel)
+ : QObject(webChannel)
+ , webChannel(webChannel)
+- , signalHandler(this)
+- , clientIsIdle(false)
+ , blockUpdates(false)
+ , propertyUpdatesInitialized(false)
+ {
+@@ -301,17 +299,17 @@ QJsonObject QMetaObjectPublisher::classInfoForObject(const QObject *object, QWeb
+ return data;
+ }
+
+-void QMetaObjectPublisher::setClientIsIdle(bool isIdle)
++void QMetaObjectPublisher::setClientIsIdle(bool isIdle, QWebChannelAbstractTransport *transport)
+ {
+- if (clientIsIdle == isIdle) {
+- return;
+- }
+- clientIsIdle = isIdle;
+- if (!isIdle && timer.isActive()) {
+- timer.stop();
+- } else if (isIdle && !timer.isActive()) {
+- timer.start(PROPERTY_UPDATE_INTERVAL, this);
+- }
++ transportState[transport].clientIsIdle = isIdle;
++ if (isIdle)
++ sendEnqueuedPropertyUpdates(transport);
++}
++
++bool QMetaObjectPublisher::isClientIdle(QWebChannelAbstractTransport *transport)
++{
++ auto found = transportState.find(transport);
++ return found != transportState.end() && found.value().clientIsIdle;
+ }
+
+ QJsonObject QMetaObjectPublisher::initializeClient(QWebChannelAbstractTransport *transport)
+@@ -333,6 +331,7 @@ QJsonObject QMetaObjectPublisher::initializeClient(QWebChannelAbstractTransport
+
+ void QMetaObjectPublisher::initializePropertyUpdates(const QObject *const object, const QJsonObject &objectInfo)
+ {
++ auto *signalHandler = signalHandlerFor(object);
+ foreach (const QJsonValue &propertyInfoVar, objectInfo[KEY_PROPERTIES].toArray()) {
+ const QJsonArray &propertyInfo = propertyInfoVar.toArray();
+ if (propertyInfo.size() < 2) {
+@@ -353,19 +352,19 @@ void QMetaObjectPublisher::initializePropertyUpdates(const QObject *const object
+
+ // Only connect for a property update once
+ if (connectedProperties.isEmpty()) {
+- signalHandler.connectTo(object, signalIndex);
++ signalHandler->connectTo(object, signalIndex);
+ }
+
+ connectedProperties.insert(propertyIndex);
+ }
+
+ // also always connect to destroyed signal
+- signalHandler.connectTo(object, s_destroyedSignalIndex);
++ signalHandler->connectTo(object, s_destroyedSignalIndex);
+ }
+
+ void QMetaObjectPublisher::sendPendingPropertyUpdates()
+ {
+- if (blockUpdates || !clientIsIdle || pendingPropertyUpdates.isEmpty()) {
++ if (blockUpdates) {
+ return;
+ }
+
+@@ -415,18 +414,19 @@ void QMetaObjectPublisher::sendPendingPropertyUpdates()
+
+ // data does not contain specific updates
+ if (!data.isEmpty()) {
+- setClientIsIdle(false);
+-
+ message[KEY_DATA] = data;
+- broadcastMessage(message);
++ enqueueBroadcastMessage(message);
+ }
+
+ // send every property update which is not supposed to be broadcasted
+ const QHash<QWebChannelAbstractTransport*, QJsonArray>::const_iterator suend = specificUpdates.constEnd();
+ for (QHash<QWebChannelAbstractTransport*, QJsonArray>::const_iterator it = specificUpdates.constBegin(); it != suend; ++it) {
+ message[KEY_DATA] = it.value();
+- it.key()->sendMessage(message);
++ enqueueMessage(message, it.key());
+ }
++
++ for (auto state = transportState.begin(); state != transportState.end(); ++state)
++ sendEnqueuedPropertyUpdates(state.key());
+ }
+
+ QVariant QMetaObjectPublisher::invokeMethod(QObject *const object, const QMetaMethod &method,
+@@ -572,7 +572,7 @@ void QMetaObjectPublisher::signalEmitted(const QObject *object, const int signal
+ }
+ } else {
+ pendingPropertyUpdates[object][signalIndex] = arguments;
+- if (clientIsIdle && !blockUpdates && !timer.isActive()) {
++ if (!blockUpdates && !timer.isActive()) {
+ timer.start(PROPERTY_UPDATE_INTERVAL, this);
+ }
+ }
+@@ -590,7 +590,7 @@ void QMetaObjectPublisher::objectDestroyed(const QObject *object)
+ // only remove from handler when we initialized the property updates
+ // cf: https://bugreports.qt.io/browse/QTBUG-60250
+ if (propertyUpdatesInitialized) {
+- signalHandler.remove(object);
++ signalHandlerFor(object)->remove(object);
+ signalToPropertyMap.remove(object);
+ }
+ pendingPropertyUpdates.remove(object);
+@@ -852,6 +852,52 @@ void QMetaObjectPublisher::broadcastMessage(const QJsonObject &message) const
+ }
+ }
+
++void QMetaObjectPublisher::enqueueBroadcastMessage(const QJsonObject &message)
++{
++ if (webChannel->d_func()->transports.isEmpty()) {
++ qWarning("QWebChannel is not connected to any transports, cannot send message: %s",
++ QJsonDocument(message).toJson().constData());
++ return;
++ }
++
++ for (auto *transport : webChannel->d_func()->transports) {
++ auto &state = transportState[transport];
++ state.queuedMessages.append(message);
++ }
++}
++
++void QMetaObjectPublisher::enqueueMessage(const QJsonObject &message,
++ QWebChannelAbstractTransport *transport)
++{
++ auto &state = transportState[transport];
++ state.queuedMessages.append(message);
++}
++
++void QMetaObjectPublisher::sendEnqueuedPropertyUpdates(QWebChannelAbstractTransport *transport)
++{
++ auto found = transportState.find(transport);
++ if (found != transportState.end() && found.value().clientIsIdle
++ && !found.value().queuedMessages.isEmpty()) {
++
++ // If the client is connected with an in-process transport, it can
++ // happen that a message triggers a subsequent property change. In
++ // that case, we need to ensure that the queued messages have already
++ // been cleared; otherwise the recursive call will send everythig again.
++ // Case in point: The qmlwebchannel tests fail if we don't clear the
++ // queued messages before sending them out.
++ // For that same reason set the client to "busy" (aka non-idle) just
++ // right before sending out the messages; otherwise a potential
++ // "Idle" type message will not correctly restore the Idle state.
++ const auto messages = std::move(found.value().queuedMessages);
++ Q_ASSERT(found.value().queuedMessages.isEmpty());
++ found.value().clientIsIdle = false;
++
++ for (const auto &message : messages) {
++ transport->sendMessage(message);
++ }
++ }
++}
++
+ void QMetaObjectPublisher::handleMessage(const QJsonObject &message, QWebChannelAbstractTransport *transport)
+ {
+ if (!webChannel->d_func()->transports.contains(transport)) {
+@@ -866,7 +912,7 @@ void QMetaObjectPublisher::handleMessage(const QJsonObject &message, QWebChannel
+
+ const MessageType type = toType(message.value(KEY_TYPE));
+ if (type == TypeIdle) {
+- setClientIsIdle(true);
++ setClientIsIdle(true, transport);
+ } else if (type == TypeInit) {
+ if (!message.contains(KEY_ID)) {
+ qWarning("JSON message object is missing the id property: %s",
+@@ -913,9 +959,9 @@ void QMetaObjectPublisher::handleMessage(const QJsonObject &message, QWebChannel
+ return;
+ transport->sendMessage(createResponse(message.value(KEY_ID), wrapResult(result, transport)));
+ } else if (type == TypeConnectToSignal) {
+- signalHandler.connectTo(object, message.value(KEY_SIGNAL).toInt(-1));
++ signalHandlerFor(object)->connectTo(object, message.value(KEY_SIGNAL).toInt(-1));
+ } else if (type == TypeDisconnectFromSignal) {
+- signalHandler.disconnectFrom(object, message.value(KEY_SIGNAL).toInt(-1));
++ signalHandlerFor(object)->disconnectFrom(object, message.value(KEY_SIGNAL).toInt(-1));
+ } else if (type == TypeSetProperty) {
+ setProperty(object, message.value(KEY_PROPERTY).toInt(-1),
+ message.value(KEY_VALUE));
+@@ -931,6 +977,7 @@ void QMetaObjectPublisher::setBlockUpdates(bool block)
+ blockUpdates = block;
+
+ if (!blockUpdates) {
++ timer.start(PROPERTY_UPDATE_INTERVAL, this);
+ sendPendingPropertyUpdates();
+ } else if (timer.isActive()) {
+ timer.stop();
+@@ -948,4 +995,15 @@ void QMetaObjectPublisher::timerEvent(QTimerEvent *event)
+ }
+ }
+
++SignalHandler<QMetaObjectPublisher> *QMetaObjectPublisher::signalHandlerFor(const QObject *object)
++{
++ auto thread = object->thread();
++ auto it = signalHandlers.find(thread);
++ if (it == signalHandlers.end()) {
++ it = signalHandlers.emplace(thread, this).first;
++ it->second.moveToThread(thread);
++ }
++ return &it->second;
++}
++
+ QT_END_NAMESPACE
+diff --git a/qtwebchannel/src/webchannel/qmetaobjectpublisher_p.h b/qtwebchannel/src/webchannel/qmetaobjectpublisher_p.h
+index bbd9875..4713ef1 100644
+--- a/qtwebchannel/src/webchannel/qmetaobjectpublisher_p.h
++++ b/qtwebchannel/src/webchannel/qmetaobjectpublisher_p.h
+@@ -59,6 +59,9 @@
+ #include <QBasicTimer>
+ #include <QPointer>
+ #include <QJsonObject>
++#include <QQueue>
++
++#include <unordered_map>
+
+ #include "qwebchannelglobal.h"
+
+@@ -109,17 +112,36 @@ public:
+ */
+ void broadcastMessage(const QJsonObject &message) const;
+
++ /**
++ * Enqueue the given @p message to all known transports.
++ */
++ void enqueueBroadcastMessage(const QJsonObject &message);
++
++ /**
++ * Enqueue the given @p message to @p transport.
++ */
++ void enqueueMessage(const QJsonObject &message, QWebChannelAbstractTransport *transport);
++
++ /**
++ * If client for given @p transport is idle, send queued messaged to @p transport and then mark
++ * the client as not idle.
++ */
++ void sendEnqueuedPropertyUpdates(QWebChannelAbstractTransport *transport);
++
+ /**
+ * Serialize the QMetaObject of @p object and return it in JSON form.
+ */
+ QJsonObject classInfoForObject(const QObject *object, QWebChannelAbstractTransport *transport);
+
+ /**
+- * Set the client to idle or busy, based on the value of @p isIdle.
+- *
+- * When the value changed, start/stop the property update timer accordingly.
++ * Set the client to idle or busy for a single @p transport, based on the value of @p isIdle.
++ */
++ void setClientIsIdle(bool isIdle, QWebChannelAbstractTransport *transport);
++
++ /**
++ * Check that client is idle for @p transport.
+ */
+- void setClientIsIdle(bool isIdle);
++ bool isClientIdle(QWebChannelAbstractTransport *transport);
+
+ /**
+ * Initialize clients by sending them the class information of the registered objects.
+@@ -272,10 +294,18 @@ private:
+ friend class TestWebChannel;
+
+ QWebChannel *webChannel;
+- SignalHandler<QMetaObjectPublisher> signalHandler;
++ std::unordered_map<const QThread*, SignalHandler<QMetaObjectPublisher>> signalHandlers;
++ SignalHandler<QMetaObjectPublisher> *signalHandlerFor(const QObject *object);
+
+- // true when the client is idle, false otherwise
+- bool clientIsIdle;
++ struct TransportState
++ {
++ TransportState() : clientIsIdle(false) { }
++ // true when the client is idle, false otherwise
++ bool clientIsIdle;
++ // messages to send
++ QQueue<QJsonObject> queuedMessages;
++ };
++ QHash<QWebChannelAbstractTransport *, TransportState> transportState;
+
+ // true when no property updates should be sent, false otherwise
+ bool blockUpdates;
+diff --git a/qtwebchannel/src/webchannel/signalhandler_p.h b/qtwebchannel/src/webchannel/signalhandler_p.h
+index 27afadb..d77373c 100644
+--- a/qtwebchannel/src/webchannel/signalhandler_p.h
++++ b/qtwebchannel/src/webchannel/signalhandler_p.h
+@@ -56,6 +56,7 @@
+ #include <QVector>
+ #include <QMetaMethod>
+ #include <QDebug>
++#include <QThread>
+
+ QT_BEGIN_NAMESPACE
+
+@@ -71,6 +72,7 @@ static const int s_destroyedSignalIndex = QObject::staticMetaObject.indexOfMetho
+ template<class Receiver>
+ class SignalHandler : public QObject
+ {
++ Q_DISABLE_COPY(SignalHandler)
+ public:
+ SignalHandler(Receiver *receiver, QObject *parent = 0);
+
+@@ -268,6 +270,7 @@ int SignalHandler<Receiver>::qt_metacall(QMetaObject::Call call, int methodId, v
+ if (call == QMetaObject::InvokeMetaMethod) {
+ const QObject *object = sender();
+ Q_ASSERT(object);
++ Q_ASSERT(QThread::currentThread() == object->thread());
+ Q_ASSERT(senderSignalIndex() == methodId);
+ Q_ASSERT(m_connectionsCounter.contains(object));
+ Q_ASSERT(m_connectionsCounter.value(object).contains(methodId));
+diff --git a/qtwebchannel/tests/auto/qml/testwebchannel.cpp b/qtwebchannel/tests/auto/qml/testwebchannel.cpp
+index 9891687..3ca81c2 100644
+--- a/qtwebchannel/tests/auto/qml/testwebchannel.cpp
++++ b/qtwebchannel/tests/auto/qml/testwebchannel.cpp
+@@ -46,7 +46,11 @@ TestWebChannel::~TestWebChannel()
+
+ bool TestWebChannel::clientIsIdle() const
+ {
+- return QWebChannel::d_func()->publisher->clientIsIdle;
++ for (auto *transport : QWebChannel::d_func()->transports) {
++ if (QWebChannel::d_func()->publisher->isClientIdle(transport))
++ return true;
++ }
++ return false;
+ }
+
+ QT_END_NAMESPACE
+diff --git a/qtwebchannel/tests/auto/webchannel/tst_webchannel.cpp b/qtwebchannel/tests/auto/webchannel/tst_webchannel.cpp
+index 181da9e..37f989a 100644
+--- a/qtwebchannel/tests/auto/webchannel/tst_webchannel.cpp
++++ b/qtwebchannel/tests/auto/webchannel/tst_webchannel.cpp
+@@ -785,7 +785,7 @@ void TestWebChannel::testTransportWrapObjectProperties()
+ DummyTransport *dummyTransport = new DummyTransport(this);
+ channel.connectTo(dummyTransport);
+ channel.d_func()->publisher->initializeClient(dummyTransport);
+- channel.d_func()->publisher->setClientIsIdle(true);
++ channel.d_func()->publisher->setClientIsIdle(true, dummyTransport);
+
+ QCOMPARE(channel.d_func()->publisher->transportedWrappedObjects.size(), 0);
+
+@@ -943,8 +943,6 @@ void TestWebChannel::testInfiniteRecursion()
+
+ void TestWebChannel::testAsyncObject()
+ {
+- QSKIP("This test is broken. See QTBUG-80729");
+-
+ QWebChannel channel;
+ channel.connectTo(m_dummyTransport);
+
+@@ -990,6 +988,50 @@ void TestWebChannel::testAsyncObject()
+ thread.wait();
+ }
+
++void TestWebChannel::testPropertyMultipleTransports()
++{
++ DummyTransport transport1;
++ DummyTransport transport2;
++
++ QWebChannel channel;
++ QMetaObjectPublisher *publisher = channel.d_func()->publisher;
++
++ TestObject testObj;
++ testObj.setObjectName("testObject");
++ channel.registerObject(testObj.objectName(), &testObj);
++ channel.connectTo(&transport1);
++ channel.connectTo(&transport2);
++
++ testObj.setProp("Hello");
++
++ publisher->initializeClient(&transport1);
++ publisher->initializeClient(&transport2);
++ publisher->setClientIsIdle(true, &transport1);
++ QCOMPARE(publisher->isClientIdle(&transport1), true);
++ QCOMPARE(publisher->isClientIdle(&transport2), false);
++ QVERIFY(transport1.messagesSent().isEmpty());
++ QVERIFY(transport2.messagesSent().isEmpty());
++
++ testObj.setProp("World");
++ QTRY_COMPARE_WITH_TIMEOUT(transport1.messagesSent().size(), 1u, 2000);
++ QCOMPARE(transport2.messagesSent().size(), 0u);
++ publisher->setClientIsIdle(true, &transport2);
++ QTRY_COMPARE_WITH_TIMEOUT(transport2.messagesSent().size(), 1u, 2000);
++ QCOMPARE(publisher->isClientIdle(&transport1), false);
++ QCOMPARE(publisher->isClientIdle(&transport2), false);
++
++ testObj.setProp("!!!");
++ publisher->setClientIsIdle(true, &transport2);
++ QCOMPARE(publisher->isClientIdle(&transport2), true);
++ QCOMPARE(publisher->isClientIdle(&transport1), false);
++ QTRY_COMPARE_WITH_TIMEOUT(transport2.messagesSent().size(), 2u, 2000);
++ QCOMPARE(transport1.messagesSent().size(), 1u);
++ publisher->setClientIsIdle(true, &transport1);
++ QTRY_COMPARE_WITH_TIMEOUT(transport1.messagesSent().size(), 2u, 2000);
++ QCOMPARE(publisher->isClientIdle(&transport1), false);
++ QCOMPARE(publisher->isClientIdle(&transport2), false);
++}
++
+ class FunctionWrapper : public QObject
+ {
+ Q_OBJECT
+@@ -1082,7 +1124,7 @@ void TestWebChannel::benchInitializeClients()
+
+ publisher->propertyUpdatesInitialized = false;
+ publisher->signalToPropertyMap.clear();
+- publisher->signalHandler.clear();
++ publisher->signalHandlers.clear();
+ }
+ }
+
+@@ -1107,7 +1149,7 @@ void TestWebChannel::benchPropertyUpdates()
+ obj->change();
+ }
+
+- channel.d_func()->publisher->clientIsIdle = true;
++ channel.d_func()->publisher->setClientIsIdle(true, m_dummyTransport);
+ channel.d_func()->publisher->sendPendingPropertyUpdates();
+ }
+ }
+diff --git a/qtwebchannel/tests/auto/webchannel/tst_webchannel.h b/qtwebchannel/tests/auto/webchannel/tst_webchannel.h
+index eae21f4..dd4e690 100644
+--- a/qtwebchannel/tests/auto/webchannel/tst_webchannel.h
++++ b/qtwebchannel/tests/auto/webchannel/tst_webchannel.h
+@@ -348,6 +348,7 @@ private slots:
+ void testJsonToVariant();
+ void testInfiniteRecursion();
+ void testAsyncObject();
++ void testPropertyMultipleTransports();
+ void testDeletionDuringMethodInvocation_data();
+ void testDeletionDuringMethodInvocation();
+
+Submodule qtwebengine f328054d...38e0df6c (commits not present)
+Submodule qtwebsockets 65850954..63fb8da1:
+diff --git a/qtwebsockets/src/websockets/qwebsocketdataprocessor.cpp b/qtwebsockets/src/websockets/qwebsocketdataprocessor.cpp
+index 2affdd5..95f1194 100644
+--- a/qtwebsockets/src/websockets/qwebsocketdataprocessor.cpp
++++ b/qtwebsockets/src/websockets/qwebsocketdataprocessor.cpp
+@@ -273,6 +273,7 @@ void QWebSocketDataProcessor::clear()
+ if (!m_pConverterState)
+ m_pConverterState = new QTextCodec::ConverterState(QTextCodec::ConvertInvalidToNull |
+ QTextCodec::IgnoreHeader);
++ frame.clear();
+ }
+
+ /*!
+diff --git a/qtwebsockets/src/websockets/qwebsocketprotocol.cpp b/qtwebsockets/src/websockets/qwebsocketprotocol.cpp
+index df87a93..d0465f1 100644
+--- a/qtwebsockets/src/websockets/qwebsocketprotocol.cpp
++++ b/qtwebsockets/src/websockets/qwebsocketprotocol.cpp
+@@ -210,7 +210,7 @@ void QWebSocketProtocol::mask(char *payload, quint64 size, quint32 maskingKey)
+ quint8((maskingKey & 0x0000FF00u) >> 8),
+ quint8((maskingKey & 0x000000FFu))
+ };
+- int i = 0;
++ quint64 i = 0;
+ while (size-- > 0)
+ *payload++ ^= mask[i++ % 4];
+ }
diff --git a/srcpkgs/qt5/template b/srcpkgs/qt5/template
index e0463e1c9198..8e091091b878 100644
--- a/srcpkgs/qt5/template
+++ b/srcpkgs/qt5/template
@@ -2,7 +2,9 @@
#
# revbump libqtxdg after bumping patch version
pkgname=qt5
-version=5.15.7+20221119
+version=5.15.8
+revision=1
+build_style=meta
# commit f8c9fb304bc3e53b3aa07f962cd74e9160decccc
# base repo: https://invent.kde.org/qt/qt/qt5
revision=4
@@ -29,8 +31,9 @@ homepage="https://qt.io/"
# tarball is generated with `git archive-all qt5-$version.tar.gz`
# to keep the size smaller qtwebengine, qtwebview, qtdocgallery, qtactiveqt and qtpim
# can be marked with the export-ignore attribute
-distfiles="https://void.johnnynator.dev/distfiles/qt5-${version}.tar.gz"
-checksum=9d57af471c78029a362276b7c99108ea009f511bb9ba6ff6cb884f6ddd255e9f
+#distfiles="https://void.johnnynator.dev/distfiles/qt5-${version}.tar.gz"
+distfiles="https://download.qt.io/archive/qt/5.15/${version}/single/qt-everywhere-opensource-src-${version}.tar.xz"
+checksum=776a9302c336671f9406a53bd30b8e36f825742b2ec44a57c08217bff0fa86b9
python_version=2 #unverified
replaces="qt5-doc<5.6.0 qt5-quick1<5.6.0 qt5-quick1-devel<5.6.0 qt5-webkit<5.6.0 qt5-webkit-devel<5.6.0
qt5-enginio<5.7.1 qt5-enginio-devel<5.7.1 qt5-plugin-gtk<5.7.1 qt5-canvas3d<5.13.0"
@@ -248,7 +251,6 @@ do_configure() {
# opts+=" -v"
opts+=" -skip qtwebengine"
opts+=" -skip qtwebview"
- opts+=" -skip qtdocgallery"
opts+=" -skip qtpim"
opts+=" -skip qtsystems"
opts+=" -skip qtspeech"
From ce617910577c6b66fca989241788c506eca03516 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:51 -0400
Subject: [PATCH 078/140] qt6-multimedia: revbump for ffmpeg-6.0
---
srcpkgs/qt6-multimedia/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/qt6-multimedia/template b/srcpkgs/qt6-multimedia/template
index d89e7d54eb5a..aae15e57ca7b 100644
--- a/srcpkgs/qt6-multimedia/template
+++ b/srcpkgs/qt6-multimedia/template
@@ -1,7 +1,7 @@
# Template file for 'qt6-multimedia'
pkgname=qt6-multimedia
version=6.4.2
-revision=1
+revision=2
build_style=cmake
configure_args="-DQT_FEATURE_gstreamer=ON"
hostmakedepends="perl qt6-declarative-host-tools pkg-config qt6-shadertools"
From c0f9eb39be84b536962e3424d343c161d6419e09 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:51 -0400
Subject: [PATCH 079/140] qtav: revbump for ffmpeg4-4.4.3
---
srcpkgs/qtav/template | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/srcpkgs/qtav/template b/srcpkgs/qtav/template
index 34c30b2c0c78..2d00ad104355 100644
--- a/srcpkgs/qtav/template
+++ b/srcpkgs/qtav/template
@@ -1,10 +1,10 @@
# Template file for 'qtav'
pkgname=qtav
version=1.13.0
-revision=1
+revision=2
build_style=qmake
hostmakedepends="qt5-qmake qt5-host-tools"
-makedepends="ffmpeg-devel libass-devel libopenal-devel
+makedepends="ffmpeg4-devel libass-devel libopenal-devel
libva-glx-devel libXv-devel pulseaudio-devel
qt5-declarative-devel qt5-svg-devel
qt5-quickcontrols"
From 3819de5bdbde44ec66fc7f5b2ff8540c5a18f5c3 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:51 -0400
Subject: [PATCH 080/140] qtox: revbump for ffmpeg-6.0
---
srcpkgs/qtox/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/qtox/template b/srcpkgs/qtox/template
index 16019d7eaec9..5cea0b11b697 100644
--- a/srcpkgs/qtox/template
+++ b/srcpkgs/qtox/template
@@ -1,7 +1,7 @@
# Template file for 'qtox'
pkgname=qtox
version=1.17.6
-revision=2
+revision=3
build_style=cmake
configure_args="-DUPDATE_CHECK=OFF
-DGIT_DESCRIBE=${version}
From 6aafd39859ee95435e81acb0e26a5b319680ad2c Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:51 -0400
Subject: [PATCH 081/140] retroarch: revbump for ffmpeg-6.0
---
srcpkgs/retroarch/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/retroarch/template b/srcpkgs/retroarch/template
index 240d3df9db00..6d0b16ae2598 100644
--- a/srcpkgs/retroarch/template
+++ b/srcpkgs/retroarch/template
@@ -1,7 +1,7 @@
# Template file for 'retroarch'
pkgname=retroarch
version=1.14.0
-revision=1
+revision=2
build_style=configure
configure_args="--prefix=/usr --sysconfdir=/etc --enable-networking
--enable-udev --disable-builtinflac --disable-builtinglslang
From 455aca9838d8cbe116f0fcfb92b4a77e8039b2b7 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:51 -0400
Subject: [PATCH 082/140] scrcpy: revbump for ffmpeg-6.0
---
srcpkgs/scrcpy/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/scrcpy/template b/srcpkgs/scrcpy/template
index ee6e698e387f..8ada5ca4323f 100644
--- a/srcpkgs/scrcpy/template
+++ b/srcpkgs/scrcpy/template
@@ -1,7 +1,7 @@
# Template file for 'scrcpy'
pkgname=scrcpy
version=2.0
-revision=1
+revision=2
build_style=meson
configure_args="-Dcompile_server=false
-Dprebuilt_server=/usr/share/scrcpy/scrcpy-server-v${version}"
From a1656359e90b966ef4b0ad4ea1c33a06f06f9fb0 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:51 -0400
Subject: [PATCH 083/140] spek-alternative: revbump for ffmpeg4-4.4.3
---
srcpkgs/spek-alternative/template | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/srcpkgs/spek-alternative/template b/srcpkgs/spek-alternative/template
index d65086b8f008..05246f1b8d0c 100644
--- a/srcpkgs/spek-alternative/template
+++ b/srcpkgs/spek-alternative/template
@@ -1,11 +1,11 @@
# Template file for 'spek-alternative'
pkgname=spek-alternative
version=0.8.2.3
-revision=1
+revision=2
build_style=gnu-configure
hostmakedepends="automake gettext-devel intltool libtool pkg-config wxWidgets-common"
-makedepends="ffmpeg-devel wxWidgets-gtk3-devel"
-depends="ffmpeg"
+makedepends="ffmpeg4-devel wxWidgets-gtk3-devel"
+depends="ffmpeg4"
short_desc="Acoustic spectrum analyser"
maintainer="Kartik Singh <kartik.ynwa@gmail.com>"
license="GPL-3.0-or-later"
From 20686d9f0451bdb1d3c611a4b5ff6d9c97c1824f Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:51 -0400
Subject: [PATCH 084/140] ssr: revbump for ffmpeg4-4.4.3
---
srcpkgs/ssr/template | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/srcpkgs/ssr/template b/srcpkgs/ssr/template
index b055b9ec0774..3448ca110eb0 100644
--- a/srcpkgs/ssr/template
+++ b/srcpkgs/ssr/template
@@ -1,11 +1,11 @@
# Template file for 'ssr'
pkgname=ssr
version=0.4.4
-revision=1
+revision=2
build_style=cmake
configure_args="-DWITH_QT5=ON"
hostmakedepends="pkg-config"
-makedepends="alsa-lib-devel ffmpeg-devel glu-devel jack-devel pulseaudio-devel
+makedepends="alsa-lib-devel ffmpeg4-devel glu-devel jack-devel pulseaudio-devel
qt5-tools-devel qt5-x11extras-devel libXinerama-devel v4l-utils-devel"
depends="desktop-file-utils hicolor-icon-theme"
short_desc="Simple Screen Recorder for programs and games"
From 0e7b81053e7bff355b75d50fe25b705a9228f138 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:51 -0400
Subject: [PATCH 085/140] sumo: revbump for ffmpeg-6.0
---
srcpkgs/sumo/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/sumo/template b/srcpkgs/sumo/template
index 0f9b9ec815f5..a3fe134aa5ac 100644
--- a/srcpkgs/sumo/template
+++ b/srcpkgs/sumo/template
@@ -1,7 +1,7 @@
# Template file for 'sumo'
pkgname=sumo
version=1.12.0
-revision=5
+revision=6
build_style=cmake
hostmakedepends="libgdal-tools pkg-config swig python3-setuptools"
makedepends="python3-devel ffmpeg-devel fox-devel gl2ps-devel libgdal-devel
From b889d24a0564806429d75552d66daadc49712054 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:52 -0400
Subject: [PATCH 086/140] synfig: revbump for ffmpeg4-4.4.3
---
srcpkgs/synfig/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/synfig/template b/srcpkgs/synfig/template
index 5f5f5bb3f4b2..9b4d9adf09c6 100644
--- a/srcpkgs/synfig/template
+++ b/srcpkgs/synfig/template
@@ -7,7 +7,7 @@ build_style=gnu-configure
configure_args="--with-boost-libdir=${XBPS_CROSS_BASE}/usr/lib"
hostmakedepends="boost-build ImageMagick pkg-config intltool"
makedepends="ETL gettext-devel libxml++-devel mlt-devel libmagick-devel
- libmng-devel boost-build boost-devel libopenexr-devel ffmpeg-devel"
+ libmng-devel boost-build boost-devel libopenexr-devel ffmpeg4-devel"
depends="ImageMagick"
short_desc="CLI 2D vector and timeline-based animation software"
maintainer="Orphaned <orphan@voidlinux.org>"
From 8de3f9a8db7b4a03d003bb0db520fa4f07c96b8b Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:52 -0400
Subject: [PATCH 087/140] telegram-desktop: revbump for ffmpeg-6.0
---
srcpkgs/telegram-desktop/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/telegram-desktop/template b/srcpkgs/telegram-desktop/template
index aae9f3135100..7943b36f0b8a 100644
--- a/srcpkgs/telegram-desktop/template
+++ b/srcpkgs/telegram-desktop/template
@@ -1,7 +1,7 @@
# Template file for 'telegram-desktop'
pkgname=telegram-desktop
version=4.6.5
-revision=1
+revision=2
build_style=cmake
build_helper="qemu"
configure_args="-DTDESKTOP_API_ID=209235
From b0b5d3041e592bd2f8cf84496a40dcf672e1a25b Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:52 -0400
Subject: [PATCH 088/140] tg_owt: revbump for ffmpeg-6.0
---
srcpkgs/tg_owt/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/tg_owt/template b/srcpkgs/tg_owt/template
index 97d195ddb34a..551614b24956 100644
--- a/srcpkgs/tg_owt/template
+++ b/srcpkgs/tg_owt/template
@@ -1,7 +1,7 @@
# Template file for 'tg_owt'
pkgname=tg_owt
version=0.0.0.20230107
-revision=1
+revision=2
_commit=5098730b9eb6173f0b52068fe2555b7c1015123a
_libyuv_commit=00950840d1c9bcbb3eb6ebc5aac5793e71166c8b
_abseil_commit=8c0b94e793a66495e0b1f34a5eb26bd7dc672db0
From 8093adaf1fd9075f760fbf840188a2afcbab41e1 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:52 -0400
Subject: [PATCH 089/140] timg: revbump for ffmpeg-6.0
---
srcpkgs/timg/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/timg/template b/srcpkgs/timg/template
index 91f1516b2597..334443d3f9bb 100644
--- a/srcpkgs/timg/template
+++ b/srcpkgs/timg/template
@@ -1,7 +1,7 @@
# Template file for 'timg'
pkgname=timg
version=1.4.4
-revision=1
+revision=2
build_style=cmake
configure_args="-DWITH_OPENSLIDE_SUPPORT=off -Wno-dev"
hostmakedepends="pkg-config git"
From cfe7604cd0adc6983408c963dd4a377a2b72238a Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:52 -0400
Subject: [PATCH 090/140] tvheadend: revbump for ffmpeg4-4.4.3
---
srcpkgs/tvheadend/template | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/srcpkgs/tvheadend/template b/srcpkgs/tvheadend/template
index e6b16d7ccf3b..46b52b6fb7f9 100644
--- a/srcpkgs/tvheadend/template
+++ b/srcpkgs/tvheadend/template
@@ -1,14 +1,14 @@
# Template file for 'tvheadend'
pkgname=tvheadend
version=4.2.8
-revision=6
+revision=7
build_style=gnu-configure
configure_args="--enable-dvbscan --disable-ffmpeg_static
--disable-hdhomerun_static --disable-bintray_cache --disable-libx264_static
--disable-libx265_static --disable-libvpx_static --disable-libtheora_static
--disable-libvorbis_static --disable-libfdkaac_static"
hostmakedepends="gettext pkg-config python git which"
-makedepends="avahi-libs-devel openssl-devel zlib-devel libcurl-devel ffmpeg-devel"
+makedepends="avahi-libs-devel openssl-devel zlib-devel libcurl-devel ffmpeg4-devel"
short_desc="TV streaming server"
maintainer="lemmi <lemmi@nerd2nerd.org>"
license="GPL-3.0-only"
From 98f93f855182352cf8660e23f0b6100403534bda Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:52 -0400
Subject: [PATCH 091/140] unpaper: update to 7.0.0.
---
srcpkgs/unpaper/template | 16 ++++++++--------
1 file changed, 8 insertions(+), 8 deletions(-)
diff --git a/srcpkgs/unpaper/template b/srcpkgs/unpaper/template
index 38ed47a58401..1ff910e722af 100644
--- a/srcpkgs/unpaper/template
+++ b/srcpkgs/unpaper/template
@@ -1,13 +1,13 @@
# Template file for 'unpaper'
pkgname=unpaper
-version=6.1
-revision=3
-build_style=gnu-configure
+version=7.0.0
+revision=1
+build_style=meson
+hostmakedepends="pkg-config meson libxslt"
+makedepends="ffmpeg-devel python3-Sphinx"
+short_desc="Post-processing tool for scanned sheets of paper"
maintainer="Orphaned <orphan@voidlinux.org>"
-hostmakedepends="pkg-config libxslt"
-makedepends="ffmpeg-devel"
-license="GPL-2"
+license="GPL-2.0-or-later"
homepage="https://www.flameeyes.eu/projects/unpaper"
-short_desc="A post-processing tool for scanned sheets of paper"
distfiles="https://www.flameeyes.eu/files/${pkgname}-${version}.tar.xz"
-checksum=237c84f5da544b3f7709827f9f12c37c346cdf029b1128fb4633f9bafa5cb930
+checksum=2575fbbf26c22719d1cb882b59602c9900c7f747118ac130883f63419be46a80
From a234462b323497066076bb43b6dbaaf1f0f6b590 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:52 -0400
Subject: [PATCH 092/140] vba-m: revbump for ffmpeg-6.0
---
srcpkgs/vba-m/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/vba-m/template b/srcpkgs/vba-m/template
index ba153e0b58ca..aa6093645e97 100644
--- a/srcpkgs/vba-m/template
+++ b/srcpkgs/vba-m/template
@@ -2,7 +2,7 @@
pkgname=vba-m
reverts=1292_2
version=2.1.5
-revision=1
+revision=2
build_style=cmake
configure_args="-DENABLE_GTK=TRUE -DENABLE_FFMPEG=TRUE -DENABLE_LINK=TRUE -DCMAKE_BUILD_TYPE=Release"
hostmakedepends="gettext pkg-config unzip zip yasm wxWidgets-gtk3-devel"
From 6ff9bfcd0dd43d5aaa1cfe74ffd5d998a264a09c Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:52 -0400
Subject: [PATCH 093/140] vice: revbump for ffmpeg4-4.4.3
---
srcpkgs/vice/template | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/srcpkgs/vice/template b/srcpkgs/vice/template
index 0924767cfcfb..5981e45149d0 100644
--- a/srcpkgs/vice/template
+++ b/srcpkgs/vice/template
@@ -1,7 +1,7 @@
# Template file for 'vice'
pkgname=vice
version=3.5
-revision=1
+revision=2
build_style=gnu-configure
configure_args="
$(vopt_enable sdl2 sdlui2)
@@ -28,7 +28,7 @@ makedepends="
$(vopt_if gtk3 gtk+3-devel)
$(vopt_if gtk3 pulseaudio-devel)
$(vopt_if gtk3 pango-devel)
- $(vopt_if ffmpeg ffmpeg-devel)"
+ $(vopt_if ffmpeg ffmpeg4-devel)"
short_desc="Emulator for C64, C128, CBM-II, PET, VIC20, Plus4 and C16"
maintainer="Orphaned <orphan@voidlinux.org>"
license="GPL-2.0-or-later"
From 308e19f02d1e1857112ab17e20990396f9b5c477 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:52 -0400
Subject: [PATCH 094/140] waypipe: revbump for ffmpeg-6.0
---
srcpkgs/waypipe/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/waypipe/template b/srcpkgs/waypipe/template
index 5c4161900060..1a46fe27f7d8 100644
--- a/srcpkgs/waypipe/template
+++ b/srcpkgs/waypipe/template
@@ -1,7 +1,7 @@
# Template file for 'waypipe'
pkgname=waypipe
version=0.8.4
-revision=1
+revision=2
build_style=meson
# lto is off because it causes linking errors in armv6l and armv7l (due to NEON)
configure_args="-Dwerror=false -Dwith_dmabuf=enabled -Dwith_lz4=enabled
From 3916eaa1fb7a6443a01f2203538833bf93ffce78 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:52 -0400
Subject: [PATCH 095/140] wf-recorder: revbump for ffmpeg-6.0
---
srcpkgs/wf-recorder/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/wf-recorder/template b/srcpkgs/wf-recorder/template
index e278eb001600..5d014a5f28af 100644
--- a/srcpkgs/wf-recorder/template
+++ b/srcpkgs/wf-recorder/template
@@ -1,7 +1,7 @@
# Template file for 'wf-recorder'
pkgname=wf-recorder
version=0.3.0
-revision=1
+revision=2
build_style=meson
hostmakedepends="pkg-config scdoc wayland-devel"
makedepends="wayland-protocols wayland-devel ffmpeg-devel x264-devel
From 0f774085616f9dc60ad8cd32d27c52773ba3a251 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:52 -0400
Subject: [PATCH 096/140] xpra: revbump for ffmpeg-6.0
---
srcpkgs/xpra/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/xpra/template b/srcpkgs/xpra/template
index 38f83283b1e5..b6e01ff0a813 100644
--- a/srcpkgs/xpra/template
+++ b/srcpkgs/xpra/template
@@ -1,7 +1,7 @@
# Template file for 'xpra'
pkgname=xpra
version=4.4.4
-revision=1
+revision=2
build_style=python3-module
make_build_args="--without-cuda_kernels --without-cuda_rebuild"
make_install_args="$(vopt_with docs) ${make_build_args}"
From 9637df2fd231b7e7a270e2eff6dd5f07aa5b0364 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Fri, 31 Mar 2023 09:07:40 -0400
Subject: [PATCH 097/140] nv-codec-headers: update to 12.0.16.0
---
srcpkgs/nv-codec-headers/template | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/srcpkgs/nv-codec-headers/template b/srcpkgs/nv-codec-headers/template
index 3d422a61e489..251e057f826f 100644
--- a/srcpkgs/nv-codec-headers/template
+++ b/srcpkgs/nv-codec-headers/template
@@ -1,6 +1,6 @@
# Template file for 'nv-codec-headers'
pkgname=nv-codec-headers
-version=11.1.5.1
+version=12.0.16.0
revision=1
build_style=gnu-makefile
short_desc="FFmpeg version of headers required to interface with Nvidias codec APIs"
@@ -8,7 +8,7 @@ maintainer="Orphaned <orphan@voidlinux.org>"
license="MIT"
homepage="http://git.videolan.org/?p=ffmpeg/nv-codec-headers.git"
distfiles="https://github.com/FFmpeg/nv-codec-headers/archive/n${version}.tar.gz"
-checksum=d095fbd56aa93772471a323be0ebe65504a0f43f06c76a30b6d25da77b06ae9c
+checksum=2a1533b65f55f9da52956faf0627ed3b74868ac0c7f269990edd21369113b48f
post_install() {
sed -n '4,25p' include/ffnvcodec/nvEncodeAPI.h > LICENSE
From 66259eae9d0e29471066f2158c45eacabb70dbef Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Fri, 31 Mar 2023 09:08:40 -0400
Subject: [PATCH 098/140] openimagedenoise: revbump for ffmpeg-6.0
---
srcpkgs/openimagedenoise/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/openimagedenoise/template b/srcpkgs/openimagedenoise/template
index db5ccdb055cc..cb90045afb63 100644
--- a/srcpkgs/openimagedenoise/template
+++ b/srcpkgs/openimagedenoise/template
@@ -1,7 +1,7 @@
# Template file for 'openimagedenoise'
pkgname=openimagedenoise
version=1.4.3
-revision=1
+revision=2
archs="x86_64*"
build_style=cmake
hostmakedepends="ispc python3"
From a88b42ee425030fde19e4e6bda4c0f210cf3de7c Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Sun, 19 Mar 2023 10:58:01 -0400
Subject: [PATCH 099/140] gst-libav: update to 1.22.1
---
srcpkgs/gst-libav/template | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/srcpkgs/gst-libav/template b/srcpkgs/gst-libav/template
index f082bd211c65..a2c97bfbcdb9 100644
--- a/srcpkgs/gst-libav/template
+++ b/srcpkgs/gst-libav/template
@@ -1,7 +1,7 @@
# Template file for 'gst-libav'
pkgname=gst-libav
-version=1.20.3
-revision=2
+version=1.22.1
+revision=1
build_style=meson
hostmakedepends="pkg-config yasm"
makedepends="orc-devel gst-plugins-base1-devel ffmpeg-devel"
@@ -11,7 +11,7 @@ maintainer="Orphaned <orphan@voidlinux.org>"
license="LGPL-2.0-or-later"
homepage="https://gstreamer.freedesktop.org"
distfiles="${homepage}/src/${pkgname}/${pkgname}-${version}.tar.xz"
-checksum=3fedd10560fcdfaa1b6462cbf79a38c4e7b57d7f390359393fc0cef6dbf27dfe
+checksum=c958e825dc3ac3b7a481f8db5268131a1cd701312385c2d803dc63c8e460b5fb
case "$XBPS_TARGET_MACHINE" in
*-musl) # Required by musl for M_SQRT1_2
From 0258179c027328efa4c1ce16d9b168153c71398a Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Sun, 19 Mar 2023 10:58:18 -0400
Subject: [PATCH 100/140] gst-omx: update to 1.22.1
---
srcpkgs/gst-omx/template | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/srcpkgs/gst-omx/template b/srcpkgs/gst-omx/template
index 893535c463da..76692c2a13f6 100644
--- a/srcpkgs/gst-omx/template
+++ b/srcpkgs/gst-omx/template
@@ -1,6 +1,6 @@
# Template file for 'gst-omx'
pkgname=gst-omx
-version=1.20.3
+version=1.22.1
revision=1
build_style=meson
configure_args="-Dexamples=disabled -Dtarget=generic"
@@ -11,4 +11,4 @@ maintainer="Orphaned <orphan@voidlinux.org>"
license="LGPL-2.1-only"
homepage="https://gstreamer.freedesktop.org"
distfiles="${homepage}/src/${pkgname}/${pkgname}-${version}.tar.xz"
-checksum=8db48040bb41f09edf8d17ff6d16c54888d7777ba4501c2c69f0083350ea9a15
+checksum=2d37f60cd33e68dcef0bcd09b2dd8a0b2eb3ab6d6ac172dca46f70eb02756687
From 8b8c544e00e9695348cf2ebe5acdbee177f79703 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Sun, 19 Mar 2023 10:59:04 -0400
Subject: [PATCH 101/140] gst-plugins-bad1: update to 1.22.1
---
common/shlibs | 1 +
srcpkgs/gst-plugins-bad1/template | 2 +-
2 files changed, 2 insertions(+), 1 deletion(-)
diff --git a/common/shlibs b/common/shlibs
index d0d328b09ef9..42744a55b1fc 100644
--- a/common/shlibs
+++ b/common/shlibs
@@ -1147,6 +1147,7 @@ libgstpbutils-1.0.so.0 gst-plugins-base1-1.0.0_1
libgstriff-1.0.so.0 gst-plugins-base1-1.0.0_1
libgstapp-1.0.so.0 gst-plugins-base1-1.0.0_1
libgstallocators-1.0.so.0 gst-plugins-base1-1.1.1_1
+libgsttranscoder-1.0.so.0 gst-plugins-bad1-1.22.1_1
libgstphotography-1.0.so.0 gst-plugins-bad1-1.18.3_2
libgstsignalprocessor-1.0.so.0 gst-plugins-bad1-1.18.3_2
libgstbasevideo-1.0.so.0 gst-plugins-bad1-1.18.3_2
diff --git a/srcpkgs/gst-plugins-bad1/template b/srcpkgs/gst-plugins-bad1/template
index 5a9d5387e0d4..7f272f915ac4 100644
--- a/srcpkgs/gst-plugins-bad1/template
+++ b/srcpkgs/gst-plugins-bad1/template
@@ -36,7 +36,7 @@ maintainer="Orphaned <orphan@voidlinux.org>"
license="GPL-2.0-or-later, LGPL-2.1-or-later"
homepage="https://gstreamer.freedesktop.org"
distfiles="${homepage}/src/${pkgname/1/}/${pkgname/1/}-${version}.tar.xz"
-checksum=7a11c13b55dd1d2386dd902219e41cbfcdda8e1e0aa3e738186c95074b35da4f
+checksum=2f39b6f222d98666f9ff420a00233e336949953a846237c2bfafc8805f509f0e
build_options="gir gme wayland"
build_options_default="gir wayland"
From ba55d5d71946d02f8e921c021b56474f4bc7a64e Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Sun, 19 Mar 2023 10:59:04 -0400
Subject: [PATCH 102/140] gst-plugins-ugly1: update to 1.22.1
---
srcpkgs/gst-plugins-ugly1/template | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/srcpkgs/gst-plugins-ugly1/template b/srcpkgs/gst-plugins-ugly1/template
index e254fd40f869..5647c012c9fe 100644
--- a/srcpkgs/gst-plugins-ugly1/template
+++ b/srcpkgs/gst-plugins-ugly1/template
@@ -1,6 +1,6 @@
# Template file for 'gst-plugins-ugly1'
pkgname=gst-plugins-ugly1
-version=1.20.3
+version=1.22.1
revision=1
build_style=meson
configure_args="-Damrnb=disabled -Damrwbdec=disabled -Dsidplay=disabled"
@@ -15,4 +15,4 @@ maintainer="Orphaned <orphan@voidlinux.org>"
license="LGPL-2.1-or-later"
homepage="https://gstreamer.freedesktop.org"
distfiles="${homepage}/src/${pkgname/1/}/${pkgname/1/}-${version}.tar.xz"
-checksum=8caa20789a09c304b49cf563d33cca9421b1875b84fcc187e4a385fa01d6aefd
+checksum=4ab3d9e13481bce1ca3c7c4bb1f65dce4f0bb40fb1cac4416e8c06dd648815c2
From 9d0baaabf3a3848ca1afd6d7defeba99d19cb85e Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Sun, 19 Mar 2023 10:59:31 -0400
Subject: [PATCH 103/140] gst-editing-services: update to 1.22.1
---
srcpkgs/gst1-editing-services/template | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/srcpkgs/gst1-editing-services/template b/srcpkgs/gst1-editing-services/template
index 673b46970f24..f2045ad6043c 100644
--- a/srcpkgs/gst1-editing-services/template
+++ b/srcpkgs/gst1-editing-services/template
@@ -1,6 +1,6 @@
# Template file for 'gst1-editing-services'
pkgname=gst1-editing-services
-version=1.20.3
+version=1.22.1
revision=1
build_style=meson
build_helper="gir"
@@ -12,7 +12,7 @@ maintainer="Toyam Cox <Vaelatern@gmail.com>"
license="LGPL-2.0-or-later"
homepage="https://gstreamer.freedesktop.org"
distfiles="${homepage}/src/${pkgname/gst1/gst}/${pkgname/gst1/gst}-${version}.tar.xz"
-checksum=5fd896de69fbe24421eb6b0ff8d2f8b4c3cba3f3025ceacd302172f39a8abaa2
+checksum=0f9e5e08ef80a4b9a0e971c5f032b13c71aa6fef236265c2d615456e15161438
do_check() {
: # Tests fail in older versions as well
From f0b50207650d199e57babe5491fb3ff7810cb57c Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Sun, 19 Mar 2023 11:00:00 -0400
Subject: [PATCH 104/140] gst-rtsp-server: update to 1.22.1
---
srcpkgs/gst-rtsp-server/template | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/srcpkgs/gst-rtsp-server/template b/srcpkgs/gst-rtsp-server/template
index 8ceea8d34b4b..ded9a69a2e9d 100644
--- a/srcpkgs/gst-rtsp-server/template
+++ b/srcpkgs/gst-rtsp-server/template
@@ -1,7 +1,7 @@
# Template file for 'gst-rtsp-server'
pkgname=gst-rtsp-server
-version=1.20.3
-revision=3
+version=1.22.1
+revision=1
build_style=meson
hostmakedepends="pkg-config python3"
makedepends="glib-devel gst-plugins-bad1-devel gobject-introspection
@@ -10,5 +10,5 @@ short_desc="GStreamer multimedia graph framework - rtsp server"
maintainer="1is7ac3 <isaac.qa13@gmail.com>"
license="LGPL-2.1-or-later"
homepage="https://gstreamer.freedesktop.org"
-distfiles="https://gstreamer.freedesktop.org/src/gst-rtsp-server/gst-rtsp-server-${version}.tar.xz"
-checksum=ee402718be9b127f0e5e66ca4c1b4f42e4926ec93ba307b7ccca5dc6cc9794ca
+distfiles="${homepage}/src/${pkgname}/${pkgname}-${version}.tar.xz"
+checksum=4e0b972608f67d5d8f5363c827cfcf132b0e00877be6f1905358d514249b05a3
From 6bcea1d88313aeed3c0587847f1221c40e6efbf8 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Sun, 19 Mar 2023 11:00:39 -0400
Subject: [PATCH 105/140] gst1-python3: update to 1.22.1
---
srcpkgs/gst1-python3/template | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/srcpkgs/gst1-python3/template b/srcpkgs/gst1-python3/template
index 3f564ac64b93..7a8d094ef61f 100644
--- a/srcpkgs/gst1-python3/template
+++ b/srcpkgs/gst1-python3/template
@@ -1,7 +1,7 @@
# Template file for 'gst1-python3'
pkgname=gst1-python3
-version=1.20.3
-revision=2
+version=1.22.1
+revision=1
build_style=meson
hostmakedepends="pkg-config python3"
makedepends="libglib-devel python3-devel python3-gobject-devel gst-plugins-base1-devel"
@@ -11,4 +11,4 @@ maintainer="Orphaned <orphan@voidlinux.org>"
license="LGPL-2.1-or-later"
homepage="https://gstreamer.freedesktop.org"
distfiles="${homepage}/src/gst-python/gst-python-${version}.tar.xz"
-checksum=db348120eae955b8cc4de3560a7ea06e36d6e1ddbaa99a7ad96b59846601cfdc
+checksum=96008a441d685a64275a515b893ccad0fea1d560c43acd0763533e17f3a13ebb
From 6fcf8665f50766b471cb548e9e8b558e2477aec2 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Sun, 19 Mar 2023 11:00:46 -0400
Subject: [PATCH 106/140] gstreamer-vaapi: update to 1.22.1
---
srcpkgs/gstreamer-vaapi/template | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/srcpkgs/gstreamer-vaapi/template b/srcpkgs/gstreamer-vaapi/template
index 3cc4e057559a..c100d99e9af1 100644
--- a/srcpkgs/gstreamer-vaapi/template
+++ b/srcpkgs/gstreamer-vaapi/template
@@ -1,6 +1,6 @@
# Template file for 'gstreamer-vaapi'
pkgname=gstreamer-vaapi
-version=1.20.3
+version=1.22.1
revision=1
build_style=meson
hostmakedepends="pkg-config"
@@ -11,7 +11,7 @@ license="LGPL-2.1-or-later"
homepage="https://gstreamer.freedesktop.org"
changelog="https://raw.githubusercontent.com/GStreamer/gstreamer-vaapi/master/ChangeLog"
distfiles="${homepage}/src/gstreamer-vaapi/gstreamer-vaapi-${version}.tar.xz"
-checksum=6ee99eb316abdde9ad37002915bd8c3867918f6fdc74b7cf2ac4c1ae0d690b45
+checksum=423b57db7fc5f9137dadf17cb3853a47438d63cd4ba6889a882e63fb5be997bc
pre_check() {
# Seems to need certain hardware to pass
From 8630148cd020d36f5d0c876b6e1a565a2827edde Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Sun, 19 Mar 2023 11:00:51 -0400
Subject: [PATCH 107/140] gstreamer1: update to 1.22.1
---
srcpkgs/gstreamer1/template | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/srcpkgs/gstreamer1/template b/srcpkgs/gstreamer1/template
index ae8a49cb20e8..362fe82faec3 100644
--- a/srcpkgs/gstreamer1/template
+++ b/srcpkgs/gstreamer1/template
@@ -1,6 +1,6 @@
# Template file for 'gstreamer1'
pkgname=gstreamer1
-version=1.20.3
+version=1.22.1
revision=1
build_style=meson
build_helper="gir"
@@ -16,7 +16,7 @@ maintainer="Orphaned <orphan@voidlinux.org>"
license="LGPL-2.0-or-later"
homepage="https://gstreamer.freedesktop.org"
distfiles="${homepage}/src/gstreamer/gstreamer-${version}.tar.xz"
-checksum=607daf64bbbd5fb18af9d17e21c0d22c4d702fffe83b23cb22d1b1af2ca23a2a
+checksum=cd3ca759f926763615fdfcea63c9761198c42889bc0615ceec73e22b24fde771
pre_check() {
# gst_gstdatetime is known to fail according to LFS
From 20d2f1f5a758b82922175d2892a50fe03ce847a3 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Sun, 19 Mar 2023 10:59:04 -0400
Subject: [PATCH 108/140] gst-plugins-good1: update to 1.22.1
---
srcpkgs/gst-plugins-good1/template | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/srcpkgs/gst-plugins-good1/template b/srcpkgs/gst-plugins-good1/template
index 1f5e620ce1fd..00baa6732c75 100644
--- a/srcpkgs/gst-plugins-good1/template
+++ b/srcpkgs/gst-plugins-good1/template
@@ -1,6 +1,6 @@
# Template file for 'gst-plugins-good1'
pkgname=gst-plugins-good1
-version=1.20.3
+version=1.22.1
revision=1
build_style=meson
configure_args="-Ddv=disabled -Ddv1394=disabled -Dshout2=disabled -Dqt5=enabled
@@ -22,7 +22,7 @@ maintainer="Orphaned <orphan@voidlinux.org>"
license="LGPL-2.1-or-later"
homepage="https://gstreamer.freedesktop.org"
distfiles="${homepage}/src/${pkgname/1/}/${pkgname/1/}-${version}.tar.xz"
-checksum=f8f3c206bf5cdabc00953920b47b3575af0ef15e9f871c0b6966f6d0aa5868b7
+checksum=44f9104654b4fd042aebe90932ab92e7ff7d8460fbc05b23dad87dffe70974cc
build_options="gtk3 wayland"
build_options_default="gtk3 wayland"
From e09d3340288d9c31c67a2928d1bd59e1bb1281da Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Sun, 19 Mar 2023 10:59:04 -0400
Subject: [PATCH 109/140] gst-plugins-base1: update to 1.22.1
---
srcpkgs/gst-plugins-base1/template | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/srcpkgs/gst-plugins-base1/template b/srcpkgs/gst-plugins-base1/template
index 29e8f76bd1fe..6d2cad16f985 100644
--- a/srcpkgs/gst-plugins-base1/template
+++ b/srcpkgs/gst-plugins-base1/template
@@ -1,6 +1,6 @@
# Template file for 'gst-plugins-base1'
pkgname=gst-plugins-base1
-version=1.20.3
+version=1.22.1
revision=1
build_style=meson
build_helper="gir"
@@ -22,7 +22,7 @@ maintainer="Orphaned <orphan@voidlinux.org>"
license="GPL-2.0-or-later, LGPL-2.0-or-later"
homepage="https://gstreamer.freedesktop.org"
distfiles="${homepage}/src/${pkgname/1/}/${pkgname/1/}-${version}.tar.xz"
-checksum=7e30b3dd81a70380ff7554f998471d6996ff76bbe6fc5447096f851e24473c9f
+checksum=59bcaeacc5646b8dbdcfa4ef20ca6e818dd234910efb4cee1bbea441a3801c69
build_options="cdparanoia gir sndio wayland"
build_options_default="cdparanoia gir wayland"
From dc50f33765103a8eda9bae95bef268f969a36d22 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Fri, 16 Dec 2022 09:25:22 -0500
Subject: [PATCH 110/140] intel-gmmlib: update to 22.3.3
---
srcpkgs/intel-gmmlib/template | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/srcpkgs/intel-gmmlib/template b/srcpkgs/intel-gmmlib/template
index 8ed6ed3cf56c..2605226152e5 100644
--- a/srcpkgs/intel-gmmlib/template
+++ b/srcpkgs/intel-gmmlib/template
@@ -1,6 +1,6 @@
# Template file for 'intel-gmmlib'
pkgname=intel-gmmlib
-version=22.2.0
+version=22.3.3
revision=1
archs="i686* x86_64*"
build_style=cmake
@@ -18,7 +18,7 @@ maintainer="Stefano Ragni <st3r4g@protonmail.com>"
license="MIT"
homepage="https://github.com/intel/gmmlib"
distfiles="https://github.com/intel/gmmlib/archive/intel-gmmlib-${version}.tar.gz"
-checksum=0b2253894c6fc8455b6d7c5e87e6504a76d6f60ea192e1445c2f93164bf529c0
+checksum=86651bd2803c9f0afd82471bec784e65d2b418dee315a053d22215eb2a679be7
lib32disabled=yes
From 19115bde2696fddbb737e5cf8ec897aac163c54c Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Fri, 16 Dec 2022 09:25:47 -0500
Subject: [PATCH 111/140] intel-media-driver: update to 22.6.4
---
...mmon-Enable-MMC-in-free-kernel-build.patch | 125 ++++++++++++++++++
.../intel-media-driver/patches/execinfo.patch | 58 --------
srcpkgs/intel-media-driver/template | 4 +-
3 files changed, 127 insertions(+), 60 deletions(-)
create mode 100644 srcpkgs/intel-media-driver/patches/0001-Media-Common-Enable-MMC-in-free-kernel-build.patch
delete mode 100644 srcpkgs/intel-media-driver/patches/execinfo.patch
diff --git a/srcpkgs/intel-media-driver/patches/0001-Media-Common-Enable-MMC-in-free-kernel-build.patch b/srcpkgs/intel-media-driver/patches/0001-Media-Common-Enable-MMC-in-free-kernel-build.patch
new file mode 100644
index 000000000000..525fb688722c
--- /dev/null
+++ b/srcpkgs/intel-media-driver/patches/0001-Media-Common-Enable-MMC-in-free-kernel-build.patch
@@ -0,0 +1,125 @@
+From e68feab7db036838d9521ba3b9f00717c37c024c Mon Sep 17 00:00:00 2001
+From: JayYang <jay.yang@intel.com>
+Date: Tue, 21 Mar 2023 17:17:55 +0800
+Subject: [PATCH] [Media Common] Enable MMC in free kernel build
+
+Add mmc build definition in free kernel build
+---
+ media_driver/agnostic/gen9/codec/hal/media_srcs.cmake | 2 +-
+ media_driver/cmake/linux/media_feature_flags_linux.cmake | 3 +--
+ .../media_interfaces_m9_bxt/media_interfaces_g9_bxt.cpp | 2 +-
+ .../media_interfaces_m9_cfl/media_interfaces_g9_cfl.cpp | 2 +-
+ .../media_interfaces_m9_glk/media_interfaces_g9_glk.cpp | 2 +-
+ .../media_interfaces_m9_kbl/media_interfaces_g9_kbl.cpp | 2 +-
+ .../media_interfaces_m9_skl/media_interfaces_g9_skl.cpp | 2 +-
+ 7 files changed, 7 insertions(+), 8 deletions(-)
+
+diff --git a/media_driver/agnostic/gen9/codec/hal/media_srcs.cmake b/media_driver/agnostic/gen9/codec/hal/media_srcs.cmake
+index 8bb36bafe..78902a22d 100644
+--- a/media_driver/agnostic/gen9/codec/hal/media_srcs.cmake
++++ b/media_driver/agnostic/gen9/codec/hal/media_srcs.cmake
+@@ -27,7 +27,7 @@ set(TMP_1_HEADERS_
+ ${CMAKE_CURRENT_LIST_DIR}/codechal_hw_g9_X.h
+ )
+
+-if(${MMC_Supported} STREQUAL "yes")
++if(${MMC_Supported} STREQUAL "yes" AND ENABLE_NONFREE_KERNELS AND ENABLE_KERNELS)
+ set(TMP_1_SOURCES_
+ ${TMP_1_SOURCES_}
+ ${CMAKE_CURRENT_LIST_DIR}/codechal_memdecomp_g9.cpp
+diff --git a/media_driver/cmake/linux/media_feature_flags_linux.cmake b/media_driver/cmake/linux/media_feature_flags_linux.cmake
+index de0ca853f..8121ea60c 100644
+--- a/media_driver/cmake/linux/media_feature_flags_linux.cmake
++++ b/media_driver/cmake/linux/media_feature_flags_linux.cmake
+@@ -35,7 +35,6 @@ if(NOT ENABLE_KERNELS OR NOT ENABLE_NONFREE_KERNELS)
+ bs_set_if_undefined(HEVC_Encode_VME_Supported "no")
+ bs_set_if_undefined(MPEG2_Encode_VME_Supported "no")
+ bs_set_if_undefined(CMRT_HEVC_ENC_FEI_Supported "no")
+- bs_set_if_undefined(MMC_Supported "no")
+ bs_set_if_undefined(VC1_Decode_Supported "no")
+ bs_set_if_undefined(Decode_Processing_Supported "no")
+ bs_set_if_undefined(Kernel_Auto_Denoise_Supported "no")
+@@ -46,7 +45,6 @@ else()
+ bs_set_if_undefined(HEVC_Encode_VME_Supported "${Encode_VME_Supported}")
+ bs_set_if_undefined(MPEG2_Encode_VME_Supported "${Encode_VME_Supported}")
+ bs_set_if_undefined(CMRT_HEVC_ENC_FEI_Supported "yes")
+- bs_set_if_undefined(MMC_Supported "yes")
+ bs_set_if_undefined(VC1_Decode_Supported "yes")
+ bs_set_if_undefined(Decode_Processing_Supported "yes")
+ bs_set_if_undefined(Kernel_Auto_Denoise_Supported "yes")
+@@ -64,6 +62,7 @@ bs_set_if_undefined(VP9_Decode_Supported "yes")
+ bs_set_if_undefined(VP_SFC_Supported "yes")
+ bs_set_if_undefined(Common_Encode_Supported "yes")
+ bs_set_if_undefined(Media_Scalability_Supported "yes")
++bs_set_if_undefined(MMC_Supported "yes")
+
+ # features controlled by global flag Encode_VDEnc_Supported
+ bs_set_if_undefined(AVC_Encode_VDEnc_Supported "${Encode_VDEnc_Supported}")
+diff --git a/media_driver/media_interface/media_interfaces_m9_bxt/media_interfaces_g9_bxt.cpp b/media_driver/media_interface/media_interfaces_m9_bxt/media_interfaces_g9_bxt.cpp
+index 3f306ee2a..8e4c0f532 100644
+--- a/media_driver/media_interface/media_interfaces_m9_bxt/media_interfaces_g9_bxt.cpp
++++ b/media_driver/media_interface/media_interfaces_m9_bxt/media_interfaces_g9_bxt.cpp
+@@ -135,7 +135,7 @@ MOS_STATUS MhwInterfacesG9Bxt::Initialize(
+
+ return MOS_STATUS_SUCCESS;
+ }
+-#ifdef _MMC_SUPPORTED
++#if defined(_MMC_SUPPORTED) && defined(ENABLE_KERNELS) && !defined(_FULL_OPEN_SOURCE)
+ static bool bxtRegisteredMmd =
+ MediaFactory<uint32_t, MmdDevice>::
+ Register<MmdDeviceG9Bxt>((uint32_t)IGFX_BROXTON);
+diff --git a/media_driver/media_interface/media_interfaces_m9_cfl/media_interfaces_g9_cfl.cpp b/media_driver/media_interface/media_interfaces_m9_cfl/media_interfaces_g9_cfl.cpp
+index b8fa1eec0..84e0fad1d 100644
+--- a/media_driver/media_interface/media_interfaces_m9_cfl/media_interfaces_g9_cfl.cpp
++++ b/media_driver/media_interface/media_interfaces_m9_cfl/media_interfaces_g9_cfl.cpp
+@@ -44,7 +44,7 @@ static bool cflRegisteredMhw =
+ MediaFactory<uint32_t, MhwInterfaces>::
+ Register<MhwInterfacesG9Kbl>((uint32_t)IGFX_COFFEELAKE);
+
+-#ifdef _MMC_SUPPORTED
++#if defined(_MMC_SUPPORTED) && defined(ENABLE_KERNELS) && !defined(_FULL_OPEN_SOURCE)
+ static bool cflRegisteredMmd =
+ MediaFactory<uint32_t, MmdDevice>::
+ Register<MmdDeviceG9Kbl>((uint32_t)IGFX_COFFEELAKE);
+diff --git a/media_driver/media_interface/media_interfaces_m9_glk/media_interfaces_g9_glk.cpp b/media_driver/media_interface/media_interfaces_m9_glk/media_interfaces_g9_glk.cpp
+index de81e6091..2638cb3a6 100644
+--- a/media_driver/media_interface/media_interfaces_m9_glk/media_interfaces_g9_glk.cpp
++++ b/media_driver/media_interface/media_interfaces_m9_glk/media_interfaces_g9_glk.cpp
+@@ -65,7 +65,7 @@ static bool glkRegisteredMhw =
+ MediaFactory<uint32_t, MhwInterfaces>::
+ Register<MhwInterfacesG9Kbl>((uint32_t)IGFX_GEMINILAKE);
+
+-#ifdef _MMC_SUPPORTED
++#if defined(_MMC_SUPPORTED) && defined(ENABLE_KERNELS) && !defined(_FULL_OPEN_SOURCE)
+ static bool glkRegisteredMmd =
+ MediaFactory<uint32_t, MmdDevice>::
+ Register<MmdDeviceG9Kbl>((uint32_t)IGFX_GEMINILAKE);
+diff --git a/media_driver/media_interface/media_interfaces_m9_kbl/media_interfaces_g9_kbl.cpp b/media_driver/media_interface/media_interfaces_m9_kbl/media_interfaces_g9_kbl.cpp
+index 99d786185..4e9c6e7f1 100644
+--- a/media_driver/media_interface/media_interfaces_m9_kbl/media_interfaces_g9_kbl.cpp
++++ b/media_driver/media_interface/media_interfaces_m9_kbl/media_interfaces_g9_kbl.cpp
+@@ -131,7 +131,7 @@ MOS_STATUS MhwInterfacesG9Kbl::Initialize(
+
+ return MOS_STATUS_SUCCESS;
+ }
+-#ifdef _MMC_SUPPORTED
++#if defined(_MMC_SUPPORTED) && defined(ENABLE_KERNELS) && !defined(_FULL_OPEN_SOURCE)
+ static bool kblRegisteredMmd =
+ MediaFactory<uint32_t, MmdDevice>::
+ Register<MmdDeviceG9Kbl>((uint32_t)IGFX_KABYLAKE);
+diff --git a/media_driver/media_interface/media_interfaces_m9_skl/media_interfaces_g9_skl.cpp b/media_driver/media_interface/media_interfaces_m9_skl/media_interfaces_g9_skl.cpp
+index e2520edf7..4b0012c64 100644
+--- a/media_driver/media_interface/media_interfaces_m9_skl/media_interfaces_g9_skl.cpp
++++ b/media_driver/media_interface/media_interfaces_m9_skl/media_interfaces_g9_skl.cpp
+@@ -139,7 +139,7 @@ MOS_STATUS MhwInterfacesG9Skl::Initialize(
+
+ return MOS_STATUS_SUCCESS;
+ }
+-#ifdef _MMC_SUPPORTED
++#if defined(_MMC_SUPPORTED) && defined(ENABLE_KERNELS) && !defined(_FULL_OPEN_SOURCE)
+ static bool sklRegisteredMmd =
+ MediaFactory<uint32_t, MmdDevice>::
+ Register<MmdDeviceG9Skl>((uint32_t)IGFX_SKYLAKE);
+--
+2.40.0
+
diff --git a/srcpkgs/intel-media-driver/patches/execinfo.patch b/srcpkgs/intel-media-driver/patches/execinfo.patch
deleted file mode 100644
index 25d21192d5a1..000000000000
--- a/srcpkgs/intel-media-driver/patches/execinfo.patch
+++ /dev/null
@@ -1,58 +0,0 @@
-From b17354142563b45e0ebf427485591426481368fd Mon Sep 17 00:00:00 2001
-From: Bernd Kuhls <bernd.kuhls@t-online.de>
-Date: Fri, 29 Jul 2022 19:51:39 +0200
-Subject: [PATCH] Fix uClibc build
-
-uClibc does not provide execinfo.h
----
- CMakeLists.txt | 6 ++++++
- .../linux/common/os/osservice/mos_utilities_specific.cpp | 4 ++++
- 2 files changed, 10 insertions(+)
-
-diff --git a/CMakeLists.txt b/CMakeLists.txt
-index 053904748..4a3f0869e 100755
---- a/CMakeLists.txt
-+++ b/CMakeLists.txt
-@@ -53,6 +53,12 @@ option (BUILD_CMRTLIB "Build and Install cmrtlib together with media driver" ON)
-
- option (ENABLE_PRODUCTION_KMD "Enable Production KMD header files" OFF)
-
-+include(CheckIncludeFileCXX)
-+check_include_file_cxx("execinfo.h" HAVE_EXECINFO)
-+if (HAVE_EXECINFO)
-+ add_definitions(-DHAVE_EXECINFO)
-+endif()
-+
- include(GNUInstallDirs)
-
- if (BUILD_CMRTLIB AND NOT CMAKE_WDDM_LINUX)
-diff --git a/media_softlet/linux/common/os/osservice/mos_utilities_specific.cpp b/media_softlet/linux/common/os/osservice/mos_utilities_specific.cpp
-index bde216b83..120b02d55 100644
---- a/media_softlet/linux/common/os/osservice/mos_utilities_specific.cpp
-+++ b/media_softlet/linux/common/os/osservice/mos_utilities_specific.cpp
-@@ -34,7 +34,9 @@
- #include <signal.h>
- #include <unistd.h> // fork
- #include <algorithm>
-+#ifdef HAVE_EXECINFO
- #include <execinfo.h> // backtrace
-+#endif
- #include <sys/types.h>
- #include <sys/stat.h> // fstat
- #include <sys/ipc.h> // System V IPC
-@@ -2473,6 +2475,7 @@ void MosUtilities::MosTraceEvent(
- MOS_FreeMemory(pTraceBuf);
- }
- }
-+#ifdef HAVE_EXECINFO
- if (m_mosTraceFilter & (1ULL << TR_KEY_CALL_STACK))
- {
- // reserve space for header and stack size field.
-@@ -2492,6 +2495,7 @@ void MosUtilities::MosTraceEvent(
- size_t ret = write(MosUtilitiesSpecificNext::m_mosTraceFd, traceBuf, nLen);
- }
- }
-+#endif
- }
- return;
- }
diff --git a/srcpkgs/intel-media-driver/template b/srcpkgs/intel-media-driver/template
index 1ca94569e117..1735b90c65ce 100644
--- a/srcpkgs/intel-media-driver/template
+++ b/srcpkgs/intel-media-driver/template
@@ -1,6 +1,6 @@
# Template file for 'intel-media-driver'
pkgname=intel-media-driver
-version=22.5.3
+version=22.6.4
revision=1
archs="x86_64*"
build_style=cmake
@@ -12,7 +12,7 @@ maintainer="Stefano Ragni <st3r4g@protonmail.com>"
license="MIT, BSD-3-Clause"
homepage="https://github.com/intel/media-driver"
distfiles="https://github.com/intel/media-driver/archive/intel-media-${version}.tar.gz"
-checksum=65652b365d48be3c9f0b3c561502952b92ee5fcc587520b88d0d752cf2a6a3b5
+checksum=0c04b9d74b92de41fd409b62913ce4afd799236c0b6bc1983a496990764e5d90
build_options="nonfree"
desc_option_nonfree="Enable nonfree kernels"
From 2df76e50af221cce09ced6a38203600ad954d59e Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Fri, 16 Dec 2022 09:31:43 -0500
Subject: [PATCH 112/140] New package: onevpl-2023.1.2
---
common/shlibs | 1 +
srcpkgs/onevpl-devel | 1 +
srcpkgs/onevpl/template | 34 ++++++++++++++++++++++++++++++++++
3 files changed, 36 insertions(+)
create mode 120000 srcpkgs/onevpl-devel
create mode 100644 srcpkgs/onevpl/template
diff --git a/common/shlibs b/common/shlibs
index 42744a55b1fc..f1675bacfe8b 100644
--- a/common/shlibs
+++ b/common/shlibs
@@ -879,6 +879,7 @@ libwebp.so.7 libwebp-0.6.0_1
libwebpmux.so.3 libwebp-0.6.0_1
libwebpdemux.so.2 libwebp-0.5.0_1
libwebpdecoder.so.3 libwebp-0.6.0_1
+libvpl.so.2 onevpl-2023.1.2_1
libva-x11.so.2 libva-2.13.0_1
libva.so.2 libva-2.13.0_1
libva-glx.so.2 libva-glx-2.13.0_1
diff --git a/srcpkgs/onevpl-devel b/srcpkgs/onevpl-devel
new file mode 120000
index 000000000000..e2306500b487
--- /dev/null
+++ b/srcpkgs/onevpl-devel
@@ -0,0 +1 @@
+onevpl
\ No newline at end of file
diff --git a/srcpkgs/onevpl/template b/srcpkgs/onevpl/template
new file mode 100644
index 000000000000..85c7c2da85ce
--- /dev/null
+++ b/srcpkgs/onevpl/template
@@ -0,0 +1,34 @@
+# Template file for 'onevpl'
+pkgname=onevpl
+version=2023.1.2
+revision=1
+archs="x86_64*"
+build_style=cmake
+configure_args="
+ -DCMAKE_BUILD_TYPE=Release -Wno-dev
+ -DBUILD_PYTHON_BINDING:BOOL='OFF'
+ -DBUILD_EXAMPLES:BOOL='OFF'
+ -DBUILD_TESTS:BOOL='ON'
+ -DINSTALL_EXAMPLE_CODE:BOOL='OFF'"
+hostmakedepends="cmake libX11 python wayland-protocols pkg-config"
+makedepends="libva-devel libX11-devel wayland-devel"
+short_desc="Intel oneAPI Video Processing library"
+maintainer="zlice <zlice555@gmail.com>"
+license="MIT"
+homepage="https://www.intel.com/content/www/us/en/developer/tools/oneapi/onevpl.html"
+distfiles="https://github.com/oneapi-src/oneVPL/archive/v${version}/${pkgname}-${version}.tar.gz"
+checksum=b2261cca174ce1815f3d47c647921ab17f68267c69c1e2444ff27aab7d199cbb
+
+post_install() {
+ vlicense LICENSE
+}
+
+onevpl-devel_package() {
+ depends="${makedepends} ${sourcepkg}-${version}_${revision}"
+ short_desc+=" - development files"
+ pkg_install() {
+ vmove usr/include
+ vmove usr/lib/pkgconfig
+ vmove "usr/lib/*.so"
+ }
+}
From 4274baf41e02d579c4194fc3315d67b0d581318d Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Fri, 16 Dec 2022 15:27:04 -0500
Subject: [PATCH 113/140] New package: onevpl-intel-gpu-22.6.4
---
srcpkgs/onevpl-intel-gpu-devel | 1 +
srcpkgs/onevpl-intel-gpu/template | 27 +++++++++++++++++++++++++++
2 files changed, 28 insertions(+)
create mode 120000 srcpkgs/onevpl-intel-gpu-devel
create mode 100644 srcpkgs/onevpl-intel-gpu/template
diff --git a/srcpkgs/onevpl-intel-gpu-devel b/srcpkgs/onevpl-intel-gpu-devel
new file mode 120000
index 000000000000..47920ceecf91
--- /dev/null
+++ b/srcpkgs/onevpl-intel-gpu-devel
@@ -0,0 +1 @@
+onevpl-intel-gpu
\ No newline at end of file
diff --git a/srcpkgs/onevpl-intel-gpu/template b/srcpkgs/onevpl-intel-gpu/template
new file mode 100644
index 000000000000..f14acb728a54
--- /dev/null
+++ b/srcpkgs/onevpl-intel-gpu/template
@@ -0,0 +1,27 @@
+# Template file for 'onevpl-intel-gpu'
+pkgname=onevpl-intel-gpu
+version=22.6.4
+revision=1
+archs="x86_64*"
+build_style=cmake
+configure_args="-Wno-dev -DCMAKE_BUILD_TYPE=Release"
+hostmakedepends="cmake pkg-config"
+makedepends="libdrm-devel libva-devel onevpl-devel"
+short_desc="Runtime implementation of oneVPL API for Intel Gen GPUs"
+maintainer="zlice <zlice555@gmail.com>"
+license="MIT"
+homepage="https://github.com/oneapi-src/oneVPL-intel-gpu"
+changelog="https://github.com/oneapi-src/oneVPL-intel-gpu/blob/main/CHANGELOG.md"
+distfiles="https://github.com/oneapi-src/oneVPL-intel-gpu/archive/refs/tags/intel-onevpl-${version}.tar.gz"
+checksum=74b0979dcb2af1b7c68edb8cbcb02d539de511090b12fac50652cbacd707c4e6
+
+post_install() {
+ vlicense LICENSE
+}
+
+onevpl-intel-gpu-devel_package() {
+ short_desc+=" - development files"
+ pkg_install() {
+ vmove usr/lib/pkgconfig
+ }
+}
From c0baf9571ee2f59abfb13995bbc0b026130285ff Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Sun, 18 Dec 2022 01:40:15 -0500
Subject: [PATCH 114/140] igt-gpu-tools: update to version 1.27 revbump idk
remove
---
...-loading-failure-in-resolve-function.patch | 63 -------------------
srcpkgs/igt-gpu-tools/patches/musl.patch | 20 ++++++
srcpkgs/igt-gpu-tools/template | 4 +-
3 files changed, 22 insertions(+), 65 deletions(-)
delete mode 100644 srcpkgs/igt-gpu-tools/patches/i-g-t-Fix-global-symbol-loading-failure-in-resolve-function.patch
diff --git a/srcpkgs/igt-gpu-tools/patches/i-g-t-Fix-global-symbol-loading-failure-in-resolve-function.patch b/srcpkgs/igt-gpu-tools/patches/i-g-t-Fix-global-symbol-loading-failure-in-resolve-function.patch
deleted file mode 100644
index 0c3b554d9949..000000000000
--- a/srcpkgs/igt-gpu-tools/patches/i-g-t-Fix-global-symbol-loading-failure-in-resolve-function.patch
+++ /dev/null
@@ -1,63 +0,0 @@
-diff --git lib/igt_halffloat.c lib/igt_halffloat.c
-index 08ab05fc..e5e8a5bd 100644
---- a/lib/igt_halffloat.c
-+++ b/lib/igt_halffloat.c
-@@ -24,6 +24,19 @@
-
- #include <assert.h>
- #include <math.h>
-+#include <stdbool.h>
-+
-+#ifdef HAVE_CPUID_H
-+#include <cpuid.h>
-+#else
-+#define __get_cpuid_max(x, y) 0
-+#define __cpuid(level, a, b, c, d) a = b = c = d = 0
-+#define __cpuid_count(level, count, a, b, c, d) a = b = c = d = 0
-+#endif
-+
-+#ifndef bit_F16C
-+#define bit_F16C (1 << 29)
-+#endif
-
- #include "igt_halffloat.h"
- #include "igt_x86.h"
-@@ -182,6 +195,20 @@ static void half_to_float_f16c(const uint16_t *h, float *f, unsigned int num)
-
- #pragma GCC pop_options
-
-+static bool f16c_is_supported(void)
-+{
-+ unsigned max = __get_cpuid_max(0, NULL);
-+ unsigned eax, ebx, ecx, edx;
-+
-+ if (max >= 1) {
-+ __cpuid(1, eax, ebx, ecx, edx);
-+
-+ if (ecx & bit_F16C)
-+ return true;
-+ }
-+ return false;
-+}
-+
- static void float_to_half(const float *f, uint16_t *h, unsigned int num)
- {
- for (int i = 0; i < num; i++)
-@@ -196,7 +223,7 @@ static void half_to_float(const uint16_t *h, float *f, unsigned int num)
-
- static void (*resolve_float_to_half(void))(const float *f, uint16_t *h, unsigned int num)
- {
-- if (igt_x86_features() & F16C)
-+ if (f16c_is_supported())
- return float_to_half_f16c;
-
- return float_to_half;
-@@ -207,7 +234,7 @@ void igt_float_to_half(const float *f, uint16_t *h, unsigned int num)
-
- static void (*resolve_half_to_float(void))(const uint16_t *h, float *f, unsigned int num)
- {
-- if (igt_x86_features() & F16C)
-+ if (f16c_is_supported())
- return half_to_float_f16c;
-
- return half_to_float;
diff --git a/srcpkgs/igt-gpu-tools/patches/musl.patch b/srcpkgs/igt-gpu-tools/patches/musl.patch
index 615afdb8f8ea..4de6e0cfd898 100644
--- a/srcpkgs/igt-gpu-tools/patches/musl.patch
+++ b/srcpkgs/igt-gpu-tools/patches/musl.patch
@@ -191,6 +191,7 @@ index 74935430..0dc87d8c 100644
+++ b/tests/i915/i915_pm_rpm.c
@@ -27,6 +27,7 @@
+<<<<<<< HEAD
#include "config.h"
+#include <limits.h> // PATH_MAX
@@ -293,3 +294,22 @@ index 0faf3fc8..f6bd970e 100644
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
+=======
+ fbo = bo->map;
+lib/ioctl_wrappers.c.new
+--- a/benchmarks/gem_exec_tracer.c 2022-12-18 10:32:15.742341964 -0500
++++ b/benchmarks/gem_exec_tracer.c 2022-12-18 10:32:09.862211372 -0500
+@@ -275,7 +275,11 @@
+ DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_GEM_EXECBUFFER2, struct drm_i915_gem_execbuffer2)
+
+ int
++#if defined(__GLIBC__) || defined(__FreeBSD__)
+ ioctl(int fd, unsigned long request, ...)
++#else
++ioctl(int fd, int request, ...)
++#endif
+ {
+ struct trace *t, **p;
+ va_list args;
+
+>>>>>>> 60301ae02f (igt-gpu-tools: update to version 1.26)
diff --git a/srcpkgs/igt-gpu-tools/template b/srcpkgs/igt-gpu-tools/template
index 225e2c79118a..1376c39d5d5b 100644
--- a/srcpkgs/igt-gpu-tools/template
+++ b/srcpkgs/igt-gpu-tools/template
@@ -1,7 +1,7 @@
# Template file for 'igt-gpu-tools'
pkgname=igt-gpu-tools
version=1.27.1
-revision=1
+revision=2
build_style=meson
configure_args="-Db_ndebug=false -Ddocs=disabled"
hostmakedepends="pkg-config flex peg python3-docutils"
@@ -13,7 +13,7 @@ maintainer="Orphaned <orphan@voidlinux.org>"
license="MIT"
homepage="https://gitlab.freedesktop.org/drm/igt-gpu-tools"
changelog="https://gitlab.freedesktop.org/drm/igt-gpu-tools/-/raw/master/NEWS"
-distfiles="${XORG_SITE}/app/igt-gpu-tools-${version}.tar.xz"
+distfiles="${XORG_SITE}/app/${pkgname}-${version}.tar.xz"
checksum=93b9a4816ed22b5145bb61024314c8a65caeea991ce93027643f1d40723bf417
# tests don't behave in containers
make_check=ci-skip
From b0c46a793bdabef1bd17f8f7983df5a74edd4195 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Mon, 3 Apr 2023 23:30:28 -0400
Subject: [PATCH 115/140] freecad: revbump for qt5-webengine-5.15.13
---
srcpkgs/freecad/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/freecad/template b/srcpkgs/freecad/template
index f62023ee8ce4..e301f32d3540 100644
--- a/srcpkgs/freecad/template
+++ b/srcpkgs/freecad/template
@@ -1,7 +1,7 @@
# Template file for 'freecad'
pkgname=freecad
version=0.20.2
-revision=3
+revision=4
build_style=cmake
_inst_prefix=/usr/lib/${pkgname}
From 02b79ac0c495f8f2c2237c43287378aa475ca39f Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Mon, 3 Apr 2023 23:31:45 -0400
Subject: [PATCH 116/140] shotcut: revbump for mlt7-7.14.0
---
srcpkgs/shotcut/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/shotcut/template b/srcpkgs/shotcut/template
index 32583277dab2..8d8a7a0ebdeb 100644
--- a/srcpkgs/shotcut/template
+++ b/srcpkgs/shotcut/template
@@ -1,7 +1,7 @@
# Template file for 'shotcut'
pkgname=shotcut
version=22.12.21
-revision=1
+revision=2
build_style=cmake
configure_args="-DSHOTCUT_VERSION=${version}"
hostmakedepends="pkg-config qt5-tools-devel"
From 9955f00a5b449e62684efac640df0c24664ce08e Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Mon, 3 Apr 2023 23:33:30 -0400
Subject: [PATCH 117/140] shiboken2: revbump for qt5-5.15.8
---
srcpkgs/shiboken2/patches/importlib-machinery-bypass.patch | 1 +
srcpkgs/shiboken2/template | 2 +-
2 files changed, 2 insertions(+), 1 deletion(-)
create mode 120000 srcpkgs/shiboken2/patches/importlib-machinery-bypass.patch
diff --git a/srcpkgs/shiboken2/patches/importlib-machinery-bypass.patch b/srcpkgs/shiboken2/patches/importlib-machinery-bypass.patch
new file mode 120000
index 000000000000..efcf3249bd88
--- /dev/null
+++ b/srcpkgs/shiboken2/patches/importlib-machinery-bypass.patch
@@ -0,0 +1 @@
+../../python3-pyside2/patches/importlib-machinery-bypass.patch
\ No newline at end of file
diff --git a/srcpkgs/shiboken2/template b/srcpkgs/shiboken2/template
index 084ecc3ba1e1..2a21998997eb 100644
--- a/srcpkgs/shiboken2/template
+++ b/srcpkgs/shiboken2/template
@@ -1,7 +1,7 @@
# Template file for 'shiboken2'
pkgname=shiboken2
version=5.15.7
-revision=1
+revision=2
_pkgname="pyside-setup-opensource-src-${version}"
build_wrksrc="sources/shiboken2"
build_style=cmake
From 55a31610af49b4d666674fba71aade6ae6dd3b7a Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Mon, 3 Apr 2023 23:33:53 -0400
Subject: [PATCH 118/140] python3-pyside2: update to 5.15.8
---
.../patches/importlib-machinery-bypass.patch | 15 +++++++++++++++
srcpkgs/python3-pyside2/template | 9 +++++----
2 files changed, 20 insertions(+), 4 deletions(-)
create mode 100644 srcpkgs/python3-pyside2/patches/importlib-machinery-bypass.patch
diff --git a/srcpkgs/python3-pyside2/patches/importlib-machinery-bypass.patch b/srcpkgs/python3-pyside2/patches/importlib-machinery-bypass.patch
new file mode 100644
index 000000000000..64c429584776
--- /dev/null
+++ b/srcpkgs/python3-pyside2/patches/importlib-machinery-bypass.patch
@@ -0,0 +1,15 @@
+Using this prevents an error around line 220 below it.
+"AttributeError: module 'importlib' has no attribute 'machinery'"
+The old backup logic is in place and compiles without issues.
+--- a/sources/shiboken2/libshiboken/embed/signature_bootstrap.py 2023-04-02 23:09:34.688912402 -0400
++++ b/sources/shiboken2/libshiboken/embed/signature_bootstrap.py 2023-04-02 23:10:03.395529582 -0400
+@@ -170,9 +170,6 @@
+
+ # 'zipstring_sequence' comes from signature.cpp
+ zipbytes = base64.b64decode(''.join(zipstring_sequence))
+- if sys.version_info[0] >= 3:
+- vzip = zipfile.ZipFile(io.BytesIO(zipbytes))
+- return sys.meta_path, EmbeddableZipImporter(vzip)
+
+ # Old version for Python 2.7, only.
+ import os
diff --git a/srcpkgs/python3-pyside2/template b/srcpkgs/python3-pyside2/template
index 50e6ff260d3b..b50e62bd215d 100644
--- a/srcpkgs/python3-pyside2/template
+++ b/srcpkgs/python3-pyside2/template
@@ -1,11 +1,12 @@
# Template file for 'python3-pyside2'
pkgname=python3-pyside2
-version=5.15.5
-revision=2
+version=5.15.8
+revision=1
_pkgname="pyside-setup-opensource-src-${version}"
build_wrksrc="sources/pyside2"
build_style=cmake
-configure_args="-DPYTHON_EXECUTABLE=/usr/bin/python"
+configure_args="-DPYTHON_EXECUTABLE=/usr/bin/python -DCMAKE_BUILD_TYPE=None
+ -DBUILD_TESTS=OFF"
hostmakedepends="cmake python3 shiboken2"
makedepends="python3-devel libshiboken2-devel qt5-devel
qt5-multimedia-devel qt5-tools-devel qt5-plugin-mysql qt5-plugin-odbc
@@ -23,7 +24,7 @@ maintainer="yopito <pierre.bourgin@free.fr>"
license="LGPL-3.0-or-later"
homepage="https://wiki.qt.io/Qt_for_Python"
distfiles="https://download.qt.io/official_releases/QtForPython/pyside2/PySide2-${version}-src/${_pkgname}.tar.xz"
-checksum=3920a4fb353300260c9bc46ff70f1fb975c5e7efa22e9d51222588928ce19b33
+checksum=23436302c8deb5b4cbc769b205d09604e38ba83b40708efccb7bd8c9af6f6b5d
build_options="webengine"
desc_option_webengine="Build Qt5 WebEngine bindings"
From 52d0ff624e2add8150a2ee66e246a64eb19f1bda Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Tue, 4 Apr 2023 11:14:35 -0400
Subject: [PATCH 119/140] konqueror: revbump for ffmpeg-6.0
---
srcpkgs/konqueror/template | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/srcpkgs/konqueror/template b/srcpkgs/konqueror/template
index d8d0e73a78ab..c5bdba601d3c 100644
--- a/srcpkgs/konqueror/template
+++ b/srcpkgs/konqueror/template
@@ -1,11 +1,11 @@
# Template file for 'konqueror'
pkgname=konqueror
version=23.04.0
-revision=1
+revision=2
build_style=cmake
configure_args="-DDESKTOPTOJSON_EXECUTABLE=/usr/bin/desktoptojson"
hostmakedepends="extra-cmake-modules python3 qt5-host-tools qt5-qmake kdoctools
-kcoreaddons kconfig gettext"
+ kcoreaddons kconfig gettext"
makedepends="qt5-devel qt5-webengine-devel qt5-declarative-devel
qt5-webchannel-devel qt5-location-devel kcmutils-devel kdelibs4support-devel
karchive-devel khtml-devel kdesu-devel kactivities5-devel"
From 61c65c67d718432529f6294b28e90626b2afc039 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Tue, 4 Apr 2023 11:14:58 -0400
Subject: [PATCH 120/140] qt5-speech: revbump for qt5-5.15.8
---
srcpkgs/qt5-speech/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/qt5-speech/template b/srcpkgs/qt5-speech/template
index 3ecd10d50650..2d7d4d4d2453 100644
--- a/srcpkgs/qt5-speech/template
+++ b/srcpkgs/qt5-speech/template
@@ -1,7 +1,7 @@
# Template file for 'qt5-speech'
pkgname=qt5-speech
version=5.15.7
-revision=2
+revision=3
_commit=d32f4a479d38a11f547598004b975f4356424a16
build_style=qmake
configure_args="-- -flite -flite-alsa -speechd"
From 2a0907b8c3f09ded664a41bb90b84f9087769c59 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Tue, 4 Apr 2023 18:38:50 -0400
Subject: [PATCH 121/140] qt5_styleplugins: revbump for qt5-5.15.8
---
srcpkgs/qt5-styleplugins/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/qt5-styleplugins/template b/srcpkgs/qt5-styleplugins/template
index 96ed97d12cd2..30d93660a2a4 100644
--- a/srcpkgs/qt5-styleplugins/template
+++ b/srcpkgs/qt5-styleplugins/template
@@ -1,7 +1,7 @@
# Template file for 'qt5-styleplugins'
pkgname=qt5-styleplugins
version=5.0.0
-revision=20
+revision=21
_gitrev=335dbece103e2cbf6c7cf819ab6672c2956b17b3
build_style=qmake
hostmakedepends="pkg-config qt5-host-tools qt5-qmake"
From 45ed5d3da5fd8fa2e2b3e08fc8bf20f885feaca8 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Thu, 27 Apr 2023 21:58:35 -0400
Subject: [PATCH 122/140] blender: update to 3.5.1
---
srcpkgs/blender/patches/numpy-2.24.patch | 22 ----------------------
srcpkgs/blender/template | 13 +++++++------
2 files changed, 7 insertions(+), 28 deletions(-)
delete mode 100644 srcpkgs/blender/patches/numpy-2.24.patch
diff --git a/srcpkgs/blender/patches/numpy-2.24.patch b/srcpkgs/blender/patches/numpy-2.24.patch
deleted file mode 100644
index 716315b74be7..000000000000
--- a/srcpkgs/blender/patches/numpy-2.24.patch
+++ /dev/null
@@ -1,22 +0,0 @@
-From 74e6e07cf7c67b55d384db72f5aa3892db8a3da6 Mon Sep 17 00:00:00 2001
-From: oreo639 <oreo6391@gmail.com>
-Date: Tue, 17 Jan 2023 14:36:54 -0800
-Subject: [PATCH] Remove usage of deprecated np.bool alias
-
----
- addons/io_scene_gltf2/blender/imp/gltf2_blender_mesh.py | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-diff --git a/addons/io_scene_gltf2/blender/imp/gltf2_blender_mesh.py b/addons/io_scene_gltf2/blender/imp/gltf2_blender_mesh.py
-index 6366434a6..8160c9e99 100644
---- a/release/scripts/addons/io_scene_gltf2/blender/imp/gltf2_blender_mesh.py
-+++ b/release/scripts/addons/io_scene_gltf2/blender/imp/gltf2_blender_mesh.py
-@@ -620,7 +620,7 @@ def set_poly_smoothing(gltf, pymesh, mesh, vert_normals, loop_vidxs):
- # Try to guess which polys should be flat based on the fact that all the
- # loop normals for a flat poly are = the poly's normal.
-
-- poly_smooths = np.empty(num_polys, dtype=np.bool)
-+ poly_smooths = np.empty(num_polys, dtype=bool)
-
- poly_normals = np.empty(num_polys * 3, dtype=np.float32)
- mesh.polygons.foreach_get('normal', poly_normals)
diff --git a/srcpkgs/blender/template b/srcpkgs/blender/template
index d18bc88838ff..900bc17937c3 100644
--- a/srcpkgs/blender/template
+++ b/srcpkgs/blender/template
@@ -1,7 +1,7 @@
# Template file for 'blender'
pkgname=blender
-version=3.4.1
-revision=4
+version=3.5.1
+revision=1
archs="x86_64* ppc64*"
build_style="cmake"
pycompile_dirs="/usr/share/blender/${version%.*}/scripts"
@@ -9,8 +9,8 @@ configure_args="-DWITH_INSTALL_PORTABLE=OFF -DWITH_PYTHON_INSTALL=OFF
-DWITH_JACK=ON -DWITH_CODEC_FFMPEG=ON -DWITH_CODEC_SNDFILE=ON -DWITH_OPENMP=ON
-DWITH_FFTW3=ON -DWITH_MOD_OCEANSIM=ON -DWITH_CYCLES_EMBREE=OFF -DWITH_OPENCOLORIO=ON
-DWITH_IMAGE_OPENEXR=ON -DWITH_IMAGE_OPENJPEG=ON -DWITH_OPENSUBDIV=ON
- -DWITH_OPENCOLLADA=ON -DWITH_SYSTEM_GLEW=ON -DWITH_OPENVDB=ON -DWITH_ALEMBIC=ON
- -DWITH_GHOST_X11=ON -DWITH_GHOST_WAYLAND=ON -DWITH_GHOST_LIBDECOR=ON
+ -DWITH_OPENCOLLADA=ON -DWITH_OPENVDB=ON -DWITH_ALEMBIC=ON
+ -DWITH_GHOST_X11=ON -DWITH_GHOST_WAYLAND=ON -DWITH_GHOST_WAYLAND_LIBDECOR=ON
-DWITH_BUILDINFO=OFF -DPYTHON_VERSION=${py3_ver} -DPYTHON_LIBPATH=/usr/lib
-DPYTHON_LIBRARY='python${py3_ver}${py3_abiver}'
-DPYTHON_INCLUDE_DIRS=/${py3_inc}"
@@ -22,14 +22,15 @@ makedepends="libgomp-devel libpng-devel tiff-devel python3-devel glu-devel
opencolorio-devel opencollada-devel python3-numpy libXrender-devel
OpenSubdiv-devel tbb-devel libxml2-devel openvdb-devel alembic-devel
pugixml-devel libXxf86vm-devel libepoxy-devel gmp-devel gmpxx-devel
- wayland-protocols wayland-devel libxkbcommon-devel libdecor-devel"
+ wayland-protocols wayland-devel libxkbcommon-devel libdecor-devel
+ level-zero-devel"
depends="desktop-file-utils hicolor-icon-theme"
short_desc="3D graphics creation suite"
maintainer="Enno Boland <gottox@voidlinux.org>"
license="GPL-3.0-or-later"
homepage="https://www.blender.org"
distfiles="https://download.blender.org/source/blender-${version}.tar.xz"
-checksum=247c4c1228270c9010f4721c985cb5b628ab50abcf9f2678630737142eeb91c3
+checksum=bd7428c7e6cba5a900216269c32111dffaabaf1bdb5472f231965e615174a809
python_version=3
LDFLAGS="-Wl,-z,stack-size=2097152"
# Blender tests are executed against a system installation of blender. This
From 40df1558fa8840c81b656bfb5b2214d91b3a11f8 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Thu, 27 Apr 2023 20:41:10 -0400
Subject: [PATCH 123/140] New package: level-zero-1.10.0
---
srcpkgs/level-zero-devel | 1 +
srcpkgs/level-zero/template | 28 ++++++++++++++++++++++++++++
2 files changed, 29 insertions(+)
create mode 120000 srcpkgs/level-zero-devel
create mode 100644 srcpkgs/level-zero/template
diff --git a/srcpkgs/level-zero-devel b/srcpkgs/level-zero-devel
new file mode 120000
index 000000000000..96ee8adf7303
--- /dev/null
+++ b/srcpkgs/level-zero-devel
@@ -0,0 +1 @@
+level-zero
\ No newline at end of file
diff --git a/srcpkgs/level-zero/template b/srcpkgs/level-zero/template
new file mode 100644
index 000000000000..4631c8c67505
--- /dev/null
+++ b/srcpkgs/level-zero/template
@@ -0,0 +1,28 @@
+# Template file for 'level-zero'
+pkgname=level-zero
+version=1.10.0
+revision=1
+archs="x86_64*"
+build_style=cmake
+hostmakedepends="cmake"
+makedepends="llvm clang clang-tools-extra SPIRV-LLVM-Translator-devel"
+short_desc="oneAPI Level Zero Specification"
+maintainer="Zlice <zlice555@gmail.com>"
+license="NCSA"
+homepage="https://github.com/oneapi-src/level-zero"
+distfiles="${homepage}/archive/refs/tags/v${version}.tar.gz"
+checksum=2811e4128ff6114020d0a147c2769b9b2e782e68ad49827685c33b9e716bf6ab
+
+post_install() {
+ vlicense LICENSE
+}
+
+level-zero-devel_package() {
+ depends="${makedepends} ${sourcepkg}-${version}_${revision}"
+ short_desc+=" - development files"
+ pkg_install() {
+ vmove usr/include
+ vmove usr/lib/pkgconfig
+ vmove "usr/lib/*.so"
+ }
+}
From 90f819a322fb212ca0df88678638ed6d1371348d Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Tue, 28 Mar 2023 19:54:49 -0400
Subject: [PATCH 124/140] New package: intel-metrics-library 1.0.133
---
srcpkgs/intel-metrics-library/template | 19 +++++++++++++++++++
1 file changed, 19 insertions(+)
create mode 100644 srcpkgs/intel-metrics-library/template
diff --git a/srcpkgs/intel-metrics-library/template b/srcpkgs/intel-metrics-library/template
new file mode 100644
index 000000000000..50f1a6079d7b
--- /dev/null
+++ b/srcpkgs/intel-metrics-library/template
@@ -0,0 +1,19 @@
+# Template file for 'intel-metrics-library'
+pkgname=intel-metrics-library
+version=1.0.133
+revision=1
+archs="x86_64*"
+build_style=cmake
+configure_args="-Wdev-no -DCMAKE_BUILD_TYPE=Release"
+hostmakedepends="cmake"
+makedepends="libdrm-devel"
+short_desc="Helper library that provides access to GPU performance counters"
+maintainer="Zlice <zlice555@gmail.com>"
+license="MIT"
+homepage="https://github.com/intel/metrics-library"
+distfiles="${homepage}/archive/refs/tags/metrics-library-${version}.tar.gz"
+checksum=83f7b2de3af5ffd2f1b487df8836e6d212e11668bd958bebae622a483fb1231f
+
+post_install() {
+ vlicense LICENSE.md
+}
From 71269b488067d3bf9cb73f2e07f26046c0193166 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Tue, 28 Mar 2023 19:54:18 -0400
Subject: [PATCH 125/140] New package: intel-metrics-discovery 1.12.163
---
srcpkgs/intel-metrics-discovery/template | 19 +++++++++++++++++++
1 file changed, 19 insertions(+)
create mode 100644 srcpkgs/intel-metrics-discovery/template
diff --git a/srcpkgs/intel-metrics-discovery/template b/srcpkgs/intel-metrics-discovery/template
new file mode 100644
index 000000000000..6083595e273c
--- /dev/null
+++ b/srcpkgs/intel-metrics-discovery/template
@@ -0,0 +1,19 @@
+# Template file for 'intel-metrics-discovery'
+pkgname=intel-metrics-discovery
+version=1.12.163
+revision=1
+archs="x86_64*"
+build_style=cmake
+configure_args="-Wdev-no -DCMAKE_BUILD_TYPE=Release"
+hostmakedepends="cmake"
+makedepends="libdrm-devel"
+short_desc="Helper library that provides access to GPU performance data"
+maintainer="Zlice <zlice555@gmail.com>"
+license="MIT"
+homepage="https://github.com/intel/metrics-discovery"
+distfiles="${homepage}/archive/refs/tags/metrics-discovery-${version}.tar.gz"
+checksum=6dfe8d11c58625bf3ebf656ec2a95dc96bbb05705ec71c6c3c3dd0ef5cd2319c
+
+post_install() {
+ vlicense LICENSE.md
+}
From b1030763a537fc9434ff74d5f6918980ae34f426 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Sun, 26 Mar 2023 10:48:34 -0400
Subject: [PATCH 126/140] New package: intel-graphics-compiler-1.0.13463.18
---
srcpkgs/intel-graphics-compiler/template | 22 ++++++++++++++++++++++
1 file changed, 22 insertions(+)
create mode 100644 srcpkgs/intel-graphics-compiler/template
diff --git a/srcpkgs/intel-graphics-compiler/template b/srcpkgs/intel-graphics-compiler/template
new file mode 100644
index 000000000000..44d38214f929
--- /dev/null
+++ b/srcpkgs/intel-graphics-compiler/template
@@ -0,0 +1,22 @@
+# Template file for 'intel-graphics-compiler'
+pkgname=intel-graphics-compiler
+version=1.0.13463.18
+revision=1
+archs="x86_64*"
+build_style=cmake
+configure_args="-Wno-dev -DIGC_OPTION__LLVM_PREFERRED_VERSION=15.0.7 -DCCLANG_FROM_SYSTEM=ON
+ -DIGC_OPTION__SPIRV_TOOLS_MODE=Prebuilds -DIGC_OPTION__USE_PREINSTALLED_SPRIV_HEADERS=ON
+ -DIGC_OPTION__VC_INTRINSICS_MODE=Prebuilds"
+hostmakedepends="flex bison zlib-devel libzstd-devel cmake"
+makedepends="llvm clang clang-tools-extra intel-opencl-clang intel-vc-intrinsics
+ lld lld-devel SPIRV-Headers SPIRV-LLVM-Translator-devel SPIRV-Tools-devel"
+short_desc="LLVM based compiler for OpenCL targeting Intel"
+maintainer="Zlice <zlice555@gmail.com>"
+license="MIT"
+homepage="https://github.com/intel/intel-graphics-compiler"
+distfiles="${homepage}/archive/refs/tags/igc-${version}.tar.gz"
+checksum=0b960878a5feffd6aa10197c48bf73a0a3a19d0105428d48163e91db0444070a
+
+post_install() {
+ vlicense LICENSE.md
+}
From 2bb11d6c0bac0e04e6ff0a5d47982b7d74f8afec Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Sun, 26 Mar 2023 10:48:05 -0400
Subject: [PATCH 127/140] New package: intel-compute-runtime-23.09.25812.14
---
srcpkgs/intel-compute-runtime/template | 22 ++++++++++++++++++++++
1 file changed, 22 insertions(+)
create mode 100644 srcpkgs/intel-compute-runtime/template
diff --git a/srcpkgs/intel-compute-runtime/template b/srcpkgs/intel-compute-runtime/template
new file mode 100644
index 000000000000..1132b830d348
--- /dev/null
+++ b/srcpkgs/intel-compute-runtime/template
@@ -0,0 +1,22 @@
+# Template file for 'intel-compute-runtime'
+pkgname=intel-compute-runtime
+version=23.09.25812.14
+revision=1
+archs="x86_64"
+build_style=cmake
+configure_args="-Wno-dev -DNEO_SKIP_UNIT_TESTS=1 -DSUPPORT_DG1=ON -DSUPPORT_DG2=ON"
+hostmakedepends="cmake pkg-config"
+makedepends="gcc intel-gmmlib-devel libva-devel ocl-icd-devel
+ intel-opencl-clang intel-graphics-compiler level-zero-devel
+ intel-metrics-library intel-metrics-discovery"
+depends="intel-graphics-compiler"
+short_desc="Intel Graphics Compute Runtime for oneAPI Level Zero and OpenCL"
+maintainer="Zlice <zlice555@gmail.com>"
+license="MIT"
+homepage="https://github.com/intel/compute-runtime"
+distfiles="${homepage}/archive/refs/tags/${version}.tar.gz"
+checksum=abe2e6d9d2ac771d5f42ee2357ce897ca3b00dc6185c06f3f62772f729c7f8e1
+
+post_install() {
+ vlicense LICENSE.md
+}
From e5a080b117dea40421ac0297c1012ec5f3016c23 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Sun, 26 Mar 2023 10:46:58 -0400
Subject: [PATCH 128/140] New package: intel-vc-intrinsics-0.12.3
---
srcpkgs/intel-vc-intrinsics/template | 21 +++++++++++++++++++++
1 file changed, 21 insertions(+)
create mode 100644 srcpkgs/intel-vc-intrinsics/template
diff --git a/srcpkgs/intel-vc-intrinsics/template b/srcpkgs/intel-vc-intrinsics/template
new file mode 100644
index 000000000000..129482bdf985
--- /dev/null
+++ b/srcpkgs/intel-vc-intrinsics/template
@@ -0,0 +1,21 @@
+# Template file for 'intel-vc-intrinsics'
+pkgname=intel-vc-intrinsics
+version=0.12.3
+revision=1
+archs="x86_64*"
+build_style=cmake
+configure_args="-Wno-dev -DLLVM_DIR=/usr/lib/cmake/llvm -DCMAKE_BUILD_TYPE=Release"
+hostmakedepends="cmake python"
+makedepends="llvm clang clang-tools-extra"
+short_desc="Set of intrinsics on top of core LLVM IR"
+maintainer="Zlice <zlice555@gmail.com>"
+license="MIT"
+homepage="https://github.com/intel/vc-intrinsics"
+distfiles="${homepage}/archive/refs/tags/v${version}.tar.gz"
+checksum=ed1c0d968cb2f8ee7b2840a14c3261639f1700e844fb7d2a89856babffd5e1d1
+
+# TODO: license isn't bundled in tar?
+# just added 2 days ago... mar 24th 2023
+#post_install() {
+# vlicense LICENSE.md
+#}
From b4bcfbf802d9db130ac1196625ba761b2a1b32ec Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Sun, 26 Mar 2023 10:46:11 -0400
Subject: [PATCH 129/140] New package: intel-opencl-clang-15.0.0
---
common/shlibs | 1 +
srcpkgs/intel-opencl-clang/template | 18 ++++++++++++++++++
2 files changed, 19 insertions(+)
create mode 100644 srcpkgs/intel-opencl-clang/template
diff --git a/common/shlibs b/common/shlibs
index f1675bacfe8b..f2d1be3d8514 100644
--- a/common/shlibs
+++ b/common/shlibs
@@ -1008,6 +1008,7 @@ libLLVM-15.so libllvm15-15.0.7_1
libLLVMSPIRVLib.so.15 SPIRV-LLVM-Translator-15.0.0_1
libomp.so.5 libomp-15.0.7_1
libomptarget.so.15 libomp-15.0.7_1
+libopencl-clang.so.15 intel-opencl-clang-15.0.0_1
libisofs.so.6 libisofs-0.6.24_1
libmpack.so.0 libmpack-1.0.5_1
libGeoIP.so.1 libgeoip-1.4.8_1
diff --git a/srcpkgs/intel-opencl-clang/template b/srcpkgs/intel-opencl-clang/template
new file mode 100644
index 000000000000..e6f09f6ad724
--- /dev/null
+++ b/srcpkgs/intel-opencl-clang/template
@@ -0,0 +1,18 @@
+# Template file for 'intel-opencl-clang'
+pkgname=intel-opencl-clang
+version=15.0.0
+revision=1
+archs="x86_64*"
+build_style=cmake
+hostmakedepends="cmake"
+makedepends="llvm clang clang-tools-extra SPIRV-LLVM-Translator-devel"
+short_desc="LLVM linked opencl-clang"
+maintainer="Zlice <zlice555@gmail.com>"
+license="NCSA"
+homepage="https://github.com/intel/opencl-clang"
+distfiles="${homepage}/archive/refs/tags/v${version}.tar.gz"
+checksum=ea179674e52bc8c658e2655f76be467f7052f7d2c37ebcfdb102dce645ad1411
+
+post_install() {
+ vlicense LICENSE
+}
From 6f9616cea0a03dc387f332b20ceff1d710d0d37b Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Sun, 30 Apr 2023 20:22:25 -0400
Subject: [PATCH 130/140] gstreamer1: update to 1.22.2
---
srcpkgs/gstreamer1/template | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/srcpkgs/gstreamer1/template b/srcpkgs/gstreamer1/template
index 362fe82faec3..571148f2ff33 100644
--- a/srcpkgs/gstreamer1/template
+++ b/srcpkgs/gstreamer1/template
@@ -1,6 +1,6 @@
# Template file for 'gstreamer1'
pkgname=gstreamer1
-version=1.22.1
+version=1.22.2
revision=1
build_style=meson
build_helper="gir"
@@ -16,7 +16,7 @@ maintainer="Orphaned <orphan@voidlinux.org>"
license="LGPL-2.0-or-later"
homepage="https://gstreamer.freedesktop.org"
distfiles="${homepage}/src/gstreamer/gstreamer-${version}.tar.xz"
-checksum=cd3ca759f926763615fdfcea63c9761198c42889bc0615ceec73e22b24fde771
+checksum=b2afe73603921c608ba48969dbb7d743776744bfe5d8059ece241137b7f88e21
pre_check() {
# gst_gstdatetime is known to fail according to LFS
From 3c68132e9334771a540b8534f3bf8fd453f67ff7 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Sun, 30 Apr 2023 20:22:26 -0400
Subject: [PATCH 131/140] gst-plugins-base1: update to 1.22.2
---
srcpkgs/gst-plugins-base1/template | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/srcpkgs/gst-plugins-base1/template b/srcpkgs/gst-plugins-base1/template
index 6d2cad16f985..2f20ea819849 100644
--- a/srcpkgs/gst-plugins-base1/template
+++ b/srcpkgs/gst-plugins-base1/template
@@ -1,6 +1,6 @@
# Template file for 'gst-plugins-base1'
pkgname=gst-plugins-base1
-version=1.22.1
+version=1.22.2
revision=1
build_style=meson
build_helper="gir"
@@ -22,7 +22,7 @@ maintainer="Orphaned <orphan@voidlinux.org>"
license="GPL-2.0-or-later, LGPL-2.0-or-later"
homepage="https://gstreamer.freedesktop.org"
distfiles="${homepage}/src/${pkgname/1/}/${pkgname/1/}-${version}.tar.xz"
-checksum=59bcaeacc5646b8dbdcfa4ef20ca6e818dd234910efb4cee1bbea441a3801c69
+checksum=eb65120c4ee79b7a153c3c1972d5c0158c2151877cc51ec7725bba5749679d49
build_options="cdparanoia gir sndio wayland"
build_options_default="cdparanoia gir wayland"
From 0447b402127d10a7baa60c971a06b18553cda909 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Sun, 30 Apr 2023 20:22:26 -0400
Subject: [PATCH 132/140] gst-plugins-good1: update to 1.22.2
---
srcpkgs/gst-plugins-good1/template | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/srcpkgs/gst-plugins-good1/template b/srcpkgs/gst-plugins-good1/template
index 00baa6732c75..5d0fe1bfe284 100644
--- a/srcpkgs/gst-plugins-good1/template
+++ b/srcpkgs/gst-plugins-good1/template
@@ -1,6 +1,6 @@
# Template file for 'gst-plugins-good1'
pkgname=gst-plugins-good1
-version=1.22.1
+version=1.22.2
revision=1
build_style=meson
configure_args="-Ddv=disabled -Ddv1394=disabled -Dshout2=disabled -Dqt5=enabled
@@ -22,7 +22,7 @@ maintainer="Orphaned <orphan@voidlinux.org>"
license="LGPL-2.1-or-later"
homepage="https://gstreamer.freedesktop.org"
distfiles="${homepage}/src/${pkgname/1/}/${pkgname/1/}-${version}.tar.xz"
-checksum=44f9104654b4fd042aebe90932ab92e7ff7d8460fbc05b23dad87dffe70974cc
+checksum=7c8cc59425f2b232f60ca7d13e56edd615da4f711e73dd01a7cffa46e6bc0cdd
build_options="gtk3 wayland"
build_options_default="gtk3 wayland"
From 02af2e3e649d84a7e11490b4ce2371bacb8f308d Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Sun, 30 Apr 2023 20:22:26 -0400
Subject: [PATCH 133/140] gst-plugins-bad1: update to 1.22.2
---
srcpkgs/gst-plugins-bad1/template | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/srcpkgs/gst-plugins-bad1/template b/srcpkgs/gst-plugins-bad1/template
index 7f272f915ac4..77bf79981c20 100644
--- a/srcpkgs/gst-plugins-bad1/template
+++ b/srcpkgs/gst-plugins-bad1/template
@@ -1,7 +1,7 @@
# Template file for 'gst-plugins-bad1'
pkgname=gst-plugins-bad1
-version=1.22.1
-revision=2
+version=1.22.2
+revision=1
build_helper="gir"
build_style=meson
configure_args="-Dpackage-origin=https://voidlinux.org -Ddoc=disabled
@@ -36,7 +36,7 @@ maintainer="Orphaned <orphan@voidlinux.org>"
license="GPL-2.0-or-later, LGPL-2.1-or-later"
homepage="https://gstreamer.freedesktop.org"
distfiles="${homepage}/src/${pkgname/1/}/${pkgname/1/}-${version}.tar.xz"
-checksum=2f39b6f222d98666f9ff420a00233e336949953a846237c2bfafc8805f509f0e
+checksum=3d8faf1ce3402c8535ce3a8c4e1a6c960e4b5655dbda6b55943db9ac79022d0f
build_options="gir gme wayland"
build_options_default="gir wayland"
From 1067e101a40008f3dcc2958e12826a7bb7ef4782 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Sun, 30 Apr 2023 20:22:26 -0400
Subject: [PATCH 134/140] gst-plugins-ugly1: update to 1.22.2
---
srcpkgs/gst-plugins-ugly1/template | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/srcpkgs/gst-plugins-ugly1/template b/srcpkgs/gst-plugins-ugly1/template
index 5647c012c9fe..85ae64bc7a0a 100644
--- a/srcpkgs/gst-plugins-ugly1/template
+++ b/srcpkgs/gst-plugins-ugly1/template
@@ -1,6 +1,6 @@
# Template file for 'gst-plugins-ugly1'
pkgname=gst-plugins-ugly1
-version=1.22.1
+version=1.22.2
revision=1
build_style=meson
configure_args="-Damrnb=disabled -Damrwbdec=disabled -Dsidplay=disabled"
@@ -15,4 +15,4 @@ maintainer="Orphaned <orphan@voidlinux.org>"
license="LGPL-2.1-or-later"
homepage="https://gstreamer.freedesktop.org"
distfiles="${homepage}/src/${pkgname/1/}/${pkgname/1/}-${version}.tar.xz"
-checksum=4ab3d9e13481bce1ca3c7c4bb1f65dce4f0bb40fb1cac4416e8c06dd648815c2
+checksum=8f30f44db0bd063709bf6fbe55138e3a98af0abcb61c360f35582bbe10e80691
From 4bea475dc6a93f55a479f17fb32ba564083c6a33 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Sun, 30 Apr 2023 20:22:26 -0400
Subject: [PATCH 135/140] gst-omx: update to 1.22.2
---
srcpkgs/gst-omx/template | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/srcpkgs/gst-omx/template b/srcpkgs/gst-omx/template
index 76692c2a13f6..5ad54cc7b9d8 100644
--- a/srcpkgs/gst-omx/template
+++ b/srcpkgs/gst-omx/template
@@ -1,6 +1,6 @@
# Template file for 'gst-omx'
pkgname=gst-omx
-version=1.22.1
+version=1.22.2
revision=1
build_style=meson
configure_args="-Dexamples=disabled -Dtarget=generic"
@@ -11,4 +11,4 @@ maintainer="Orphaned <orphan@voidlinux.org>"
license="LGPL-2.1-only"
homepage="https://gstreamer.freedesktop.org"
distfiles="${homepage}/src/${pkgname}/${pkgname}-${version}.tar.xz"
-checksum=2d37f60cd33e68dcef0bcd09b2dd8a0b2eb3ab6d6ac172dca46f70eb02756687
+checksum=1b0c57f2cc4ddeec5e7f0c436e502f06665c4e93c73261855b94e04fc94337b2
From bc1ad2483f42e78ecd04d7ec5719a00484e769f4 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Sun, 30 Apr 2023 20:22:26 -0400
Subject: [PATCH 136/140] gst-rtsp-server: update to 1.22.2
---
srcpkgs/gst-rtsp-server/template | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/srcpkgs/gst-rtsp-server/template b/srcpkgs/gst-rtsp-server/template
index ded9a69a2e9d..2f0c0c45ff82 100644
--- a/srcpkgs/gst-rtsp-server/template
+++ b/srcpkgs/gst-rtsp-server/template
@@ -1,6 +1,6 @@
# Template file for 'gst-rtsp-server'
pkgname=gst-rtsp-server
-version=1.22.1
+version=1.22.2
revision=1
build_style=meson
hostmakedepends="pkg-config python3"
@@ -11,4 +11,4 @@ maintainer="1is7ac3 <isaac.qa13@gmail.com>"
license="LGPL-2.1-or-later"
homepage="https://gstreamer.freedesktop.org"
distfiles="${homepage}/src/${pkgname}/${pkgname}-${version}.tar.xz"
-checksum=4e0b972608f67d5d8f5363c827cfcf132b0e00877be6f1905358d514249b05a3
+checksum=2be4aecfb88710100ea7115ed0216403e8094344ebf146094271b8d4d73828bf
From 81805936cd502dfdcaefad8fa2440cedb5afb593 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Sun, 30 Apr 2023 20:22:26 -0400
Subject: [PATCH 137/140] gst1-editing-services: update to 1.22.2
---
srcpkgs/gst1-editing-services/template | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/srcpkgs/gst1-editing-services/template b/srcpkgs/gst1-editing-services/template
index f2045ad6043c..102440f7f253 100644
--- a/srcpkgs/gst1-editing-services/template
+++ b/srcpkgs/gst1-editing-services/template
@@ -1,6 +1,6 @@
# Template file for 'gst1-editing-services'
pkgname=gst1-editing-services
-version=1.22.1
+version=1.22.2
revision=1
build_style=meson
build_helper="gir"
@@ -12,7 +12,7 @@ maintainer="Toyam Cox <Vaelatern@gmail.com>"
license="LGPL-2.0-or-later"
homepage="https://gstreamer.freedesktop.org"
distfiles="${homepage}/src/${pkgname/gst1/gst}/${pkgname/gst1/gst}-${version}.tar.xz"
-checksum=0f9e5e08ef80a4b9a0e971c5f032b13c71aa6fef236265c2d615456e15161438
+checksum=453b1464fc3857de269a7cb0ebd966afe02171d97bef672a0b8a0a6d43e0cebf
do_check() {
: # Tests fail in older versions as well
From ffcb63dfd50b81c480c7db576d97968898bc60ac Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Sun, 30 Apr 2023 20:22:26 -0400
Subject: [PATCH 138/140] gst1-python3: update to 1.22.2
---
srcpkgs/gst1-python3/template | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/srcpkgs/gst1-python3/template b/srcpkgs/gst1-python3/template
index 7a8d094ef61f..789e40f036ea 100644
--- a/srcpkgs/gst1-python3/template
+++ b/srcpkgs/gst1-python3/template
@@ -1,6 +1,6 @@
# Template file for 'gst1-python3'
pkgname=gst1-python3
-version=1.22.1
+version=1.22.2
revision=1
build_style=meson
hostmakedepends="pkg-config python3"
@@ -11,4 +11,4 @@ maintainer="Orphaned <orphan@voidlinux.org>"
license="LGPL-2.1-or-later"
homepage="https://gstreamer.freedesktop.org"
distfiles="${homepage}/src/gst-python/gst-python-${version}.tar.xz"
-checksum=96008a441d685a64275a515b893ccad0fea1d560c43acd0763533e17f3a13ebb
+checksum=bef2b3d82ce4be46b775b1bb56305c1003ee01b535a53a82f9fe8924972153ad
From 81fd5645d7ad253c01bc8704beb7bc502ff19bab Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Sun, 30 Apr 2023 20:22:26 -0400
Subject: [PATCH 139/140] gstreamer-vaapi: update to 1.22.2
---
srcpkgs/gstreamer-vaapi/template | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/srcpkgs/gstreamer-vaapi/template b/srcpkgs/gstreamer-vaapi/template
index c100d99e9af1..0a5ee8b1ca3f 100644
--- a/srcpkgs/gstreamer-vaapi/template
+++ b/srcpkgs/gstreamer-vaapi/template
@@ -1,6 +1,6 @@
# Template file for 'gstreamer-vaapi'
pkgname=gstreamer-vaapi
-version=1.22.1
+version=1.22.2
revision=1
build_style=meson
hostmakedepends="pkg-config"
@@ -11,7 +11,7 @@ license="LGPL-2.1-or-later"
homepage="https://gstreamer.freedesktop.org"
changelog="https://raw.githubusercontent.com/GStreamer/gstreamer-vaapi/master/ChangeLog"
distfiles="${homepage}/src/gstreamer-vaapi/gstreamer-vaapi-${version}.tar.xz"
-checksum=423b57db7fc5f9137dadf17cb3853a47438d63cd4ba6889a882e63fb5be997bc
+checksum=d2e642f9745f97d9f73a7f5085e7659a9a31fe209b774e6e45dae041b435df06
pre_check() {
# Seems to need certain hardware to pass
From 1a380ed32a8c3fe5d508cc6a4af5f72f9e965b8c Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Sun, 30 Apr 2023 20:22:26 -0400
Subject: [PATCH 140/140] gst-libav: update to 1.22.2
---
srcpkgs/gst-libav/template | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/srcpkgs/gst-libav/template b/srcpkgs/gst-libav/template
index a2c97bfbcdb9..8c72fc3e97ee 100644
--- a/srcpkgs/gst-libav/template
+++ b/srcpkgs/gst-libav/template
@@ -1,6 +1,6 @@
# Template file for 'gst-libav'
pkgname=gst-libav
-version=1.22.1
+version=1.22.2
revision=1
build_style=meson
hostmakedepends="pkg-config yasm"
@@ -11,7 +11,7 @@ maintainer="Orphaned <orphan@voidlinux.org>"
license="LGPL-2.0-or-later"
homepage="https://gstreamer.freedesktop.org"
distfiles="${homepage}/src/${pkgname}/${pkgname}-${version}.tar.xz"
-checksum=c958e825dc3ac3b7a481f8db5268131a1cd701312385c2d803dc63c8e460b5fb
+checksum=fcaaf9878fe8f3bc82317ef13a1558824cb68df1f8968c6797f556c5e33bcffd
case "$XBPS_TARGET_MACHINE" in
*-musl) # Required by musl for M_SQRT1_2
^ permalink raw reply [flat|nested] 175+ messages in thread
* Re: [PR PATCH] [Updated] ffmpeg6 split
2023-05-05 13:20 [PR PATCH] ffmpeg6 split zlice
@ 2023-05-05 13:27 ` zlice
2023-05-05 13:53 ` zlice
` (172 subsequent siblings)
173 siblings, 0 replies; 175+ messages in thread
From: zlice @ 2023-05-05 13:27 UTC (permalink / raw)
To: ml
[-- Attachment #1: Type: text/plain, Size: 2799 bytes --]
There is an updated pull request by zlice against master on the void-packages repository
https://github.com/zlice/void-packages ffmpeg6-split
https://github.com/void-linux/void-packages/pull/43761
ffmpeg6 split
[ci skip]
#### Testing the changes
- I tested the changes in this PR: **YES**
main testing has been vaapi in Firefox Nightly and enc/dec in Shotcut on Intel A770
#### New package
- This new package conforms to the [package requirements](https://github.com/void-linux/void-packages/blob/master/CONTRIBUTING.md#package-requirements): **YES**
#### Local build testing
- I built this PR locally for my native architecture, **x86_64**
#### Discussion
Continuation of https://github.com/void-linux/void-packages/pull/36315
`libavresample` is deprecated, but marked as a dependency when trying to build other packages and install `ffmpeg`(5). I think the right way to handle this is make a meta package and the add to removals?
##### Commit naming / misc
Commits are 'dirty' right now, running with [gstreamer 1.22.1 updates](https://github.com/void-linux/void-packages/pull/42861) and [Intel OpenCL](https://github.com/void-linux/void-packages/pull/43084). This will also make [intel packages pr](https://github.com/void-linux/void-packages/pull/41132) obsolete.
Maintainer for previous ffmpeg(4) was orphaned, I can put my name in there if that matters, though I don't exactly see myself keeping up on ffmpeg.
This updates QT5 which looks like it is usually hosted by Johnny. Not sure if there's any reason to stay there or these sources are fine.
##### STILL FFMPEG4
These are a mix of emulators, games and/or older packages.
- attract (multiple patches in master)
- audacity (3.2.x should work but void is missing some libs? vst3sdk?)
- ccextractor (master patches? no release)
- vice
- kodi
- mlt
- synfig (mlt)
- tvheadend
- ssr
- spek-alternative
- ppsspp
- olive
- moc
- mediastreamer
- libextractor
- idjc
- hedgewars
- ffmpegthumbnailer
- ffmpegthumbs
- deadbeef
- omxplayer
- qtav (fork has ffmpeg 5 patch - https://github.com/cmguo/QtAV)
- `vlc` (vlc4 will support ffmpeg5, there's a patch to build 3.x with ffmpeg5 but it will lack vaapi)
- `osg` (OpenSceneGraph plus `xine-lib`)
- `ytmdl` ? not sure but it uses `python3-ffmpeg-python` which being 6-8yr old I imagine is ffmpeg4
##### HAVE NOT BUILT YET
- omxplayer (rpi only?)
- kodi (big, but ffmpeg4)
##### UPDATED (for ffmpeg5)
- unpaper: update to 7.0.0.
- guvcview: update to 2.0.8.
- qt5: update to 5.15.8
- qt5-webengine: update to 5.18.13
- shiboken2: revbump for qt5.15.8 (patch)
- python3-pyside2: update to 5.15.8 (patch)
A patch file from https://github.com/void-linux/void-packages/pull/43761.patch is attached
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: github-pr-ffmpeg6-split-43761.patch --]
[-- Type: text/x-diff, Size: 822699 bytes --]
From 6d537689f78de1b6595fed56dcb67c7a180b5fbf Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 19:55:46 -0400
Subject: [PATCH 001/140] ffmpeg: update to 6.0.
---
common/shlibs | 26 +++++---
srcpkgs/ffmpeg/files/altivec.patch | 60 -------------------
.../patches/armv5tel-floating-point.patch | 18 ------
.../workaround-mesa-readeon-vaapi-bug.patch | 28 ---------
srcpkgs/ffmpeg/template | 31 +++++-----
5 files changed, 33 insertions(+), 130 deletions(-)
delete mode 100644 srcpkgs/ffmpeg/files/altivec.patch
delete mode 100644 srcpkgs/ffmpeg/patches/armv5tel-floating-point.patch
delete mode 100644 srcpkgs/ffmpeg/patches/workaround-mesa-readeon-vaapi-bug.patch
diff --git a/common/shlibs b/common/shlibs
index 8c47e79b8c43..d650f2a3045d 100644
--- a/common/shlibs
+++ b/common/shlibs
@@ -390,15 +390,23 @@ libid3tag.so.0 libid3tag-0.15.1b_1
libgif.so.7 giflib-5.1.0_1
libImlib2.so.1 imlib2-1.4.2_1
libmp3lame.so.0 lame-3.98.2_1
-libavdevice.so.58 libavdevice-4.0_1
-libavformat.so.58 libavformat-4.0_1
-libswscale.so.5 libswscale-4.0_1
-libswresample.so.3 libswresample-4.0_1
-libavresample.so.4 libavresample-4.0_1
-libpostproc.so.55 libpostproc-4.0_1
-libavcodec.so.58 libavcodec-4.0_1
-libavutil.so.56 libavutil-4.0_1
-libavfilter.so.7 libavfilter-4.0_1
+libavdevice.so.60 libavdevice-6.0_1
+libavformat.so.60 libavformat-6.0_1
+libswscale.so.7 libswscale-6.0_1
+libswresample.so.4 libswresample-6.0_1
+libpostproc.so.57 libpostproc-6.0_1
+libavcodec.so.60 libavcodec-6.0_1
+libavutil.so.58 libavutil-6.0_1
+libavfilter.so.9 libavfilter-6.0_1
+libavdevice.so.58 libavdevice4-4.0_1
+libavformat.so.58 libavformat4-4.0_1
+libswscale.so.5 libswscale4-4.0_1
+libswresample.so.3 libswresample4-4.0_1
+libavresample.so.4 libavresample4-4.0_1
+libpostproc.so.55 libpostproc4-4.0_1
+libavcodec.so.58 libavcodec4-4.0_1
+libavutil.so.56 libavutil4-4.0_1
+libavfilter.so.7 libavfilter4-4.0_1
libSDL-1.2.so.0 SDL-1.2.14_1
libSDL_image-1.2.so.0 SDL_image-1.2.10_1
libx264.so.157 x264-20190507.2245_1
diff --git a/srcpkgs/ffmpeg/files/altivec.patch b/srcpkgs/ffmpeg/files/altivec.patch
deleted file mode 100644
index 9c5720046332..000000000000
--- a/srcpkgs/ffmpeg/files/altivec.patch
+++ /dev/null
@@ -1,60 +0,0 @@
-revert some altivec specific change on all ppc* except ppc64le*
-
-q66: "We should also throw in a revert of FFmpeg/FFmpeg@3a557c5 but only
-conditionally, for ppc* but not ppc64le* (the new code is valid for
-POWER8 VSX which LE targets as a baseline but not BE)"
-
-
-This reverts commit 3a557c5d88b7b15b5954ba2743febb055549b536.
----
- libswscale/ppc/yuv2rgb_altivec.c | 24 ++++++++++++++++++++----
- 1 file changed, 20 insertions(+), 4 deletions(-)
-
-diff --git a/libswscale/ppc/yuv2rgb_altivec.c b/libswscale/ppc/yuv2rgb_altivec.c
-index 536545293d..c1e2852adb 100644
---- a/libswscale/ppc/yuv2rgb_altivec.c
-+++ b/libswscale/ppc/yuv2rgb_altivec.c
-@@ -305,6 +305,9 @@ static int altivec_ ## name(SwsContext *c, const unsigned char **in, \
- vector signed short R1, G1, B1; \
- vector unsigned char R, G, B; \
- \
-+ const vector unsigned char *y1ivP, *y2ivP, *uivP, *vivP; \
-+ vector unsigned char align_perm; \
-+ \
- vector signed short lCY = c->CY; \
- vector signed short lOY = c->OY; \
- vector signed short lCRV = c->CRV; \
-@@ -335,13 +338,26 @@ static int altivec_ ## name(SwsContext *c, const unsigned char **in, \
- vec_dstst(oute, (0x02000002 | (((w * 3 + 32) / 32) << 16)), 1); \
- \
- for (j = 0; j < w / 16; j++) { \
-- y0 = vec_xl(0, y1i); \
-+ y1ivP = (const vector unsigned char *) y1i; \
-+ y2ivP = (const vector unsigned char *) y2i; \
-+ uivP = (const vector unsigned char *) ui; \
-+ vivP = (const vector unsigned char *) vi; \
-+ \
-+ align_perm = vec_lvsl(0, y1i); \
-+ y0 = (vector unsigned char) \
-+ vec_perm(y1ivP[0], y1ivP[1], align_perm); \
- \
-- y1 = vec_xl(0, y2i); \
-+ align_perm = vec_lvsl(0, y2i); \
-+ y1 = (vector unsigned char) \
-+ vec_perm(y2ivP[0], y2ivP[1], align_perm); \
- \
-- u = (vector signed char) vec_xl(0, ui); \
-+ align_perm = vec_lvsl(0, ui); \
-+ u = (vector signed char) \
-+ vec_perm(uivP[0], uivP[1], align_perm); \
- \
-- v = (vector signed char) vec_xl(0, vi); \
-+ align_perm = vec_lvsl(0, vi); \
-+ v = (vector signed char) \
-+ vec_perm(vivP[0], vivP[1], align_perm); \
- \
- u = (vector signed char) \
- vec_sub(u, \
---
-2.27.0
-
diff --git a/srcpkgs/ffmpeg/patches/armv5tel-floating-point.patch b/srcpkgs/ffmpeg/patches/armv5tel-floating-point.patch
deleted file mode 100644
index 9a55178c74f0..000000000000
--- a/srcpkgs/ffmpeg/patches/armv5tel-floating-point.patch
+++ /dev/null
@@ -1,18 +0,0 @@
---- a/libavfilter/vf_drawtext.c 2017-10-26 21:03:03.000000000 +0200
-+++ b/libavfilter/vf_drawtext.c 2017-11-21 11:06:49.602284422 +0100
-@@ -39,6 +39,15 @@
- #endif
- #include <fenv.h>
-
-+#if (FE_ALL_EXCEPT == 0)
-+/* E.g. ARM soft float does not define these */
-+#define FE_INVALID 0
-+#define FE_DIVBYZERO 0
-+#define FE_OVERFLOW 0
-+#define FE_UNDERFLOW 0
-+#define FE_INEXACT 0
-+#endif
-+
- #if CONFIG_LIBFONTCONFIG
- #include <fontconfig/fontconfig.h>
- #endif
diff --git a/srcpkgs/ffmpeg/patches/workaround-mesa-readeon-vaapi-bug.patch b/srcpkgs/ffmpeg/patches/workaround-mesa-readeon-vaapi-bug.patch
deleted file mode 100644
index 00e3f68a415b..000000000000
--- a/srcpkgs/ffmpeg/patches/workaround-mesa-readeon-vaapi-bug.patch
+++ /dev/null
@@ -1,28 +0,0 @@
-From 811d290844206fc73dc39c3e5b67d5d895baedf8 Mon Sep 17 00:00:00 2001
-From: Rainer Hochecker <fernetmenta@online.de>
-Date: Sat, 26 Jan 2019 19:48:35 +0100
-Subject: [PATCH] avcodec/vaapi_h264: skip decode if pic has no slices
-
-This fixes / workarounds https://bugs.freedesktop.org/show_bug.cgi?id=105368.
-It was hit frequently when watching h264 channels received via DVB-X.
-Corresponding kodi bug: https://github.com/xbmc/xbmc/issues/15704
----
- libavcodec/vaapi_h264.c | 5 +++++
- 1 file changed, 5 insertions(+)
-
-diff --git a/libavcodec/vaapi_h264.c b/libavcodec/vaapi_h264.c
-index 5854587a255..f12fdc457a4 100644
---- a/libavcodec/vaapi_h264.c
-+++ b/libavcodec/vaapi_h264.c
-@@ -317,6 +317,11 @@ static int vaapi_h264_end_frame(AVCodecContext *avctx)
- H264SliceContext *sl = &h->slice_ctx[0];
- int ret;
-
-+ if (pic->nb_slices == 0) {
-+ ret = AVERROR_INVALIDDATA;
-+ goto finish;
-+ }
-+
- ret = ff_vaapi_decode_issue(avctx, pic);
- if (ret < 0)
- goto finish;
diff --git a/srcpkgs/ffmpeg/template b/srcpkgs/ffmpeg/template
index 23a3d5c9967b..3d99e5173697 100644
--- a/srcpkgs/ffmpeg/template
+++ b/srcpkgs/ffmpeg/template
@@ -1,15 +1,15 @@
# Template file for 'ffmpeg'
# audacity also needs to be bumped when a new ffmpeg version bumps libavformat's soname!
pkgname=ffmpeg
-version=4.4.3
-revision=2
+version=6.0
+revision=1
short_desc="Decoding, encoding and streaming software"
maintainer="Orphaned <orphan@voidlinux.org>"
license="GPL-3.0-or-later"
homepage="https://www.ffmpeg.org"
changelog="https://raw.githubusercontent.com/FFmpeg/FFmpeg/master/Changelog"
distfiles="https://www.ffmpeg.org/releases/ffmpeg-${version}.tar.xz"
-checksum=6c5b6c195e61534766a0b5fe16acc919170c883362612816d0a1c7f4f947006e
+checksum=57be87c22d9b49c112b6d24bc67d42508660e6b718b3db89c44e47e289137082
hostmakedepends="pkg-config perl yasm"
makedepends="zlib-devel bzip2-devel freetype-devel alsa-lib-devel libXfixes-devel
@@ -26,12 +26,13 @@ makedepends="zlib-devel bzip2-devel freetype-devel alsa-lib-devel libXfixes-deve
$(vopt_if webp libwebp-devel) $(vopt_if sofa libmysofa-devel)
$(vopt_if drm libdrm-devel) $(vopt_if svtav1 libsvt-av1-devel)
$(vopt_if srt srt-devel) $(vopt_if rist librist-devel)
- $(vopt_if vulkan 'vulkan-loader Vulkan-Headers')
+ $(vopt_if vulkan 'vulkan-loader Vulkan-Headers Vulkan-Tools Vulkan-ValidationLayers')
+ $(vopt_if onevpl 'onevpl onevpl-devel')
$(vopt_if nvenc nv-codec-headers) $(vopt_if nvdec nv-codec-headers)"
depends="ffplay>=${version}_${revision}"
build_options="x265 v4l2 vaapi vdpau vpx fdk_aac aom nvenc sndio pulseaudio
- dav1d zimg webp sofa vulkan drm svtav1 srt rist nvdec"
+ dav1d zimg webp sofa vulkan drm svtav1 srt rist nvdec onevpl"
build_options_default="x265 v4l2 vpx aom sndio pulseaudio dav1d webp vulkan drm srt rist"
desc_option_srt="Enable support for SRT (Secure, Reliable, Transport)"
desc_option_rist="Enable support for RIST (Reliable Internet Stream Transport)"
@@ -39,7 +40,8 @@ desc_option_sofa="Enable support for AES SOFA"
desc_option_webp="Enable support for WebP"
case "$XBPS_TARGET_MACHINE" in
- i686*|x86_64*) build_options_default+=" vaapi vdpau nvenc nvdec";;
+ i686*) build_options_default+=" vaapi vdpau nvenc nvdec";;
+ x86_64*) build_options_default+=" vaapi vdpau nvenc nvdec onevpl";;
ppc64*) build_options_default+=" vaapi vdpau";;
mips*) CFLAGS="-mnan=legacy";;
esac
@@ -114,18 +116,19 @@ do_configure() {
$(vopt_enable x265 libx265) \
$(vopt_enable v4l2 libv4l2) \
$(vopt_enable aom libaom) $(vopt_enable vaapi) $(vopt_enable vdpau) \
- --enable-libbs2b --enable-avresample --enable-libvidstab \
+ --enable-libbs2b --enable-libvidstab \
$(vopt_enable dav1d libdav1d) \
$(vopt_enable zimg libzimg) \
$(vopt_enable webp libwebp) \
$(vopt_enable sofa libmysofa) \
$(vopt_enable vulkan) \
+ $(vopt_enable onevpl libvpl) \
$(vopt_enable drm libdrm) \
$(vopt_enable svtav1 libsvtav1) \
$(vopt_enable srt libsrt) \
$(vopt_enable rist librist) \
- $(vopt_if nvenc '--enable-nvenc') \
- $(vopt_if nvdec '--enable-nvdec')
+ $(vopt_enable nvenc nvenc) \
+ $(vopt_enable nvdec nvdec)
}
do_build() {
make ${makejobs}
@@ -148,10 +151,8 @@ libavdevice_package() {
}
}
libavresample_package() {
- short_desc="FFmpeg audio resampling library"
- pkg_install() {
- vmove "usr/lib/libavresample.so.*"
- }
+ short_desc="Package deprecated, removal needed"
+ build_style=meta
}
libavformat_package() {
short_desc="FFmpeg file format library"
@@ -198,9 +199,9 @@ ffmpeg-devel_package() {
libavfilter>=${version}_${revision}
libpostproc>=${version}_${revision}
libswscale>=${version}_${revision}
- libswresample>=${version}_${revision}
- libavresample>=${version}_${revision}"
+ libswresample>=${version}_${revision}"
short_desc+=" - development files"
+ conflicts="ffmpeg4-devel"
pkg_install() {
vmove usr/include
vmove usr/lib/pkgconfig
From 6f50791cd4cb463c5967e0c1431b987e1146b800 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 19:56:22 -0400
Subject: [PATCH 002/140] New package: ffmpeg4-4.4.3.
---
srcpkgs/ffmpeg4-devel | 1 +
srcpkgs/ffmpeg4/files/altivec.patch | 60 +++++
.../patches/armv5tel-floating-point.patch | 18 ++
.../workaround-mesa-readeon-vaapi-bug.patch | 28 +++
srcpkgs/ffmpeg4/template | 214 ++++++++++++++++++
srcpkgs/libavcodec4 | 1 +
srcpkgs/libavdevice4 | 1 +
srcpkgs/libavfilter4 | 1 +
srcpkgs/libavformat4 | 1 +
srcpkgs/libavresample4 | 1 +
srcpkgs/libavutil4 | 1 +
srcpkgs/libpostproc4 | 1 +
srcpkgs/libswresample4 | 1 +
srcpkgs/libswscale4 | 1 +
14 files changed, 330 insertions(+)
create mode 120000 srcpkgs/ffmpeg4-devel
create mode 100644 srcpkgs/ffmpeg4/files/altivec.patch
create mode 100644 srcpkgs/ffmpeg4/patches/armv5tel-floating-point.patch
create mode 100644 srcpkgs/ffmpeg4/patches/workaround-mesa-readeon-vaapi-bug.patch
create mode 100644 srcpkgs/ffmpeg4/template
create mode 120000 srcpkgs/libavcodec4
create mode 120000 srcpkgs/libavdevice4
create mode 120000 srcpkgs/libavfilter4
create mode 120000 srcpkgs/libavformat4
create mode 120000 srcpkgs/libavresample4
create mode 120000 srcpkgs/libavutil4
create mode 120000 srcpkgs/libpostproc4
create mode 120000 srcpkgs/libswresample4
create mode 120000 srcpkgs/libswscale4
diff --git a/srcpkgs/ffmpeg4-devel b/srcpkgs/ffmpeg4-devel
new file mode 120000
index 000000000000..887f354e7c6b
--- /dev/null
+++ b/srcpkgs/ffmpeg4-devel
@@ -0,0 +1 @@
+ffmpeg4
\ No newline at end of file
diff --git a/srcpkgs/ffmpeg4/files/altivec.patch b/srcpkgs/ffmpeg4/files/altivec.patch
new file mode 100644
index 000000000000..9c5720046332
--- /dev/null
+++ b/srcpkgs/ffmpeg4/files/altivec.patch
@@ -0,0 +1,60 @@
+revert some altivec specific change on all ppc* except ppc64le*
+
+q66: "We should also throw in a revert of FFmpeg/FFmpeg@3a557c5 but only
+conditionally, for ppc* but not ppc64le* (the new code is valid for
+POWER8 VSX which LE targets as a baseline but not BE)"
+
+
+This reverts commit 3a557c5d88b7b15b5954ba2743febb055549b536.
+---
+ libswscale/ppc/yuv2rgb_altivec.c | 24 ++++++++++++++++++++----
+ 1 file changed, 20 insertions(+), 4 deletions(-)
+
+diff --git a/libswscale/ppc/yuv2rgb_altivec.c b/libswscale/ppc/yuv2rgb_altivec.c
+index 536545293d..c1e2852adb 100644
+--- a/libswscale/ppc/yuv2rgb_altivec.c
++++ b/libswscale/ppc/yuv2rgb_altivec.c
+@@ -305,6 +305,9 @@ static int altivec_ ## name(SwsContext *c, const unsigned char **in, \
+ vector signed short R1, G1, B1; \
+ vector unsigned char R, G, B; \
+ \
++ const vector unsigned char *y1ivP, *y2ivP, *uivP, *vivP; \
++ vector unsigned char align_perm; \
++ \
+ vector signed short lCY = c->CY; \
+ vector signed short lOY = c->OY; \
+ vector signed short lCRV = c->CRV; \
+@@ -335,13 +338,26 @@ static int altivec_ ## name(SwsContext *c, const unsigned char **in, \
+ vec_dstst(oute, (0x02000002 | (((w * 3 + 32) / 32) << 16)), 1); \
+ \
+ for (j = 0; j < w / 16; j++) { \
+- y0 = vec_xl(0, y1i); \
++ y1ivP = (const vector unsigned char *) y1i; \
++ y2ivP = (const vector unsigned char *) y2i; \
++ uivP = (const vector unsigned char *) ui; \
++ vivP = (const vector unsigned char *) vi; \
++ \
++ align_perm = vec_lvsl(0, y1i); \
++ y0 = (vector unsigned char) \
++ vec_perm(y1ivP[0], y1ivP[1], align_perm); \
+ \
+- y1 = vec_xl(0, y2i); \
++ align_perm = vec_lvsl(0, y2i); \
++ y1 = (vector unsigned char) \
++ vec_perm(y2ivP[0], y2ivP[1], align_perm); \
+ \
+- u = (vector signed char) vec_xl(0, ui); \
++ align_perm = vec_lvsl(0, ui); \
++ u = (vector signed char) \
++ vec_perm(uivP[0], uivP[1], align_perm); \
+ \
+- v = (vector signed char) vec_xl(0, vi); \
++ align_perm = vec_lvsl(0, vi); \
++ v = (vector signed char) \
++ vec_perm(vivP[0], vivP[1], align_perm); \
+ \
+ u = (vector signed char) \
+ vec_sub(u, \
+--
+2.27.0
+
diff --git a/srcpkgs/ffmpeg4/patches/armv5tel-floating-point.patch b/srcpkgs/ffmpeg4/patches/armv5tel-floating-point.patch
new file mode 100644
index 000000000000..9a55178c74f0
--- /dev/null
+++ b/srcpkgs/ffmpeg4/patches/armv5tel-floating-point.patch
@@ -0,0 +1,18 @@
+--- a/libavfilter/vf_drawtext.c 2017-10-26 21:03:03.000000000 +0200
++++ b/libavfilter/vf_drawtext.c 2017-11-21 11:06:49.602284422 +0100
+@@ -39,6 +39,15 @@
+ #endif
+ #include <fenv.h>
+
++#if (FE_ALL_EXCEPT == 0)
++/* E.g. ARM soft float does not define these */
++#define FE_INVALID 0
++#define FE_DIVBYZERO 0
++#define FE_OVERFLOW 0
++#define FE_UNDERFLOW 0
++#define FE_INEXACT 0
++#endif
++
+ #if CONFIG_LIBFONTCONFIG
+ #include <fontconfig/fontconfig.h>
+ #endif
diff --git a/srcpkgs/ffmpeg4/patches/workaround-mesa-readeon-vaapi-bug.patch b/srcpkgs/ffmpeg4/patches/workaround-mesa-readeon-vaapi-bug.patch
new file mode 100644
index 000000000000..00e3f68a415b
--- /dev/null
+++ b/srcpkgs/ffmpeg4/patches/workaround-mesa-readeon-vaapi-bug.patch
@@ -0,0 +1,28 @@
+From 811d290844206fc73dc39c3e5b67d5d895baedf8 Mon Sep 17 00:00:00 2001
+From: Rainer Hochecker <fernetmenta@online.de>
+Date: Sat, 26 Jan 2019 19:48:35 +0100
+Subject: [PATCH] avcodec/vaapi_h264: skip decode if pic has no slices
+
+This fixes / workarounds https://bugs.freedesktop.org/show_bug.cgi?id=105368.
+It was hit frequently when watching h264 channels received via DVB-X.
+Corresponding kodi bug: https://github.com/xbmc/xbmc/issues/15704
+---
+ libavcodec/vaapi_h264.c | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+diff --git a/libavcodec/vaapi_h264.c b/libavcodec/vaapi_h264.c
+index 5854587a255..f12fdc457a4 100644
+--- a/libavcodec/vaapi_h264.c
++++ b/libavcodec/vaapi_h264.c
+@@ -317,6 +317,11 @@ static int vaapi_h264_end_frame(AVCodecContext *avctx)
+ H264SliceContext *sl = &h->slice_ctx[0];
+ int ret;
+
++ if (pic->nb_slices == 0) {
++ ret = AVERROR_INVALIDDATA;
++ goto finish;
++ }
++
+ ret = ff_vaapi_decode_issue(avctx, pic);
+ if (ret < 0)
+ goto finish;
diff --git a/srcpkgs/ffmpeg4/template b/srcpkgs/ffmpeg4/template
new file mode 100644
index 000000000000..7bc64bb39f41
--- /dev/null
+++ b/srcpkgs/ffmpeg4/template
@@ -0,0 +1,214 @@
+# Template file for 'ffmpeg4'
+# audacity also needs to be bumped when a new ffmpeg version bumps libavformat's soname!
+pkgname=ffmpeg4
+version=4.4.3
+revision=1
+short_desc="Decoding, encoding and streaming software - ffmpeg4 libraries only"
+maintainer="Orphaned <orphan@voidlinux.org>"
+license="GPL-3.0-or-later"
+homepage="https://www.ffmpeg.org"
+changelog="https://raw.githubusercontent.com/FFmpeg/FFmpeg/master/Changelog"
+distfiles="https://www.ffmpeg.org/releases/ffmpeg-${version}.tar.xz"
+checksum=6c5b6c195e61534766a0b5fe16acc919170c883362612816d0a1c7f4f947006e
+
+hostmakedepends="pkg-config perl yasm"
+makedepends="zlib-devel bzip2-devel freetype-devel alsa-lib-devel libXfixes-devel
+ libXext-devel libXvMC-devel libxcb-devel lame-devel libtheora-devel
+ libvorbis-devel x264-devel xvidcore-devel jack-devel SDL2-devel
+ libcdio-paranoia-devel librtmp-devel libmodplug-devel gnutls-devel
+ speex-devel celt-devel harfbuzz-devel libass-devel opus-devel ocl-icd-devel
+ libbs2b-devel libvidstab-devel $(vopt_if pulseaudio pulseaudio-devel)
+ $(vopt_if vaapi libva-devel) $(vopt_if vdpau libvdpau-devel)
+ $(vopt_if x265 x265-devel) $(vopt_if v4l2 v4l-utils-devel)
+ $(vopt_if fdk_aac fdk-aac-devel) $(vopt_if vpx libvpx-devel)
+ $(vopt_if aom libaom-devel) $(vopt_if sndio sndio-devel)
+ $(vopt_if dav1d libdav1d-devel) $(vopt_if zimg zimg-devel)
+ $(vopt_if webp libwebp-devel) $(vopt_if sofa libmysofa-devel)
+ $(vopt_if drm libdrm-devel) $(vopt_if svtav1 libsvt-av1-devel)
+ $(vopt_if srt srt-devel) $(vopt_if rist librist-devel)
+ $(vopt_if vulkan 'vulkan-loader Vulkan-Headers')
+ $(vopt_if nvenc nv-codec-headers) $(vopt_if nvdec nv-codec-headers)"
+
+build_options="x265 v4l2 vaapi vdpau vpx fdk_aac aom nvenc sndio pulseaudio
+ dav1d zimg webp sofa vulkan drm svtav1 srt rist nvdec"
+build_options_default="x265 v4l2 vpx aom sndio pulseaudio dav1d webp vulkan drm srt rist"
+
+desc_option_srt="Enable support for SRT (Secure, Reliable, Transport)"
+desc_option_rist="Enable support for RIST (Reliable Internet Stream Transport)"
+desc_option_sofa="Enable support for AES SOFA"
+desc_option_webp="Enable support for WebP"
+
+case "$XBPS_TARGET_MACHINE" in
+ i686*|x86_64*) build_options_default+=" vaapi vdpau nvenc nvdec";;
+ ppc64*) build_options_default+=" vaapi vdpau";;
+ mips*) CFLAGS="-mnan=legacy";;
+esac
+
+if [ "$XBPS_TARGET_WORDSIZE" != "32" ]; then
+ build_options_default+=" svtav1"
+fi
+
+if [ "$XBPS_TARGET_NO_ATOMIC8" ]; then
+ makedepends+=" libatomic-devel"
+fi
+
+_apply_patch() {
+ local args="$1" pname="$(basename $2)"
+
+ if [ ! -f ".${pname}_done" ]; then
+ patch -N $args -i $2
+ touch .${pname}_done
+ fi
+}
+
+post_patch() {
+ case "$XBPS_TARGET_MACHINE" in
+ ppc64le*) ;;
+ ppc*) _apply_patch -p1 ${FILESDIR}/altivec.patch ;;
+ esac
+}
+
+do_configure() {
+ # Fix gcc on x86_64-musl only
+ if [ "$XBPS_TARGET_MACHINE" = "x86_64-musl" ]; then
+ sed -i configure -e "s;_cflags_speed='-O3';_cflags_speed='-O2';"
+ fi
+
+ if [ "$CROSS_BUILD" ]; then
+ case "$XBPS_TARGET_MACHINE" in
+ arm*) _arch="arm";;
+ aarch64*) _arch="aarch64";;
+ mips*) _arch="mips";;
+ ppc64*) _arch="ppc64";;
+ ppc*) _arch="ppc";;
+ *) _arch="${XBPS_TARGET_MACHINE%%-musl}";;
+ esac
+
+ _args+=" --enable-cross-compile
+ --sysroot=$XBPS_CROSS_BASE
+ --cross-prefix=${XBPS_CROSS_TRIPLET}-
+ --target-os=linux --arch=${_arch}"
+ fi
+
+ case "$XBPS_TARGET_MACHINE" in
+ ppc|ppc-musl) _args+=" --disable-altivec";;
+ esac
+
+ if [ "$XBPS_TARGET_NO_ATOMIC8" ]; then
+ _args+=" --extra-libs=-latomic"
+ fi
+
+ ./configure --prefix=/usr --disable-debug --enable-gpl --enable-gnutls \
+ --disable-stripping \
+ --enable-libcdio --enable-version3 --enable-runtime-cpudetect \
+ --enable-libmp3lame --enable-libvorbis --enable-libxvid \
+ --enable-libx264 $(vopt_enable vpx libvpx) --enable-libtheora \
+ --enable-shared --enable-static --enable-libxcb \
+ $(vopt_enable pulseaudio libpulse) --enable-libfreetype --enable-libmodplug \
+ --enable-libspeex --enable-libcelt --enable-libass \
+ --enable-libopus --enable-librtmp --enable-libjack \
+ $(vopt_if fdk_aac '--enable-nonfree --enable-libfdk-aac') \
+ --disable-libopencore_amrnb --disable-libopencore_amrwb \
+ --disable-libopenjpeg \
+ --enable-postproc --enable-opencl ${_args} \
+ $(vopt_enable x265 libx265) \
+ $(vopt_enable v4l2 libv4l2) \
+ $(vopt_enable aom libaom) $(vopt_enable vaapi) $(vopt_enable vdpau) \
+ --enable-libbs2b --enable-avresample --enable-libvidstab \
+ $(vopt_enable dav1d libdav1d) \
+ $(vopt_enable zimg libzimg) \
+ $(vopt_enable webp libwebp) \
+ $(vopt_enable sofa libmysofa) \
+ $(vopt_enable vulkan) \
+ $(vopt_enable drm libdrm) \
+ $(vopt_enable svtav1 libsvtav1) \
+ $(vopt_enable srt libsrt) \
+ $(vopt_enable rist librist) \
+ $(vopt_if nvenc '--enable-nvenc') \
+ $(vopt_if nvdec '--enable-nvdec')
+}
+do_build() {
+ make ${makejobs}
+ make doc/ff{mpeg,play}.1
+}
+do_install() {
+ make DESTDIR=${DESTDIR} install install-man
+ rm -rf ${DESTDIR}/usr/bin
+}
+
+libavcodec4_package() {
+ short_desc="FFmpeg codec library"
+ pkg_install() {
+ vmove "usr/lib/libavcodec.so.*"
+ }
+}
+libavdevice4_package() {
+ short_desc="FFmpeg device handling library"
+ pkg_install() {
+ vmove "usr/lib/libavdevice.so.*"
+ }
+}
+libavresample4_package() {
+ short_desc="FFmpeg audio resampling library"
+ pkg_install() {
+ vmove "usr/lib/libavresample.so.*"
+ }
+}
+libavformat4_package() {
+ short_desc="FFmpeg file format library"
+ pkg_install() {
+ vmove "usr/lib/libavformat.so.*"
+ }
+}
+libavutil4_package() {
+ short_desc="FFmpeg utility library"
+ pkg_install() {
+ vmove "usr/lib/libavutil.so.*"
+ }
+}
+libavfilter4_package() {
+ short_desc="FFmpeg audio/video filter library"
+ pkg_install() {
+ vmove "usr/lib/libavfilter.so.*"
+ }
+}
+libpostproc4_package() {
+ short_desc="FFmpeg video postprocessing library"
+ pkg_install() {
+ vmove "usr/lib/libpostproc.so.*"
+ }
+}
+libswscale4_package() {
+ short_desc="FFmpeg video scaling library"
+ pkg_install() {
+ vmove "usr/lib/libswscale.so.*"
+ }
+}
+libswresample4_package() {
+ short_desc="FFmpeg video resampling library"
+ pkg_install() {
+ vmove "usr/lib/libswresample.so.*"
+ }
+}
+ffmpeg4-devel_package() {
+ depends="
+ libavcodec4>=${version}_${revision}
+ libavdevice4>=${version}_${revision}
+ libavformat4>=${version}_${revision}
+ libavutil4>=${version}_${revision}
+ libavfilter4>=${version}_${revision}
+ libpostproc4>=${version}_${revision}
+ libswscale4>=${version}_${revision}
+ libswresample4>=${version}_${revision}
+ libavresample4>=${version}_${revision}"
+ short_desc+=" - development files"
+ conflicts="ffmpeg-devel"
+ pkg_install() {
+ vmove usr/include
+ vmove usr/lib/pkgconfig
+ vmove usr/lib/*.a
+ vmove usr/lib/*.so
+ vmove usr/share/ffmpeg/examples
+ vmove usr/share/man/man3
+ }
+}
diff --git a/srcpkgs/libavcodec4 b/srcpkgs/libavcodec4
new file mode 120000
index 000000000000..887f354e7c6b
--- /dev/null
+++ b/srcpkgs/libavcodec4
@@ -0,0 +1 @@
+ffmpeg4
\ No newline at end of file
diff --git a/srcpkgs/libavdevice4 b/srcpkgs/libavdevice4
new file mode 120000
index 000000000000..887f354e7c6b
--- /dev/null
+++ b/srcpkgs/libavdevice4
@@ -0,0 +1 @@
+ffmpeg4
\ No newline at end of file
diff --git a/srcpkgs/libavfilter4 b/srcpkgs/libavfilter4
new file mode 120000
index 000000000000..887f354e7c6b
--- /dev/null
+++ b/srcpkgs/libavfilter4
@@ -0,0 +1 @@
+ffmpeg4
\ No newline at end of file
diff --git a/srcpkgs/libavformat4 b/srcpkgs/libavformat4
new file mode 120000
index 000000000000..887f354e7c6b
--- /dev/null
+++ b/srcpkgs/libavformat4
@@ -0,0 +1 @@
+ffmpeg4
\ No newline at end of file
diff --git a/srcpkgs/libavresample4 b/srcpkgs/libavresample4
new file mode 120000
index 000000000000..887f354e7c6b
--- /dev/null
+++ b/srcpkgs/libavresample4
@@ -0,0 +1 @@
+ffmpeg4
\ No newline at end of file
diff --git a/srcpkgs/libavutil4 b/srcpkgs/libavutil4
new file mode 120000
index 000000000000..887f354e7c6b
--- /dev/null
+++ b/srcpkgs/libavutil4
@@ -0,0 +1 @@
+ffmpeg4
\ No newline at end of file
diff --git a/srcpkgs/libpostproc4 b/srcpkgs/libpostproc4
new file mode 120000
index 000000000000..887f354e7c6b
--- /dev/null
+++ b/srcpkgs/libpostproc4
@@ -0,0 +1 @@
+ffmpeg4
\ No newline at end of file
diff --git a/srcpkgs/libswresample4 b/srcpkgs/libswresample4
new file mode 120000
index 000000000000..887f354e7c6b
--- /dev/null
+++ b/srcpkgs/libswresample4
@@ -0,0 +1 @@
+ffmpeg4
\ No newline at end of file
diff --git a/srcpkgs/libswscale4 b/srcpkgs/libswscale4
new file mode 120000
index 000000000000..887f354e7c6b
--- /dev/null
+++ b/srcpkgs/libswscale4
@@ -0,0 +1 @@
+ffmpeg4
\ No newline at end of file
From b456cf2f2dcb036c8810093de5929d40df8c7c7d Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 19:59:04 -0400
Subject: [PATCH 003/140] opencv: update to 4.7.0.
---
common/shlibs | 104 ++++++++++++++++++++--------------------
srcpkgs/opencv/template | 8 ++--
2 files changed, 56 insertions(+), 56 deletions(-)
diff --git a/common/shlibs b/common/shlibs
index d650f2a3045d..4626cfda810b 100644
--- a/common/shlibs
+++ b/common/shlibs
@@ -2137,58 +2137,58 @@ libcapstone.so.4 capstone-4.0_1
libhavege.so.2 libhaveged-1.9.11_1
libnih.so.1 libnih-1.0.3_1
libnih-dbus.so.1 libnih-1.0.3_1
-libopencv_quality.so.406 libopencv-4.6.0_1
-libopencv_reg.so.406 libopencv-4.6.0_1
-libopencv_surface_matching.so.406 libopencv-4.6.0_1
-libopencv_xphoto.so.406 libopencv-4.6.0_1
-libopencv_freetype.so.406 libopencv-4.6.0_1
-libopencv_fuzzy.so.406 libopencv-4.6.0_1
-libopencv_hfs.so.406 libopencv-4.6.0_1
-libopencv_img_hash.so.406 libopencv-4.6.0_1
-libopencv_line_descriptor.so.406 libopencv-4.6.0_1
-libopencv_saliency.so.406 libopencv-4.6.0_1
-libopencv_structured_light.so.406 libopencv-4.6.0_1
-libopencv_aruco.so.406 libopencv-4.6.0_1
-libopencv_bgsegm.so.406 libopencv-4.6.0_1
-libopencv_bioinspired.so.406 libopencv-4.6.0_1
-libopencv_ccalib.so.406 libopencv-4.6.0_1
-libopencv_face.so.406 libopencv-4.6.0_1
-libopencv_tracking.so.406 libopencv-4.6.0_1
-libopencv_xfeatures2d.so.406 libopencv-4.6.0_1
-libopencv_optflow.so.406 libopencv-4.6.0_1
-libopencv_ximgproc.so.406 libopencv-4.6.0_1
-libopencv_plot.so.406 libopencv-4.6.0_1
-libopencv_text.so.406 libopencv-4.6.0_1
-libopencv_ml.so.406 libopencv-4.6.0_1
-libopencv_objdetect.so.406 libopencv-4.6.0_1
-libopencv_dnn.so.406 libopencv-4.6.0_1
-libopencv_shape.so.406 libopencv-4.6.0_1
-libopencv_stitching.so.406 libopencv-4.6.0_1
-libopencv_photo.so.406 libopencv-4.6.0_1
-libopencv_video.so.406 libopencv-4.6.0_1
-libopencv_calib3d.so.406 libopencv-4.6.0_1
-libopencv_features2d.so.406 libopencv-4.6.0_1
-libopencv_flann.so.406 libopencv-4.6.0_1
-libopencv_highgui.so.406 libopencv-4.6.0_1
-libopencv_videoio.so.406 libopencv-4.6.0_1
-libopencv_imgcodecs.so.406 libopencv-4.6.0_1
-libopencv_imgproc.so.406 libopencv-4.6.0_1
-libopencv_core.so.406 libopencv-4.6.0_1
-libopencv_superres.so.406 libopencv-4.6.0_1
-libopencv_videostab.so.406 libopencv-4.6.0_1
-libopencv_gapi.so.406 libopencv-4.6.0_1
-libopencv_xobjdetect.so.406 libopencv-4.6.0_1
-libopencv_datasets.so.406 libopencv-4.6.0_1
-libopencv_dnn_objdetect.so.406 libopencv-4.6.0_1
-libopencv_dnn_superres.so.406 libopencv-4.6.0_1
-libopencv_dpm.so.406 libopencv-4.6.0_1
-libopencv_phase_unwrapping.so.406 libopencv-4.6.0_1
-libopencv_stereo.so.406 libopencv-4.6.0_1
-libopencv_rapid.so.406 libopencv-4.6.0_1
-libopencv_intensity_transform.so.406 libopencv-4.6.0_1
-libopencv_alphamat.so.406 libopencv-4.6.0_1
-libopencv_barcode.so.406 libopencv-4.6.0_1
-libopencv_mcc.so.406 libopencv-4.6.0_1
+libopencv_quality.so.407 libopencv-4.7.0_1
+libopencv_reg.so.407 libopencv-4.7.0_1
+libopencv_surface_matching.so.407 libopencv-4.7.0_1
+libopencv_xphoto.so.407 libopencv-4.7.0_1
+libopencv_freetype.so.407 libopencv-4.7.0_1
+libopencv_fuzzy.so.407 libopencv-4.7.0_1
+libopencv_hfs.so.407 libopencv-4.7.0_1
+libopencv_img_hash.so.407 libopencv-4.7.0_1
+libopencv_line_descriptor.so.407 libopencv-4.7.0_1
+libopencv_saliency.so.407 libopencv-4.7.0_1
+libopencv_structured_light.so.407 libopencv-4.7.0_1
+libopencv_aruco.so.407 libopencv-4.7.0_1
+libopencv_bgsegm.so.407 libopencv-4.7.0_1
+libopencv_bioinspired.so.407 libopencv-4.7.0_1
+libopencv_ccalib.so.407 libopencv-4.7.0_1
+libopencv_face.so.407 libopencv-4.7.0_1
+libopencv_tracking.so.407 libopencv-4.7.0_1
+libopencv_xfeatures2d.so.407 libopencv-4.7.0_1
+libopencv_optflow.so.407 libopencv-4.7.0_1
+libopencv_ximgproc.so.407 libopencv-4.7.0_1
+libopencv_plot.so.407 libopencv-4.7.0_1
+libopencv_text.so.407 libopencv-4.7.0_1
+libopencv_ml.so.407 libopencv-4.7.0_1
+libopencv_objdetect.so.407 libopencv-4.7.0_1
+libopencv_dnn.so.407 libopencv-4.7.0_1
+libopencv_shape.so.407 libopencv-4.7.0_1
+libopencv_stitching.so.407 libopencv-4.7.0_1
+libopencv_photo.so.407 libopencv-4.7.0_1
+libopencv_video.so.407 libopencv-4.7.0_1
+libopencv_calib3d.so.407 libopencv-4.7.0_1
+libopencv_features2d.so.407 libopencv-4.7.0_1
+libopencv_flann.so.407 libopencv-4.7.0_1
+libopencv_highgui.so.407 libopencv-4.7.0_1
+libopencv_videoio.so.407 libopencv-4.7.0_1
+libopencv_imgcodecs.so.407 libopencv-4.7.0_1
+libopencv_imgproc.so.407 libopencv-4.7.0_1
+libopencv_core.so.407 libopencv-4.7.0_1
+libopencv_superres.so.407 libopencv-4.7.0_1
+libopencv_videostab.so.407 libopencv-4.7.0_1
+libopencv_gapi.so.407 libopencv-4.7.0_1
+libopencv_xobjdetect.so.407 libopencv-4.7.0_1
+libopencv_datasets.so.407 libopencv-4.7.0_1
+libopencv_dnn_objdetect.so.407 libopencv-4.7.0_1
+libopencv_dnn_superres.so.407 libopencv-4.7.0_1
+libopencv_dpm.so.407 libopencv-4.7.0_1
+libopencv_phase_unwrapping.so.407 libopencv-4.7.0_1
+libopencv_stereo.so.407 libopencv-4.7.0_1
+libopencv_rapid.so.407 libopencv-4.7.0_1
+libopencv_intensity_transform.so.407 libopencv-4.7.0_1
+libopencv_alphamat.so.407 libopencv-4.7.0_1
+libopencv_barcode.so.407 libopencv-4.7.0_1
+libopencv_mcc.so.407 libopencv-4.7.0_1
libuniconf.so.4.6 wvstreams-4.6.1_20
libwvbase.so.4.6 wvstreams-4.6.1_20
libwvutils.so.4.6 wvstreams-4.6.1_20
diff --git a/srcpkgs/opencv/template b/srcpkgs/opencv/template
index 69c635b1ad2b..41f3183f1582 100644
--- a/srcpkgs/opencv/template
+++ b/srcpkgs/opencv/template
@@ -1,7 +1,7 @@
# Template file for 'opencv'
pkgname=opencv
-version=4.6.0
-revision=4
+version=4.7.0
+revision=1
create_wrksrc=yes
build_wrksrc=${pkgname}-${version}
build_style=cmake
@@ -24,8 +24,8 @@ homepage="https://opencv.org"
changelog="https://github.com/opencv/opencv/wiki/ChangeLog"
distfiles="https://github.com/opencv/opencv/archive/${version}.tar.gz
https://github.com/opencv/opencv_contrib/archive/${version}.tar.gz>contrib.tar.gz"
-checksum="1ec1cba65f9f20fe5a41fda1586e01c70ea0c9a6d7b67c9e13edf0cfe2239277
- 1777d5fd2b59029cf537e5fd6f8aa68d707075822f90bde683fcde086f85f7a7"
+checksum="8df0079cdbe179748a18d44731af62a245a45ebf5085223dc03133954c662973
+ 42df840cf9055e59d0e22c249cfb19f04743e1bdad113d31b1573d3934d62584"
patch_args="-Np1 -d ${build_wrksrc}"
# tests hang indenfinitely, even with test data included
make_check=no
From 98ba394049b5ff00dbacf97220c2c2692eafc4b1 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 19:59:45 -0400
Subject: [PATCH 004/140] actiona: revbump for opencv-4.7.0
---
srcpkgs/actiona/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/actiona/template b/srcpkgs/actiona/template
index cf5f0b7a2ae6..0d899311e6df 100644
--- a/srcpkgs/actiona/template
+++ b/srcpkgs/actiona/template
@@ -1,7 +1,7 @@
# Template file for 'actiona'
pkgname=actiona
version=3.10.1
-revision=2
+revision=3
build_style=qmake
configure_args="PKGCONFIG_OPENCV=opencv4"
hostmakedepends="pkg-config qt5-plugin-mysql qt5-qmake qt5-host-tools"
From 032bfac6e8d4086b7fa313de4952eaee56405e9f Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 19:59:45 -0400
Subject: [PATCH 005/140] gmic: revbump for opencv-4.7.0
---
srcpkgs/gmic/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/gmic/template b/srcpkgs/gmic/template
index 24a9c7218fdf..0bb4034d5cc8 100644
--- a/srcpkgs/gmic/template
+++ b/srcpkgs/gmic/template
@@ -1,7 +1,7 @@
# Template file for 'gmic'
pkgname=gmic
version=3.1.6
-revision=3
+revision=4
_zart_hash=34ebf6cce0bafb98abe57cec83c4a02cd1abeca0
create_wrksrc=yes
build_wrksrc="src"
From 325d5177879a203290498024126089d270eb12f0 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 19:59:46 -0400
Subject: [PATCH 006/140] qimgv: revbump for opencv-4.7.0
---
srcpkgs/qimgv/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/qimgv/template b/srcpkgs/qimgv/template
index 7eb30db33992..dd341dfe1bfc 100644
--- a/srcpkgs/qimgv/template
+++ b/srcpkgs/qimgv/template
@@ -1,7 +1,7 @@
# Template file for 'qimgv'
pkgname=qimgv
version=1.0.2
-revision=2
+revision=3
build_style=cmake
configure_args="$(vopt_if video -DVIDEO_SUPPORT=ON -DVIDEO_SUPPORT=OFF)
$(vopt_if scale -DOPENCV_SUPPORT=ON -DOPENCV_SUPPORT=OFF)
From 816c3f26e0a7f0a6e6a9e6d2d862d93d389c87d6 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 19:59:46 -0400
Subject: [PATCH 007/140] retroshare: revbump for opencv-4.7.0
---
srcpkgs/retroshare/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/retroshare/template b/srcpkgs/retroshare/template
index 8a0786c21a08..72023fa98b75 100644
--- a/srcpkgs/retroshare/template
+++ b/srcpkgs/retroshare/template
@@ -1,7 +1,7 @@
# Template file for 'retroshare'
pkgname=retroshare
version=0.6.6
-revision=2
+revision=4
build_style=qmake
#XXX broadcast feature requires an ancient udp-discovery-cpp which either needs
# to be fetched+patched (FTBFS) here or packaged :/
From 199f93854a9ac7bd07d23bbd07cf04a19c4f7272 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 19:59:46 -0400
Subject: [PATCH 008/140] siril: revbump for opencv-4.7.0
---
srcpkgs/siril/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/siril/template b/srcpkgs/siril/template
index e88f30fb6178..84332f79d060 100644
--- a/srcpkgs/siril/template
+++ b/srcpkgs/siril/template
@@ -1,7 +1,7 @@
# Template file for 'siril'
pkgname=siril
version=0.9.12
-revision=9
+revision=10
build_style=gnu-configure
hostmakedepends="pkg-config intltool autoconf automake gettext-devel"
makedepends="fftw-devel libconfig-devel libopencv-devel libffms2-devel
From 674f578a40f767aac1cb8add733a22679a88ab68 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 19:59:46 -0400
Subject: [PATCH 009/140] waifu2x-converter-cpp: revbump for opencv-4.7.0
---
srcpkgs/waifu2x-converter-cpp/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/waifu2x-converter-cpp/template b/srcpkgs/waifu2x-converter-cpp/template
index 8c095d0d7bab..aa52d8c981a8 100644
--- a/srcpkgs/waifu2x-converter-cpp/template
+++ b/srcpkgs/waifu2x-converter-cpp/template
@@ -1,7 +1,7 @@
# Template file for 'waifu2x-converter-cpp'
pkgname=waifu2x-converter-cpp
version=5.2.4
-revision=2
+revision=3
build_style=cmake
configure_args="-DINSTALL_MODELS=ON"
hostmakedepends="pkg-config"
From b50a3d189eef2ddf2fe36600d8b3b20082d90b06 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:00:38 -0400
Subject: [PATCH 010/140] vlc: revbump for ffmpeg4-4.4.3
---
srcpkgs/vlc/template | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/srcpkgs/vlc/template b/srcpkgs/vlc/template
index 210762b0a7e2..855ca5238662 100644
--- a/srcpkgs/vlc/template
+++ b/srcpkgs/vlc/template
@@ -1,7 +1,7 @@
# Template file for 'vlc'
pkgname=vlc
version=3.0.18
-revision=3
+revision=4
build_style=gnu-configure
configure_args="--disable-gme --disable-libtar --enable-jack
--enable-live555 --disable-fluidsynth --enable-dvdread
@@ -25,7 +25,7 @@ lib32disabled=yes
hostmakedepends="automake libtool pkg-config flex gettext libgcrypt-devel
live555-devel gettext-devel $(vopt_if lua lua52) $(vopt_if chromecast protobuf)"
makedepends="
- avahi-libs-devel dbus-glib-devel faad2-devel ffmpeg-devel freefont-ttf
+ avahi-libs-devel dbus-glib-devel faad2-devel ffmpeg4-devel freefont-ttf
gnutls-devel jack-devel liba52-devel libass-devel libbluray-devel
libcdio-devel libdca-devel libdvbpsi-devel libdvdnav-devel libmad-devel
libmatroska-devel libmodplug-devel libmpcdec-devel libmpeg2-devel
From 67e074dd1a4376ca7ecad28c6c810ec19b58a17d Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:00:55 -0400
Subject: [PATCH 011/140] osg: revbump for ffmpeg4-4.4.3
---
srcpkgs/osg/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/osg/template b/srcpkgs/osg/template
index a9ebbd287933..755793f7e11b 100644
--- a/srcpkgs/osg/template
+++ b/srcpkgs/osg/template
@@ -8,7 +8,7 @@ build_helper="qemu"
configure_args="-DLIB_POSTFIX="
hostmakedepends="pkg-config xrandr"
makedepends="MesaLib-devel gtkglext-devel libcurl-devel giflib-devel librsvg-devel
- jasper-devel tiff-devel libgdal-devel libgta-devel ffmpeg-devel xine-lib-devel
+ jasper-devel tiff-devel libgdal-devel libgta-devel ffmpeg4-devel xine-lib-devel
SDL2-devel gst-plugins-base1-devel
$(vopt_if openexr libopenexr-devel)
$(vopt_if poppler poppler-glib-devel)
From a02d106ff6726a0ba03d6adac66e5e38e569a99c Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:13 -0400
Subject: [PATCH 012/140] xine-lib: revbump for ffmpeg4-4.4.3
---
srcpkgs/xine-lib/template | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/srcpkgs/xine-lib/template b/srcpkgs/xine-lib/template
index f713eff49b07..ed6194c17d11 100644
--- a/srcpkgs/xine-lib/template
+++ b/srcpkgs/xine-lib/template
@@ -1,6 +1,6 @@
# Template file for 'xine-lib'
pkgname=xine-lib
-version=1.2.12
+version=1.2.13
revision=1
build_style=gnu-configure
configure_args="--disable-vcd --disable-gnomevfs --without-esound --disable-dxr3
@@ -8,7 +8,7 @@ configure_args="--disable-vcd --disable-gnomevfs --without-esound --disable-dxr3
hostmakedepends="automake gettext-devel libtool pkg-config perl"
makedepends="
zlib-devel alsa-lib-devel libxcb-devel libSM-devel libXext-devel libXv-devel
- libXvMC-devel liba52-devel libmad-devel ffmpeg-devel pulseaudio-devel
+ libXvMC-devel liba52-devel libmad-devel ffmpeg4-devel pulseaudio-devel
jack-devel samba-devel libflac-devel libmodplug-devel libmpcdec-devel
speex-devel libtheora-devel libvorbis-devel libdca-devel faad2-devel
libcdio-devel libbluray-devel aalib-devel libcaca-devel libXinerama-devel
@@ -19,7 +19,7 @@ license="GPL-2.0-or-later, LGPL-2.0-or-later"
homepage="http://www.xine-project.org"
changelog="https://sourceforge.net/projects/xine/files/xine-lib/${version}/README.txt/view"
distfiles="${SOURCEFORGE_SITE}/xine/${pkgname}-${version}.tar.xz"
-checksum=d606270468e1540c2a89c0d7f5fdf11e17ecc0c2698cc0bcb1065ff26abee098
+checksum=5f10d6d718a4a51c17ed1b32b031d4f9b80b061e8276535b2be31e5ac4b75e6f
case "$XBPS_TARGET_MACHINE" in
i686-musl)
From 04e6e3455350981602b6bf9cac81e024bda83e72 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:45 -0400
Subject: [PATCH 013/140] QMPlay2: revbump for ffmpeg-6.0
---
srcpkgs/QMPlay2/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/QMPlay2/template b/srcpkgs/QMPlay2/template
index ad73cbb01bae..55284c051161 100644
--- a/srcpkgs/QMPlay2/template
+++ b/srcpkgs/QMPlay2/template
@@ -1,7 +1,7 @@
# Template file for 'QMPlay2'
pkgname=QMPlay2
version=23.02.05
-revision=1
+revision=2
build_style=cmake
hostmakedepends="pkg-config qt5-qmake qt5-host-tools"
makedepends="alsa-lib-devel ffmpeg-devel libass-devel libcdio-devel libgme-devel
From 5fb396a304576e623150439ed6ffe40c1feaceeb Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:45 -0400
Subject: [PATCH 014/140] alsa-plugins: revbump for ffmpeg-6.0
---
srcpkgs/alsa-plugins/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/alsa-plugins/template b/srcpkgs/alsa-plugins/template
index 0bfa6d9fd264..a5708a7d82a8 100644
--- a/srcpkgs/alsa-plugins/template
+++ b/srcpkgs/alsa-plugins/template
@@ -1,7 +1,7 @@
# Template file for 'alsa-plugins'
pkgname=alsa-plugins
version=1.2.7.1
-revision=1
+revision=2
build_style=gnu-configure
configure_args="--disable-maemo-plugin"
hostmakedepends="pkg-config"
From 45b6117de5bc18b8c4ccacc0ba51bf73a79facb9 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:45 -0400
Subject: [PATCH 015/140] arcan: revbump for ffmpeg-6.0
---
srcpkgs/arcan/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/arcan/template b/srcpkgs/arcan/template
index 7be9652eccf3..ccc7df11ceac 100644
--- a/srcpkgs/arcan/template
+++ b/srcpkgs/arcan/template
@@ -2,7 +2,7 @@
# !! keep synced with: acfgfs aclip aloadimage
pkgname=arcan
version=0.6.2.1
-revision=1
+revision=2
create_wrksrc=yes
build_wrksrc=arcan/src
build_style=cmake
From 7d7f17e2bd9358810d2f5323f078acac16b0dbef Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:45 -0400
Subject: [PATCH 016/140] attract: revbump for ffmpeg4-4.4.3
---
srcpkgs/attract/template | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/srcpkgs/attract/template b/srcpkgs/attract/template
index 26144e931a3c..e760bf0d18ae 100644
--- a/srcpkgs/attract/template
+++ b/srcpkgs/attract/template
@@ -1,12 +1,12 @@
# Template file for 'attract'
pkgname=attract
version=2.6.2
-revision=1
+revision=2
build_style=gnu-makefile
make_build_args="VERBOSE=1"
make_use_env=yes
hostmakedepends="pkg-config"
-makedepends="SFML-devel ffmpeg-devel fontconfig-devel glu-devel libarchive-devel
+makedepends="SFML-devel ffmpeg4-devel fontconfig-devel glu-devel libarchive-devel
libcurl-devel libjpeg-turbo-devel xine-lib rapidjson libXrandr-devel"
depends="git"
short_desc="Attract-Mode is a graphical frontend for emulators"
From 2e80b0c920f6311d77a8c4a05982d9476bfb0ba5 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:45 -0400
Subject: [PATCH 017/140] aubio: revbump for ffmpeg-6.0
---
srcpkgs/aubio/patches/ffmpeg5.patch | 25 +++++++++++++++++++++++++
srcpkgs/aubio/template | 2 +-
2 files changed, 26 insertions(+), 1 deletion(-)
create mode 100644 srcpkgs/aubio/patches/ffmpeg5.patch
diff --git a/srcpkgs/aubio/patches/ffmpeg5.patch b/srcpkgs/aubio/patches/ffmpeg5.patch
new file mode 100644
index 000000000000..aace41a6e6d9
--- /dev/null
+++ b/srcpkgs/aubio/patches/ffmpeg5.patch
@@ -0,0 +1,25 @@
+From 8a05420e5dd8c7b8b2447f82dc919765876511b3 Mon Sep 17 00:00:00 2001
+From: Paul Brossier <piem@piem.org>
+Date: Tue, 25 Jan 2022 18:30:27 +0100
+Subject: [PATCH] [source_avcodec] define FF_API_LAVF_AVCTX for libavcodec >
+ 59, thx @berolinux (closes gh-353)
+
+---
+ src/io/source_avcodec.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/src/io/source_avcodec.c b/src/io/source_avcodec.c
+index e0ae93b5..1421bd9a 100644
+--- a/src/io/source_avcodec.c
++++ b/src/io/source_avcodec.c
+@@ -68,6 +68,10 @@
+ #define AUBIO_AVCODEC_MAX_BUFFER_SIZE AV_INPUT_BUFFER_MIN_SIZE
+ #endif
+
++#if LIBAVCODEC_VERSION_MAJOR >= 59
++#define FF_API_LAVF_AVCTX 1
++#endif
++
+ struct _aubio_source_avcodec_t {
+ uint_t hop_size;
+ uint_t samplerate;
diff --git a/srcpkgs/aubio/template b/srcpkgs/aubio/template
index ad1c4b256991..7d875cc02541 100644
--- a/srcpkgs/aubio/template
+++ b/srcpkgs/aubio/template
@@ -1,7 +1,7 @@
# Template file for 'aubio'
pkgname=aubio
version=0.4.9
-revision=1
+revision=2
build_style=waf3
# XXX lash, pure and swig support.
hostmakedepends="pkg-config txt2man"
From 7fb01cc5e73a215422bd72f9fa8b5fc26c7400a1 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:45 -0400
Subject: [PATCH 018/140] audacious-plugins: revbump for ffmpeg-6.0
---
.../audacious-plugins/patches/ffmpeg5.patch | 43 +++++++++++++++++++
srcpkgs/audacious-plugins/template | 2 +-
2 files changed, 44 insertions(+), 1 deletion(-)
create mode 100644 srcpkgs/audacious-plugins/patches/ffmpeg5.patch
diff --git a/srcpkgs/audacious-plugins/patches/ffmpeg5.patch b/srcpkgs/audacious-plugins/patches/ffmpeg5.patch
new file mode 100644
index 000000000000..4e5e34099d71
--- /dev/null
+++ b/srcpkgs/audacious-plugins/patches/ffmpeg5.patch
@@ -0,0 +1,43 @@
+commit 298aa371c56c2f52c25a33d9bdec4918b11cebdc
+Author: tibequadorian <tibequadorian@posteo.de>
+Date: Sat Mar 19 18:40:12 2022 +0100
+
+ audacious-plugins: rebuild against ffmpeg-5.0
+
+diff --git a/srcpkgs/audacious-plugins/patches/ffmpeg-5.0.patch b/srcpkgs/audacious-plugins/patches/ffmpeg-5.0.patch
+new file mode 100644
+index 0000000000..617c11215b
+--- /dev/null
++++ b/srcpkgs/audacious-plugins/patches/ffmpeg-5.0.patch
+@@ -0,0 +1,31 @@
++From f60beb400eeb1e4778bbfd738bc4a4ccef3de539 Mon Sep 17 00:00:00 2001
++From: John Lindgren <john@jlindgren.net>
++Date: Sat, 5 Mar 2022 12:05:34 -0500
++Subject: [PATCH] Fix build with FFmpeg 5.0
++
++---
++ src/ffaudio/ffaudio-core.cc | 4 ++--
++ 1 file changed, 2 insertions(+), 2 deletions(-)
++
++diff --git a/src/ffaudio/ffaudio-core.cc b/src/ffaudio/ffaudio-core.cc
++index 16dc63e3a..a2b95fd6c 100644
++--- a/src/ffaudio/ffaudio-core.cc
+++++ b/src/ffaudio/ffaudio-core.cc
++@@ -274,7 +274,7 @@ static AVInputFormat * get_format_by_content (const char * name, VFSFile & file)
++ AVProbeData d = {name, buf, filled};
++ score = target;
++
++- f = av_probe_input_format2 (& d, true, & score);
+++ f = (AVInputFormat *) av_probe_input_format2 (& d, true, & score);
++ if (f)
++ break;
++
++@@ -347,7 +347,7 @@ static bool find_codec (AVFormatContext * c, CodecInfo * cinfo)
++ #endif
++ if (stream && stream->codecpar && stream->codecpar->codec_type == AVMEDIA_TYPE_AUDIO)
++ {
++- AVCodec * codec = avcodec_find_decoder (stream->codecpar->codec_id);
+++ AVCodec * codec = (AVCodec *) avcodec_find_decoder (stream->codecpar->codec_id);
++
++ if (codec)
++ {
diff --git a/srcpkgs/audacious-plugins/template b/srcpkgs/audacious-plugins/template
index 88cbc1671fc6..beebfae59ed4 100644
--- a/srcpkgs/audacious-plugins/template
+++ b/srcpkgs/audacious-plugins/template
@@ -2,7 +2,7 @@
#Keep in sync with audacious!
pkgname=audacious-plugins
version=4.3.1
-revision=1
+revision=2
build_style=meson
configure_args="$(vopt_bool gtk3 gtk) $(vopt_bool gtk3)
$(vopt_bool qt) $(vopt_bool qt qt6)"
From c8955a13670baa12da2f68c6802e23bf5bdda641 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:45 -0400
Subject: [PATCH 019/140] audacity: revbump for ffmpeg4-4.4.3
---
srcpkgs/audacity/template | 5 ++---
1 file changed, 2 insertions(+), 3 deletions(-)
diff --git a/srcpkgs/audacity/template b/srcpkgs/audacity/template
index d509c0a89407..11e20255685b 100644
--- a/srcpkgs/audacity/template
+++ b/srcpkgs/audacity/template
@@ -1,7 +1,7 @@
# Template file for 'audacity'
pkgname=audacity
version=2.4.1
-revision=2
+revision=3
build_style=gnu-configure
configure_args="--with-ffmpeg=system --with-libsndfile=system --with-expat=system
--with-libsoxr=system --with-lame=system --with-lv2=system ac_cv_path_WX_CONFIG=wx-config-gtk3"
@@ -9,7 +9,7 @@ hostmakedepends="pkg-config cmake gettext libtool m4 which"
makedepends="jack-devel wxWidgets-gtk3-devel gtk+3-devel
libmad-devel soundtouch-devel libsoxr-devel
vamp-plugin-sdk-devel lame-devel libid3tag-devel libflac-devel
- ffmpeg-devel twolame-devel serd-devel lv2 lilv-devel suil-devel"
+ ffmpeg4-devel twolame-devel serd-devel lv2 lilv-devel suil-devel"
depends="desktop-file-utils hicolor-icon-theme"
short_desc="Graphical cross-platform audio editor"
maintainer="Orphaned <orphan@voidlinux.org>"
@@ -33,5 +33,4 @@ post_install() {
vcopy plug-ins /usr/share/audacity
rm ${DESTDIR}/usr/share/doc/audacity/LICENSE.txt
- vlicense LICENSE.txt LICENSE
}
From 145985c0b62ee4b1888332a5be8256d6adcb5dca Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:45 -0400
Subject: [PATCH 020/140] avidemux: revbump for ffmpeg-6.0
---
srcpkgs/avidemux/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/avidemux/template b/srcpkgs/avidemux/template
index 253a0243e225..557285982d2b 100644
--- a/srcpkgs/avidemux/template
+++ b/srcpkgs/avidemux/template
@@ -1,7 +1,7 @@
# Template file for 'avidemux'
pkgname=avidemux
version=2.8.0
-revision=2
+revision=3
# Can't be compiled for aarch64, arm* or mips*
archs="x86_64* i686*"
hostmakedepends="cmake pkg-config qt5-host-tools qt5-devel tar yasm"
From 1b314054810e8de661612ee40015dc043141ae3f Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:45 -0400
Subject: [PATCH 021/140] baresip: revbump for ffmpeg-6.0
---
srcpkgs/baresip/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/baresip/template b/srcpkgs/baresip/template
index f1bd1817048b..b21e22334316 100644
--- a/srcpkgs/baresip/template
+++ b/srcpkgs/baresip/template
@@ -1,7 +1,7 @@
# Template file for 'baresip'
pkgname=baresip
version=2.10.0
-revision=1
+revision=2
build_style=cmake
hostmakedepends="pkg-config glib-devel"
makedepends="libgsm-devel libpng-devel openssl-devel libsndfile-devel
From fd55de773224302a44fb079fe9cf5f0913e9ce94 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:46 -0400
Subject: [PATCH 022/140] blender: revbump for ffmpeg-6.0
---
.../patches/ffmpeg6-compat-blender.patch | 42 +++++++++++++++++++
srcpkgs/blender/template | 2 +-
2 files changed, 43 insertions(+), 1 deletion(-)
create mode 100644 srcpkgs/blender/patches/ffmpeg6-compat-blender.patch
diff --git a/srcpkgs/blender/patches/ffmpeg6-compat-blender.patch b/srcpkgs/blender/patches/ffmpeg6-compat-blender.patch
new file mode 100644
index 000000000000..d51a9c7710cc
--- /dev/null
+++ b/srcpkgs/blender/patches/ffmpeg6-compat-blender.patch
@@ -0,0 +1,42 @@
+--- a/source/blender/blenkernel/intern/writeffmpeg.c 2022-11-08 13:50:16 UTC
++++ b/source/blender/blenkernel/intern/writeffmpeg.c
+@@ -855,7 +855,7 @@ static AVStream *alloc_video_stream(FFMpegContext *con
+ 255);
+ st->avg_frame_rate = av_inv_q(c->time_base);
+
+- if (codec->capabilities & AV_CODEC_CAP_AUTO_THREADS) {
++ if (codec->capabilities & AV_CODEC_CAP_OTHER_THREADS) {
+ c->thread_count = 0;
+ }
+ else {
+--- a/source/blender/imbuf/intern/anim_movie.c 2022-11-04 00:33:07 UTC
++++ b/source/blender/imbuf/intern/anim_movie.c
+@@ -554,7 +554,7 @@ static int startffmpeg(struct anim *anim)
+ avcodec_parameters_to_context(pCodecCtx, video_stream->codecpar);
+ pCodecCtx->workaround_bugs = FF_BUG_AUTODETECT;
+
+- if (pCodec->capabilities & AV_CODEC_CAP_AUTO_THREADS) {
++ if (pCodec->capabilities & AV_CODEC_CAP_OTHER_THREADS) {
+ pCodecCtx->thread_count = 0;
+ }
+ else {
+--- a/source/blender/imbuf/intern/indexer.c 2022-11-04 00:33:07 UTC
++++ b/source/blender/imbuf/intern/indexer.c
+@@ -559,7 +559,7 @@ static struct proxy_output_ctx *alloc_proxy_output_ffm
+ av_dict_set(&codec_opts, "preset", "veryfast", 0);
+ av_dict_set(&codec_opts, "tune", "fastdecode", 0);
+
+- if (rv->codec->capabilities & AV_CODEC_CAP_AUTO_THREADS) {
++ if (rv->codec->capabilities & AV_CODEC_CAP_OTHER_THREADS) {
+ rv->c->thread_count = 0;
+ }
+ else {
+@@ -872,7 +872,7 @@ static IndexBuildContext *index_ffmpeg_create_context(
+ avcodec_parameters_to_context(context->iCodecCtx, context->iStream->codecpar);
+ context->iCodecCtx->workaround_bugs = FF_BUG_AUTODETECT;
+
+- if (context->iCodec->capabilities & AV_CODEC_CAP_AUTO_THREADS) {
++ if (context->iCodec->capabilities & AV_CODEC_CAP_OTHER_THREADS) {
+ context->iCodecCtx->thread_count = 0;
+ }
+ else {
diff --git a/srcpkgs/blender/template b/srcpkgs/blender/template
index 61b42eb2e51e..d18bc88838ff 100644
--- a/srcpkgs/blender/template
+++ b/srcpkgs/blender/template
@@ -1,7 +1,7 @@
# Template file for 'blender'
pkgname=blender
version=3.4.1
-revision=3
+revision=4
archs="x86_64* ppc64*"
build_style="cmake"
pycompile_dirs="/usr/share/blender/${version%.*}/scripts"
From b5178e4e573e5b75627b166200152ee31412c182 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:46 -0400
Subject: [PATCH 023/140] cantata: revbump for ffmpeg-6.0
---
srcpkgs/cantata/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/cantata/template b/srcpkgs/cantata/template
index 4b417d80d5c2..8a90aaa4c07a 100644
--- a/srcpkgs/cantata/template
+++ b/srcpkgs/cantata/template
@@ -1,7 +1,7 @@
# Template file for 'cantata'
pkgname=cantata
version=2.5.0
-revision=1
+revision=2
build_style=cmake
hostmakedepends="pkg-config qt5-qmake qt5-host-tools qt5-tools"
makedepends="qt5-devel qt5-tools-devel qt5-svg-devel qt5-xmlpatterns-devel
From 59259d40817fa204e536d43c7e944132f9beba14 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:46 -0400
Subject: [PATCH 024/140] ccextractor: revbump for ffmpeg4-4.4.3
---
srcpkgs/ccextractor/template | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/srcpkgs/ccextractor/template b/srcpkgs/ccextractor/template
index 9abcd82852b2..6eccad5885af 100644
--- a/srcpkgs/ccextractor/template
+++ b/srcpkgs/ccextractor/template
@@ -1,12 +1,12 @@
# Template file for 'ccextractor'
pkgname=ccextractor
version=0.93
-revision=1
+revision=2
build_wrksrc="linux"
build_style=gnu-configure
configure_args="--enable-ocr --enable-hardsubx"
hostmakedepends="automake pkg-config"
-makedepends="leptonica-devel tesseract-ocr-devel ffmpeg-devel"
+makedepends="leptonica-devel tesseract-ocr-devel ffmpeg4-devel"
short_desc="Extract subtitles from video streams"
maintainer="newbluemoon <blaumolch@mailbox.org>"
license="GPL-2.0-or-later"
From 4300dd323d02bba6a36b8b4a0a1be5ed85f25fdb Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:46 -0400
Subject: [PATCH 025/140] chromaprint: revbump for ffmpeg-6.0
---
srcpkgs/chromaprint/patches/ffmpeg5.patch | 569 ++++++++++++++++++++++
srcpkgs/chromaprint/template | 2 +-
2 files changed, 570 insertions(+), 1 deletion(-)
create mode 100644 srcpkgs/chromaprint/patches/ffmpeg5.patch
diff --git a/srcpkgs/chromaprint/patches/ffmpeg5.patch b/srcpkgs/chromaprint/patches/ffmpeg5.patch
new file mode 100644
index 000000000000..a9fd307a23c8
--- /dev/null
+++ b/srcpkgs/chromaprint/patches/ffmpeg5.patch
@@ -0,0 +1,569 @@
+From 8ccad6937177b1b92e40ab8f4447ea27bac009a7 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Luk=C3=A1=C5=A1=20Lalinsk=C3=BD?= <lalinsky@gmail.com>
+Date: Fri, 4 Nov 2022 21:47:38 +0100
+Subject: [PATCH] Use FFmpeg 5.x (#120)
+
+* Use FFmpeg 5.1.2 for CI builds
+
+* Build on Ubuntu 20.04
+
+* Upgrade code to FFmpeg 5.x APIs
+
+* Only set FFmpeg include dirs if building tools
+
+* No longer needed
+
+* Use ubuntu 20.04
+---
+ .github/workflows/build.yml | 6 +-
+ CMakeLists.txt | 16 --
+ package/build.sh | 4 +-
+ src/audio/ffmpeg_audio_processor.h | 2 -
+ src/audio/ffmpeg_audio_processor_avresample.h | 72 -------
+ src/audio/ffmpeg_audio_processor_swresample.h | 18 +-
+ src/audio/ffmpeg_audio_reader.h | 197 +++++++++---------
+ tests/CMakeLists.txt | 6 +
+ 8 files changed, 122 insertions(+), 199 deletions(-)
+ delete mode 100644 src/audio/ffmpeg_audio_processor_avresample.h
+
+diff --git a/CMakeLists.txt b/CMakeLists.txt
+index f8d6a32..4da2405 100644
+--- a/CMakeLists.txt
++++ b/CMakeLists.txt
+@@ -84,9 +84,6 @@ find_package(FFmpeg)
+ if(FFMPEG_LIBRARIES)
+ cmake_push_check_state(RESET)
+ set(CMAKE_REQUIRED_LIBRARIES ${FFMPEG_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT} -lm)
+- check_function_exists(av_packet_unref HAVE_AV_PACKET_UNREF)
+- check_function_exists(av_frame_alloc HAVE_AV_FRAME_ALLOC)
+- check_function_exists(av_frame_free HAVE_AV_FRAME_FREE)
+ cmake_pop_check_state()
+ endif()
+
+@@ -163,14 +160,11 @@ message(STATUS "Using ${FFT_LIB} for FFT calculations")
+ if(NOT AUDIO_PROCESSOR_LIB)
+ if(FFMPEG_LIBSWRESAMPLE_FOUND)
+ set(AUDIO_PROCESSOR_LIB "swresample")
+- elseif(FFMPEG_LIBAVRESAMPLE_FOUND)
+- set(AUDIO_PROCESSOR_LIB "avresample")
+ endif()
+ endif()
+
+ if(AUDIO_PROCESSOR_LIB STREQUAL "swresample")
+ if(FFMPEG_LIBSWRESAMPLE_FOUND)
+- set(USE_AVRESAMPLE OFF)
+ set(USE_SWRESAMPLE ON)
+ set(AUDIO_PROCESSOR_LIBRARIES ${FFMPEG_LIBSWRESAMPLE_LIBRARIES})
+ set(AUDIO_PROCESSOR_INCLUDE_DIRS ${FFMPEG_LIBSWRESAMPLE_INCLUDE_DIRS})
+@@ -178,16 +172,6 @@ if(AUDIO_PROCESSOR_LIB STREQUAL "swresample")
+ message(FATAL_ERROR "Selected ${AUDIO_PROCESSOR_LIB} for audio processing, but the library is not found")
+ endif()
+ message(STATUS "Using ${AUDIO_PROCESSOR_LIB} for audio conversion")
+-elseif(AUDIO_PROCESSOR_LIB STREQUAL "avresample")
+- if(FFMPEG_LIBAVRESAMPLE_FOUND)
+- set(USE_AVRESAMPLE ON)
+- set(USE_SWRESAMPLE OFF)
+- set(AUDIO_PROCESSOR_LIBRARIES ${FFMPEG_LIBAVRESAMPLE_LIBRARIES})
+- set(AUDIO_PROCESSOR_INCLUDE_DIRS ${FFMPEG_LIBAVRESAMPLE_INCLUDE_DIRS})
+- else()
+- message(FATAL_ERROR "Selected ${AUDIO_PROCESSOR_LIB} for audio processing, but the library is not found")
+- endif()
+- message(STATUS "Using ${AUDIO_PROCESSOR_LIB} for audio conversion")
+ else()
+ message(STATUS "Building without audio conversion support, please install FFmpeg with libswresample")
+ endif()
+diff --git a/package/build.sh b/package/build.sh
+index da631ae..b41d36e 100755
+--- a/package/build.sh
++++ b/package/build.sh
+@@ -7,8 +7,8 @@ set -eux
+
+ BASE_DIR=$(cd $(dirname $0)/.. && pwd)
+
+-FFMPEG_VERSION=4.4.1
+-FFMPEG_BUILD_TAG=v4.4.1-1
++FFMPEG_VERSION=5.1.2
++FFMPEG_BUILD_TAG=v${FFMPEG_VERSION}-1
+
+ TMP_BUILD_DIR=$BASE_DIR/$(mktemp -d build.XXXXXXXX)
+ trap 'rm -rf $TMP_BUILD_DIR' EXIT
+diff --git a/src/audio/ffmpeg_audio_processor.h b/src/audio/ffmpeg_audio_processor.h
+index 7628fc7..39f4f6d 100644
+--- a/src/audio/ffmpeg_audio_processor.h
++++ b/src/audio/ffmpeg_audio_processor.h
+@@ -10,8 +10,6 @@
+
+ #if defined(USE_SWRESAMPLE)
+ #include "audio/ffmpeg_audio_processor_swresample.h"
+-#elif defined(USE_AVRESAMPLE)
+-#include "audio/ffmpeg_audio_processor_avresample.h"
+ #else
+ #error "no audio processing library"
+ #endif
+diff --git a/src/audio/ffmpeg_audio_processor_avresample.h b/src/audio/ffmpeg_audio_processor_avresample.h
+deleted file mode 100644
+index bd85f92..0000000
+--- a/src/audio/ffmpeg_audio_processor_avresample.h
++++ /dev/null
+@@ -1,72 +0,0 @@
+-// Copyright (C) 2016 Lukas Lalinsky
+-// Distributed under the MIT license, see the LICENSE file for details.
+-
+-#ifndef CHROMAPRINT_AUDIO_FFMPEG_AUDIO_PROCESSOR_AVRESAMPLE_H_
+-#define CHROMAPRINT_AUDIO_FFMPEG_AUDIO_PROCESSOR_AVRESAMPLE_H_
+-
+-extern "C" {
+-#include <libavresample/avresample.h>
+-}
+-
+-namespace chromaprint {
+-
+-class FFmpegAudioProcessor {
+-public:
+- FFmpegAudioProcessor() {
+- m_resample_ctx = avresample_alloc_context();
+- }
+-
+- ~FFmpegAudioProcessor() {
+- avresample_free(&m_resample_ctx);
+- }
+-
+- void SetCompatibleMode() {
+- av_opt_set_int(m_resample_ctx, "filter_size", 16, 0);
+- av_opt_set_int(m_resample_ctx, "phase_shift", 8, 0);
+- av_opt_set_int(m_resample_ctx, "linear_interp", 1, 0);
+- av_opt_set_double(m_resample_ctx, "cutoff", 0.8, 0);
+- }
+-
+- void SetInputChannelLayout(int64_t channel_layout) {
+- av_opt_set_int(m_resample_ctx, "in_channel_layout", channel_layout, 0);
+- }
+-
+- void SetInputSampleFormat(AVSampleFormat sample_format) {
+- av_opt_set_int(m_resample_ctx, "in_sample_fmt", sample_format, 0);
+- }
+-
+- void SetInputSampleRate(int sample_rate) {
+- av_opt_set_int(m_resample_ctx, "in_sample_rate", sample_rate, 0);
+- }
+-
+- void SetOutputChannelLayout(int64_t channel_layout) {
+- av_opt_set_int(m_resample_ctx, "out_channel_layout", channel_layout, 0);
+- }
+-
+- void SetOutputSampleFormat(AVSampleFormat sample_format) {
+- av_opt_set_int(m_resample_ctx, "out_sample_fmt", sample_format, 0);
+- }
+-
+- void SetOutputSampleRate(int sample_rate) {
+- av_opt_set_int(m_resample_ctx, "out_sample_fmt", sample_rate, 0);
+- }
+-
+- int Init() {
+- return avresample_open(m_resample_ctx);
+- }
+-
+- int Convert(uint8_t **out, int out_count, const uint8_t **in, int in_count) {
+- return avresample_convert(m_resample_ctx, out, 0, out_count, (uint8_t **) in, 0, in_count);
+- }
+-
+- int Flush(uint8_t **out, int out_count) {
+- return avresample_read(m_resample_ctx, out, out_count);
+- }
+-
+-private:
+- AVAudioResampleContext *m_resample_ctx = nullptr;
+-};
+-
+-}; // namespace chromaprint
+-
+-#endif
+diff --git a/src/audio/ffmpeg_audio_processor_swresample.h b/src/audio/ffmpeg_audio_processor_swresample.h
+index b86266b..b1d4bea 100644
+--- a/src/audio/ffmpeg_audio_processor_swresample.h
++++ b/src/audio/ffmpeg_audio_processor_swresample.h
+@@ -28,30 +28,28 @@ public:
+ av_opt_set_double(m_swr_ctx, "cutoff", 0.8, 0);
+ }
+
+- void SetInputChannelLayout(int64_t channel_layout) {
+- av_opt_set_int(m_swr_ctx, "icl", channel_layout, 0);
+- av_opt_set_int(m_swr_ctx, "ich", av_get_channel_layout_nb_channels(channel_layout), 0);
++ void SetInputChannelLayout(AVChannelLayout *channel_layout) {
++ av_opt_set_int(m_swr_ctx, "in_channel_layout", channel_layout->u.mask, 0);
+ }
+
+ void SetInputSampleFormat(AVSampleFormat sample_format) {
+- av_opt_set_int(m_swr_ctx, "isf", sample_format, 0);
++ av_opt_set_sample_fmt(m_swr_ctx, "in_sample_fmt", sample_format, 0);
+ }
+
+ void SetInputSampleRate(int sample_rate) {
+- av_opt_set_int(m_swr_ctx, "isr", sample_rate, 0);
++ av_opt_set_int(m_swr_ctx, "in_sample_rate", sample_rate, 0);
+ }
+
+- void SetOutputChannelLayout(int64_t channel_layout) {
+- av_opt_set_int(m_swr_ctx, "ocl", channel_layout, 0);
+- av_opt_set_int(m_swr_ctx, "och", av_get_channel_layout_nb_channels(channel_layout), 0);
++ void SetOutputChannelLayout(AVChannelLayout *channel_layout) {
++ av_opt_set_int(m_swr_ctx, "out_channel_layout", channel_layout->u.mask, 0);
+ }
+
+ void SetOutputSampleFormat(AVSampleFormat sample_format) {
+- av_opt_set_int(m_swr_ctx, "osf", sample_format, 0);
++ av_opt_set_sample_fmt(m_swr_ctx, "out_sample_fmt", sample_format, 0);
+ }
+
+ void SetOutputSampleRate(int sample_rate) {
+- av_opt_set_int(m_swr_ctx, "osr", sample_rate, 0);
++ av_opt_set_int(m_swr_ctx, "out_sample_rate", sample_rate, 0);
+ }
+
+ int Init() {
+diff --git a/src/audio/ffmpeg_audio_reader.h b/src/audio/ffmpeg_audio_reader.h
+index 5550164..1c6b346 100644
+--- a/src/audio/ffmpeg_audio_reader.h
++++ b/src/audio/ffmpeg_audio_reader.h
+@@ -62,7 +62,7 @@ public:
+ bool Read(const int16_t **data, size_t *size);
+
+ bool IsOpen() const { return m_opened; }
+- bool IsFinished() const { return m_finished && !m_got_frame; }
++ bool IsFinished() const { return !m_has_more_packets && !m_has_more_frames; }
+
+ std::string GetError() const { return m_error; }
+ int GetErrorCode() const { return m_error_code; }
+@@ -74,20 +74,19 @@ private:
+ uint8_t *m_convert_buffer[1] = { nullptr };
+ int m_convert_buffer_nb_samples = 0;
+
+- AVInputFormat *m_input_fmt = nullptr;
++ const AVInputFormat *m_input_fmt = nullptr;
+ AVDictionary *m_input_opts = nullptr;
+
+ AVFormatContext *m_format_ctx = nullptr;
+ AVCodecContext *m_codec_ctx = nullptr;
+- AVFrame *m_frame = nullptr;
+ int m_stream_index = -1;
+ std::string m_error;
+ int m_error_code = 0;
+- bool m_finished = false;
+ bool m_opened = false;
+- int m_got_frame = 0;
+- AVPacket m_packet;
+- AVPacket m_packet0;
++ bool m_has_more_packets = true;
++ bool m_has_more_frames = true;
++ AVPacket *m_packet = nullptr;
++ AVFrame *m_frame = nullptr;
+
+ int m_output_sample_rate = 0;
+ int m_output_channels = 0;
+@@ -98,19 +97,12 @@ private:
+
+ inline FFmpegAudioReader::FFmpegAudioReader() {
+ av_log_set_level(AV_LOG_QUIET);
+-
+- av_init_packet(&m_packet);
+- m_packet.data = nullptr;
+- m_packet.size = 0;
+-
+- m_packet0 = m_packet;
+ }
+
+ inline FFmpegAudioReader::~FFmpegAudioReader() {
+ Close();
+ av_dict_free(&m_input_opts);
+ av_freep(&m_convert_buffer[0]);
+- av_packet_unref(&m_packet0);
+ }
+
+ inline bool FFmpegAudioReader::SetInputFormat(const char *name) {
+@@ -135,11 +127,10 @@ inline bool FFmpegAudioReader::Open(const std::string &file_name) {
+
+ Close();
+
+- av_init_packet(&m_packet);
+- m_packet.data = nullptr;
+- m_packet.size = 0;
+-
+- m_packet0 = m_packet;
++ m_packet = av_packet_alloc();
++ if (!m_packet) {
++ return false;
++ }
+
+ ret = avformat_open_input(&m_format_ctx, file_name.c_str(), m_input_fmt, &m_input_opts);
+ if (ret < 0) {
+@@ -153,26 +144,31 @@ inline bool FFmpegAudioReader::Open(const std::string &file_name) {
+ return false;
+ }
+
+- AVCodec *codec;
++ const AVCodec *codec;
+ ret = av_find_best_stream(m_format_ctx, AVMEDIA_TYPE_AUDIO, -1, -1, &codec, 0);
+ if (ret < 0) {
+ SetError("Could not find any audio stream in the file", ret);
+ return false;
+ }
+ m_stream_index = ret;
++ auto stream = m_format_ctx->streams[m_stream_index];
+
+- m_codec_ctx = m_format_ctx->streams[m_stream_index]->codec;
++ m_codec_ctx = avcodec_alloc_context3(codec);
+ m_codec_ctx->request_sample_fmt = AV_SAMPLE_FMT_S16;
+
++ ret = avcodec_parameters_to_context(m_codec_ctx, stream->codecpar);
++ if (ret < 0) {
++ SetError("Could not copy the stream parameters", ret);
++ return false;
++ }
++
+ ret = avcodec_open2(m_codec_ctx, codec, nullptr);
+ if (ret < 0) {
+ SetError("Could not open the codec", ret);
+ return false;
+ }
+
+- if (!m_codec_ctx->channel_layout) {
+- m_codec_ctx->channel_layout = av_get_default_channel_layout(m_codec_ctx->channels);
+- }
++ av_dump_format(m_format_ctx, 0, "foo", 0);
+
+ m_frame = av_frame_alloc();
+ if (!m_frame) {
+@@ -183,19 +179,23 @@ inline bool FFmpegAudioReader::Open(const std::string &file_name) {
+ m_output_sample_rate = m_codec_ctx->sample_rate;
+ }
+
+- if (!m_output_channels) {
+- m_output_channels = m_codec_ctx->channels;
++ AVChannelLayout output_channel_layout;
++ if (m_output_channels) {
++ av_channel_layout_default(&output_channel_layout, m_output_channels);
++ } else {
++ m_output_channels = m_codec_ctx->ch_layout.nb_channels;
++ av_channel_layout_default(&output_channel_layout, m_output_channels);
+ }
+
+- if (m_codec_ctx->sample_fmt != AV_SAMPLE_FMT_S16 || m_codec_ctx->channels != m_output_channels || m_codec_ctx->sample_rate != m_output_sample_rate) {
++ if (m_codec_ctx->sample_fmt != AV_SAMPLE_FMT_S16 || m_codec_ctx->ch_layout.nb_channels != m_output_channels || m_codec_ctx->sample_rate != m_output_sample_rate) {
+ m_converter.reset(new FFmpegAudioProcessor());
+ m_converter->SetCompatibleMode();
+ m_converter->SetInputSampleFormat(m_codec_ctx->sample_fmt);
+ m_converter->SetInputSampleRate(m_codec_ctx->sample_rate);
+- m_converter->SetInputChannelLayout(m_codec_ctx->channel_layout);
++ m_converter->SetInputChannelLayout(&(m_codec_ctx->ch_layout));
+ m_converter->SetOutputSampleFormat(AV_SAMPLE_FMT_S16);
+ m_converter->SetOutputSampleRate(m_output_sample_rate);
+- m_converter->SetOutputChannelLayout(av_get_default_channel_layout(m_output_channels));
++ m_converter->SetOutputChannelLayout(&output_channel_layout);
+ auto ret = m_converter->Init();
+ if (ret != 0) {
+ SetError("Could not create an audio converter instance", ret);
+@@ -203,10 +203,11 @@ inline bool FFmpegAudioReader::Open(const std::string &file_name) {
+ }
+ }
+
++ av_channel_layout_uninit(&output_channel_layout);
++
+ m_opened = true;
+- m_finished = false;
+- m_got_frame = 0;
+- m_nb_packets = 0;
++ m_has_more_packets = true;
++ m_has_more_frames = true;
+ m_decode_error = 0;
+
+ return true;
+@@ -214,6 +215,7 @@ inline bool FFmpegAudioReader::Open(const std::string &file_name) {
+
+ inline void FFmpegAudioReader::Close() {
+ av_frame_free(&m_frame);
++ av_packet_free(&m_packet);
+
+ m_stream_index = -1;
+
+@@ -252,91 +254,98 @@ inline bool FFmpegAudioReader::Read(const int16_t **data, size_t *size) {
+ return false;
+ }
+
++ *data = nullptr;
++ *size = 0;
++
+ int ret;
++ bool needs_packet = false;
+ while (true) {
+- while (m_packet.size <= 0) {
+- av_packet_unref(&m_packet0);
+- av_init_packet(&m_packet);
+- m_packet.data = nullptr;
+- m_packet.size = 0;
+- ret = av_read_frame(m_format_ctx, &m_packet);
++ while (needs_packet && m_packet->size == 0) {
++ ret = av_read_frame(m_format_ctx, m_packet);
+ if (ret < 0) {
+ if (ret == AVERROR_EOF) {
+- m_finished = true;
++ needs_packet = false;
++ m_has_more_packets = false;
+ break;
+- } else {
++ }
++ SetError("Error reading from the audio source", ret);
++ return false;
++ }
++ if (m_packet->stream_index == m_stream_index) {
++ needs_packet = false;
++ } else {
++ av_packet_unref(m_packet);
++ }
++ }
++
++ if (m_packet->size != 0) {
++ ret = avcodec_send_packet(m_codec_ctx, m_packet);
++ if (ret < 0) {
++ if (ret != AVERROR(EAGAIN)) {
+ SetError("Error reading from the audio source", ret);
+ return false;
+ }
+- }
+- m_packet0 = m_packet;
+- if (m_packet.stream_index != m_stream_index) {
+- m_packet.data = nullptr;
+- m_packet.size = 0;
+ } else {
+- m_nb_packets++;
++ av_packet_unref(m_packet);
+ }
+ }
+
+- ret = avcodec_decode_audio4(m_codec_ctx, m_frame, &m_got_frame, &m_packet);
++ ret = avcodec_receive_frame(m_codec_ctx, m_frame);
+ if (ret < 0) {
+- if (m_decode_error) {
+- SetError("Error decoding audio frame", m_decode_error);
+- return false;
++ if (ret == AVERROR_EOF) {
++ m_has_more_frames = false;
++ } else if (ret == AVERROR(EAGAIN)) {
++ if (m_has_more_packets) {
++ needs_packet = true;
++ continue;
++ } else {
++ m_has_more_frames = false;
++ }
+ }
+- m_decode_error = ret;
+- m_packet.data = nullptr;
+- m_packet.size = 0;
+- continue;
++ SetError("Error decoding the audio source", ret);
++ return false;
+ }
+
+- break;
+- }
+-
+- m_decode_error = 0;
+-
+- const int decoded = std::min(ret, m_packet.size);
+- m_packet.data += decoded;
+- m_packet.size -= decoded;
+-
+- if (m_got_frame) {
+- if (m_converter) {
+- if (m_frame->nb_samples > m_convert_buffer_nb_samples) {
+- int linsize;
+- av_freep(&m_convert_buffer[0]);
+- m_convert_buffer_nb_samples = std::max(1024 * 8, m_frame->nb_samples);
+- ret = av_samples_alloc(m_convert_buffer, &linsize, m_codec_ctx->channels, m_convert_buffer_nb_samples, AV_SAMPLE_FMT_S16, 1);
+- if (ret < 0) {
+- SetError("Couldn't allocate audio converter buffer", ret);
++ if (m_frame->nb_samples > 0) {
++ if (m_converter) {
++ if (m_frame->nb_samples > m_convert_buffer_nb_samples) {
++ int linsize;
++ av_freep(&m_convert_buffer[0]);
++ m_convert_buffer_nb_samples = std::max(1024 * 8, m_frame->nb_samples);
++ ret = av_samples_alloc(m_convert_buffer, &linsize, m_codec_ctx->ch_layout.nb_channels, m_convert_buffer_nb_samples, AV_SAMPLE_FMT_S16, 1);
++ if (ret < 0) {
++ SetError("Couldn't allocate audio converter buffer", ret);
++ return false;
++ }
++ }
++ auto nb_samples = m_converter->Convert(m_convert_buffer, m_convert_buffer_nb_samples, (const uint8_t **) m_frame->data, m_frame->nb_samples);
++ if (nb_samples < 0) {
++ SetError("Couldn't convert audio", ret);
+ return false;
+ }
+- }
+- auto nb_samples = m_converter->Convert(m_convert_buffer, m_convert_buffer_nb_samples, (const uint8_t **) m_frame->data, m_frame->nb_samples);
+- if (nb_samples < 0) {
+- SetError("Couldn't convert audio", ret);
+- return false;
+- }
+- *data = (const int16_t *) m_convert_buffer[0];
+- *size = nb_samples;
+- } else {
+- *data = (const int16_t *) m_frame->data[0];
+- *size = m_frame->nb_samples;
+- }
+- } else {
+- if (m_finished && m_converter) {
+- auto nb_samples = m_converter->Flush(m_convert_buffer, m_convert_buffer_nb_samples);
+- if (nb_samples < 0) {
+- SetError("Couldn't convert audio", ret);
+- return false;
+- } else if (nb_samples > 0) {
+- m_got_frame = 1;
+ *data = (const int16_t *) m_convert_buffer[0];
+ *size = nb_samples;
++ } else {
++ *data = (const int16_t *) m_frame->data[0];
++ *size = m_frame->nb_samples;
++ }
++ } else {
++ if (m_converter) {
++ if (IsFinished()) {
++ auto nb_samples = m_converter->Flush(m_convert_buffer, m_convert_buffer_nb_samples);
++ if (nb_samples < 0) {
++ SetError("Couldn't convert audio", ret);
++ return false;
++ } else if (nb_samples > 0) {
++ *data = (const int16_t *) m_convert_buffer[0];
++ *size = nb_samples;
++ }
++ }
+ }
+ }
+- }
+
+- return true;
++ return true;
++ }
+ }
+
+ inline void FFmpegAudioReader::SetError(const char *message, int errnum) {
+diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt
+index a2b517b..123e643 100644
+--- a/tests/CMakeLists.txt
++++ b/tests/CMakeLists.txt
+@@ -38,6 +38,12 @@ set(SRCS
+
+ if(BUILD_TOOLS)
+ set(SRCS ${SRCS} ../src/audio/ffmpeg_audio_reader_test.cpp)
++ include_directories(
++ ${FFMPEG_LIBAVFORMAT_INCLUDE_DIRS}
++ ${FFMPEG_LIBAVCODEC_INCLUDE_DIRS}
++ ${FFMPEG_LIBAVUTIL_INCLUDE_DIRS}
++ ${AUDIO_PROCESSOR_INCLUDE_DIRS}
++ )
+ link_libraries(fpcalc_libs)
+ endif()
+
+--
+2.38.1
+
+
diff --git a/srcpkgs/chromaprint/template b/srcpkgs/chromaprint/template
index 7ef7838949f3..1f7bbc70a22c 100644
--- a/srcpkgs/chromaprint/template
+++ b/srcpkgs/chromaprint/template
@@ -1,7 +1,7 @@
# Template file for 'chromaprint'
pkgname=chromaprint
version=1.5.1
-revision=1
+revision=2
build_style=cmake
configure_args="-DBUILD_TOOLS=ON"
make_check_target="check"
From a25f84beadcc55197ebe6f2993098618baa74728 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:46 -0400
Subject: [PATCH 026/140] chromium: revbump for ffmpeg-6.0
---
.../patches/chromium-93-ffmpeg-4.4.patch | 36 --------------
srcpkgs/chromium/patches/ffmpeg5.patch | 47 +++++++++++++++++++
srcpkgs/chromium/template | 2 +-
3 files changed, 48 insertions(+), 37 deletions(-)
delete mode 100644 srcpkgs/chromium/patches/chromium-93-ffmpeg-4.4.patch
create mode 100644 srcpkgs/chromium/patches/ffmpeg5.patch
diff --git a/srcpkgs/chromium/patches/chromium-93-ffmpeg-4.4.patch b/srcpkgs/chromium/patches/chromium-93-ffmpeg-4.4.patch
deleted file mode 100644
index f0ec736f98bc..000000000000
--- a/srcpkgs/chromium/patches/chromium-93-ffmpeg-4.4.patch
+++ /dev/null
@@ -1,36 +0,0 @@
-diff --git a/media/filters/ffmpeg_demuxer.cc b/media/filters/ffmpeg_demuxer.cc
-index ac4713b07268..492a9a37d096 100644
---- a/media/filters/ffmpeg_demuxer.cc
-+++ b/media/filters/ffmpeg_demuxer.cc
-@@ -427,11 +427,11 @@ void FFmpegDemuxerStream::EnqueuePacket(ScopedAVPacket packet) {
- scoped_refptr<DecoderBuffer> buffer;
-
- if (type() == DemuxerStream::TEXT) {
-- size_t id_size = 0;
-+ int id_size = 0;
- uint8_t* id_data = av_packet_get_side_data(
- packet.get(), AV_PKT_DATA_WEBVTT_IDENTIFIER, &id_size);
-
-- size_t settings_size = 0;
-+ int settings_size = 0;
- uint8_t* settings_data = av_packet_get_side_data(
- packet.get(), AV_PKT_DATA_WEBVTT_SETTINGS, &settings_size);
-
-@@ -443,7 +443,7 @@ void FFmpegDemuxerStream::EnqueuePacket(ScopedAVPacket packet) {
- buffer = DecoderBuffer::CopyFrom(packet->data, packet->size,
- side_data.data(), side_data.size());
- } else {
-- size_t side_data_size = 0;
-+ int side_data_size = 0;
- uint8_t* side_data = av_packet_get_side_data(
- packet.get(), AV_PKT_DATA_MATROSKA_BLOCKADDITIONAL, &side_data_size);
-
-@@ -504,7 +504,7 @@ void FFmpegDemuxerStream::EnqueuePacket(ScopedAVPacket packet) {
- packet->size - data_offset);
- }
-
-- size_t skip_samples_size = 0;
-+ int skip_samples_size = 0;
- const uint32_t* skip_samples_ptr =
- reinterpret_cast<const uint32_t*>(av_packet_get_side_data(
- packet.get(), AV_PKT_DATA_SKIP_SAMPLES, &skip_samples_size));
diff --git a/srcpkgs/chromium/patches/ffmpeg5.patch b/srcpkgs/chromium/patches/ffmpeg5.patch
new file mode 100644
index 000000000000..24e2da38e34c
--- /dev/null
+++ b/srcpkgs/chromium/patches/ffmpeg5.patch
@@ -0,0 +1,47 @@
+--- a/media/filters/ffmpeg_demuxer.cc 2023-01-23 17:33:57.366213805 +0200
++++ b/media/filters/ffmpeg_demuxer.cc 2023-01-23 17:43:09.283436983 +0200
+@@ -92,24 +92,12 @@
+
+ static base::TimeDelta ExtractStartTime(AVStream* stream) {
+ // The default start time is zero.
+- base::TimeDelta start_time;
++ base::TimeDelta start_time = kNoTimestamp;
+
+ // First try to use the |start_time| value as is.
+- if (stream->start_time != kNoFFmpegTimestamp)
++ if (stream->start_time != kNoFFmpegTimestamp) // AV_NOPTS_VALUE
+ start_time = ConvertFromTimeBase(stream->time_base, stream->start_time);
+
+- // Next try to use the first DTS value, for codecs where we know PTS == DTS
+- // (excludes all H26x codecs). The start time must be returned in PTS.
+- if (av_stream_get_first_dts(stream) != kNoFFmpegTimestamp &&
+- stream->codecpar->codec_id != AV_CODEC_ID_HEVC &&
+- stream->codecpar->codec_id != AV_CODEC_ID_H264 &&
+- stream->codecpar->codec_id != AV_CODEC_ID_MPEG4) {
+- const base::TimeDelta first_pts =
+- ConvertFromTimeBase(stream->time_base, av_stream_get_first_dts(stream));
+- if (first_pts < start_time)
+- start_time = first_pts;
+- }
+-
+ return start_time;
+ }
+
+@@ -1597,7 +1585,7 @@
+ for (const auto& stream : streams_) {
+ if (!stream || stream->IsEnabled() != enabled)
+ continue;
+- if (av_stream_get_first_dts(stream->av_stream()) == kInvalidPTSMarker)
++ if (stream->av_stream()->start_time == AV_NOPTS_VALUE)
+ continue;
+ if (!lowest_start_time_stream ||
+ stream->start_time() < lowest_start_time_stream->start_time()) {
+@@ -1618,7 +1606,7 @@
+ if (stream->type() != DemuxerStream::VIDEO)
+ continue;
+
+- if (av_stream_get_first_dts(stream->av_stream()) == kInvalidPTSMarker)
++ if (stream->av_stream()->start_time == AV_NOPTS_VALUE)
+ continue;
+
+ if (!stream->IsEnabled())
diff --git a/srcpkgs/chromium/template b/srcpkgs/chromium/template
index e50c739d3ee7..8705f2ef973f 100644
--- a/srcpkgs/chromium/template
+++ b/srcpkgs/chromium/template
@@ -2,7 +2,7 @@
pkgname=chromium
# See https://chromiumdash.appspot.com/releases?platform=Linux for the latest version
version=112.0.5615.49
-revision=1
+revision=2
archs="i686* x86_64* aarch64* armv7l*"
hostmakedepends="
$(vopt_if clang "clang lld llvm15")
From 896ee3463a55901c7c6c1aac5258f8fa49e13295 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:46 -0400
Subject: [PATCH 027/140] cmus: revbump for ffmpeg-6.0
---
srcpkgs/cmus/patches/ffmpeg6.patch | 12 ++++++++++++
srcpkgs/cmus/template | 2 +-
2 files changed, 13 insertions(+), 1 deletion(-)
create mode 100644 srcpkgs/cmus/patches/ffmpeg6.patch
diff --git a/srcpkgs/cmus/patches/ffmpeg6.patch b/srcpkgs/cmus/patches/ffmpeg6.patch
new file mode 100644
index 000000000000..ffa95ab81110
--- /dev/null
+++ b/srcpkgs/cmus/patches/ffmpeg6.patch
@@ -0,0 +1,12 @@
+--- a/ip/ffmpeg.c
++++ b/ip/ffmpeg.c
+@@ -202,9 +202,6 @@ static int ffmpeg_open(struct input_plugin_data *ip_data)
+ break;
+ }
+
+- if (codec->capabilities & AV_CODEC_CAP_TRUNCATED)
+- cc->flags |= AV_CODEC_FLAG_TRUNCATED;
+-
+ if (avcodec_open2(cc, codec, NULL) < 0) {
+ d_print("could not open codec: %d, %s\n", cc->codec_id, avcodec_get_name(cc->codec_id));
+ err = -IP_ERROR_UNSUPPORTED_FILE_TYPE;
diff --git a/srcpkgs/cmus/template b/srcpkgs/cmus/template
index 0fcb424ce336..05b77d0fecae 100644
--- a/srcpkgs/cmus/template
+++ b/srcpkgs/cmus/template
@@ -1,7 +1,7 @@
# Template file for 'cmus'
pkgname=cmus
version=2.10.0
-revision=1
+revision=2
build_style=configure
configure_args="prefix=/usr LD=$CC"
hostmakedepends="pkg-config"
From 49941a66bd74a643b03290a573a7b181a61157f5 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:46 -0400
Subject: [PATCH 028/140] cyanrip: revbump for ffmpeg-6.0
---
srcpkgs/cyanrip/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/cyanrip/template b/srcpkgs/cyanrip/template
index 9796e3461601..5db30e020d17 100644
--- a/srcpkgs/cyanrip/template
+++ b/srcpkgs/cyanrip/template
@@ -1,7 +1,7 @@
# Template file for 'cyanrip'
pkgname=cyanrip
version=0.9.0
-revision=1
+revision=2
build_style=meson
hostmakedepends="pkg-config"
makedepends="ffmpeg-devel libcdio-devel libcdio-paranoia-devel libcurl-devel libmusicbrainz5-devel"
From cfe9a27590ddc6a5bb1b9e294d76f074ebb0cca0 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:46 -0400
Subject: [PATCH 029/140] deadbeef: revbump for ffmpeg4-4.4.3
---
srcpkgs/deadbeef/template | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/srcpkgs/deadbeef/template b/srcpkgs/deadbeef/template
index b664bb1b9bd9..165b3c7b9cad 100644
--- a/srcpkgs/deadbeef/template
+++ b/srcpkgs/deadbeef/template
@@ -1,14 +1,14 @@
# Template file for 'deadbeef'
pkgname=deadbeef
version=1.8.8
-revision=1
+revision=2
create_wrksrc=yes
build_style=gnu-configure
configure_args="--disable-oss --disable-lfm --disable-notify --disable-gtk2"
hostmakedepends="automake libtool gettext gettext-devel intltool pkg-config
yasm clang glib-devel"
makedepends="
- alsa-lib-devel dbus-devel faad2-devel ffmpeg-devel gtk+3-devel imlib2-devel
+ alsa-lib-devel dbus-devel faad2-devel ffmpeg4-devel gtk+3-devel imlib2-devel
jansson-devel libcddb-devel libcdio-devel libcurl-devel libflac-devel
libmad-devel libpng-devel libsamplerate-devel libsndfile-devel libvorbis-devel
libzip-devel mpg123-devel opusfile-devel pulseaudio-devel wavpack-devel"
From e0d905a5fac0324504370f59e9be401db7d5b3bb Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:46 -0400
Subject: [PATCH 030/140] dolphin-emu: revbump for ffmpeg-6.0
---
srcpkgs/dolphin-emu/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/dolphin-emu/template b/srcpkgs/dolphin-emu/template
index 7ea197ceb2a8..7aeb0a5b645e 100644
--- a/srcpkgs/dolphin-emu/template
+++ b/srcpkgs/dolphin-emu/template
@@ -1,7 +1,7 @@
# Template file for 'dolphin-emu'
pkgname=dolphin-emu
version=5.0.16101
-revision=1
+revision=2
_dolphin_commit=8ecfa537a242de74d2e372e30d9d79b14584b2fb
_mgba_commit=40d4c430fc36caeb7ea32fd39624947ed487d2f2
#Version/hash pair can be found at https://dolphin-emu.org/download/
From 7f368372b0a37992f33586451b27e680017caf64 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:46 -0400
Subject: [PATCH 031/140] droidcam-obs-plugin: revbump for ffmpeg-6.0
---
srcpkgs/droidcam-obs-plugin/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/droidcam-obs-plugin/template b/srcpkgs/droidcam-obs-plugin/template
index fc9c9bf6b9d5..fb0480754df4 100644
--- a/srcpkgs/droidcam-obs-plugin/template
+++ b/srcpkgs/droidcam-obs-plugin/template
@@ -1,7 +1,7 @@
# Template file for 'droidcam-obs-plugin'
pkgname=droidcam-obs-plugin
version=2.0.1
-revision=1
+revision=2
build_style=gnu-makefile
make_use_env=yes
make_build_args="ALLOW_STATIC=no"
From c1f67c71ba9baa4e302567e35821387bdf282fcb Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:46 -0400
Subject: [PATCH 032/140] droidcam: revbump for ffmpeg-6.0
---
srcpkgs/droidcam/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/droidcam/template b/srcpkgs/droidcam/template
index 1c3f1b8b1fc6..32a9220b79a4 100644
--- a/srcpkgs/droidcam/template
+++ b/srcpkgs/droidcam/template
@@ -1,7 +1,7 @@
# Template file for 'droidcam'
pkgname=droidcam
version=1.8.2
-revision=2
+revision=3
build_style=gnu-makefile
make_build_args="USBMUXD=-lusbmuxd-2.0 JPEG=-lturbojpeg"
hostmakedepends="pkg-config"
From c86d7439a778ef3ac904490276eb79f0771f53a4 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:46 -0400
Subject: [PATCH 033/140] electron19: revbump for ffmpeg-6.0
---
srcpkgs/electron19/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/electron19/template b/srcpkgs/electron19/template
index 068136be7623..32ce301e730c 100644
--- a/srcpkgs/electron19/template
+++ b/srcpkgs/electron19/template
@@ -1,7 +1,7 @@
# Template file for 'electron19'
pkgname=electron19
version=19.0.8
-revision=2
+revision=3
_nodever=16.14.2
_chromiumver=102.0.5005.125
archs="x86_64* aarch64* ppc64le*"
From 0e91a31d5e892b8d03857bbc0769be09314be4c2 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:47 -0400
Subject: [PATCH 034/140] ffmpegthumbnailer: revbump for ffmpeg4-4.4.3
---
srcpkgs/ffmpegthumbnailer/template | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/srcpkgs/ffmpegthumbnailer/template b/srcpkgs/ffmpegthumbnailer/template
index 039eea7622b3..8546bef3e868 100644
--- a/srcpkgs/ffmpegthumbnailer/template
+++ b/srcpkgs/ffmpegthumbnailer/template
@@ -1,16 +1,16 @@
# Template file for 'ffmpegthumbnailer'
pkgname=ffmpegthumbnailer
version=2.2.2
-revision=1
+revision=2
build_style=cmake
hostmakedepends="pkg-config"
-makedepends="libpng-devel libjpeg-turbo-devel ffmpeg-devel"
-depends="ffmpeg"
+makedepends="libpng-devel libjpeg-turbo-devel ffmpeg4-devel"
+depends="ffmpeg4"
short_desc="Lightweight video thumbnailer"
maintainer="Orphaned <orphan@voidlinux.org>"
license="GPL-2.0-or-later"
-homepage="https://github.com/dirkvdb/${pkgname}"
-distfiles="${homepage}/releases/download/${version}/${pkgname}-${version}.tar.bz2"
+homepage="https://github.com/dirkvdb"
+distfiles="${homepage}/${pkgname}/releases/download/${version}/${pkgname}-${version}.tar.bz2"
checksum=1cb24059c38223f657b300c84dd80491b7040d4b69471c4fea69be862bc99b5b
post_install() {
From b398f64c5d68da8602a69df88ff41f0d1fbaeeec Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:47 -0400
Subject: [PATCH 035/140] ffmpegthumbs: revbump for ffmpeg4-4.4.3
---
srcpkgs/ffmpegthumbs/template | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/srcpkgs/ffmpegthumbs/template b/srcpkgs/ffmpegthumbs/template
index 5f0b9414dada..944a78fbc96c 100644
--- a/srcpkgs/ffmpegthumbs/template
+++ b/srcpkgs/ffmpegthumbs/template
@@ -1,11 +1,11 @@
# Template file for 'ffmpegthumbs'
pkgname=ffmpegthumbs
version=22.12.1
-revision=1
+revision=2
build_style=cmake
hostmakedepends="extra-cmake-modules kcoreaddons kconfig-devel
pkg-config qt5-host-tools qt5-qmake gettext"
-makedepends="qt5-devel kio-devel ffmpeg-devel taglib-devel"
+makedepends="qt5-devel kio-devel ffmpeg4-devel taglib-devel"
short_desc="FFmpeg-based thumbnail creator for video files"
maintainer="Michael Straube <straubem@gmx.de>"
license="GPL-2.0-or-later"
From b15f02b9b062bacc8822f960111d558f1db98500 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:47 -0400
Subject: [PATCH 036/140] ffms2: revbump for ffmpeg-6.0
---
srcpkgs/ffms2/patches/ffmpeg5.patch | 424 ++++++++++++++++++++++++++++
srcpkgs/ffms2/template | 2 +-
2 files changed, 425 insertions(+), 1 deletion(-)
create mode 100644 srcpkgs/ffms2/patches/ffmpeg5.patch
diff --git a/srcpkgs/ffms2/patches/ffmpeg5.patch b/srcpkgs/ffms2/patches/ffmpeg5.patch
new file mode 100644
index 000000000000..1479fabcafcb
--- /dev/null
+++ b/srcpkgs/ffms2/patches/ffmpeg5.patch
@@ -0,0 +1,424 @@
+From 45673149e9a2f5586855ad472e3059084eaa36b1 Mon Sep 17 00:00:00 2001
+From: Derek Buitenhuis <derek.buitenhuis@gmail.com>
+Date: Tue, 4 May 2021 14:41:21 +0100
+Subject: [PATCH] Use auto for AVCodec
+
+The geniuses over at FFmpeg decided to constify this API, so old
+versions of the library will return AVCodec *, while new versions
+of the libary will return const AVCodec *, which, in C++, are not
+OK to convert between.
+
+Rather than use some macro hell in ffmscompat.h, we can work around
+this by using auto.
+
+Gross.
+
+Signed-off-by: Derek Buitenhuis <derek.buitenhuis@gmail.com>
+---
+ src/core/audiosource.cpp | 2 +-
+ src/core/indexing.cpp | 6 +++---
+ src/core/videosource.cpp | 2 +-
+ 3 files changed, 5 insertions(+), 5 deletions(-)
+
+diff --git a/src/core/audiosource.cpp b/src/core/audiosource.cpp
+index e4ce97c..ac09666 100644
+--- a/src/core/audiosource.cpp
++++ b/src/core/audiosource.cpp
+@@ -469,7 +469,7 @@ void FFMS_AudioSource::OpenFile() {
+
+ LAVFOpenFile(SourceFile.c_str(), FormatContext, TrackNumber);
+
+- AVCodec *Codec = avcodec_find_decoder(FormatContext->streams[TrackNumber]->codecpar->codec_id);
++ auto *Codec = avcodec_find_decoder(FormatContext->streams[TrackNumber]->codecpar->codec_id);
+ if (Codec == nullptr)
+ throw FFMS_Exception(FFMS_ERROR_DECODING, FFMS_ERROR_CODEC,
+ "Audio codec not found");
+diff --git a/src/core/indexing.cpp b/src/core/indexing.cpp
+index e547c5a..59fb4e8 100644
+--- a/src/core/indexing.cpp
++++ b/src/core/indexing.cpp
+@@ -384,7 +384,7 @@ FFMS_TrackType FFMS_Indexer::GetTrackType(int Track) {
+ }
+
+ const char *FFMS_Indexer::GetTrackCodec(int Track) {
+- AVCodec *codec = avcodec_find_decoder(FormatContext->streams[Track]->codecpar->codec_id);
++ auto *codec = avcodec_find_decoder(FormatContext->streams[Track]->codecpar->codec_id);
+ return codec ? codec->name : nullptr;
+ }
+
+@@ -402,7 +402,7 @@ FFMS_Index *FFMS_Indexer::DoIndexing() {
+ UseDTS);
+
+ if (IndexMask.count(i) && FormatContext->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
+- AVCodec *VideoCodec = avcodec_find_decoder(FormatContext->streams[i]->codecpar->codec_id);
++ auto *VideoCodec = avcodec_find_decoder(FormatContext->streams[i]->codecpar->codec_id);
+ if (!VideoCodec) {
+ FormatContext->streams[i]->discard = AVDISCARD_ALL;
+ IndexMask.erase(i);
+@@ -433,7 +433,7 @@ FFMS_Index *FFMS_Indexer::DoIndexing() {
+ IndexMask.insert(i);
+ }
+ } else if (IndexMask.count(i) && FormatContext->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) {
+- AVCodec *AudioCodec = avcodec_find_decoder(FormatContext->streams[i]->codecpar->codec_id);
++ auto *AudioCodec = avcodec_find_decoder(FormatContext->streams[i]->codecpar->codec_id);
+ if (AudioCodec == nullptr)
+ throw FFMS_Exception(FFMS_ERROR_CODEC, FFMS_ERROR_UNSUPPORTED,
+ "Audio codec not found");
+diff --git a/src/core/videosource.cpp b/src/core/videosource.cpp
+index b889970..8956c22 100644
+--- a/src/core/videosource.cpp
++++ b/src/core/videosource.cpp
+@@ -171,7 +171,7 @@ FFMS_VideoSource::FFMS_VideoSource(const char *SourceFile, FFMS_Index &Index, in
+
+ LAVFOpenFile(SourceFile, FormatContext, VideoTrack);
+
+- AVCodec *Codec = avcodec_find_decoder(FormatContext->streams[VideoTrack]->codecpar->codec_id);
++ auto *Codec = avcodec_find_decoder(FormatContext->streams[VideoTrack]->codecpar->codec_id);
+ if (Codec == nullptr)
+ throw FFMS_Exception(FFMS_ERROR_DECODING, FFMS_ERROR_CODEC,
+ "Video codec not found");
+--
+2.40.0
+
+From 96cbf38ea9381829a1314f432a2c60495dcefaad Mon Sep 17 00:00:00 2001
+From: Derek Buitenhuis <derek.buitenhuis@gmail.com>
+Date: Tue, 4 May 2021 14:12:41 +0100
+Subject: [PATCH] all: Update AVPacket API usage
+
+AVPackets must all be on the heap now, since it is no longer
+part of the libav* ABI.
+
+Signed-off-by: Derek Buitenhuis <derek.buitenhuis@gmail.com>
+---
+ src/core/audiosource.cpp | 16 ++++++----
+ src/core/indexing.cpp | 63 ++++++++++++++++++++++------------------
+ src/core/indexing.h | 4 +--
+ src/core/utils.cpp | 6 ----
+ src/core/utils.h | 1 -
+ src/core/videosource.cpp | 30 ++++++++++---------
+ 6 files changed, 64 insertions(+), 56 deletions(-)
+
+diff --git a/src/core/audiosource.cpp b/src/core/audiosource.cpp
+index 37cf9ae..e4ce97c 100644
+--- a/src/core/audiosource.cpp
++++ b/src/core/audiosource.cpp
+@@ -285,10 +285,15 @@ FFMS_AudioSource::AudioBlock *FFMS_AudioSource::CacheBlock(CacheIterator &pos) {
+ int FFMS_AudioSource::DecodeNextBlock(CacheIterator *pos) {
+ CurrentFrame = &Frames[PacketNumber];
+
+- AVPacket Packet;
+- if (!ReadPacket(&Packet))
++ AVPacket *Packet = av_packet_alloc();
++ if (!Packet)
++ throw FFMS_Exception(FFMS_ERROR_PARSER, FFMS_ERROR_ALLOCATION_FAILED,
++ "Could not allocate packet.");
++ if (!ReadPacket(Packet)) {
++ av_packet_free(&Packet);
+ throw FFMS_Exception(FFMS_ERROR_PARSER, FFMS_ERROR_UNKNOWN,
+ "ReadPacket unexpectedly failed to read a packet");
++ }
+
+ // ReadPacket may have changed the packet number
+ CurrentFrame = &Frames[PacketNumber];
+@@ -297,8 +302,9 @@ int FFMS_AudioSource::DecodeNextBlock(CacheIterator *pos) {
+ int NumberOfSamples = 0;
+ AudioBlock *CachedBlock = nullptr;
+
+- int Ret = avcodec_send_packet(CodecContext, &Packet);
+- av_packet_unref(&Packet);
++ int Ret = avcodec_send_packet(CodecContext, Packet);
++ av_packet_unref(Packet);
++ av_packet_free(&Packet);
+
+ av_frame_unref(DecodeFrame);
+ Ret = avcodec_receive_frame(CodecContext, DecodeFrame);
+@@ -513,8 +519,6 @@ void FFMS_AudioSource::Seek() {
+ }
+
+ bool FFMS_AudioSource::ReadPacket(AVPacket *Packet) {
+- InitNullPacket(*Packet);
+-
+ while (av_read_frame(FormatContext, Packet) >= 0) {
+ if (Packet->stream_index == TrackNumber) {
+ // Required because not all audio packets, especially in ogg, have a pts. Use the previous valid packet's pts instead.
+diff --git a/src/core/indexing.cpp b/src/core/indexing.cpp
+index 23fb95b..e547c5a 100644
+--- a/src/core/indexing.cpp
++++ b/src/core/indexing.cpp
+@@ -320,7 +320,7 @@ void FFMS_Indexer::CheckAudioProperties(int Track, AVCodecContext *Context) {
+ }
+ }
+
+-void FFMS_Indexer::ParseVideoPacket(SharedAVContext &VideoContext, AVPacket &pkt, int *RepeatPict,
++void FFMS_Indexer::ParseVideoPacket(SharedAVContext &VideoContext, AVPacket *pkt, int *RepeatPict,
+ int *FrameType, bool *Invisible, enum AVPictureStructure *LastPicStruct) {
+ if (VideoContext.Parser) {
+ uint8_t *OB;
+@@ -330,8 +330,8 @@ void FFMS_Indexer::ParseVideoPacket(SharedAVContext &VideoContext, AVPacket &pkt
+ av_parser_parse2(VideoContext.Parser,
+ VideoContext.CodecContext,
+ &OB, &OBSize,
+- pkt.data, pkt.size,
+- pkt.pts, pkt.dts, pkt.pos);
++ pkt->data, pkt->size,
++ pkt->pts, pkt->dts, pkt->pos);
+
+ // H.264 (PAFF) and HEVC may have one field per packet, so we need to track
+ // when we have a full or half frame available, and mark one of them as
+@@ -351,15 +351,15 @@ void FFMS_Indexer::ParseVideoPacket(SharedAVContext &VideoContext, AVPacket &pkt
+
+ *RepeatPict = VideoContext.Parser->repeat_pict;
+ *FrameType = VideoContext.Parser->pict_type;
+- *Invisible = (IncompleteFrame || VideoContext.Parser->repeat_pict < 0 || (pkt.flags & AV_PKT_FLAG_DISCARD));
++ *Invisible = (IncompleteFrame || VideoContext.Parser->repeat_pict < 0 || (pkt->flags & AV_PKT_FLAG_DISCARD));
+ } else {
+- *Invisible = !!(pkt.flags & AV_PKT_FLAG_DISCARD);
++ *Invisible = !!(pkt->flags & AV_PKT_FLAG_DISCARD);
+ }
+
+ if (VideoContext.CodecContext->codec_id == AV_CODEC_ID_VP8)
+- ParseVP8(pkt.data[0], Invisible, FrameType);
++ ParseVP8(pkt->data[0], Invisible, FrameType);
+ else if (VideoContext.CodecContext->codec_id == AV_CODEC_ID_VP9)
+- ParseVP9(pkt.data[0], Invisible, FrameType);
++ ParseVP9(pkt->data[0], Invisible, FrameType);
+ }
+
+ void FFMS_Indexer::Free() {
+@@ -458,32 +458,36 @@ FFMS_Index *FFMS_Indexer::DoIndexing() {
+ }
+ }
+
+- AVPacket Packet;
+- InitNullPacket(Packet);
++ AVPacket *Packet = av_packet_alloc();
++ if (!Packet)
++ throw FFMS_Exception(FFMS_ERROR_CODEC, FFMS_ERROR_ALLOCATION_FAILED,
++ "Could not allocate packet.");
+ std::vector<int64_t> LastValidTS(FormatContext->nb_streams, AV_NOPTS_VALUE);
+
+ int64_t filesize = avio_size(FormatContext->pb);
+ enum AVPictureStructure LastPicStruct = AV_PICTURE_STRUCTURE_UNKNOWN;
+- while (av_read_frame(FormatContext, &Packet) >= 0) {
++ while (av_read_frame(FormatContext, Packet) >= 0) {
+ // Update progress
+ // FormatContext->pb can apparently be NULL when opening images.
+ if (IC && FormatContext->pb) {
+- if ((*IC)(FormatContext->pb->pos, filesize, ICPrivate))
++ if ((*IC)(FormatContext->pb->pos, filesize, ICPrivate)) {
++ av_packet_free(&Packet);
+ throw FFMS_Exception(FFMS_ERROR_CANCELLED, FFMS_ERROR_USER,
+ "Cancelled by user");
++ }
+ }
+- if (!IndexMask.count(Packet.stream_index)) {
+- av_packet_unref(&Packet);
++ if (!IndexMask.count(Packet->stream_index)) {
++ av_packet_unref(Packet);
+ continue;
+ }
+
+- int Track = Packet.stream_index;
++ int Track = Packet->stream_index;
+ FFMS_Track &TrackInfo = (*TrackIndices)[Track];
+- bool KeyFrame = !!(Packet.flags & AV_PKT_FLAG_KEY);
++ bool KeyFrame = !!(Packet->flags & AV_PKT_FLAG_KEY);
+ ReadTS(Packet, LastValidTS[Track], (*TrackIndices)[Track].UseDTS);
+
+ if (FormatContext->streams[Track]->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
+- int64_t PTS = TrackInfo.UseDTS ? Packet.dts : Packet.pts;
++ int64_t PTS = TrackInfo.UseDTS ? Packet->dts : Packet->pts;
+ if (PTS == AV_NOPTS_VALUE) {
+ // VPx alt-refs are output as packets which lack timestmps or durations, since
+ // they are invisible. Currently, the timestamp mangling code in libavformat
+@@ -495,9 +499,11 @@ FFMS_Index *FFMS_Indexer::DoIndexing() {
+ // FFMS2 currently sorts packets by PTS, which will break decoding, otherwise.
+ bool HasAltRefs = (FormatContext->streams[Track]->codecpar->codec_id == AV_CODEC_ID_VP8 ||
+ FormatContext->streams[Track]->codecpar->codec_id == AV_CODEC_ID_VP9);
+- if (Packet.duration == 0 && !HasAltRefs)
++ if (Packet->duration == 0 && !HasAltRefs) {
++ av_packet_free(&Packet);
+ throw FFMS_Exception(FFMS_ERROR_INDEXING, FFMS_ERROR_PARSER,
+ "Invalid packet pts, dts, and duration");
++ }
+
+ if (TrackInfo.empty())
+ PTS = 0;
+@@ -513,7 +519,7 @@ FFMS_Index *FFMS_Indexer::DoIndexing() {
+ ParseVideoPacket(AVContexts[Track], Packet, &RepeatPict, &FrameType, &Invisible, &LastPicStruct);
+
+ TrackInfo.AddVideoFrame(PTS, RepeatPict, KeyFrame,
+- FrameType, Packet.pos, Invisible);
++ FrameType, Packet->pos, Invisible);
+ } else if (FormatContext->streams[Track]->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) {
+ // For video seeking timestamps are used only if all packets have
+ // timestamps, while for audio they're used if any have timestamps,
+@@ -522,28 +528,29 @@ FFMS_Index *FFMS_Indexer::DoIndexing() {
+ TrackInfo.HasTS = true;
+
+ int64_t StartSample = AVContexts[Track].CurrentSample;
+- uint32_t SampleCount = IndexAudioPacket(Track, &Packet, AVContexts[Track], *TrackIndices);
++ uint32_t SampleCount = IndexAudioPacket(Track, Packet, AVContexts[Track], *TrackIndices);
+ TrackInfo.SampleRate = AVContexts[Track].CodecContext->sample_rate;
+
+ TrackInfo.AddAudioFrame(LastValidTS[Track],
+- StartSample, SampleCount, KeyFrame, Packet.pos, Packet.flags & AV_PKT_FLAG_DISCARD);
++ StartSample, SampleCount, KeyFrame, Packet->pos, Packet->flags & AV_PKT_FLAG_DISCARD);
+ }
+
+- if (!(Packet.flags & AV_PKT_FLAG_DISCARD))
+- TrackInfo.LastDuration = Packet.duration;
++ if (!(Packet->flags & AV_PKT_FLAG_DISCARD))
++ TrackInfo.LastDuration = Packet->duration;
+
+- av_packet_unref(&Packet);
++ av_packet_unref(Packet);
+ }
++ av_packet_free(&Packet);
+
+ TrackIndices->Finalize(AVContexts, FormatContext->iformat->name);
+ return TrackIndices.release();
+ }
+
+-void FFMS_Indexer::ReadTS(const AVPacket &Packet, int64_t &TS, bool &UseDTS) {
+- if (!UseDTS && Packet.pts != AV_NOPTS_VALUE)
+- TS = Packet.pts;
++void FFMS_Indexer::ReadTS(const AVPacket *Packet, int64_t &TS, bool &UseDTS) {
++ if (!UseDTS && Packet->pts != AV_NOPTS_VALUE)
++ TS = Packet->pts;
+ if (TS == AV_NOPTS_VALUE)
+ UseDTS = true;
+- if (UseDTS && Packet.dts != AV_NOPTS_VALUE)
+- TS = Packet.dts;
++ if (UseDTS && Packet->dts != AV_NOPTS_VALUE)
++ TS = Packet->dts;
+ }
+diff --git a/src/core/indexing.h b/src/core/indexing.h
+index 3cfc3c3..5c06868 100644
+--- a/src/core/indexing.h
++++ b/src/core/indexing.h
+@@ -80,10 +80,10 @@ private:
+ int64_t Filesize;
+ uint8_t Digest[20];
+
+- void ReadTS(const AVPacket &Packet, int64_t &TS, bool &UseDTS);
++ void ReadTS(const AVPacket *Packet, int64_t &TS, bool &UseDTS);
+ void CheckAudioProperties(int Track, AVCodecContext *Context);
+ uint32_t IndexAudioPacket(int Track, AVPacket *Packet, SharedAVContext &Context, FFMS_Index &TrackIndices);
+- void ParseVideoPacket(SharedAVContext &VideoContext, AVPacket &pkt, int *RepeatPict, int *FrameType, bool *Invisible, enum AVPictureStructure *LastPicStruct);
++ void ParseVideoPacket(SharedAVContext &VideoContext, AVPacket *pkt, int *RepeatPict, int *FrameType, bool *Invisible, enum AVPictureStructure *LastPicStruct);
+ void Free();
+ public:
+ FFMS_Indexer(const char *Filename);
+diff --git a/src/core/utils.cpp b/src/core/utils.cpp
+index ce67533..8a2e997 100644
+--- a/src/core/utils.cpp
++++ b/src/core/utils.cpp
+@@ -62,12 +62,6 @@ void ClearErrorInfo(FFMS_ErrorInfo *ErrorInfo) {
+ }
+ }
+
+-void InitNullPacket(AVPacket &pkt) {
+- av_init_packet(&pkt);
+- pkt.data = nullptr;
+- pkt.size = 0;
+-}
+-
+ void FillAP(FFMS_AudioProperties &AP, AVCodecContext *CTX, FFMS_Track &Frames) {
+ AP.SampleFormat = static_cast<FFMS_SampleFormat>(av_get_packed_sample_fmt(CTX->sample_fmt));
+ AP.BitsPerSample = av_get_bytes_per_sample(CTX->sample_fmt) * 8;
+diff --git a/src/core/utils.h b/src/core/utils.h
+index 9819dc7..003ab79 100644
+--- a/src/core/utils.h
++++ b/src/core/utils.h
+@@ -58,7 +58,6 @@ std::unique_ptr<T> make_unique(Args&&... args) {
+ }
+
+ void ClearErrorInfo(FFMS_ErrorInfo *ErrorInfo);
+-void InitNullPacket(AVPacket &pkt);
+ void FillAP(FFMS_AudioProperties &AP, AVCodecContext *CTX, FFMS_Track &Frames);
+
+ void LAVFOpenFile(const char *SourceFile, AVFormatContext *&FormatContext, int Track);
+diff --git a/src/core/videosource.cpp b/src/core/videosource.cpp
+index 06bd161..b889970 100644
+--- a/src/core/videosource.cpp
++++ b/src/core/videosource.cpp
+@@ -673,30 +673,34 @@ void FFMS_VideoSource::DecodeNextFrame(int64_t &AStartTime, int64_t &Pos) {
+ if (HasPendingDelayedFrames())
+ return;
+
+- AVPacket Packet;
+- InitNullPacket(Packet);
+-
+- while (ReadFrame(&Packet) >= 0) {
+- if (Packet.stream_index != VideoTrack) {
+- av_packet_unref(&Packet);
++ AVPacket *Packet = av_packet_alloc();
++ if (!Packet)
++ throw FFMS_Exception(FFMS_ERROR_DECODING, FFMS_ERROR_ALLOCATION_FAILED,
++ "Could not allocate packet.");
++
++ while (ReadFrame(Packet) >= 0) {
++ if (Packet->stream_index != VideoTrack) {
++ av_packet_unref(Packet);
+ continue;
+ }
+
+ if (AStartTime < 0)
+- AStartTime = Frames.UseDTS ? Packet.dts : Packet.pts;
++ AStartTime = Frames.UseDTS ? Packet->dts : Packet->pts;
+
+ if (Pos < 0)
+- Pos = Packet.pos;
++ Pos = Packet->pos;
+
+- bool FrameFinished = DecodePacket(&Packet);
+- av_packet_unref(&Packet);
+- if (FrameFinished)
++ bool FrameFinished = DecodePacket(Packet);
++ av_packet_unref(Packet);
++ if (FrameFinished) {
++ av_packet_free(&Packet);
+ return;
++ }
+ }
+
+ // Flush final frames
+- InitNullPacket(Packet);
+- DecodePacket(&Packet);
++ DecodePacket(Packet);
++ av_packet_free(&Packet);
+ }
+
+ bool FFMS_VideoSource::SeekTo(int n, int SeekOffset) {
+--
+2.40.0
+
+From bf9e03e9e08534c024e5a744a6437c4aac160201 Mon Sep 17 00:00:00 2001
+From: Derek Buitenhuis <derek.buitenhuis@gmail.com>
+Date: Tue, 4 May 2021 14:20:47 +0100
+Subject: [PATCH 2/3] configure: Remove deprecated API use
+
+Signed-off-by: Derek Buitenhuis <derek.buitenhuis@gmail.com>
+---
+ configure.ac | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/configure.ac b/configure.ac
+index b35ef80bc..d19714d0f 100644
+--- a/configure.ac
++++ b/configure.ac
+@@ -102,10 +102,10 @@ CFLAGS="$_CFLAGS $FFMPEG_CFLAGS"
+
+ AC_DEFUN([TEST_FFMPEG],
+ [AC_LINK_IFELSE([AC_LANG_PROGRAM([[
+- #include <libavcodec/avcodec.h>
++ #include <libavformat/avformat.h>
+ #include <libswscale/swscale.h>
+ ]],[[
+- avcodec_register_all();
++ avformat_network_init();
+ swscale_version();
+ ]])], [eval $1=yes], [eval $1=no])
+ ])
+
diff --git a/srcpkgs/ffms2/template b/srcpkgs/ffms2/template
index 68e8a0c14bce..2acfadac44b3 100644
--- a/srcpkgs/ffms2/template
+++ b/srcpkgs/ffms2/template
@@ -1,7 +1,7 @@
# Template file for 'ffms2'
pkgname=ffms2
version=2.40
-revision=1
+revision=2
build_style=gnu-configure
configure_args="--enable-shared --disable-static"
hostmakedepends="pkg-config autoconf automake libtool"
From f8ba7182faafc779e42cdee475f3cdd8e0f97373 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:47 -0400
Subject: [PATCH 037/140] freerdp: revbump for ffmpeg-6.0
---
.../freerdp/patches/ffmpeg6_aa2cb9aa.patch | 42 +++++++++++++++++++
srcpkgs/freerdp/template | 2 +-
2 files changed, 43 insertions(+), 1 deletion(-)
create mode 100644 srcpkgs/freerdp/patches/ffmpeg6_aa2cb9aa.patch
diff --git a/srcpkgs/freerdp/patches/ffmpeg6_aa2cb9aa.patch b/srcpkgs/freerdp/patches/ffmpeg6_aa2cb9aa.patch
new file mode 100644
index 000000000000..a4324da3a882
--- /dev/null
+++ b/srcpkgs/freerdp/patches/ffmpeg6_aa2cb9aa.patch
@@ -0,0 +1,42 @@
+From aa2cb9aa5ff5562433598ba168a466e0752bca0e Mon Sep 17 00:00:00 2001
+From: akallabeth <akallabeth@posteo.net>
+Date: Tue, 14 Feb 2023 07:48:54 +0100
+Subject: [PATCH] Fixed #8686: Update h264 to use new FFMPEG API
+
+---
+ channels/tsmf/client/ffmpeg/tsmf_ffmpeg.c | 2 ++
+ libfreerdp/codec/h264_ffmpeg.c | 2 ++
+ 2 files changed, 4 insertions(+)
+
+diff --git a/channels/tsmf/client/ffmpeg/tsmf_ffmpeg.c b/channels/tsmf/client/ffmpeg/tsmf_ffmpeg.c
+index 339462d865f..beea80b7a1e 100644
+--- a/channels/tsmf/client/ffmpeg/tsmf_ffmpeg.c
++++ b/channels/tsmf/client/ffmpeg/tsmf_ffmpeg.c
+@@ -239,8 +239,10 @@ static BOOL tsmf_ffmpeg_init_stream(ITSMFDecoder* decoder, const TS_AM_MEDIA_TYP
+ }
+ }
+
++#if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(59, 18, 100)
+ if (mdecoder->codec->capabilities & AV_CODEC_CAP_TRUNCATED)
+ mdecoder->codec_context->flags |= AV_CODEC_FLAG_TRUNCATED;
++#endif
+
+ return TRUE;
+ }
+diff --git a/libfreerdp/codec/h264_ffmpeg.c b/libfreerdp/codec/h264_ffmpeg.c
+index 8a23db2473c..896a333019b 100644
+--- a/libfreerdp/codec/h264_ffmpeg.c
++++ b/libfreerdp/codec/h264_ffmpeg.c
+@@ -615,10 +615,12 @@ static BOOL libavcodec_init(H264_CONTEXT* h264)
+ goto EXCEPTION;
+ }
+
++#if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(59, 18, 100)
+ if (sys->codecDecoder->capabilities & AV_CODEC_CAP_TRUNCATED)
+ {
+ sys->codecDecoderContext->flags |= AV_CODEC_FLAG_TRUNCATED;
+ }
++#endif
+
+ #ifdef WITH_VAAPI
+
diff --git a/srcpkgs/freerdp/template b/srcpkgs/freerdp/template
index 25e8aa9677f0..4d51c8189902 100644
--- a/srcpkgs/freerdp/template
+++ b/srcpkgs/freerdp/template
@@ -1,7 +1,7 @@
# Template file for 'freerdp'
pkgname=freerdp
version=2.10.0
-revision=1
+revision=2
build_style=cmake
configure_args="-DWITH_ALSA=ON -DWITH_CUPS=OFF -DWITH_FFMPEG=ON
-DWITH_GSTREAMER_0_10=OFF -DWITH_GSTREAMER_1_0=OFF -DWITH_JPEG=ON
From 8a1cda0bcf5c5b610e68541ae240384bb4a1136f Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:47 -0400
Subject: [PATCH 038/140] gerbera: revbump for ffmpeg-6.0
---
srcpkgs/gerbera/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/gerbera/template b/srcpkgs/gerbera/template
index ae14f35c767c..2dc0ac0ce03b 100644
--- a/srcpkgs/gerbera/template
+++ b/srcpkgs/gerbera/template
@@ -1,7 +1,7 @@
# Template file for 'gerbera'
pkgname=gerbera
version=1.12.1
-revision=1
+revision=2
build_style=cmake
configure_args="-DWITH_SYSTEMD=0 -DWITH_AVCODEC=1"
hostmakedepends="pkg-config"
From 8d5de4c9cf5b975fe58c6f191c6aeadb07ff9597 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:47 -0400
Subject: [PATCH 039/140] goldendict: revbump for ffmpeg-6.0
---
srcpkgs/goldendict/patches/ffmpeg4.patch | 21 --
srcpkgs/goldendict/patches/ffmpeg5.patch | 232 +++++++++++++++++++++++
srcpkgs/goldendict/template | 2 +-
3 files changed, 233 insertions(+), 22 deletions(-)
delete mode 100644 srcpkgs/goldendict/patches/ffmpeg4.patch
create mode 100644 srcpkgs/goldendict/patches/ffmpeg5.patch
diff --git a/srcpkgs/goldendict/patches/ffmpeg4.patch b/srcpkgs/goldendict/patches/ffmpeg4.patch
deleted file mode 100644
index f045fa27f54b..000000000000
--- a/srcpkgs/goldendict/patches/ffmpeg4.patch
+++ /dev/null
@@ -1,21 +0,0 @@
---- a/ffmpegaudio.cc.orig 2018-05-09 22:16:13.480659958 +0200
-+++ b/ffmpegaudio.cc 2018-05-09 22:16:50.748322790 +0200
-@@ -143,7 +143,7 @@
- return false;
- }
-
-- unsigned char * avioBuffer = ( unsigned char * )av_malloc( kBufferSize + FF_INPUT_BUFFER_PADDING_SIZE );
-+ unsigned char * avioBuffer = ( unsigned char * )av_malloc( kBufferSize + AV_INPUT_BUFFER_PADDING_SIZE );
- if ( !avioBuffer )
- {
- errorString = QObject::tr( "av_malloc() failed." );
-@@ -380,7 +380,7 @@
- }
-
- if ( !Qt4x5::AtomicInt::loadAcquire( isCancelled_ ) &&
-- codecContext_->codec->capabilities & CODEC_CAP_DELAY )
-+ codecContext_->codec->capabilities & AV_CODEC_CAP_DELAY )
- {
- av_init_packet( &packet );
- int gotFrame = 0;
-
diff --git a/srcpkgs/goldendict/patches/ffmpeg5.patch b/srcpkgs/goldendict/patches/ffmpeg5.patch
new file mode 100644
index 000000000000..7cfc98ada368
--- /dev/null
+++ b/srcpkgs/goldendict/patches/ffmpeg5.patch
@@ -0,0 +1,232 @@
+From 03bbe01b79a1f07a6780cb60f23a087104c5d77b Mon Sep 17 00:00:00 2001
+From: Abs62 <ottomann@yandex.ru>
+Date: Fri, 30 Mar 2018 22:53:24 +0300
+Subject: [PATCH] Fix warnings while compile with FFMpeg 3.4.2 (issue #978)
+
+---
+ ffmpegaudio.cc | 68 +++++++++++++++++++++++++++++++++++++++++++++-----
+ 1 file changed, 62 insertions(+), 6 deletions(-)
+
+diff --git a/ffmpegaudio.cc b/ffmpegaudio.cc
+index ed1172bdd..56e8f788e 100644
+--- a/ffmpegaudio.cc
++++ b/ffmpegaudio.cc
+@@ -91,6 +91,7 @@ struct DecoderContext
+ QByteArray audioData_;
+ QDataStream audioDataStream_;
+ AVFormatContext * formatContext_;
++ AVCodec * codec_;
+ AVCodecContext * codecContext_;
+ AVIOContext * avioContext_;
+ AVStream * audioStream_;
+@@ -114,6 +115,7 @@ DecoderContext::DecoderContext( QByteArray const & audioData, QAtomicInt & isCan
+ audioData_( audioData ),
+ audioDataStream_( audioData_ ),
+ formatContext_( NULL ),
++ codec_( NULL ),
+ codecContext_( NULL ),
+ avioContext_( NULL ),
+ audioStream_( NULL ),
+@@ -143,7 +145,11 @@ bool DecoderContext::openCodec( QString & errorString )
+ return false;
+ }
+
++#if LIBAVCODEC_VERSION_MAJOR < 56 || ( LIBAVCODEC_VERSION_MAJOR == 56 && LIBAVCODEC_VERSION_MINOR < 56 )
+ unsigned char * avioBuffer = ( unsigned char * )av_malloc( kBufferSize + FF_INPUT_BUFFER_PADDING_SIZE );
++#else
++ unsigned char * avioBuffer = ( unsigned char * )av_malloc( kBufferSize + AV_INPUT_BUFFER_PADDING_SIZE );
++#endif
+ if ( !avioBuffer )
+ {
+ errorString = QObject::tr( "av_malloc() failed." );
+@@ -186,7 +192,11 @@ bool DecoderContext::openCodec( QString & errorString )
+ // Find audio stream, use the first audio stream if available
+ for ( unsigned i = 0; i < formatContext_->nb_streams; i++ )
+ {
++#if LIBAVCODEC_VERSION_MAJOR < 57 || ( LIBAVCODEC_VERSION_MAJOR == 57 && LIBAVCODEC_VERSION_MINOR < 33 )
+ if ( formatContext_->streams[i]->codec->codec_type == AVMEDIA_TYPE_AUDIO )
++#else
++ if ( formatContext_->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_AUDIO )
++#endif
+ {
+ audioStream_ = formatContext_->streams[i];
+ break;
+@@ -198,22 +208,38 @@ bool DecoderContext::openCodec( QString & errorString )
+ return false;
+ }
+
++#if LIBAVCODEC_VERSION_MAJOR < 57 || ( LIBAVCODEC_VERSION_MAJOR == 57 && LIBAVCODEC_VERSION_MINOR < 33 )
+ codecContext_ = audioStream_->codec;
+- AVCodec * codec = avcodec_find_decoder( codecContext_->codec_id );
+- if ( !codec )
++ codec_ = avcodec_find_decoder( codecContext_->codec_id );
++ if ( !codec_ )
+ {
+ errorString = QObject::tr( "Codec [id: %1] not found." ).arg( codecContext_->codec_id );
+ return false;
+ }
++#else
++ codec_ = avcodec_find_decoder( audioStream_->codecpar->codec_id );
++ if ( !codec_ )
++ {
++ errorString = QObject::tr( "Codec [id: %1] not found." ).arg( audioStream_->codecpar->codec_id );
++ return false;
++ }
++ codecContext_ = avcodec_alloc_context3( codec_ );
++ if ( !codecContext_ )
++ {
++ errorString = QObject::tr( "avcodec_alloc_context3() failed." );
++ return false;
++ }
++ avcodec_parameters_to_context( codecContext_, audioStream_->codecpar );
++#endif
+
+- ret = avcodec_open2( codecContext_, codec, NULL );
++ ret = avcodec_open2( codecContext_, codec_, NULL );
+ if ( ret < 0 )
+ {
+ errorString = QObject::tr( "avcodec_open2() failed: %1." ).arg( avErrorString( ret ) );
+ return false;
+ }
+
+- av_log( NULL, AV_LOG_INFO, "Codec open: %s: channels: %d, rate: %d, format: %s\n", codec->long_name,
++ av_log( NULL, AV_LOG_INFO, "Codec open: %s: channels: %d, rate: %d, format: %s\n", codec_->long_name,
+ codecContext_->channels, codecContext_->sample_rate, av_get_sample_fmt_name( codecContext_->sample_fmt ) );
+ return true;
+ }
+@@ -252,10 +278,13 @@ void DecoderContext::closeCodec()
+
+ // Closing a codec context without prior avcodec_open2() will result in
+ // a crash in ffmpeg
+- if ( audioStream_ && audioStream_->codec && audioStream_->codec->codec )
++ if ( audioStream_ && codecContext_ && codec_ )
+ {
+ audioStream_->discard = AVDISCARD_ALL;
+- avcodec_close( audioStream_->codec );
++ avcodec_close( codecContext_ );
++#if LIBAVCODEC_VERSION_MAJOR > 57 || ( LIBAVCODEC_VERSION_MAJOR == 57 && LIBAVCODEC_VERSION_MINOR >= 33 )
++ avcodec_free_context( &codecContext_ );
++#endif
+ }
+
+ avformat_close_input( &formatContext_ );
+@@ -356,6 +385,7 @@ bool DecoderContext::play( QString & errorString )
+ if ( packet.stream_index == audioStream_->index )
+ {
+ AVPacket pack = packet;
++#if LIBAVCODEC_VERSION_MAJOR < 57 || ( LIBAVCODEC_VERSION_MAJOR == 57 && LIBAVCODEC_VERSION_MINOR < 37 )
+ int gotFrame = 0;
+ do
+ {
+@@ -370,6 +400,19 @@ bool DecoderContext::play( QString & errorString )
+ pack.data += len;
+ }
+ while( pack.size > 0 );
++#else
++ int ret = avcodec_send_packet( codecContext_, &pack );
++ /* read all the output frames (in general there may be any number of them) */
++ while( ret >= 0 )
++ {
++ ret = avcodec_receive_frame( codecContext_, frame);
++
++ if ( Qt4x5::AtomicInt::loadAcquire( isCancelled_ ) || ret < 0 )
++ break;
++
++ playFrame( frame );
++ }
++#endif
+ }
+ // av_free_packet() must be called after each call to av_read_frame()
+ #if LIBAVCODEC_VERSION_MAJOR < 57 || ( LIBAVCODEC_VERSION_MAJOR == 57 && LIBAVCODEC_VERSION_MINOR < 7 )
+@@ -379,6 +422,7 @@ bool DecoderContext::play( QString & errorString )
+ #endif
+ }
+
++#if LIBAVCODEC_VERSION_MAJOR < 57 || ( LIBAVCODEC_VERSION_MAJOR == 57 && LIBAVCODEC_VERSION_MINOR < 37 )
+ if ( !Qt4x5::AtomicInt::loadAcquire( isCancelled_ ) &&
+ codecContext_->codec->capabilities & CODEC_CAP_DELAY )
+ {
+@@ -391,6 +435,18 @@ bool DecoderContext::play( QString & errorString )
+ playFrame( frame );
+ }
+ }
++#else
++ /* flush the decoder */
++ av_init_packet( &packet );
++ int ret = avcodec_send_packet(codecContext_, &packet );
++ while( ret >= 0 )
++ {
++ ret = avcodec_receive_frame(codecContext_, frame);
++ if ( Qt4x5::AtomicInt::loadAcquire( isCancelled_ ) || ret < 0 )
++ break;
++ playFrame( frame );
++ }
++#endif
+
+ #if LIBAVCODEC_VERSION_MAJOR < 54
+ av_free( frame );
+32
+srcpkgs/goldendict/patches/ffmpeg5-2.patch
+Comment on this file
+@@ -0,0 +1,32 @@
+From 966f4a8b78e6324b930e5a50f2bb930bd87e565e Mon Sep 17 00:00:00 2001
+From: Abs62 <ottomann@yandex.ru>
+Date: Fri, 27 Sep 2019 17:00:52 +0300
+Subject: [PATCH] FFmpeg player: Fix some crashes on broken files
+
+---
+ ffmpegaudio.cc | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/ffmpegaudio.cc b/ffmpegaudio.cc
+index 56e8f788e..415fc79cb 100644
+--- a/ffmpegaudio.cc
++++ b/ffmpegaudio.cc
+@@ -51,7 +51,9 @@ AudioService & AudioService::instance()
+
+ AudioService::AudioService()
+ {
++#if LIBAVFORMAT_VERSION_MAJOR < 58 || ( LIBAVFORMAT_VERSION_MAJOR == 58 && LIBAVFORMAT_VERSION_MINOR < 9 )
+ av_register_all();
++#endif
+ ao_initialize();
+ }
+
+@@ -438,6 +440,8 @@ bool DecoderContext::play( QString & errorString )
+ #else
+ /* flush the decoder */
+ av_init_packet( &packet );
++ packet.data = NULL;
++ packet.size = 0;
+ int ret = avcodec_send_packet(codecContext_, &packet );
+ while( ret >= 0 )
+ {
+25
+srcpkgs/goldendict/patches/ffmpeg5-3.patch
+Comment on this file
+@@ -0,0 +1,25 @@
+From 8acb288c9e9bdb3c6bf2e803954dd3b6ac273c05 Mon Sep 17 00:00:00 2001
+From: Liao Junxuan <mikeljx@126.com>
+Date: Sun, 20 Feb 2022 12:28:05 +0800
+Subject: [PATCH] add support for ffmpeg 5.0
+
+---
+ ffmpegaudio.cc | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/ffmpegaudio.cc b/ffmpegaudio.cc
+index d550f4a77..7948d2187 100644
+--- a/ffmpegaudio.cc
++++ b/ffmpegaudio.cc
+@@ -94,7 +94,11 @@ struct DecoderContext
+ QByteArray audioData_;
+ QDataStream audioDataStream_;
+ AVFormatContext * formatContext_;
++#if LIBAVCODEC_VERSION_MAJOR < 59
+ AVCodec * codec_;
++#else
++ const AVCodec * codec_;
++#endif
+ AVCodecContext * codecContext_;
+ AVIOContext * avioContext_;
+ AVStream * audioStream_;
diff --git a/srcpkgs/goldendict/template b/srcpkgs/goldendict/template
index 4544ae710ee6..2ca4185e538a 100644
--- a/srcpkgs/goldendict/template
+++ b/srcpkgs/goldendict/template
@@ -9,7 +9,7 @@ makedepends="tiff-devel qt5-devel libvorbis-devel zlib-devel
libXtst-devel hunspell-devel qt5-tools-devel qt5-declarative-devel
qt5-webkit-devel lzo-devel bzip2-devel libao-devel qt5-svg-devel
libeb-devel qt5-x11extras-devel ffmpeg-devel liblzma-devel"
-short_desc="A feature-rich dictionary lookup program"
+short_desc="Feature-rich dictionary lookup program"
maintainer="John <me@johnnynator.dev>"
license="GPL-3.0-or-later"
homepage="http://goldendict.org/"
From 96aba07c75f8f26cc885e53581ae3c66dd189c9d Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:47 -0400
Subject: [PATCH 040/140] gst-libav: revbump for ffmpeg-6.0
---
srcpkgs/gst-libav/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/gst-libav/template b/srcpkgs/gst-libav/template
index e9a79dc650a5..f082bd211c65 100644
--- a/srcpkgs/gst-libav/template
+++ b/srcpkgs/gst-libav/template
@@ -1,7 +1,7 @@
# Template file for 'gst-libav'
pkgname=gst-libav
version=1.20.3
-revision=1
+revision=2
build_style=meson
hostmakedepends="pkg-config yasm"
makedepends="orc-devel gst-plugins-base1-devel ffmpeg-devel"
From edd46d846c94db43f01bf94f3a339e504cced676 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:47 -0400
Subject: [PATCH 041/140] gst-plugins-bad1: revbump for ffmpeg-6.0
---
srcpkgs/gst-plugins-bad1/template | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/srcpkgs/gst-plugins-bad1/template b/srcpkgs/gst-plugins-bad1/template
index f55f82fd4c77..5a9d5387e0d4 100644
--- a/srcpkgs/gst-plugins-bad1/template
+++ b/srcpkgs/gst-plugins-bad1/template
@@ -1,7 +1,7 @@
# Template file for 'gst-plugins-bad1'
pkgname=gst-plugins-bad1
-version=1.20.3
-revision=3
+version=1.22.1
+revision=2
build_helper="gir"
build_style=meson
configure_args="-Dpackage-origin=https://voidlinux.org -Ddoc=disabled
From 968f4008f3565a806b881a07649b3ca474bff6ca Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:47 -0400
Subject: [PATCH 042/140] gst-rtsp-server: revbump for ffmpeg-6.0
---
srcpkgs/gst-rtsp-server/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/gst-rtsp-server/template b/srcpkgs/gst-rtsp-server/template
index 33cd64ceb95e..8ceea8d34b4b 100644
--- a/srcpkgs/gst-rtsp-server/template
+++ b/srcpkgs/gst-rtsp-server/template
@@ -1,7 +1,7 @@
# Template file for 'gst-rtsp-server'
pkgname=gst-rtsp-server
version=1.20.3
-revision=2
+revision=3
build_style=meson
hostmakedepends="pkg-config python3"
makedepends="glib-devel gst-plugins-bad1-devel gobject-introspection
From 1f3930648b11bdcb3e2538ea2bacc0235364aacb Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:47 -0400
Subject: [PATCH 043/140] guvcview: update to 2.0.8.
---
srcpkgs/guvcview/patches/fix-include.patch | 10 ++++++++++
srcpkgs/guvcview/template | 5 ++---
2 files changed, 12 insertions(+), 3 deletions(-)
create mode 100644 srcpkgs/guvcview/patches/fix-include.patch
diff --git a/srcpkgs/guvcview/patches/fix-include.patch b/srcpkgs/guvcview/patches/fix-include.patch
new file mode 100644
index 000000000000..503c2af3b78c
--- /dev/null
+++ b/srcpkgs/guvcview/patches/fix-include.patch
@@ -0,0 +1,10 @@
+--- a/guvcview/guvcview.c
++++ b/guvcview/guvcview.c
+@@ -28,6 +28,7 @@
+ #include <sys/stat.h>
+ #include <sys/resource.h>
+ #include <errno.h>
++#include <locale.h>
+
+ #include "gview.h"
+ #include "gviewv4l2core.h"
diff --git a/srcpkgs/guvcview/template b/srcpkgs/guvcview/template
index 345cf6006f24..86a7fd619612 100644
--- a/srcpkgs/guvcview/template
+++ b/srcpkgs/guvcview/template
@@ -1,8 +1,7 @@
# Template file for 'guvcview'
pkgname=guvcview
-version=2.0.7
+version=2.0.8
revision=1
-create_wrksrc=yes
build_style=gnu-configure
configure_args="--disable-static --disable-debian-menu"
hostmakedepends="pkg-config intltool autoconf automake libtool glib-devel"
@@ -14,7 +13,7 @@ maintainer="Orphaned <orphan@voidlinux.org>"
license="GPL-3.0-or-later"
homepage="http://guvcview.sourceforge.net/"
distfiles="${SOURCEFORGE_SITE}/${pkgname}/${pkgname}-src-${version}.tar.bz2"
-checksum=f47d51fbd06e44eeaa1a82f4a153c927527c90d94514197a70b2956028cc8ad4
+checksum=a21f4e448286666cf27bafef5290cc953a0a1796b752e5bbe521266dc1230c81
post_patch() {
sed '31a#include <locale.h>' -i guvcview/guvcview.c
From 28aceac5ac8bd39db425db1484974f357fd8e2b7 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:48 -0400
Subject: [PATCH 044/140] handbrake: update to 1.6.1
---
.../patches/fix-missing-x265-link-flag.patch | 11 ++++++-----
.../handbrake/patches/libhb-vpl-include.patch | 15 +++++++++++++++
srcpkgs/handbrake/template | 18 +++++++++++-------
3 files changed, 32 insertions(+), 12 deletions(-)
create mode 100644 srcpkgs/handbrake/patches/libhb-vpl-include.patch
diff --git a/srcpkgs/handbrake/patches/fix-missing-x265-link-flag.patch b/srcpkgs/handbrake/patches/fix-missing-x265-link-flag.patch
index 26db03867a0c..d6bb2eda627a 100644
--- a/srcpkgs/handbrake/patches/fix-missing-x265-link-flag.patch
+++ b/srcpkgs/handbrake/patches/fix-missing-x265-link-flag.patch
@@ -1,14 +1,15 @@
--- a/gtk/configure.ac
+++ b/gtk/configure.ac
@@ -203,7 +203,7 @@
-
+
AM_CONDITIONAL([MINGW], [test "x$mingw_flag" = "xyes"])
-
--HB_LIBS="$HB_LIBS -lhandbrake -lavformat -lavfilter -lavcodec -lavutil -ldav1d -lswresample -lpostproc -ldvdnav -ldvdread -lmp3lame -lvorbis -lvorbisenc -logg -lswscale -ltheoraenc -ltheoradec -lvpx -lz -lbz2 -lbluray -lass -lfontconfig -lfreetype -lxml2 -ljansson -lopus -lspeex -lturbojpeg -llzma -lzimg"
-+HB_LIBS="$HB_LIBS -lhandbrake -lavformat -lavfilter -lavcodec -lavutil -ldav1d -lswresample -lpostproc -ldvdnav -ldvdread -lmp3lame -lvorbis -lvorbisenc -logg -lswscale -ltheoraenc -ltheoradec -lvpx -lz -lbz2 -lbluray -lass -lfontconfig -lfreetype -lxml2 -ljansson -lopus -lspeex -lturbojpeg -llzma -lzimg -ldl"
+
+-HB_LIBS="$HB_LIBS -lhandbrake -lavformat -lavfilter -lavcodec -lavutil -ldav1d -lswresample -lpostproc -ldvdnav -ldvdread -lmp3lame -lvorbis -lvorbisenc -logg -lswscale -ltheoraenc -ltheoradec -lvpx -lz -lbz2 -lbluray -lass -lfontconfig -lfreetype -lxml2 -ljansson -lopus -lspeex -lturbojpeg -llzma -lzimg -lSvtAv1Enc"
++HB_LIBS="$HB_LIBS -lhandbrake -lavformat -lavfilter -lavcodec -lavutil -ldav1d -lswresample -lpostproc -ldvdnav -ldvdread -lmp3lame -lvorbis -lvorbisenc -logg -lswscale -ltheoraenc -ltheoradec -lvpx -lz -lbz2 -lbluray -lass -lfontconfig -lfreetype -lxml2 -ljansson -lopus -lspeex -lturbojpeg -llzma -lzimg -lSvtAv1Enc -ldl"
HB_CPPFLAGS="$HB_CPPFLAGS $HBINC"
-
+
PKG_CHECK_MODULES([x264], [x264], sys_x264=yes, sys_x264=no)
+
--- a/test/module.defs
+++ b/test/module.defs
@@ -69,6 +69,9 @@
diff --git a/srcpkgs/handbrake/patches/libhb-vpl-include.patch b/srcpkgs/handbrake/patches/libhb-vpl-include.patch
new file mode 100644
index 000000000000..298f9f4ab28f
--- /dev/null
+++ b/srcpkgs/handbrake/patches/libhb-vpl-include.patch
@@ -0,0 +1,15 @@
+--- a/libhb/module.defs 2023-01-22 11:36:49.000000000 -0500
++++ b/libhb/module.defs 2023-04-03 22:37:52.395467010 -0400
+@@ -46,11 +46,7 @@
+ LIBHB.GCC.I += $(LIBHB.build/) $(CONTRIB.build/)include
+
+ ifeq (1,$(FEATURE.qsv))
+- ifeq ($(HOST.system),freebsd))
+- LIBHB.GCC.I += $(LOCALBASE)/include/vpl
+- else
+- LIBHB.GCC.I += $(CONTRIB.build/)include/vpl
+- endif
++ LIBHB.GCC.I += /usr/include/vpl
+ endif
+
+ ifneq (,$(filter $(HOST.system),freebsd netbsd openbsd))
diff --git a/srcpkgs/handbrake/template b/srcpkgs/handbrake/template
index ca5e4571e49c..3c2ab8659615 100644
--- a/srcpkgs/handbrake/template
+++ b/srcpkgs/handbrake/template
@@ -1,10 +1,11 @@
# Template file for 'handbrake'
pkgname=handbrake
-version=1.5.1
+version=1.6.1
revision=1
+wrksrc=HandBrake-${version}
build_style=gnu-configure
configure_args="--force --disable-gtk-update-checks --disable-df-fetch --harden
- $(vopt_enable fdk_aac fdk-aac) $(vopt_enable nvenc)"
+ $(vopt_enable fdk_aac fdk-aac) $(vopt_enable nvenc) $(vopt_enable qsv)"
make_build_args="-C ${XBPS_TRIPLET}"
make_install_args="-C ${XBPS_TRIPLET}"
hostmakedepends="automake cmake gettext-devel glib-devel intltool libtool m4 meson nasm pkg-config python3"
@@ -12,8 +13,11 @@ makedepends="bzip2-devel ffmpeg-devel gst-plugins-base1-devel gtk+3-devel
jansson-devel lame-devel libass-devel libbluray-devel libdav1d-devel
libdvdnav-devel libdvdread-devel libgudev-devel libnuma-devel
libsamplerate-devel libtheora-devel libvorbis-devel libvpx-devel libxml2-devel
- opus-devel speex-devel x264-devel x265-devel zimg-devel
+ opus-devel speex-devel x264-devel x265-devel zimg-devel libsvt-av1-devel
$(vopt_if fdk_aac fdk-aac-devel)
+ $(vopt_if qsv libva-devel)
+ $(vopt_if qsv libdrm-devel)
+ $(vopt_if qsv onevpl-devel)
$(vopt_if nvenc nv-codec-headers)"
depends="desktop-file-utils gst-plugins-good1 hicolor-icon-theme"
short_desc="Multithreaded video transcoder"
@@ -21,15 +25,15 @@ maintainer="Enno Boland <gottox@voidlinux.org>"
license="GPL-2.0-only"
homepage="https://handbrake.fr/"
distfiles="https://github.com/HandBrake/HandBrake/releases/download/${version}/HandBrake-${version}-source.tar.bz2"
-checksum=3999fe06d5309c819799a73a968a8ec3840e7840c2b64af8f5cdb7fd8c9430f0
+checksum=94ccfe03db917a91650000c510f7fd53f844da19f19ad4b4be1b8f6bc31a8d4c
nocross=yes
-build_options="fdk_aac nvenc"
+build_options="fdk_aac nvenc qsv"
case "$XBPS_TARGET_MACHINE" in
x86_64*|i686*)
CFLAGS="-msse"
- build_options_default="nvenc"
+ build_options_default="nvenc qsv"
;;
esac
@@ -37,7 +41,7 @@ pre_configure() {
# use system libraries, don't download them
rm -rf contrib/
for module in fdk-aac ffmpeg libbluray libdav1d libdvdnav libdvdread nvenc \
- x265 zimg; do
+ x265 zimg svt-av1 libvpl; do
vsed -i "/MODULES += contrib\/${module}/d" make/include/main.defs
done
}
From de923bdfbde5b1a4c000cd948d5b2a8772c84490 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:48 -0400
Subject: [PATCH 045/140] hedgewars: revbump for ffmpeg4-4.4.3
---
srcpkgs/hedgewars/template | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/srcpkgs/hedgewars/template b/srcpkgs/hedgewars/template
index 419f29b98b44..926fe4fe3e68 100644
--- a/srcpkgs/hedgewars/template
+++ b/srcpkgs/hedgewars/template
@@ -1,13 +1,13 @@
# Template file for 'hedgewars'
pkgname=hedgewars
version=1.0.2
-revision=1
+revision=2
build_style=cmake
configure_args="-DNOSERVER=1 -DDATA_INSTALL_DIR=/usr/share/${pkgname}
-DPHYSFS_SYSTEM=1 -DMINIMAL_FLAGS=1"
make_cmd=make
hostmakedepends="lua51 pkg-config qt5-qmake qt5-host-tools"
-makedepends="ffmpeg-devel lua51-devel physfs-devel qt5-tools-devel SDL2_image-devel
+makedepends="ffmpeg4-devel lua51-devel physfs-devel qt5-tools-devel SDL2_image-devel
SDL2_mixer-devel SDL2_net-devel SDL2_ttf-devel"
depends="libfreeglut"
short_desc="Funny turn-based artillery game, featuring fighting Hedgehogs!"
From 563a3d51126d0e0ec3e65ca1471f2dc40a402ef6 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:48 -0400
Subject: [PATCH 046/140] idjc: revbump for ffmpeg4-4.4.3
---
srcpkgs/idjc/template | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/srcpkgs/idjc/template b/srcpkgs/idjc/template
index df60318b3db9..36a75baf597c 100644
--- a/srcpkgs/idjc/template
+++ b/srcpkgs/idjc/template
@@ -1,11 +1,11 @@
# Template file for 'idjc'
pkgname=idjc
version=0.9.1
-revision=3
+revision=4
build_style=gnu-configure
hostmakedepends="pkg-config git python3 automake gettext-devel libtool"
makedepends="libvorbis-devel libogg-devel jack-devel libsamplerate-devel
- libflac-devel libsndfile-devel mpg123-devel ffmpeg-devel speex-devel
+ libflac-devel libsndfile-devel mpg123-devel ffmpeg4-devel speex-devel
glib-devel pixman-devel lame-devel python3-gobject-devel libshout-idjc-devel
opus-devel twolame-devel python3-mutagen python3-devel"
depends="python3-gobject python3-mutagen desktop-file-utils shared-mime-info python3-dbus jack"
From ae47a462256653492a0847b49eb47cd5e1f3a678 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:48 -0400
Subject: [PATCH 047/140] kfilemetadata5: revbump for ffmpeg-6.0
---
srcpkgs/kfilemetadata5/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/kfilemetadata5/template b/srcpkgs/kfilemetadata5/template
index 8980121fbc69..f662a2043f93 100644
--- a/srcpkgs/kfilemetadata5/template
+++ b/srcpkgs/kfilemetadata5/template
@@ -1,7 +1,7 @@
# Template file for 'kfilemetadata5'
pkgname=kfilemetadata5
version=5.105.0
-revision=1
+revision=2
build_style=cmake
hostmakedepends="kcoreaddons extra-cmake-modules pkg-config qt5-host-tools qt5-qmake
gettext kcoreaddons python3"
From cdbb9f85e235fce9725fe5c9dc07a2e86a4b133c Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:48 -0400
Subject: [PATCH 048/140] kid3: revbump for ffmpeg-6.0
---
srcpkgs/kid3/patches/ffmpeg5.patch | 17 +++++++++++++++++
srcpkgs/kid3/template | 2 +-
2 files changed, 18 insertions(+), 1 deletion(-)
create mode 100644 srcpkgs/kid3/patches/ffmpeg5.patch
diff --git a/srcpkgs/kid3/patches/ffmpeg5.patch b/srcpkgs/kid3/patches/ffmpeg5.patch
new file mode 100644
index 000000000000..135fc50e07c9
--- /dev/null
+++ b/srcpkgs/kid3/patches/ffmpeg5.patch
@@ -0,0 +1,17 @@
+# https://aur.archlinux.org/cgit/aur.git/diff/ffmpeg5.patch?h=kid3-cli&id=12410a74906612e7efc0ec8fbce739b4a0fef7e7
+diff --git a/src/plugins/acoustidimport/ffmpegfingerprintdecoder.cpp b/src/plugins/acoustidimport/ffmpegfingerprintdecoder.cpp
+index e156d424..e12b9abd 100644
+--- a/src/plugins/acoustidimport/ffmpegfingerprintdecoder.cpp
++++ b/src/plugins/acoustidimport/ffmpegfingerprintdecoder.cpp
+@@ -232,7 +232,11 @@ private:
+ friend class Format;
+ friend class Converter;
+ AVCodecContext* m_ptr;
++#if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(59, 0, 0)
+ AVCodec* m_impl;
++#else
++ const AVCodec* m_impl;
++#endif
+ AVFrame* m_frame;
+ bool m_opened;
+ };
diff --git a/srcpkgs/kid3/template b/srcpkgs/kid3/template
index 456206d90e16..f32f9decb0e7 100644
--- a/srcpkgs/kid3/template
+++ b/srcpkgs/kid3/template
@@ -1,7 +1,7 @@
# Template file for 'kid3'
pkgname=kid3
version=3.9.1
-revision=2
+revision=3
build_style=cmake
configure_args="-DWITH_APPS='CLI;$(vopt_if KDE KDE Qt)'
-DWITH_DOCBOOKDIR=/usr/share/xsl/docbook -DWITH_FLAC=$(vopt_if flac ON OFF)
From fcc89c7cdb4043b467ab41050af8dfd0e68dacf1 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:48 -0400
Subject: [PATCH 049/140] kodi: revbump for ffmpeg4-4.4.3
---
srcpkgs/kodi/template | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/srcpkgs/kodi/template b/srcpkgs/kodi/template
index 8057964d78a3..6cc1874be7ba 100644
--- a/srcpkgs/kodi/template
+++ b/srcpkgs/kodi/template
@@ -1,7 +1,7 @@
# Template file for 'kodi'
pkgname=kodi
version=19.4
-revision=6
+revision=7
_codename="Matrix"
build_style=cmake
configure_args="-DWITH_FFMPEG=/usr -DENABLE_LDGOLD=OFF
@@ -54,7 +54,7 @@ makedepends="
libmad-devel fontconfig-devel libXinerama-devel libsamplerate-devel libmms-devel
enca-devel boost-devel libcurl-devel libva-devel libvdpau-devel libass-devel
libbluetooth-devel yajl-devel libplist-devel librtmp-devel tinyxml-devel
- taglib-devel libcap-devel lame-devel libbluray-devel libnfs-devel ffmpeg-devel
+ taglib-devel libcap-devel lame-devel libbluray-devel libnfs-devel ffmpeg4-devel
giflib-devel libxslt-devel gnutls-devel libssh-devel libmicrohttpd-devel
libcec-devel dcadec-devel flatbuffers-devel fmt-devel lcms2-devel
libfstrcmp-devel rapidjson libcdio-paranoia spdlog libwaylandpp-devel
From 345e9511ce2c59a3609c3cfe767722687453bdb1 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:48 -0400
Subject: [PATCH 050/140] kpipewire: revbump for ffmpeg-6.0
---
srcpkgs/kpipewire/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/kpipewire/template b/srcpkgs/kpipewire/template
index 467ab823a5e1..51827f24db9e 100644
--- a/srcpkgs/kpipewire/template
+++ b/srcpkgs/kpipewire/template
@@ -1,7 +1,7 @@
# Template file for 'kpipewire'
pkgname=kpipewire
version=5.27.4
-revision=1
+revision=2
build_style=cmake
hostmakedepends="extra-cmake-modules plasma-wayland-protocols gettext
qt5-qmake qt5-host-tools pkg-config wayland-devel kcoreaddons
From 24053eaa9fc09bc454ee9eb01511621c5c48a44d Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:48 -0400
Subject: [PATCH 051/140] libextractor: revbump for ffmpeg4-4.4.3
---
srcpkgs/libextractor/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/libextractor/template b/srcpkgs/libextractor/template
index ddd4790f93e8..1fb9ca56a96a 100644
--- a/srcpkgs/libextractor/template
+++ b/srcpkgs/libextractor/template
@@ -7,7 +7,7 @@ configure_args="--disable-static"
hostmakedepends="pkg-config"
makedepends="zlib-devel bzip2-devel exiv2-devel tiff-devel libpng-devel
libjpeg-turbo-devel libvorbis-devel libflac-devel giflib-devel libmpeg2-devel
- ffmpeg-devel gtk+3-devel libltdl-devel libarchive-devel file-devel libgsf-devel"
+ ffmpeg4-devel gtk+3-devel libltdl-devel libarchive-devel file-devel libgsf-devel"
short_desc="Library used to extract meta data from files"
maintainer="Martin Riese <grauehaare@gmx.de>"
license="GPL-3.0-or-later"
From 86cb35a9f5c68b3598d5fdf806e541d0d818ea79 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:48 -0400
Subject: [PATCH 052/140] libopenal: revbump for ffmpeg-6.0
---
srcpkgs/libopenal/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/libopenal/template b/srcpkgs/libopenal/template
index 77218f9e539d..3f49ed75a1fd 100644
--- a/srcpkgs/libopenal/template
+++ b/srcpkgs/libopenal/template
@@ -1,7 +1,7 @@
# Template file for 'libopenal'
pkgname=libopenal
version=1.22.2
-revision=1
+revision=2
build_style=cmake
configure_args="-DALSOFT_EXAMPLES=OFF"
hostmakedepends="pkg-config"
From 0320728c9770a94718824c7064e8014dc581b2dd Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:48 -0400
Subject: [PATCH 053/140] libopenshot: revbump for ffmpeg-6.0
---
srcpkgs/libopenshot/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/libopenshot/template b/srcpkgs/libopenshot/template
index db831f69b474..81aa0d7136d9 100644
--- a/srcpkgs/libopenshot/template
+++ b/srcpkgs/libopenshot/template
@@ -1,7 +1,7 @@
# Template file for 'libopenshot'
pkgname=libopenshot
version=0.3.0
-revision=1
+revision=2
build_style=cmake
# Builds fail with Ruby-2.4.1
configure_args="-DENABLE_RUBY=OFF -DUSE_SYSTEM_JSONCPP=ON"
From a8850c66c56b254f339c01730cf536a36e20c851 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:48 -0400
Subject: [PATCH 054/140] loudgain: revbump for ffmpeg-6.0
---
srcpkgs/loudgain/patches/ffmpeg5.patch | 11 +++++++++++
srcpkgs/loudgain/template | 2 +-
2 files changed, 12 insertions(+), 1 deletion(-)
create mode 100644 srcpkgs/loudgain/patches/ffmpeg5.patch
diff --git a/srcpkgs/loudgain/patches/ffmpeg5.patch b/srcpkgs/loudgain/patches/ffmpeg5.patch
new file mode 100644
index 000000000000..16d4510ee98f
--- /dev/null
+++ b/srcpkgs/loudgain/patches/ffmpeg5.patch
@@ -0,0 +1,11 @@
+--- a/src/scan.c 2019-09-06 11:31:19.000000000 -0400
++++ b/src/scan.c 2023-03-23 11:15:40.867968521 -0400
+@@ -69,8 +69,6 @@
+ * It is now useless
+ * https://github.com/FFmpeg/FFmpeg/blob/70d25268c21cbee5f08304da95be1f647c630c15/doc/APIchanges#L86
+ */
+- if (avformat_version() < AV_VERSION_INT(58,9,100))
+- av_register_all();
+
+ av_log_set_callback(scan_av_log);
+
diff --git a/srcpkgs/loudgain/template b/srcpkgs/loudgain/template
index da4f2d56e94c..4d6bf29efb4f 100644
--- a/srcpkgs/loudgain/template
+++ b/srcpkgs/loudgain/template
@@ -1,7 +1,7 @@
# Template file for 'loudgain'
pkgname=loudgain
version=0.6.8
-revision=2
+revision=3
build_style=cmake
hostmakedepends="pkg-config"
makedepends="libebur128-devel taglib-devel ffmpeg-devel"
From 78c33ebcb4b9c30d700461716cffd0a59e480b5c Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:48 -0400
Subject: [PATCH 055/140] mediastreamer: revbump for ffmpeg4-4.4.3
---
srcpkgs/mediastreamer/template | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/srcpkgs/mediastreamer/template b/srcpkgs/mediastreamer/template
index d0e97e858e29..1bde031443a5 100644
--- a/srcpkgs/mediastreamer/template
+++ b/srcpkgs/mediastreamer/template
@@ -1,11 +1,11 @@
# Template file for 'mediastreamer'
pkgname=mediastreamer
version=5.2.6
-revision=1
+revision=2
build_style=cmake
configure_args="-DENABLE_STRICT=0 -DENABLE_UNIT_TESTS=0"
hostmakedepends="python3"
-makedepends="bzrtp-devel ffmpeg-devel glew-devel libXv-devel libsrtp-devel
+makedepends="bzrtp-devel ffmpeg4-devel glew-devel libXv-devel libsrtp-devel
libupnp-devel libvpx-devel mbedtls-devel opus-devel ortp-devel pulseaudio-devel
libtheora-devel speex-devel v4l-utils-devel bcg729-devel bcmatroska2-devel libgsm-devel"
# zxing-cpp-devel (1.2.0 probably not compatible, check again after updaing xzing)
From 74a40808546a46252594896a3a939199ead27675 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:48 -0400
Subject: [PATCH 056/140] mgba: revbump for ffmpeg-6.0
---
srcpkgs/mgba/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/mgba/template b/srcpkgs/mgba/template
index ae0504311eee..d31295a0cd3d 100644
--- a/srcpkgs/mgba/template
+++ b/srcpkgs/mgba/template
@@ -1,7 +1,7 @@
# Template file for 'mgba'
pkgname=mgba
version=0.10.2
-revision=1
+revision=2
build_style=cmake
hostmakedepends="pkg-config qt5-host-tools qt5-qmake desktop-file-utils"
makedepends="SDL2-devel ffmpeg-devel libedit-devel libepoxy-devel libmagick-devel
From b8e1f5567fb37dce052377785069a5e37ac88b0a Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:48 -0400
Subject: [PATCH 057/140] minidlna: revbump for ffmpeg-6.0
---
srcpkgs/minidlna/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/minidlna/template b/srcpkgs/minidlna/template
index e8081b1cbc67..9ee9714861fd 100644
--- a/srcpkgs/minidlna/template
+++ b/srcpkgs/minidlna/template
@@ -1,7 +1,7 @@
# Template file for 'minidlna'
pkgname=minidlna
version=1.3.2
-revision=1
+revision=2
build_style=gnu-configure
configure_args="
--sbindir=/usr/bin
From 4a1c6b28e96b9b4b3a7343688ffb58f6a611050e Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:49 -0400
Subject: [PATCH 058/140] mixxx: revbump for ffmpeg-6.0
---
srcpkgs/mixxx/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/mixxx/template b/srcpkgs/mixxx/template
index 619ddca0d332..4b9ea00d3fb3 100644
--- a/srcpkgs/mixxx/template
+++ b/srcpkgs/mixxx/template
@@ -1,7 +1,7 @@
# Template file for 'mixxx'
pkgname=mixxx
version=2.3.3
-revision=1
+revision=2
build_style=cmake
configure_args="-DCMAKE_BUILD_TYPE=Release"
hostmakedepends="extra-cmake-modules pkg-config protobuf qt5-host-tools qt5-devel"
From 7f23c0e62bcadba7e24ce2e1a3198ee4bfea78fe Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:49 -0400
Subject: [PATCH 059/140] mlt: revbump for ffmpeg4-4.4.3
---
srcpkgs/mlt/template | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/srcpkgs/mlt/template b/srcpkgs/mlt/template
index 8933eb4e7bb9..73353fedafb5 100644
--- a/srcpkgs/mlt/template
+++ b/srcpkgs/mlt/template
@@ -1,14 +1,14 @@
# Template file for 'mlt'
pkgname=mlt
version=6.26.1
-revision=1
+revision=2
build_style=configure
configure_args="--prefix=/usr --libdir=/usr/lib$XBPS_TARGET_WORDSIZE
--enable-gpl --enable-gpl3 --disable-swfdec --without-kde
--swig-languages=python"
hostmakedepends="doxygen pkg-config ladspa-sdk swig python3 which"
# XXX: movit vid.stab
-makedepends="alsa-lib-devel ffmpeg-devel gtk+-devel jack-devel ladspa-sdk
+makedepends="alsa-lib-devel ffmpeg4-devel gtk+-devel jack-devel ladspa-sdk
libexif-devel libsamplerate-devel libxml2-devel sox-devel SDL_image-devel
fftw-devel frei0r-plugins python3-devel pulseaudio-devel movit-devel
libvidstab-devel libatomic-devel"
From 7426dae5d7ab434ea223f0e79fe4b7c6a830ceb9 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:49 -0400
Subject: [PATCH 060/140] moc: revbump for ffmpeg4-4.4.3
---
srcpkgs/moc/template | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/srcpkgs/moc/template b/srcpkgs/moc/template
index c42be650a1d2..d4f0eefbad52 100644
--- a/srcpkgs/moc/template
+++ b/srcpkgs/moc/template
@@ -1,10 +1,10 @@
# Template file for 'moc'
pkgname=moc
version=2.5.2
-revision=6
+revision=7
build_style=gnu-configure
hostmakedepends="pkg-config"
-makedepends="db-devel ncurses-devel libcurl-devel popt-devel ffmpeg-devel
+makedepends="db-devel ncurses-devel libcurl-devel popt-devel ffmpeg4-devel
jack-devel alsa-lib-devel libltdl-devel libflac-devel libvorbis-devel
libmad-devel libmpcdec-devel libmodplug-devel libid3tag-devel faad2-devel
taglib-devel libsndfile-devel wavpack-devel speex-devel libsamplerate-devel
From 8b3ce3fef5898d875463b31509c8794d36fae97f Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:49 -0400
Subject: [PATCH 061/140] motion: revbump for ffmpeg-6.0
---
srcpkgs/motion/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/motion/template b/srcpkgs/motion/template
index 3cf3c3035c5b..7dca12d851e3 100644
--- a/srcpkgs/motion/template
+++ b/srcpkgs/motion/template
@@ -1,7 +1,7 @@
# Template file for 'motion'
pkgname=motion
version=4.5.1
-revision=1
+revision=2
build_style=gnu-configure
hostmakedepends="automake pkg-config gettext-devel tar"
makedepends="ffmpeg-devel libmicrohttpd-devel v4l-utils-devel gettext-devel"
From f46cbaf4c6f4dee663f07532151cf4f778b728eb Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:49 -0400
Subject: [PATCH 062/140] mpv: revbump for ffmpeg-6.0
---
srcpkgs/mpv/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/mpv/template b/srcpkgs/mpv/template
index e163c496c6eb..d4fefbf5e3c7 100644
--- a/srcpkgs/mpv/template
+++ b/srcpkgs/mpv/template
@@ -1,7 +1,7 @@
# Template file for 'mpv'
pkgname=mpv
version=0.35.1
-revision=2
+revision=3
build_style=meson
configure_args="-Dcdda=enabled -Ddvbin=enabled -Ddvdnav=enabled
-Dlibmpv=true -Dcplugins=enabled
From e3b0a90b4158a37fdb4020f4aff351ad675e1979 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:49 -0400
Subject: [PATCH 063/140] musikcube: revbump for ffmpeg-6.0
---
srcpkgs/musikcube/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/musikcube/template b/srcpkgs/musikcube/template
index 4b7930041126..7cd65cf76b77 100644
--- a/srcpkgs/musikcube/template
+++ b/srcpkgs/musikcube/template
@@ -1,7 +1,7 @@
# Template file for 'musikcube'
pkgname=musikcube
version=0.99.4
-revision=1
+revision=2
build_style=cmake
make_cmd=make
configure_args="-DNO_NCURSESW=1"
From d4b795f42b057ed90a2ff99719a8bb8b00bf3cd5 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:49 -0400
Subject: [PATCH 064/140] notcurses: revbump for ffmpeg-6.0
---
srcpkgs/notcurses/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/notcurses/template b/srcpkgs/notcurses/template
index 6dd8a091319f..3110c30c9aff 100644
--- a/srcpkgs/notcurses/template
+++ b/srcpkgs/notcurses/template
@@ -1,7 +1,7 @@
# Template file for 'notcurses'
pkgname=notcurses
version=3.0.9
-revision=1
+revision=2
build_style=cmake
configure_args="-DUSE_STATIC=ON $(vopt_bool man USE_PANDOC)"
hostmakedepends="pkg-config $(vopt_if man pandoc)"
From cba457bf8a12bb55c5c145d9bcc50bc685eadab1 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:49 -0400
Subject: [PATCH 065/140] obs: revbump for ffmpeg-6.0
---
srcpkgs/obs/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/obs/template b/srcpkgs/obs/template
index 89fd11297c3f..3cf49e414bf3 100644
--- a/srcpkgs/obs/template
+++ b/srcpkgs/obs/template
@@ -1,7 +1,7 @@
# Template file for 'obs'
pkgname=obs
version=29.1.0
-revision=1
+revision=2
archs="i686* x86_64* ppc64le* aarch64*"
build_style=cmake
configure_args="-DOBS_VERSION_OVERRIDE=${version} -DENABLE_JACK=ON
From dc07ee177bf1f11a77e38d6d9af319e2b3cc3a79 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:49 -0400
Subject: [PATCH 066/140] olive: revbump for ffmpeg4-4.4.3
---
srcpkgs/olive/template | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/srcpkgs/olive/template b/srcpkgs/olive/template
index 12a46936c990..5c2917b9c512 100644
--- a/srcpkgs/olive/template
+++ b/srcpkgs/olive/template
@@ -1,10 +1,10 @@
# Template file for 'olive'
pkgname=olive
version=0.1.2
-revision=2
+revision=3
build_style=qmake
hostmakedepends="qt5-qmake qt5-host-tools pkg-config"
-makedepends="qt5-devel qt5-multimedia-devel qt5-svg-devel ffmpeg-devel frei0r-plugins"
+makedepends="qt5-devel qt5-multimedia-devel qt5-svg-devel ffmpeg4-devel frei0r-plugins"
short_desc="Non-linear video editor"
maintainer="Orphaned <orphan@voidlinux.org>"
license="GPL-3.0-or-later"
From b43691adbdd8f7326caa228f2e246ddc0e80c550 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:49 -0400
Subject: [PATCH 067/140] omxplayer: revbump for ffmpeg4-4.4.3
---
srcpkgs/omxplayer/template | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/srcpkgs/omxplayer/template b/srcpkgs/omxplayer/template
index e70bf7873d4d..c835103d8789 100644
--- a/srcpkgs/omxplayer/template
+++ b/srcpkgs/omxplayer/template
@@ -1,10 +1,10 @@
# Template file for 'omxplayer'
pkgname=omxplayer
version=20190102
-revision=1
+revision=2
short_desc="Commandline OMX player for the Raspberry Pi"
maintainer="Orphaned <orphan@voidlinux.org>"
-license="GPL-2"
+license="GPL-2-or-later"
homepage="https://github.com/popcornmix/omxplayer"
_commit="f06235cc9690a6d58187514452df8cf8fcdaacec"
@@ -15,7 +15,7 @@ checksum=af2d9450f8947842ea8c401fe9f71eec444013ebbdee29f2ac828c9c493c1329
archs="armv6l* armv7l*"
build_style=gnu-makefile
hostmakedepends="curl pkg-config"
-makedepends="alsa-lib-devel rpi-userland-devel pcre-devel boost-devel freetype-devel ffmpeg-devel dbus-devel"
+makedepends="alsa-lib-devel rpi-userland-devel pcre-devel boost-devel freetype-devel ffmpeg4-devel dbus-devel"
depends="freefont-ttf"
do_build() {
From c181523e510ad21c7ca28b2647415853ae05f127 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:50 -0400
Subject: [PATCH 068/140] openimageio: revbump for ffmpeg-6.0
---
common/shlibs | 2 ++
srcpkgs/openimageio/template | 2 +-
2 files changed, 3 insertions(+), 1 deletion(-)
diff --git a/common/shlibs b/common/shlibs
index 4626cfda810b..d0d328b09ef9 100644
--- a/common/shlibs
+++ b/common/shlibs
@@ -2262,6 +2262,8 @@ libxmp.so.4 libxmp-4.3.7_1
libKF5ThreadWeaver.so.5 threadweaver-5.26.0_1
libOpenImageIO_Util.so.2.4 openimageio-2.4.9.0_1
libOpenImageIO.so.2.4 openimageio-2.4.9.0_1
+libOpenImageIO_Util.so.2.4 openimageio-2.4.8.1_1
+libOpenImageIO.so.2.4 openimageio-2.4.8.1_1
libOpenColorIO.so.2.1 opencolorio-2.1.2_1
libpystring.so.1 pystring-1.1.3_1
libyaml-cpp.so.0.7 yaml-cpp-0.7.0_1
diff --git a/srcpkgs/openimageio/template b/srcpkgs/openimageio/template
index b661bbf7ba57..9b38ace50f7e 100644
--- a/srcpkgs/openimageio/template
+++ b/srcpkgs/openimageio/template
@@ -1,7 +1,7 @@
# Template file for 'openimageio'
pkgname=openimageio
version=2.4.9.0
-revision=2
+revision=3
build_style=cmake
build_helper=qemu
configure_args="-DUSE_QT=0 -DUSE_PYTHON=0 -DOIIO_BUILD_TESTS=0
From 0d93cf026a7b56a3bd6f942c63c71bc4b48b43dd Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:50 -0400
Subject: [PATCH 069/140] openmw: revbump for ffmpeg-6.0
---
srcpkgs/openmw/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/openmw/template b/srcpkgs/openmw/template
index 5251a0283dc1..e3771c7aaf1a 100644
--- a/srcpkgs/openmw/template
+++ b/srcpkgs/openmw/template
@@ -1,7 +1,7 @@
# Template file for 'openmw'
pkgname=openmw
version=0.47.0
-revision=4
+revision=5
build_style=cmake
_recast_commit=e75adf86f91eb3082220085e42dda62679f9a3ea
_bullet_tag=3.17
From 96a94e42a7719eca112174c79402331d7a079615 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:50 -0400
Subject: [PATCH 070/140] openshot: revbump for ffmpeg-6.0
---
srcpkgs/openshot/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/openshot/template b/srcpkgs/openshot/template
index 322717d40abc..c074e0338773 100644
--- a/srcpkgs/openshot/template
+++ b/srcpkgs/openshot/template
@@ -1,7 +1,7 @@
# Template file for 'openshot'
pkgname=openshot
version=3.0.0
-revision=1
+revision=2
build_style=python3-module
hostmakedepends="python3 python3-setuptools"
makedepends="ffmpeg-devel python3-PyQt5"
From 16853b969fd4289d545dc8e8539de5970c4b431e Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:50 -0400
Subject: [PATCH 071/140] opentoonz: revbump for ffmpeg-6.0
---
srcpkgs/opentoonz/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/opentoonz/template b/srcpkgs/opentoonz/template
index ee9f7603f55f..3e81834ca0ed 100644
--- a/srcpkgs/opentoonz/template
+++ b/srcpkgs/opentoonz/template
@@ -1,7 +1,7 @@
# Template file for 'opentoonz'
pkgname=opentoonz
version=1.6.0
-revision=2
+revision=3
build_wrksrc="toonz/sources"
build_style=cmake
make_cmd=make
From bddb16cb1c74d93f687afbdb8306c6f0c35084ba Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:50 -0400
Subject: [PATCH 072/140] pianobar: revbump for ffmpeg-6.0
---
srcpkgs/pianobar/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/pianobar/template b/srcpkgs/pianobar/template
index a9b29e91993f..81efcd122c4d 100644
--- a/srcpkgs/pianobar/template
+++ b/srcpkgs/pianobar/template
@@ -1,7 +1,7 @@
# Template file for 'pianobar'
pkgname=pianobar
version=2022.04.01
-revision=1
+revision=2
build_style=gnu-makefile
make_build_args="V=1"
hostmakedepends="pkg-config"
From 90cae6cbf0b385f4536714f5f2acba544de56f46 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:50 -0400
Subject: [PATCH 073/140] ppsspp: revbump for ffmpeg4-4.4.3
---
srcpkgs/ppsspp/template | 7 +++----
1 file changed, 3 insertions(+), 4 deletions(-)
diff --git a/srcpkgs/ppsspp/template b/srcpkgs/ppsspp/template
index 7984a733d4be..15a42fd2c993 100644
--- a/srcpkgs/ppsspp/template
+++ b/srcpkgs/ppsspp/template
@@ -1,7 +1,7 @@
# Template file for 'ppsspp'
pkgname=ppsspp
version=1.14.4
-revision=1
+revision=2
_glslang_commit=dc11adde23c455a24e13dd54de9b4ede8bdd7db8
_SPIRV_Cross_commit=9acb9ec31f5a8ef80ea6b994bb77be787b08d3d1
_armips_commit=6719edebaae03330ee5441d9b28280672edf00d5
@@ -13,7 +13,7 @@ configure_args="-DHEADLESS=1 -DUSE_SYSTEM_FFMPEG=1 -DUNITTEST=ON
-DUSING_QT_UI=$(vopt_if qt ON OFF) -DUSE_SYSTEM_ZSTD=ON
-DARMIPS_USE_STD_FILESYSTEM=ON"
hostmakedepends="pkg-config python3 $(vopt_if qt qt5-host-tools)"
-makedepends="zlib-devel glew-devel ffmpeg-devel libzip-devel
+makedepends="zlib-devel glew-devel ffmpeg4-devel libzip-devel
snappy-devel rapidjson libpng-devel libzstd-devel
$(vopt_if sdl2 SDL2-devel) $(vopt_if wayland wayland-devel)
$(vopt_if qt 'qt5-devel qt5-multimedia-devel')"
@@ -62,13 +62,12 @@ post_extract() {
mv ${wrksrc}/miniupnp-${_miniupnp_commit} ${wrksrc}/ext/miniupnp
}
-post_patch(){
+post_patch() {
# disable git versioning
vsed -e 's|find_package(Git)|# &|' -i git-version.cmake
}
do_install() {
- vlicense LICENSE.TXT
vinstall icons/icon.svg 644 usr/share/pixmaps ppsspp.svg
vinstall Qt/PPSSPP.desktop 644 usr/share/applications
vbin build/PPSSPPHeadless ppsspp-headless
From cb6988a511ed1a99d34dcc0121889f28cdfcbbe7 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:50 -0400
Subject: [PATCH 074/140] pqiv: revbump for ffmpeg-6.0
---
srcpkgs/pqiv/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/pqiv/template b/srcpkgs/pqiv/template
index 542fc27a2d32..9308d949b6a1 100644
--- a/srcpkgs/pqiv/template
+++ b/srcpkgs/pqiv/template
@@ -1,7 +1,7 @@
# Template file for 'pqiv'
pkgname=pqiv
version=2.12
-revision=1
+revision=2
build_style=gnu-makefile
hostmakedepends="pkg-config"
makedepends="glib-devel gtk+3-devel $(vopt_if ffmpeg ffmpeg-devel)
From c2a2a18c8a5809c68bb764ec475b4131042e7192 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:50 -0400
Subject: [PATCH 075/140] qmmp: revbump for ffmpeg-6.0
---
srcpkgs/qmmp/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/qmmp/template b/srcpkgs/qmmp/template
index 26c661ed16be..a150d7441c7a 100644
--- a/srcpkgs/qmmp/template
+++ b/srcpkgs/qmmp/template
@@ -1,7 +1,7 @@
# Template file for 'qmmp'
pkgname=qmmp
version=1.6.1
-revision=1
+revision=2
build_style=cmake
configure_args="-DUSE_HAL:BOOL=FALSE -DQMMP_DEFAULT_UI:STRING=simple"
hostmakedepends="pkg-config qt5-host-tools qt5-qmake"
From 9057694e1c778a3107703dd582126ca58902dc18 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:50 -0400
Subject: [PATCH 076/140] qt5-webengine: update to 5.15.13
---
.../chromium-media-filters-cpp14.patch | 11 ++
srcpkgs/qt5-webengine/patches/ffmpeg5.patch | 179 ++++++++++++++++++
srcpkgs/qt5-webengine/template | 10 +-
3 files changed, 195 insertions(+), 5 deletions(-)
create mode 100644 srcpkgs/qt5-webengine/patches/chromium-media-filters-cpp14.patch
create mode 100644 srcpkgs/qt5-webengine/patches/ffmpeg5.patch
diff --git a/srcpkgs/qt5-webengine/patches/chromium-media-filters-cpp14.patch b/srcpkgs/qt5-webengine/patches/chromium-media-filters-cpp14.patch
new file mode 100644
index 000000000000..04adc540f2cb
--- /dev/null
+++ b/srcpkgs/qt5-webengine/patches/chromium-media-filters-cpp14.patch
@@ -0,0 +1,11 @@
+--- a/src/3rdparty/chromium/media/filters/BUILD.gn 2023-02-27 13:32:59.000000000 -0500
++++ b/src/3rdparty/chromium/media/filters/BUILD.gn 2023-04-02 17:21:39.204066384 -0400
+@@ -96,6 +96,8 @@
+ "//ui/gfx/geometry:geometry",
+ ]
+
++ cflags_cc = [ "-std=c++14" ]
++
+ libs = []
+
+ if (proprietary_codecs) {
diff --git a/srcpkgs/qt5-webengine/patches/ffmpeg5.patch b/srcpkgs/qt5-webengine/patches/ffmpeg5.patch
new file mode 100644
index 000000000000..ac55e1634423
--- /dev/null
+++ b/srcpkgs/qt5-webengine/patches/ffmpeg5.patch
@@ -0,0 +1,179 @@
+--- a/src/3rdparty/chromium/media/filters/ffmpeg_demuxer.cc 2023-04-02 16:50:57.732547446 -0400
++++ b/src/3rdparty/chromium/media/filters/ffmpeg_demuxer.cc 2023-04-02 16:50:09.486478995 -0400
+@@ -57,6 +57,8 @@
+
+ namespace {
+
++constexpr int64_t kRelativeTsBase = static_cast<int64_t>(0x7ffeffffffffffff);
++
+ void SetAVStreamDiscard(AVStream* stream, AVDiscard discard) {
+ DCHECK(stream);
+ stream->discard = discard;
+@@ -90,24 +92,12 @@
+
+ static base::TimeDelta ExtractStartTime(AVStream* stream) {
+ // The default start time is zero.
+- base::TimeDelta start_time;
++ base::TimeDelta start_time = kNoTimestamp;
+
+ // First try to use the |start_time| value as is.
+ if (stream->start_time != kNoFFmpegTimestamp)
+ start_time = ConvertFromTimeBase(stream->time_base, stream->start_time);
+
+- // Next try to use the first DTS value, for codecs where we know PTS == DTS
+- // (excludes all H26x codecs). The start time must be returned in PTS.
+- if (stream->first_dts != kNoFFmpegTimestamp &&
+- stream->codecpar->codec_id != AV_CODEC_ID_HEVC &&
+- stream->codecpar->codec_id != AV_CODEC_ID_H264 &&
+- stream->codecpar->codec_id != AV_CODEC_ID_MPEG4) {
+- const base::TimeDelta first_pts =
+- ConvertFromTimeBase(stream->time_base, stream->first_dts);
+- if (first_pts < start_time)
+- start_time = first_pts;
+- }
+-
+ return start_time;
+ }
+
+@@ -408,11 +398,11 @@
+ scoped_refptr<DecoderBuffer> buffer;
+
+ if (type() == DemuxerStream::TEXT) {
+- int id_size = 0;
++ size_t id_size = 0;
+ uint8_t* id_data = av_packet_get_side_data(
+ packet.get(), AV_PKT_DATA_WEBVTT_IDENTIFIER, &id_size);
+
+- int settings_size = 0;
++ size_t settings_size = 0;
+ uint8_t* settings_data = av_packet_get_side_data(
+ packet.get(), AV_PKT_DATA_WEBVTT_SETTINGS, &settings_size);
+
+@@ -424,7 +414,7 @@
+ buffer = DecoderBuffer::CopyFrom(packet->data, packet->size,
+ side_data.data(), side_data.size());
+ } else {
+- int side_data_size = 0;
++ size_t side_data_size = 0;
+ uint8_t* side_data = av_packet_get_side_data(
+ packet.get(), AV_PKT_DATA_MATROSKA_BLOCKADDITIONAL, &side_data_size);
+
+@@ -485,7 +475,7 @@
+ packet->size - data_offset);
+ }
+
+- int skip_samples_size = 0;
++ size_t skip_samples_size = 0;
+ const uint32_t* skip_samples_ptr =
+ reinterpret_cast<const uint32_t*>(av_packet_get_side_data(
+ packet.get(), AV_PKT_DATA_SKIP_SAMPLES, &skip_samples_size));
+@@ -1587,6 +1577,8 @@
+ for (const auto& stream : streams_) {
+ if (!stream || stream->IsEnabled() != enabled)
+ continue;
++ if (stream->av_stream()->start_time == AV_NOPTS_VALUE)
++ continue;
+ if (!lowest_start_time_stream ||
+ stream->start_time() < lowest_start_time_stream->start_time()) {
+ lowest_start_time_stream = stream.get();
+@@ -1604,6 +1596,8 @@
+ if (stream && stream->type() == DemuxerStream::VIDEO &&
+ stream->IsEnabled()) {
+ video_stream = stream.get();
++ if (stream->av_stream()->start_time == AV_NOPTS_VALUE)
++ continue;
+ if (video_stream->start_time() <= seek_time) {
+ return video_stream;
+ }
+diff -Naurp qtwebengine-5.15.10.orig/src/3rdparty/chromium/media/ffmpeg/ffmpeg_common.h qtwebengine-5.15.10/src/3rdparty/chromium/media/ffmpeg/ffmpeg_common.h
+--- a/src/3rdparty/chromium/media/ffmpeg/ffmpeg_common.h 2022-05-23 06:38:40.000000000 -0500
++++ b/src/3rdparty/chromium/media/ffmpeg/ffmpeg_common.h 2022-07-11 22:12:47.917192788 -0500
+@@ -29,6 +29,7 @@ extern "C" {
+ #include <libavformat/avformat.h>
+ #include <libavformat/avio.h>
+ #include <libavutil/avutil.h>
++#include <libavutil/channel_layout.h>
+ #include <libavutil/imgutils.h>
+ #include <libavutil/log.h>
+ #include <libavutil/mastering_display_metadata.h>
+diff -Naurp qtwebengine-5.15.10.orig/src/3rdparty/chromium/media/filters/audio_file_reader.cc qtwebengine-5.15.10/src/3rdparty/chromium/media/filters/audio_file_reader.cc
+--- a/src/3rdparty/chromium/media/filters/audio_file_reader.cc 2022-05-23 06:38:40.000000000 -0500
++++ b/src/3rdparty/chromium/media/filters/audio_file_reader.cc 2022-07-11 22:12:47.917192788 -0500
+@@ -85,7 +85,7 @@ bool AudioFileReader::OpenDemuxer() {
+ }
+
+ bool AudioFileReader::OpenDecoder() {
+- AVCodec* codec = avcodec_find_decoder(codec_context_->codec_id);
++ const AVCodec* codec = avcodec_find_decoder(codec_context_->codec_id);
+ if (codec) {
+ // MP3 decodes to S16P which we don't support, tell it to use S16 instead.
+ if (codec_context_->sample_fmt == AV_SAMPLE_FMT_S16P)
+diff -Naurp qtwebengine-5.15.10.orig/src/3rdparty/chromium/media/filters/ffmpeg_audio_decoder.cc qtwebengine-5.15.10/src/3rdparty/chromium/media/filters/ffmpeg_audio_decoder.cc
+--- a/src/3rdparty/chromium/media/filters/ffmpeg_audio_decoder.cc 2022-05-23 06:38:40.000000000 -0500
++++ b/src/3rdparty/chromium/media/filters/ffmpeg_audio_decoder.cc 2022-07-11 22:12:47.917192788 -0500
+@@ -329,7 +329,7 @@ bool FFmpegAudioDecoder::ConfigureDecode
+ }
+ }
+
+- AVCodec* codec = avcodec_find_decoder(codec_context_->codec_id);
++ const AVCodec* codec = avcodec_find_decoder(codec_context_->codec_id);
+ if (!codec ||
+ avcodec_open2(codec_context_.get(), codec, &codec_options) < 0) {
+ DLOG(ERROR) << "Could not initialize audio decoder: "
+diff -Naurp qtwebengine-5.15.10.orig/src/3rdparty/chromium/media/filters/ffmpeg_glue.cc qtwebengine-5.15.10/src/3rdparty/chromium/media/filters/ffmpeg_glue.cc
+--- a/src/3rdparty/chromium/media/filters/ffmpeg_glue.cc 2022-05-23 06:38:40.000000000 -0500
++++ b/src/3rdparty/chromium/media/filters/ffmpeg_glue.cc 2022-07-11 22:12:47.918192779 -0500
+@@ -59,7 +59,6 @@ static int64_t AVIOSeekOperation(void* o
+ }
+
+ void FFmpegGlue::InitializeFFmpeg() {
+- av_register_all();
+ }
+
+ static void LogContainer(bool is_local_file,
+@@ -95,9 +94,6 @@ FFmpegGlue::FFmpegGlue(FFmpegURLProtocol
+ // Enable fast, but inaccurate seeks for MP3.
+ format_context_->flags |= AVFMT_FLAG_FAST_SEEK;
+
+- // Ensures we can read out various metadata bits like vp8 alpha.
+- format_context_->flags |= AVFMT_FLAG_KEEP_SIDE_DATA;
+-
+ // Ensures format parsing errors will bail out. From an audit on 11/2017, all
+ // instances were real failures. Solves bugs like http://crbug.com/710791.
+ format_context_->error_recognition |= AV_EF_EXPLODE;
+diff -Naurp qtwebengine-5.15.10.orig/src/3rdparty/chromium/media/filters/ffmpeg_video_decoder.cc qtwebengine-5.15.10/src/3rdparty/chromium/media/filters/ffmpeg_video_decoder.cc
+--- a/src/3rdparty/chromium/media/filters/ffmpeg_video_decoder.cc 2022-05-23 06:38:40.000000000 -0500
++++ b/src/3rdparty/chromium/media/filters/ffmpeg_video_decoder.cc 2022-07-11 22:12:47.918192779 -0500
+@@ -391,7 +391,7 @@ bool FFmpegVideoDecoder::ConfigureDecode
+ if (decode_nalus_)
+ codec_context_->flags2 |= AV_CODEC_FLAG2_CHUNKS;
+
+- AVCodec* codec = avcodec_find_decoder(codec_context_->codec_id);
++ const AVCodec* codec = avcodec_find_decoder(codec_context_->codec_id);
+ if (!codec || avcodec_open2(codec_context_.get(), codec, NULL) < 0) {
+ ReleaseFFmpegResources();
+ return false;
+diff -Naurp qtwebengine-5.15.10.orig/src/3rdparty/chromium/media/filters/media_file_checker.cc qtwebengine-5.15.10/src/3rdparty/chromium/media/filters/media_file_checker.cc
+--- a/src/3rdparty/chromium/media/filters/media_file_checker.cc 2022-05-23 06:38:40.000000000 -0500
++++ b/src/3rdparty/chromium/media/filters/media_file_checker.cc 2022-07-11 22:12:47.918192779 -0500
+@@ -68,7 +68,7 @@ bool MediaFileChecker::Start(base::TimeD
+ auto context = AVStreamToAVCodecContext(format_context->streams[i]);
+ if (!context)
+ continue;
+- AVCodec* codec = avcodec_find_decoder(cp->codec_id);
++ const AVCodec* codec = avcodec_find_decoder(cp->codec_id);
+ if (codec && avcodec_open2(context.get(), codec, nullptr) >= 0) {
+ auto loop = std::make_unique<FFmpegDecodingLoop>(context.get());
+ stream_contexts[i] = {std::move(context), std::move(loop)};
+diff -Naurp qtwebengine-5.15.10.orig/src/3rdparty/chromium/third_party/webrtc/modules/video_coding/codecs/h264/h264_decoder_impl.cc qtwebengine-5.15.10/src/3rdparty/chromium/third_party/webrtc/modules/video_coding/codecs/h264/h264_decoder_impl.cc
+--- a/src/3rdparty/chromium/third_party/webrtc/modules/video_coding/codecs/h264/h264_decoder_impl.cc 2022-05-23 06:38:40.000000000 -0500
++++ b/src/3rdparty/chromium/third_party/webrtc/modules/video_coding/codecs/h264/h264_decoder_impl.cc 2022-07-11 22:12:47.918192779 -0500
+@@ -203,7 +203,7 @@ int32_t H264DecoderImpl::InitDecode(cons
+ // a pointer |this|.
+ av_context_->opaque = this;
+
+- AVCodec* codec = avcodec_find_decoder(av_context_->codec_id);
++ const AVCodec* codec = avcodec_find_decoder(av_context_->codec_id);
+ if (!codec) {
+ // This is an indication that FFmpeg has not been initialized or it has not
+ // been compiled/initialized with the correct set of codecs.
diff --git a/srcpkgs/qt5-webengine/template b/srcpkgs/qt5-webengine/template
index 0a71484208bc..095ab67701e4 100644
--- a/srcpkgs/qt5-webengine/template
+++ b/srcpkgs/qt5-webengine/template
@@ -1,9 +1,9 @@
# Template file for 'qt5-webengine'
pkgname=qt5-webengine
-version=5.15.11
-revision=2
+version=5.15.13
+revision=1
_version="${version}-lts"
-_chromium_commit=be349eaf62e77955791d7bf29f893f1e8a37daf4
+_chromium_commit=e48df7803c7c98b0b2471c94057d32e44a301ad5
archs="x86_64* i686* armv[67]* ppc64* aarch64*"
create_wrksrc=yes
build_style=qmake
@@ -32,8 +32,8 @@ license="GPL-3.0-or-later, LGPL-3.0-or-later"
homepage="https://qt.io/"
distfiles="https://github.com/qt/qtwebengine/archive/v${_version}.tar.gz
https://github.com/qt/qtwebengine-chromium/archive/${_chromium_commit}.tar.gz"
-checksum="aa7466356c450c5f5870f979b93cd7e7e62da1165c328ffcab1a9928db18ad67
- 6f47ed8ab8cc062411f6f206da6353bc8263d6ed6d6290c689a05c01d91f646b"
+checksum="4b59838ed75ef788b59e1e412535a0e42dd9d311661fdeadb191b581ba815c63
+ a91686562b1d4e8b220e0bbcbab5feb64630e2de974b35ac034bf388af771a6c"
no_generic_pkgconfig_link=yes
build_options="sndio pipewire"
From 9e6975288419beaa47ec110318f59cdd112cc36f Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:51 -0400
Subject: [PATCH 077/140] qt5: update to 5.15.8
---
...erywhere-opensource-src-5.15.8-kf5-1.patch | 12913 ++++++++++++++++
srcpkgs/qt5/template | 12 +-
2 files changed, 12919 insertions(+), 6 deletions(-)
create mode 100644 srcpkgs/qt5/patches/qt-everywhere-opensource-src-5.15.8-kf5-1.patch
diff --git a/srcpkgs/qt5/patches/qt-everywhere-opensource-src-5.15.8-kf5-1.patch b/srcpkgs/qt5/patches/qt-everywhere-opensource-src-5.15.8-kf5-1.patch
new file mode 100644
index 000000000000..966c98bcd3bb
--- /dev/null
+++ b/srcpkgs/qt5/patches/qt-everywhere-opensource-src-5.15.8-kf5-1.patch
@@ -0,0 +1,12913 @@
+Submitted By: Pierre Labastie <pierre_dot_labastie_at_neuf_dot_fr>
+Date: 2023-01-05
+Initial Package Version: 5.15.8
+Upstream Status: Applied (according to KDE)
+Origin: KDE patch set
+Description: Patch set maintained by the KDE folks
+see https://dot.kde.org/2021/04/06/announcing-kdes-qt-5-patch-collection
+Patch generated using the procedure in
+https://wiki.linuxfromscratch.org/blfs/ticket/17476#comment:3
+
+Submodule qtbase 4ee4fc18..9cf586d6:
+diff --git a/qtbase/mkspecs/common/android/qplatformdefs.h b/qtbase/mkspecs/common/android/qplatformdefs.h
+index f75bc4093b..2bd59410d4 100644
+--- a/qtbase/mkspecs/common/android/qplatformdefs.h
++++ b/qtbase/mkspecs/common/android/qplatformdefs.h
+@@ -144,11 +144,7 @@
+ #define QT_SIGNAL_ARGS int
+ #define QT_SIGNAL_IGNORE SIG_IGN
+
+-#if defined(__GLIBC__) && (__GLIBC__ >= 2)
+ #define QT_SOCKLEN_T socklen_t
+-#else
+-#define QT_SOCKLEN_T int
+-#endif
+
+ #if defined(_XOPEN_SOURCE) && (_XOPEN_SOURCE >= 500)
+ #define QT_SNPRINTF ::snprintf
+diff --git a/qtbase/mkspecs/features/mac/sdk.mk b/qtbase/mkspecs/features/mac/sdk.mk
+index f30b5830b4..a32ceacb6c 100644
+--- a/qtbase/mkspecs/features/mac/sdk.mk
++++ b/qtbase/mkspecs/features/mac/sdk.mk
+@@ -1,6 +1,6 @@
+
+ ifeq ($(QT_MAC_SDK_NO_VERSION_CHECK),)
+- CHECK_SDK_COMMAND = /usr/bin/xcrun --sdk $(EXPORT_QMAKE_MAC_SDK) -show-sdk-version 2>&1
++ CHECK_SDK_COMMAND = /usr/bin/xcrun --sdk $(EXPORT_QMAKE_MAC_SDK) -show-sdk-version 2>/dev/null
+ CURRENT_MAC_SDK_VERSION := $(shell DEVELOPER_DIR=$(EXPORT_QMAKE_XCODE_DEVELOPER_PATH) $(CHECK_SDK_COMMAND))
+ ifneq ($(CURRENT_MAC_SDK_VERSION),$(EXPORT_QMAKE_MAC_SDK_VERSION))
+ # We don't want to complain about out of date SDK unless the target needs to be remade.
+diff --git a/qtbase/mkspecs/linux-clang/qplatformdefs.h b/qtbase/mkspecs/linux-clang/qplatformdefs.h
+index a818d973f0..c1ab72fbc6 100644
+--- a/qtbase/mkspecs/linux-clang/qplatformdefs.h
++++ b/qtbase/mkspecs/linux-clang/qplatformdefs.h
+@@ -79,14 +79,6 @@
+ #define QT_USE_XOPEN_LFS_EXTENSIONS
+ #include "../common/posix/qplatformdefs.h"
+
+-#undef QT_SOCKLEN_T
+-
+-#if defined(__GLIBC__) && (__GLIBC__ >= 2)
+-#define QT_SOCKLEN_T socklen_t
+-#else
+-#define QT_SOCKLEN_T int
+-#endif
+-
+ #if defined(_XOPEN_SOURCE) && (_XOPEN_SOURCE >= 500)
+ #define QT_SNPRINTF ::snprintf
+ #define QT_VSNPRINTF ::vsnprintf
+diff --git a/qtbase/mkspecs/linux-g++/qplatformdefs.h b/qtbase/mkspecs/linux-g++/qplatformdefs.h
+index 13523f0702..4d2750d9ec 100644
+--- a/qtbase/mkspecs/linux-g++/qplatformdefs.h
++++ b/qtbase/mkspecs/linux-g++/qplatformdefs.h
+@@ -79,14 +79,6 @@
+ #define QT_USE_XOPEN_LFS_EXTENSIONS
+ #include "../common/posix/qplatformdefs.h"
+
+-#undef QT_SOCKLEN_T
+-
+-#if defined(__GLIBC__) && (__GLIBC__ < 2)
+-#define QT_SOCKLEN_T int
+-#else
+-#define QT_SOCKLEN_T socklen_t
+-#endif
+-
+ #if defined(_XOPEN_SOURCE) && (_XOPEN_SOURCE >= 500)
+ #define QT_SNPRINTF ::snprintf
+ #define QT_VSNPRINTF ::vsnprintf
+diff --git a/qtbase/mkspecs/linux-llvm/qplatformdefs.h b/qtbase/mkspecs/linux-llvm/qplatformdefs.h
+index dc750ab1ef..d3cc39b47f 100644
+--- a/qtbase/mkspecs/linux-llvm/qplatformdefs.h
++++ b/qtbase/mkspecs/linux-llvm/qplatformdefs.h
+@@ -80,14 +80,6 @@
+ #define QT_USE_XOPEN_LFS_EXTENSIONS
+ #include "../common/posix/qplatformdefs.h"
+
+-#undef QT_SOCKLEN_T
+-
+-#if defined(__GLIBC__) && (__GLIBC__ >= 2)
+-#define QT_SOCKLEN_T socklen_t
+-#else
+-#define QT_SOCKLEN_T int
+-#endif
+-
+ #if defined(_XOPEN_SOURCE) && (_XOPEN_SOURCE >= 500)
+ #define QT_SNPRINTF ::snprintf
+ #define QT_VSNPRINTF ::vsnprintf
+diff --git a/qtbase/mkspecs/linux-lsb-g++/qplatformdefs.h b/qtbase/mkspecs/linux-lsb-g++/qplatformdefs.h
+index 4c4e53da2a..83baffb3e3 100644
+--- a/qtbase/mkspecs/linux-lsb-g++/qplatformdefs.h
++++ b/qtbase/mkspecs/linux-lsb-g++/qplatformdefs.h
+@@ -85,16 +85,9 @@
+ #include "../common/posix/qplatformdefs.h"
+
+ #undef QT_OPEN_LARGEFILE
+-#undef QT_SOCKLEN_T
+
+ #define QT_OPEN_LARGEFILE 0
+
+-#if defined(__GLIBC__) && (__GLIBC__ >= 2)
+-#define QT_SOCKLEN_T socklen_t
+-#else
+-#define QT_SOCKLEN_T int
+-#endif
+-
+ #ifndef SIOCGIFBRDADDR
+ # define SIOCGIFBRDADDR 0x8919
+ #endif
+diff --git a/qtbase/mkspecs/lynxos-g++/qplatformdefs.h b/qtbase/mkspecs/lynxos-g++/qplatformdefs.h
+index 4339ea2b23..6007af0055 100644
+--- a/qtbase/mkspecs/lynxos-g++/qplatformdefs.h
++++ b/qtbase/mkspecs/lynxos-g++/qplatformdefs.h
+@@ -72,14 +72,6 @@
+
+ #include "../common/posix/qplatformdefs.h"
+
+-#undef QT_SOCKLEN_T
+-
+-#if defined(__GLIBC__) && (__GLIBC__ >= 2)
+-#define QT_SOCKLEN_T socklen_t
+-#else
+-#define QT_SOCKLEN_T int
+-#endif
+-
+ #if defined(_XOPEN_SOURCE) && (_XOPEN_SOURCE >= 500)
+ #define QT_SNPRINTF ::snprintf
+ #define QT_VSNPRINTF ::vsnprintf
+diff --git a/qtbase/src/3rdparty/angle/src/libANGLE/HandleAllocator.cpp b/qtbase/src/3rdparty/angle/src/libANGLE/HandleAllocator.cpp
+index c3c184258f..32af3f8f29 100644
+--- a/qtbase/src/3rdparty/angle/src/libANGLE/HandleAllocator.cpp
++++ b/qtbase/src/3rdparty/angle/src/libANGLE/HandleAllocator.cpp
+@@ -10,6 +10,7 @@
+ #include "libANGLE/HandleAllocator.h"
+
+ #include <algorithm>
++#include <limits>
+
+ #include "common/debug.h"
+
+diff --git a/qtbase/src/3rdparty/forkfd/forkfd_linux.c b/qtbase/src/3rdparty/forkfd/forkfd_linux.c
+index ffe0e9a5e2..b1f5408d11 100644
+--- a/qtbase/src/3rdparty/forkfd/forkfd_linux.c
++++ b/qtbase/src/3rdparty/forkfd/forkfd_linux.c
+@@ -82,7 +82,8 @@ static int sys_clone(unsigned long cloneflags, int *ptid)
+ return syscall(__NR_clone, cloneflags, child_stack, stack_size, ptid, newtls, ctid);
+ #elif defined(__arc__) || defined(__arm__) || defined(__aarch64__) || defined(__mips__) || \
+ defined(__nds32__) || defined(__hppa__) || defined(__powerpc__) || defined(__i386__) || \
+- defined(__x86_64__) || defined(__xtensa__) || defined(__alpha__) || defined(__riscv)
++ defined(__x86_64__) || defined(__xtensa__) || defined(__alpha__) || defined(__riscv) || \
++ defined(__loongarch__)
+ /* ctid and newtls are inverted on CONFIG_CLONE_BACKWARDS architectures,
+ * but since both values are 0, there's no harm. */
+ return syscall(__NR_clone, cloneflags, child_stack, ptid, ctid, newtls);
+diff --git a/qtbase/src/android/jar/src/org/qtproject/qt5/android/QtNative.java b/qtbase/src/android/jar/src/org/qtproject/qt5/android/QtNative.java
+index 5792b5b2f5..2f74750fcf 100644
+--- a/qtbase/src/android/jar/src/org/qtproject/qt5/android/QtNative.java
++++ b/qtbase/src/android/jar/src/org/qtproject/qt5/android/QtNative.java
+@@ -116,6 +116,7 @@ public class QtNative
+ public static QtThread m_qtThread = new QtThread();
+ private static HashMap<String, Uri> m_cachedUris = new HashMap<String, Uri>();
+ private static ArrayList<String> m_knownDirs = new ArrayList<String>();
++ private static final String NoPermissionErrorMessage = "No permissions to open Uri";
+
+ private static final Runnable runPendingCppRunnablesRunnable = new Runnable() {
+ @Override
+@@ -193,11 +194,10 @@ public class QtNative
+ return iterUri;
+ }
+
+- // Android 6 and earlier could still manage to open the file so we can return the
+- // parsed uri here
+- if (Build.VERSION.SDK_INT < 24)
+- return parsedUri;
+- return null;
++ // if we only have transient permissions on uri all the above will fail,
++ // but we will be able to read the file anyway, so continue with uri here anyway
++ // and check for SecurityExceptions later
++ return parsedUri;
+ } catch (SecurityException e) {
+ e.printStackTrace();
+ return null;
+@@ -244,7 +244,7 @@ public class QtNative
+ int error = -1;
+
+ if (uri == null) {
+- Log.e(QtTAG, "openFdForContentUrl(): No permissions to open Uri");
++ Log.e(QtTAG, "openFdForContentUrl(): " + NoPermissionErrorMessage);
+ return error;
+ }
+
+@@ -254,12 +254,13 @@ public class QtNative
+ return fdDesc.detachFd();
+ } catch (FileNotFoundException e) {
+ e.printStackTrace();
+- return error;
+ } catch (IllegalArgumentException e) {
+ Log.e(QtTAG, "openFdForContentUrl(): Invalid Uri");
+ e.printStackTrace();
+- return error;
++ } catch (SecurityException e) {
++ Log.e(QtTAG, NoPermissionErrorMessage);
+ }
++ return error;
+ }
+
+ public static long getSize(Context context, String contentUrl)
+@@ -270,7 +271,7 @@ public class QtNative
+ uri = getUriWithValidPermission(context, contentUrl, "r");
+
+ if (uri == null) {
+- Log.e(QtTAG, "getSize(): No permissions to open Uri");
++ Log.e(QtTAG, NoPermissionErrorMessage);
+ return size;
+ } else if (!m_cachedUris.containsKey(contentUrl)) {
+ m_cachedUris.put(contentUrl, uri);
+@@ -288,12 +289,13 @@ public class QtNative
+ } catch (IllegalArgumentException e) {
+ Log.e(QtTAG, "getSize(): Invalid Uri");
+ e.printStackTrace();
+- return size;
+ } catch (UnsupportedOperationException e) {
+ Log.e(QtTAG, "getSize(): Unsupported operation for given Uri");
+ e.printStackTrace();
+- return size;
++ } catch (SecurityException e) {
++ Log.e(QtTAG, NoPermissionErrorMessage);
+ }
++ return size;
+ }
+
+ public static boolean checkFileExists(Context context, String contentUrl)
+@@ -303,7 +305,7 @@ public class QtNative
+ if (uri == null)
+ uri = getUriWithValidPermission(context, contentUrl, "r");
+ if (uri == null) {
+- Log.e(QtTAG, "checkFileExists(): No permissions to open Uri");
++ Log.e(QtTAG, NoPermissionErrorMessage);
+ return exists;
+ } else {
+ if (!m_cachedUris.containsKey(contentUrl))
+@@ -321,12 +323,13 @@ public class QtNative
+ } catch (IllegalArgumentException e) {
+ Log.e(QtTAG, "checkFileExists(): Invalid Uri");
+ e.printStackTrace();
+- return exists;
+ } catch (UnsupportedOperationException e) {
+ Log.e(QtTAG, "checkFileExists(): Unsupported operation for given Uri");
+ e.printStackTrace();
+- return false;
++ } catch (SecurityException e) {
++ Log.e(QtTAG, NoPermissionErrorMessage);
+ }
++ return exists;
+ }
+
+ public static boolean checkIfWritable(Context context, String contentUrl)
+@@ -344,7 +347,7 @@ public class QtNative
+ uri = getUriWithValidPermission(context, contentUrl, "r");
+ }
+ if (uri == null) {
+- Log.e(QtTAG, "isDir(): No permissions to open Uri");
++ Log.e(QtTAG, NoPermissionErrorMessage);
+ return isDir;
+ } else {
+ if (!m_cachedUris.containsKey(contentUrl))
+@@ -374,12 +377,13 @@ public class QtNative
+ } catch (IllegalArgumentException e) {
+ Log.e(QtTAG, "checkIfDir(): Invalid Uri");
+ e.printStackTrace();
+- return false;
+ } catch (UnsupportedOperationException e) {
+ Log.e(QtTAG, "checkIfDir(): Unsupported operation for given Uri");
+ e.printStackTrace();
+- return false;
++ } catch (SecurityException e) {
++ Log.e(QtTAG, NoPermissionErrorMessage);
+ }
++ return false;
+ }
+ public static String[] listContentsFromTreeUri(Context context, String contentUrl)
+ {
+diff --git a/qtbase/src/concurrent/qtconcurrentreducekernel.h b/qtbase/src/concurrent/qtconcurrentreducekernel.h
+index 8f9a938952..a98dedef2e 100644
+--- a/qtbase/src/concurrent/qtconcurrentreducekernel.h
++++ b/qtbase/src/concurrent/qtconcurrentreducekernel.h
+@@ -212,11 +212,13 @@ public:
+
+ inline bool shouldThrottle()
+ {
++ std::lock_guard<QMutex> locker(mutex);
+ return (resultsMapSize > (ReduceQueueThrottleLimit * threadCount));
+ }
+
+ inline bool shouldStartThread()
+ {
++ std::lock_guard<QMutex> locker(mutex);
+ return (resultsMapSize <= (ReduceQueueStartLimit * threadCount));
+ }
+ };
+diff --git a/qtbase/src/concurrent/qtconcurrentthreadengine.cpp b/qtbase/src/concurrent/qtconcurrentthreadengine.cpp
+index ea6ce3ac42..7f91a2ba68 100644
+--- a/qtbase/src/concurrent/qtconcurrentthreadengine.cpp
++++ b/qtbase/src/concurrent/qtconcurrentthreadengine.cpp
+@@ -176,6 +176,39 @@ void ThreadEngineBase::startSingleThreaded()
+ finish();
+ }
+
++void ThreadEngineBase::startBlocking()
++{
++ start();
++ barrier.acquire();
++ startThreads();
++
++ bool throttled = false;
++#ifndef QT_NO_EXCEPTIONS
++ try {
++#endif
++ while (threadFunction() == ThrottleThread) {
++ if (threadThrottleExit()) {
++ throttled = true;
++ break;
++ }
++ }
++#ifndef QT_NO_EXCEPTIONS
++ } catch (QException &e) {
++ handleException(e);
++ } catch (...) {
++ handleException(QUnhandledException());
++ }
++#endif
++
++ if (throttled == false) {
++ barrier.release();
++ }
++
++ barrier.wait();
++ finish();
++ exceptionStore.throwPossibleException();
++}
++
+ void ThreadEngineBase::startThread()
+ {
+ startThreadInternal();
+diff --git a/qtbase/src/concurrent/qtconcurrentthreadengine.h b/qtbase/src/concurrent/qtconcurrentthreadengine.h
+index 7c30cebdbc..a4c8548cc4 100644
+--- a/qtbase/src/concurrent/qtconcurrentthreadengine.h
++++ b/qtbase/src/concurrent/qtconcurrentthreadengine.h
+@@ -91,6 +91,7 @@ public:
+ ThreadEngineBase();
+ virtual ~ThreadEngineBase();
+ void startSingleThreaded();
++ void startBlocking();
+ void startThread();
+ bool isCanceled();
+ void waitForResume();
+@@ -143,6 +144,15 @@ public:
+ return result();
+ }
+
++ // Runs the user algorithm using multiple threads.
++ // This function blocks until the algorithm is finished,
++ // and then returns the result.
++ T *startBlocking()
++ {
++ ThreadEngineBase::startBlocking();
++ return result();
++ }
++
+ // Runs the user algorithm using multiple threads.
+ // Does not block, returns a future.
+ QFuture<T> startAsynchronously()
+@@ -223,6 +233,13 @@ class ThreadEngineStarter : public ThreadEngineStarterBase<T>
+ public:
+ ThreadEngineStarter(TypedThreadEngine *eng)
+ : Base(eng) { }
++
++ T startBlocking()
++ {
++ T t = *this->threadEngine->startBlocking();
++ delete this->threadEngine;
++ return t;
++ }
+ };
+
+ // Full template specialization where T is void.
+@@ -232,6 +249,12 @@ class ThreadEngineStarter<void> : public ThreadEngineStarterBase<void>
+ public:
+ ThreadEngineStarter(ThreadEngine<void> *_threadEngine)
+ : ThreadEngineStarterBase<void>(_threadEngine) {}
++
++ void startBlocking()
++ {
++ this->threadEngine->startBlocking();
++ delete this->threadEngine;
++ }
+ };
+
+ //! [qtconcurrentthreadengine-1]
+diff --git a/qtbase/src/corelib/animation/qvariantanimation.cpp b/qtbase/src/corelib/animation/qvariantanimation.cpp
+index 98b02f0202..eac1524107 100644
+--- a/qtbase/src/corelib/animation/qvariantanimation.cpp
++++ b/qtbase/src/corelib/animation/qvariantanimation.cpp
+@@ -276,7 +276,9 @@ void QVariantAnimationPrivate::setCurrentValueForProgress(const qreal progress)
+
+ const qreal startProgress = currentInterval.start.first;
+ const qreal endProgress = currentInterval.end.first;
+- const qreal localProgress = (progress - startProgress) / (endProgress - startProgress);
++ const qreal localProgress =
++ qIsNull(progress - startProgress) ? 0.0 // avoid 0/0 below
++ /* else */ : (progress - startProgress) / (endProgress - startProgress);
+
+ QVariant ret = q->interpolated(currentInterval.start.second,
+ currentInterval.end.second,
+diff --git a/qtbase/src/corelib/global/qnamespace.h b/qtbase/src/corelib/global/qnamespace.h
+index ad4150b317..bf19b1627b 100644
+--- a/qtbase/src/corelib/global/qnamespace.h
++++ b/qtbase/src/corelib/global/qnamespace.h
+@@ -1864,7 +1864,7 @@ public:
+ QT_Q_ENUM(TimerType)
+ QT_Q_ENUM(ScrollPhase)
+ QT_Q_ENUM(MouseEventSource)
+- QT_Q_FLAG(MouseEventFlag)
++ QT_Q_FLAG(MouseEventFlags)
+ QT_Q_ENUM(ChecksumType)
+ QT_Q_ENUM(HighDpiScaleFactorRoundingPolicy)
+ QT_Q_ENUM(TabFocusBehavior)
+diff --git a/qtbase/src/corelib/global/qrandom.cpp b/qtbase/src/corelib/global/qrandom.cpp
+index 10672c1f92..25f87c7e6a 100644
+--- a/qtbase/src/corelib/global/qrandom.cpp
++++ b/qtbase/src/corelib/global/qrandom.cpp
+@@ -383,7 +383,6 @@ struct QRandomGenerator::SystemAndGlobalGenerators
+
+ constexpr SystemAndGlobalGenerators g = {};
+ Q_UNUSED(g);
+- Q_STATIC_ASSERT(std::is_literal_type<SystemAndGlobalGenerators>::value);
+ #endif
+ }
+
+diff --git a/qtbase/src/corelib/io/qbuffer.cpp b/qtbase/src/corelib/io/qbuffer.cpp
+index 595fcd2724..032c0ddd4b 100644
+--- a/qtbase/src/corelib/io/qbuffer.cpp
++++ b/qtbase/src/corelib/io/qbuffer.cpp
+@@ -41,6 +41,8 @@
+ #include <QtCore/qmetaobject.h>
+ #include "private/qiodevice_p.h"
+
++#include <limits>
++
+ QT_BEGIN_NAMESPACE
+
+ /** QBufferPrivate **/
+@@ -366,7 +368,9 @@ qint64 QBuffer::size() const
+ bool QBuffer::seek(qint64 pos)
+ {
+ Q_D(QBuffer);
+- if (pos > d->buf->size() && isWritable()) {
++ const auto oldBufSize = d->buf->size();
++ constexpr qint64 MaxSeekPos = (std::numeric_limits<decltype(oldBufSize)>::max)();
++ if (pos <= MaxSeekPos && pos > oldBufSize && isWritable()) {
+ if (seek(d->buf->size())) {
+ const qint64 gapSize = pos - d->buf->size();
+ if (write(QByteArray(gapSize, 0)) != gapSize) {
+@@ -377,7 +381,7 @@ bool QBuffer::seek(qint64 pos)
+ return false;
+ }
+ } else if (pos > d->buf->size() || pos < 0) {
+- qWarning("QBuffer::seek: Invalid pos: %d", int(pos));
++ qWarning("QBuffer::seek: Invalid pos: %lld", pos);
+ return false;
+ }
+ return QIODevice::seek(pos);
+diff --git a/qtbase/src/corelib/io/qfilesystemengine_win.cpp b/qtbase/src/corelib/io/qfilesystemengine_win.cpp
+index 81d3a71986..c86ed1f9b0 100644
+--- a/qtbase/src/corelib/io/qfilesystemengine_win.cpp
++++ b/qtbase/src/corelib/io/qfilesystemengine_win.cpp
+@@ -664,14 +664,14 @@ QFileSystemEntry QFileSystemEngine::absoluteName(const QFileSystemEntry &entry)
+ return QFileSystemEntry(ret, QFileSystemEntry::FromInternalPath());
+ }
+
+-#if defined(Q_CC_MINGW) && WINVER < 0x0602 // Windows 8 onwards
++#if defined(Q_CC_MINGW) && WINVER < 0x0602 && _WIN32_WINNT < _WIN32_WINNT_WIN8 // Windows 8 onwards
+
+ typedef struct _FILE_ID_INFO {
+ ULONGLONG VolumeSerialNumber;
+ FILE_ID_128 FileId;
+ } FILE_ID_INFO, *PFILE_ID_INFO;
+
+-#endif // if defined (Q_CC_MINGW) && WINVER < 0x0602
++#endif // if defined(Q_CC_MINGW) && WINVER < 0x0602 && _WIN32_WINNT < _WIN32_WINNT_WIN8
+
+ // File ID for Windows up to version 7 and FAT32 drives
+ static inline QByteArray fileId(HANDLE handle)
+diff --git a/qtbase/src/corelib/io/qfilesystemwatcher_inotify.cpp b/qtbase/src/corelib/io/qfilesystemwatcher_inotify.cpp
+index 94d9d06bcb..27e0b13b0b 100644
+--- a/qtbase/src/corelib/io/qfilesystemwatcher_inotify.cpp
++++ b/qtbase/src/corelib/io/qfilesystemwatcher_inotify.cpp
+@@ -366,7 +366,9 @@ void QInotifyFileSystemWatcherEngine::readFromInotify()
+ // qDebug("QInotifyFileSystemWatcherEngine::readFromInotify");
+
+ int buffSize = 0;
+- ioctl(inotifyFd, FIONREAD, (char *) &buffSize);
++ if (ioctl(inotifyFd, FIONREAD, (char *) &buffSize) == -1 || buffSize == 0)
++ return;
++
+ QVarLengthArray<char, 4096> buffer(buffSize);
+ buffSize = read(inotifyFd, buffer.data(), buffSize);
+ char *at = buffer.data();
+diff --git a/qtbase/src/corelib/io/qlockfile_win.cpp b/qtbase/src/corelib/io/qlockfile_win.cpp
+index 277f8d4230..38ecef5550 100644
+--- a/qtbase/src/corelib/io/qlockfile_win.cpp
++++ b/qtbase/src/corelib/io/qlockfile_win.cpp
+@@ -48,6 +48,8 @@
+ #include "QtCore/qdebug.h"
+ #include "QtCore/qthread.h"
+
++#include "private/qsystemlibrary_p.h"
++
+ QT_BEGIN_NAMESPACE
+
+ static inline bool fileExists(const wchar_t *fileName)
+@@ -150,7 +152,7 @@ QString QLockFilePrivate::processNameByPid(qint64 pid)
+ #if !defined(Q_OS_WINRT)
+ typedef DWORD (WINAPI *GetModuleFileNameExFunc)(HANDLE, HMODULE, LPTSTR, DWORD);
+
+- HMODULE hPsapi = LoadLibraryA("psapi");
++ HMODULE hPsapi = QSystemLibrary::load(L"psapi");
+ if (!hPsapi)
+ return QString();
+ GetModuleFileNameExFunc qGetModuleFileNameEx = reinterpret_cast<GetModuleFileNameExFunc>(
+diff --git a/qtbase/src/corelib/io/qprocess_unix.cpp b/qtbase/src/corelib/io/qprocess_unix.cpp
+index 50390e57f5..15c8f30745 100644
+--- a/qtbase/src/corelib/io/qprocess_unix.cpp
++++ b/qtbase/src/corelib/io/qprocess_unix.cpp
+@@ -1,7 +1,7 @@
+ /****************************************************************************
+ **
+ ** Copyright (C) 2016 The Qt Company Ltd.
+-** Copyright (C) 2016 Intel Corporation.
++** Copyright (C) 2022 Intel Corporation.
+ ** Contact: https://www.qt.io/licensing/
+ **
+ ** This file is part of the QtCore module of the Qt Toolkit.
+@@ -422,14 +422,15 @@ void QProcessPrivate::startProcess()
+ // Add the program name to the argument list.
+ argv[0] = nullptr;
+ if (!program.contains(QLatin1Char('/'))) {
++ // findExecutable() returns its argument if it's an absolute path,
++ // otherwise it searches $PATH; returns empty if not found (we handle
++ // that case much later)
+ const QString &exeFilePath = QStandardPaths::findExecutable(program);
+- if (!exeFilePath.isEmpty()) {
+- const QByteArray &tmp = QFile::encodeName(exeFilePath);
+- argv[0] = ::strdup(tmp.constData());
+- }
+- }
+- if (!argv[0])
++ const QByteArray &tmp = QFile::encodeName(exeFilePath);
++ argv[0] = ::strdup(tmp.constData());
++ } else {
+ argv[0] = ::strdup(encodedProgramName.constData());
++ }
+
+ // Add every argument to the list
+ for (int i = 0; i < arguments.count(); ++i)
+@@ -983,15 +984,16 @@ bool QProcessPrivate::startDetached(qint64 *pid)
+ envp = _q_dupEnvironment(environment.d.constData()->vars, &envc);
+ }
+
+- QByteArray tmp;
+ if (!program.contains(QLatin1Char('/'))) {
++ // findExecutable() returns its argument if it's an absolute path,
++ // otherwise it searches $PATH; returns empty if not found (we handle
++ // that case much later)
+ const QString &exeFilePath = QStandardPaths::findExecutable(program);
+- if (!exeFilePath.isEmpty())
+- tmp = QFile::encodeName(exeFilePath);
++ const QByteArray &tmp = QFile::encodeName(exeFilePath);
++ argv[0] = ::strdup(tmp.constData());
++ } else {
++ argv[0] = ::strdup(QFile::encodeName(program));
+ }
+- if (tmp.isEmpty())
+- tmp = QFile::encodeName(program);
+- argv[0] = tmp.data();
+
+ if (envp)
+ qt_safe_execve(argv[0], argv, envp);
+diff --git a/qtbase/src/corelib/itemmodels/qabstractitemmodel.cpp b/qtbase/src/corelib/itemmodels/qabstractitemmodel.cpp
+index 3a79c502af..997a634e76 100644
+--- a/qtbase/src/corelib/itemmodels/qabstractitemmodel.cpp
++++ b/qtbase/src/corelib/itemmodels/qabstractitemmodel.cpp
+@@ -3196,9 +3196,8 @@ bool QAbstractItemModel::beginMoveColumns(const QModelIndex &sourceParent, int s
+ destinationChange.needsAdjust = destinationParent.isValid() && destinationParent.row() >= sourceLast && destinationParent.parent() == sourceParent;
+ d->changes.push(destinationChange);
+
+- d->itemsAboutToBeMoved(sourceParent, sourceFirst, sourceLast, destinationParent, destinationChild, Qt::Horizontal);
+-
+ emit columnsAboutToBeMoved(sourceParent, sourceFirst, sourceLast, destinationParent, destinationChild, QPrivateSignal());
++ d->itemsAboutToBeMoved(sourceParent, sourceFirst, sourceLast, destinationParent, destinationChild, Qt::Horizontal);
+ return true;
+ }
+
+@@ -3231,7 +3230,6 @@ void QAbstractItemModel::endMoveColumns()
+ adjustedSource = createIndex(adjustedSource.row(), adjustedSource.column() + numMoved, adjustedSource.internalPointer());
+
+ d->itemsMoved(adjustedSource, removeChange.first, removeChange.last, adjustedDestination, insertChange.first, Qt::Horizontal);
+-
+ emit columnsMoved(adjustedSource, removeChange.first, removeChange.last, adjustedDestination, insertChange.first, QPrivateSignal());
+ }
+
+diff --git a/qtbase/src/corelib/itemmodels/qsortfilterproxymodel.cpp b/qtbase/src/corelib/itemmodels/qsortfilterproxymodel.cpp
+index dc6379d9fb..c5e287ee84 100644
+--- a/qtbase/src/corelib/itemmodels/qsortfilterproxymodel.cpp
++++ b/qtbase/src/corelib/itemmodels/qsortfilterproxymodel.cpp
+@@ -939,8 +939,9 @@ void QSortFilterProxyModelPrivate::insert_source_items(
+ q->beginInsertColumns(proxy_parent, proxy_start, proxy_end);
+ }
+
+- for (int i = 0; i < source_items.size(); ++i)
+- proxy_to_source.insert(proxy_start + i, source_items.at(i));
++ // TODO: use the range QList::insert() overload once it is implemented (QTBUG-58633).
++ proxy_to_source.insert(proxy_start, source_items.size(), 0);
++ std::copy(source_items.cbegin(), source_items.cend(), proxy_to_source.begin() + proxy_start);
+
+ build_source_to_proxy_mapping(proxy_to_source, source_to_proxy);
+
+@@ -3123,8 +3124,9 @@ bool QSortFilterProxyModel::filterAcceptsRow(int source_row, const QModelIndex &
+
+ if (d->filter_data.isEmpty())
+ return true;
++
++ int column_count = d->model->columnCount(source_parent);
+ if (d->filter_column == -1) {
+- int column_count = d->model->columnCount(source_parent);
+ for (int column = 0; column < column_count; ++column) {
+ QModelIndex source_index = d->model->index(source_row, column, source_parent);
+ QString key = d->model->data(source_index, d->filter_role).toString();
+@@ -3133,9 +3135,10 @@ bool QSortFilterProxyModel::filterAcceptsRow(int source_row, const QModelIndex &
+ }
+ return false;
+ }
+- QModelIndex source_index = d->model->index(source_row, d->filter_column, source_parent);
+- if (!source_index.isValid()) // the column may not exist
++
++ if (d->filter_column >= column_count) // the column may not exist
+ return true;
++ QModelIndex source_index = d->model->index(source_row, d->filter_column, source_parent);
+ QString key = d->model->data(source_index, d->filter_role).toString();
+ return d->filter_data.hasMatch(key);
+ }
+diff --git a/qtbase/src/corelib/kernel/qcoreapplication.cpp b/qtbase/src/corelib/kernel/qcoreapplication.cpp
+index ca2864df83..132b2eae52 100644
+--- a/qtbase/src/corelib/kernel/qcoreapplication.cpp
++++ b/qtbase/src/corelib/kernel/qcoreapplication.cpp
+@@ -1157,7 +1157,7 @@ static bool doNotify(QObject *receiver, QEvent *event)
+ bool QCoreApplicationPrivate::sendThroughApplicationEventFilters(QObject *receiver, QEvent *event)
+ {
+ // We can't access the application event filters outside of the main thread (race conditions)
+- Q_ASSERT(receiver->d_func()->threadData.loadRelaxed()->thread.loadAcquire() == mainThread());
++ Q_ASSERT(receiver->d_func()->threadData.loadAcquire()->thread.loadRelaxed() == mainThread());
+
+ if (extraData) {
+ // application event filters are only called for objects in the GUI thread
+diff --git a/qtbase/src/corelib/kernel/qobject.cpp b/qtbase/src/corelib/kernel/qobject.cpp
+index 1eb79138d9..36cd780ee1 100644
+--- a/qtbase/src/corelib/kernel/qobject.cpp
++++ b/qtbase/src/corelib/kernel/qobject.cpp
+@@ -1010,7 +1010,7 @@ QObject::~QObject()
+ emit destroyed(this);
+ }
+
+- if (d->declarativeData) {
++ if (!d->isDeletingChildren && d->declarativeData) {
+ if (static_cast<QAbstractDeclarativeDataImpl*>(d->declarativeData)->ownedByQml1) {
+ if (QAbstractDeclarativeData::destroyed_qml1)
+ QAbstractDeclarativeData::destroyed_qml1(d->declarativeData, this);
+@@ -1580,7 +1580,7 @@ void QObject::moveToThread(QThread *targetThread)
+
+ QThreadData *currentData = QThreadData::current();
+ QThreadData *targetData = targetThread ? QThreadData::get2(targetThread) : nullptr;
+- QThreadData *thisThreadData = d->threadData.loadRelaxed();
++ QThreadData *thisThreadData = d->threadData.loadAcquire();
+ if (!thisThreadData->thread.loadAcquire() && currentData == targetData) {
+ // one exception to the rule: we allow moving objects with no thread affinity to the current thread
+ currentData = d->threadData;
+@@ -2620,7 +2620,7 @@ int QObject::receivers(const char *signal) const
+ if (!d->isSignalConnected(signal_index))
+ return receivers;
+
+- if (d->declarativeData && QAbstractDeclarativeData::receivers) {
++ if (!d->isDeletingChildren && d->declarativeData && QAbstractDeclarativeData::receivers) {
+ receivers += QAbstractDeclarativeData::receivers(d->declarativeData, this,
+ signal_index);
+ }
+diff --git a/qtbase/src/corelib/kernel/qobject_p.h b/qtbase/src/corelib/kernel/qobject_p.h
+index 0b827a52ca..13ffb88999 100644
+--- a/qtbase/src/corelib/kernel/qobject_p.h
++++ b/qtbase/src/corelib/kernel/qobject_p.h
+@@ -444,7 +444,7 @@ inline void QObjectPrivate::checkForIncompatibleLibraryVersion(int version) cons
+
+ inline bool QObjectPrivate::isDeclarativeSignalConnected(uint signal_index) const
+ {
+- return declarativeData && QAbstractDeclarativeData::isSignalConnected
++ return !isDeletingChildren && declarativeData && QAbstractDeclarativeData::isSignalConnected
+ && QAbstractDeclarativeData::isSignalConnected(declarativeData, q_func(), signal_index);
+ }
+
+diff --git a/qtbase/src/corelib/kernel/qtranslator.cpp b/qtbase/src/corelib/kernel/qtranslator.cpp
+index 2812ffb7ea..bc0177c5ec 100644
+--- a/qtbase/src/corelib/kernel/qtranslator.cpp
++++ b/qtbase/src/corelib/kernel/qtranslator.cpp
+@@ -902,7 +902,7 @@ static QString getMessage(const uchar *m, const uchar *end, const char *context,
+ goto end;
+ case Tag_Translation: {
+ int len = read32(m);
+- if (len % 1)
++ if (len & 1)
+ return QString();
+ m += 4;
+ if (!numerus--) {
+diff --git a/qtbase/src/corelib/mimetypes/qmimedatabase.cpp b/qtbase/src/corelib/mimetypes/qmimedatabase.cpp
+index 9de22cef33..ff868a3268 100644
+--- a/qtbase/src/corelib/mimetypes/qmimedatabase.cpp
++++ b/qtbase/src/corelib/mimetypes/qmimedatabase.cpp
+@@ -389,20 +389,23 @@ QMimeType QMimeDatabasePrivate::mimeTypeForFileNameAndData(const QString &fileNa
+ // Disambiguate conflicting extensions (if magic matching found something)
+ if (candidateByData.isValid() && magicAccuracy > 0) {
+ const QString sniffedMime = candidateByData.name();
+- // If the sniffedMime matches a glob match, use it
++ // If the sniffedMime matches a highest-weight glob match, use it
+ if (candidatesByName.m_matchingMimeTypes.contains(sniffedMime)) {
+ *accuracyPtr = 100;
+ return candidateByData;
+ }
+- for (const QString &m : qAsConst(candidatesByName.m_matchingMimeTypes)) {
++ for (const QString &m : qAsConst(candidatesByName.m_allMatchingMimeTypes)) {
+ if (inherits(m, sniffedMime)) {
+ // We have magic + pattern pointing to this, so it's a pretty good match
+ *accuracyPtr = 100;
+ return mimeTypeForName(m);
+ }
+ }
+- *accuracyPtr = magicAccuracy;
+- return candidateByData;
++ if (candidatesByName.m_allMatchingMimeTypes.isEmpty()) {
++ // No glob, use magic
++ *accuracyPtr = magicAccuracy;
++ return candidateByData;
++ }
+ }
+ }
+
+diff --git a/qtbase/src/corelib/mimetypes/qmimeglobpattern.cpp b/qtbase/src/corelib/mimetypes/qmimeglobpattern.cpp
+index a81112d227..fa8f4c545d 100644
+--- a/qtbase/src/corelib/mimetypes/qmimeglobpattern.cpp
++++ b/qtbase/src/corelib/mimetypes/qmimeglobpattern.cpp
+@@ -83,7 +83,10 @@ void QMimeGlobMatchResult::addMatch(const QString &mimeType, int weight, const Q
+ }
+ if (!m_matchingMimeTypes.contains(mimeType)) {
+ m_matchingMimeTypes.append(mimeType);
+- m_allMatchingMimeTypes.append(mimeType);
++ if (replace)
++ m_allMatchingMimeTypes.prepend(mimeType); // highest-weight first
++ else
++ m_allMatchingMimeTypes.append(mimeType);
+ m_knownSuffixLength = knownSuffixLength;
+ }
+ }
+@@ -94,7 +97,7 @@ QMimeGlobPattern::PatternType QMimeGlobPattern::detectPatternType(const QString
+ if (!patternLength)
+ return OtherPattern;
+
+- const bool starCount = pattern.count(QLatin1Char('*')) == 1;
++ const int starCount = pattern.count(QLatin1Char('*'));
+ const bool hasSquareBracket = pattern.indexOf(QLatin1Char('[')) != -1;
+ const bool hasQuestionMark = pattern.indexOf(QLatin1Char('?')) != -1;
+
+@@ -106,10 +109,10 @@ QMimeGlobPattern::PatternType QMimeGlobPattern::detectPatternType(const QString
+ // Patterns like "README*" (well this is currently the only one like that...)
+ if (pattern.at(patternLength - 1) == QLatin1Char('*'))
+ return PrefixPattern;
+- }
+- // Names without any wildcards like "README"
+- if (starCount == 0)
++ } else if (starCount == 0) {
++ // Names without any wildcards like "README"
+ return LiteralPattern;
++ }
+ }
+
+ if (pattern == QLatin1String("[0-9][0-9][0-9].vdr"))
+diff --git a/qtbase/src/corelib/mimetypes/qmimeprovider.cpp b/qtbase/src/corelib/mimetypes/qmimeprovider.cpp
+index 258dddf8cb..4642d0f2d0 100644
+--- a/qtbase/src/corelib/mimetypes/qmimeprovider.cpp
++++ b/qtbase/src/corelib/mimetypes/qmimeprovider.cpp
+@@ -244,15 +244,18 @@ void QMimeBinaryProvider::addFileNameMatches(const QString &fileName, QMimeGlobM
+ const QString lowerFileName = fileName.toLower();
+ // Check literals (e.g. "Makefile")
+ matchGlobList(result, m_cacheFile, m_cacheFile->getUint32(PosLiteralListOffset), fileName);
+- // Check complex globs (e.g. "callgrind.out[0-9]*")
+- matchGlobList(result, m_cacheFile, m_cacheFile->getUint32(PosGlobListOffset), fileName);
+ // Check the very common *.txt cases with the suffix tree
+- const int reverseSuffixTreeOffset = m_cacheFile->getUint32(PosReverseSuffixTreeOffset);
+- const int numRoots = m_cacheFile->getUint32(reverseSuffixTreeOffset);
+- const int firstRootOffset = m_cacheFile->getUint32(reverseSuffixTreeOffset + 4);
+- matchSuffixTree(result, m_cacheFile, numRoots, firstRootOffset, lowerFileName, lowerFileName.length() - 1, false);
++ if (result.m_matchingMimeTypes.isEmpty()) {
++ const int reverseSuffixTreeOffset = m_cacheFile->getUint32(PosReverseSuffixTreeOffset);
++ const int numRoots = m_cacheFile->getUint32(reverseSuffixTreeOffset);
++ const int firstRootOffset = m_cacheFile->getUint32(reverseSuffixTreeOffset + 4);
++ matchSuffixTree(result, m_cacheFile, numRoots, firstRootOffset, lowerFileName, lowerFileName.length() - 1, false);
++ if (result.m_matchingMimeTypes.isEmpty())
++ matchSuffixTree(result, m_cacheFile, numRoots, firstRootOffset, fileName, fileName.length() - 1, true);
++ }
++ // Check complex globs (e.g. "callgrind.out[0-9]*" or "README*")
+ if (result.m_matchingMimeTypes.isEmpty())
+- matchSuffixTree(result, m_cacheFile, numRoots, firstRootOffset, fileName, fileName.length() - 1, true);
++ matchGlobList(result, m_cacheFile, m_cacheFile->getUint32(PosGlobListOffset), fileName);
+ }
+
+ void QMimeBinaryProvider::matchGlobList(QMimeGlobMatchResult &result, CacheFile *cacheFile, int off, const QString &fileName)
+diff --git a/qtbase/src/corelib/serialization/qjsonparser.cpp b/qtbase/src/corelib/serialization/qjsonparser.cpp
+index 17e6f111ab..2e40b6c8fb 100644
+--- a/qtbase/src/corelib/serialization/qjsonparser.cpp
++++ b/qtbase/src/corelib/serialization/qjsonparser.cpp
+@@ -379,10 +379,30 @@ error:
+ return QCborValue();
+ }
+
++// We need to retain the _last_ value for any duplicate keys and we need to deref containers.
++// Therefore the manual implementation of std::unique().
++template<typename Iterator, typename Compare, typename Assign>
++static Iterator customAssigningUniqueLast(Iterator first, Iterator last,
++ Compare compare, Assign assign)
++{
++ first = std::adjacent_find(first, last, compare);
++ if (first == last)
++ return last;
++
++ Iterator result = first;
++ while (++first != last) {
++ if (!compare(*result, *first))
++ ++result;
++ if (result != first)
++ assign(*result, *first);
++ }
++
++ return ++result;
++}
++
+ static void sortContainer(QCborContainerPrivate *container)
+ {
+ using Forward = QJsonPrivate::KeyIterator;
+- using Reverse = std::reverse_iterator<Forward>;
+ using Value = Forward::value_type;
+
+ auto compare = [container](const Value &a, const Value &b)
+@@ -420,17 +440,31 @@ static void sortContainer(QCborContainerPrivate *container)
+ }
+ };
+
+- std::sort(Forward(container->elements.begin()), Forward(container->elements.end()),
+- [&compare](const Value &a, const Value &b) { return compare(a, b) < 0; });
++ // The elements' containers are owned by the outer container, not by the elements themselves.
++ auto move = [](Forward::reference target, Forward::reference source)
++ {
++ QtCbor::Element &targetValue = target.value();
++
++ // If the target has a container, deref it before overwriting, so that we don't leak.
++ if (targetValue.flags & QtCbor::Element::IsContainer)
++ targetValue.container->deref();
++
++ // Do not move, so that we can clear the value afterwards.
++ target = source;
++
++ // Clear the source value, so that we don't store the same container twice.
++ source.value() = QtCbor::Element();
++ };
++
++ std::stable_sort(
++ Forward(container->elements.begin()), Forward(container->elements.end()),
++ [&compare](const Value &a, const Value &b) { return compare(a, b) < 0; });
+
+- // We need to retain the _last_ value for any duplicate keys. Therefore the reverse dance here.
+- auto it = std::unique(Reverse(container->elements.end()), Reverse(container->elements.begin()),
+- [&compare](const Value &a, const Value &b) {
+- return compare(a, b) == 0;
+- }).base().elementsIterator();
++ Forward result = customAssigningUniqueLast(
++ Forward(container->elements.begin()), Forward(container->elements.end()),
++ [&compare](const Value &a, const Value &b) { return compare(a, b) == 0; }, move);
+
+- // The erase from beginning is expensive but hopefully rare.
+- container->elements.erase(container->elements.begin(), it);
++ container->elements.erase(result.elementsIterator(), container->elements.end());
+ }
+
+
+diff --git a/qtbase/src/corelib/serialization/qxmlstream.cpp b/qtbase/src/corelib/serialization/qxmlstream.cpp
+index b2f846544d..7cd457ba3a 100644
+--- a/qtbase/src/corelib/serialization/qxmlstream.cpp
++++ b/qtbase/src/corelib/serialization/qxmlstream.cpp
+@@ -980,7 +980,7 @@ inline uint QXmlStreamReaderPrivate::peekChar()
+ bool QXmlStreamReaderPrivate::scanUntil(const char *str, short tokenToInject)
+ {
+ int pos = textBuffer.size();
+- int oldLineNumber = lineNumber;
++ const auto oldLineNumber = lineNumber;
+
+ uint c;
+ while ((c = getChar()) != StreamEOF) {
+diff --git a/qtbase/src/corelib/text/qstring.cpp b/qtbase/src/corelib/text/qstring.cpp
+index 3e88ab4859..8deeae47bb 100644
+--- a/qtbase/src/corelib/text/qstring.cpp
++++ b/qtbase/src/corelib/text/qstring.cpp
+@@ -12312,7 +12312,7 @@ static qsizetype qLastIndexOf(Haystack haystack0, qsizetype from,
+ const auto needle = needle0.data();
+ const auto *end = haystack;
+ haystack += from;
+- const std::size_t sl_minus_1 = sl - 1;
++ const std::size_t sl_minus_1 = sl ? sl - 1 : 0;
+ const auto *n = needle + sl_minus_1;
+ const auto *h = haystack + sl_minus_1;
+ std::size_t hashNeedle = 0, hashHaystack = 0;
+diff --git a/qtbase/src/corelib/text/qstringiterator_p.h b/qtbase/src/corelib/text/qstringiterator_p.h
+index 219589b6e4..1d0c66cc78 100644
+--- a/qtbase/src/corelib/text/qstringiterator_p.h
++++ b/qtbase/src/corelib/text/qstringiterator_p.h
+@@ -61,6 +61,8 @@ class QStringIterator
+ {
+ QString::const_iterator i, pos, e;
+ Q_STATIC_ASSERT((std::is_same<QString::const_iterator, const QChar *>::value));
++ static bool less(const QChar *lhs, const QChar *rhs) noexcept
++ { return std::less<QString::const_iterator>{}(lhs, rhs); }
+ public:
+ explicit QStringIterator(QStringView string, qsizetype idx = 0)
+ : i(string.begin()),
+@@ -95,7 +97,8 @@ public:
+
+ inline void setPosition(QString::const_iterator position)
+ {
+- Q_ASSERT_X(i <= position && position <= e, Q_FUNC_INFO, "position out of bounds");
++ Q_ASSERT_X(!less(position, i) && !less(e, position),
++ Q_FUNC_INFO, "position out of bounds");
+ pos = position;
+ }
+
+@@ -103,7 +106,7 @@ public:
+
+ inline bool hasNext() const
+ {
+- return pos < e;
++ return less(pos, e);
+ }
+
+ inline void advance()
+@@ -120,16 +123,20 @@ public:
+ {
+ Q_ASSERT_X(hasNext(), Q_FUNC_INFO, "iterator hasn't a next item");
+
+- if (Q_UNLIKELY((pos++)->isHighSurrogate()))
++ if (Q_UNLIKELY((pos++)->isHighSurrogate())) {
++ Q_ASSERT(hasNext() && pos->isLowSurrogate());
+ ++pos;
++ }
+ }
+
+ inline uint peekNextUnchecked() const
+ {
+ Q_ASSERT_X(hasNext(), Q_FUNC_INFO, "iterator hasn't a next item");
+
+- if (Q_UNLIKELY(pos->isHighSurrogate()))
++ if (Q_UNLIKELY(pos->isHighSurrogate())) {
++ Q_ASSERT(less(pos + 1, e) && pos[1].isLowSurrogate());
+ return QChar::surrogateToUcs4(pos[0], pos[1]);
++ }
+
+ return pos->unicode();
+ }
+@@ -155,8 +162,10 @@ public:
+ Q_ASSERT_X(hasNext(), Q_FUNC_INFO, "iterator hasn't a next item");
+
+ const QChar cur = *pos++;
+- if (Q_UNLIKELY(cur.isHighSurrogate()))
++ if (Q_UNLIKELY(cur.isHighSurrogate())) {
++ Q_ASSERT(hasNext() && pos->isLowSurrogate());
+ return QChar::surrogateToUcs4(cur, *pos++);
++ }
+ return cur.unicode();
+ }
+
+@@ -166,7 +175,7 @@ public:
+
+ const QChar uc = *pos++;
+ if (Q_UNLIKELY(uc.isSurrogate())) {
+- if (Q_LIKELY(uc.isHighSurrogate() && pos < e && pos->isLowSurrogate()))
++ if (Q_LIKELY(uc.isHighSurrogate() && hasNext() && pos->isLowSurrogate()))
+ return QChar::surrogateToUcs4(uc, *pos++);
+ return invalidAs;
+ }
+@@ -178,7 +187,7 @@ public:
+
+ inline bool hasPrevious() const
+ {
+- return pos > i;
++ return less(i, pos);
+ }
+
+ inline void recede()
+@@ -196,16 +205,20 @@ public:
+ {
+ Q_ASSERT_X(hasPrevious(), Q_FUNC_INFO, "iterator hasn't a previous item");
+
+- if (Q_UNLIKELY((--pos)->isLowSurrogate()))
++ if (Q_UNLIKELY((--pos)->isLowSurrogate())) {
++ Q_ASSERT(hasPrevious() && pos[-1].isHighSurrogate());
+ --pos;
++ }
+ }
+
+ inline uint peekPreviousUnchecked() const
+ {
+ Q_ASSERT_X(hasPrevious(), Q_FUNC_INFO, "iterator hasn't a previous item");
+
+- if (Q_UNLIKELY(pos[-1].isLowSurrogate()))
++ if (Q_UNLIKELY(pos[-1].isLowSurrogate())) {
++ Q_ASSERT(less(i + 1, pos) && pos[-2].isHighSurrogate());
+ return QChar::surrogateToUcs4(pos[-2], pos[-1]);
++ }
+ return pos[-1].unicode();
+ }
+
+@@ -230,8 +243,10 @@ public:
+ Q_ASSERT_X(hasPrevious(), Q_FUNC_INFO, "iterator hasn't a previous item");
+
+ const QChar cur = *--pos;
+- if (Q_UNLIKELY(cur.isLowSurrogate()))
++ if (Q_UNLIKELY(cur.isLowSurrogate())) {
++ Q_ASSERT(hasPrevious() && pos[-1].isHighSurrogate());
+ return QChar::surrogateToUcs4(*--pos, cur);
++ }
+ return cur.unicode();
+ }
+
+@@ -241,7 +256,7 @@ public:
+
+ const QChar uc = *--pos;
+ if (Q_UNLIKELY(uc.isSurrogate())) {
+- if (Q_LIKELY(uc.isLowSurrogate() && pos > i && pos[-1].isHighSurrogate()))
++ if (Q_LIKELY(uc.isLowSurrogate() && hasPrevious() && pos[-1].isHighSurrogate()))
+ return QChar::surrogateToUcs4(*--pos, uc);
+ return invalidAs;
+ }
+diff --git a/qtbase/src/corelib/thread/qfutex_p.h b/qtbase/src/corelib/thread/qfutex_p.h
+index f287b752d7..e294537787 100644
+--- a/qtbase/src/corelib/thread/qfutex_p.h
++++ b/qtbase/src/corelib/thread/qfutex_p.h
+@@ -52,6 +52,7 @@
+ //
+
+ #include <qglobal.h>
++#include <QtCore/qtsan_impl.h>
+
+ QT_BEGIN_NAMESPACE
+
+@@ -106,16 +107,13 @@ namespace QtLinuxFutex {
+ inline int _q_futex(int *addr, int op, int val, quintptr val2 = 0,
+ int *addr2 = nullptr, int val3 = 0) noexcept
+ {
+- // A futex call ensures total ordering on the futex words
+- // (in either success or failure of the call). Instruct TSAN accordingly,
+- // as TSAN does not understand the futex(2) syscall.
+- _q_tsan_release(addr, addr2);
++ QtTsan::futexRelease(addr, addr2);
+
+ // we use __NR_futex because some libcs (like Android's bionic) don't
+ // provide SYS_futex etc.
+ int result = syscall(__NR_futex, addr, op | FUTEX_PRIVATE_FLAG, val, val2, addr2, val3);
+
+- _q_tsan_acquire(addr, addr2);
++ QtTsan::futexAcquire(addr, addr2);
+
+ return result;
+ }
+diff --git a/qtbase/src/corelib/thread/qmutex.cpp b/qtbase/src/corelib/thread/qmutex.cpp
+index 310d1cb14f..7097122d8e 100644
+--- a/qtbase/src/corelib/thread/qmutex.cpp
++++ b/qtbase/src/corelib/thread/qmutex.cpp
+@@ -152,6 +152,7 @@ public:
+
+ /*!
+ \enum QMutex::RecursionMode
++ \obsolete Use QRecursiveMutex to create a recursive mutex.
+
+ \value Recursive In this mode, a thread can lock the same mutex
+ multiple times and the mutex won't be unlocked
+@@ -173,6 +174,7 @@ public:
+
+ /*!
+ Constructs a new mutex. The mutex is created in an unlocked state.
++ \obsolete Use QRecursiveMutex to create a recursive mutex.
+
+ If \a mode is QMutex::Recursive, a thread can lock the same mutex
+ multiple times and the mutex won't be unlocked until a
+@@ -197,7 +199,7 @@ QMutex::QMutex(RecursionMode mode)
+ QMutex::~QMutex()
+ {
+ QMutexData *d = d_ptr.loadRelaxed();
+- if (isRecursive()) {
++ if (QBasicMutex::isRecursive()) {
+ delete static_cast<QRecursiveMutexPrivate *>(d);
+ } else if (d) {
+ #ifndef QT_LINUX_FUTEX
+diff --git a/qtbase/src/corelib/thread/qmutex.h b/qtbase/src/corelib/thread/qmutex.h
+index 73c9e00663..1bae573a03 100644
+--- a/qtbase/src/corelib/thread/qmutex.h
++++ b/qtbase/src/corelib/thread/qmutex.h
+@@ -42,6 +42,7 @@
+
+ #include <QtCore/qglobal.h>
+ #include <QtCore/qatomic.h>
++#include <QtCore/qtsan_impl.h>
+ #include <new>
+
+ #if __has_include(<chrono>)
+@@ -77,19 +78,37 @@ public:
+
+ // BasicLockable concept
+ inline void lock() QT_MUTEX_LOCK_NOEXCEPT {
++ QtTsan::mutexPreLock(this, 0u);
++
+ if (!fastTryLock())
+ lockInternal();
++
++ QtTsan::mutexPostLock(this, 0u, 0);
+ }
+
+ // BasicLockable concept
+ inline void unlock() noexcept {
+ Q_ASSERT(d_ptr.loadRelaxed()); //mutex must be locked
++
++ QtTsan::mutexPreUnlock(this, 0u);
++
+ if (!fastTryUnlock())
+ unlockInternal();
++
++ QtTsan::mutexPostUnlock(this, 0u);
+ }
+
+ bool tryLock() noexcept {
+- return fastTryLock();
++ unsigned tsanFlags = QtTsan::TryLock;
++ QtTsan::mutexPreLock(this, tsanFlags);
++
++ const bool success = fastTryLock();
++
++ if (!success)
++ tsanFlags |= QtTsan::TryLockFailed;
++ QtTsan::mutexPostLock(this, tsanFlags, 0);
++
++ return success;
+ }
+
+ // Lockable concept
+@@ -134,8 +153,16 @@ public:
+ #else
+ QMutex() { d_ptr.storeRelaxed(nullptr); }
+ #endif
++#if QT_DEPRECATED_SINCE(5,15)
+ enum RecursionMode { NonRecursive, Recursive };
++ QT_DEPRECATED_VERSION_X(5, 15, "Use QRecursiveMutex instead of a recursive QMutex")
+ explicit QMutex(RecursionMode mode);
++
++ QT_DEPRECATED_VERSION_X(5, 15, "Use QRecursiveMutex instead of a recursive QMutex")
++ bool isRecursive() const noexcept
++ { return QBasicMutex::isRecursive(); }
++#endif
++
+ ~QMutex();
+
+ // BasicLockable concept
+@@ -166,9 +193,6 @@ public:
+ }
+ #endif
+
+- bool isRecursive() const noexcept
+- { return QBasicMutex::isRecursive(); }
+-
+ private:
+ Q_DISABLE_COPY(QMutex)
+ friend class QMutexLocker;
+diff --git a/qtbase/src/corelib/thread/qreadwritelock.cpp b/qtbase/src/corelib/thread/qreadwritelock.cpp
+index 8c28507d5a..9dd8503116 100644
+--- a/qtbase/src/corelib/thread/qreadwritelock.cpp
++++ b/qtbase/src/corelib/thread/qreadwritelock.cpp
+@@ -155,7 +155,7 @@ QReadWriteLock::QReadWriteLock(RecursionMode recursionMode)
+ */
+ QReadWriteLock::~QReadWriteLock()
+ {
+- auto d = d_ptr.loadRelaxed();
++ auto d = d_ptr.loadAcquire();
+ if (isUncontendedLocked(d)) {
+ qWarning("QReadWriteLock: destroying locked QReadWriteLock");
+ return;
+@@ -445,7 +445,7 @@ void QReadWriteLock::unlock()
+ /*! \internal Helper for QWaitCondition::wait */
+ QReadWriteLock::StateForWaitCondition QReadWriteLock::stateForWaitCondition() const
+ {
+- QReadWriteLockPrivate *d = d_ptr.loadRelaxed();
++ QReadWriteLockPrivate *d = d_ptr.loadAcquire();
+ switch (quintptr(d) & StateMask) {
+ case StateLockedForRead: return LockedForRead;
+ case StateLockedForWrite: return LockedForWrite;
+@@ -453,6 +453,7 @@ QReadWriteLock::StateForWaitCondition QReadWriteLock::stateForWaitCondition() co
+
+ if (!d)
+ return Unlocked;
++ const auto lock = qt_scoped_lock(d->mutex);
+ if (d->writerCount > 1)
+ return RecursivelyLocked;
+ else if (d->writerCount == 1)
+diff --git a/qtbase/src/corelib/thread/qsemaphore.cpp b/qtbase/src/corelib/thread/qsemaphore.cpp
+index 1d01fc1b28..3ecdee3747 100644
+--- a/qtbase/src/corelib/thread/qsemaphore.cpp
++++ b/qtbase/src/corelib/thread/qsemaphore.cpp
+@@ -354,7 +354,12 @@ void QSemaphore::release(int n)
+ quintptr nn = unsigned(n);
+ if (futexHasWaiterCount)
+ nn |= quint64(nn) << 32; // token count replicated in high word
+- quintptr prevValue = u.fetchAndAddRelease(nn);
++ quintptr prevValue = u.loadRelaxed();
++ quintptr newValue;
++ do { // loop just to ensure the operations are done atomically
++ newValue = prevValue + nn;
++ newValue &= (futexNeedsWakeAllBit - 1);
++ } while (!u.testAndSetRelease(prevValue, newValue, prevValue));
+ if (futexNeedsWake(prevValue)) {
+ #ifdef FUTEX_OP
+ if (futexHasWaiterCount) {
+@@ -376,7 +381,6 @@ void QSemaphore::release(int n)
+ quint32 oparg = 0;
+ quint32 cmp = FUTEX_OP_CMP_NE;
+ quint32 cmparg = 0;
+- u.fetchAndAndRelease(futexNeedsWakeAllBit - 1);
+ futexWakeOp(*futexLow32(&u), n, INT_MAX, *futexHigh32(&u), FUTEX_OP(op, oparg, cmp, cmparg));
+ return;
+ }
+@@ -388,7 +392,6 @@ void QSemaphore::release(int n)
+ // its acquisition anyway, so it has to wait;
+ // 2) it did not see the new counter value, in which case its
+ // futexWait will fail.
+- u.fetchAndAndRelease(futexNeedsWakeAllBit - 1);
+ if (futexHasWaiterCount) {
+ futexWakeAll(*futexLow32(&u));
+ futexWakeAll(*futexHigh32(&u));
+diff --git a/qtbase/src/corelib/thread/qthread_p.h b/qtbase/src/corelib/thread/qthread_p.h
+index b2d1628e6e..f32f6f0460 100644
+--- a/qtbase/src/corelib/thread/qthread_p.h
++++ b/qtbase/src/corelib/thread/qthread_p.h
+@@ -174,7 +174,7 @@ public:
+ int returnCode;
+
+ uint stackSize;
+- QThread::Priority priority;
++ std::underlying_type<QThread::Priority>::type priority;
+
+ static QThread *threadForId(int id);
+
+@@ -213,6 +213,13 @@ public:
+ QCoreApplication::instance()->postEvent(q_ptr, new QEvent(QEvent::Quit));
+ }
+ }
++
++#ifndef Q_OS_INTEGRITY
++private:
++ // Used in QThread(Private)::start to avoid racy access to QObject::objectName,
++ // unset afterwards. On INTEGRITY we set the thread name before starting it.
++ QString objectName;
++#endif
+ };
+
+ #else // QT_CONFIG(thread)
+diff --git a/qtbase/src/corelib/thread/qthread_unix.cpp b/qtbase/src/corelib/thread/qthread_unix.cpp
+index 56a8e0a038..610117a640 100644
+--- a/qtbase/src/corelib/thread/qthread_unix.cpp
++++ b/qtbase/src/corelib/thread/qthread_unix.cpp
+@@ -169,8 +169,7 @@ static void set_thread_data(QThreadData *data)
+
+ static void clear_thread_data()
+ {
+- currentThreadData = nullptr;
+- pthread_setspecific(current_thread_data_key, nullptr);
++ set_thread_data(nullptr);
+ }
+
+ template <typename T>
+@@ -296,7 +295,7 @@ void *QThreadPrivate::start(void *arg)
+ QMutexLocker locker(&thr->d_func()->mutex);
+
+ // do we need to reset the thread priority?
+- if (int(thr->d_func()->priority) & ThreadPriorityResetFlag) {
++ if (thr->d_func()->priority & ThreadPriorityResetFlag) {
+ thr->d_func()->setPriority(QThread::Priority(thr->d_func()->priority & ~ThreadPriorityResetFlag));
+ }
+
+@@ -316,10 +315,10 @@ void *QThreadPrivate::start(void *arg)
+ // Sets the name of the current thread. We can only do this
+ // when the thread is starting, as we don't have a cross
+ // platform way of setting the name of an arbitrary thread.
+- if (Q_LIKELY(thr->objectName().isEmpty()))
++ if (Q_LIKELY(thr->d_func()->objectName.isEmpty()))
+ setCurrentThreadName(thr->metaObject()->className());
+ else
+- setCurrentThreadName(thr->objectName().toLocal8Bit());
++ setCurrentThreadName(std::exchange(thr->d_func()->objectName, {}).toLocal8Bit());
+ }
+ #endif
+
+@@ -671,7 +670,7 @@ void QThread::start(Priority priority)
+ // could not set scheduling hints, fallback to inheriting them
+ // we'll try again from inside the thread
+ pthread_attr_setinheritsched(&attr, PTHREAD_INHERIT_SCHED);
+- d->priority = Priority(priority | ThreadPriorityResetFlag);
++ d->priority = static_cast<std::underlying_type<QThread::Priority>::type>(priority) | ThreadPriorityResetFlag;
+ }
+ break;
+ }
+@@ -702,7 +701,10 @@ void QThread::start(Priority priority)
+ pthread_attr_setthreadname(&attr, metaObject()->className());
+ else
+ pthread_attr_setthreadname(&attr, objectName().toLocal8Bit());
++#else
++ d->objectName = objectName();
+ #endif
++
+ pthread_t threadId;
+ int code = pthread_create(&threadId, &attr, QThreadPrivate::start, this);
+ if (code == EPERM) {
+diff --git a/qtbase/src/corelib/thread/qthread_win.cpp b/qtbase/src/corelib/thread/qthread_win.cpp
+index bc70e3178a..4e76972498 100644
+--- a/qtbase/src/corelib/thread/qthread_win.cpp
++++ b/qtbase/src/corelib/thread/qthread_win.cpp
+@@ -394,10 +394,9 @@ unsigned int __stdcall QT_ENSURE_STACK_ALIGNED_FOR_SSE QThreadPrivate::start(voi
+
+ #if !defined(QT_NO_DEBUG) && defined(Q_CC_MSVC) && !defined(Q_OS_WINRT)
+ // sets the name of the current thread.
+- QByteArray objectName = thr->objectName().toLocal8Bit();
+- qt_set_thread_name(HANDLE(-1),
+- objectName.isEmpty() ?
+- thr->metaObject()->className() : objectName.constData());
++ qt_set_thread_name(HANDLE(-1), thr->d_func()->objectName.isEmpty()
++ ? thr->metaObject()->className()
++ : std::exchange(thr->d_func()->objectName, {}).toLocal8Bit().constData());
+ #endif
+
+ emit thr->started(QThread::QPrivateSignal());
+@@ -503,6 +502,7 @@ void QThread::start(Priority priority)
+ if (d->running)
+ return;
+
++ d->objectName = objectName();
+ d->running = true;
+ d->finished = false;
+ d->exited = false;
+@@ -548,7 +548,7 @@ void QThread::start(Priority priority)
+
+ int prio;
+ d->priority = priority;
+- switch (d->priority) {
++ switch (priority) {
+ case IdlePriority:
+ prio = THREAD_PRIORITY_IDLE;
+ break;
+@@ -686,7 +686,7 @@ void QThreadPrivate::setPriority(QThread::Priority threadPriority)
+
+ int prio;
+ priority = threadPriority;
+- switch (priority) {
++ switch (threadPriority) {
+ case QThread::IdlePriority:
+ prio = THREAD_PRIORITY_IDLE;
+ break;
+diff --git a/qtbase/src/corelib/thread/qtsan_impl.h b/qtbase/src/corelib/thread/qtsan_impl.h
+new file mode 100644
+index 0000000000..580a738b91
+--- /dev/null
++++ b/qtbase/src/corelib/thread/qtsan_impl.h
+@@ -0,0 +1,115 @@
++/****************************************************************************
++**
++** Copyright (C) 2017 Intel Corporation.
++** Copyright (C) 2022 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Giuseppe D'Angelo <giuseppe.dangelo@kdab.com>
++** Contact: https://www.qt.io/licensing/
++**
++** This file is part of the QtCore module of the Qt Toolkit.
++**
++** $QT_BEGIN_LICENSE:LGPL$
++** Commercial License Usage
++** Licensees holding valid commercial Qt licenses may use this file in
++** accordance with the commercial license agreement provided with the
++** Software or, alternatively, in accordance with the terms contained in
++** a written agreement between you and The Qt Company. For licensing terms
++** and conditions see https://www.qt.io/terms-conditions. For further
++** information use the contact form at https://www.qt.io/contact-us.
++**
++** GNU Lesser General Public License Usage
++** Alternatively, this file may be used under the terms of the GNU Lesser
++** General Public License version 3 as published by the Free Software
++** Foundation and appearing in the file LICENSE.LGPL3 included in the
++** packaging of this file. Please review the following information to
++** ensure the GNU Lesser General Public License version 3 requirements
++** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
++**
++** GNU General Public License Usage
++** Alternatively, this file may be used under the terms of the GNU
++** General Public License version 2.0 or (at your option) the GNU General
++** Public license version 3 or any later version approved by the KDE Free
++** Qt Foundation. The licenses are as published by the Free Software
++** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
++** included in the packaging of this file. Please review the following
++** information to ensure the GNU General Public License requirements will
++** be met: https://www.gnu.org/licenses/gpl-2.0.html and
++** https://www.gnu.org/licenses/gpl-3.0.html.
++**
++** $QT_END_LICENSE$
++**
++****************************************************************************/
++
++#ifndef QTSAN_IMPL_H
++#define QTSAN_IMPL_H
++
++#include <QtCore/qglobal.h>
++
++#if (__has_feature(thread_sanitizer) || defined(__SANITIZE_THREAD__)) && __has_include(<sanitizer/tsan_interface.h>)
++# define QT_BUILDING_UNDER_TSAN
++# include <sanitizer/tsan_interface.h>
++#endif
++
++QT_BEGIN_NAMESPACE
++
++namespace QtTsan {
++#ifdef QT_BUILDING_UNDER_TSAN
++inline void futexAcquire(void *addr, void *addr2 = nullptr)
++{
++ // A futex call ensures total ordering on the futex words
++ // (in either success or failure of the call). Instruct TSAN accordingly,
++ // as TSAN does not understand the futex(2) syscall (or equivalent).
++ ::__tsan_acquire(addr);
++ if (addr2)
++ ::__tsan_acquire(addr2);
++}
++
++inline void futexRelease(void *addr, void *addr2 = nullptr)
++{
++ if (addr2)
++ ::__tsan_release(addr2);
++ ::__tsan_release(addr);
++}
++
++inline void mutexPreLock(void *addr, unsigned flags)
++{
++ ::__tsan_mutex_pre_lock(addr, flags);
++}
++
++inline void mutexPostLock(void *addr, unsigned flags, int recursion)
++{
++ ::__tsan_mutex_post_lock(addr, flags, recursion);
++}
++
++inline void mutexPreUnlock(void *addr, unsigned flags)
++{
++ ::__tsan_mutex_pre_unlock(addr, flags);
++}
++
++inline void mutexPostUnlock(void *addr, unsigned flags)
++{
++ ::__tsan_mutex_post_unlock(addr, flags);
++}
++
++enum : unsigned {
++ MutexWriteReentrant = ::__tsan_mutex_write_reentrant,
++ TryLock = ::__tsan_mutex_try_lock,
++ TryLockFailed = ::__tsan_mutex_try_lock_failed,
++};
++#else
++inline void futexAcquire(void *, void * = nullptr) {}
++inline void futexRelease(void *, void * = nullptr) {}
++
++enum : unsigned {
++ MutexWriteReentrant,
++ TryLock,
++ TryLockFailed,
++};
++inline void mutexPreLock(void *, unsigned) {}
++inline void mutexPostLock(void *, unsigned, int) {}
++inline void mutexPreUnlock(void *, unsigned) {}
++inline void mutexPostUnlock(void *, unsigned) {}
++#endif // QT_BUILDING_UNDER_TSAN
++} // namespace QtTsan
++
++QT_END_NAMESPACE
++
++#endif // QTSAN_IMPL_H
+diff --git a/qtbase/src/corelib/thread/qwaitcondition_unix.cpp b/qtbase/src/corelib/thread/qwaitcondition_unix.cpp
+index 88b058f410..0f1da4dc9b 100644
+--- a/qtbase/src/corelib/thread/qwaitcondition_unix.cpp
++++ b/qtbase/src/corelib/thread/qwaitcondition_unix.cpp
+@@ -213,7 +213,7 @@ bool QWaitCondition::wait(QMutex *mutex, QDeadlineTimer deadline)
+ {
+ if (! mutex)
+ return false;
+- if (mutex->isRecursive()) {
++ if (static_cast<QBasicMutex *>(mutex)->isRecursive()) {
+ qWarning("QWaitCondition: cannot wait on recursive mutexes");
+ return false;
+ }
+diff --git a/qtbase/src/corelib/time/qdatetime.cpp b/qtbase/src/corelib/time/qdatetime.cpp
+index ec12569e3f..2c0b098079 100644
+--- a/qtbase/src/corelib/time/qdatetime.cpp
++++ b/qtbase/src/corelib/time/qdatetime.cpp
+@@ -43,6 +43,7 @@
+ #if QT_CONFIG(datetimeparser)
+ #include "private/qdatetimeparser_p.h"
+ #endif
++#include <private/qnumeric_p.h>
+
+ #include "qdatastream.h"
+ #include "qset.h"
+@@ -1429,9 +1430,11 @@ QDate QDate::addDays(qint64 ndays) const
+ if (isNull())
+ return QDate();
+
+- // Due to limits on minJd() and maxJd() we know that any overflow
+- // will be invalid and caught by fromJulianDay().
+- return fromJulianDay(jd + ndays);
++ qint64 r;
++ if (Q_UNLIKELY(add_overflow(jd, ndays, &r)))
++ return QDate();
++ else
++ return fromJulianDay(r);
+ }
+
+ /*!
+diff --git a/qtbase/src/corelib/time/qtimezone.cpp b/qtbase/src/corelib/time/qtimezone.cpp
+index 0309e43e52..3d451696a1 100644
+--- a/qtbase/src/corelib/time/qtimezone.cpp
++++ b/qtbase/src/corelib/time/qtimezone.cpp
+@@ -1,6 +1,6 @@
+ /****************************************************************************
+ **
+-** Copyright (C) 2013 John Layt <jlayt@kde.org>
++** Copyright (C) 2020 John Layt <jlayt@kde.org>
+ ** Contact: https://www.qt.io/licensing/
+ **
+ ** This file is part of the QtCore module of the Qt Toolkit.
+@@ -975,9 +975,15 @@ QList<QByteArray> QTimeZone::windowsIdToIanaIds(const QByteArray &windowsId,
+ }
+
+ #ifndef QT_NO_DATASTREAM
++// Invalid, as an IANA ID: too long, starts with - and has other invalid characters in it
++static inline QString invalidId() { return QStringLiteral("-No Time Zone Specified!"); }
++
+ QDataStream &operator<<(QDataStream &ds, const QTimeZone &tz)
+ {
+- tz.d->serialize(ds);
++ if (tz.isValid())
++ tz.d->serialize(ds);
++ else
++ ds << invalidId();
+ return ds;
+ }
+
+@@ -985,7 +991,9 @@ QDataStream &operator>>(QDataStream &ds, QTimeZone &tz)
+ {
+ QString ianaId;
+ ds >> ianaId;
+- if (ianaId == QLatin1String("OffsetFromUtc")) {
++ if (ianaId == invalidId()) {
++ tz = QTimeZone();
++ } else if (ianaId == QLatin1String("OffsetFromUtc")) {
+ int utcOffset;
+ QString name;
+ QString abbreviation;
+diff --git a/qtbase/src/corelib/time/qtimezoneprivate_tz.cpp b/qtbase/src/corelib/time/qtimezoneprivate_tz.cpp
+index b1611d7ddb..a7a6a72ccf 100644
+--- a/qtbase/src/corelib/time/qtimezoneprivate_tz.cpp
++++ b/qtbase/src/corelib/time/qtimezoneprivate_tz.cpp
+@@ -42,6 +42,7 @@
+ #include "qtimezone.h"
+ #include "qtimezoneprivate_p.h"
+ #include "private/qlocale_tools_p.h"
++#include "private/qlocking_p.h"
+
+ #include <QtCore/QDataStream>
+ #include <QtCore/QDateTime>
+@@ -62,6 +63,10 @@
+
+ QT_BEGIN_NAMESPACE
+
++#if QT_CONFIG(icu)
++static QBasicMutex s_icu_mutex;
++#endif
++
+ /*
+ Private
+
+@@ -670,6 +675,9 @@ QTzTimeZonePrivate::~QTzTimeZonePrivate()
+
+ QTzTimeZonePrivate *QTzTimeZonePrivate::clone() const
+ {
++#if QT_CONFIG(icu)
++ const auto lock = qt_scoped_lock(s_icu_mutex);
++#endif
+ return new QTzTimeZonePrivate(*this);
+ }
+
+@@ -913,12 +921,14 @@ QString QTzTimeZonePrivate::displayName(qint64 atMSecsSinceEpoch,
+ const QLocale &locale) const
+ {
+ #if QT_CONFIG(icu)
++ auto lock = qt_unique_lock(s_icu_mutex);
+ if (!m_icu)
+ m_icu = new QIcuTimeZonePrivate(m_id);
+ // TODO small risk may not match if tran times differ due to outdated files
+ // TODO Some valid TZ names are not valid ICU names, use translation table?
+ if (m_icu->isValid())
+ return m_icu->displayName(atMSecsSinceEpoch, nameType, locale);
++ lock.unlock();
+ #else
+ Q_UNUSED(nameType)
+ Q_UNUSED(locale)
+@@ -932,12 +942,14 @@ QString QTzTimeZonePrivate::displayName(QTimeZone::TimeType timeType,
+ const QLocale &locale) const
+ {
+ #if QT_CONFIG(icu)
++ auto lock = qt_unique_lock(s_icu_mutex);
+ if (!m_icu)
+ m_icu = new QIcuTimeZonePrivate(m_id);
+ // TODO small risk may not match if tran times differ due to outdated files
+ // TODO Some valid TZ names are not valid ICU names, use translation table?
+ if (m_icu->isValid())
+ return m_icu->displayName(timeType, nameType, locale);
++ lock.unlock();
+ #else
+ Q_UNUSED(timeType)
+ Q_UNUSED(nameType)
+diff --git a/qtbase/src/corelib/tools/qarraydata.h b/qtbase/src/corelib/tools/qarraydata.h
+index dcd95924c1..d01739e7e6 100644
+--- a/qtbase/src/corelib/tools/qarraydata.h
++++ b/qtbase/src/corelib/tools/qarraydata.h
+@@ -42,6 +42,7 @@
+
+ #include <QtCore/qrefcount.h>
+ #include <string.h>
++#include <cstdint>
+
+ QT_BEGIN_NAMESPACE
+
+@@ -58,14 +59,14 @@ struct Q_CORE_EXPORT QArrayData
+ {
+ Q_ASSERT(size == 0
+ || offset < 0 || size_t(offset) >= sizeof(QArrayData));
+- return reinterpret_cast<char *>(this) + offset;
++ return reinterpret_cast<void *> (reinterpret_cast<uintptr_t>(this) + offset);
+ }
+
+ const void *data() const
+ {
+ Q_ASSERT(size == 0
+ || offset < 0 || size_t(offset) >= sizeof(QArrayData));
+- return reinterpret_cast<const char *>(this) + offset;
++ return reinterpret_cast<void *> (reinterpret_cast<uintptr_t>(this) + offset);
+ }
+
+ // This refers to array data mutability, not "header data" represented by
+diff --git a/qtbase/src/corelib/tools/qfreelist_p.h b/qtbase/src/corelib/tools/qfreelist_p.h
+index 5ba23b344b..9974102136 100644
+--- a/qtbase/src/corelib/tools/qfreelist_p.h
++++ b/qtbase/src/corelib/tools/qfreelist_p.h
+@@ -161,7 +161,7 @@ class QFreeList
+ return i;
+ x -= size;
+ }
+- Q_ASSERT(false);
++ Q_UNREACHABLE();
+ return -1;
+ }
+
+diff --git a/qtbase/src/corelib/tools/qversionnumber.h b/qtbase/src/corelib/tools/qversionnumber.h
+index d43b86ba51..2843f2b043 100644
+--- a/qtbase/src/corelib/tools/qversionnumber.h
++++ b/qtbase/src/corelib/tools/qversionnumber.h
+@@ -273,10 +273,10 @@ public:
+
+ Q_REQUIRED_RESULT Q_CORE_EXPORT QString toString() const;
+ #if QT_STRINGVIEW_LEVEL < 2
+- Q_REQUIRED_RESULT Q_CORE_EXPORT static Q_DECL_PURE_FUNCTION QVersionNumber fromString(const QString &string, int *suffixIndex = nullptr);
++ Q_REQUIRED_RESULT Q_CORE_EXPORT static QVersionNumber fromString(const QString &string, int *suffixIndex = nullptr);
+ #endif
+- Q_REQUIRED_RESULT Q_CORE_EXPORT static Q_DECL_PURE_FUNCTION QVersionNumber fromString(QLatin1String string, int *suffixIndex = nullptr);
+- Q_REQUIRED_RESULT Q_CORE_EXPORT static Q_DECL_PURE_FUNCTION QVersionNumber fromString(QStringView string, int *suffixIndex = nullptr);
++ Q_REQUIRED_RESULT Q_CORE_EXPORT static QVersionNumber fromString(QLatin1String string, int *suffixIndex = nullptr);
++ Q_REQUIRED_RESULT Q_CORE_EXPORT static QVersionNumber fromString(QStringView string, int *suffixIndex = nullptr);
+
+ private:
+ #ifndef QT_NO_DATASTREAM
+diff --git a/qtbase/src/dbus/qdbusintegrator.cpp b/qtbase/src/dbus/qdbusintegrator.cpp
+index 5b66ce971b..28a3b0ffea 100644
+--- a/qtbase/src/dbus/qdbusintegrator.cpp
++++ b/qtbase/src/dbus/qdbusintegrator.cpp
+@@ -1135,7 +1135,13 @@ void QDBusConnectionPrivate::closeConnection()
+ }
+ }
+
+- qDeleteAll(pendingCalls);
++ for (auto it = pendingCalls.begin(); it != pendingCalls.end(); ++it) {
++ auto call = *it;
++ if (!call->ref.deref()) {
++ delete call;
++ }
++ }
++ pendingCalls.clear();
+
+ // Disconnect all signals from signal hooks and from the object tree to
+ // avoid QObject::destroyed being sent to dbus daemon thread which has
+@@ -2584,6 +2590,11 @@ QDBusConnectionPrivate::findMetaObject(const QString &service, const QString &pa
+ if (mo)
+ return mo;
+ }
++ if (path.isEmpty()) {
++ error = QDBusError(QDBusError::InvalidObjectPath, QLatin1String("Object path cannot be empty"));
++ lastError = error;
++ return nullptr;
++ }
+
+ // introspect the target object
+ QDBusMessage msg = QDBusMessage::createMethodCall(service, path,
+diff --git a/qtbase/src/dbus/qdbusmetaobject.cpp b/qtbase/src/dbus/qdbusmetaobject.cpp
+index 5265568f42..7e9f0f1acc 100644
+--- a/qtbase/src/dbus/qdbusmetaobject.cpp
++++ b/qtbase/src/dbus/qdbusmetaobject.cpp
+@@ -210,6 +210,9 @@ QDBusMetaObjectGenerator::findType(const QByteArray &signature,
+ } else if (signature == "a{ss}") {
+ result.name = "QMap<QString,QString>";
+ type = qMetaTypeId<QMap<QString, QString> >();
++ } else if (signature == "aay") {
++ result.name = "QByteArrayList";
++ type = qMetaTypeId<QByteArrayList>();
+ } else {
+ result.name = "{D-Bus type \"" + signature + "\"}";
+ type = registerComplexDBusType(result.name);
+diff --git a/qtbase/src/gui/accessible/qaccessible.cpp b/qtbase/src/gui/accessible/qaccessible.cpp
+index d705bfccb5..0caf3c808c 100644
+--- a/qtbase/src/gui/accessible/qaccessible.cpp
++++ b/qtbase/src/gui/accessible/qaccessible.cpp
+@@ -54,6 +54,7 @@
+ #include <QtCore/qdebug.h>
+ #include <QtCore/qloggingcategory.h>
+ #include <QtCore/qmetaobject.h>
++#include <QtCore/private/qmetaobject_p.h>
+ #include <QtCore/qhash.h>
+ #include <private/qfactoryloader_p.h>
+
+@@ -681,6 +682,25 @@ QAccessibleInterface *QAccessible::queryAccessibleInterface(QObject *object)
+ // Create a QAccessibleInterface for the object class. Start by the most
+ // derived class and walk up the class hierarchy.
+ const QMetaObject *mo = object->metaObject();
++ const auto *objectPriv = QObjectPrivate::get(object);
++ /*
++ We do not want to cache each and every QML metaobject (Button_QMLTYPE_124,
++ Button_QMLTYPE_125, etc.). Those dynamic metaobjects shouldn't have an
++ accessible interface in any case. Instead, we start the whole checking
++ with the first non-dynamic meta-object. To avoid potential regressions
++ in other areas of Qt that also use dynamic metaobjects, we only do this
++ for objects that are QML-related (approximated by checking whether they
++ have ddata set).
++ */
++ const bool qmlRelated = !objectPriv->isDeletingChildren &&
++ objectPriv->declarativeData;
++ while (qmlRelated && mo) {
++ auto mop = QMetaObjectPrivate::get(mo);
++ if (!mop || !(mop->flags & DynamicMetaObject))
++ break;
++
++ mo = mo->superClass();
++ };
+ while (mo) {
+ const QString cn = QLatin1String(mo->className());
+
+@@ -696,14 +716,15 @@ QAccessibleInterface *QAccessible::queryAccessibleInterface(QObject *object)
+ // Find a QAccessiblePlugin (factory) for the class name. If there's
+ // no entry in the cache try to create it using the plugin loader.
+ if (!qAccessiblePlugins()->contains(cn)) {
++ QAccessiblePlugin *factory = nullptr; // 0 means "no plugin found". This is cached as well.
+ const int index = loader()->indexOf(cn);
+- if (index != -1) {
+- QAccessiblePlugin *factory = qobject_cast<QAccessiblePlugin *>(loader()->instance(index));
+- qAccessiblePlugins()->insert(cn, factory);
+- }
++ if (index != -1)
++ factory = qobject_cast<QAccessiblePlugin *>(loader()->instance(index));
++ qAccessiblePlugins()->insert(cn, factory);
+ }
+
+ // At this point the cache should contain a valid factory pointer or 0:
++ Q_ASSERT(qAccessiblePlugins()->contains(cn));
+ QAccessiblePlugin *factory = qAccessiblePlugins()->value(cn);
+ if (factory) {
+ QAccessibleInterface *result = factory->create(cn, object);
+diff --git a/qtbase/src/gui/configure.json b/qtbase/src/gui/configure.json
+index 1f08795c57..12c95742d2 100644
+--- a/qtbase/src/gui/configure.json
++++ b/qtbase/src/gui/configure.json
+@@ -834,7 +834,8 @@
+ "// embedded devices, are not intended to be used together with X. EGL support",
+ "// has to be disabled in plugins like xcb in this case since the native display,",
+ "// window and pixmap types will be different than what an X-based platform",
+- "// plugin would expect."
++ "// plugin would expect.",
++ "#define USE_X11"
+ ],
+ "include": [ "EGL/egl.h", "X11/Xlib.h" ],
+ "main": [
+diff --git a/qtbase/src/gui/image/qbmphandler.cpp b/qtbase/src/gui/image/qbmphandler.cpp
+index 96f1e8cb1d..0e73bbbdb0 100644
+--- a/qtbase/src/gui/image/qbmphandler.cpp
++++ b/qtbase/src/gui/image/qbmphandler.cpp
+@@ -150,16 +150,42 @@ static QDataStream &operator<<(QDataStream &s, const BMP_INFOHDR &bi)
+ return s;
+ }
+
+-static int calc_shift(uint mask)
++static uint calc_shift(uint mask)
+ {
+- int result = 0;
+- while (mask && !(mask & 1)) {
++ uint result = 0;
++ while ((mask >= 0x100) || (!(mask & 1) && mask)) {
+ result++;
+ mask >>= 1;
+ }
+ return result;
+ }
+
++static uint calc_scale(uint low_mask)
++{
++ uint result = 8;
++ while (low_mask && result) {
++ result--;
++ low_mask >>= 1;
++ }
++ return result;
++}
++
++static inline uint apply_scale(uint value, uint scale)
++{
++ if (!(scale & 0x07)) // return immediately if scale == 8 or 0
++ return value;
++
++ uint filled = 8 - scale;
++ uint result = value << scale;
++
++ do {
++ result |= result >> filled;
++ filled <<= 1;
++ } while (filled < 8);
++
++ return result;
++}
++
+ static bool read_dib_fileheader(QDataStream &s, BMP_FILEHDR &bf)
+ {
+ // read BMP file header
+@@ -222,14 +248,14 @@ static bool read_dib_body(QDataStream &s, const BMP_INFOHDR &bi, qint64 offset,
+ uint green_mask = 0;
+ uint blue_mask = 0;
+ uint alpha_mask = 0;
+- int red_shift = 0;
+- int green_shift = 0;
+- int blue_shift = 0;
+- int alpha_shift = 0;
+- int red_scale = 0;
+- int green_scale = 0;
+- int blue_scale = 0;
+- int alpha_scale = 0;
++ uint red_shift = 0;
++ uint green_shift = 0;
++ uint blue_shift = 0;
++ uint alpha_shift = 0;
++ uint red_scale = 0;
++ uint green_scale = 0;
++ uint blue_scale = 0;
++ uint alpha_scale = 0;
+
+ if (!d->isSequential())
+ d->seek(startpos + BMP_FILEHDR_SIZE + bi.biSize); // goto start of colormap or masks
+@@ -308,19 +334,19 @@ static bool read_dib_body(QDataStream &s, const BMP_INFOHDR &bi, qint64 offset,
+ red_shift = calc_shift(red_mask);
+ if (((red_mask >> red_shift) + 1) == 0)
+ return false;
+- red_scale = 256 / ((red_mask >> red_shift) + 1);
++ red_scale = calc_scale(red_mask >> red_shift);
+ green_shift = calc_shift(green_mask);
+ if (((green_mask >> green_shift) + 1) == 0)
+ return false;
+- green_scale = 256 / ((green_mask >> green_shift) + 1);
++ green_scale = calc_scale(green_mask >> green_shift);
+ blue_shift = calc_shift(blue_mask);
+ if (((blue_mask >> blue_shift) + 1) == 0)
+ return false;
+- blue_scale = 256 / ((blue_mask >> blue_shift) + 1);
++ blue_scale = calc_scale(blue_mask >> blue_shift);
+ alpha_shift = calc_shift(alpha_mask);
+ if (((alpha_mask >> alpha_shift) + 1) == 0)
+ return false;
+- alpha_scale = 256 / ((alpha_mask >> alpha_shift) + 1);
++ alpha_scale = calc_scale(alpha_mask >> alpha_shift);
+ } else if (comp == BMP_RGB && (nbits == 24 || nbits == 32)) {
+ blue_mask = 0x000000ff;
+ green_mask = 0x0000ff00;
+@@ -328,17 +354,15 @@ static bool read_dib_body(QDataStream &s, const BMP_INFOHDR &bi, qint64 offset,
+ blue_shift = 0;
+ green_shift = 8;
+ red_shift = 16;
+- blue_scale = green_scale = red_scale = 1;
++ blue_scale = green_scale = red_scale = 0;
+ } else if (comp == BMP_RGB && nbits == 16) {
+ blue_mask = 0x001f;
+ green_mask = 0x03e0;
+ red_mask = 0x7c00;
+ blue_shift = 0;
+- green_shift = 2;
+- red_shift = 7;
+- red_scale = 1;
+- green_scale = 1;
+- blue_scale = 8;
++ green_shift = 5;
++ red_shift = 10;
++ blue_scale = green_scale = red_scale = 3;
+ }
+
+ #if 0
+@@ -544,10 +568,10 @@ static bool read_dib_body(QDataStream &s, const BMP_INFOHDR &bi, qint64 offset,
+ c |= *(uchar*)(b+2)<<16;
+ if (nbits > 24)
+ c |= *(uchar*)(b+3)<<24;
+- *p++ = qRgba(((c & red_mask) >> red_shift) * red_scale,
+- ((c & green_mask) >> green_shift) * green_scale,
+- ((c & blue_mask) >> blue_shift) * blue_scale,
+- transp ? ((c & alpha_mask) >> alpha_shift) * alpha_scale : 0xff);
++ *p++ = qRgba(apply_scale((c & red_mask) >> red_shift, red_scale),
++ apply_scale((c & green_mask) >> green_shift, green_scale),
++ apply_scale((c & blue_mask) >> blue_shift, blue_scale),
++ transp ? apply_scale((c & alpha_mask) >> alpha_shift, alpha_scale) : 0xff);
+ b += nbits/8;
+ }
+ }
+diff --git a/qtbase/src/gui/image/qimage.cpp b/qtbase/src/gui/image/qimage.cpp
+index 7152ac1607..0df772564c 100644
+--- a/qtbase/src/gui/image/qimage.cpp
++++ b/qtbase/src/gui/image/qimage.cpp
+@@ -4694,6 +4694,8 @@ QImage QImage::smoothScaled(int w, int h) const {
+ static QImage rotated90(const QImage &image)
+ {
+ QImage out(image.height(), image.width(), image.format());
++ if (out.isNull())
++ return out;
+ copyMetadata(&out, image);
+ if (image.colorCount() > 0)
+ out.setColorTable(image.colorTable());
+@@ -4722,6 +4724,8 @@ static QImage rotated180(const QImage &image)
+ return image.mirrored(true, true);
+
+ QImage out(image.width(), image.height(), image.format());
++ if (out.isNull())
++ return out;
+ copyMetadata(&out, image);
+ if (image.colorCount() > 0)
+ out.setColorTable(image.colorTable());
+@@ -4734,6 +4738,8 @@ static QImage rotated180(const QImage &image)
+ static QImage rotated270(const QImage &image)
+ {
+ QImage out(image.height(), image.width(), image.format());
++ if (out.isNull())
++ return out;
+ copyMetadata(&out, image);
+ if (image.colorCount() > 0)
+ out.setColorTable(image.colorTable());
+diff --git a/qtbase/src/gui/kernel/qcursor.cpp b/qtbase/src/gui/kernel/qcursor.cpp
+index d6ccaff8ed..455088241c 100644
+--- a/qtbase/src/gui/kernel/qcursor.cpp
++++ b/qtbase/src/gui/kernel/qcursor.cpp
+@@ -251,7 +251,8 @@ void QCursor::setPos(QScreen *screen, int x, int y)
+ {
+ if (screen) {
+ if (QPlatformCursor *cursor = screen->handle()->cursor()) {
+- const QPoint devicePos = QHighDpi::toNativePixels(QPoint(x, y), screen);
++ const QPoint pos(x, y);
++ const QPoint devicePos = QHighDpi::toNativePixels(pos, screen->virtualSiblingAt(pos));
+ // Need to check, since some X servers generate null mouse move
+ // events, causing looping in applications which call setPos() on
+ // every mouse move event.
+diff --git a/qtbase/src/gui/kernel/qhighdpiscaling.cpp b/qtbase/src/gui/kernel/qhighdpiscaling.cpp
+index 9bbf2773a9..3ac4a4d8b6 100644
+--- a/qtbase/src/gui/kernel/qhighdpiscaling.cpp
++++ b/qtbase/src/gui/kernel/qhighdpiscaling.cpp
+@@ -580,9 +580,8 @@ void QHighDpiScaling::setScreenFactor(QScreen *screen, qreal factor)
+ else
+ qNamedScreenScaleFactors()->insert(name, factor);
+
+- // hack to force re-evaluation of screen geometry
+ if (screen->handle())
+- screen->d_func()->setPlatformScreen(screen->handle()); // updates geometries based on scale factor
++ screen->d_func()->updateLogicalDpi();
+ }
+
+ QPoint QHighDpiScaling::mapPositionToNative(const QPoint &pos, const QPlatformScreen *platformScreen)
+diff --git a/qtbase/src/gui/kernel/qkeysequence.cpp b/qtbase/src/gui/kernel/qkeysequence.cpp
+index a75b8ef920..4f2d294739 100644
+--- a/qtbase/src/gui/kernel/qkeysequence.cpp
++++ b/qtbase/src/gui/kernel/qkeysequence.cpp
+@@ -701,6 +701,10 @@ static const struct {
+ { Qt::Key_TouchpadToggle, QT_TRANSLATE_NOOP("QShortcut", "Touchpad Toggle") },
+ { Qt::Key_TouchpadOn, QT_TRANSLATE_NOOP("QShortcut", "Touchpad On") },
+ { Qt::Key_TouchpadOff, QT_TRANSLATE_NOOP("QShortcut", "Touchpad Off") },
++ { Qt::Key_Shift, QT_TRANSLATE_NOOP("QShortcut", "Shift") },
++ { Qt::Key_Control, QT_TRANSLATE_NOOP("QShortcut", "Control") },
++ { Qt::Key_Alt, QT_TRANSLATE_NOOP("QShortcut", "Alt") },
++ { Qt::Key_Meta, QT_TRANSLATE_NOOP("QShortcut", "Meta") },
+
+ };
+ static Q_CONSTEXPR int numKeyNames = sizeof keyname / sizeof *keyname;
+diff --git a/qtbase/src/gui/kernel/qplatformservices.cpp b/qtbase/src/gui/kernel/qplatformservices.cpp
+index fdc6a6c4aa..ac47f98c5d 100644
+--- a/qtbase/src/gui/kernel/qplatformservices.cpp
++++ b/qtbase/src/gui/kernel/qplatformservices.cpp
+@@ -55,6 +55,19 @@ QT_BEGIN_NAMESPACE
+ \brief The QPlatformServices provides the backend for desktop-related functionality.
+ */
+
++/*!
++ \enum QPlatformServices::Capability
++
++ Capabilities are used to determine a specific platform service's availability.
++
++ \value ColorPickingFromScreen The platform natively supports color picking from screen.
++ This capability indicates that the platform supports "opaque" color picking, where the
++ platform implements a complete user experience for color picking and outputs a color.
++ This is in contrast to the application implementing the color picking user experience
++ (taking care of showing a cross hair, instructing the platform integration to obtain
++ the color at a given pixel, etc.). The related service function is pickColor().
++ */
++
+ QPlatformServices::QPlatformServices()
+ { }
+
+@@ -85,5 +98,16 @@ QByteArray QPlatformServices::desktopEnvironment() const
+ return QByteArray("UNKNOWN");
+ }
+
++QPlatformServiceColorPicker *QPlatformServices::colorPicker(QWindow *parent)
++{
++ Q_UNUSED(parent);
++ return nullptr;
++}
++
++bool QPlatformServices::hasCapability(Capability capability) const
++{
++ Q_UNUSED(capability)
++ return false;
++}
+
+ QT_END_NAMESPACE
+diff --git a/qtbase/src/gui/kernel/qplatformservices.h b/qtbase/src/gui/kernel/qplatformservices.h
+index 5de96cfa7d..a8b2a4ce71 100644
+--- a/qtbase/src/gui/kernel/qplatformservices.h
++++ b/qtbase/src/gui/kernel/qplatformservices.h
+@@ -50,16 +50,32 @@
+ //
+
+ #include <QtGui/qtguiglobal.h>
++#include <QtCore/qobject.h>
+
+ QT_BEGIN_NAMESPACE
+
+ class QUrl;
++class QWindow;
++
++class Q_GUI_EXPORT QPlatformServiceColorPicker : public QObject
++{
++ Q_OBJECT
++public:
++ using QObject::QObject;
++ virtual void pickColor() = 0;
++Q_SIGNALS:
++ void colorPicked(const QColor &color);
++};
+
+ class Q_GUI_EXPORT QPlatformServices
+ {
+ public:
+ Q_DISABLE_COPY_MOVE(QPlatformServices)
+
++ enum Capability {
++ ColorPicking,
++ };
++
+ QPlatformServices();
+ virtual ~QPlatformServices() { }
+
+@@ -67,6 +83,10 @@ public:
+ virtual bool openDocument(const QUrl &url);
+
+ virtual QByteArray desktopEnvironment() const;
++
++ virtual bool hasCapability(Capability capability) const;
++
++ virtual QPlatformServiceColorPicker *colorPicker(QWindow *parent = nullptr);
+ };
+
+ QT_END_NAMESPACE
+diff --git a/qtbase/src/gui/kernel/qplatformtheme.cpp b/qtbase/src/gui/kernel/qplatformtheme.cpp
+index 71521c0339..2325873245 100644
+--- a/qtbase/src/gui/kernel/qplatformtheme.cpp
++++ b/qtbase/src/gui/kernel/qplatformtheme.cpp
+@@ -163,6 +163,8 @@ QT_BEGIN_NAMESPACE
+
+ \value ShowShortcutsInContextMenus (bool) Whether to display shortcut key sequences in context menus.
+
++ \value ButtonPressKeys (QList<Qt::Key>) A list of keys that can be used to press buttons via keyboard input.
++
+ \sa themeHint(), QStyle::pixelMetric()
+ */
+
+@@ -563,6 +565,8 @@ QVariant QPlatformTheme::defaultThemeHint(ThemeHint hint)
+ }
+ case MouseQuickSelectionThreshold:
+ return QVariant(10);
++ case ButtonPressKeys:
++ return QVariant::fromValue(QList<Qt::Key>({ Qt::Key_Space, Qt::Key_Select }));
+ }
+ return QVariant();
+ }
+diff --git a/qtbase/src/gui/kernel/qplatformtheme.h b/qtbase/src/gui/kernel/qplatformtheme.h
+index 3185fc4541..7e6c9d5740 100644
+--- a/qtbase/src/gui/kernel/qplatformtheme.h
++++ b/qtbase/src/gui/kernel/qplatformtheme.h
+@@ -120,7 +120,8 @@ public:
+ TouchDoubleTapDistance,
+ ShowShortcutsInContextMenus,
+ IconFallbackSearchPaths,
+- MouseQuickSelectionThreshold
++ MouseQuickSelectionThreshold,
++ ButtonPressKeys
+ };
+
+ enum DialogType {
+diff --git a/qtbase/src/gui/kernel/qscreen.cpp b/qtbase/src/gui/kernel/qscreen.cpp
+index 8e0eb35116..5d172a58dd 100644
+--- a/qtbase/src/gui/kernel/qscreen.cpp
++++ b/qtbase/src/gui/kernel/qscreen.cpp
+@@ -77,6 +77,12 @@ QScreen::QScreen(QPlatformScreen *screen)
+ d->setPlatformScreen(screen);
+ }
+
++void QScreenPrivate::updateLogicalDpi()
++{
++ logicalDpi = QPlatformScreen::overrideDpi(platformScreen->logicalDpi());
++ updateGeometriesWithSignals(); // updates geometries based on scale factor
++}
++
+ void QScreenPrivate::updateGeometriesWithSignals()
+ {
+ const QRect oldGeometry = geometry;
+diff --git a/qtbase/src/gui/kernel/qscreen_p.h b/qtbase/src/gui/kernel/qscreen_p.h
+index 7da542c25e..e50fc3190b 100644
+--- a/qtbase/src/gui/kernel/qscreen_p.h
++++ b/qtbase/src/gui/kernel/qscreen_p.h
+@@ -70,6 +70,7 @@ public:
+ geometry = platformScreen->deviceIndependentGeometry();
+ availableGeometry = QHighDpi::fromNative(platformScreen->availableGeometry(), QHighDpiScaling::factor(platformScreen), geometry.topLeft());
+ }
++ void updateLogicalDpi();
+
+ void updatePrimaryOrientation();
+ void updateGeometriesWithSignals();
+diff --git a/qtbase/src/gui/painting/qblendfunctions_p.h b/qtbase/src/gui/painting/qblendfunctions_p.h
+index 080da98ec4..6997d62b3c 100644
+--- a/qtbase/src/gui/painting/qblendfunctions_p.h
++++ b/qtbase/src/gui/painting/qblendfunctions_p.h
+@@ -246,25 +246,32 @@ void qt_transform_image_rasterize(DestT *destPixels, int dbpl,
+ int dudx, int dvdx, int dudy, int dvdy, int u0, int v0,
+ Blender blender)
+ {
+- int fromY = qMax(qRound(topY), clip.top());
+- int toY = qMin(qRound(bottomY), clip.top() + clip.height());
++ qint64 fromY = qMax(qRound(topY), clip.top());
++ qint64 toY = qMin(qRound(bottomY), clip.top() + clip.height());
+ if (fromY >= toY)
+ return;
+
+ qreal leftSlope = (bottomLeft.x - topLeft.x) / (bottomLeft.y - topLeft.y);
+ qreal rightSlope = (bottomRight.x - topRight.x) / (bottomRight.y - topRight.y);
+- int dx_l = int(leftSlope * 0x10000);
+- int dx_r = int(rightSlope * 0x10000);
+- int x_l = int((topLeft.x + (qreal(0.5) + fromY - topLeft.y) * leftSlope + qreal(0.5)) * 0x10000);
+- int x_r = int((topRight.x + (qreal(0.5) + fromY - topRight.y) * rightSlope + qreal(0.5)) * 0x10000);
+-
+- int fromX, toX, x1, x2, u, v, i, ii;
++ qint64 dx_l = qint64(leftSlope * 0x10000);
++ qint64 dx_r = qint64(rightSlope * 0x10000);
++ qint64 x_l = qint64((topLeft.x + (qreal(0.5) + fromY - topLeft.y) * leftSlope + qreal(0.5)) * 0x10000);
++ qint64 x_r = qint64((topRight.x + (qreal(0.5) + fromY - topRight.y) * rightSlope + qreal(0.5)) * 0x10000);
++
++ qint64 sourceRectTop = qint64(sourceRect.top());
++ qint64 sourceRectLeft = qint64(sourceRect.left());
++ qint64 sourceRectWidth = qint64(sourceRect.width());
++ qint64 sourceRectHeight = qint64(sourceRect.height());
++ qint64 clipLeft = qint64(clip.left());
++ qint64 clipWidth = qint64(clip.width());
++
++ qint64 fromX, toX, x1, x2, u, v, i, ii;
+ DestT *line;
+- for (int y = fromY; y < toY; ++y) {
++ for (qint64 y = fromY; y < toY; ++y) {
+ line = reinterpret_cast<DestT *>(reinterpret_cast<uchar *>(destPixels) + y * dbpl);
+
+- fromX = qMax(x_l >> 16, clip.left());
+- toX = qMin(x_r >> 16, clip.left() + clip.width());
++ fromX = qMax(x_l >> 16, clipLeft);
++ toX = qMin(x_r >> 16, clipLeft + clipWidth);
+ if (fromX < toX) {
+ // Because of rounding, we can get source coordinates outside the source image.
+ // Clamp these coordinates to the source rect to avoid segmentation fault and
+@@ -275,10 +282,10 @@ void qt_transform_image_rasterize(DestT *destPixels, int dbpl,
+ u = x1 * dudx + y * dudy + u0;
+ v = x1 * dvdx + y * dvdy + v0;
+ for (; x1 < toX; ++x1) {
+- int uu = u >> 16;
+- int vv = v >> 16;
+- if (uu >= sourceRect.left() && uu < sourceRect.left() + sourceRect.width()
+- && vv >= sourceRect.top() && vv < sourceRect.top() + sourceRect.height()) {
++ qint64 uu = u >> 16;
++ qint64 vv = v >> 16;
++ if (uu >= sourceRectLeft && uu < sourceRectLeft + sourceRectWidth
++ && vv >= sourceRectTop && vv < sourceRectTop + sourceRectHeight) {
+ break;
+ }
+ u += dudx;
+@@ -290,10 +297,10 @@ void qt_transform_image_rasterize(DestT *destPixels, int dbpl,
+ u = (x2 - 1) * dudx + y * dudy + u0;
+ v = (x2 - 1) * dvdx + y * dvdy + v0;
+ for (; x2 > x1; --x2) {
+- int uu = u >> 16;
+- int vv = v >> 16;
+- if (uu >= sourceRect.left() && uu < sourceRect.left() + sourceRect.width()
+- && vv >= sourceRect.top() && vv < sourceRect.top() + sourceRect.height()) {
++ qint64 uu = u >> 16;
++ qint64 vv = v >> 16;
++ if (uu >= sourceRectLeft && uu < sourceRectLeft + sourceRectWidth
++ && vv >= sourceRectTop && vv < sourceRectTop + sourceRectHeight) {
+ break;
+ }
+ u -= dudx;
+@@ -308,8 +315,8 @@ void qt_transform_image_rasterize(DestT *destPixels, int dbpl,
+ // Beginning of the scan line, with per-pixel checks.
+ i = x1 - fromX;
+ while (i) {
+- int uu = qBound(sourceRect.left(), u >> 16, sourceRect.left() + sourceRect.width() - 1);
+- int vv = qBound(sourceRect.top(), v >> 16, sourceRect.top() + sourceRect.height() - 1);
++ qint64 uu = qBound(sourceRectLeft, u >> 16, sourceRectLeft + sourceRectWidth - 1);
++ qint64 vv = qBound(sourceRectTop, v >> 16, sourceRectTop + sourceRectHeight - 1);
+ blender.write(line, reinterpret_cast<const SrcT *>(reinterpret_cast<const uchar *>(srcPixels) + vv * sbpl)[uu]);
+ u += dudx;
+ v += dvdx;
+@@ -348,8 +355,8 @@ void qt_transform_image_rasterize(DestT *destPixels, int dbpl,
+ // End of the scan line, with per-pixel checks.
+ i = toX - x2;
+ while (i) {
+- int uu = qBound(sourceRect.left(), u >> 16, sourceRect.left() + sourceRect.width() - 1);
+- int vv = qBound(sourceRect.top(), v >> 16, sourceRect.top() + sourceRect.height() - 1);
++ qint64 uu = qBound(sourceRectLeft, u >> 16, sourceRectLeft + sourceRectWidth - 1);
++ qint64 vv = qBound(sourceRectTop, v >> 16, sourceRectTop + sourceRectHeight - 1);
+ blender.write(line, reinterpret_cast<const SrcT *>(reinterpret_cast<const uchar *>(srcPixels) + vv * sbpl)[uu]);
+ u += dudx;
+ v += dvdx;
+diff --git a/qtbase/src/gui/painting/qcolortrclut_p.h b/qtbase/src/gui/painting/qcolortrclut_p.h
+index 76a6a60803..24fd522e6c 100644
+--- a/qtbase/src/gui/painting/qcolortrclut_p.h
++++ b/qtbase/src/gui/painting/qcolortrclut_p.h
+@@ -118,6 +118,7 @@ public:
+ return QRgba64::fromRgba64(r, g, b, qAlpha(rgb32) * 257);
+ #endif
+ }
++ QRgba64 toLinear64(QRgba64) const = delete;
+
+ QRgb toLinear(QRgb rgb32) const
+ {
+diff --git a/qtbase/src/gui/painting/qdrawhelper.cpp b/qtbase/src/gui/painting/qdrawhelper.cpp
+index a61793508a..5ba2d277b7 100644
+--- a/qtbase/src/gui/painting/qdrawhelper.cpp
++++ b/qtbase/src/gui/painting/qdrawhelper.cpp
+@@ -6091,7 +6091,7 @@ static inline void alphargbblend_argb32(quint32 *dst, uint coverage, const QRgba
+ static inline void rgbBlendPixel(QRgba64 &dst, int coverage, QRgba64 slinear, const QColorTrcLut *colorProfile)
+ {
+ // Do a gammacorrected RGB alphablend...
+- const QRgba64 dlinear = colorProfile ? colorProfile->toLinear64(dst) : dst;
++ const QRgba64 dlinear = colorProfile ? colorProfile->toLinear(dst) : dst;
+
+ QRgba64 blend = rgbBlend(dlinear, slinear, coverage);
+
+diff --git a/qtbase/src/gui/painting/qpaintengine_raster.cpp b/qtbase/src/gui/painting/qpaintengine_raster.cpp
+index 283923de52..f08eb9cbee 100644
+--- a/qtbase/src/gui/painting/qpaintengine_raster.cpp
++++ b/qtbase/src/gui/painting/qpaintengine_raster.cpp
+@@ -560,31 +560,6 @@ void QRasterPaintEngine::updateMatrix(const QTransform &matrix)
+ QRasterPaintEngineState *s = state();
+ // FALCON: get rid of this line, see drawImage call below.
+ s->matrix = matrix;
+- QTransform::TransformationType txop = s->matrix.type();
+-
+- switch (txop) {
+-
+- case QTransform::TxNone:
+- s->flags.int_xform = true;
+- break;
+-
+- case QTransform::TxTranslate:
+- s->flags.int_xform = qreal(int(s->matrix.dx())) == s->matrix.dx()
+- && qreal(int(s->matrix.dy())) == s->matrix.dy();
+- break;
+-
+- case QTransform::TxScale:
+- s->flags.int_xform = qreal(int(s->matrix.dx())) == s->matrix.dx()
+- && qreal(int(s->matrix.dy())) == s->matrix.dy()
+- && qreal(int(s->matrix.m11())) == s->matrix.m11()
+- && qreal(int(s->matrix.m22())) == s->matrix.m22();
+- break;
+-
+- default: // shear / perspective...
+- s->flags.int_xform = false;
+- break;
+- }
+-
+ s->flags.tx_noshear = qt_scaleForTransform(s->matrix, &s->txscale);
+
+ ensureOutlineMapper();
+@@ -617,7 +592,6 @@ QRasterPaintEngineState::QRasterPaintEngineState()
+ flags.bilinear = false;
+ flags.legacy_rounding = false;
+ flags.fast_text = true;
+- flags.int_xform = true;
+ flags.tx_noshear = true;
+ flags.fast_images = true;
+
+@@ -1793,7 +1767,7 @@ void QRasterPaintEngine::fill(const QVectorPath &path, const QBrush &brush)
+ QRectF cpRect = path.controlPointRect();
+ const QRectF pathDeviceRect = s->matrix.mapRect(cpRect);
+ // Skip paths that by conservative estimates are completely outside the paint device.
+- if (!pathDeviceRect.intersects(QRectF(d->deviceRect)))
++ if (!pathDeviceRect.intersects(QRectF(d->deviceRect)) || !pathDeviceRect.isValid())
+ return;
+
+ ProcessSpans blend = d->getBrushFunc(pathDeviceRect, &s->brushData);
+diff --git a/qtbase/src/gui/painting/qpaintengine_raster_p.h b/qtbase/src/gui/painting/qpaintengine_raster_p.h
+index 089aadc3f7..bf7363d5aa 100644
+--- a/qtbase/src/gui/painting/qpaintengine_raster_p.h
++++ b/qtbase/src/gui/painting/qpaintengine_raster_p.h
+@@ -111,7 +111,6 @@ public:
+ uint bilinear : 1;
+ uint legacy_rounding : 1;
+ uint fast_text : 1;
+- uint int_xform : 1;
+ uint tx_noshear : 1;
+ uint fast_images : 1;
+ };
+diff --git a/qtbase/src/gui/painting/qpainterpath.cpp b/qtbase/src/gui/painting/qpainterpath.cpp
+index f9544a3241..d80fafeaf1 100644
+--- a/qtbase/src/gui/painting/qpainterpath.cpp
++++ b/qtbase/src/gui/painting/qpainterpath.cpp
+@@ -1253,7 +1253,7 @@ void QPainterPath::addText(const QPointF &point, const QFont &f, const QString &
+
+ if (si.analysis.flags < QScriptAnalysis::TabOrObject) {
+ QGlyphLayout glyphs = eng->shapedGlyphs(&si);
+- QFontEngine *fe = f.d->engineForScript(si.analysis.script);
++ QFontEngine *fe = eng->fontEngine(si);
+ Q_ASSERT(fe);
+ fe->addOutlineToPath(x, y, glyphs, this,
+ si.analysis.bidiLevel % 2
+diff --git a/qtbase/src/gui/painting/qpathclipper_p.h b/qtbase/src/gui/painting/qpathclipper_p.h
+index 9444a87b71..18f64c5e8c 100644
+--- a/qtbase/src/gui/painting/qpathclipper_p.h
++++ b/qtbase/src/gui/painting/qpathclipper_p.h
+@@ -156,7 +156,7 @@ public:
+ int vertex(Direction direction) const;
+
+ private:
+- int m_next[2][2];
++ int m_next[2][2] = { { -1, -1 }, { -1, -1 } };
+ };
+
+ class QPathSegments
+@@ -296,10 +296,6 @@ inline QPathEdge::QPathEdge(int a, int b)
+ , angle(0)
+ , invAngle(0)
+ {
+- m_next[0][0] = -1;
+- m_next[1][0] = -1;
+- m_next[0][0] = -1;
+- m_next[1][0] = -1;
+ }
+
+ inline int QPathEdge::next(Traversal traversal, Direction direction) const
+diff --git a/qtbase/src/gui/painting/qpdf.cpp b/qtbase/src/gui/painting/qpdf.cpp
+index 3066744f1b..2c8d3c3b53 100644
+--- a/qtbase/src/gui/painting/qpdf.cpp
++++ b/qtbase/src/gui/painting/qpdf.cpp
+@@ -2760,6 +2760,8 @@ int QPdfEnginePrivate::addBrushPattern(const QTransform &m, bool *specifyColor,
+ return gradientBrush(brush, matrix, gStateObject);
+ }
+
++ matrix = brush.transform() * matrix;
++
+ if ((!brush.isOpaque() && brush.style() < Qt::LinearGradientPattern) || opacity != 1.0)
+ *gStateObject = addConstantAlphaObject(qRound(brush.color().alpha() * opacity),
+ qRound(pen.color().alpha() * opacity));
+diff --git a/qtbase/src/gui/painting/qstroker.cpp b/qtbase/src/gui/painting/qstroker.cpp
+index cb5d395e80..3b6357a893 100644
+--- a/qtbase/src/gui/painting/qstroker.cpp
++++ b/qtbase/src/gui/painting/qstroker.cpp
+@@ -1182,6 +1182,7 @@ void QDashStroker::processCurrentSubpath()
+ // Check if the entire line should be clipped away or simplified
+ bool clipIt = clipping && !lineIntersectsRect(prev, e, clip_tl, clip_br);
+ bool skipDashing = elen * invSumLength > repetitionLimit();
++ int maxDashes = dashCount;
+ if (skipDashing || clipIt) {
+ // Cut away full dash sequences.
+ elen -= std::floor(elen * invSumLength) * sumLength;
+@@ -1196,7 +1197,7 @@ void QDashStroker::processCurrentSubpath()
+ pos = estop; // move pos to next path element
+ done = true;
+ } else { // Dash is on this line
+- pos = dpos + estart;
++ pos = --maxDashes > 0 ? dpos + estart : estop;
+ done = pos >= estop;
+ if (++idash >= dashCount)
+ idash = 0;
+diff --git a/qtbase/src/gui/painting/qt_attribution.json b/qtbase/src/gui/painting/qt_attribution.json
+index 7b16e8c211..0e87d30aa2 100644
+--- a/qtbase/src/gui/painting/qt_attribution.json
++++ b/qtbase/src/gui/painting/qt_attribution.json
+@@ -10,7 +10,7 @@
+ "Homepage": "http://www.freetype.org",
+ "License": "Freetype Project License or GNU General Public License v2.0 only",
+ "LicenseId": "FTL or GPL-2.0",
+- "LicenseFile": "../../3rdparty/freetype/docs/LICENSE.TXT",
++ "LicenseFile": "../../3rdparty/freetype/LICENSE.TXT",
+ "Copyright": "Copyright 2000-2016 by David Turner, Robert Wilhelm, and Werner Lemberg."
+ },
+ {
+diff --git a/qtbase/src/gui/rhi/qshader_p_p.h b/qtbase/src/gui/rhi/qshader_p_p.h
+index ec9d25971f..4a5a7a6d51 100644
+--- a/qtbase/src/gui/rhi/qshader_p_p.h
++++ b/qtbase/src/gui/rhi/qshader_p_p.h
+@@ -68,13 +68,13 @@ struct Q_GUI_EXPORT QShaderPrivate
+ {
+ }
+
+- QShaderPrivate(const QShaderPrivate *other)
++ QShaderPrivate(const QShaderPrivate &other)
+ : ref(1),
+- qsbVersion(other->qsbVersion),
+- stage(other->stage),
+- desc(other->desc),
+- shaders(other->shaders),
+- bindings(other->bindings)
++ qsbVersion(other.qsbVersion),
++ stage(other.stage),
++ desc(other.desc),
++ shaders(other.shaders),
++ bindings(other.bindings)
+ {
+ }
+
+diff --git a/qtbase/src/gui/rhi/qshaderdescription_p_p.h b/qtbase/src/gui/rhi/qshaderdescription_p_p.h
+index ec2b0b6b4c..3da33a8a2b 100644
+--- a/qtbase/src/gui/rhi/qshaderdescription_p_p.h
++++ b/qtbase/src/gui/rhi/qshaderdescription_p_p.h
+@@ -63,16 +63,16 @@ struct Q_GUI_EXPORT QShaderDescriptionPrivate
+ localSize[0] = localSize[1] = localSize[2] = 0;
+ }
+
+- QShaderDescriptionPrivate(const QShaderDescriptionPrivate *other)
++ QShaderDescriptionPrivate(const QShaderDescriptionPrivate &other)
+ : ref(1),
+- inVars(other->inVars),
+- outVars(other->outVars),
+- uniformBlocks(other->uniformBlocks),
+- pushConstantBlocks(other->pushConstantBlocks),
+- storageBlocks(other->storageBlocks),
+- combinedImageSamplers(other->combinedImageSamplers),
+- storageImages(other->storageImages),
+- localSize(other->localSize)
++ inVars(other.inVars),
++ outVars(other.outVars),
++ uniformBlocks(other.uniformBlocks),
++ pushConstantBlocks(other.pushConstantBlocks),
++ storageBlocks(other.storageBlocks),
++ combinedImageSamplers(other.combinedImageSamplers),
++ storageImages(other.storageImages),
++ localSize(other.localSize)
+ {
+ }
+
+diff --git a/qtbase/src/gui/text/qfontdatabase.cpp b/qtbase/src/gui/text/qfontdatabase.cpp
+index a657a8c516..4fc0100958 100644
+--- a/qtbase/src/gui/text/qfontdatabase.cpp
++++ b/qtbase/src/gui/text/qfontdatabase.cpp
+@@ -983,7 +983,7 @@ QFontEngine *loadSingleEngine(int script,
+ if (style->key.stretch != 0 && request.stretch != 0
+ && (request.styleName.isEmpty() || request.styleName != style->styleName)) {
+ def.stretch = (request.stretch * 100 + style->key.stretch / 2) / style->key.stretch;
+- } else {
++ } else if (request.stretch == QFont::AnyStretch) {
+ def.stretch = 100;
+ }
+
+diff --git a/qtbase/src/gui/text/qtextdocumentlayout.cpp b/qtbase/src/gui/text/qtextdocumentlayout.cpp
+index f3e6ea2100..72267e9380 100644
+--- a/qtbase/src/gui/text/qtextdocumentlayout.cpp
++++ b/qtbase/src/gui/text/qtextdocumentlayout.cpp
+@@ -2123,7 +2123,7 @@ void QTextDocumentLayoutPrivate::drawListItem(const QPointF &offset, QPainter *p
+ {
+ Q_Q(const QTextDocumentLayout);
+ const QTextBlockFormat blockFormat = bl.blockFormat();
+- const QTextCharFormat charFormat = QTextCursor(bl).charFormat();
++ const QTextCharFormat charFormat = bl.charFormat();
+ QFont font(charFormat.font());
+ if (q->paintDevice())
+ font = QFont(font, q->paintDevice());
+diff --git a/qtbase/src/gui/text/qtextengine.cpp b/qtbase/src/gui/text/qtextengine.cpp
+index ce4abac472..a6c66e5d2d 100644
+--- a/qtbase/src/gui/text/qtextengine.cpp
++++ b/qtbase/src/gui/text/qtextengine.cpp
+@@ -1,6 +1,6 @@
+ /****************************************************************************
+ **
+-** Copyright (C) 2016 The Qt Company Ltd.
++** Copyright (C) 2021 The Qt Company Ltd.
+ ** Contact: https://www.qt.io/licensing/
+ **
+ ** This file is part of the QtGui module of the Qt Toolkit.
+@@ -1565,6 +1565,12 @@ void QTextEngine::shapeText(int item) const
+ // Overwrite with 0 token to indicate failure
+ QGlyphLayout g = availableGlyphs(&si);
+ g.glyphs[0] = 0;
++ g.attributes[0].clusterStart = true;
++
++ ushort *log_clusters = logClusters(&si);
++ for (int i = 0; i < itemLength; ++i)
++ log_clusters[i] = 0;
++
+ return;
+ }
+
+diff --git a/qtbase/src/gui/util/qdesktopservices.cpp b/qtbase/src/gui/util/qdesktopservices.cpp
+index fbb63a9408..4d5fafaaa7 100644
+--- a/qtbase/src/gui/util/qdesktopservices.cpp
++++ b/qtbase/src/gui/util/qdesktopservices.cpp
+@@ -54,6 +54,8 @@
+ #include <qpa/qplatformintegration.h>
+ #include <qdir.h>
+
++#include <QtCore/private/qlocking_p.h>
++
+ QT_BEGIN_NAMESPACE
+
+ class QOpenUrlHandlerRegistry : public QObject
+@@ -81,6 +83,7 @@ Q_GLOBAL_STATIC(QOpenUrlHandlerRegistry, handlerRegistry)
+
+ void QOpenUrlHandlerRegistry::handlerDestroyed(QObject *handler)
+ {
++ const auto lock = qt_scoped_lock(mutex);
+ HandlerHash::Iterator it = handlers.begin();
+ while (it != handlers.end()) {
+ if (it->receiver == handler) {
+@@ -294,7 +297,8 @@ void QDesktopServices::setUrlHandler(const QString &scheme, QObject *receiver, c
+ h.name = method;
+ registry->handlers.insert(scheme.toLower(), h);
+ QObject::connect(receiver, SIGNAL(destroyed(QObject*)),
+- registry, SLOT(handlerDestroyed(QObject*)));
++ registry, SLOT(handlerDestroyed(QObject*)),
++ Qt::DirectConnection);
+ }
+
+ /*!
+diff --git a/qtbase/src/gui/util/qpkmhandler.cpp b/qtbase/src/gui/util/qpkmhandler.cpp
+index e0c3b75efe..3414f9d8ba 100644
+--- a/qtbase/src/gui/util/qpkmhandler.cpp
++++ b/qtbase/src/gui/util/qpkmhandler.cpp
+@@ -57,7 +57,7 @@ struct PkmType
+ quint32 bytesPerBlock;
+ };
+
+-static PkmType typeMap[5] = {
++static constexpr PkmType typeMap[5] = {
+ { 0x8D64, 8 }, // GL_ETC1_RGB8_OES
+ { 0x9274, 8 }, // GL_COMPRESSED_RGB8_ETC2
+ { 0, 0 }, // unused (obsolete)
+diff --git a/qtbase/src/network/access/qnetworkreplyfileimpl.cpp b/qtbase/src/network/access/qnetworkreplyfileimpl.cpp
+index b6be93147a..6e69b4c4d3 100644
+--- a/qtbase/src/network/access/qnetworkreplyfileimpl.cpp
++++ b/qtbase/src/network/access/qnetworkreplyfileimpl.cpp
+@@ -89,9 +89,10 @@ QNetworkReplyFileImpl::QNetworkReplyFileImpl(QNetworkAccessManager *manager, con
+ // we handle only local files
+ QString msg = QCoreApplication::translate("QNetworkAccessFileBackend", "Request for opening non-local file %1").arg(url.toString());
+ setError(QNetworkReply::ProtocolInvalidOperationError, msg);
++ setFinished(true); // We're finished, will emit finished() after ctor is done.
+ QMetaObject::invokeMethod(this, "errorOccurred", Qt::QueuedConnection,
+ Q_ARG(QNetworkReply::NetworkError, QNetworkReply::ProtocolInvalidOperationError));
+- fileOpenFinished(false);
++ QMetaObject::invokeMethod(this, [this](){ fileOpenFinished(false); }, Qt::QueuedConnection);
+ return;
+ }
+ #endif
+diff --git a/qtbase/src/network/access/qnetworkreplyimpl.cpp b/qtbase/src/network/access/qnetworkreplyimpl.cpp
+index bcdf6ee2f1..3b6deb82bd 100644
+--- a/qtbase/src/network/access/qnetworkreplyimpl.cpp
++++ b/qtbase/src/network/access/qnetworkreplyimpl.cpp
+@@ -680,7 +680,7 @@ void QNetworkReplyImplPrivate::appendDownstreamData(QIODevice *data)
+ // read until EOF from data
+ if (Q_UNLIKELY(copyDevice)) {
+ qCritical("QNetworkReplyImpl: copy from QIODevice already in progress -- "
+- "backend probly needs to be fixed");
++ "backend probably needs to be fixed");
+ return;
+ }
+
+diff --git a/qtbase/src/network/kernel/qauthenticator.cpp b/qtbase/src/network/kernel/qauthenticator.cpp
+index d9fe7bc47b..ccd04b294a 100644
+--- a/qtbase/src/network/kernel/qauthenticator.cpp
++++ b/qtbase/src/network/kernel/qauthenticator.cpp
+@@ -50,6 +50,7 @@
+ #include <qstring.h>
+ #include <qdatetime.h>
+ #include <qrandom.h>
++#include "private/qsystemlibrary_p.h"
+
+ #ifdef Q_OS_WIN
+ #include <qmutex.h>
+@@ -1563,7 +1564,7 @@ static bool q_SSPI_library_load()
+
+ // Initialize security interface
+ if (pSecurityFunctionTable == nullptr) {
+- securityDLLHandle = LoadLibrary(L"secur32.dll");
++ securityDLLHandle = QSystemLibrary::load(L"secur32");
+ if (securityDLLHandle != nullptr) {
+ INIT_SECURITY_INTERFACE pInitSecurityInterface =
+ reinterpret_cast<INIT_SECURITY_INTERFACE>(
+diff --git a/qtbase/src/network/kernel/qhostinfo_unix.cpp b/qtbase/src/network/kernel/qhostinfo_unix.cpp
+index 9b0a2ee669..73679c9ef1 100644
+--- a/qtbase/src/network/kernel/qhostinfo_unix.cpp
++++ b/qtbase/src/network/kernel/qhostinfo_unix.cpp
+@@ -122,7 +122,6 @@ static QFunctionPointer resolveSymbol(QLibrary &lib, const char *sym)
+
+ LibResolv::LibResolv()
+ {
+- QLibrary lib;
+ #ifdef LIBRESOLV_SO
+ lib.setFileName(QStringLiteral(LIBRESOLV_SO));
+ if (!lib.load())
+diff --git a/qtbase/src/network/socket/qsocks5socketengine.cpp b/qtbase/src/network/socket/qsocks5socketengine.cpp
+index 3a046fd116..97fadca0b3 100644
+--- a/qtbase/src/network/socket/qsocks5socketengine.cpp
++++ b/qtbase/src/network/socket/qsocks5socketengine.cpp
+@@ -1296,7 +1296,7 @@ void QSocks5SocketEnginePrivate::_q_udpSocketReadNotification()
+ int pos = 0;
+ const char *buf = inBuf.constData();
+ if (inBuf.size() < 4) {
+- QSOCKS5_D_DEBUG << "bugus udp data, discarding";
++ QSOCKS5_D_DEBUG << "bogus udp data, discarding";
+ return;
+ }
+ QSocks5RevivedDatagram datagram;
+diff --git a/qtbase/src/network/ssl/qsslcontext_openssl.cpp b/qtbase/src/network/ssl/qsslcontext_openssl.cpp
+index c9f202f573..c992da9d8e 100644
+--- a/qtbase/src/network/ssl/qsslcontext_openssl.cpp
++++ b/qtbase/src/network/ssl/qsslcontext_openssl.cpp
+@@ -409,7 +409,7 @@ init_context:
+ break;
+ case QSsl::DtlsV1_0OrLater:
+ minVersion = DTLS1_VERSION;
+- maxVersion = DTLS_MAX_VERSION;
++ maxVersion = 0;
+ break;
+ case QSsl::DtlsV1_2:
+ minVersion = DTLS1_2_VERSION;
+@@ -417,7 +417,7 @@ init_context:
+ break;
+ case QSsl::DtlsV1_2OrLater:
+ minVersion = DTLS1_2_VERSION;
+- maxVersion = DTLS_MAX_VERSION;
++ maxVersion = 0;
+ break;
+ case QSsl::TlsV1_3OrLater:
+ #ifdef TLS1_3_VERSION
+@@ -455,7 +455,7 @@ init_context:
+ }
+
+ // Enable bug workarounds.
+- long options = QSslSocketBackendPrivate::setupOpenSslOptions(configuration.protocol(), configuration.d->sslOptions);
++ qssloptions options = QSslSocketBackendPrivate::setupOpenSslOptions(configuration.protocol(), configuration.d->sslOptions);
+ q_SSL_CTX_set_options(sslContext->ctx, options);
+
+ // Tell OpenSSL to release memory early
+diff --git a/qtbase/src/network/ssl/qssldiffiehellmanparameters_openssl.cpp b/qtbase/src/network/ssl/qssldiffiehellmanparameters_openssl.cpp
+index aaf8741130..b58935372c 100644
+--- a/qtbase/src/network/ssl/qssldiffiehellmanparameters_openssl.cpp
++++ b/qtbase/src/network/ssl/qssldiffiehellmanparameters_openssl.cpp
+@@ -59,57 +59,6 @@
+
+ QT_BEGIN_NAMESPACE
+
+-#ifdef OPENSSL_NO_DEPRECATED_3_0
+-
+-static int q_DH_check(DH *dh, int *status)
+-{
+- // DH_check was first deprecated in OpenSSL 3.0.0, as low-level
+- // API; the EVP_PKEY family of functions was advised as an alternative.
+- // As of now EVP_PKEY_params_check ends up calling ... DH_check,
+- // which is good enough.
+-
+- Q_ASSERT(dh);
+- Q_ASSERT(status);
+-
+- EVP_PKEY *key = q_EVP_PKEY_new();
+- if (!key) {
+- qCWarning(lcSsl, "EVP_PKEY_new failed");
+- QSslSocketBackendPrivate::logAndClearErrorQueue();
+- return 0;
+- }
+- const auto keyDeleter = qScopeGuard([key](){
+- q_EVP_PKEY_free(key);
+- });
+- if (!q_EVP_PKEY_set1_DH(key, dh)) {
+- qCWarning(lcSsl, "EVP_PKEY_set1_DH failed");
+- QSslSocketBackendPrivate::logAndClearErrorQueue();
+- return 0;
+- }
+-
+- EVP_PKEY_CTX *keyCtx = q_EVP_PKEY_CTX_new(key, nullptr);
+- if (!keyCtx) {
+- qCWarning(lcSsl, "EVP_PKEY_CTX_new failed");
+- QSslSocketBackendPrivate::logAndClearErrorQueue();
+- return 0;
+- }
+- const auto ctxDeleter = qScopeGuard([keyCtx]{
+- q_EVP_PKEY_CTX_free(keyCtx);
+- });
+-
+- const int result = q_EVP_PKEY_param_check(keyCtx);
+- QSslSocketBackendPrivate::logAndClearErrorQueue();
+- // Note: unlike DH_check, we cannot obtain the 'status',
+- // if the 'result' is 0 (actually the result is 1 only
+- // if this 'status' was 0). We could probably check the
+- // errors from the error queue, but it's not needed anyway
+- // - see the 'isSafeDH' below, how it returns immediately
+- // on 0.
+- Q_UNUSED(status)
+-
+- return result;
+-}
+-#endif // OPENSSL_NO_DEPRECATED_3_0
+-
+ static bool isSafeDH(DH *dh)
+ {
+ int status = 0;
+diff --git a/qtbase/src/network/ssl/qsslsocket_openssl.cpp b/qtbase/src/network/ssl/qsslsocket_openssl.cpp
+index 37fad2a68f..8f6858c867 100644
+--- a/qtbase/src/network/ssl/qsslsocket_openssl.cpp
++++ b/qtbase/src/network/ssl/qsslsocket_openssl.cpp
+@@ -550,9 +550,9 @@ static void q_loadCiphersForConnection(SSL *connection, QList<QSslCipher> &ciphe
+ // Defined in qsslsocket.cpp
+ void q_setDefaultDtlsCiphers(const QList<QSslCipher> &ciphers);
+
+-long QSslSocketBackendPrivate::setupOpenSslOptions(QSsl::SslProtocol protocol, QSsl::SslOptions sslOptions)
++qssloptions QSslSocketBackendPrivate::setupOpenSslOptions(QSsl::SslProtocol protocol, QSsl::SslOptions sslOptions)
+ {
+- long options;
++ qssloptions options;
+ if (protocol == QSsl::TlsV1SslV3)
+ options = SSL_OP_ALL|SSL_OP_NO_SSLv2|SSL_OP_NO_SSLv3;
+ else if (protocol == QSsl::SecureProtocols)
+diff --git a/qtbase/src/network/ssl/qsslsocket_openssl_p.h b/qtbase/src/network/ssl/qsslsocket_openssl_p.h
+index 4103de23e8..5547589256 100644
+--- a/qtbase/src/network/ssl/qsslsocket_openssl_p.h
++++ b/qtbase/src/network/ssl/qsslsocket_openssl_p.h
+@@ -107,6 +107,12 @@
+
+ QT_BEGIN_NAMESPACE
+
++#if defined(OPENSSL_VERSION_MAJOR) && OPENSSL_VERSION_MAJOR >= 3
++typedef uint64_t qssloptions;
++#else
++typedef unsigned long qssloptions;
++#endif
++
+ struct QSslErrorEntry {
+ int code;
+ int depth;
+@@ -171,7 +177,7 @@ public:
+ QVector<QSslError> ocspErrors;
+ QByteArray ocspResponseDer;
+
+- Q_AUTOTEST_EXPORT static long setupOpenSslOptions(QSsl::SslProtocol protocol, QSsl::SslOptions sslOptions);
++ Q_AUTOTEST_EXPORT static qssloptions setupOpenSslOptions(QSsl::SslProtocol protocol, QSsl::SslOptions sslOptions);
+ static QSslCipher QSslCipher_from_SSL_CIPHER(const SSL_CIPHER *cipher);
+ static QList<QSslCertificate> STACKOFX509_to_QSslCertificates(STACK_OF(X509) *x509);
+ static QList<QSslError> verify(const QList<QSslCertificate> &certificateChain, const QString &hostName);
+diff --git a/qtbase/src/network/ssl/qsslsocket_openssl_symbols.cpp b/qtbase/src/network/ssl/qsslsocket_openssl_symbols.cpp
+index e53fb279f0..459ccd0b19 100644
+--- a/qtbase/src/network/ssl/qsslsocket_openssl_symbols.cpp
++++ b/qtbase/src/network/ssl/qsslsocket_openssl_symbols.cpp
+@@ -148,7 +148,6 @@ DEFINEFUNC(int, EVP_PKEY_up_ref, EVP_PKEY *a, a, return 0, return)
+ DEFINEFUNC2(EVP_PKEY_CTX *, EVP_PKEY_CTX_new, EVP_PKEY *pkey, pkey, ENGINE *e, e, return nullptr, return)
+ DEFINEFUNC(int, EVP_PKEY_param_check, EVP_PKEY_CTX *ctx, ctx, return 0, return)
+ DEFINEFUNC(void, EVP_PKEY_CTX_free, EVP_PKEY_CTX *ctx, ctx, return, return)
+-DEFINEFUNC(int, EVP_PKEY_base_id, EVP_PKEY *a, a, return NID_undef, return)
+ DEFINEFUNC(int, RSA_bits, RSA *a, a, return 0, return)
+ DEFINEFUNC(int, DSA_bits, DSA *a, a, return 0, return)
+ DEFINEFUNC(int, OPENSSL_sk_num, OPENSSL_STACK *a, a, return -1, return)
+@@ -158,7 +157,7 @@ DEFINEFUNC2(void, OPENSSL_sk_push, OPENSSL_STACK *a, a, void *b, b, return, DUMM
+ DEFINEFUNC(void, OPENSSL_sk_free, OPENSSL_STACK *a, a, return, DUMMYARG)
+ DEFINEFUNC2(void *, OPENSSL_sk_value, OPENSSL_STACK *a, a, int b, b, return nullptr, return)
+ DEFINEFUNC(int, SSL_session_reused, SSL *a, a, return 0, return)
+-DEFINEFUNC2(unsigned long, SSL_CTX_set_options, SSL_CTX *ctx, ctx, unsigned long op, op, return 0, return)
++DEFINEFUNC2(qssloptions, SSL_CTX_set_options, SSL_CTX *ctx, ctx, qssloptions op, op, return 0, return)
+ DEFINEFUNC(int, SSL_CTX_get_security_level, const SSL_CTX *ctx, ctx, return -1, return)
+ DEFINEFUNC2(void, SSL_CTX_set_security_level, SSL_CTX *ctx, ctx, int level, level, return, return)
+ #ifdef TLS1_3_VERSION
+@@ -371,7 +370,15 @@ DEFINEFUNC(const SSL_CIPHER *, SSL_get_current_cipher, SSL *a, a, return nullptr
+ DEFINEFUNC(int, SSL_version, const SSL *a, a, return 0, return)
+ DEFINEFUNC2(int, SSL_get_error, SSL *a, a, int b, b, return -1, return)
+ DEFINEFUNC(STACK_OF(X509) *, SSL_get_peer_cert_chain, SSL *a, a, return nullptr, return)
++
++#if defined(OPENSSL_VERSION_MAJOR) && OPENSSL_VERSION_MAJOR >= 3
++DEFINEFUNC(X509 *, SSL_get1_peer_certificate, SSL *a, a, return nullptr, return)
++DEFINEFUNC(int, EVP_PKEY_get_base_id, const EVP_PKEY *pkey, pkey, return -1, return)
++#else
+ DEFINEFUNC(X509 *, SSL_get_peer_certificate, SSL *a, a, return nullptr, return)
++DEFINEFUNC(int, EVP_PKEY_base_id, EVP_PKEY *a, a, return NID_undef, return)
++#endif // OPENSSL_VERSION_MAJOR >= 3
++
+ DEFINEFUNC(long, SSL_get_verify_result, const SSL *a, a, return -1, return)
+ DEFINEFUNC(SSL *, SSL_new, SSL_CTX *a, a, return nullptr, return)
+ DEFINEFUNC(SSL_CTX *, SSL_get_SSL_CTX, SSL *a, a, return nullptr, return)
+@@ -492,9 +499,7 @@ DEFINEFUNC(DH *, DH_new, DUMMYARG, DUMMYARG, return nullptr, return)
+ DEFINEFUNC(void, DH_free, DH *dh, dh, return, DUMMYARG)
+ DEFINEFUNC3(DH *, d2i_DHparams, DH**a, a, const unsigned char **pp, pp, long length, length, return nullptr, return)
+ DEFINEFUNC2(int, i2d_DHparams, DH *a, a, unsigned char **p, p, return -1, return)
+-#ifndef OPENSSL_NO_DEPRECATED_3_0
+ DEFINEFUNC2(int, DH_check, DH *dh, dh, int *codes, codes, return 0, return)
+-#endif // OPENSSL_NO_DEPRECATED_3_0
+ DEFINEFUNC3(BIGNUM *, BN_bin2bn, const unsigned char *s, s, int len, len, BIGNUM *ret, ret, return nullptr, return)
+
+ #ifndef OPENSSL_NO_EC
+@@ -868,7 +873,6 @@ bool q_resolveOpenSslSymbols()
+ RESOLVEFUNC(EVP_PKEY_CTX_new)
+ RESOLVEFUNC(EVP_PKEY_param_check)
+ RESOLVEFUNC(EVP_PKEY_CTX_free)
+- RESOLVEFUNC(EVP_PKEY_base_id)
+ RESOLVEFUNC(RSA_bits)
+ RESOLVEFUNC(OPENSSL_sk_new_null)
+ RESOLVEFUNC(OPENSSL_sk_push)
+@@ -1107,7 +1111,15 @@ bool q_resolveOpenSslSymbols()
+ RESOLVEFUNC(SSL_version)
+ RESOLVEFUNC(SSL_get_error)
+ RESOLVEFUNC(SSL_get_peer_cert_chain)
++
++#if defined(OPENSSL_VERSION_MAJOR) && OPENSSL_VERSION_MAJOR >= 3
++ RESOLVEFUNC(SSL_get1_peer_certificate)
++ RESOLVEFUNC(EVP_PKEY_get_base_id)
++#else
+ RESOLVEFUNC(SSL_get_peer_certificate)
++ RESOLVEFUNC(EVP_PKEY_base_id)
++#endif // OPENSSL_VERSION_MAJOR >= 3
++
+ RESOLVEFUNC(SSL_get_verify_result)
+ RESOLVEFUNC(SSL_new)
+ RESOLVEFUNC(SSL_get_SSL_CTX)
+@@ -1206,9 +1218,7 @@ bool q_resolveOpenSslSymbols()
+ RESOLVEFUNC(DH_free)
+ RESOLVEFUNC(d2i_DHparams)
+ RESOLVEFUNC(i2d_DHparams)
+-#ifndef OPENSSL_NO_DEPRECATED_3_0
+ RESOLVEFUNC(DH_check)
+-#endif // OPENSSL_NO_DEPRECATED_3_0
+ RESOLVEFUNC(BN_bin2bn)
+
+ #ifndef OPENSSL_NO_EC
+diff --git a/qtbase/src/network/ssl/qsslsocket_openssl_symbols_p.h b/qtbase/src/network/ssl/qsslsocket_openssl_symbols_p.h
+index 95e8897a3b..27aeffa18a 100644
+--- a/qtbase/src/network/ssl/qsslsocket_openssl_symbols_p.h
++++ b/qtbase/src/network/ssl/qsslsocket_openssl_symbols_p.h
+@@ -237,7 +237,6 @@ Q_AUTOTEST_EXPORT int q_EVP_PKEY_up_ref(EVP_PKEY *a);
+ EVP_PKEY_CTX *q_EVP_PKEY_CTX_new(EVP_PKEY *pkey, ENGINE *e);
+ void q_EVP_PKEY_CTX_free(EVP_PKEY_CTX *ctx);
+ int q_EVP_PKEY_param_check(EVP_PKEY_CTX *ctx);
+-int q_EVP_PKEY_base_id(EVP_PKEY *a);
+ int q_RSA_bits(RSA *a);
+ Q_AUTOTEST_EXPORT int q_OPENSSL_sk_num(OPENSSL_STACK *a);
+ Q_AUTOTEST_EXPORT void q_OPENSSL_sk_pop_free(OPENSSL_STACK *a, void (*b)(void *));
+@@ -246,7 +245,7 @@ Q_AUTOTEST_EXPORT void q_OPENSSL_sk_push(OPENSSL_STACK *st, void *data);
+ Q_AUTOTEST_EXPORT void q_OPENSSL_sk_free(OPENSSL_STACK *a);
+ Q_AUTOTEST_EXPORT void * q_OPENSSL_sk_value(OPENSSL_STACK *a, int b);
+ int q_SSL_session_reused(SSL *a);
+-unsigned long q_SSL_CTX_set_options(SSL_CTX *ctx, unsigned long op);
++qssloptions q_SSL_CTX_set_options(SSL_CTX *ctx, qssloptions op);
+ int q_OPENSSL_init_ssl(uint64_t opts, const OPENSSL_INIT_SETTINGS *settings);
+ size_t q_SSL_get_client_random(SSL *a, unsigned char *out, size_t outlen);
+ size_t q_SSL_SESSION_get_master_key(const SSL_SESSION *session, unsigned char *out, size_t outlen);
+@@ -510,7 +509,6 @@ const SSL_CIPHER *q_SSL_get_current_cipher(SSL *a);
+ int q_SSL_version(const SSL *a);
+ int q_SSL_get_error(SSL *a, int b);
+ STACK_OF(X509) *q_SSL_get_peer_cert_chain(SSL *a);
+-X509 *q_SSL_get_peer_certificate(SSL *a);
+ long q_SSL_get_verify_result(const SSL *a);
+ SSL *q_SSL_new(SSL_CTX *a);
+ SSL_CTX *q_SSL_get_SSL_CTX(SSL *a);
+@@ -582,10 +580,7 @@ DH *q_DH_new();
+ void q_DH_free(DH *dh);
+ DH *q_d2i_DHparams(DH **a, const unsigned char **pp, long length);
+ int q_i2d_DHparams(DH *a, unsigned char **p);
+-
+-#ifndef OPENSSL_NO_DEPRECATED_3_0
+ int q_DH_check(DH *dh, int *codes);
+-#endif // OPENSSL_NO_DEPRECATED_3_0
+
+ BIGNUM *q_BN_bin2bn(const unsigned char *s, int len, BIGNUM *ret);
+ #define q_SSL_CTX_set_tmp_dh(ctx, dh) q_SSL_CTX_ctrl((ctx), SSL_CTRL_SET_TMP_DH, 0, (char *)dh)
+@@ -754,6 +749,17 @@ void q_CRYPTO_free(void *str, const char *file, int line);
+ int q_SSL_CTX_get_security_level(const SSL_CTX *ctx);
+ void q_SSL_CTX_set_security_level(SSL_CTX *ctx, int level);
+
++// Here we have the ones that make difference between OpenSSL pre/post v3:
++#if defined(OPENSSL_VERSION_MAJOR) && OPENSSL_VERSION_MAJOR >= 3
++X509 *q_SSL_get1_peer_certificate(SSL *a);
++#define q_SSL_get_peer_certificate q_SSL_get1_peer_certificate
++int q_EVP_PKEY_get_base_id(const EVP_PKEY *pkey);
++#define q_EVP_PKEY_base_id q_EVP_PKEY_get_base_id
++#else
++X509 *q_SSL_get_peer_certificate(SSL *a);
++int q_EVP_PKEY_base_id(EVP_PKEY *a);
++#endif // OPENSSL_VERSION_MAJOR >= 3
++
+ QT_END_NAMESPACE
+
+ #endif
+diff --git a/qtbase/src/platformsupport/eglconvenience/qt_egl_p.h b/qtbase/src/platformsupport/eglconvenience/qt_egl_p.h
+index bf37d07fd8..dbd42fb799 100644
+--- a/qtbase/src/platformsupport/eglconvenience/qt_egl_p.h
++++ b/qtbase/src/platformsupport/eglconvenience/qt_egl_p.h
+@@ -61,7 +61,11 @@
+ # if !defined(Q_OS_INTEGRITY)
+ # define WIN_INTERFACE_CUSTOM // NV
+ # endif // Q_OS_INTEGRITY
+-#endif // QT_EGL_NO_X11
++#else // QT_EGL_NO_X11
++// If one has an eglplatform.h with https://github.com/KhronosGroup/EGL-Registry/pull/130
++// that needs USE_X11 to be defined.
++# define USE_X11
++#endif
+
+ #ifdef QT_EGL_WAYLAND
+ # define WAYLAND // NV
+diff --git a/qtbase/src/platformsupport/fontdatabases/fontconfig/qfontconfigdatabase.cpp b/qtbase/src/platformsupport/fontdatabases/fontconfig/qfontconfigdatabase.cpp
+index 159b490ce0..00aa80cd58 100644
+--- a/qtbase/src/platformsupport/fontdatabases/fontconfig/qfontconfigdatabase.cpp
++++ b/qtbase/src/platformsupport/fontdatabases/fontconfig/qfontconfigdatabase.cpp
+@@ -567,6 +567,8 @@ void QFontconfigDatabase::populateFontDatabase()
+ fonts = FcFontList(nullptr, pattern, os);
+ FcObjectSetDestroy(os);
+ FcPatternDestroy(pattern);
++ if (!fonts)
++ return;
+ }
+
+ for (int i = 0; i < fonts->nfont; i++)
+diff --git a/qtbase/src/platformsupport/input/xkbcommon/qxkbcommon.cpp b/qtbase/src/platformsupport/input/xkbcommon/qxkbcommon.cpp
+index b713c19447..7cb9a8c79a 100644
+--- a/qtbase/src/platformsupport/input/xkbcommon/qxkbcommon.cpp
++++ b/qtbase/src/platformsupport/input/xkbcommon/qxkbcommon.cpp
+@@ -95,6 +95,7 @@ static constexpr const auto KeyTbl = qMakeArray(
+ Xkb2Qt<XKB_KEY_Clear, Qt::Key_Delete>,
+ Xkb2Qt<XKB_KEY_Pause, Qt::Key_Pause>,
+ Xkb2Qt<XKB_KEY_Print, Qt::Key_Print>,
++ Xkb2Qt<XKB_KEY_Sys_Req, Qt::Key_SysReq>,
+ Xkb2Qt<0x1005FF60, Qt::Key_SysReq>, // hardcoded Sun SysReq
+ Xkb2Qt<0x1007ff00, Qt::Key_SysReq>, // hardcoded X386 SysReq
+
+@@ -471,7 +472,7 @@ QVector<xkb_keysym_t> QXkbCommon::toKeysym(QKeyEvent *event)
+ } else if (event->modifiers() & Qt::KeypadModifier) {
+ if (qtKey >= Qt::Key_0 && qtKey <= Qt::Key_9)
+ keysyms.append(XKB_KEY_KP_0 + (qtKey - Qt::Key_0));
+- } else if (isLatin(qtKey) && event->text().isUpper()) {
++ } else if (isLatin1(qtKey) && event->text().isUpper()) {
+ keysyms.append(qtKey);
+ }
+
+@@ -523,7 +524,7 @@ int QXkbCommon::keysymToQtKey(xkb_keysym_t keysym, Qt::KeyboardModifiers modifie
+ // With standard shortcuts we should prefer a latin character, this is
+ // for checks like "some qkeyevent == QKeySequence::Copy" to work even
+ // when using for example 'russian' keyboard layout.
+- if (!QXkbCommon::isLatin(keysym)) {
++ if (!QXkbCommon::isLatin1(keysym)) {
+ xkb_keysym_t latinKeysym = QXkbCommon::lookupLatinKeysym(state, code);
+ if (latinKeysym != XKB_KEY_NoSymbol)
+ keysym = latinKeysym;
+@@ -546,7 +547,7 @@ static int keysymToQtKey_internal(xkb_keysym_t keysym, Qt::KeyboardModifiers mod
+ } else if (keysym >= XKB_KEY_KP_0 && keysym <= XKB_KEY_KP_9) {
+ // numeric keypad keys
+ qtKey = Qt::Key_0 + (keysym - XKB_KEY_KP_0);
+- } else if (QXkbCommon::isLatin(keysym)) {
++ } else if (QXkbCommon::isLatin1(keysym)) {
+ qtKey = QXkbCommon::qxkbcommon_xkb_keysym_to_upper(keysym);
+ } else {
+ // check if we have a direct mapping
+@@ -678,7 +679,7 @@ QList<int> QXkbCommon::possibleKeys(xkb_state *state, const QKeyEvent *event,
+ Qt::KeyboardModifiers neededMods = ModsTbl[i];
+ if ((modifiers & neededMods) == neededMods) {
+ if (i == 8) {
+- if (isLatin(baseQtKey))
++ if (isLatin1(baseQtKey))
+ continue;
+ // add a latin key as a fall back key
+ sym = lookupLatinKeysym(state, keycode);
+@@ -733,7 +734,7 @@ void QXkbCommon::verifyHasLatinLayout(xkb_keymap *keymap)
+ for (xkb_layout_index_t layout = 0; layout < layoutCount; ++layout) {
+ for (xkb_keycode_t code = minKeycode; code < maxKeycode; ++code) {
+ xkb_keymap_key_get_syms_by_level(keymap, code, layout, 0, &keysyms);
+- if (keysyms && isLatin(keysyms[0]))
++ if (keysyms && isLatin1(keysyms[0]))
+ nrLatinKeys++;
+ if (nrLatinKeys > 10) // arbitrarily chosen threshold
+ return;
+@@ -766,7 +767,7 @@ xkb_keysym_t QXkbCommon::lookupLatinKeysym(xkb_state *state, xkb_keycode_t keyco
+ xkb_level_index_t level = xkb_state_key_get_level(state, keycode, layout);
+ if (xkb_keymap_key_get_syms_by_level(keymap, keycode, layout, level, &syms) != 1)
+ continue;
+- if (isLatin(syms[0])) {
++ if (isLatin1(syms[0])) {
+ sym = syms[0];
+ break;
+ }
+diff --git a/qtbase/src/platformsupport/input/xkbcommon/qxkbcommon_p.h b/qtbase/src/platformsupport/input/xkbcommon/qxkbcommon_p.h
+index 561eae03db..8389bd8f5a 100644
+--- a/qtbase/src/platformsupport/input/xkbcommon/qxkbcommon_p.h
++++ b/qtbase/src/platformsupport/input/xkbcommon/qxkbcommon_p.h
+@@ -94,8 +94,8 @@ public:
+ static void verifyHasLatinLayout(xkb_keymap *keymap);
+ static xkb_keysym_t lookupLatinKeysym(xkb_state *state, xkb_keycode_t keycode);
+
+- static bool isLatin(xkb_keysym_t sym) {
+- return ((sym >= 'a' && sym <= 'z') || (sym >= 'A' && sym <= 'Z'));
++ static bool isLatin1(xkb_keysym_t sym) {
++ return sym <= 0xff;
+ }
+ static bool isKeypad(xkb_keysym_t sym) {
+ return sym >= XKB_KEY_KP_Space && sym <= XKB_KEY_KP_9;
+diff --git a/qtbase/src/platformsupport/kmsconvenience/qkmsdevice.cpp b/qtbase/src/platformsupport/kmsconvenience/qkmsdevice.cpp
+index 8cd7f9b368..406f84663f 100644
+--- a/qtbase/src/platformsupport/kmsconvenience/qkmsdevice.cpp
++++ b/qtbase/src/platformsupport/kmsconvenience/qkmsdevice.cpp
+@@ -318,7 +318,7 @@ QPlatformScreen *QKmsDevice::createScreenForConnector(drmModeResPtr resources,
+
+ if (current < 0 && crtc_mode.clock != 0) {
+ modes << crtc_mode;
+- current = mode.size() - 1;
++ current = modes.size() - 1;
+ }
+
+ if (configuration == OutputConfigCurrent)
+diff --git a/qtbase/src/platformsupport/linuxaccessibility/atspiadaptor.cpp b/qtbase/src/platformsupport/linuxaccessibility/atspiadaptor.cpp
+index 9153fd20bb..255ea5e33e 100644
+--- a/qtbase/src/platformsupport/linuxaccessibility/atspiadaptor.cpp
++++ b/qtbase/src/platformsupport/linuxaccessibility/atspiadaptor.cpp
+@@ -194,6 +194,9 @@ QString AtSpiAdaptor::introspect(const QString &path) const
+ " <arg direction=\"out\" type=\"(so)\"/>\n"
+ " <annotation value=\"QSpiObjectReference\" name=\"org.qtproject.QtDBus.QtTypeName.Out0\"/>\n"
+ " </method>\n"
++ " <method name=\"GetAccessibleId\">\n"
++ " <arg direction=\"out\" type=\"s\"/>\n"
++ " </method>\n"
+ " </interface>\n"
+ );
+
+@@ -913,8 +916,17 @@ void AtSpiAdaptor::notify(QAccessibleEvent *event)
+ }
+ case QAccessible::NameChanged: {
+ if (sendObject || sendObject_property_change || sendObject_property_change_accessible_name) {
+- QString path = pathForInterface(event->accessibleInterface());
+- QVariantList args = packDBusSignalArguments(QLatin1String("accessible-name"), 0, 0, variantForPath(path));
++ QAccessibleInterface *iface = event->accessibleInterface();
++ if (!iface) {
++ qCDebug(lcAccessibilityAtspi,
++ "NameChanged event from invalid accessible.");
++ return;
++ }
++
++ QString path = pathForInterface(iface);
++ QVariantList args = packDBusSignalArguments(
++ QLatin1String("accessible-name"), 0, 0,
++ QVariant::fromValue(QDBusVariant(iface->text(QAccessible::Name))));
+ sendDBusSignal(path, QLatin1String(ATSPI_DBUS_INTERFACE_EVENT_OBJECT),
+ QLatin1String("PropertyChange"), args);
+ }
+@@ -922,8 +934,17 @@ void AtSpiAdaptor::notify(QAccessibleEvent *event)
+ }
+ case QAccessible::DescriptionChanged: {
+ if (sendObject || sendObject_property_change || sendObject_property_change_accessible_description) {
+- QString path = pathForInterface(event->accessibleInterface());
+- QVariantList args = packDBusSignalArguments(QLatin1String("accessible-description"), 0, 0, variantForPath(path));
++ QAccessibleInterface *iface = event->accessibleInterface();
++ if (!iface) {
++ qCDebug(lcAccessibilityAtspi,
++ "DescriptionChanged event from invalid accessible.");
++ return;
++ }
++
++ QString path = pathForInterface(iface);
++ QVariantList args = packDBusSignalArguments(
++ QLatin1String("accessible-description"), 0, 0,
++ QVariant::fromValue(QDBusVariant(iface->text(QAccessible::Description))));
+ sendDBusSignal(path, QLatin1String(ATSPI_DBUS_INTERFACE_EVENT_OBJECT),
+ QLatin1String("PropertyChange"), args);
+ }
+@@ -1038,7 +1059,9 @@ void AtSpiAdaptor::notify(QAccessibleEvent *event)
+ // Combo Box with AT-SPI likes to be special
+ // It requires a name-change to update caches and then selection-changed
+ QString path = pathForInterface(iface);
+- QVariantList args1 = packDBusSignalArguments(QLatin1String("accessible-name"), 0, 0, variantForPath(path));
++ QVariantList args1 = packDBusSignalArguments(
++ QLatin1String("accessible-name"), 0, 0,
++ QVariant::fromValue(QDBusVariant(iface->text(QAccessible::Name))));
+ sendDBusSignal(path, QLatin1String(ATSPI_DBUS_INTERFACE_EVENT_OBJECT),
+ QLatin1String("PropertyChange"), args1);
+ QVariantList args2 = packDBusSignalArguments(QString(), 0, 0, QVariant::fromValue(QDBusVariant(QVariant(0))));
+@@ -1358,6 +1381,26 @@ void AtSpiAdaptor::registerApplication()
+ delete registry;
+ }
+
++namespace {
++QString accessibleIdForAccessible(QAccessibleInterface *accessible)
++{
++ QString result;
++ while (accessible) {
++ if (!result.isEmpty())
++ result.prepend(QLatin1Char('.'));
++ if (auto obj = accessible->object()) {
++ const QString name = obj->objectName();
++ if (!name.isEmpty())
++ result.prepend(name);
++ else
++ result.prepend(QString::fromUtf8(obj->metaObject()->className()));
++ }
++ accessible = accessible->parent();
++ }
++ return result;
++}
++} // namespace
++
+ // Accessible
+ bool AtSpiAdaptor::accessibleInterface(QAccessibleInterface *interface, const QString &function, const QDBusMessage &message, const QDBusConnection &connection)
+ {
+@@ -1441,6 +1484,9 @@ bool AtSpiAdaptor::accessibleInterface(QAccessibleInterface *interface, const QS
+ children << ref;
+ }
+ connection.send(message.createReply(QVariant::fromValue(children)));
++ } else if (function == QLatin1String("GetAccessibleId")) {
++ sendReply(connection, message,
++ QVariant::fromValue(QDBusVariant(accessibleIdForAccessible(interface))));
+ } else {
+ qCDebug(lcAccessibilityAtspi) << "WARNING: AtSpiAdaptor::accessibleInterface does not implement " << function << message.path();
+ return false;
+diff --git a/qtbase/src/platformsupport/linuxaccessibility/dbusconnection.cpp b/qtbase/src/platformsupport/linuxaccessibility/dbusconnection.cpp
+index 45ddc8e496..cc734abc63 100644
+--- a/qtbase/src/platformsupport/linuxaccessibility/dbusconnection.cpp
++++ b/qtbase/src/platformsupport/linuxaccessibility/dbusconnection.cpp
+@@ -69,6 +69,21 @@ QT_BEGIN_NAMESPACE
+ DBusConnection::DBusConnection(QObject *parent)
+ : QObject(parent), m_a11yConnection(QString()), m_enabled(false)
+ {
++ // If the bus is explicitly set via env var it overrides everything else.
++ QByteArray addressEnv = qgetenv("AT_SPI_BUS_ADDRESS");
++ if (!addressEnv.isEmpty()) {
++ // Only connect on next loop run, connections to our enabled signal are
++ // only established after the ctor returns.
++ QMetaObject::invokeMethod(
++ this,
++ [this, addressEnv] {
++ m_enabled = true;
++ connectA11yBus(QString::fromLocal8Bit(addressEnv));
++ },
++ Qt::QueuedConnection);
++ return;
++ }
++
+ // Start monitoring if "org.a11y.Bus" is registered as DBus service.
+ QDBusConnection c = QDBusConnection::sessionBus();
+ if (!c.isConnected()) {
+diff --git a/qtbase/src/platformsupport/services/genericunix/qgenericunixservices.cpp b/qtbase/src/platformsupport/services/genericunix/qgenericunixservices.cpp
+index 1a3cab275d..2abe039126 100644
+--- a/qtbase/src/platformsupport/services/genericunix/qgenericunixservices.cpp
++++ b/qtbase/src/platformsupport/services/genericunix/qgenericunixservices.cpp
+@@ -51,6 +51,9 @@
+ #include <QtCore/QStandardPaths>
+ #include <QtCore/QUrl>
+
++#include <QtGui/QGuiApplication>
++#include <QtGui/QWindow>
++
+ #if QT_CONFIG(dbus)
+ // These QtCore includes are needed for xdg-desktop-portal support
+ #include <QtCore/private/qcore_unix_p.h>
+@@ -58,6 +61,8 @@
+ #include <QtCore/QFileInfo>
+ #include <QtCore/QUrlQuery>
+
++#include <QtGui/QColor>
++
+ #include <QtDBus/QDBusConnection>
+ #include <QtDBus/QDBusMessage>
+ #include <QtDBus/QDBusPendingCall>
+@@ -142,6 +147,8 @@ static inline bool detectWebBrowser(const QByteArray &desktop,
+ }
+
+ if (desktop == QByteArray("KDE")) {
++ if (checkExecutable(QStringLiteral("kde-open5"), browser))
++ return true;
+ // Konqueror launcher
+ if (checkExecutable(QStringLiteral("kfmclient"), browser)) {
+ browser->append(QLatin1String(" exec"));
+@@ -296,8 +303,135 @@ static inline QDBusMessage xdgDesktopPortalSendEmail(const QUrl &url)
+
+ return QDBusConnection::sessionBus().call(message);
+ }
++
++namespace {
++struct XDGDesktopColor
++{
++ double r = 0;
++ double g = 0;
++ double b = 0;
++
++ QColor toQColor() const
++ {
++ constexpr auto rgbMax = 255;
++ return { static_cast<int>(r * rgbMax), static_cast<int>(g * rgbMax),
++ static_cast<int>(b * rgbMax) };
++ }
++};
++
++const QDBusArgument &operator>>(const QDBusArgument &argument, XDGDesktopColor &myStruct)
++{
++ argument.beginStructure();
++ argument >> myStruct.r >> myStruct.g >> myStruct.b;
++ argument.endStructure();
++ return argument;
++}
++
++class XdgDesktopPortalColorPicker : public QPlatformServiceColorPicker
++{
++ Q_OBJECT
++public:
++ XdgDesktopPortalColorPicker(const QString &parentWindowId, QWindow *parent)
++ : QPlatformServiceColorPicker(parent), m_parentWindowId(parentWindowId)
++ {
++ }
++
++ void pickColor() override
++ {
++ // DBus signature:
++ // PickColor (IN s parent_window,
++ // IN a{sv} options
++ // OUT o handle)
++ // Options:
++ // handle_token (s) - A string that will be used as the last element of the @handle.
++
++ QDBusMessage message = QDBusMessage::createMethodCall(
++ QStringLiteral("org.freedesktop.portal.Desktop"), QStringLiteral("/org/freedesktop/portal/desktop"),
++ QStringLiteral("org.freedesktop.portal.Screenshot"), QStringLiteral("PickColor"));
++ message << m_parentWindowId << QVariantMap();
++
++ QDBusPendingCall pendingCall = QDBusConnection::sessionBus().asyncCall(message);
++ auto watcher = new QDBusPendingCallWatcher(pendingCall, this);
++ connect(watcher, &QDBusPendingCallWatcher::finished, this,
++ [this](QDBusPendingCallWatcher *watcher) {
++ watcher->deleteLater();
++ QDBusPendingReply<QDBusObjectPath> reply = *watcher;
++ if (reply.isError()) {
++ qWarning("DBus call to pick color failed: %s",
++ qPrintable(reply.error().message()));
++ Q_EMIT colorPicked({});
++ } else {
++ QDBusConnection::sessionBus().connect(
++ QStringLiteral("org.freedesktop.portal.Desktop"), reply.value().path(),
++ QStringLiteral("org.freedesktop.portal.Request"), QStringLiteral("Response"), this,
++ // clang-format off
++ SLOT(gotColorResponse(uint,QVariantMap))
++ // clang-format on
++ );
++ }
++ });
++ }
++
++private Q_SLOTS:
++ void gotColorResponse(uint result, const QVariantMap &map)
++ {
++ if (result != 0)
++ return;
++ XDGDesktopColor color{};
++ map.value(QStringLiteral("color")).value<QDBusArgument>() >> color;
++ Q_EMIT colorPicked(color.toQColor());
++ deleteLater();
++ }
++
++private:
++ const QString m_parentWindowId;
++};
++} // namespace
++
+ #endif // QT_CONFIG(dbus)
+
++QGenericUnixServices::QGenericUnixServices()
++{
++#if QT_CONFIG(dbus)
++ if (qEnvironmentVariableIntValue("QT_NO_XDG_DESKTOP_PORTAL") > 0) {
++ return;
++ }
++ QDBusMessage message = QDBusMessage::createMethodCall(
++ QStringLiteral("org.freedesktop.portal.Desktop"), QStringLiteral("/org/freedesktop/portal/desktop"),
++ QStringLiteral("org.freedesktop.DBus.Properties"), QStringLiteral("Get"));
++ message << QStringLiteral("org.freedesktop.portal.Screenshot")
++ << QStringLiteral("version");
++
++ QDBusPendingCall pendingCall = QDBusConnection::sessionBus().asyncCall(message);
++ auto watcher = new QDBusPendingCallWatcher(pendingCall);
++ QObject::connect(watcher, &QDBusPendingCallWatcher::finished, watcher,
++ [this](QDBusPendingCallWatcher *watcher) {
++ watcher->deleteLater();
++ QDBusPendingReply<QVariant> reply = *watcher;
++ if (!reply.isError() && reply.value().toUInt() >= 2)
++ m_hasScreenshotPortalWithColorPicking = true;
++ });
++
++#endif
++}
++
++QPlatformServiceColorPicker *QGenericUnixServices::colorPicker(QWindow *parent)
++{
++#if QT_CONFIG(dbus)
++ // Make double sure that we are in a wayland environment. In particular check
++ // WAYLAND_DISPLAY so also XWayland apps benefit from portal-based color picking.
++ // Outside wayland we'll rather rely on other means than the XDG desktop portal.
++ if (!qEnvironmentVariableIsEmpty("WAYLAND_DISPLAY")
++ || QGuiApplication::platformName().startsWith(QLatin1String("wayland"))) {
++ return new XdgDesktopPortalColorPicker(portalWindowIdentifier(parent), parent);
++ }
++ return nullptr;
++#else
++ Q_UNUSED(parent);
++ return nullptr;
++#endif
++}
++
+ QByteArray QGenericUnixServices::desktopEnvironment() const
+ {
+ static const QByteArray result = detectDesktopEnvironment();
+@@ -352,6 +486,8 @@ bool QGenericUnixServices::openDocument(const QUrl &url)
+ }
+
+ #else
++QGenericUnixServices::QGenericUnixServices() = default;
++
+ QByteArray QGenericUnixServices::desktopEnvironment() const
+ {
+ return QByteArrayLiteral("UNKNOWN");
+@@ -371,6 +507,30 @@ bool QGenericUnixServices::openDocument(const QUrl &url)
+ return false;
+ }
+
++QPlatformServiceColorPicker *QGenericUnixServices::colorPicker(QWindow *parent)
++{
++ Q_UNUSED(parent);
++ return nullptr;
++}
++
+ #endif // QT_NO_MULTIPROCESS
+
++QString QGenericUnixServices::portalWindowIdentifier(QWindow *window)
++{
++ if (QGuiApplication::platformName() == QLatin1String("xcb"))
++ return QStringLiteral("x11:") + QString::number(window->winId(), 16);
++ return QString();
++}
++
++bool QGenericUnixServices::hasCapability(Capability capability) const
++{
++ switch (capability) {
++ case Capability::ColorPicking:
++ return m_hasScreenshotPortalWithColorPicking;
++ }
++ return false;
++}
++
+ QT_END_NAMESPACE
++
++#include "qgenericunixservices.moc"
+diff --git a/qtbase/src/platformsupport/services/genericunix/qgenericunixservices_p.h b/qtbase/src/platformsupport/services/genericunix/qgenericunixservices_p.h
+index 8ac3de6f03..30924e64bd 100644
+--- a/qtbase/src/platformsupport/services/genericunix/qgenericunixservices_p.h
++++ b/qtbase/src/platformsupport/services/genericunix/qgenericunixservices_p.h
+@@ -59,16 +59,21 @@ QT_BEGIN_NAMESPACE
+ class QGenericUnixServices : public QPlatformServices
+ {
+ public:
+- QGenericUnixServices() {}
++ QGenericUnixServices();
+
+ QByteArray desktopEnvironment() const override;
+
++ bool hasCapability(Capability capability) const override;
+ bool openUrl(const QUrl &url) override;
+ bool openDocument(const QUrl &url) override;
++ QPlatformServiceColorPicker *colorPicker(QWindow *parent = nullptr) override;
++
++ virtual QString portalWindowIdentifier(QWindow *window);
+
+ private:
+ QString m_webBrowser;
+ QString m_documentLauncher;
++ bool m_hasScreenshotPortalWithColorPicking = false;
+ };
+
+ QT_END_NAMESPACE
+diff --git a/qtbase/src/platformsupport/themes/genericunix/dbusmenu/qdbusmenuconnection.cpp b/qtbase/src/platformsupport/themes/genericunix/dbusmenu/qdbusmenuconnection.cpp
+index 09470bccc6..cc7c7d4d8a 100644
+--- a/qtbase/src/platformsupport/themes/genericunix/dbusmenu/qdbusmenuconnection.cpp
++++ b/qtbase/src/platformsupport/themes/genericunix/dbusmenu/qdbusmenuconnection.cpp
+@@ -69,6 +69,7 @@ const QString MenuBarPath = QLatin1String("/MenuBar");
+ */
+ QDBusMenuConnection::QDBusMenuConnection(QObject *parent, const QString &serviceName)
+ : QObject(parent)
++ , m_serviceName(serviceName)
+ , m_connection(serviceName.isNull() ? QDBusConnection::sessionBus()
+ : QDBusConnection::connectToBus(QDBusConnection::SessionBus, serviceName))
+ , m_dbusWatcher(new QDBusServiceWatcher(StatusNotifierWatcherService, m_connection, QDBusServiceWatcher::WatchForRegistration, this))
+@@ -83,6 +84,12 @@ QDBusMenuConnection::QDBusMenuConnection(QObject *parent, const QString &service
+ #endif
+ }
+
++QDBusMenuConnection::~QDBusMenuConnection()
++{
++ if (!m_serviceName.isEmpty() && m_connection.isConnected())
++ QDBusConnection::disconnectFromBus(m_serviceName);
++}
++
+ void QDBusMenuConnection::dbusError(const QDBusError &error)
+ {
+ qWarning() << "QDBusTrayIcon encountered a D-Bus error:" << error;
+@@ -105,13 +112,7 @@ void QDBusMenuConnection::unregisterTrayIconMenu(QDBusTrayIcon *item)
+
+ bool QDBusMenuConnection::registerTrayIcon(QDBusTrayIcon *item)
+ {
+- bool success = connection().registerService(item->instanceId());
+- if (!success) {
+- qWarning() << "failed to register service" << item->instanceId();
+- return false;
+- }
+-
+- success = connection().registerObject(StatusNotifierItemPath, item);
++ bool success = connection().registerObject(StatusNotifierItemPath, item);
+ if (!success) {
+ unregisterTrayIcon(item);
+ qWarning() << "failed to register" << item->instanceId() << StatusNotifierItemPath;
+@@ -126,21 +127,18 @@ bool QDBusMenuConnection::registerTrayIcon(QDBusTrayIcon *item)
+
+ bool QDBusMenuConnection::registerTrayIconWithWatcher(QDBusTrayIcon *item)
+ {
++ Q_UNUSED(item);
+ QDBusMessage registerMethod = QDBusMessage::createMethodCall(
+ StatusNotifierWatcherService, StatusNotifierWatcherPath, StatusNotifierWatcherService,
+ QLatin1String("RegisterStatusNotifierItem"));
+- registerMethod.setArguments(QVariantList() << item->instanceId());
++ registerMethod.setArguments(QVariantList() << m_connection.baseService());
+ return m_connection.callWithCallback(registerMethod, this, SIGNAL(trayIconRegistered()), SLOT(dbusError(QDBusError)));
+ }
+
+-bool QDBusMenuConnection::unregisterTrayIcon(QDBusTrayIcon *item)
++void QDBusMenuConnection::unregisterTrayIcon(QDBusTrayIcon *item)
+ {
+ unregisterTrayIconMenu(item);
+ connection().unregisterObject(StatusNotifierItemPath);
+- bool success = connection().unregisterService(item->instanceId());
+- if (!success)
+- qWarning() << "failed to unregister service" << item->instanceId();
+- return success;
+ }
+ #endif // QT_NO_SYSTEMTRAYICON
+
+diff --git a/qtbase/src/platformsupport/themes/genericunix/dbusmenu/qdbusmenuconnection_p.h b/qtbase/src/platformsupport/themes/genericunix/dbusmenu/qdbusmenuconnection_p.h
+index f484795fbb..97bdfabb85 100644
+--- a/qtbase/src/platformsupport/themes/genericunix/dbusmenu/qdbusmenuconnection_p.h
++++ b/qtbase/src/platformsupport/themes/genericunix/dbusmenu/qdbusmenuconnection_p.h
+@@ -70,6 +70,7 @@ class QDBusMenuConnection : public QObject
+
+ public:
+ QDBusMenuConnection(QObject *parent = nullptr, const QString &serviceName = QString());
++ ~QDBusMenuConnection();
+ QDBusConnection connection() const { return m_connection; }
+ QDBusServiceWatcher *dbusWatcher() const { return m_dbusWatcher; }
+ bool isStatusNotifierHostRegistered() const { return m_statusNotifierHostRegistered; }
+@@ -78,7 +79,7 @@ public:
+ void unregisterTrayIconMenu(QDBusTrayIcon *item);
+ bool registerTrayIcon(QDBusTrayIcon *item);
+ bool registerTrayIconWithWatcher(QDBusTrayIcon *item);
+- bool unregisterTrayIcon(QDBusTrayIcon *item);
++ void unregisterTrayIcon(QDBusTrayIcon *item);
+ #endif // QT_NO_SYSTEMTRAYICON
+
+ Q_SIGNALS:
+@@ -90,6 +91,7 @@ private Q_SLOTS:
+ void dbusError(const QDBusError &error);
+
+ private:
++ QString m_serviceName;
+ QDBusConnection m_connection;
+ QDBusServiceWatcher *m_dbusWatcher;
+ bool m_statusNotifierHostRegistered;
+diff --git a/qtbase/src/platformsupport/themes/genericunix/dbustray/qdbustrayicon.cpp b/qtbase/src/platformsupport/themes/genericunix/dbustray/qdbustrayicon.cpp
+index bede70975a..76bfec5e5a 100644
+--- a/qtbase/src/platformsupport/themes/genericunix/dbustray/qdbustrayicon.cpp
++++ b/qtbase/src/platformsupport/themes/genericunix/dbustray/qdbustrayicon.cpp
+@@ -71,8 +71,12 @@ Q_LOGGING_CATEGORY(qLcTray, "qt.qpa.tray")
+ static QString iconTempPath()
+ {
+ QString tempPath = QStandardPaths::writableLocation(QStandardPaths::RuntimeLocation);
+- if (!tempPath.isEmpty())
++ if (!tempPath.isEmpty()) {
++ QString flatpakId = qEnvironmentVariable("FLATPAK_ID");
++ if (!flatpakId.isEmpty() && QFileInfo::exists(QLatin1String("/.flatpak-info")))
++ tempPath += QLatin1String("/app/") + flatpakId;
+ return tempPath;
++ }
+
+ tempPath = QStandardPaths::writableLocation(QStandardPaths::GenericCacheLocation);
+
+diff --git a/qtbase/src/platformsupport/themes/genericunix/qgenericunixthemes.cpp b/qtbase/src/platformsupport/themes/genericunix/qgenericunixthemes.cpp
+index cb1b39db64..6e01af052c 100644
+--- a/qtbase/src/platformsupport/themes/genericunix/qgenericunixthemes.cpp
++++ b/qtbase/src/platformsupport/themes/genericunix/qgenericunixthemes.cpp
+@@ -755,6 +755,9 @@ QVariant QGnomeTheme::themeHint(QPlatformTheme::ThemeHint hint) const
+ return QVariant(QChar(0x2022));
+ case QPlatformTheme::UiEffects:
+ return QVariant(int(HoverEffect));
++ case QPlatformTheme::ButtonPressKeys:
++ return QVariant::fromValue(
++ QList<Qt::Key>({ Qt::Key_Space, Qt::Key_Return, Qt::Key_Enter, Qt::Key_Select }));
+ default:
+ break;
+ }
+diff --git a/qtbase/src/plugins/platforms/eglfs/api/qeglfscursor.cpp b/qtbase/src/plugins/platforms/eglfs/api/qeglfscursor.cpp
+index 98e05195ee..1e92f43dec 100644
+--- a/qtbase/src/plugins/platforms/eglfs/api/qeglfscursor.cpp
++++ b/qtbase/src/plugins/platforms/eglfs/api/qeglfscursor.cpp
+@@ -343,8 +343,7 @@ void QEglFSCursor::paintOnScreen()
+ // screens are siblings of each other. When not enabled, the sibling list
+ // only contains m_screen itself.
+ for (QPlatformScreen *screen : m_screen->virtualSiblings()) {
+- if (screen->geometry().contains(cr.topLeft().toPoint() + m_cursor.hotSpot)
+- && QOpenGLContext::currentContext()->screen() == screen->screen())
++ if (screen->geometry().contains(cr.topLeft().toPoint() + m_cursor.hotSpot))
+ {
+ cr.translate(-screen->geometry().topLeft());
+ const QSize screenSize = screen->geometry().size();
+@@ -468,11 +467,12 @@ void QEglFSCursor::draw(const QRectF &r)
+ {
+ StateSaver stateSaver;
+
+- QEglFSCursorData &gfx = static_cast<QEglFSContext*>(QOpenGLContext::currentContext()->handle())->cursorData;
+- if (!gfx.program) {
+- // one time initialization
++ // one time initialization
++ if (!QOpenGLFunctions::d_ptr)
+ initializeOpenGLFunctions();
+
++ QEglFSCursorData &gfx = static_cast<QEglFSContext*>(QOpenGLContext::currentContext()->handle())->cursorData;
++ if (!gfx.program) {
+ createShaderPrograms();
+
+ if (!gfx.atlasTexture) {
+diff --git a/qtbase/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmseventreader.cpp b/qtbase/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmseventreader.cpp
+index 645a0ae2e9..3e0e406f1a 100644
+--- a/qtbase/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmseventreader.cpp
++++ b/qtbase/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmseventreader.cpp
+@@ -179,7 +179,7 @@ void QEglFSKmsEventReader::create(QEglFSKmsDevice *device)
+
+ m_device = device;
+
+- qCDebug(qLcEglfsKmsDebug, "Initalizing event reader for device %p fd %d",
++ qCDebug(qLcEglfsKmsDebug, "Initializing event reader for device %p fd %d",
+ m_device, m_device->fd());
+
+ m_thread = new QEglFSKmsEventReaderThread(m_device->fd());
+diff --git a/qtbase/src/plugins/platforms/offscreen/qoffscreenintegration.cpp b/qtbase/src/plugins/platforms/offscreen/qoffscreenintegration.cpp
+index 141fb68a23..d4294d425a 100644
+--- a/qtbase/src/plugins/platforms/offscreen/qoffscreenintegration.cpp
++++ b/qtbase/src/plugins/platforms/offscreen/qoffscreenintegration.cpp
+@@ -122,11 +122,13 @@ QOffscreenIntegration::QOffscreenIntegration()
+ #endif
+ m_services.reset(new QPlatformServices);
+
+- QWindowSystemInterface::handleScreenAdded(new QOffscreenScreen);
++ m_screen = new QOffscreenScreen;
++ QWindowSystemInterface::handleScreenAdded(m_screen);
+ }
+
+ QOffscreenIntegration::~QOffscreenIntegration()
+ {
++ QWindowSystemInterface::handleScreenRemoved(m_screen);
+ }
+
+ void QOffscreenIntegration::initialize()
+diff --git a/qtbase/src/plugins/platforms/offscreen/qoffscreenintegration.h b/qtbase/src/plugins/platforms/offscreen/qoffscreenintegration.h
+index 0ea90f6c2f..fe00fde07c 100644
+--- a/qtbase/src/plugins/platforms/offscreen/qoffscreenintegration.h
++++ b/qtbase/src/plugins/platforms/offscreen/qoffscreenintegration.h
+@@ -84,6 +84,7 @@ protected:
+ #endif
+ QScopedPointer<QPlatformInputContext> m_inputContext;
+ QScopedPointer<QPlatformServices> m_services;
++ QPlatformScreen *m_screen;
+ mutable QScopedPointer<QPlatformNativeInterface> m_nativeInterface;
+ };
+
+diff --git a/qtbase/src/plugins/platforms/windows/qwindowsglcontext.cpp b/qtbase/src/plugins/platforms/windows/qwindowsglcontext.cpp
+index 6fa5a8a2b3..1f49f0aefd 100644
+--- a/qtbase/src/plugins/platforms/windows/qwindowsglcontext.cpp
++++ b/qtbase/src/plugins/platforms/windows/qwindowsglcontext.cpp
+@@ -48,6 +48,7 @@
+ #include <qpa/qplatformnativeinterface.h>
+ #include <QtPlatformHeaders/qwglnativecontext.h>
+
++#include <private/qsystemlibrary_p.h>
+ #include <algorithm>
+
+ #include <wingdi.h>
+@@ -162,19 +163,25 @@ QFunctionPointer QWindowsOpengl32DLL::resolve(const char *name)
+
+ bool QWindowsOpengl32DLL::init(bool softwareRendering)
+ {
+- const QByteArray opengl32 = QByteArrayLiteral("opengl32.dll");
+- const QByteArray swopengl = QByteArrayLiteral("opengl32sw.dll");
++ const QByteArray opengl32 = QByteArrayLiteral("opengl32");
++ const QByteArray swopengl = QByteArrayLiteral("opengl32sw");
++ bool useSystemLib = false;
+
+ QByteArray openglDll = qgetenv("QT_OPENGL_DLL");
+- if (openglDll.isEmpty())
++ if (openglDll.isEmpty()) {
+ openglDll = softwareRendering ? swopengl : opengl32;
++ useSystemLib = !softwareRendering;
++ }
+
+ openglDll = openglDll.toLower();
+ m_nonOpengl32 = openglDll != opengl32;
+
+ qCDebug(lcQpaGl) << "Qt: Using WGL and OpenGL from" << openglDll;
+
+- m_lib = ::LoadLibraryA(openglDll.constData());
++ if (useSystemLib)
++ m_lib = QSystemLibrary::load((wchar_t*)(QString::fromLatin1(openglDll).utf16()));
++ else
++ m_lib = LoadLibraryA(openglDll.constData());
+ if (!m_lib) {
+ qErrnoWarning(::GetLastError(), "Failed to load %s", openglDll.constData());
+ return false;
+@@ -184,7 +191,7 @@ bool QWindowsOpengl32DLL::init(bool softwareRendering)
+ // Load opengl32.dll always. GDI functions like ChoosePixelFormat do
+ // GetModuleHandle for opengl32.dll and behave differently (and call back into
+ // opengl32) when the module is present. This is fine for dummy contexts and windows.
+- ::LoadLibraryA("opengl32.dll");
++ QSystemLibrary::load(L"opengl32");
+ }
+
+ wglCreateContext = reinterpret_cast<HGLRC (WINAPI *)(HDC)>(resolve("wglCreateContext"));
+diff --git a/qtbase/src/plugins/platforms/windows/qwindowsopengltester.cpp b/qtbase/src/plugins/platforms/windows/qwindowsopengltester.cpp
+index d7d186e804..9eb4011bf2 100644
+--- a/qtbase/src/plugins/platforms/windows/qwindowsopengltester.cpp
++++ b/qtbase/src/plugins/platforms/windows/qwindowsopengltester.cpp
+@@ -49,6 +49,7 @@
+ #include <QtCore/qstandardpaths.h>
+ #include <QtCore/qlibraryinfo.h>
+ #include <QtCore/qhash.h>
++#include <private/qsystemlibrary_p.h>
+
+ #ifndef QT_NO_OPENGL
+ #include <private/qopengl_p.h>
+@@ -396,7 +397,7 @@ bool QWindowsOpenGLTester::testDesktopGL()
+
+ // Test #1: Load opengl32.dll and try to resolve an OpenGL 2 function.
+ // This will typically fail on systems that do not have a real OpenGL driver.
+- lib = LoadLibraryA("opengl32.dll");
++ lib = QSystemLibrary::load(L"opengl32");
+ if (lib) {
+ CreateContext = reinterpret_cast<CreateContextType>(
+ reinterpret_cast<QFunctionPointer>(::GetProcAddress(lib, "wglCreateContext")));
+diff --git a/qtbase/src/plugins/platforms/xcb/nativepainting/qtessellator.cpp b/qtbase/src/plugins/platforms/xcb/nativepainting/qtessellator.cpp
+index 1afa00cfc9..118af6ce73 100644
+--- a/qtbase/src/plugins/platforms/xcb/nativepainting/qtessellator.cpp
++++ b/qtbase/src/plugins/platforms/xcb/nativepainting/qtessellator.cpp
+@@ -41,6 +41,7 @@
+
+ #include <QRect>
+ #include <QList>
++#include <QMap>
+ #include <QDebug>
+
+ #include <qmath.h>
+diff --git a/qtbase/src/plugins/platforms/xcb/qxcbconnection.cpp b/qtbase/src/plugins/platforms/xcb/qxcbconnection.cpp
+index 9e2a37a6a1..e6e175a118 100644
+--- a/qtbase/src/plugins/platforms/xcb/qxcbconnection.cpp
++++ b/qtbase/src/plugins/platforms/xcb/qxcbconnection.cpp
+@@ -488,12 +488,12 @@ void QXcbConnection::printXcbError(const char *message, xcb_generic_error_t *err
+ uint clamped_error_code = qMin<uint>(error->error_code, (sizeof(xcb_errors) / sizeof(xcb_errors[0])) - 1);
+ uint clamped_major_code = qMin<uint>(error->major_code, (sizeof(xcb_protocol_request_codes) / sizeof(xcb_protocol_request_codes[0])) - 1);
+
+- qCWarning(lcQpaXcb, "%s: %d (%s), sequence: %d, resource id: %d, major code: %d (%s), minor code: %d",
+- message,
+- int(error->error_code), xcb_errors[clamped_error_code],
+- int(error->sequence), int(error->resource_id),
+- int(error->major_code), xcb_protocol_request_codes[clamped_major_code],
+- int(error->minor_code));
++ qCDebug(lcQpaXcb, "%s: %d (%s), sequence: %d, resource id: %d, major code: %d (%s), minor code: %d",
++ message,
++ int(error->error_code), xcb_errors[clamped_error_code],
++ int(error->sequence), int(error->resource_id),
++ int(error->major_code), xcb_protocol_request_codes[clamped_major_code],
++ int(error->minor_code));
+ }
+
+ static Qt::MouseButtons translateMouseButtons(int s)
+@@ -702,6 +702,8 @@ void QXcbConnection::handleXcbEvent(xcb_generic_event_t *event)
+ QXcbVirtualDesktop *virtualDesktop = virtualDesktopForRootWindow(propertyNotify->window);
+ if (virtualDesktop)
+ virtualDesktop->updateWorkArea();
++ } else if (propertyNotify->atom == atom(QXcbAtom::_NET_SUPPORTED)) {
++ m_wmSupport->updateNetWMAtoms();
+ } else {
+ HANDLE_PLATFORM_WINDOW_EVENT(xcb_property_notify_event_t, window, handlePropertyNotifyEvent);
+ }
+@@ -750,7 +752,7 @@ void QXcbConnection::handleXcbEvent(xcb_generic_event_t *event)
+ case XCB_XKB_NEW_KEYBOARD_NOTIFY: {
+ xcb_xkb_new_keyboard_notify_event_t *ev = &xkb_event->new_keyboard_notify;
+ if (ev->changed & XCB_XKB_NKN_DETAIL_KEYCODES)
+- m_keyboard->updateKeymap(ev);
++ m_keyboard->updateKeymap();
+ break;
+ }
+ default:
+diff --git a/qtbase/src/plugins/platforms/xcb/qxcbintegration.cpp b/qtbase/src/plugins/platforms/xcb/qxcbintegration.cpp
+index 76869ced60..02d2eebb56 100644
+--- a/qtbase/src/plugins/platforms/xcb/qxcbintegration.cpp
++++ b/qtbase/src/plugins/platforms/xcb/qxcbintegration.cpp
+@@ -274,8 +274,7 @@ QPlatformWindow *QXcbIntegration::createForeignWindow(QWindow *window, WId nativ
+ #ifndef QT_NO_OPENGL
+ QPlatformOpenGLContext *QXcbIntegration::createPlatformOpenGLContext(QOpenGLContext *context) const
+ {
+- QXcbScreen *screen = static_cast<QXcbScreen *>(context->screen()->handle());
+- QXcbGlIntegration *glIntegration = screen->connection()->glIntegration();
++ QXcbGlIntegration *glIntegration = defaultConnection()->glIntegration();
+ if (!glIntegration) {
+ qWarning("QXcbIntegration: Cannot create platform OpenGL context, neither GLX nor EGL are enabled");
+ return nullptr;
+diff --git a/qtbase/src/plugins/platforms/xcb/qxcbkeyboard.cpp b/qtbase/src/plugins/platforms/xcb/qxcbkeyboard.cpp
+index efecd7e2d1..e8286381a2 100644
+--- a/qtbase/src/plugins/platforms/xcb/qxcbkeyboard.cpp
++++ b/qtbase/src/plugins/platforms/xcb/qxcbkeyboard.cpp
+@@ -365,17 +365,6 @@ void QXcbKeyboard::updateKeymap(xcb_mapping_notify_event_t *event)
+ updateKeymap();
+ }
+
+-void QXcbKeyboard::updateKeymap(xcb_xkb_new_keyboard_notify_event_t *event)
+-{
+- if (!event)
+- return;
+-
+- if (event->deviceID != event->oldDeviceID)
+- m_config = false;
+-
+- updateKeymap();
+-}
+-
+ void QXcbKeyboard::updateKeymap()
+ {
+ KeysymModifierMap keysymMods;
+@@ -383,6 +372,8 @@ void QXcbKeyboard::updateKeymap()
+ keysymMods = keysymsToModifiers();
+ updateModifiers(keysymMods);
+
++ m_config = true;
++
+ if (!m_xkbContext) {
+ m_xkbContext.reset(xkb_context_new(XKB_CONTEXT_NO_DEFAULT_INCLUDES));
+ if (!m_xkbContext) {
+@@ -398,13 +389,8 @@ void QXcbKeyboard::updateKeymap()
+ if (connection()->hasXKB()) {
+ m_xkbKeymap.reset(xkb_x11_keymap_new_from_device(m_xkbContext.get(), xcb_connection(),
+ core_device_id, XKB_KEYMAP_COMPILE_NO_FLAGS));
+- if (m_xkbKeymap) {
+- if (m_config)
+- m_xkbState.reset(xkb_state_new(m_xkbKeymap.get()));
+- else
+- m_xkbState.reset(xkb_x11_state_new_from_device(m_xkbKeymap.get(), xcb_connection(), core_device_id));
+-
+- }
++ if (m_xkbKeymap)
++ m_xkbState.reset(xkb_x11_state_new_from_device(m_xkbKeymap.get(), xcb_connection(), core_device_id));
+ } else {
+ m_xkbKeymap.reset(keymapFromCore(keysymMods));
+ if (m_xkbKeymap)
+@@ -425,8 +411,6 @@ void QXcbKeyboard::updateKeymap()
+ updateXKBMods();
+
+ QXkbCommon::verifyHasLatinLayout(m_xkbKeymap.get());
+-
+- m_config = true;
+ }
+
+ QList<int> QXcbKeyboard::possibleKeys(const QKeyEvent *event) const
+diff --git a/qtbase/src/plugins/platforms/xcb/qxcbkeyboard.h b/qtbase/src/plugins/platforms/xcb/qxcbkeyboard.h
+index b652c85fe3..0ee08aeff2 100644
+--- a/qtbase/src/plugins/platforms/xcb/qxcbkeyboard.h
++++ b/qtbase/src/plugins/platforms/xcb/qxcbkeyboard.h
+@@ -69,7 +69,6 @@ public:
+
+ Qt::KeyboardModifiers translateModifiers(int s) const;
+ void updateKeymap(xcb_mapping_notify_event_t *event);
+- void updateKeymap(xcb_xkb_new_keyboard_notify_event_t *event);
+ void updateKeymap();
+ QList<int> possibleKeys(const QKeyEvent *event) const;
+
+diff --git a/qtbase/src/plugins/platforms/xcb/qxcbwindow.cpp b/qtbase/src/plugins/platforms/xcb/qxcbwindow.cpp
+index ffda7b6a57..863e961f4c 100644
+--- a/qtbase/src/plugins/platforms/xcb/qxcbwindow.cpp
++++ b/qtbase/src/plugins/platforms/xcb/qxcbwindow.cpp
+@@ -564,11 +564,6 @@ void QXcbWindow::setGeometry(const QRect &rect)
+ {
+ QPlatformWindow::setGeometry(rect);
+
+- if (shouldDeferTask(Task::SetGeometry)) {
+- m_deferredGeometry = rect;
+- return;
+- }
+-
+ propagateSizeHints();
+
+ QXcbScreen *currentScreen = xcbScreen();
+@@ -693,9 +688,6 @@ void QXcbWindow::setVisible(bool visible)
+
+ void QXcbWindow::show()
+ {
+- if (shouldDeferTask(Task::Map))
+- return;
+-
+ if (window()->isTopLevel()) {
+
+ // update WM_NORMAL_HINTS
+@@ -706,7 +698,7 @@ void QXcbWindow::show()
+ if (isTransient(window())) {
+ const QWindow *tp = window()->transientParent();
+ if (tp && tp->handle())
+- transientXcbParent = static_cast<const QXcbWindow *>(tp->handle())->winId();
++ transientXcbParent = tp->handle()->winId();
+ // Default to client leader if there is no transient parent, else modal dialogs can
+ // be hidden by their parents.
+ if (!transientXcbParent)
+@@ -746,10 +738,6 @@ void QXcbWindow::show()
+
+ void QXcbWindow::hide()
+ {
+- if (shouldDeferTask(Task::Unmap))
+- return;
+-
+- m_wmStateValid = false;
+ xcb_unmap_window(xcb_connection(), m_window);
+
+ // send synthetic UnmapNotify event according to icccm 4.1.4
+@@ -909,9 +897,6 @@ QXcbWindow::NetWmStates QXcbWindow::netWmStates()
+
+ void QXcbWindow::setWindowFlags(Qt::WindowFlags flags)
+ {
+- if (shouldDeferTask(Task::SetWindowFlags))
+- return;
+-
+ Qt::WindowType type = static_cast<Qt::WindowType>(int(flags & Qt::WindowType_Mask));
+
+ if (type == Qt::ToolTip)
+@@ -941,8 +926,6 @@ void QXcbWindow::setWindowFlags(Qt::WindowFlags flags)
+
+ setTransparentForMouseEvents(flags & Qt::WindowTransparentForInput);
+ updateDoesNotAcceptFocus(flags & Qt::WindowDoesNotAcceptFocus);
+-
+- m_isWmManagedWindow = !(flags & Qt::X11BypassWindowManagerHint);
+ }
+
+ void QXcbWindow::setMotifWmHints(Qt::WindowFlags flags)
+@@ -1142,9 +1125,6 @@ void QXcbWindow::setWindowState(Qt::WindowStates state)
+ if (state == m_windowState)
+ return;
+
+- if (shouldDeferTask(Task::SetWindowState))
+- return;
+-
+ // unset old state
+ if (m_windowState & Qt::WindowMinimized)
+ xcb_map_window(xcb_connection(), m_window);
+@@ -1350,6 +1330,12 @@ void QXcbWindow::setWindowIcon(const QIcon &icon)
+ }
+
+ if (!icon_data.isEmpty()) {
++ // Ignore icon exceeding maximum xcb request length
++ if (icon_data.size() > xcb_get_maximum_request_length(xcb_connection())) {
++ qWarning("Ignoring window icon: Size %llu exceeds maximum xcb request length %u.",
++ icon_data.size(), xcb_get_maximum_request_length(xcb_connection()));
++ return;
++ }
+ xcb_change_property(xcb_connection(),
+ XCB_PROP_MODE_REPLACE,
+ m_window,
+@@ -1639,7 +1625,7 @@ void QXcbWindow::setWmWindowType(QXcbWindowFunctions::WmWindowTypes types, Qt::W
+ break;
+ }
+
+- if ((flags & Qt::FramelessWindowHint) && !(type & QXcbWindowFunctions::KdeOverride)) {
++ if ((flags & Qt::FramelessWindowHint) && !(types & QXcbWindowFunctions::KdeOverride)) {
+ // override netwm type - quick and easy for KDE noborder
+ atoms.append(atom(QXcbAtom::_KDE_NET_WM_WINDOW_TYPE_OVERRIDE));
+ }
+@@ -1894,10 +1880,6 @@ void QXcbWindow::handleUnmapNotifyEvent(const xcb_unmap_notify_event_t *event)
+ if (event->window == m_window) {
+ m_mapped = false;
+ QWindowSystemInterface::handleExposeEvent(window(), QRegion());
+- if (!m_isWmManagedWindow || parent()) {
+- m_wmStateValid = true;
+- handleDeferredTasks();
+- }
+ }
+ }
+
+@@ -2212,98 +2194,30 @@ void QXcbWindow::handleLeaveNotifyEvent(const xcb_leave_notify_event_t *event)
+ handleLeaveNotifyEvent(event->root_x, event->root_y, event->mode, event->detail, event->time);
+ }
+
+-bool QXcbWindow::shouldDeferTask(Task task)
+-{
+- if (m_wmStateValid)
+- return false;
+-
+- m_deferredTasks.append(task);
+- return true;
+-}
+-
+-void QXcbWindow::handleDeferredTasks()
+-{
+- Q_ASSERT(m_wmStateValid == true);
+- if (m_deferredTasks.isEmpty())
+- return;
+-
+- bool map = false;
+- bool unmap = false;
+-
+- QVector<Task> tasks;
+- for (auto taskIt = m_deferredTasks.rbegin(); taskIt != m_deferredTasks.rend(); ++taskIt) {
+- if (!tasks.contains(*taskIt))
+- tasks.prepend(*taskIt);
+- }
+-
+- for (Task task : tasks) {
+- switch (task) {
+- case Task::Map:
+- map = true;
+- unmap = false;
+- break;
+- case Task::Unmap:
+- unmap = true;
+- map = false;
+- break;
+- case Task::SetGeometry:
+- setGeometry(m_deferredGeometry);
+- break;
+- case Task::SetWindowFlags:
+- setWindowFlags(window()->flags());
+- break;
+- case Task::SetWindowState:
+- setWindowState(window()->windowState());
+- break;
+- }
+- }
+- m_deferredTasks.clear();
+-
+- if (map) {
+- Q_ASSERT(unmap == false);
+- show();
+- }
+- if (unmap) {
+- Q_ASSERT(map == false);
+- hide();
+- }
+-}
+-
+ void QXcbWindow::handlePropertyNotifyEvent(const xcb_property_notify_event_t *event)
+ {
+ connection()->setTime(event->time);
+
+- const bool wmStateChanged = event->atom == atom(QXcbAtom::WM_STATE);
+- const bool netWmStateChanged = event->atom == atom(QXcbAtom::_NET_WM_STATE);
+- if (netWmStateChanged || wmStateChanged) {
+- if (wmStateChanged && !m_wmStateValid && m_isWmManagedWindow) {
+- // ICCCM 4.1.4
+- // Clients that want to re-use a client window (e.g. by mapping it again)
+- // after withdrawing it must wait for the withdrawal to be complete before
+- // proceeding. The preferred method for doing this is for clients to wait for
+- // a window manager to update or remove the WM_STATE property.
+- m_wmStateValid = true;
+- handleDeferredTasks();
+- }
+- if (event->state == XCB_PROPERTY_DELETE)
++ const bool propertyDeleted = event->state == XCB_PROPERTY_DELETE;
++
++ if (event->atom == atom(QXcbAtom::_NET_WM_STATE) || event->atom == atom(QXcbAtom::WM_STATE)) {
++ if (propertyDeleted)
+ return;
+
+- if (wmStateChanged) {
++ Qt::WindowStates newState = Qt::WindowNoState;
++
++ if (event->atom == atom(QXcbAtom::WM_STATE)) { // WM_STATE: Quick check for 'Minimize'.
+ auto reply = Q_XCB_REPLY(xcb_get_property, xcb_connection(),
+ 0, m_window, atom(QXcbAtom::WM_STATE),
+ XCB_ATOM_ANY, 0, 1024);
+ if (reply && reply->format == 32 && reply->type == atom(QXcbAtom::WM_STATE)) {
+- auto data = static_cast<const quint32 *>(xcb_get_property_value(reply.get()));
+- if (reply->length != 0) {
+- const bool changedToWithdrawn = data[0] == XCB_ICCCM_WM_STATE_WITHDRAWN;
+- const bool changedToIconic = data[0] == XCB_ICCCM_WM_STATE_ICONIC;
+- m_minimized = changedToIconic || (changedToWithdrawn && m_minimized);
+- }
++ const quint32 *data = (const quint32 *)xcb_get_property_value(reply.get());
++ if (reply->length != 0)
++ m_minimized = (data[0] == XCB_ICCCM_WM_STATE_ICONIC
++ || (data[0] == XCB_ICCCM_WM_STATE_WITHDRAWN && m_minimized));
+ }
+ }
+
+- // _NET_WM_STATE handling
+- Qt::WindowStates newState = Qt::WindowNoState;
+ const NetWmStates states = netWmStates();
+ // _NET_WM_STATE_HIDDEN should be set by the Window Manager to indicate that a window would
+ // not be visible on the screen if its desktop/viewport were active and its coordinates were
+@@ -2325,6 +2239,7 @@ void QXcbWindow::handlePropertyNotifyEvent(const xcb_property_notify_event_t *ev
+ if ((m_windowState & Qt::WindowMinimized) && connection()->mouseGrabber() == this)
+ connection()->setMouseGrabber(nullptr);
+ }
++ return;
+ } else if (event->atom == atom(QXcbAtom::_NET_FRAME_EXTENTS)) {
+ m_dirtyFrameMargins = true;
+ }
+diff --git a/qtbase/src/plugins/platforms/xcb/qxcbwindow.h b/qtbase/src/plugins/platforms/xcb/qxcbwindow.h
+index 55af9279b1..6f5c1f5ed9 100644
+--- a/qtbase/src/plugins/platforms/xcb/qxcbwindow.h
++++ b/qtbase/src/plugins/platforms/xcb/qxcbwindow.h
+@@ -74,14 +74,6 @@ public:
+
+ Q_DECLARE_FLAGS(NetWmStates, NetWmState)
+
+- enum Task {
+- Map,
+- Unmap,
+- SetGeometry,
+- SetWindowFlags,
+- SetWindowState
+- };
+-
+ QXcbWindow(QWindow *window);
+ ~QXcbWindow();
+
+@@ -151,9 +143,6 @@ public:
+
+ QXcbWindow *toWindow() override;
+
+- bool shouldDeferTask(Task task);
+- void handleDeferredTasks();
+-
+ void handleMouseEvent(xcb_timestamp_t time, const QPoint &local, const QPoint &global,
+ Qt::KeyboardModifiers modifiers, QEvent::Type type, Qt::MouseEventSource source);
+
+@@ -292,11 +281,6 @@ protected:
+ int m_swapInterval = -1;
+
+ qreal m_sizeHintsScaleFactor = 1.0;
+-
+- bool m_wmStateValid = true;
+- QVector<Task> m_deferredTasks;
+- bool m_isWmManagedWindow = true;
+- QRect m_deferredGeometry;
+ };
+
+ class QXcbForeignWindow : public QXcbWindow
+diff --git a/qtbase/src/plugins/platformthemes/gtk3/qgtk3menu.cpp b/qtbase/src/plugins/platformthemes/gtk3/qgtk3menu.cpp
+index d9d117faeb..640b49daa0 100644
+--- a/qtbase/src/plugins/platformthemes/gtk3/qgtk3menu.cpp
++++ b/qtbase/src/plugins/platformthemes/gtk3/qgtk3menu.cpp
+@@ -85,6 +85,7 @@ QGtk3MenuItem::QGtk3MenuItem()
+ m_checkable(false),
+ m_checked(false),
+ m_enabled(true),
++ m_exclusive(false),
+ m_underline(false),
+ m_invalid(true),
+ m_menu(nullptr),
+diff --git a/qtbase/src/plugins/platformthemes/xdgdesktopportal/qxdgdesktopportalfiledialog.cpp b/qtbase/src/plugins/platformthemes/xdgdesktopportal/qxdgdesktopportalfiledialog.cpp
+index 0048bbc1e6..396e7f6d1c 100644
+--- a/qtbase/src/plugins/platformthemes/xdgdesktopportal/qxdgdesktopportalfiledialog.cpp
++++ b/qtbase/src/plugins/platformthemes/xdgdesktopportal/qxdgdesktopportalfiledialog.cpp
+@@ -102,15 +102,12 @@ const QDBusArgument &operator >>(const QDBusArgument &arg, QXdgDesktopPortalFile
+ class QXdgDesktopPortalFileDialogPrivate
+ {
+ public:
+- QXdgDesktopPortalFileDialogPrivate(QPlatformFileDialogHelper *nativeFileDialog)
++ QXdgDesktopPortalFileDialogPrivate(QPlatformFileDialogHelper *nativeFileDialog, uint fileChooserPortalVersion)
+ : nativeFileDialog(nativeFileDialog)
++ , fileChooserPortalVersion(fileChooserPortalVersion)
+ { }
+
+- WId winId = 0;
+- bool directoryMode = false;
+- bool modal = false;
+- bool multipleFiles = false;
+- bool saveFile = false;
++ QEventLoop loop;
+ QString acceptLabel;
+ QString directory;
+ QString title;
+@@ -121,19 +118,27 @@ public:
+ QString selectedMimeTypeFilter;
+ QString selectedNameFilter;
+ QStringList selectedFiles;
+- QPlatformFileDialogHelper *nativeFileDialog = nullptr;
++ std::unique_ptr<QPlatformFileDialogHelper> nativeFileDialog;
++ uint fileChooserPortalVersion = 0;
++ bool failedToOpen = false;
++ bool directoryMode = false;
++ bool multipleFiles = false;
++ bool saveFile = false;
+ };
+
+-QXdgDesktopPortalFileDialog::QXdgDesktopPortalFileDialog(QPlatformFileDialogHelper *nativeFileDialog)
++QXdgDesktopPortalFileDialog::QXdgDesktopPortalFileDialog(QPlatformFileDialogHelper *nativeFileDialog, uint fileChooserPortalVersion)
+ : QPlatformFileDialogHelper()
+- , d_ptr(new QXdgDesktopPortalFileDialogPrivate(nativeFileDialog))
++ , d_ptr(new QXdgDesktopPortalFileDialogPrivate(nativeFileDialog, fileChooserPortalVersion))
+ {
+ Q_D(QXdgDesktopPortalFileDialog);
+
+ if (d->nativeFileDialog) {
+- connect(d->nativeFileDialog, SIGNAL(accept()), this, SIGNAL(accept()));
+- connect(d->nativeFileDialog, SIGNAL(reject()), this, SIGNAL(reject()));
++ connect(d->nativeFileDialog.get(), SIGNAL(accept()), this, SIGNAL(accept()));
++ connect(d->nativeFileDialog.get(), SIGNAL(reject()), this, SIGNAL(reject()));
+ }
++
++ d->loop.connect(this, SIGNAL(accept()), SLOT(quit()));
++ d->loop.connect(this, SIGNAL(reject()), SLOT(quit()));
+ }
+
+ QXdgDesktopPortalFileDialog::~QXdgDesktopPortalFileDialog()
+@@ -177,7 +182,7 @@ void QXdgDesktopPortalFileDialog::initializeDialog()
+ setDirectory(options()->initialDirectory());
+ }
+
+-void QXdgDesktopPortalFileDialog::openPortal()
++void QXdgDesktopPortalFileDialog::openPortal(Qt::WindowFlags windowFlags, Qt::WindowModality windowModality, QWindow *parent)
+ {
+ Q_D(QXdgDesktopPortalFileDialog);
+
+@@ -185,13 +190,13 @@ void QXdgDesktopPortalFileDialog::openPortal()
+ QLatin1String("/org/freedesktop/portal/desktop"),
+ QLatin1String("org.freedesktop.portal.FileChooser"),
+ d->saveFile ? QLatin1String("SaveFile") : QLatin1String("OpenFile"));
+- QString parentWindowId = QLatin1String("x11:") + QString::number(d->winId, 16);
++ QString parentWindowId = QLatin1String("x11:") + QString::number(parent ? parent->winId() : 0, 16);
+
+ QVariantMap options;
+ if (!d->acceptLabel.isEmpty())
+ options.insert(QLatin1String("accept_label"), d->acceptLabel);
+
+- options.insert(QLatin1String("modal"), d->modal);
++ options.insert(QLatin1String("modal"), windowModality != Qt::NonModal);
+ options.insert(QLatin1String("multiple"), d->multipleFiles);
+ options.insert(QLatin1String("directory"), d->directoryMode);
+
+@@ -290,10 +295,18 @@ void QXdgDesktopPortalFileDialog::openPortal()
+
+ QDBusPendingCall pendingCall = QDBusConnection::sessionBus().asyncCall(message);
+ QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(pendingCall);
+- connect(watcher, &QDBusPendingCallWatcher::finished, this, [this] (QDBusPendingCallWatcher *watcher) {
++ connect(watcher, &QDBusPendingCallWatcher::finished, this, [=] (QDBusPendingCallWatcher *watcher) {
+ QDBusPendingReply<QDBusObjectPath> reply = *watcher;
+- if (reply.isError()) {
+- Q_EMIT reject();
++ // Any error means the dialog is not shown and we need to fallback
++ d->failedToOpen = reply.isError();
++ if (d->failedToOpen) {
++ if (d->nativeFileDialog) {
++ d->nativeFileDialog->show(windowFlags, windowModality, parent);
++ if (d->loop.isRunning())
++ d->nativeFileDialog->exec();
++ } else {
++ Q_EMIT reject();
++ }
+ } else {
+ QDBusConnection::sessionBus().connect(nullptr,
+ reply.value().path(),
+@@ -302,6 +315,7 @@ void QXdgDesktopPortalFileDialog::openPortal()
+ this,
+ SLOT(gotResponse(uint,QVariantMap)));
+ }
++ watcher->deleteLater();
+ });
+ }
+
+@@ -326,7 +340,7 @@ QUrl QXdgDesktopPortalFileDialog::directory() const
+ {
+ Q_D(const QXdgDesktopPortalFileDialog);
+
+- if (d->nativeFileDialog && (options()->fileMode() == QFileDialogOptions::Directory || options()->fileMode() == QFileDialogOptions::DirectoryOnly))
++ if (d->nativeFileDialog && useNativeFileDialog())
+ return d->nativeFileDialog->directory();
+
+ return d->directory;
+@@ -348,7 +362,7 @@ QList<QUrl> QXdgDesktopPortalFileDialog::selectedFiles() const
+ {
+ Q_D(const QXdgDesktopPortalFileDialog);
+
+- if (d->nativeFileDialog && (options()->fileMode() == QFileDialogOptions::Directory || options()->fileMode() == QFileDialogOptions::DirectoryOnly))
++ if (d->nativeFileDialog && useNativeFileDialog())
+ return d->nativeFileDialog->selectedFiles();
+
+ QList<QUrl> files;
+@@ -403,16 +417,13 @@ void QXdgDesktopPortalFileDialog::exec()
+ {
+ Q_D(QXdgDesktopPortalFileDialog);
+
+- if (d->nativeFileDialog && (options()->fileMode() == QFileDialogOptions::Directory || options()->fileMode() == QFileDialogOptions::DirectoryOnly)) {
++ if (d->nativeFileDialog && useNativeFileDialog()) {
+ d->nativeFileDialog->exec();
+ return;
+ }
+
+ // HACK we have to avoid returning until we emit that the dialog was accepted or rejected
+- QEventLoop loop;
+- loop.connect(this, SIGNAL(accept()), SLOT(quit()));
+- loop.connect(this, SIGNAL(reject()), SLOT(quit()));
+- loop.exec();
++ d->loop.exec();
+ }
+
+ void QXdgDesktopPortalFileDialog::hide()
+@@ -429,13 +440,10 @@ bool QXdgDesktopPortalFileDialog::show(Qt::WindowFlags windowFlags, Qt::WindowMo
+
+ initializeDialog();
+
+- d->modal = windowModality != Qt::NonModal;
+- d->winId = parent ? parent->winId() : 0;
+-
+- if (d->nativeFileDialog && (options()->fileMode() == QFileDialogOptions::Directory || options()->fileMode() == QFileDialogOptions::DirectoryOnly))
++ if (d->nativeFileDialog && useNativeFileDialog(OpenFallback))
+ return d->nativeFileDialog->show(windowFlags, windowModality, parent);
+
+- openPortal();
++ openPortal(windowFlags, windowModality, parent);
+
+ return true;
+ }
+@@ -465,4 +473,21 @@ void QXdgDesktopPortalFileDialog::gotResponse(uint response, const QVariantMap &
+ }
+ }
+
++bool QXdgDesktopPortalFileDialog::useNativeFileDialog(QXdgDesktopPortalFileDialog::FallbackType fallbackType) const
++{
++ Q_D(const QXdgDesktopPortalFileDialog);
++
++ if (d->failedToOpen && fallbackType != OpenFallback)
++ return true;
++
++ if (d->fileChooserPortalVersion < 3) {
++ if (options()->fileMode() == QFileDialogOptions::Directory)
++ return true;
++ else if (options()->fileMode() == QFileDialogOptions::DirectoryOnly)
++ return true;
++ }
++
++ return false;
++}
++
+ QT_END_NAMESPACE
+diff --git a/qtbase/src/plugins/platformthemes/xdgdesktopportal/qxdgdesktopportalfiledialog_p.h b/qtbase/src/plugins/platformthemes/xdgdesktopportal/qxdgdesktopportalfiledialog_p.h
+index 4f4de96ecf..65e22a5cf2 100644
+--- a/qtbase/src/plugins/platformthemes/xdgdesktopportal/qxdgdesktopportalfiledialog_p.h
++++ b/qtbase/src/plugins/platformthemes/xdgdesktopportal/qxdgdesktopportalfiledialog_p.h
+@@ -51,6 +51,11 @@ class QXdgDesktopPortalFileDialog : public QPlatformFileDialogHelper
+ Q_OBJECT
+ Q_DECLARE_PRIVATE(QXdgDesktopPortalFileDialog)
+ public:
++ enum FallbackType {
++ GenericFallback,
++ OpenFallback
++ };
++
+ enum ConditionType : uint {
+ GlobalPattern = 0,
+ MimeType = 1
+@@ -69,7 +74,7 @@ public:
+ };
+ typedef QVector<Filter> FilterList;
+
+- QXdgDesktopPortalFileDialog(QPlatformFileDialogHelper *nativeFileDialog = nullptr);
++ QXdgDesktopPortalFileDialog(QPlatformFileDialogHelper *nativeFileDialog = nullptr, uint fileChooserPortalVersion = 0);
+ ~QXdgDesktopPortalFileDialog();
+
+ bool defaultNameFilterDisables() const override;
+@@ -92,7 +97,8 @@ private Q_SLOTS:
+
+ private:
+ void initializeDialog();
+- void openPortal();
++ void openPortal(Qt::WindowFlags windowFlags, Qt::WindowModality windowModality, QWindow *parent);
++ bool useNativeFileDialog(FallbackType fallbackType = GenericFallback) const;
+
+ QScopedPointer<QXdgDesktopPortalFileDialogPrivate> d_ptr;
+ };
+diff --git a/qtbase/src/plugins/platformthemes/xdgdesktopportal/qxdgdesktopportaltheme.cpp b/qtbase/src/plugins/platformthemes/xdgdesktopportal/qxdgdesktopportaltheme.cpp
+index fb324afbd8..b809503122 100644
+--- a/qtbase/src/plugins/platformthemes/xdgdesktopportal/qxdgdesktopportaltheme.cpp
++++ b/qtbase/src/plugins/platformthemes/xdgdesktopportal/qxdgdesktopportaltheme.cpp
+@@ -111,6 +111,7 @@ QXdgDesktopPortalTheme::QXdgDesktopPortalTheme()
+ if (reply.isValid()) {
+ d->fileChooserPortalVersion = reply.value().toUInt();
+ }
++ watcher->deleteLater();
+ });
+ }
+
+@@ -152,11 +153,12 @@ QPlatformDialogHelper* QXdgDesktopPortalTheme::createPlatformDialogHelper(Dialog
+ {
+ Q_D(const QXdgDesktopPortalTheme);
+
+- if (type == FileDialog) {
++ if (type == FileDialog && d->fileChooserPortalVersion) {
+ // Older versions of FileChooser portal don't support opening directories, therefore we fallback
+ // to native file dialog opened inside the sandbox to open a directory.
+- if (d->fileChooserPortalVersion < 3 && d->baseTheme->usePlatformNativeDialog(type))
+- return new QXdgDesktopPortalFileDialog(static_cast<QPlatformFileDialogHelper*>(d->baseTheme->createPlatformDialogHelper(type)));
++ if (d->baseTheme->usePlatformNativeDialog(type))
++ return new QXdgDesktopPortalFileDialog(static_cast<QPlatformFileDialogHelper*>(d->baseTheme->createPlatformDialogHelper(type)),
++ d->fileChooserPortalVersion);
+
+ return new QXdgDesktopPortalFileDialog;
+ }
+diff --git a/qtbase/src/plugins/printsupport/cups/qcupsprintengine.cpp b/qtbase/src/plugins/printsupport/cups/qcupsprintengine.cpp
+index 43d5e119ad..1f9cbc4565 100644
+--- a/qtbase/src/plugins/printsupport/cups/qcupsprintengine.cpp
++++ b/qtbase/src/plugins/printsupport/cups/qcupsprintengine.cpp
+@@ -89,8 +89,10 @@ void QCupsPrintEngine::setProperty(PrintEnginePropertyKey key, const QVariant &v
+ break;
+ case PPK_Duplex: {
+ QPrint::DuplexMode mode = QPrint::DuplexMode(value.toInt());
+- if (mode != d->duplex && d->m_printDevice.supportedDuplexModes().contains(mode))
++ if (d->m_printDevice.supportedDuplexModes().contains(mode)) {
+ d->duplex = mode;
++ d->duplexRequestedExplicitly = true;
++ }
+ break;
+ }
+ case PPK_PrinterName:
+@@ -277,9 +279,12 @@ void QCupsPrintEnginePrivate::changePrinter(const QString &newPrinter)
+ m_printDevice.swap(printDevice);
+ printerName = m_printDevice.id();
+
+- // Check if new printer supports current settings, otherwise us defaults
+- if (duplex != QPrint::DuplexAuto && !m_printDevice.supportedDuplexModes().contains(duplex))
++ // in case a duplex value was explicitly set, check if new printer supports current value,
++ // otherwise use device default
++ if (!duplexRequestedExplicitly || !m_printDevice.supportedDuplexModes().contains(duplex)) {
+ duplex = m_printDevice.defaultDuplexMode();
++ duplexRequestedExplicitly = false;
++ }
+ QPrint::ColorMode colorMode = grayscale ? QPrint::GrayScale : QPrint::Color;
+ if (!m_printDevice.supportedColorModes().contains(colorMode))
+ grayscale = m_printDevice.defaultColorMode() == QPrint::GrayScale;
+diff --git a/qtbase/src/plugins/printsupport/cups/qcupsprintengine_p.h b/qtbase/src/plugins/printsupport/cups/qcupsprintengine_p.h
+index c021b0c643..8f81fe478d 100644
+--- a/qtbase/src/plugins/printsupport/cups/qcupsprintengine_p.h
++++ b/qtbase/src/plugins/printsupport/cups/qcupsprintengine_p.h
+@@ -100,6 +100,7 @@ private:
+ QStringList cupsOptions;
+ QString cupsTempFile;
+ QPrint::DuplexMode duplex;
++ bool duplexRequestedExplicitly = false;
+ };
+
+ QT_END_NAMESPACE
+diff --git a/qtbase/src/plugins/sqldrivers/ibase/qsql_ibase.cpp b/qtbase/src/plugins/sqldrivers/ibase/qsql_ibase.cpp
+index 67e7154fa6..40876152e5 100644
+--- a/qtbase/src/plugins/sqldrivers/ibase/qsql_ibase.cpp
++++ b/qtbase/src/plugins/sqldrivers/ibase/qsql_ibase.cpp
+@@ -817,7 +817,7 @@ bool QIBaseResultPrivate::writeArray(int column, const QList<QVariant> &list)
+ ba.resize(int(bufLen));
+
+ if (list.size() > arraySize) {
+- error = QLatin1String("Array size missmatch: size of %1 is %2, size of provided list is %3");
++ error = QLatin1String("Array size mismatch: size of %1 is %2, size of provided list is %3");
+ error = error.arg(QLatin1String(sqlname)).arg(arraySize).arg(list.size());
+ q->setLastError(QSqlError(error, QLatin1String(""), QSqlError::StatementError));
+ return false;
+diff --git a/qtbase/src/plugins/sqldrivers/mysql/qsql_mysql.cpp b/qtbase/src/plugins/sqldrivers/mysql/qsql_mysql.cpp
+index 7ca055eea2..6bc9d46755 100644
+--- a/qtbase/src/plugins/sqldrivers/mysql/qsql_mysql.cpp
++++ b/qtbase/src/plugins/sqldrivers/mysql/qsql_mysql.cpp
+@@ -223,7 +223,7 @@ public:
+ struct QMyField
+ {
+ char *outField = nullptr;
+- MYSQL_FIELD *myField = nullptr;
++ const MYSQL_FIELD *myField = nullptr;
+ QMetaType::Type type = QMetaType::UnknownType;
+ my_bool nullIndicator = false;
+ ulong bufLength = 0ul;
+@@ -361,7 +361,7 @@ static bool qIsInteger(int t)
+ void QMYSQLResultPrivate::bindBlobs()
+ {
+ int i;
+- MYSQL_FIELD *fieldInfo;
++ const MYSQL_FIELD *fieldInfo;
+ MYSQL_BIND *bind;
+
+ for(i = 0; i < fields.count(); ++i) {
+@@ -379,7 +379,6 @@ void QMYSQLResultPrivate::bindBlobs()
+ bool QMYSQLResultPrivate::bindInValues()
+ {
+ MYSQL_BIND *bind;
+- char *field;
+ int i = 0;
+
+ if (!meta)
+@@ -392,35 +391,34 @@ bool QMYSQLResultPrivate::bindInValues()
+ inBinds = new MYSQL_BIND[fields.size()];
+ memset(inBinds, 0, fields.size() * sizeof(MYSQL_BIND));
+
+- MYSQL_FIELD *fieldInfo;
++ const MYSQL_FIELD *fieldInfo;
+
+ while((fieldInfo = mysql_fetch_field(meta))) {
++ bind = &inBinds[i];
++
+ QMyField &f = fields[i];
+ f.myField = fieldInfo;
+-
++ bind->buffer_length = f.bufLength = fieldInfo->length + 1;
++ bind->buffer_type = fieldInfo->type;
+ f.type = qDecodeMYSQLType(fieldInfo->type, fieldInfo->flags);
+ if (qIsBlob(fieldInfo->type)) {
+ // the size of a blob-field is available as soon as we call
+ // mysql_stmt_store_result()
+ // after mysql_stmt_exec() in QMYSQLResult::exec()
+- fieldInfo->length = 0;
++ bind->buffer_length = f.bufLength = 0;
+ hasBlobs = true;
+ } else if (qIsInteger(f.type)) {
+- fieldInfo->length = 8;
++ bind->buffer_length = f.bufLength = 8;
+ } else {
+- fieldInfo->type = MYSQL_TYPE_STRING;
++ bind->buffer_type = MYSQL_TYPE_STRING;
+ }
+- bind = &inBinds[i];
+- field = new char[fieldInfo->length + 1];
+- memset(field, 0, fieldInfo->length + 1);
+
+- bind->buffer_type = fieldInfo->type;
+- bind->buffer = field;
+- bind->buffer_length = f.bufLength = fieldInfo->length + 1;
+ bind->is_null = &f.nullIndicator;
+ bind->length = &f.bufLength;
+ bind->is_unsigned = fieldInfo->flags & UNSIGNED_FLAG ? 1 : 0;
+- f.outField=field;
++
++ char *field = new char[bind->buffer_length + 1]{};
++ bind->buffer = f.outField = field;
+
+ ++i;
+ }
+@@ -1369,20 +1367,20 @@ bool QMYSQLDriver::open(const QString& db,
+ }
+
+ #if MYSQL_VERSION_ID >= 50007
+- if (mysql_get_client_version() >= 50503 && mysql_get_server_version(d->mysql) >= 50503) {
+- // force the communication to be utf8mb4 (only utf8mb4 supports 4-byte characters)
+- mysql_set_character_set(d->mysql, "utf8mb4");
++ // force the communication to be utf8mb4 (only utf8mb4 supports 4-byte characters)
++ if (mysql_set_character_set(d->mysql, "utf8mb4")) {
++ // this failed, try forcing it to utf (BMP only)
++ if (mysql_set_character_set(d->mysql, "utf8"))
++ qWarning() << "MySQL: Unable to set the client character set to utf8.";
+ #if QT_CONFIG(textcodec)
+- d->tc = QTextCodec::codecForName("UTF-8");
++ else
++ d->tc = codec(d->mysql);
+ #endif
+- } else
+- {
+- // force the communication to be utf8
+- mysql_set_character_set(d->mysql, "utf8");
++ }
+ #if QT_CONFIG(textcodec)
+- d->tc = codec(d->mysql);
++ else
++ d->tc = QTextCodec::codecForName("UTF-8");
+ #endif
+- }
+ #endif // MYSQL_VERSION_ID >= 50007
+
+ d->preparedQuerysEnabled = checkPreparedQueries(d->mysql);
+diff --git a/qtbase/src/printsupport/dialogs/images/print-24.png b/qtbase/src/printsupport/dialogs/images/printer-24.png
+similarity index 100%
+rename from src/printsupport/dialogs/images/print-24.png
+rename to src/printsupport/dialogs/images/printer-24.png
+diff --git a/qtbase/src/printsupport/dialogs/images/print-32.png b/qtbase/src/printsupport/dialogs/images/printer-32.png
+similarity index 100%
+rename from src/printsupport/dialogs/images/print-32.png
+rename to src/printsupport/dialogs/images/printer-32.png
+diff --git a/qtbase/src/printsupport/dialogs/images/view-page-sided-24.png b/qtbase/src/printsupport/dialogs/images/view-pages-facing-24.png
+similarity index 100%
+rename from src/printsupport/dialogs/images/view-page-sided-24.png
+rename to src/printsupport/dialogs/images/view-pages-facing-24.png
+diff --git a/qtbase/src/printsupport/dialogs/images/view-page-sided-32.png b/qtbase/src/printsupport/dialogs/images/view-pages-facing-32.png
+similarity index 100%
+rename from src/printsupport/dialogs/images/view-page-sided-32.png
+rename to src/printsupport/dialogs/images/view-pages-facing-32.png
+diff --git a/qtbase/src/printsupport/dialogs/images/view-page-multi-24.png b/qtbase/src/printsupport/dialogs/images/view-pages-overview-24.png
+similarity index 100%
+rename from src/printsupport/dialogs/images/view-page-multi-24.png
+rename to src/printsupport/dialogs/images/view-pages-overview-24.png
+diff --git a/qtbase/src/printsupport/dialogs/images/view-page-multi-32.png b/qtbase/src/printsupport/dialogs/images/view-pages-overview-32.png
+similarity index 100%
+rename from src/printsupport/dialogs/images/view-page-multi-32.png
+rename to src/printsupport/dialogs/images/view-pages-overview-32.png
+diff --git a/qtbase/src/printsupport/dialogs/images/view-page-one-24.png b/qtbase/src/printsupport/dialogs/images/view-pages-single-24.png
+similarity index 100%
+rename from src/printsupport/dialogs/images/view-page-one-24.png
+rename to src/printsupport/dialogs/images/view-pages-single-24.png
+diff --git a/qtbase/src/printsupport/dialogs/images/view-page-one-32.png b/qtbase/src/printsupport/dialogs/images/view-pages-single-32.png
+similarity index 100%
+rename from src/printsupport/dialogs/images/view-page-one-32.png
+rename to src/printsupport/dialogs/images/view-pages-single-32.png
+diff --git a/qtbase/src/printsupport/dialogs/images/fit-page-24.png b/qtbase/src/printsupport/dialogs/images/zoom-fit-page-24.png
+similarity index 100%
+rename from src/printsupport/dialogs/images/fit-page-24.png
+rename to src/printsupport/dialogs/images/zoom-fit-page-24.png
+diff --git a/qtbase/src/printsupport/dialogs/images/fit-page-32.png b/qtbase/src/printsupport/dialogs/images/zoom-fit-page-32.png
+similarity index 100%
+rename from src/printsupport/dialogs/images/fit-page-32.png
+rename to src/printsupport/dialogs/images/zoom-fit-page-32.png
+diff --git a/qtbase/src/printsupport/dialogs/images/fit-width-24.png b/qtbase/src/printsupport/dialogs/images/zoom-fit-width-24.png
+similarity index 100%
+rename from src/printsupport/dialogs/images/fit-width-24.png
+rename to src/printsupport/dialogs/images/zoom-fit-width-24.png
+diff --git a/qtbase/src/printsupport/dialogs/images/fit-width-32.png b/qtbase/src/printsupport/dialogs/images/zoom-fit-width-32.png
+similarity index 100%
+rename from src/printsupport/dialogs/images/fit-width-32.png
+rename to src/printsupport/dialogs/images/zoom-fit-width-32.png
+diff --git a/qtbase/src/printsupport/dialogs/qpagesetupdialog_unix.cpp b/qtbase/src/printsupport/dialogs/qpagesetupdialog_unix.cpp
+index 78e5b8d1ef..2a28516719 100644
+--- a/qtbase/src/printsupport/dialogs/qpagesetupdialog_unix.cpp
++++ b/qtbase/src/printsupport/dialogs/qpagesetupdialog_unix.cpp
+@@ -532,6 +532,7 @@ void QPageSetupWidget::updateWidget()
+ void QPageSetupWidget::setupPrinter() const
+ {
+ m_printer->setPageLayout(m_pageLayout);
++ m_printer->setPageOrientation(m_pageLayout.orientation());
+ #if QT_CONFIG(cups)
+ QCUPSSupport::PagesPerSheet pagesPerSheet = qvariant_cast<QCUPSSupport::PagesPerSheet>(m_ui.pagesPerSheetCombo->currentData()
+ );
+diff --git a/qtbase/src/printsupport/dialogs/qprintdialog.qrc b/qtbase/src/printsupport/dialogs/qprintdialog.qrc
+index 5a579baa55..10b8e1d341 100644
+--- a/qtbase/src/printsupport/dialogs/qprintdialog.qrc
++++ b/qtbase/src/printsupport/dialogs/qprintdialog.qrc
+@@ -1,9 +1,9 @@
+ <!DOCTYPE RCC><RCC version="1.0">
+ <qresource prefix="/qt-project.org/dialogs/qprintpreviewdialog">
+-<file>images/fit-page-24.png</file>
+-<file>images/fit-page-32.png</file>
+-<file>images/fit-width-24.png</file>
+-<file>images/fit-width-32.png</file>
++<file>images/zoom-fit-page-24.png</file>
++<file>images/zoom-fit-page-32.png</file>
++<file>images/zoom-fit-width-24.png</file>
++<file>images/zoom-fit-width-32.png</file>
+ <file>images/go-first-24.png</file>
+ <file>images/go-first-32.png</file>
+ <file>images/go-last-24.png</file>
+@@ -18,14 +18,14 @@
+ <file>images/layout-portrait-32.png</file>
+ <file>images/page-setup-24.png</file>
+ <file>images/page-setup-32.png</file>
+-<file>images/print-24.png</file>
+-<file>images/print-32.png</file>
+-<file>images/view-page-multi-24.png</file>
+-<file>images/view-page-multi-32.png</file>
+-<file>images/view-page-one-24.png</file>
+-<file>images/view-page-one-32.png</file>
+-<file>images/view-page-sided-24.png</file>
+-<file>images/view-page-sided-32.png</file>
++<file>images/printer-24.png</file>
++<file>images/printer-32.png</file>
++<file>images/view-pages-overview-24.png</file>
++<file>images/view-pages-overview-32.png</file>
++<file>images/view-pages-single-24.png</file>
++<file>images/view-pages-single-32.png</file>
++<file>images/view-pages-facing-24.png</file>
++<file>images/view-pages-facing-32.png</file>
+ <file>images/zoom-in-24.png</file>
+ <file>images/zoom-in-32.png</file>
+ <file>images/zoom-out-24.png</file>
+diff --git a/qtbase/src/printsupport/dialogs/qprintdialog_unix.cpp b/qtbase/src/printsupport/dialogs/qprintdialog_unix.cpp
+index c5b845f4ec..5a5ba1d0a8 100644
+--- a/qtbase/src/printsupport/dialogs/qprintdialog_unix.cpp
++++ b/qtbase/src/printsupport/dialogs/qprintdialog_unix.cpp
+@@ -702,13 +702,14 @@ void QPrintDialogPrivate::selectPrinter(const QPrinter::OutputFormat outputForma
+ else
+ options.grayscale->setChecked(true);
+
+- // keep duplex value explicitly set by user, if any, and selected printer supports it;
+- // use device default otherwise
++ // duplex priorities to be as follows:
++ // 1) a user-selected duplex value in the dialog has highest prority
++ // 2) duplex value set in the QPrinter
+ QPrint::DuplexMode duplex;
+ if (explicitDuplexMode != QPrint::DuplexAuto && supportedDuplexMode.contains(explicitDuplexMode))
+ duplex = explicitDuplexMode;
+ else
+- duplex = top->d->m_currentPrintDevice.defaultDuplexMode();
++ duplex = static_cast<QPrint::DuplexMode>(p->duplex());
+ switch (duplex) {
+ case QPrint::DuplexNone:
+ options.noDuplex->setChecked(true); break;
+@@ -1242,10 +1243,10 @@ void QUnixPrintWidgetPrivate::_q_printerChanged(int index)
+ QString filename = widget.filename->text();
+ widget.filename->setText(filename);
+ widget.lOutput->setEnabled(true);
+- if (optionsPane)
+- optionsPane->selectPrinter(QPrinter::PdfFormat);
+ printer->setOutputFormat(QPrinter::PdfFormat);
+ m_currentPrintDevice = QPrintDevice();
++ if (optionsPane)
++ optionsPane->selectPrinter(QPrinter::PdfFormat);
+ return;
+ }
+ }
+diff --git a/qtbase/src/printsupport/dialogs/qprintpreviewdialog.cpp b/qtbase/src/printsupport/dialogs/qprintpreviewdialog.cpp
+index 39575d5f57..23b7e89538 100644
+--- a/qtbase/src/printsupport/dialogs/qprintpreviewdialog.cpp
++++ b/qtbase/src/printsupport/dialogs/qprintpreviewdialog.cpp
+@@ -352,7 +352,7 @@ void QPrintPreviewDialogPrivate::init(QPrinter *_printer)
+ static inline void qt_setupActionIcon(QAction *action, QLatin1String name)
+ {
+ QLatin1String imagePrefix(":/qt-project.org/dialogs/qprintpreviewdialog/images/");
+- QIcon icon;
++ QIcon icon = QIcon::fromTheme(name);
+ icon.addFile(imagePrefix + name + QLatin1String("-24.png"), QSize(24, 24));
+ icon.addFile(imagePrefix + name + QLatin1String("-32.png"), QSize(32, 32));
+ action->setIcon(icon);
+@@ -383,8 +383,8 @@ void QPrintPreviewDialogPrivate::setupActions()
+ fitPageAction->setObjectName(QLatin1String("fitPageAction"));
+ fitWidthAction->setCheckable(true);
+ fitPageAction->setCheckable(true);
+- qt_setupActionIcon(fitWidthAction, QLatin1String("fit-width"));
+- qt_setupActionIcon(fitPageAction, QLatin1String("fit-page"));
++ qt_setupActionIcon(fitWidthAction, QLatin1String("zoom-fit-width"));
++ qt_setupActionIcon(fitPageAction, QLatin1String("zoom-fit-page"));
+ QObject::connect(fitGroup, SIGNAL(triggered(QAction*)), q, SLOT(_q_fit(QAction*)));
+
+ // Zoom
+@@ -410,9 +410,9 @@ void QPrintPreviewDialogPrivate::setupActions()
+ singleModeAction = modeGroup->addAction(QCoreApplication::translate("QPrintPreviewDialog", "Show single page"));
+ facingModeAction = modeGroup->addAction(QCoreApplication::translate("QPrintPreviewDialog", "Show facing pages"));
+ overviewModeAction = modeGroup->addAction(QCoreApplication::translate("QPrintPreviewDialog", "Show overview of all pages"));
+- qt_setupActionIcon(singleModeAction, QLatin1String("view-page-one"));
+- qt_setupActionIcon(facingModeAction, QLatin1String("view-page-sided"));
+- qt_setupActionIcon(overviewModeAction, QLatin1String("view-page-multi"));
++ qt_setupActionIcon(singleModeAction, QLatin1String("view-pages-single"));
++ qt_setupActionIcon(facingModeAction, QLatin1String("view-pages-facing"));
++ qt_setupActionIcon(overviewModeAction, QLatin1String("view-pages-overview"));
+ singleModeAction->setObjectName(QLatin1String("singleModeAction"));
+ facingModeAction->setObjectName(QLatin1String("facingModeAction"));
+ overviewModeAction->setObjectName(QLatin1String("overviewModeAction"));
+@@ -426,7 +426,7 @@ void QPrintPreviewDialogPrivate::setupActions()
+ printerGroup = new QActionGroup(q);
+ printAction = printerGroup->addAction(QCoreApplication::translate("QPrintPreviewDialog", "Print"));
+ pageSetupAction = printerGroup->addAction(QCoreApplication::translate("QPrintPreviewDialog", "Page setup"));
+- qt_setupActionIcon(printAction, QLatin1String("print"));
++ qt_setupActionIcon(printAction, QLatin1String("printer"));
+ qt_setupActionIcon(pageSetupAction, QLatin1String("page-setup"));
+ QObject::connect(printAction, SIGNAL(triggered(bool)), q, SLOT(_q_print()));
+ QObject::connect(pageSetupAction, SIGNAL(triggered(bool)), q, SLOT(_q_pageSetup()));
+diff --git a/qtbase/src/sql/kernel/qsqlquery.cpp b/qtbase/src/sql/kernel/qsqlquery.cpp
+index 32c6166c79..60afef10c3 100644
+--- a/qtbase/src/sql/kernel/qsqlquery.cpp
++++ b/qtbase/src/sql/kernel/qsqlquery.cpp
+@@ -1,6 +1,6 @@
+ /****************************************************************************
+ **
+-** Copyright (C) 2016 The Qt Company Ltd.
++** Copyright (C) 2022 The Qt Company Ltd.
+ ** Contact: https://www.qt.io/licensing/
+ **
+ ** This file is part of the QtSql module of the Qt Toolkit.
+@@ -377,6 +377,10 @@ bool QSqlQuery::exec(const QString& query)
+ QElapsedTimer t;
+ t.start();
+ #endif
++ if (!driver()) {
++ qWarning("QSqlQuery::exec: called before driver has been set up");
++ return false;
++ }
+ if (d->ref.loadRelaxed() != 1) {
+ bool fo = isForwardOnly();
+ *this = QSqlQuery(driver()->createResult());
+diff --git a/qtbase/src/testlib/qabstractitemmodeltester.cpp b/qtbase/src/testlib/qabstractitemmodeltester.cpp
+index 8efb9c53d4..ce062f66d7 100644
+--- a/qtbase/src/testlib/qabstractitemmodeltester.cpp
++++ b/qtbase/src/testlib/qabstractitemmodeltester.cpp
+@@ -454,7 +454,7 @@ void QAbstractItemModelTesterPrivate::parent()
+
+ // Common error test #2, make sure that a second level index has a parent
+ // that is the first level index.
+- if (model->rowCount(topIndex) > 0) {
++ if (model->rowCount(topIndex) > 0 && model->columnCount(topIndex) > 0) {
+ QModelIndex childIndex = model->index(0, 0, topIndex);
+ MODELTESTER_VERIFY(childIndex.isValid());
+ MODELTESTER_COMPARE(model->parent(childIndex), topIndex);
+diff --git a/qtbase/src/testlib/qasciikey.cpp b/qtbase/src/testlib/qasciikey.cpp
+index 9a308da2bc..93498b256f 100644
+--- a/qtbase/src/testlib/qasciikey.cpp
++++ b/qtbase/src/testlib/qasciikey.cpp
+@@ -498,6 +498,11 @@ char QTest::keyToAscii(Qt::Key key)
+ case Qt::Key_LaunchE : return 0; // = 0x10b0,
+ case Qt::Key_LaunchF : return 0; // = 0x10b1,
+
++ // Keypad navigation keys
++ case Qt::Key_Select : return 0; // = 0x01010000
++ case Qt::Key_Yes : return 0; // = 0x01010001
++ case Qt::Key_No : return 0; // = 0x01010002
++
+ default: QTEST_ASSERT(false); return 0;
+ }
+ }
+diff --git a/qtbase/src/testlib/qtestresult.cpp b/qtbase/src/testlib/qtestresult.cpp
+index 88028aac6e..2e89930776 100644
+--- a/qtbase/src/testlib/qtestresult.cpp
++++ b/qtbase/src/testlib/qtestresult.cpp
+@@ -251,7 +251,8 @@ bool QTestResult::verify(bool statement, const char *statementStr,
+ {
+ QTEST_ASSERT(statementStr);
+
+- char msg[1024] = {'\0'};
++ char msg[1024];
++ msg[0] = '\0';
+
+ if (QTestLog::verboseLevel() >= 2) {
+ qsnprintf(msg, 1024, "QVERIFY(%s)", statementStr);
+@@ -309,7 +310,8 @@ static bool compareHelper(bool success, const char *failureMsg,
+ bool hasValues = true)
+ {
+ const size_t maxMsgLen = 1024;
+- char msg[maxMsgLen] = {'\0'};
++ char msg[maxMsgLen];
++ msg[0] = '\0';
+
+ QTEST_ASSERT(expected);
+ QTEST_ASSERT(actual);
+diff --git a/qtbase/src/widgets/dialogs/qcolordialog.cpp b/qtbase/src/widgets/dialogs/qcolordialog.cpp
+index 4247731275..cb325be85c 100644
+--- a/qtbase/src/widgets/dialogs/qcolordialog.cpp
++++ b/qtbase/src/widgets/dialogs/qcolordialog.cpp
+@@ -78,7 +78,10 @@
+ #include "qwindow.h"
+
+ #include "private/qdialog_p.h"
++#include "private/qguiapplication_p.h"
+
++#include <qpa/qplatformservices.h>
++#include <qpa/qplatformintegration.h>
+ #include <algorithm>
+
+ QT_BEGIN_NAMESPACE
+@@ -1611,6 +1614,20 @@ void QColorDialogPrivate::_q_newStandard(int r, int c)
+ void QColorDialogPrivate::_q_pickScreenColor()
+ {
+ Q_Q(QColorDialog);
++
++ auto *platformServices = QGuiApplicationPrivate::platformIntegration()->services();
++ if (platformServices->hasCapability(QPlatformServices::Capability::ColorPicking)) {
++ if (auto *colorPicker = platformServices->colorPicker(q->windowHandle())) {
++ q->connect(colorPicker, &QPlatformServiceColorPicker::colorPicked, q,
++ [q, colorPicker](const QColor &color) {
++ colorPicker->deleteLater();
++ q->setCurrentColor(color);
++ });
++ colorPicker->pickColor();
++ return;
++ }
++ }
++
+ if (!colorPickingEventFilter)
+ colorPickingEventFilter = new QColorPickingEventFilter(this, q);
+ q->installEventFilter(colorPickingEventFilter);
+diff --git a/qtbase/src/widgets/itemviews/qabstractitemdelegate.cpp b/qtbase/src/widgets/itemviews/qabstractitemdelegate.cpp
+index e120817edc..8ea36b5427 100644
+--- a/qtbase/src/widgets/itemviews/qabstractitemdelegate.cpp
++++ b/qtbase/src/widgets/itemviews/qabstractitemdelegate.cpp
+@@ -400,12 +400,7 @@ bool QAbstractItemDelegate::helpEvent(QHelpEvent *event,
+ const QString tooltip = index.isValid() ?
+ d->textForRole(Qt::ToolTipRole, index.data(Qt::ToolTipRole), option.locale, precision) :
+ QString();
+- QRect rect;
+- if (index.isValid()) {
+- const QRect r = view->visualRect(index);
+- rect = QRect(view->mapToGlobal(r.topLeft()), r.size());
+- }
+- QToolTip::showText(he->globalPos(), tooltip, view, rect);
++ QToolTip::showText(he->globalPos(), tooltip, view->viewport(), option.rect);
+ event->setAccepted(!tooltip.isEmpty());
+ break;
+ }
+diff --git a/qtbase/src/widgets/itemviews/qlistview.cpp b/qtbase/src/widgets/itemviews/qlistview.cpp
+index 2b34476642..eebfaa030e 100644
+--- a/qtbase/src/widgets/itemviews/qlistview.cpp
++++ b/qtbase/src/widgets/itemviews/qlistview.cpp
+@@ -3386,6 +3386,7 @@ void QIconModeViewBase::updateContentsSize()
+ */
+ void QListView::currentChanged(const QModelIndex ¤t, const QModelIndex &previous)
+ {
++ QAbstractItemView::currentChanged(current, previous);
+ #ifndef QT_NO_ACCESSIBILITY
+ if (QAccessible::isActive()) {
+ if (current.isValid()) {
+@@ -3396,7 +3397,6 @@ void QListView::currentChanged(const QModelIndex ¤t, const QModelIndex &pr
+ }
+ }
+ #endif
+- QAbstractItemView::currentChanged(current, previous);
+ }
+
+ /*!
+diff --git a/qtbase/src/widgets/itemviews/qtableview.cpp b/qtbase/src/widgets/itemviews/qtableview.cpp
+index 934ac581b2..f79bb24249 100644
+--- a/qtbase/src/widgets/itemviews/qtableview.cpp
++++ b/qtbase/src/widgets/itemviews/qtableview.cpp
+@@ -1013,6 +1013,7 @@ void QTableViewPrivate::drawCell(QPainter *painter, const QStyleOptionViewItem &
+ int QTableViewPrivate::widthHintForIndex(const QModelIndex &index, int hint, const QStyleOptionViewItem &option) const
+ {
+ Q_Q(const QTableView);
++ const int oldHint = hint;
+ QWidget *editor = editorForIndex(index).widget.data();
+ if (editor && persistent.contains(editor)) {
+ hint = qMax(hint, editor->sizeHint().width());
+@@ -1021,6 +1022,17 @@ int QTableViewPrivate::widthHintForIndex(const QModelIndex &index, int hint, con
+ hint = qBound(min, hint, max);
+ }
+ hint = qMax(hint, q->itemDelegate(index)->sizeHint(option, index).width());
++
++ if (hasSpans()) {
++ auto span = spans.spanAt(index.column(), index.row());
++ if (span && span->m_left == index.column() && span->m_top == index.row()) {
++ // spans are screwed up when sections are moved
++ const auto left = logicalColumn(span->m_left);
++ for (int i = 1; i <= span->width(); ++i)
++ hint -= q->columnWidth(visualColumn(left + i));
++ }
++ hint = std::max(hint, oldHint);
++ }
+ return hint;
+ }
+
+@@ -1053,6 +1065,11 @@ int QTableViewPrivate::heightHintForIndex(const QModelIndex &index, int hint, QS
+ option.rect.setHeight(height);
+ option.rect.setX(q->columnViewportPosition(index.column()));
+ option.rect.setWidth(q->columnWidth(index.column()));
++ if (hasSpans()) {
++ auto span = spans.spanAt(index.column(), index.row());
++ if (span && span->m_left == index.column() && span->m_top == index.row())
++ option.rect.setWidth(std::max(option.rect.width(), visualSpanRect(*span).width()));
++ }
+ // 1px less space when grid is shown (see drawCell)
+ if (showGrid)
+ option.rect.setWidth(option.rect.width() - 1);
+diff --git a/qtbase/src/widgets/kernel/qaction.h b/qtbase/src/widgets/kernel/qaction.h
+index 258a1ea0a0..737c1e8285 100644
+--- a/qtbase/src/widgets/kernel/qaction.h
++++ b/qtbase/src/widgets/kernel/qaction.h
+@@ -81,7 +81,7 @@ class Q_WIDGETS_EXPORT QAction : public QObject
+ Q_PROPERTY(MenuRole menuRole READ menuRole WRITE setMenuRole NOTIFY changed)
+ Q_PROPERTY(bool iconVisibleInMenu READ isIconVisibleInMenu WRITE setIconVisibleInMenu NOTIFY changed)
+ Q_PROPERTY(bool shortcutVisibleInContextMenu READ isShortcutVisibleInContextMenu WRITE setShortcutVisibleInContextMenu NOTIFY changed)
+- Q_PROPERTY(Priority priority READ priority WRITE setPriority)
++ Q_PROPERTY(Priority priority READ priority WRITE setPriority NOTIFY changed)
+
+ public:
+ // note this is copied into qplatformmenu.h, which must stay in sync
+diff --git a/qtbase/src/widgets/kernel/qwidget.cpp b/qtbase/src/widgets/kernel/qwidget.cpp
+index 9eba1e001e..26f6d27e18 100644
+--- a/qtbase/src/widgets/kernel/qwidget.cpp
++++ b/qtbase/src/widgets/kernel/qwidget.cpp
+@@ -5296,7 +5296,7 @@ void QWidgetPrivate::drawWidget(QPaintDevice *pdev, const QRegion &rgn, const QP
+ QWidgetEffectSourcePrivate *sourced = static_cast<QWidgetEffectSourcePrivate *>
+ (source->d_func());
+ if (!sourced->context) {
+- const QRegion effectRgn(rgn.boundingRect());
++ const QRegion effectRgn((flags & UseEffectRegionBounds) ? rgn.boundingRect() : rgn);
+ QWidgetPaintContext context(pdev, effectRgn, offset, flags, sharedPainter, repaintManager);
+ sourced->context = &context;
+ if (!sharedPainter) {
+@@ -5328,6 +5328,7 @@ void QWidgetPrivate::drawWidget(QPaintDevice *pdev, const QRegion &rgn, const QP
+ }
+ }
+ #endif // QT_CONFIG(graphicseffect)
++ flags = flags & ~UseEffectRegionBounds;
+
+ const bool alsoOnScreen = flags & DrawPaintOnScreen;
+ const bool recursive = flags & DrawRecursive;
+diff --git a/qtbase/src/widgets/kernel/qwidget_p.h b/qtbase/src/widgets/kernel/qwidget_p.h
+index eef6b8fa2c..c432f4b5d5 100644
+--- a/qtbase/src/widgets/kernel/qwidget_p.h
++++ b/qtbase/src/widgets/kernel/qwidget_p.h
+@@ -229,7 +229,8 @@ public:
+ DontSubtractOpaqueChildren = 0x10,
+ DontDrawOpaqueChildren = 0x20,
+ DontDrawNativeChildren = 0x40,
+- DontSetCompositionMode = 0x80
++ DontSetCompositionMode = 0x80,
++ UseEffectRegionBounds = 0x100
+ };
+ Q_DECLARE_FLAGS(DrawWidgetFlags, DrawWidgetFlag)
+ Q_FLAG(DrawWidgetFlags)
+diff --git a/qtbase/src/widgets/kernel/qwidgetrepaintmanager.cpp b/qtbase/src/widgets/kernel/qwidgetrepaintmanager.cpp
+index 02880b34da..0d44e1326d 100644
+--- a/qtbase/src/widgets/kernel/qwidgetrepaintmanager.cpp
++++ b/qtbase/src/widgets/kernel/qwidgetrepaintmanager.cpp
+@@ -1018,7 +1018,8 @@ void QWidgetRepaintManager::paintAndFlush()
+
+ // Paint the rest with composition.
+ if (repaintAllWidgets || !dirtyCopy.isEmpty()) {
+- QWidgetPrivate::DrawWidgetFlags flags = QWidgetPrivate::DrawAsRoot | QWidgetPrivate::DrawRecursive;
++ QWidgetPrivate::DrawWidgetFlags flags = QWidgetPrivate::DrawAsRoot | QWidgetPrivate::DrawRecursive
++ | QWidgetPrivate::UseEffectRegionBounds;
+ tlw->d_func()->drawWidget(store->paintDevice(), dirtyCopy, QPoint(), flags, nullptr, this);
+ }
+
+diff --git a/qtbase/src/widgets/styles/qfusionstyle.cpp b/qtbase/src/widgets/styles/qfusionstyle.cpp
+index f4345d97c4..962912c838 100644
+--- a/qtbase/src/widgets/styles/qfusionstyle.cpp
++++ b/qtbase/src/widgets/styles/qfusionstyle.cpp
+@@ -1772,14 +1772,6 @@ void QFusionStyle::drawControl(ControlElement element, const QStyleOption *optio
+ proxy()->drawControl(CE_PushButtonLabel, &subopt, painter, widget);
+ }
+ break;
+- case CE_PushButtonLabel:
+- if (const QStyleOptionButton *button = qstyleoption_cast<const QStyleOptionButton *>(option)) {
+- QStyleOptionButton b(*button);
+- // no PM_ButtonShiftHorizontal and PM_ButtonShiftVertical for fusion style
+- b.state &= ~(State_On | State_Sunken);
+- QCommonStyle::drawControl(element, &b, painter, widget);
+- }
+- break;
+ case CE_MenuBarEmptyArea:
+ painter->save();
+ {
+diff --git a/qtbase/src/widgets/util/qcompleter.cpp b/qtbase/src/widgets/util/qcompleter.cpp
+index 18b24063d8..ef7207a8a3 100644
+--- a/qtbase/src/widgets/util/qcompleter.cpp
++++ b/qtbase/src/widgets/util/qcompleter.cpp
+@@ -1120,6 +1120,8 @@ void QCompleter::setModel(QAbstractItemModel *model)
+ {
+ Q_D(QCompleter);
+ QAbstractItemModel *oldModel = d->proxy->sourceModel();
++ if (oldModel == model)
++ return;
+ #if QT_CONFIG(filesystemmodel)
+ if (qobject_cast<const QFileSystemModel *>(oldModel))
+ setCompletionRole(Qt::EditRole); // QTBUG-54642, clear FileNameRole set by QFileSystemModel
+diff --git a/qtbase/src/widgets/widgets/qabstractbutton.cpp b/qtbase/src/widgets/widgets/qabstractbutton.cpp
+index a128b23950..dc40bf62fb 100644
+--- a/qtbase/src/widgets/widgets/qabstractbutton.cpp
++++ b/qtbase/src/widgets/widgets/qabstractbutton.cpp
+@@ -56,6 +56,7 @@
+ #ifndef QT_NO_ACCESSIBILITY
+ #include "qaccessible.h"
+ #endif
++#include <qpa/qplatformtheme.h>
+
+ #include <algorithm>
+
+@@ -1076,19 +1077,19 @@ void QAbstractButton::keyPressEvent(QKeyEvent *e)
+ {
+ Q_D(QAbstractButton);
+ bool next = true;
+- switch (e->key()) {
+- case Qt::Key_Enter:
+- case Qt::Key_Return:
+- e->ignore();
+- break;
+- case Qt::Key_Select:
+- case Qt::Key_Space:
+- if (!e->isAutoRepeat()) {
+- setDown(true);
+- repaint();
+- d->emitPressed();
+- }
+- break;
++
++ const auto key = static_cast<Qt::Key>(e->key());
++ const auto buttonPressKeys = QGuiApplicationPrivate::platformTheme()
++ ->themeHint(QPlatformTheme::ButtonPressKeys)
++ .value<QList<Qt::Key>>();
++ if (buttonPressKeys.contains(key) && !e->isAutoRepeat()) {
++ setDown(true);
++ repaint();
++ d->emitPressed();
++ return;
++ }
++
++ switch (key) {
+ case Qt::Key_Up:
+ next = false;
+ Q_FALLTHROUGH();
+@@ -1153,15 +1154,15 @@ void QAbstractButton::keyReleaseEvent(QKeyEvent *e)
+ if (!e->isAutoRepeat())
+ d->repeatTimer.stop();
+
+- switch (e->key()) {
+- case Qt::Key_Select:
+- case Qt::Key_Space:
+- if (!e->isAutoRepeat() && d->down)
+- d->click();
+- break;
+- default:
+- e->ignore();
++ const auto buttonPressKeys = QGuiApplicationPrivate::platformTheme()
++ ->themeHint(QPlatformTheme::ButtonPressKeys)
++ .value<QList<Qt::Key>>();
++ if (buttonPressKeys.contains(static_cast<Qt::Key>(e->key())) && !e->isAutoRepeat() && d->down) {
++ d->click();
++ return;
+ }
++
++ e->ignore();
+ }
+
+ /*!\reimp
+diff --git a/qtbase/src/widgets/widgets/qcombobox.cpp b/qtbase/src/widgets/widgets/qcombobox.cpp
+index 7a496c27e0..0a3d96647b 100644
+--- a/qtbase/src/widgets/widgets/qcombobox.cpp
++++ b/qtbase/src/widgets/widgets/qcombobox.cpp
+@@ -3352,7 +3352,23 @@ void QComboBox::keyPressEvent(QKeyEvent *e)
+
+ Move move = NoMove;
+ int newIndex = currentIndex();
+- switch (e->key()) {
++
++ bool pressLikeButton = !d->lineEdit;
++#ifdef QT_KEYPAD_NAVIGATION
++ pressLikeButton |= QApplicationPrivate::keypadNavigationEnabled() && !hasEditFocus();
++#endif
++ auto key = static_cast<Qt::Key>(e->key());
++ if (pressLikeButton) {
++ const auto buttonPressKeys = QGuiApplicationPrivate::platformTheme()
++ ->themeHint(QPlatformTheme::ButtonPressKeys)
++ .value<QList<Qt::Key>>();
++ if (buttonPressKeys.contains(key)) {
++ showPopup();
++ return;
++ }
++ }
++
++ switch (key) {
+ case Qt::Key_Up:
+ if (e->modifiers() & Qt::ControlModifier)
+ break; // pass to line edit for auto completion
+@@ -3394,26 +3410,11 @@ void QComboBox::keyPressEvent(QKeyEvent *e)
+ return;
+ }
+ break;
+- case Qt::Key_Space:
+- if (!d->lineEdit) {
+- showPopup();
+- return;
+- }
+- break;
+- case Qt::Key_Enter:
+- case Qt::Key_Return:
+ case Qt::Key_Escape:
+ if (!d->lineEdit)
+ e->ignore();
+ break;
+ #ifdef QT_KEYPAD_NAVIGATION
+- case Qt::Key_Select:
+- if (QApplicationPrivate::keypadNavigationEnabled()
+- && (!hasEditFocus() || !d->lineEdit)) {
+- showPopup();
+- return;
+- }
+- break;
+ case Qt::Key_Left:
+ case Qt::Key_Right:
+ if (QApplicationPrivate::keypadNavigationEnabled() && !hasEditFocus())
+diff --git a/qtbase/src/widgets/widgets/qdatetimeedit_p.h b/qtbase/src/widgets/widgets/qdatetimeedit_p.h
+index d36b6f8f9a..e0df5b5158 100644
+--- a/qtbase/src/widgets/widgets/qdatetimeedit_p.h
++++ b/qtbase/src/widgets/widgets/qdatetimeedit_p.h
+@@ -1,6 +1,6 @@
+ /****************************************************************************
+ **
+-** Copyright (C) 2018 The Qt Company Ltd.
++** Copyright (C) 2021 The Qt Company Ltd.
+ ** Contact: https://www.qt.io/licensing/
+ **
+ ** This file is part of the QtWidgets module of the Qt Toolkit.
+diff --git a/qtbase/src/widgets/widgets/qgroupbox.cpp b/qtbase/src/widgets/widgets/qgroupbox.cpp
+index 02a0bed325..3f3eccc370 100644
+--- a/qtbase/src/widgets/widgets/qgroupbox.cpp
++++ b/qtbase/src/widgets/widgets/qgroupbox.cpp
+@@ -54,6 +54,8 @@
+ #include "qaccessible.h"
+ #endif
+ #include <private/qwidget_p.h>
++#include <private/qguiapplication_p.h>
++#include <qpa/qplatformtheme.h>
+
+ #include "qdebug.h"
+
+@@ -360,7 +362,10 @@ bool QGroupBox::event(QEvent *e)
+ return true;
+ case QEvent::KeyPress: {
+ QKeyEvent *k = static_cast<QKeyEvent*>(e);
+- if (!k->isAutoRepeat() && (k->key() == Qt::Key_Select || k->key() == Qt::Key_Space)) {
++ const auto buttonPressKeys = QGuiApplicationPrivate::platformTheme()
++ ->themeHint(QPlatformTheme::ButtonPressKeys)
++ .value<QList<Qt::Key>>();
++ if (!k->isAutoRepeat() && buttonPressKeys.contains(static_cast<Qt::Key>(k->key()))) {
+ d->pressedControl = QStyle::SC_GroupBoxCheckBox;
+ update(style()->subControlRect(QStyle::CC_GroupBox, &box, QStyle::SC_GroupBoxCheckBox, this));
+ return true;
+@@ -369,7 +374,10 @@ bool QGroupBox::event(QEvent *e)
+ }
+ case QEvent::KeyRelease: {
+ QKeyEvent *k = static_cast<QKeyEvent*>(e);
+- if (!k->isAutoRepeat() && (k->key() == Qt::Key_Select || k->key() == Qt::Key_Space)) {
++ const auto buttonPressKeys = QGuiApplicationPrivate::platformTheme()
++ ->themeHint(QPlatformTheme::ButtonPressKeys)
++ .value<QList<Qt::Key>>();
++ if (!k->isAutoRepeat() && buttonPressKeys.contains(static_cast<Qt::Key>(k->key()))) {
+ bool toggle = (d->pressedControl == QStyle::SC_GroupBoxLabel
+ || d->pressedControl == QStyle::SC_GroupBoxCheckBox);
+ d->pressedControl = QStyle::SC_None;
+diff --git a/qtbase/src/widgets/widgets/qlabel.cpp b/qtbase/src/widgets/widgets/qlabel.cpp
+index 30ff80cbb0..cf2605c17c 100644
+--- a/qtbase/src/widgets/widgets/qlabel.cpp
++++ b/qtbase/src/widgets/widgets/qlabel.cpp
+@@ -421,9 +421,6 @@ void QLabel::setPixmap(const QPixmap &pixmap)
+ d->pixmap = new QPixmap(pixmap);
+ }
+
+- if (d->pixmap->depth() == 1 && !d->pixmap->mask())
+- d->pixmap->setMask(*((QBitmap *)d->pixmap));
+-
+ d->updateLabel();
+ }
+
+diff --git a/qtbase/src/widgets/widgets/qtoolbararealayout.cpp b/qtbase/src/widgets/widgets/qtoolbararealayout.cpp
+index 493c094cc1..d5f4b59017 100644
+--- a/qtbase/src/widgets/widgets/qtoolbararealayout.cpp
++++ b/qtbase/src/widgets/widgets/qtoolbararealayout.cpp
+@@ -1367,7 +1367,7 @@ bool QToolBarAreaLayout::restoreState(QDataStream &stream, const QList<QToolBar*
+ item.widgetItem = new QWidgetItemV2(toolBar);
+ toolBar->setOrientation(floating ? ((shown & 2) ? Qt::Vertical : Qt::Horizontal) : dock.o);
+ toolBar->setVisible(shown & 1);
+- toolBar->d_func()->setWindowState(floating, true, rect);
++ toolBar->d_func()->setWindowState(floating, false, rect);
+
+ item.preferredSize = item.size;
+ line.toolBarItems.append(item);
+diff --git a/qtbase/tests/auto/concurrent/qtconcurrentiteratekernel/tst_qtconcurrentiteratekernel.cpp b/qtbase/tests/auto/concurrent/qtconcurrentiteratekernel/tst_qtconcurrentiteratekernel.cpp
+index 212c0a2e13..3c77b1ba0b 100644
+--- a/qtbase/tests/auto/concurrent/qtconcurrentiteratekernel/tst_qtconcurrentiteratekernel.cpp
++++ b/qtbase/tests/auto/concurrent/qtconcurrentiteratekernel/tst_qtconcurrentiteratekernel.cpp
+@@ -126,8 +126,7 @@ public:
+
+ void tst_QtConcurrentIterateKernel::instantiate()
+ {
+- auto future = startThreadEngine(new PrintFor(0, 40)).startAsynchronously();
+- future.waitForFinished();
++ startThreadEngine(new PrintFor(0, 40)).startBlocking();
+ QCOMPARE(iterations.loadRelaxed(), 40);
+ }
+
+@@ -166,10 +165,8 @@ void tst_QtConcurrentIterateKernel::stresstest()
+ const int times = 50;
+ for (int i = 0; i < times; ++i) {
+ counter.storeRelaxed(0);
+- // ThreadEngine will delete f when it finishes
+- auto f = new CountFor(0, iterations);
+- auto future = f->startAsynchronously();
+- future.waitForFinished();
++ CountFor f(0, iterations);
++ f.startBlocking();
+ QCOMPARE(counter.loadRelaxed(), iterations);
+ }
+ }
+@@ -177,11 +174,8 @@ void tst_QtConcurrentIterateKernel::stresstest()
+ void tst_QtConcurrentIterateKernel::noIterations()
+ {
+ const int times = 20000;
+- for (int i = 0; i < times; ++i) {
+- auto future = startThreadEngine(new IterateKernel<TestIterator, void>(0, 0))
+- .startAsynchronously();
+- future.waitForFinished();
+- }
++ for (int i = 0; i < times; ++i)
++ startThreadEngine(new IterateKernel<TestIterator, void>(0, 0)).startBlocking();
+ }
+
+ QMutex threadsMutex;
+@@ -236,10 +230,8 @@ void tst_QtConcurrentIterateKernel::throttling()
+
+ threads.clear();
+
+- // ThreadEngine will delete f when it finishes
+- auto f = new ThrottleFor(0, totalIterations);
+- auto future = f->startAsynchronously();
+- future.waitForFinished();
++ ThrottleFor f(0, totalIterations);
++ f.startBlocking();
+
+ QCOMPARE(iterations.loadRelaxed(), totalIterations);
+
+diff --git a/qtbase/tests/auto/concurrent/qtconcurrentthreadengine/tst_qtconcurrentthreadengine.cpp b/qtbase/tests/auto/concurrent/qtconcurrentthreadengine/tst_qtconcurrentthreadengine.cpp
+index ac7be7acdd..81bc64c8d9 100644
+--- a/qtbase/tests/auto/concurrent/qtconcurrentthreadengine/tst_qtconcurrentthreadengine.cpp
++++ b/qtbase/tests/auto/concurrent/qtconcurrentthreadengine/tst_qtconcurrentthreadengine.cpp
+@@ -65,9 +65,16 @@ public:
+
+ void tst_QtConcurrentThreadEngine::runDirectly()
+ {
+- PrintUser *engine = new PrintUser();
+- QFuture<void> f = engine->startAsynchronously();
+- f.waitForFinished();
++ {
++ PrintUser engine;
++ engine.startSingleThreaded();
++ engine.startBlocking();
++ }
++ {
++ PrintUser *engine = new PrintUser();
++ QFuture<void> f = engine->startAsynchronously();
++ f.waitForFinished();
++ }
+ }
+
+ class StringResultUser : public ThreadEngine<QString>
+@@ -99,10 +106,8 @@ public:
+
+ void tst_QtConcurrentThreadEngine::result()
+ {
+- // ThreadEngine will delete 'engine' when it finishes
+- auto engine = new StringResultUser();
+- auto future = engine->startAsynchronously();
+- QCOMPARE(future.result(), QString("Foo"));
++ StringResultUser engine;
++ QCOMPARE(*engine.startBlocking(), QString("Foo"));
+ }
+
+ class VoidResultUser : public ThreadEngine<void>
+@@ -128,9 +133,17 @@ public:
+
+ void tst_QtConcurrentThreadEngine::runThroughStarter()
+ {
+- ThreadEngineStarter<QString> starter = startThreadEngine(new StringResultUser());
+- QFuture<QString> f = starter.startAsynchronously();
+- QCOMPARE(f.result(), QString("Foo"));
++ {
++ ThreadEngineStarter<QString> starter = startThreadEngine(new StringResultUser());
++ QFuture<QString> f = starter.startAsynchronously();
++ QCOMPARE(f.result(), QString("Foo"));
++ }
++
++ {
++ ThreadEngineStarter<QString> starter = startThreadEngine(new StringResultUser());
++ QString str = starter.startBlocking();
++ QCOMPARE(str, QString("Foo"));
++ }
+ }
+
+ class CancelUser : public ThreadEngine<void>
+@@ -213,6 +226,12 @@ void tst_QtConcurrentThreadEngine::throttle()
+ f.waitForFinished();
+ QCOMPARE(count.loadRelaxed(), 0);
+ }
++
++ for (int i = 0; i < repeats; ++i) {
++ ThrottleAlwaysUser t;
++ t.startBlocking();
++ QCOMPARE(count.loadRelaxed(), 0);
++ }
+ }
+
+ QSet<QThread *> threads;
+@@ -249,17 +268,35 @@ void tst_QtConcurrentThreadEngine::threadCount()
+ {
+ const int repeats = 10;
+ for (int i = 0; i < repeats; ++i) {
++ ThreadCountUser t;
++ t.startBlocking();
++ int count = threads.count();
++ int count_expected = QThreadPool::globalInstance()->maxThreadCount() + 1; // +1 for the main thread.
++ if (count != count_expected)
++ QEXPECT_FAIL("", "QTBUG-23333", Abort);
++ QCOMPARE(count, count_expected);
++
+ (new ThreadCountUser())->startAsynchronously().waitForFinished();
+- const auto count = threads.count();
+- const auto maxThreadCount = QThreadPool::globalInstance()->maxThreadCount();
+- QVERIFY(count <= maxThreadCount);
+- QVERIFY(!threads.contains(QThread::currentThread()));
++ count = threads.count();
++ count_expected = QThreadPool::globalInstance()->maxThreadCount();
++ if (count != count_expected)
++ QEXPECT_FAIL("", "QTBUG-23333", Abort);
++ QCOMPARE(count, count_expected);
+ }
+
+ // Set the finish flag immediately, this should give us one thread only.
+ for (int i = 0; i < repeats; ++i) {
++ ThreadCountUser t(true /*finishImmediately*/);
++ t.startBlocking();
++ int count = threads.count();
++ if (count != 1)
++ QEXPECT_FAIL("", "QTBUG-23333", Abort);
++ QCOMPARE(count, 1);
++
+ (new ThreadCountUser(true /*finishImmediately*/))->startAsynchronously().waitForFinished();
+- const auto count = threads.count();
++ count = threads.count();
++ if (count != 1)
++ QEXPECT_FAIL("", "QTBUG-23333", Abort);
+ QCOMPARE(count, 1);
+ QVERIFY(!threads.contains(QThread::currentThread()));
+ }
+@@ -400,6 +437,7 @@ public:
+
+ void tst_QtConcurrentThreadEngine::exceptions()
+ {
++ // Asynchronous mode:
+ {
+ bool caught = false;
+ try {
+@@ -412,6 +450,32 @@ void tst_QtConcurrentThreadEngine::exceptions()
+ QVERIFY2(caught, "did not get exception");
+ }
+
++ // Blocking mode:
++ // test throwing the exception from a worker thread.
++ {
++ bool caught = false;
++ try {
++ QtConcurrentExceptionThrower e(QThread::currentThread());
++ e.startBlocking();
++ } catch (const QException &) {
++ caught = true;
++ }
++ QVERIFY2(caught, "did not get exception");
++ }
++
++ // test throwing the exception from the main thread (different code path)
++ {
++ bool caught = false;
++ try {
++ QtConcurrentExceptionThrower e(0);
++ e.startBlocking();
++ } catch (const QException &) {
++ caught = true;
++ }
++ QVERIFY2(caught, "did not get exception");
++ }
++
++ // Asynchronous mode:
+ {
+ bool caught = false;
+ try {
+@@ -423,6 +487,31 @@ void tst_QtConcurrentThreadEngine::exceptions()
+ }
+ QVERIFY2(caught, "did not get exception");
+ }
++
++ // Blocking mode:
++ // test throwing the exception from a worker thread.
++ {
++ bool caught = false;
++ try {
++ UnrelatedExceptionThrower e(QThread::currentThread());
++ e.startBlocking();
++ } catch (const QUnhandledException &) {
++ caught = true;
++ }
++ QVERIFY2(caught, "did not get exception");
++ }
++
++ // test throwing the exception from the main thread (different code path)
++ {
++ bool caught = false;
++ try {
++ UnrelatedExceptionThrower e(0);
++ e.startBlocking();
++ } catch (const QUnhandledException &) {
++ caught = true;
++ }
++ QVERIFY2(caught, "did not get exception");
++ }
+ }
+
+ #endif
+diff --git a/qtbase/tests/auto/corelib/io/qbuffer/tst_qbuffer.cpp b/qtbase/tests/auto/corelib/io/qbuffer/tst_qbuffer.cpp
+index 4968742110..f4c3fb711d 100644
+--- a/qtbase/tests/auto/corelib/io/qbuffer/tst_qbuffer.cpp
++++ b/qtbase/tests/auto/corelib/io/qbuffer/tst_qbuffer.cpp
+@@ -42,6 +42,7 @@ private slots:
+ void writeBlock_data();
+ void writeBlock();
+ void seek();
++ void invalidSeeks();
+ void seekTest_data();
+ void seekTest();
+ void read_rawdata();
+@@ -286,6 +287,29 @@ void tst_QBuffer::seek()
+ QCOMPARE(buffer.size(), pos);
+ }
+
++void tst_QBuffer::invalidSeeks()
++{
++ if constexpr (sizeof(qsizetype) == sizeof(qint64)) {
++ // sizeof(qsizetype) == sizeof(qint64), so +1 would overflow
++ QSKIP("This is a 32-bit-only test.");
++ } else {
++ QBuffer buffer;
++ buffer.open(QIODevice::WriteOnly);
++ QCOMPARE(buffer.buffer().size(), qsizetype(0));
++ QCOMPARE(buffer.pos(), qint64(0));
++ constexpr qint64 MaxQByteArrayCapacity = (std::numeric_limits<qsizetype>::max)();
++ // this should fail fast, not after trying to allocate nearly 2 GiB of data,
++ // potentially crashing in the process:
++ QVERIFY(!buffer.seek(2 * MaxQByteArrayCapacity - 1));
++ QCOMPARE(buffer.buffer().size(), qsizetype(0));
++ QCOMPARE(buffer.pos(), qint64(0));
++ // ditto:
++ QVERIFY(!buffer.seek(MaxQByteArrayCapacity + 1));
++ QCOMPARE(buffer.buffer().size(), qsizetype(0));
++ QCOMPARE(buffer.pos(), qint64(0));
++ }
++}
++
+ void tst_QBuffer::seekTest_data()
+ {
+ writeBlock_data();
+diff --git a/qtbase/tests/auto/corelib/io/qiodevice/tst_qiodevice.cpp b/qtbase/tests/auto/corelib/io/qiodevice/tst_qiodevice.cpp
+index da5327594c..4a04e0f7c6 100644
+--- a/qtbase/tests/auto/corelib/io/qiodevice/tst_qiodevice.cpp
++++ b/qtbase/tests/auto/corelib/io/qiodevice/tst_qiodevice.cpp
+@@ -561,7 +561,8 @@ protected:
+ qint64 readData(char *data, qint64 maxSize) override
+ {
+ maxSize = qMin(maxSize, qint64(buf->size() - offset));
+- memcpy(data, buf->constData() + offset, maxSize);
++ if (maxSize > 0)
++ memcpy(data, buf->constData() + offset, maxSize);
+ offset += maxSize;
+ return maxSize;
+ }
+@@ -604,13 +605,15 @@ protected:
+ qint64 readData(char *data, qint64 maxSize) override
+ {
+ maxSize = qMin(maxSize, qint64(buf.size() - pos()));
+- memcpy(data, buf.constData() + pos(), maxSize);
++ if (maxSize > 0)
++ memcpy(data, buf.constData() + pos(), maxSize);
+ return maxSize;
+ }
+ qint64 writeData(const char *data, qint64 maxSize) override
+ {
+ maxSize = qMin(maxSize, qint64(buf.size() - pos()));
+- memcpy(buf.data() + pos(), data, maxSize);
++ if (maxSize > 0)
++ memcpy(buf.data() + pos(), data, maxSize);
+ return maxSize;
+ }
+
+diff --git a/qtbase/tests/auto/corelib/io/qprocess/tst_qprocess.cpp b/qtbase/tests/auto/corelib/io/qprocess/tst_qprocess.cpp
+index db60bead64..f345a44414 100644
+--- a/qtbase/tests/auto/corelib/io/qprocess/tst_qprocess.cpp
++++ b/qtbase/tests/auto/corelib/io/qprocess/tst_qprocess.cpp
+@@ -1,7 +1,8 @@
+ /****************************************************************************
+ **
+ ** Copyright (C) 2021 The Qt Company Ltd.
+-** Copyright (C) 2020 Intel Corporation.
++** Copyright (C) 2020 The Qt Company Ltd.
++** Copyright (C) 2022 Intel Corporation.
+ ** Contact: https://www.qt.io/licensing/
+ **
+ ** This file is part of the test suite of the Qt Toolkit.
+@@ -150,6 +151,8 @@ private slots:
+ void startStopStartStopBuffers();
+ void processEventsInAReadyReadSlot_data();
+ void processEventsInAReadyReadSlot();
++ void startFromCurrentWorkingDir_data();
++ void startFromCurrentWorkingDir();
+
+ // keep these at the end, since they use lots of processes and sometimes
+ // caused obscure failures to occur in tests that followed them (esp. on the Mac)
+@@ -2731,5 +2734,94 @@ void tst_QProcess::finishProcessBeforeReadingDone_deprecated()
+
+ #endif
+
++enum class ChdirMode {
++ None = 0,
++ InParent,
++ InChild
++};
++Q_DECLARE_METATYPE(ChdirMode)
++
++void tst_QProcess::startFromCurrentWorkingDir_data()
++{
++ qRegisterMetaType<ChdirMode>();
++ QTest::addColumn<QString>("programPrefix");
++ QTest::addColumn<ChdirMode>("chdirMode");
++ QTest::addColumn<bool>("success");
++
++ constexpr bool IsWindows = true
++#ifdef Q_OS_UNIX
++ && false
++#endif
++ ;
++
++ // baseline: trying to execute the directory, this can't possibly succeed!
++ QTest::newRow("plain-same-cwd") << QString() << ChdirMode::None << false;
++
++ // cross-platform behavior: neither OS searches the setWorkingDirectory()
++ // dir without "./"
++ QTest::newRow("plain-child-chdir") << QString() << ChdirMode::InChild << false;
++
++ // cross-platform behavior: both OSes search the parent's CWD with "./"
++ QTest::newRow("prefixed-parent-chdir") << "./" << ChdirMode::InParent << true;
++
++ // opposite behaviors: Windows searches the parent's CWD and Unix searches
++ // the child's with "./"
++ QTest::newRow("prefixed-child-chdir") << "./" << ChdirMode::InChild << !IsWindows;
++
++ // Windows searches the parent's CWD without "./"
++ QTest::newRow("plain-parent-chdir") << QString() << ChdirMode::InParent << IsWindows;
++}
++
++void tst_QProcess::startFromCurrentWorkingDir()
++{
++ QFETCH(QString, programPrefix);
++ QFETCH(ChdirMode, chdirMode);
++ QFETCH(bool, success);
++
++ QProcess process;
++ qRegisterMetaType<QProcess::ProcessError>();
++ QSignalSpy errorSpy(&process, &QProcess::errorOccurred);
++ QVERIFY(errorSpy.isValid());
++
++ // both the dir name and the executable name
++ const QString target = QStringLiteral("testProcessNormal");
++ process.setProgram(programPrefix + target);
++
++#ifdef Q_OS_UNIX
++ // Reset PATH, to be sure it doesn't contain . or the empty path.
++ // We can't do this on Windows because DLLs are searched in PATH
++ // and Windows always searches "." anyway.
++ auto restoreEnv = qScopeGuard([old = qgetenv("PATH")] {
++ qputenv("PATH", old);
++ });
++ qputenv("PATH", "/");
++#endif
++
++ switch (chdirMode) {
++ case ChdirMode::InParent: {
++ auto restoreCwd = qScopeGuard([old = QDir::currentPath()] {
++ QDir::setCurrent(old);
++ });
++ QVERIFY(QDir::setCurrent(target));
++ process.start();
++ break;
++ }
++ case ChdirMode::InChild:
++ process.setWorkingDirectory(target);
++ Q_FALLTHROUGH();
++ case ChdirMode::None:
++ process.start();
++ break;
++ }
++
++ QCOMPARE(process.waitForStarted(), success);
++ QCOMPARE(errorSpy.count(), int(!success));
++ if (success) {
++ QVERIFY(process.waitForFinished());
++ } else {
++ QCOMPARE(process.error(), QProcess::FailedToStart);
++ }
++}
++
+ QTEST_MAIN(tst_QProcess)
+ #include "tst_qprocess.moc"
+diff --git a/qtbase/tests/auto/corelib/itemmodels/qconcatenatetablesproxymodel/tst_qconcatenatetablesproxymodel.cpp b/qtbase/tests/auto/corelib/itemmodels/qconcatenatetablesproxymodel/tst_qconcatenatetablesproxymodel.cpp
+index e1ea7a4552..90972caa57 100644
+--- a/qtbase/tests/auto/corelib/itemmodels/qconcatenatetablesproxymodel/tst_qconcatenatetablesproxymodel.cpp
++++ b/qtbase/tests/auto/corelib/itemmodels/qconcatenatetablesproxymodel/tst_qconcatenatetablesproxymodel.cpp
+@@ -117,6 +117,7 @@ private Q_SLOTS:
+ void shouldPropagateDropAfterLastRow_data();
+ void shouldPropagateDropAfterLastRow();
+ void qtbug91788();
++ void qtbug91878();
+
+ private:
+ QStandardItemModel mod;
+@@ -843,6 +844,22 @@ void tst_QConcatenateTablesProxyModel::qtbug91788()
+ QCOMPARE(proxyConcat.columnCount(), 0);
+ }
+
++void tst_QConcatenateTablesProxyModel::qtbug91878()
++{
++ QStandardItemModel m;
++ m.setRowCount(4);
++ m.setColumnCount(4);
++
++ QConcatenateTablesProxyModel pm;
++ QSortFilterProxyModel proxyFilter;
++ proxyFilter.setSourceModel(&pm);
++ proxyFilter.setFilterFixedString("something");
++ pm.addSourceModel(&m); // This should not assert
++
++ QCOMPARE(pm.columnCount(), 4);
++ QCOMPARE(pm.rowCount(), 4);
++}
++
+ QTEST_GUILESS_MAIN(tst_QConcatenateTablesProxyModel)
+
+ #include "tst_qconcatenatetablesproxymodel.moc"
+diff --git a/qtbase/tests/auto/corelib/kernel/qobject/tst_qobject.cpp b/qtbase/tests/auto/corelib/kernel/qobject/tst_qobject.cpp
+index 9bd66c0835..ed4a0bae5d 100644
+--- a/qtbase/tests/auto/corelib/kernel/qobject/tst_qobject.cpp
++++ b/qtbase/tests/auto/corelib/kernel/qobject/tst_qobject.cpp
+@@ -158,6 +158,7 @@ private slots:
+ void nullReceiver();
+ void functorReferencesConnection();
+ void disconnectDisconnects();
++ void declarativeData();
+ };
+
+ struct QObjectCreatedOnShutdown
+@@ -7679,5 +7680,81 @@ void tst_QObject::disconnectDisconnects()
+ Q_STATIC_ASSERT(QtPrivate::HasQ_OBJECT_Macro<tst_QObject>::Value);
+ Q_STATIC_ASSERT(!QtPrivate::HasQ_OBJECT_Macro<SiblingDeleter>::Value);
+
++#ifdef QT_BUILD_INTERNAL
++/*
++ Since QObjectPrivate stores the declarativeData pointer in a union with the pointer
++ to the currently destroyed child, calls to the QtDeclarative handlers need to be
++ correctly guarded. QTBUG-105286
++*/
++namespace QtDeclarative {
++static QAbstractDeclarativeData *theData;
++
++static void destroyed(QAbstractDeclarativeData *data, QObject *)
++{
++ QCOMPARE(data, theData);
++}
++static void signalEmitted(QAbstractDeclarativeData *data, QObject *, int, void **)
++{
++ QCOMPARE(data, theData);
++}
++// we can't use QCOMPARE in the next two functions, as they don't return void
++static int receivers(QAbstractDeclarativeData *data, const QObject *, int)
++{
++ QTest::qCompare(data, theData, "data", "theData", __FILE__, __LINE__);
++ return 0;
++}
++static bool isSignalConnected(QAbstractDeclarativeData *data, const QObject *, int)
++{
++ QTest::qCompare(data, theData, "data", "theData", __FILE__, __LINE__);
++ return true;
++}
++
++class Object : public QObject
++{
++ Q_OBJECT
++public:
++ using QObject::QObject;
++ ~Object()
++ {
++ if (Object *p = static_cast<Object *>(parent()))
++ p->emitSignal();
++ }
++
++ void emitSignal()
++ {
++ emit theSignal();
++ }
++
++signals:
++ void theSignal();
++};
++
++}
++#endif
++
++void tst_QObject::declarativeData()
++{
++#ifdef QT_BUILD_INTERNAL
++ QScopedValueRollback destroyed(QAbstractDeclarativeData::destroyed,
++ QtDeclarative::destroyed);
++ QScopedValueRollback signalEmitted(QAbstractDeclarativeData::signalEmitted,
++ QtDeclarative::signalEmitted);
++ QScopedValueRollback receivers(QAbstractDeclarativeData::receivers,
++ QtDeclarative::receivers);
++ QScopedValueRollback isSignalConnected(QAbstractDeclarativeData::isSignalConnected,
++ QtDeclarative::isSignalConnected);
++
++ QtDeclarative::Object p;
++ QObjectPrivate *priv = QObjectPrivate::get(&p);
++ priv->declarativeData = QtDeclarative::theData = new QAbstractDeclarativeData;
++
++ connect(&p, &QtDeclarative::Object::theSignal, &p, []{
++ });
++
++ QtDeclarative::Object *child = new QtDeclarative::Object;
++ child->setParent(&p);
++#endif
++}
++
+ QTEST_MAIN(tst_QObject)
+ #include "tst_qobject.moc"
+diff --git a/qtbase/tests/auto/corelib/mimetypes/qmimedatabase/tst_qmimedatabase.cpp b/qtbase/tests/auto/corelib/mimetypes/qmimedatabase/tst_qmimedatabase.cpp
+index 0ea422ecbc..1a3256534b 100644
+--- a/qtbase/tests/auto/corelib/mimetypes/qmimedatabase/tst_qmimedatabase.cpp
++++ b/qtbase/tests/auto/corelib/mimetypes/qmimedatabase/tst_qmimedatabase.cpp
+@@ -70,15 +70,15 @@ static inline QString testSuiteWarning()
+
+ QString result;
+ QTextStream str(&result);
+- str << "\nCannot find the shared-mime-info test suite\nstarting from: "
++ str << "\nCannot find the shared-mime-info test suite\nin the parent of: "
+ << QDir::toNativeSeparators(QDir::currentPath()) << "\n"
+ "cd " << QDir::toNativeSeparators(QStringLiteral("tests/auto/corelib/mimetypes/qmimedatabase")) << "\n"
+- "wget http://cgit.freedesktop.org/xdg/shared-mime-info/snapshot/Release-1-10.zip\n"
+- "unzip Release-1-10.zip\n";
++ "wget https://gitlab.freedesktop.org/xdg/shared-mime-info/-/archive/2.1/shared-mime-info-2.1.zip\n"
++ "unzip shared-mime-info-2.1.zip\n";
+ #ifdef Q_OS_WIN
+- str << "mkdir testfiles\nxcopy /s Release-1-10 s-m-i\n";
++ str << "mkdir testfiles\nxcopy /s shared-mime-info-2.1 s-m-i\n";
+ #else
+- str << "ln -s Release-1-10 s-m-i\n";
++ str << "ln -s shared-mime-info-2.1 s-m-i\n";
+ #endif
+ return result;
+ }
+@@ -154,7 +154,7 @@ void tst_QMimeDatabase::initTestCase()
+ QVERIFY2(copyResourceFile(xmlFileName, xmlTargetFileName, &errorMessage), qPrintable(errorMessage));
+ #endif
+
+- m_testSuite = QFINDTESTDATA("s-m-i/tests");
++ m_testSuite = QFINDTESTDATA("s-m-i/tests/mime-detection");
+ if (m_testSuite.isEmpty())
+ qWarning("%s", qPrintable(testSuiteWarning()));
+
+@@ -611,7 +611,7 @@ void tst_QMimeDatabase::allMimeTypes()
+ QVERIFY(!lst.isEmpty());
+
+ // Hardcoding this is the only way to check both providers find the same number of mimetypes.
+- QCOMPARE(lst.count(), 779);
++ QCOMPARE(lst.count(), 811);
+
+ foreach (const QMimeType &mime, lst) {
+ const QString name = mime.name();
+@@ -631,10 +631,9 @@ void tst_QMimeDatabase::suffixes_data()
+
+ QTest::newRow("mimetype with a single pattern") << "application/pdf" << "*.pdf" << "pdf";
+ QTest::newRow("mimetype with multiple patterns") << "application/x-kpresenter" << "*.kpr;*.kpt" << "kpr";
+- QTest::newRow("jpeg") << "image/jpeg" << "*.jpe;*.jpg;*.jpeg" << "jpeg";
+- //if (KMimeType::sharedMimeInfoVersion() > KDE_MAKE_VERSION(0, 60, 0)) {
+- QTest::newRow("mimetype with many patterns") << "application/vnd.wordperfect" << "*.wp;*.wp4;*.wp5;*.wp6;*.wpd;*.wpp" << "wp";
+- //}
++ // The preferred suffix for image/jpeg is *.jpg, as per https://bugs.kde.org/show_bug.cgi?id=176737
++ QTest::newRow("jpeg") << "image/jpeg" << "*.jpe;*.jpg;*.jpeg" << "jpg";
++ QTest::newRow("mimetype with many patterns") << "application/vnd.wordperfect" << "*.wp;*.wp4;*.wp5;*.wp6;*.wpd;*.wpp" << "wp";
+ QTest::newRow("oasis text mimetype") << "application/vnd.oasis.opendocument.text" << "*.odt" << "odt";
+ QTest::newRow("oasis presentation mimetype") << "application/vnd.oasis.opendocument.presentation" << "*.odp" << "odp";
+ QTest::newRow("mimetype with multiple patterns") << "text/plain" << "*.asc;*.txt;*,v" << "txt";
+diff --git a/qtbase/tests/auto/corelib/serialization/json/tst_qtjson.cpp b/qtbase/tests/auto/corelib/serialization/json/tst_qtjson.cpp
+index 3e58dd03cc..c8f82ef5d5 100644
+--- a/qtbase/tests/auto/corelib/serialization/json/tst_qtjson.cpp
++++ b/qtbase/tests/auto/corelib/serialization/json/tst_qtjson.cpp
+@@ -176,6 +176,8 @@ private Q_SLOTS:
+ void fromToVariantConversions_data();
+ void fromToVariantConversions();
+
++ void noLeakOnNameClash();
++
+ private:
+ QString testDataDir;
+ };
+@@ -3685,5 +3687,23 @@ void tst_QtJson::fromToVariantConversions()
+ }
+ }
+
++void tst_QtJson::noLeakOnNameClash()
++{
++ QJsonDocument doc = QJsonDocument::fromJson("{\"\":{\"\":0},\"\":0}");
++ QVERIFY(!doc.isNull());
++ const QJsonObject obj = doc.object();
++
++ // Removed the duplicate key.
++ QCOMPARE(obj.length(), 1);
++
++ // Retained the last of the duplicates.
++ const QJsonValue val = obj.begin().value();
++ QVERIFY(val.isDouble());
++ QCOMPARE(val.toDouble(), 0.0);
++
++ // It should not leak.
++ // In particular it should not forget to deref the container for the inner object.
++}
++
+ QTEST_MAIN(tst_QtJson)
+ #include "tst_qtjson.moc"
+diff --git a/qtbase/tests/auto/corelib/time/qtimezone/tst_qtimezone.cpp b/qtbase/tests/auto/corelib/time/qtimezone/tst_qtimezone.cpp
+index a59b58d57f..241c3e84ac 100644
+--- a/qtbase/tests/auto/corelib/time/qtimezone/tst_qtimezone.cpp
++++ b/qtbase/tests/auto/corelib/time/qtimezone/tst_qtimezone.cpp
+@@ -63,6 +63,7 @@ private slots:
+ void isValidId_data();
+ void isValidId();
+ void malformed();
++ void serialize();
+ // Backend tests
+ void utcTest();
+ void icuTest();
+@@ -947,6 +948,33 @@ void tst_QTimeZone::malformed()
+ barf.offsetFromUtc(now);
+ }
+
++void tst_QTimeZone::serialize()
++{
++ int parts = 0;
++#ifndef QT_NO_DEBUG_STREAM
++ qDebug() << QTimeZone(); // to verify no crash
++ parts++;
++#endif
++#ifndef QT_NO_DATASTREAM
++ QByteArray blob;
++ {
++ QDataStream stream(&blob, QIODevice::WriteOnly);
++ stream << QTimeZone("Europe/Oslo") << QTimeZone(420) << QTimeZone() << qint64(-1);
++ }
++ QDataStream stream(&blob, QIODevice::ReadOnly);
++ QTimeZone invalid, offset, oslo;
++ qint64 minusone;
++ stream >> oslo >> offset >> invalid >> minusone;
++ QCOMPARE(oslo, QTimeZone("Europe/Oslo"));
++ QCOMPARE(offset, QTimeZone(420));
++ QVERIFY(!invalid.isValid());
++ QCOMPARE(minusone, qint64(-1));
++ parts++;
++#endif
++ if (!parts)
++ QSKIP("No serialization enabled");
++}
++
+ void tst_QTimeZone::utcTest()
+ {
+ #ifdef QT_BUILD_INTERNAL
+diff --git a/qtbase/tests/auto/dbus/qdbusinterface/tst_qdbusinterface.cpp b/qtbase/tests/auto/dbus/qdbusinterface/tst_qdbusinterface.cpp
+index 05480c6dd2..70f4c75756 100644
+--- a/qtbase/tests/auto/dbus/qdbusinterface/tst_qdbusinterface.cpp
++++ b/qtbase/tests/auto/dbus/qdbusinterface/tst_qdbusinterface.cpp
+@@ -324,6 +324,13 @@ void tst_QDBusInterface::notValid()
+
+ QVERIFY(!interface.isValid());
+ QVERIFY(!QMetaObject::invokeMethod(&interface, "ListNames", Qt::DirectConnection));
++
++ // With a connection, but empty/null service and path specified
++ QDBusConnection con = QDBusConnection::sessionBus();
++ QVERIFY(con.isConnected());
++ QDBusInterface iface({}, {}, {}, con);
++ QVERIFY(!iface.isValid());
++ QVERIFY(!QMetaObject::invokeMethod(&interface, "ListNames", Qt::DirectConnection));
+ }
+
+ void tst_QDBusInterface::notValidDerived()
+diff --git a/qtbase/tests/auto/gui/kernel/qkeysequence/tst_qkeysequence.cpp b/qtbase/tests/auto/gui/kernel/qkeysequence/tst_qkeysequence.cpp
+index 874468c954..04ceb4ab65 100644
+--- a/qtbase/tests/auto/gui/kernel/qkeysequence/tst_qkeysequence.cpp
++++ b/qtbase/tests/auto/gui/kernel/qkeysequence/tst_qkeysequence.cpp
+@@ -507,6 +507,10 @@ void tst_QKeySequence::toStringFromKeycode_data()
+ QTest::newRow("Ctrl+Alt+Num+Del") << QKeySequence(Qt::ControlModifier | Qt::AltModifier | Qt::KeypadModifier | Qt::Key_Delete) << "Ctrl+Alt+Num+Del";
+ QTest::newRow("Ctrl+Ins") << QKeySequence(Qt::ControlModifier | Qt::Key_Insert) << "Ctrl+Ins";
+ QTest::newRow("Ctrl+Num+Ins(1)") << QKeySequence(Qt::Key_Insert | Qt::KeypadModifier | Qt::ControlModifier) << "Ctrl+Num+Ins";
++ QTest::newRow("Ctrl") << QKeySequence(Qt::Key_Control) << "Control";
++ QTest::newRow("Alt") << QKeySequence(Qt::Key_Alt) << "Alt";
++ QTest::newRow("Shift") << QKeySequence(Qt::Key_Shift) << "Shift";
++ QTest::newRow("Meta") << QKeySequence(Qt::Key_Meta) << "Meta";
+ }
+
+ void tst_QKeySequence::toStringFromKeycode()
+diff --git a/qtbase/tests/auto/gui/text/qfontdatabase/tst_qfontdatabase.cpp b/qtbase/tests/auto/gui/text/qfontdatabase/tst_qfontdatabase.cpp
+index 15e0ecadaa..b4eca74283 100644
+--- a/qtbase/tests/auto/gui/text/qfontdatabase/tst_qfontdatabase.cpp
++++ b/qtbase/tests/auto/gui/text/qfontdatabase/tst_qfontdatabase.cpp
+@@ -81,6 +81,8 @@ private slots:
+ void registerOpenTypePreferredNamesSystem();
+ void registerOpenTypePreferredNamesApplication();
+
++ void stretchRespected();
++
+ private:
+ QString m_ledFont;
+ QString m_testFont;
+@@ -355,6 +357,28 @@ static QString testString()
+ return QStringLiteral("foo bar");
+ }
+
++void tst_QFontDatabase::stretchRespected()
++{
++ int italicId = QFontDatabase::addApplicationFont(m_testFontItalic);
++ QVERIFY(italicId != -1);
++
++ QVERIFY(!QFontDatabase::applicationFontFamilies(italicId).isEmpty());
++
++ QString italicFontName = QFontDatabase::applicationFontFamilies(italicId).first();
++
++ QFont italicFont = QFontDatabase().font(italicFontName,
++ QString::fromLatin1("Italic"), 14);
++ QVERIFY(italicFont.italic());
++
++ QFont italicStretchedFont = italicFont;
++ italicStretchedFont.setStretch( 400 );
++
++ QVERIFY(QFontMetricsF(italicFont).horizontalAdvance(QStringLiteral("foobar")) <
++ QFontMetricsF(italicStretchedFont).horizontalAdvance(QStringLiteral("foobar")));
++
++ QFontDatabase::removeApplicationFont(italicId);
++}
++
+ void tst_QFontDatabase::condensedFontWidthNoFontMerging()
+ {
+ int regularFontId = QFontDatabase::addApplicationFont(m_testFont);
+diff --git a/qtbase/tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp b/qtbase/tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp
+index 3d4a094c43..b423e11a99 100644
+--- a/qtbase/tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp
++++ b/qtbase/tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp
+@@ -281,6 +281,7 @@ private Q_SLOTS:
+ void ioGetFromFileSpecial();
+ void ioGetFromFile_data();
+ void ioGetFromFile();
++ void ioGetFromFileUrl();
+ void ioGetFromFtp_data();
+ void ioGetFromFtp();
+ void ioGetFromFtpWithReuse();
+@@ -3300,6 +3301,18 @@ void tst_QNetworkReply::ioGetFromFile()
+ QCOMPARE(reader.data, data);
+ }
+
++void tst_QNetworkReply::ioGetFromFileUrl()
++{
++ // This immediately fails on non-windows platforms:
++ QNetworkRequest request(QUrl("file://unc-server/some/path"));
++ QNetworkReplyPtr reply(manager.get(request));
++ QSignalSpy finishedSpy(reply.get(), &QNetworkReply::finished);
++ // QTBUG-105618: This would, on non-Windows platforms, never happen because the signal
++ // was emitted before the constructor finished, leaving no chance at all to connect to the
++ // signal
++ QVERIFY(finishedSpy.wait());
++}
++
+ void tst_QNetworkReply::ioGetFromFtp_data()
+ {
+ QTest::addColumn<QString>("fileName");
+diff --git a/qtbase/tests/auto/network/ssl/qsslsocket/certs/fluke.cert b/qtbase/tests/auto/network/ssl/qsslsocket/certs/fluke.cert
+index 069fa6b341..4cc4d9a5ea 100644
+--- a/qtbase/tests/auto/network/ssl/qsslsocket/certs/fluke.cert
++++ b/qtbase/tests/auto/network/ssl/qsslsocket/certs/fluke.cert
+@@ -1,75 +1,34 @@
+-Certificate:
+- Data:
+- Version: 3 (0x2)
+- Serial Number: 0 (0x0)
+- Signature Algorithm: sha1WithRSAEncryption
+- Issuer: C=NO, ST=Oslo, L=Nydalen, O=Nokia Corporation and/or its subsidiary(-ies), OU=Development, CN=fluke.troll.no/emailAddress=ahanssen@trolltech.com
+- Validity
+- Not Before: Dec 4 01:10:32 2007 GMT
+- Not After : Apr 21 01:10:32 2035 GMT
+- Subject: C=NO, ST=Oslo, O=Nokia Corporation and/or its subsidiary(-ies), OU=Development, CN=fluke.troll.no
+- Subject Public Key Info:
+- Public Key Algorithm: rsaEncryption
+- RSA Public Key: (1024 bit)
+- Modulus (1024 bit):
+- 00:a7:c8:a0:4a:c4:19:05:1b:66:ba:32:e2:d2:f1:
+- 1c:6f:17:82:e4:39:2e:01:51:90:db:04:34:32:11:
+- 21:c2:0d:6f:59:d8:53:90:54:3f:83:8f:a9:d3:b3:
+- d5:ee:1a:9b:80:ae:c3:25:c9:5e:a5:af:4b:60:05:
+- aa:a0:d1:91:01:1f:ca:04:83:e3:58:1c:99:32:45:
+- 84:70:72:58:03:98:4a:63:8b:41:f5:08:49:d2:91:
+- 02:60:6b:e4:64:fe:dd:a0:aa:74:08:e9:34:4c:91:
+- 5f:12:3d:37:4d:54:2c:ad:7f:5b:98:60:36:02:8c:
+- 3b:f6:45:f3:27:6a:9b:94:9d
+- Exponent: 65537 (0x10001)
+- X509v3 extensions:
+- X509v3 Basic Constraints:
+- CA:FALSE
+- Netscape Comment:
+- OpenSSL Generated Certificate
+- X509v3 Subject Key Identifier:
+- 21:85:04:3D:23:01:66:E5:F7:9F:1A:84:24:8A:AF:0A:79:F4:E5:AC
+- X509v3 Authority Key Identifier:
+- DirName:/C=NO/ST=Oslo/L=Nydalen/O=Nokia Corporation and/or its subsidiary(-ies)/OU=Development/CN=fluke.troll.no/emailAddress=ahanssen@trolltech.com
+- serial:8E:A8:B4:E8:91:B7:54:2E
+-
+- Signature Algorithm: sha1WithRSAEncryption
+- 6d:57:5f:d1:05:43:f0:62:05:ec:2a:71:a5:dc:19:08:f2:c4:
+- a6:bd:bb:25:d9:ca:89:01:0e:e4:cf:1f:c1:8c:c8:24:18:35:
+- 53:59:7b:c0:43:b4:32:e6:98:b2:a6:ef:15:05:0b:48:5f:e1:
+- a0:0c:97:a9:a1:77:d8:35:18:30:bc:a9:8f:d3:b7:54:c7:f1:
+- a9:9e:5d:e6:19:bf:f6:3c:5b:2b:d8:e4:3e:62:18:88:8b:d3:
+- 24:e1:40:9b:0c:e6:29:16:62:ab:ea:05:24:70:36:aa:55:93:
+- ef:02:81:1b:23:10:a2:04:eb:56:95:75:fc:f8:94:b1:5d:42:
+- c5:3f:36:44:85:5d:3a:2e:90:46:8a:a2:b9:6f:87:ae:0c:15:
+- 40:19:31:90:fc:3b:25:bb:ae:f1:66:13:0d:85:90:d9:49:34:
+- 8f:f2:5d:f9:7a:db:4d:5d:27:f6:76:9d:35:8c:06:a6:4c:a3:
+- b1:b2:b6:6f:1d:d7:a3:00:fd:72:eb:9e:ea:44:a1:af:21:34:
+- 7d:c7:42:e2:49:91:19:8b:c0:ad:ba:82:80:a8:71:70:f4:35:
+- 31:91:63:84:20:95:e9:60:af:64:8b:cc:ff:3d:8a:76:74:3d:
+- c8:55:6d:e4:8e:c3:2b:1c:e8:42:18:ae:9f:e6:6b:9c:34:06:
+- ec:6a:f2:c3
+ -----BEGIN CERTIFICATE-----
+-MIIEEzCCAvugAwIBAgIBADANBgkqhkiG9w0BAQUFADCBnDELMAkGA1UEBhMCTk8x
+-DTALBgNVBAgTBE9zbG8xEDAOBgNVBAcTB055ZGFsZW4xFjAUBgNVBAoTDVRyb2xs
+-dGVjaCBBU0ExFDASBgNVBAsTC0RldmVsb3BtZW50MRcwFQYDVQQDEw5mbHVrZS50
+-cm9sbC5ubzElMCMGCSqGSIb3DQEJARYWYWhhbnNzZW5AdHJvbGx0ZWNoLmNvbTAe
+-Fw0wNzEyMDQwMTEwMzJaFw0zNTA0MjEwMTEwMzJaMGMxCzAJBgNVBAYTAk5PMQ0w
+-CwYDVQQIEwRPc2xvMRYwFAYDVQQKEw1Ucm9sbHRlY2ggQVNBMRQwEgYDVQQLEwtE
+-ZXZlbG9wbWVudDEXMBUGA1UEAxMOZmx1a2UudHJvbGwubm8wgZ8wDQYJKoZIhvcN
+-AQEBBQADgY0AMIGJAoGBAKfIoErEGQUbZroy4tLxHG8XguQ5LgFRkNsENDIRIcIN
+-b1nYU5BUP4OPqdOz1e4am4CuwyXJXqWvS2AFqqDRkQEfygSD41gcmTJFhHByWAOY
+-SmOLQfUISdKRAmBr5GT+3aCqdAjpNEyRXxI9N01ULK1/W5hgNgKMO/ZF8ydqm5Sd
+-AgMBAAGjggEaMIIBFjAJBgNVHRMEAjAAMCwGCWCGSAGG+EIBDQQfFh1PcGVuU1NM
+-IEdlbmVyYXRlZCBDZXJ0aWZpY2F0ZTAdBgNVHQ4EFgQUIYUEPSMBZuX3nxqEJIqv
+-Cnn05awwgbsGA1UdIwSBszCBsKGBoqSBnzCBnDELMAkGA1UEBhMCTk8xDTALBgNV
+-BAgTBE9zbG8xEDAOBgNVBAcTB055ZGFsZW4xFjAUBgNVBAoTDVRyb2xsdGVjaCBB
+-U0ExFDASBgNVBAsTC0RldmVsb3BtZW50MRcwFQYDVQQDEw5mbHVrZS50cm9sbC5u
+-bzElMCMGCSqGSIb3DQEJARYWYWhhbnNzZW5AdHJvbGx0ZWNoLmNvbYIJAI6otOiR
+-t1QuMA0GCSqGSIb3DQEBBQUAA4IBAQBtV1/RBUPwYgXsKnGl3BkI8sSmvbsl2cqJ
+-AQ7kzx/BjMgkGDVTWXvAQ7Qy5piypu8VBQtIX+GgDJepoXfYNRgwvKmP07dUx/Gp
+-nl3mGb/2PFsr2OQ+YhiIi9Mk4UCbDOYpFmKr6gUkcDaqVZPvAoEbIxCiBOtWlXX8
+-+JSxXULFPzZEhV06LpBGiqK5b4euDBVAGTGQ/Dslu67xZhMNhZDZSTSP8l35ettN
+-XSf2dp01jAamTKOxsrZvHdejAP1y657qRKGvITR9x0LiSZEZi8CtuoKAqHFw9DUx
+-kWOEIJXpYK9ki8z/PYp2dD3IVW3kjsMrHOhCGK6f5mucNAbsavLD
++MIIF6zCCA9OgAwIBAgIUfo9amJtJGWqWE6f+SkAO85zkGr4wDQYJKoZIhvcNAQEL
++BQAwgYMxCzAJBgNVBAYTAk5PMQ0wCwYDVQQIDARPc2xvMQ0wCwYDVQQHDARPc2xv
++MRcwFQYDVQQKDA5UaGUgUXQgQ29tcGFueTEMMAoGA1UECwwDUiZEMRIwEAYDVQQD
++DAlIMiBUZXN0ZXIxGzAZBgkqhkiG9w0BCQEWDG1pbmltaUBxdC5pbzAgFw0yMDEw
++MjYxMjAxMzFaGA8yMTIwMTAwMjEyMDEzMVowgYMxCzAJBgNVBAYTAk5PMQ0wCwYD
++VQQIDARPc2xvMQ0wCwYDVQQHDARPc2xvMRcwFQYDVQQKDA5UaGUgUXQgQ29tcGFu
++eTEMMAoGA1UECwwDUiZEMRIwEAYDVQQDDAlIMiBUZXN0ZXIxGzAZBgkqhkiG9w0B
++CQEWDG1pbmltaUBxdC5pbzCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIB
++AOiUp5+E4blouKH7q+rVNR8NoYX2XkBW+q+rpy1zu5ssRSzbqxAjDx9dkht7Qlnf
++VlDT00JvpOWdeuPon5915edQRsY4Unl6mKH29ra3OtUa1/yCJXsGVJTKCj7k4Bxb
++5mZzb/fTlZntMLdTIBMfUbw62FKir1WjKIcJ9fCoG8JaGeKVO4Rh5p0ezd4UUUId
++r1BXl5Nqdqy2vTMsEDnjOsD3egkv8I2SKN4O6n/C3wWYpMOWYZkGoZiKz7rJs/i/
++ez7bsV7JlwdzTlhpJzkcOSVFBP6JlEOxTNNxZ1wtKy7PtZGmsSSATq2e6+bw38Ae
++Op0XnzzqcGjtDDofBmT7OFzZWjS9VZS6+DOOe2QHWle1nCHcHyH4ku6IRlsr9xkR
++NAIlOfnvHHxqJUenoeaZ4oQDjCBKS1KXygJO/tL7BLTQVn/xK1EmPvKNnjzWk4tR
++PnibUhhs5635qpOU/YPqFBh1JjVruZbsWcDAhRcew0uxONXOa9E+4lttQ9ySYa1A
++LvWqJuAX7gu2BsBMLyqfm811YnA7CIFMyO+HlqmkLFfv5L/xIRAXR7l26YGO0VwX
++CGjMfz4NVPMMke4nB7qa9NkpXQBQKMms3Qzd5JW0Hy9Ruj5O8GPcFZmV0twjd1uJ
++PD/cAjkWLaXjdNsJ16QWc2nghQRS6HYqKRX6j+CXOxupAgMBAAGjUzBRMB0GA1Ud
++DgQWBBRSCOU58j9NJZkMamt623qyCrhN3TAfBgNVHSMEGDAWgBRSCOU58j9NJZkM
++amt623qyCrhN3TAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEBCwUAA4ICAQCq
++q4jxsWeNDv5Nq14hJtF9HB+ZL64zcZtRjJP1YgNs0QppKICmjPOL2nIMGmI/jKrs
++0eGAL/9XXNVHPxm1OPOncvimMMmU6emZfpMdEtTfKP43+Pg9HgKRjLoQp406vGeQ
++8ki/mbBhrItVPgEm3tu2AFA02XTYi+YxCI9kRZLGkM3FbgtOuTLPl0Z9y+kiPc9F
++uCSC03anBEqv+vDSI8+wODymQ/IJ3Jyz1lxIRDfp4qAekmy0jU2c91VOHHEmOmqq
++kqygGFRdwbe99m9yP63r6q0b5K3X2UnJ6bns0hmTwThYwpVPXLU8jdaTddbMukN2
++/Ef96Tsw8nWOEOPMySHOTIPgwyZRp26b0kA9EmhLwOP401SxXVQCmSRmtwNagmtg
++jJKmZoYBN+//D45ibK8z6Q0oOm9P+Whf/uUXehcRxBxyV3xz7k0wKGQbHj/ddwcy
++IUoIN4lrAlib+lK170kTKN352PDmrpo2gmIzPEsfurKAIMSelDl6H+kih16BtZ8y
++Nz6fh9Soqrg3OSAware8pxV7k51crBMoPLN78KoRV8MFCK4K7Fddq4rRISq6hiXq
++r1nsjoEPuKM9huprmZVZe9t5YcDa2I+wb3IiE3uwpZbAdaLDyQ5n6F/qpsiIkZXn
++gtcF7oqpG5oYrwCcZ53y/ezUgUg7PlSz2XwAGvQtgg==
+ -----END CERTIFICATE-----
+diff --git a/qtbase/tests/auto/network/ssl/qsslsocket/certs/fluke.key b/qtbase/tests/auto/network/ssl/qsslsocket/certs/fluke.key
+index 9d1664d609..337ce541a6 100644
+--- a/qtbase/tests/auto/network/ssl/qsslsocket/certs/fluke.key
++++ b/qtbase/tests/auto/network/ssl/qsslsocket/certs/fluke.key
+@@ -1,15 +1,52 @@
+------BEGIN RSA PRIVATE KEY-----
+-MIICXAIBAAKBgQCnyKBKxBkFG2a6MuLS8RxvF4LkOS4BUZDbBDQyESHCDW9Z2FOQ
+-VD+Dj6nTs9XuGpuArsMlyV6lr0tgBaqg0ZEBH8oEg+NYHJkyRYRwclgDmEpji0H1
+-CEnSkQJga+Rk/t2gqnQI6TRMkV8SPTdNVCytf1uYYDYCjDv2RfMnapuUnQIDAQAB
+-AoGANFzLkanTeSGNFM0uttBipFT9F4a00dqHz6JnO7zXAT26I5r8sU1pqQBb6uLz
+-/+Qz5Zwk8RUAQcsMRgJetuPQUb0JZjF6Duv24hNazqXBCu7AZzUenjafwmKC/8ri
+-KpX3fTwqzfzi//FKGgbXQ80yykSSliDL3kn/drATxsLCgQECQQDXhEFWLJ0vVZ1s
+-1Ekf+3NITE+DR16X+LQ4W6vyEHAjTbaNWtcTKdAWLA2l6N4WAAPYSi6awm+zMxx4
+-VomVTsjdAkEAx0z+e7natLeFcrrq8pbU+wa6SAP1VfhQWKitxL1e7u/QO90NCpxE
+-oQYKzMkmmpOOFjQwEMAy1dvFMbm4LHlewQJAC/ksDBaUcQHHqjktCtrUb8rVjAyW
+-A8lscckeB2fEYyG5J6dJVaY4ClNOOs5yMDS2Afk1F6H/xKvtQ/5CzInA/QJATDub
+-K+BPU8jO9q+gpuIi3VIZdupssVGmCgObVCHLakG4uO04y9IyPhV9lA9tALtoIf4c
+-VIvv5fWGXBrZ48kZAQJBAJmVCdzQxd9LZI5vxijUCj5EI4e+x5DRqVUvyP8KCZrC
+-AiNyoDP85T+hBZaSXK3aYGpVwelyj3bvo1GrTNwNWLw=
+------END RSA PRIVATE KEY-----
++-----BEGIN PRIVATE KEY-----
++MIIJQgIBADANBgkqhkiG9w0BAQEFAASCCSwwggkoAgEAAoICAQDolKefhOG5aLih
+++6vq1TUfDaGF9l5AVvqvq6ctc7ubLEUs26sQIw8fXZIbe0JZ31ZQ09NCb6TlnXrj
++6J+fdeXnUEbGOFJ5epih9va2tzrVGtf8giV7BlSUygo+5OAcW+Zmc2/305WZ7TC3
++UyATH1G8OthSoq9VoyiHCfXwqBvCWhnilTuEYeadHs3eFFFCHa9QV5eTanastr0z
++LBA54zrA93oJL/CNkijeDup/wt8FmKTDlmGZBqGYis+6ybP4v3s+27FeyZcHc05Y
++aSc5HDklRQT+iZRDsUzTcWdcLSsuz7WRprEkgE6tnuvm8N/AHjqdF5886nBo7Qw6
++HwZk+zhc2Vo0vVWUuvgzjntkB1pXtZwh3B8h+JLuiEZbK/cZETQCJTn57xx8aiVH
++p6HmmeKEA4wgSktSl8oCTv7S+wS00FZ/8StRJj7yjZ481pOLUT54m1IYbOet+aqT
++lP2D6hQYdSY1a7mW7FnAwIUXHsNLsTjVzmvRPuJbbUPckmGtQC71qibgF+4LtgbA
++TC8qn5vNdWJwOwiBTMjvh5appCxX7+S/8SEQF0e5dumBjtFcFwhozH8+DVTzDJHu
++Jwe6mvTZKV0AUCjJrN0M3eSVtB8vUbo+TvBj3BWZldLcI3dbiTw/3AI5Fi2l43Tb
++CdekFnNp4IUEUuh2KikV+o/glzsbqQIDAQABAoICAFw1q6tr5I48vY7DF+rXsuLn
++5ZUWE1IQ6fzB4lr72nJv/9EEGnMgYzt9PpMUsD6vdCpBgS2C0+6RHArFzJtNA+RM
++iHLIG7K7702veyr/xBx/MwiSlMeMv/XpkFxVI6E6skMGG2s3AMXxKvJTy5CpRx+I
++eQFyLG+Ya1X2lgJes/q+/CpAHkOjCOpcLySQC5NZ74q734V7nSdmn+Zs3tYEh+O/
++eiuwTP/j5b38Te5vVTqDxTciJPmljmXLCwa0N100lWlbcpvw8qbqiTI2Jm3XCbUE
++AzHjW9vmrF3cRS1fXxKFGShw3SRqlkbxjfeWoi8qDPUBS4m8LOr8qG9Wo5Nfon0z
++zLP4bci3zHDvVcaaZrrsUBs/yZbg+Dgka1DmX7ekmeccr2yTdKDFgPupYUyxVbTl
++a9ZLJysjFD7rgBv1ZclHonLp6Vbm+ZoTqvteo4ikAy6L9RtBWJ23XEK34PkP/+c5
++2vWZaOrnjSeBHbFce8cdJSxqWpP+eSCI5I9XbDrYFIsQ/gqKgtzDKy2ihJ2Y8STL
++yO4hyFPFjxc+Gg4/P2PpmT5CY2ty44M0BWs+JGW96CJPrrplf2lmQUQJj5LZY66X
++Z/4C9L7ZYtKZ+bs5SvU46yWugAvQZX22Xm9xLXWyVXRdx3bj+3M3fDnF9di/zdbh
++CgLx7oWPNrXc7FCajnn9AoIBAQD5FMYwRpw9NWT9WDxQwx+cSI4Icbd88ByTW63S
++LzeRwZA0J9/SfwO+aBRupzc9GkGXCiZcGMw3AGsCtig8yFlw8E5KnzN7KlftDMnM
++9NUxxzlR8VwKyLnZfG7sDTl057ZlUujnqhmt/F8F7dIy7FVO1dE/8nngA+FYTCOG
++UZdGjwyBDlDM0JJdUWGY3xslutcpCDN5mzSTKjy9drMvImAshRawxRF6WBpn7vr2
++nC6vciqfx1Mzx1vyk0Jm0ilaydDdLMADjt/iL4Nkr0BEs4k+UzQiKDwp8gu7abQ1
++eBfxd9Iar4htQa2I1Ewl6P01G/q+ZYwgHhJ9RVn4AxQXefILAoIBAQDvCouORdQX
++C8wsyp7MwXlF/3NQeNN5/+B2mhbxrBOf7PmMCXLnkRWcjwJtzypWFqJ0sqai/2+0
++bqbMcjX5maT8stT2shl3zXe/Ejt2e3TBYpc1tyuses8Kb5BMU8hu6tTd3G2CMXpD
++dT6DVemJZCTtwj9aBNIxSizvlgMolJnCpzhPnlfHSI6E+g3m/LTTo3HwbjMSw/Uq
++irgjOpI2wSBB6LZPSgjvfcYPRyWUk16L4A5uSX0cADnovDFLa5/h0wJvN/OoCSQg
++rLCXG5E18EyL5Wc58BCY1ZvxmjG3lQtgPxYu2Jwc36R/y/JKlxW5suER5ZNpbbD4
++uOyTt2VxMQ2bAoIBAQC5+MzRFqdo/AjfL5Y5JrbfVTzXCTDa09xCGd16ZU60QTWN
+++4ed/r+o1sUKqUcRFB2MzEM/2DQBjQpZB/CbEWvWa1XJWXxypXbowveZU+QqOnmN
++uQvj8WLyA3o+PNF9e9QvauwCrHpn8VpxbtPWuaYoKnUFreFZZQxHhPGxRBIS2JOZ
++eDrT8ZaWnkCkh1AZp5smQ71LOprSlmKrg4jd1GjCVMxQR5N5KXbtyv0OTCZ/UFqK
++2aRBsMPyJgkaBChkZPLRcKwc+/wlQRx1fHQb14DNTApMxoXFO7eOwqmOkpAt9iyl
++SBIwoS0UUI5ab88+bBmXNvKcuFdNuQ4nowTJUn9pAoIBADMNkILBXSvS5DeIyuO2
++Sp1tkoZUV+5NfPY3sMDK3KIibaW/+t+EOBZo4L7tKQCb8vRzl21mmsfxfgRaPDbj
++3r3tv9g0b4YLxxBy52pFscj/soXRai17SS7UZwA2QK+XzgDYbDcLNC6mIsTQG4Gx
++dsWk3/zs3KuUSQaehmwrWK+fIUK38c1pLK8v7LoxrLkqxlHwZ04RthHw8KTthH7X
++Pnl1J0LF8CSeOyfWLSuPUfkT0GEzptnNHpEbaHfQM6R6eaGhVJPF6AZme4y6YYgg
++m2ihhSt1n0XVEWpHYWjxFy3mK2mz75unFC4LM+NEY2p2zuUQoCw7NjnY3QYrfCnx
++rRMCggEAXeXsMSLFjjyuoL7iKbAxo52HD/P0fBoy58LyRcwfNVr0lvYan4pYEx+o
++KijIh9K16PqXZXKMA9v003B+ulmF8bJ7SddCZ5NGvnFhUTDe4DdTKgp2RuwQ3Bsc
++3skPIDbhVETyOLCtys34USHrq8U/0DlGY3eLRfxw9GnbKxSBGa/KEu/qQLPNUo50
++7xHZDg7GKeC3kqNJeqKM9rkp0VzIGkEnaD9127LeNDmERDfftxJzFoC/THvUBLfU
++6Sus2ZYwRE8VFvKC30Q45t/c54X3IuhYvAuiCuTmyfE4ruyzyOwKzhUkeeLq1APX
++g0veFbyfzlJ0q8qzD/iffqqIa2ZSmQ==
++-----END PRIVATE KEY-----
+diff --git a/qtbase/tests/auto/other/qaccessibilitylinux/tst_qaccessibilitylinux.cpp b/qtbase/tests/auto/other/qaccessibilitylinux/tst_qaccessibilitylinux.cpp
+index 7ba3715e13..752aa122f6 100644
+--- a/qtbase/tests/auto/other/qaccessibilitylinux/tst_qaccessibilitylinux.cpp
++++ b/qtbase/tests/auto/other/qaccessibilitylinux/tst_qaccessibilitylinux.cpp
+@@ -179,6 +179,7 @@ void tst_QAccessibilityLinux::initTestCase()
+ QVERIFY(!address.isEmpty());
+
+ m_window = new AccessibleTestWindow();
++ m_window->setObjectName("mainWindow"_L1);
+ m_window->show();
+
+ QVERIFY(QTest::qWaitForWindowExposed(m_window));
+@@ -236,8 +237,11 @@ bool hasState(QDBusInterface *interface, AtspiStateType state)
+ void tst_QAccessibilityLinux::testLabel()
+ {
+ QLabel *l = new QLabel(m_window);
++ l->setObjectName("theObjectName"_L1);
+ l->setText("Hello A11y");
+ m_window->addWidget(l);
++ auto a11yEmpty = new QLabel(m_window);
++ m_window->addWidget(l);
+
+ // Application
+ QCOMPARE(getParent(mainWindow), QLatin1String(ATSPI_DBUS_PATH_ROOT));
+@@ -249,6 +253,8 @@ void tst_QAccessibilityLinux::testLabel()
+ QCOMPARE(getChildren(labelInterface).count(), 0);
+ QCOMPARE(labelInterface->call(QDBus::Block, "GetRoleName").arguments().first().toString(), QLatin1String("label"));
+ QCOMPARE(labelInterface->call(QDBus::Block, "GetRole").arguments().first().toUInt(), 29u);
++ QCOMPARE(labelInterface->call(QDBus::Block, "GetAccessibleId").arguments().first().toString(),
++ QLatin1String("mainWindow.theObjectName"));
+ QCOMPARE(getParent(labelInterface), mainWindow->path());
+ QVERIFY(!hasState(labelInterface, ATSPI_STATE_EDITABLE));
+ QVERIFY(hasState(labelInterface, ATSPI_STATE_READ_ONLY));
+@@ -256,7 +262,12 @@ void tst_QAccessibilityLinux::testLabel()
+ l->setText("New text");
+ QCOMPARE(labelInterface->property("Name").toString(), l->text());
+
++ auto *a11yEmptyInterface = getInterface(children.at(1), "org.a11y.atspi.Accessible");
++ QCOMPARE(a11yEmptyInterface->call(QDBus::Block, "GetAccessibleId").arguments().first().toString(),
++ QLatin1String("mainWindow.QLabel"));
++
+ m_window->clearChildren();
++ delete a11yEmptyInterface;
+ delete labelInterface;
+ }
+
+diff --git a/qtbase/tests/auto/sql/kernel/qsqlquery/tst_qsqlquery.cpp b/qtbase/tests/auto/sql/kernel/qsqlquery/tst_qsqlquery.cpp
+index 76df61c892..6d6d65b791 100644
+--- a/qtbase/tests/auto/sql/kernel/qsqlquery/tst_qsqlquery.cpp
++++ b/qtbase/tests/auto/sql/kernel/qsqlquery/tst_qsqlquery.cpp
+@@ -1,6 +1,6 @@
+ /****************************************************************************
+ **
+-** Copyright (C) 2016 The Qt Company Ltd.
++** Copyright (C) 2022 The Qt Company Ltd.
+ ** Contact: https://www.qt.io/licensing/
+ **
+ ** This file is part of the test suite of the Qt Toolkit.
+@@ -68,6 +68,8 @@ private slots:
+ void query_exec();
+ void execErrorRecovery_data() { generic_data(); }
+ void execErrorRecovery();
++ void prematureExec_data() { generic_data(); }
++ void prematureExec();
+ void first_data() { generic_data(); }
+ void first();
+ void next_data() { generic_data(); }
+@@ -2770,6 +2772,35 @@ void tst_QSqlQuery::execErrorRecovery()
+ QVERIFY_SQL( q, exec() );
+ }
+
++void tst_QSqlQuery::prematureExec()
++{
++ QFETCH(QString, dbName);
++ // We only want the engine name, for addDatabase():
++ int cut = dbName.indexOf(QChar('@'));
++ if (cut < 0)
++ QSKIP("Failed to parse database type out of name");
++ dbName.truncate(cut);
++ cut = dbName.indexOf(QChar('_'));
++ if (cut >= 0)
++ dbName = dbName.mid(cut + 1);
++
++ auto db = QSqlDatabase::addDatabase(dbName);
++ QSqlQuery q(db);
++
++ QTest::ignoreMessage(QtWarningMsg,
++ "QSqlDatabasePrivate::removeDatabase: connection "
++ "'qt_sql_default_connection' is still in use, all "
++ "queries will cease to work.");
++ QTest::ignoreMessage(QtWarningMsg,
++ "QSqlDatabasePrivate::addDatabase: duplicate connection name "
++ "'qt_sql_default_connection', old connection removed.");
++ auto otherDb = QSqlDatabase::addDatabase(dbName);
++
++ QTest::ignoreMessage(QtWarningMsg, "QSqlQuery::exec: called before driver has been set up");
++ // QTBUG-100037: shouldn't crash !
++ QVERIFY(!q.exec("select stuff from TheVoid"));
++}
++
+ void tst_QSqlQuery::lastInsertId()
+ {
+ QFETCH( QString, dbName );
+diff --git a/qtbase/tests/auto/testlib/qabstractitemmodeltester/tst_qabstractitemmodeltester.cpp b/qtbase/tests/auto/testlib/qabstractitemmodeltester/tst_qabstractitemmodeltester.cpp
+index 4aa3f8d60b..d2050a61aa 100644
+--- a/qtbase/tests/auto/testlib/qabstractitemmodeltester/tst_qabstractitemmodeltester.cpp
++++ b/qtbase/tests/auto/testlib/qabstractitemmodeltester/tst_qabstractitemmodeltester.cpp
+@@ -115,6 +115,10 @@ void tst_QAbstractItemModelTester::standardItemModelZeroColumns()
+ // QTBUG-92886
+ model.insertRows(0, 5);
+ model.removeRows(1, 2);
++
++ const QModelIndex parentIndex = model.index(0, 0);
++ model.insertRows(0, 5, parentIndex);
++ model.removeRows(1, 2, parentIndex);
+ }
+
+ void tst_QAbstractItemModelTester::testInsertThroughProxy()
+diff --git a/qtbase/tests/auto/tools/moc/allmocs_baseline_in.json b/qtbase/tests/auto/tools/moc/allmocs_baseline_in.json
+index 12a4a22a19..ce518e78fb 100644
+--- a/qtbase/tests/auto/tools/moc/allmocs_baseline_in.json
++++ b/qtbase/tests/auto/tools/moc/allmocs_baseline_in.json
+@@ -668,50 +668,6 @@
+ "inputFile": "task192552.h",
+ "outputRevision": 67
+ },
+- {
+- "classes": [
+- {
+- "className": "InlineSlotsWithThrowDeclaration",
+- "object": true,
+- "qualifiedClassName": "InlineSlotsWithThrowDeclaration",
+- "slots": [
+- {
+- "access": "public",
+- "name": "a",
+- "returnType": "void"
+- },
+- {
+- "access": "public",
+- "name": "b",
+- "returnType": "void"
+- },
+- {
+- "access": "public",
+- "name": "c",
+- "returnType": "void"
+- },
+- {
+- "access": "public",
+- "name": "d",
+- "returnType": "void"
+- },
+- {
+- "access": "public",
+- "name": "e",
+- "returnType": "void"
+- }
+- ],
+- "superClasses": [
+- {
+- "access": "public",
+- "name": "QObject"
+- }
+- ]
+- }
+- ],
+- "inputFile": "task189996.h",
+- "outputRevision": 67
+- },
+ {
+ "classes": [
+ {
+diff --git a/qtbase/tests/auto/tools/moc/moc.pro b/qtbase/tests/auto/tools/moc/moc.pro
+index c324b3a8cd..4aceb78dc0 100644
+--- a/qtbase/tests/auto/tools/moc/moc.pro
++++ b/qtbase/tests/auto/tools/moc/moc.pro
+@@ -15,7 +15,7 @@ cross_compile: DEFINES += MOC_CROSS_COMPILED
+ HEADERS += using-namespaces.h no-keywords.h task87883.h c-comments.h backslash-newlines.h oldstyle-casts.h \
+ slots-with-void-template.h qinvokable.h namespaced-flags.h trigraphs.h \
+ escapes-in-string-literals.h cstyle-enums.h qprivateslots.h gadgetwithnoenums.h \
+- dir-in-include-path.h single_function_keyword.h task192552.h task189996.h \
++ dir-in-include-path.h single_function_keyword.h task192552.h \
+ task234909.h task240368.h pure-virtual-signals.h cxx11-enums.h \
+ cxx11-final-classes.h \
+ cxx11-explicit-override-control.h \
+diff --git a/qtbase/tests/auto/tools/moc/task189996.h b/qtbase/tests/auto/tools/moc/task189996.h
+deleted file mode 100644
+index f94a051b3a..0000000000
+--- a/qtbase/tests/auto/tools/moc/task189996.h
++++ /dev/null
+@@ -1,47 +0,0 @@
+-/****************************************************************************
+-**
+-** Copyright (C) 2016 The Qt Company Ltd.
+-** Contact: https://www.qt.io/licensing/
+-**
+-** This file is part of the test suite of the Qt Toolkit.
+-**
+-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+-** Commercial License Usage
+-** Licensees holding valid commercial Qt licenses may use this file in
+-** accordance with the commercial license agreement provided with the
+-** Software or, alternatively, in accordance with the terms contained in
+-** a written agreement between you and The Qt Company. For licensing terms
+-** and conditions see https://www.qt.io/terms-conditions. For further
+-** information use the contact form at https://www.qt.io/contact-us.
+-**
+-** GNU General Public License Usage
+-** Alternatively, this file may be used under the terms of the GNU
+-** General Public License version 3 as published by the Free Software
+-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+-** included in the packaging of this file. Please review the following
+-** information to ensure the GNU General Public License requirements will
+-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+-**
+-** $QT_END_LICENSE$
+-**
+-****************************************************************************/
+-// inline functions can have throw declarations
+-
+-#ifndef TASK189996_H
+-#define TASK189996_H
+-
+-#include <QObject>
+-
+-class InlineSlotsWithThrowDeclaration : public QObject
+-{
+- Q_OBJECT
+-
+-public slots:
+- void a() throw() { }
+- void b() const throw() { }
+- void c() throw();
+- void d() throw(int) { }
+- void e() const throw(int,double) { }
+-};
+-
+-#endif
+diff --git a/qtbase/tests/auto/tools/moc/tst_moc.cpp b/qtbase/tests/auto/tools/moc/tst_moc.cpp
+index c716aead21..15dd9e41e5 100644
+--- a/qtbase/tests/auto/tools/moc/tst_moc.cpp
++++ b/qtbase/tests/auto/tools/moc/tst_moc.cpp
+@@ -631,7 +631,6 @@ public:
+ private slots:
+ void initTestCase();
+
+- void slotWithException() throw(MyStruct);
+ void dontStripNamespaces();
+ void oldStyleCasts();
+ void warnOnExtraSignalSlotQualifiaction();
+@@ -673,7 +672,6 @@ private slots:
+ void templateGtGt();
+ void qprivateslots();
+ void qprivateproperties();
+- void inlineSlotsWithThrowDeclaration();
+ void warnOnPropertyWithoutREAD();
+ void constructors();
+ void typenameWithUnsigned();
+@@ -784,12 +782,6 @@ void tst_Moc::initTestCase()
+ #endif
+ }
+
+-void tst_Moc::slotWithException() throw(MyStruct)
+-{
+- // be happy
+- QVERIFY(true);
+-}
+-
+ void tst_Moc::dontStripNamespaces()
+ {
+ Sender sender;
+@@ -824,7 +816,7 @@ void tst_Moc::oldStyleCasts()
+
+ QStringList args;
+ args << "-c" << "-x" << "c++" << "-Wold-style-cast" << "-I" << "."
+- << "-I" << qtIncludePath << "-o" << "/dev/null" << "-fPIC" << "-std=c++11" << "-";
++ << "-I" << qtIncludePath << "-o" << "/dev/null" << "-fPIC" << "-std=c++1z" << "-";
+ proc.start("gcc", args);
+ QVERIFY(proc.waitForStarted());
+ proc.write(mocOut);
+@@ -894,7 +886,7 @@ void tst_Moc::inputFileNameWithDotsButNoExtension()
+
+ QStringList args;
+ args << "-c" << "-x" << "c++" << "-I" << ".."
+- << "-I" << qtIncludePath << "-o" << "/dev/null" << "-fPIC" << "-std=c++11" << "-";
++ << "-I" << qtIncludePath << "-o" << "/dev/null" << "-fPIC" << "-std=c++1z" << "-";
+ proc.start("gcc", args);
+ QVERIFY(proc.waitForStarted());
+ proc.write(mocOut);
+@@ -1174,7 +1166,7 @@ void tst_Moc::ignoreOptionClashes()
+ QStringList gccArgs;
+ gccArgs << "-c" << "-x" << "c++" << "-I" << ".."
+ << "-I" << qtIncludePath << "-I" << includeDir << "-o" << "/dev/null"
+- << "-fPIC" << "-std=c++11" << "-";
++ << "-fPIC" << "-std=c++1z" << "-";
+ proc.start("gcc", gccArgs);
+ QVERIFY(proc.waitForStarted());
+ proc.write(mocOut);
+@@ -1593,21 +1585,6 @@ void tst_Moc::qprivateproperties()
+
+ }
+
+-#include "task189996.h"
+-
+-void InlineSlotsWithThrowDeclaration::c() throw() {}
+-
+-void tst_Moc::inlineSlotsWithThrowDeclaration()
+-{
+- InlineSlotsWithThrowDeclaration tst;
+- const QMetaObject *mobj = tst.metaObject();
+- QVERIFY(mobj->indexOfSlot("a()") != -1);
+- QVERIFY(mobj->indexOfSlot("b()") != -1);
+- QVERIFY(mobj->indexOfSlot("c()") != -1);
+- QVERIFY(mobj->indexOfSlot("d()") != -1);
+- QVERIFY(mobj->indexOfSlot("e()") != -1);
+-}
+-
+ void tst_Moc::warnOnPropertyWithoutREAD()
+ {
+ #ifdef MOC_CROSS_COMPILED
+@@ -1869,7 +1846,7 @@ void tst_Moc::notifyError()
+
+ QStringList args;
+ args << "-c" << "-x" << "c++" << "-I" << "."
+- << "-I" << qtIncludePath << "-o" << "/dev/null" << "-fPIC" << "-std=c++11" << "-";
++ << "-I" << qtIncludePath << "-o" << "/dev/null" << "-fPIC" << "-std=c++1z" << "-";
+ proc.start("gcc", args);
+ QVERIFY(proc.waitForStarted());
+ proc.write(mocOut);
+diff --git a/qtbase/tests/auto/widgets/itemviews/qheaderview/tst_qheaderview.cpp b/qtbase/tests/auto/widgets/itemviews/qheaderview/tst_qheaderview.cpp
+index c355ee9665..88c09de8e0 100644
+--- a/qtbase/tests/auto/widgets/itemviews/qheaderview/tst_qheaderview.cpp
++++ b/qtbase/tests/auto/widgets/itemviews/qheaderview/tst_qheaderview.cpp
+@@ -251,6 +251,7 @@ private slots:
+ void testResetCachedSizeHint();
+ void statusTips();
+ void testRemovingColumnsViaLayoutChanged();
++ void testModelMovingColumns();
+
+ protected:
+ void setupTestData(bool use_reset_model = false);
+@@ -360,6 +361,12 @@ public:
+ endRemoveColumns();
+ }
+
++ void moveColumn(int from, int to)
++ {
++ beginMoveColumns(QModelIndex(), from, from, QModelIndex(), to);
++ endMoveColumns();
++ }
++
+ void cleanup()
+ {
+ emit layoutAboutToBeChanged();
+@@ -3627,5 +3634,18 @@ void tst_QHeaderView::testRemovingColumnsViaLayoutChanged()
+ // The main point of this test is that the section-size restoring code didn't go out of bounds.
+ }
+
++void tst_QHeaderView::testModelMovingColumns()
++{
++ QtTestModel model(10, 10);
++ QHeaderView hv(Qt::Horizontal);
++ hv.setModel(&model);
++ hv.resizeSections(QHeaderView::ResizeToContents);
++ hv.show();
++
++ QPersistentModelIndex index3 = model.index(0, 3);
++ model.moveColumn(3, 1);
++ QCOMPARE(index3.column(), 1);
++}
++
+ QTEST_MAIN(tst_QHeaderView)
+ #include "tst_qheaderview.moc"
+diff --git a/qtbase/tests/auto/widgets/itemviews/qtableview/tst_qtableview.cpp b/qtbase/tests/auto/widgets/itemviews/qtableview/tst_qtableview.cpp
+index 761357b252..06bb706074 100644
+--- a/qtbase/tests/auto/widgets/itemviews/qtableview/tst_qtableview.cpp
++++ b/qtbase/tests/auto/widgets/itemviews/qtableview/tst_qtableview.cpp
+@@ -397,6 +397,7 @@ private slots:
+ void checkHeaderMinSize();
+
+ void resizeToContents();
++ void resizeToContentsSpans();
+
+ void tabFocus();
+ void bigModel();
+@@ -3721,6 +3722,70 @@ void tst_QTableView::resizeToContents()
+
+ }
+
++
++class SpanModel : public QAbstractTableModel
++{
++public:
++ SpanModel(bool sectionsMoved)
++ : _sectionsMoved(sectionsMoved)
++ {}
++ int columnCount(const QModelIndex & = {}) const override { return 2; }
++ int rowCount(const QModelIndex & = {}) const override { return 1; }
++ QVariant data(const QModelIndex &idx, int role = Qt::DisplayRole) const override
++ {
++ if (role != Qt::DisplayRole)
++ return QVariant();
++ const int col = _sectionsMoved ? 1 - idx.column() : idx.column();
++ if (col == 0)
++ return "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.";
++ return QVariant();
++ }
++private:
++ bool _sectionsMoved;
++};
++
++
++void tst_QTableView::resizeToContentsSpans()
++{
++ SpanModel model1(false);
++ SpanModel model2(true);
++ QTableView view1, view2, view3;
++ view1.setModel(&model1);
++ view2.setModel(&model2);
++ view2.horizontalHeader()->moveSection(0, 1);
++ view3.setModel(&model1);
++
++ view1.setSpan(0, 0, 1, 2);
++ view2.setSpan(0, 1, 1, 2);
++ view1.show();
++ view2.show();
++ view3.show();
++ QVERIFY(QTest::qWaitForWindowExposed(&view1));
++ QVERIFY(QTest::qWaitForWindowExposed(&view2));
++ QVERIFY(QTest::qWaitForWindowExposed(&view3));
++ view1.setColumnWidth(0, 100);
++ view1.setColumnWidth(1, 100);
++ view2.setColumnWidth(0, 100);
++ view2.setColumnWidth(1, 100);
++ view3.setColumnWidth(0, 200);
++
++ view1.resizeRowToContents(0);
++ view2.resizeRowToContents(0);
++ view3.resizeRowToContents(0);
++ QCOMPARE(view1.rowHeight(0), view3.rowHeight(0));
++ QCOMPARE(view2.rowHeight(0), view3.rowHeight(0));
++
++ view3.resizeColumnToContents(0);
++ view3.resizeRowToContents(0);
++ // height should be only 1 text line for easy testing
++ view1.setRowHeight(0, view3.verticalHeader()->sectionSize(0));
++ view2.setRowHeight(0, view3.verticalHeader()->sectionSize(0));
++ view1.resizeColumnToContents(0);
++ view2.resizeColumnToContents(1);
++ QCOMPARE(view1.columnWidth(0), view3.columnWidth(0) - view1.columnWidth(1));
++ QCOMPARE(view2.columnWidth(0), view3.columnWidth(0) - view2.columnWidth(1));
++}
++
+ QT_BEGIN_NAMESPACE
+ extern bool Q_WIDGETS_EXPORT qt_tab_all_widgets(); // qapplication.cpp
+ QT_END_NAMESPACE
+diff --git a/qtbase/tests/auto/widgets/kernel/qapplication/tst_qapplication.cpp b/qtbase/tests/auto/widgets/kernel/qapplication/tst_qapplication.cpp
+index a3b8ef78d8..4955cebd5d 100644
+--- a/qtbase/tests/auto/widgets/kernel/qapplication/tst_qapplication.cpp
++++ b/qtbase/tests/auto/widgets/kernel/qapplication/tst_qapplication.cpp
+@@ -1498,7 +1498,7 @@ void tst_QApplication::desktopSettingsAware()
+ environment += QLatin1String("QT_MAC_DISABLE_FOREGROUND_APPLICATION_TRANSFORM=1");
+ testProcess.setEnvironment(environment);
+ #endif
+- testProcess.start("desktopsettingsaware_helper");
++ testProcess.start("./desktopsettingsaware_helper");
+ QVERIFY2(testProcess.waitForStarted(),
+ qPrintable(QString::fromLatin1("Cannot start 'desktopsettingsaware_helper': %1").arg(testProcess.errorString())));
+ QVERIFY(testProcess.waitForFinished(10000));
+@@ -2452,7 +2452,7 @@ void tst_QApplication::qtbug_12673()
+ #if QT_CONFIG(process)
+ QProcess testProcess;
+ QStringList arguments;
+- testProcess.start("modal_helper", arguments);
++ testProcess.start("./modal_helper", arguments);
+ QVERIFY2(testProcess.waitForStarted(),
+ qPrintable(QString::fromLatin1("Cannot start 'modal_helper': %1").arg(testProcess.errorString())));
+ QVERIFY(testProcess.waitForFinished(20000));
+diff --git a/qtbase/tests/auto/widgets/widgets/qabstractbutton/tst_qabstractbutton.cpp b/qtbase/tests/auto/widgets/widgets/qabstractbutton/tst_qabstractbutton.cpp
+index eb108a40de..dca5528c1b 100644
+--- a/qtbase/tests/auto/widgets/widgets/qabstractbutton/tst_qabstractbutton.cpp
++++ b/qtbase/tests/auto/widgets/widgets/qabstractbutton/tst_qabstractbutton.cpp
+@@ -41,6 +41,7 @@
+
+ #include <private/qguiapplication_p.h>
+ #include <qpa/qplatformintegration.h>
++#include <qpa/qplatformtheme.h>
+
+ class tst_QAbstractButton : public QObject
+ {
+@@ -76,6 +77,8 @@ private slots:
+ void keyNavigation();
+ #endif
+
++ void buttonPressKeys();
++
+ protected slots:
+ void onClicked();
+ void onToggled( bool on );
+@@ -269,7 +272,13 @@ void tst_QAbstractButton::setAutoRepeat()
+ QCOMPARE(press_count, click_count);
+ QVERIFY(click_count > 1);
+ break;
+- case 4:
++ case 4: {
++ const auto buttonPressKeys = QGuiApplicationPrivate::platformTheme()
++ ->themeHint(QPlatformTheme::ButtonPressKeys)
++ .value<QList<Qt::Key>>();
++ if (buttonPressKeys.contains(Qt::Key_Enter)) {
++ QSKIP("platform theme has Key_Enter in ButtonPressKeys");
++ }
+ // check that pressing ENTER has no effect when autorepeat is false
+ testWidget->setDown( false );
+ testWidget->setAutoRepeat( false );
+@@ -286,7 +295,14 @@ void tst_QAbstractButton::setAutoRepeat()
+
+ QVERIFY( click_count == 0 );
+ break;
+- case 5:
++ }
++ case 5: {
++ const auto buttonPressKeys = QGuiApplicationPrivate::platformTheme()
++ ->themeHint(QPlatformTheme::ButtonPressKeys)
++ .value<QList<Qt::Key>>();
++ if (buttonPressKeys.contains(Qt::Key_Enter)) {
++ QSKIP("platform theme has Key_Enter in ButtonPressKeys");
++ }
+ // check that pressing ENTER has no effect when autorepeat is true
+ testWidget->setDown( false );
+ testWidget->setAutoRepeat( true );
+@@ -304,6 +320,7 @@ void tst_QAbstractButton::setAutoRepeat()
+
+ QVERIFY( click_count == 0 );
+ break;
++ }
+ case 6:
+ // verify autorepeat is off by default.
+ MyButton tmp( 0);
+@@ -651,5 +668,16 @@ void tst_QAbstractButton::keyNavigation()
+ }
+ #endif
+
++void tst_QAbstractButton::buttonPressKeys()
++{
++ const auto buttonPressKeys = QGuiApplicationPrivate::platformTheme()
++ ->themeHint(QPlatformTheme::ButtonPressKeys)
++ .value<QList<Qt::Key>>();
++ for (int i = 0; i < buttonPressKeys.length(); ++i) {
++ QTest::keyClick(testWidget, buttonPressKeys[i]);
++ QCOMPARE(click_count, i + 1);
++ }
++}
++
+ QTEST_MAIN(tst_QAbstractButton)
+ #include "tst_qabstractbutton.moc"
+diff --git a/qtbase/tests/auto/widgets/widgets/qcombobox/tst_qcombobox.cpp b/qtbase/tests/auto/widgets/widgets/qcombobox/tst_qcombobox.cpp
+index 32437050f5..46b5af6d63 100644
+--- a/qtbase/tests/auto/widgets/widgets/qcombobox/tst_qcombobox.cpp
++++ b/qtbase/tests/auto/widgets/widgets/qcombobox/tst_qcombobox.cpp
+@@ -168,6 +168,7 @@ private slots:
+ void checkMenuItemPosWhenStyleSheetIsSet();
+ void checkEmbeddedLineEditWhenStyleSheetIsSet();
+ void propagateStyleChanges();
++ void buttonPressKeys();
+
+ private:
+ PlatformInputContext m_platformInputContext;
+@@ -1682,6 +1683,16 @@ void tst_QComboBox::setModel()
+ QCOMPARE(box.rootModelIndex(), rootModelIndex);
+ box.setModel(box.model());
+ QCOMPARE(box.rootModelIndex(), rootModelIndex);
++
++ // check that setting the same model as the completer's doesn't crash
++ QCompleter *completer = new QCompleter(&box);
++ box.setEditable(true);
++ box.setCompleter(completer);
++ auto *listModel = new QStringListModel({ "one", "two" }, completer);
++ completer->setModel(listModel);
++ QCOMPARE(listModel->rowCount(), 2); // make sure it wasn't deleted
++ box.setModel(listModel);
++ QCOMPARE(listModel->rowCount(), 2); // make sure it wasn't deleted
+ }
+
+ void tst_QComboBox::setCustomModelAndView()
+@@ -3632,5 +3643,24 @@ void tst_QComboBox::propagateStyleChanges()
+ QVERIFY(frameStyle.inquired);
+ }
+
++void tst_QComboBox::buttonPressKeys()
++{
++ QComboBox comboBox;
++ comboBox.setEditable(false);
++ comboBox.addItem(QString::number(1));
++ comboBox.addItem(QString::number(2));
++ const auto buttonPressKeys = QGuiApplicationPrivate::platformTheme()
++ ->themeHint(QPlatformTheme::ButtonPressKeys)
++ .value<QList<Qt::Key>>();
++ for (int i = 0; i < buttonPressKeys.length(); ++i) {
++ QTest::keyClick(&comboBox, buttonPressKeys[i]);
++ // On some platforms, a window will not be immediately visible,
++ // but take some event-loop iterations to complete.
++ // Using QTRY_VERIFY to deal with that.
++ QTRY_VERIFY(comboBox.view()->isVisible());
++ comboBox.hidePopup();
++ }
++}
++
+ QTEST_MAIN(tst_QComboBox)
+ #include "tst_qcombobox.moc"
+diff --git a/qtbase/tests/auto/widgets/widgets/qcommandlinkbutton/qcommandlinkbutton.pro b/qtbase/tests/auto/widgets/widgets/qcommandlinkbutton/qcommandlinkbutton.pro
+index be3cfcd104..c228fdfcca 100644
+--- a/qtbase/tests/auto/widgets/widgets/qcommandlinkbutton/qcommandlinkbutton.pro
++++ b/qtbase/tests/auto/widgets/widgets/qcommandlinkbutton/qcommandlinkbutton.pro
+@@ -1,6 +1,6 @@
+ CONFIG += testcase
+ TARGET = tst_qcommandlinkbutton
+-QT += widgets testlib
++QT += widgets testlib gui-private
+ SOURCES += tst_qcommandlinkbutton.cpp
+
+
+diff --git a/qtbase/tests/auto/widgets/widgets/qcommandlinkbutton/tst_qcommandlinkbutton.cpp b/qtbase/tests/auto/widgets/widgets/qcommandlinkbutton/tst_qcommandlinkbutton.cpp
+index 0044d33c66..4cf06296e4 100644
+--- a/qtbase/tests/auto/widgets/widgets/qcommandlinkbutton/tst_qcommandlinkbutton.cpp
++++ b/qtbase/tests/auto/widgets/widgets/qcommandlinkbutton/tst_qcommandlinkbutton.cpp
+@@ -40,6 +40,9 @@
+ #include <QGridLayout>
+ #include <QPainter>
+
++#include <private/qguiapplication_p.h>
++#include <qpa/qplatformtheme.h>
++
+ class tst_QCommandLinkButton : public QObject
+ {
+ Q_OBJECT
+@@ -223,6 +226,13 @@ void tst_QCommandLinkButton::setAutoRepeat()
+ // check that pressing ENTER has no effect
+ resetCounters();
+ testWidget->setDown( false );
++ // Skip after reset if ButtonPressKeys has Key_Enter
++ const auto buttonPressKeys = QGuiApplicationPrivate::platformTheme()
++ ->themeHint(QPlatformTheme::ButtonPressKeys)
++ .value<QList<Qt::Key>>();
++ if (buttonPressKeys.contains(Qt::Key_Enter)) {
++ return;
++ }
+ testWidget->setAutoRepeat( false );
+ QTest::keyPress( testWidget, Qt::Key_Enter );
+
+@@ -255,6 +265,14 @@ void tst_QCommandLinkButton::pressed()
+ QCOMPARE( press_count, (uint)1 );
+ QCOMPARE( release_count, (uint)1 );
+
++ // Skip if ButtonPressKeys has Key_Enter
++ const auto buttonPressKeys = QGuiApplicationPrivate::platformTheme()
++ ->themeHint(QPlatformTheme::ButtonPressKeys)
++ .value<QList<Qt::Key>>();
++ if (buttonPressKeys.contains(Qt::Key_Enter)) {
++ return;
++ }
++
+ QTest::keyPress( testWidget,Qt::Key_Enter );
+ QCOMPARE( press_count, (uint)1 );
+ QCOMPARE( release_count, (uint)1 );
+diff --git a/qtbase/tests/auto/widgets/widgets/qgroupbox/qgroupbox.pro b/qtbase/tests/auto/widgets/widgets/qgroupbox/qgroupbox.pro
+index 4a5e76ff65..a235fa1fac 100644
+--- a/qtbase/tests/auto/widgets/widgets/qgroupbox/qgroupbox.pro
++++ b/qtbase/tests/auto/widgets/widgets/qgroupbox/qgroupbox.pro
+@@ -1,6 +1,6 @@
+ CONFIG += testcase
+ TARGET = tst_qgroupbox
+-QT += widgets testlib
++QT += widgets testlib gui-private
+ SOURCES += tst_qgroupbox.cpp
+
+
+diff --git a/qtbase/tests/auto/widgets/widgets/qgroupbox/tst_qgroupbox.cpp b/qtbase/tests/auto/widgets/widgets/qgroupbox/tst_qgroupbox.cpp
+index 4fb5d262ca..d8d7562b73 100644
+--- a/qtbase/tests/auto/widgets/widgets/qgroupbox/tst_qgroupbox.cpp
++++ b/qtbase/tests/auto/widgets/widgets/qgroupbox/tst_qgroupbox.cpp
+@@ -35,6 +35,9 @@
+ #include <QRadioButton>
+ #include <QDialog>
+
++#include <private/qguiapplication_p.h>
++#include <qpa/qplatformtheme.h>
++
+ #include "qgroupbox.h"
+
+ class tst_QGroupBox : public QObject
+@@ -69,6 +72,7 @@ private slots:
+ void propagateFocus();
+ void task_QTBUG_19170_ignoreMouseReleaseEvent();
+ void task_QTBUG_15519_propagateMouseEvents();
++ void buttonPressKeys();
+
+ private:
+ bool checked;
+@@ -610,6 +614,20 @@ void tst_QGroupBox::task_QTBUG_15519_propagateMouseEvents()
+ QCOMPARE(parent.mouseMoved, true);
+ }
+
++void tst_QGroupBox::buttonPressKeys()
++{
++ QGroupBox groupBox;
++ groupBox.setCheckable(true);
++ QSignalSpy clickedSpy(&groupBox, &QGroupBox::clicked);
++ const auto buttonPressKeys = QGuiApplicationPrivate::platformTheme()
++ ->themeHint(QPlatformTheme::ButtonPressKeys)
++ .value<QList<Qt::Key>>();
++ for (int i = 0; i < buttonPressKeys.length(); ++i) {
++ QTest::keyClick(&groupBox, buttonPressKeys[i]);
++ QCOMPARE(clickedSpy.length(), i + 1);
++ }
++}
++
+ void tst_QGroupBox::sendMouseMoveEvent(QWidget *widget, const QPoint &localPos)
+ {
+ // Send a MouseMove event without actually moving the pointer
+diff --git a/qtbase/tests/auto/widgets/widgets/qpushbutton/qpushbutton.pro b/qtbase/tests/auto/widgets/widgets/qpushbutton/qpushbutton.pro
+index 353ad06ca2..e55f6148f2 100644
+--- a/qtbase/tests/auto/widgets/widgets/qpushbutton/qpushbutton.pro
++++ b/qtbase/tests/auto/widgets/widgets/qpushbutton/qpushbutton.pro
+@@ -1,6 +1,6 @@
+ CONFIG += testcase
+ TARGET = tst_qpushbutton
+-QT += widgets testlib
++QT += widgets testlib gui-private
+ SOURCES += tst_qpushbutton.cpp
+
+
+diff --git a/qtbase/tests/auto/widgets/widgets/qpushbutton/tst_qpushbutton.cpp b/qtbase/tests/auto/widgets/widgets/qpushbutton/tst_qpushbutton.cpp
+index e818514a79..4043e9326a 100644
+--- a/qtbase/tests/auto/widgets/widgets/qpushbutton/tst_qpushbutton.cpp
++++ b/qtbase/tests/auto/widgets/widgets/qpushbutton/tst_qpushbutton.cpp
+@@ -41,6 +41,9 @@
+ #include <QStyleFactory>
+ #include <QTabWidget>
+
++#include <private/qguiapplication_p.h>
++#include <qpa/qplatformtheme.h>
++
+ class tst_QPushButton : public QObject
+ {
+ Q_OBJECT
+@@ -212,6 +215,13 @@ void tst_QPushButton::autoRepeat()
+ // check that pressing ENTER has no effect
+ resetCounters();
+ testWidget->setDown( false );
++ // Skip after reset if ButtonPressKeys has Key_Enter
++ const auto buttonPressKeys = QGuiApplicationPrivate::platformTheme()
++ ->themeHint(QPlatformTheme::ButtonPressKeys)
++ .value<QList<Qt::Key>>();
++ if (buttonPressKeys.contains(Qt::Key_Enter)) {
++ return;
++ }
+ testWidget->setAutoRepeat( false );
+ QTest::keyPress( testWidget, Qt::Key_Enter );
+
+@@ -247,6 +257,14 @@ void tst_QPushButton::pressed()
+ QCOMPARE( press_count, (uint)1 );
+ QCOMPARE( release_count, (uint)1 );
+
++ // Skip if ButtonPressKeys has Key_Enter
++ const auto buttonPressKeys = QGuiApplicationPrivate::platformTheme()
++ ->themeHint(QPlatformTheme::ButtonPressKeys)
++ .value<QList<Qt::Key>>();
++ if (buttonPressKeys.contains(Qt::Key_Enter)) {
++ return;
++ }
++
+ QTest::keyPress( testWidget,Qt::Key_Enter );
+ QCOMPARE( press_count, (uint)1 );
+ QCOMPARE( release_count, (uint)1 );
+diff --git a/qtbase/tests/manual/rhi/cubemap_render/buildshader.bat b/qtbase/tests/manual/rhi/cubemap_render/buildshader.bat
+old mode 100755
+new mode 100644
+Submodule qtconnectivity e957d481..056294c0:
+diff --git a/qtconnectivity/src/bluetooth/bluez/hcimanager.cpp b/qtconnectivity/src/bluetooth/bluez/hcimanager.cpp
+index e2635fae..a8b8e3b9 100644
+--- a/qtconnectivity/src/bluetooth/bluez/hcimanager.cpp
++++ b/qtconnectivity/src/bluetooth/bluez/hcimanager.cpp
+@@ -563,9 +563,11 @@ void HciManager::handleHciAclPacket(const quint8 *data, int size)
+
+ void HciManager::handleLeMetaEvent(const quint8 *data)
+ {
+- // Spec v4.2, Vol 2, part E, 7.7.65ff
++ // Spec v5.3, Vol 4, part E, 7.7.65.*
+ switch (*data) {
+- case 0x1: {
++ case 0x1: // HCI_LE_Connection_Complete
++ case 0xA: // HCI_LE_Enhanced_Connection_Complete
++ {
+ const quint16 handle = bt_get_le16(data + 2);
+ emit connectionComplete(handle);
+ break;
+diff --git a/qtconnectivity/src/bluetooth/qbluetoothservicediscoveryagent_bluez.cpp b/qtconnectivity/src/bluetooth/qbluetoothservicediscoveryagent_bluez.cpp
+index 6a93143b..4a18cfc7 100644
+--- a/qtconnectivity/src/bluetooth/qbluetoothservicediscoveryagent_bluez.cpp
++++ b/qtconnectivity/src/bluetooth/qbluetoothservicediscoveryagent_bluez.cpp
+@@ -320,7 +320,10 @@ void QBluetoothServiceDiscoveryAgentPrivate::_q_finishSdpScan(QBluetoothServiceD
+ for (const QBluetoothUuid &id : serviceClassUuids) {
+ if (id.minimumSize() == 16) {
+ serviceInfo.setServiceUuid(id);
+- serviceInfo.setServiceName(QBluetoothServiceDiscoveryAgent::tr("Custom Service"));
++ if (serviceInfo.serviceName().isEmpty()) {
++ serviceInfo.setServiceName(
++ QBluetoothServiceDiscoveryAgent::tr("Custom Service"));
++ }
+ QBluetoothServiceInfo::Sequence modSeq =
+ serviceInfo.attribute(QBluetoothServiceInfo::ServiceClassIds).value<QBluetoothServiceInfo::Sequence>();
+ modSeq.removeOne(QVariant::fromValue(id));
+@@ -334,8 +337,10 @@ void QBluetoothServiceDiscoveryAgentPrivate::_q_finishSdpScan(QBluetoothServiceD
+ qCDebug(QT_BT_BLUEZ) << "Discovered services" << discoveredDevices.at(0).address().toString()
+ << serviceInfo.serviceName() << serviceInfo.serviceUuid()
+ << ">>>" << serviceInfo.serviceClassUuids();
+-
+- emit q->serviceDiscovered(serviceInfo);
++ // Use queued connection to allow us finish the service looping; the application
++ // might call stop() when it has detected the service-of-interest.
++ QMetaObject::invokeMethod(q, "serviceDiscovered", Qt::QueuedConnection,
++ Q_ARG(QBluetoothServiceInfo, serviceInfo));
+ }
+ }
+ }
+diff --git a/qtconnectivity/src/bluetooth/qbluetoothsocket.cpp b/qtconnectivity/src/bluetooth/qbluetoothsocket.cpp
+index e4d85447..aadd4755 100644
+--- a/qtconnectivity/src/bluetooth/qbluetoothsocket.cpp
++++ b/qtconnectivity/src/bluetooth/qbluetoothsocket.cpp
+@@ -593,7 +593,7 @@ void QBluetoothSocket::setSocketState(QBluetoothSocket::SocketState state)
+ bool QBluetoothSocket::canReadLine() const
+ {
+ Q_D(const QBluetoothSocketBase);
+- return d->canReadLine();
++ return d->canReadLine() || QIODevice::canReadLine();
+ }
+
+ /*!
+diff --git a/qtconnectivity/src/bluetooth/qbluetoothsocket_bluezdbus.cpp b/qtconnectivity/src/bluetooth/qbluetoothsocket_bluezdbus.cpp
+index 084aa958..d6aa17a7 100644
+--- a/qtconnectivity/src/bluetooth/qbluetoothsocket_bluezdbus.cpp
++++ b/qtconnectivity/src/bluetooth/qbluetoothsocket_bluezdbus.cpp
+@@ -284,6 +284,10 @@ void QBluetoothSocketPrivateBluezDBus::connectToService(
+ return;
+ }
+
++ if (service.socketProtocol() != QBluetoothServiceInfo::Protocol::UnknownProtocol)
++ socketType = service.socketProtocol();
++ qCDebug(QT_BT_BLUEZ) << "Socket protocol used:" << socketType;
++
+ connectToService(service.device().address(), targetService, openMode);
+ }
+
+diff --git a/qtconnectivity/tests/auto/qbluetoothsocket/tst_qbluetoothsocket.cpp b/qtconnectivity/tests/auto/qbluetoothsocket/tst_qbluetoothsocket.cpp
+index 05bc1a0f..a7b5ef1f 100644
+--- a/qtconnectivity/tests/auto/qbluetoothsocket/tst_qbluetoothsocket.cpp
++++ b/qtconnectivity/tests/auto/qbluetoothsocket/tst_qbluetoothsocket.cpp
+@@ -142,7 +142,7 @@ void tst_QBluetoothSocket::initTestCase()
+ qDebug() << "Starting discovery";
+
+ sda->setUuidFilter(QBluetoothUuid(QString(TEST_SERVICE_UUID)));
+- sda->start(QBluetoothServiceDiscoveryAgent::MinimalDiscovery);
++ sda->start(QBluetoothServiceDiscoveryAgent::FullDiscovery);
+
+ for (int connectTime = MaxConnectTime; !done_discovery && connectTime > 0; connectTime -= 1000)
+ QTest::qWait(1000);
+Submodule qtdeclarative f5701f0d..8defe7bf:
+diff --git a/qtdeclarative/src/qml/common/qqmljsfixedpoolarray_p.h b/qtdeclarative/src/qml/common/qqmljsfixedpoolarray_p.h
+index b65b994d6c..15a8cd6878 100644
+--- a/qtdeclarative/src/qml/common/qqmljsfixedpoolarray_p.h
++++ b/qtdeclarative/src/qml/common/qqmljsfixedpoolarray_p.h
+@@ -86,7 +86,7 @@ public:
+ if (QTypeInfo<T>::isComplex) {
+ for (int i = 0; i < count; ++i)
+ new (data + i) T(vector.at(i));
+- } else {
++ } else if (count) {
+ memcpy(data, static_cast<const void*>(vector.constData()), count * sizeof(T));
+ }
+ }
+diff --git a/qtdeclarative/src/qml/jsruntime/qv4qobjectwrapper.cpp b/qtdeclarative/src/qml/jsruntime/qv4qobjectwrapper.cpp
+index e57cdd8278..94613598af 100644
+--- a/qtdeclarative/src/qml/jsruntime/qv4qobjectwrapper.cpp
++++ b/qtdeclarative/src/qml/jsruntime/qv4qobjectwrapper.cpp
+@@ -1145,8 +1145,7 @@ void Heap::QObjectWrapper::markObjects(Heap::Base *that, QV4::MarkStack *markSta
+ void QObjectWrapper::destroyObject(bool lastCall)
+ {
+ Heap::QObjectWrapper *h = d();
+- if (!h->internalClass)
+- return; // destroyObject already got called
++ Q_ASSERT(h->internalClass);
+
+ if (h->object()) {
+ QQmlData *ddata = QQmlData::get(h->object(), false);
+@@ -1176,7 +1175,7 @@ void QObjectWrapper::destroyObject(bool lastCall)
+ }
+ }
+
+- h->~Data();
++ h->destroy();
+ }
+
+
+diff --git a/qtdeclarative/src/qml/memory/qv4mm.cpp b/qtdeclarative/src/qml/memory/qv4mm.cpp
+index 06caf04e5a..da149a67c4 100644
+--- a/qtdeclarative/src/qml/memory/qv4mm.cpp
++++ b/qtdeclarative/src/qml/memory/qv4mm.cpp
+@@ -981,7 +981,7 @@ void MemoryManager::sweep(bool lastSweep, ClassDestroyStatsCallback classCountPt
+
+ if (MultiplyWrappedQObjectMap *multiplyWrappedQObjects = engine->m_multiplyWrappedQObjects) {
+ for (MultiplyWrappedQObjectMap::Iterator it = multiplyWrappedQObjects->begin(); it != multiplyWrappedQObjects->end();) {
+- if (!it.value().isNullOrUndefined())
++ if (it.value().isNullOrUndefined())
+ it = multiplyWrappedQObjects->erase(it);
+ else
+ ++it;
+diff --git a/qtdeclarative/src/qmlmodels/qqmldelegatemodel.cpp b/qtdeclarative/src/qmlmodels/qqmldelegatemodel.cpp
+index 2079a8ed04..a577cb2351 100644
+--- a/qtdeclarative/src/qmlmodels/qqmldelegatemodel.cpp
++++ b/qtdeclarative/src/qmlmodels/qqmldelegatemodel.cpp
+@@ -389,6 +389,12 @@ void QQmlDelegateModelPrivate::connectToAbstractItemModel()
+ q, QQmlDelegateModel, SLOT(_q_rowsRemoved(QModelIndex,int,int)));
+ qmlobject_connect(aim, QAbstractItemModel, SIGNAL(rowsAboutToBeRemoved(QModelIndex,int,int)),
+ q, QQmlDelegateModel, SLOT(_q_rowsAboutToBeRemoved(QModelIndex,int,int)));
++ qmlobject_connect(aim, QAbstractItemModel, SIGNAL(columnsInserted(QModelIndex,int,int)),
++ q, QQmlDelegateModel, SLOT(_q_columnsInserted(QModelIndex,int,int)));
++ qmlobject_connect(aim, QAbstractItemModel, SIGNAL(columnsRemoved(QModelIndex,int,int)),
++ q, QQmlDelegateModel, SLOT(_q_columnsRemoved(QModelIndex,int,int)));
++ qmlobject_connect(aim, QAbstractItemModel, SIGNAL(columnsMoved(QModelIndex,int,int,QModelIndex,int)),
++ q, QQmlDelegateModel, SLOT(_q_columnsMoved(QModelIndex,int,int,QModelIndex,int)));
+ qmlobject_connect(aim, QAbstractItemModel, SIGNAL(dataChanged(QModelIndex,QModelIndex,QVector<int>)),
+ q, QQmlDelegateModel, SLOT(_q_dataChanged(QModelIndex,QModelIndex,QVector<int>)));
+ qmlobject_connect(aim, QAbstractItemModel, SIGNAL(rowsMoved(QModelIndex,int,int,QModelIndex,int)),
+@@ -413,6 +419,12 @@ void QQmlDelegateModelPrivate::disconnectFromAbstractItemModel()
+ q, SLOT(_q_rowsAboutToBeRemoved(QModelIndex,int,int)));
+ QObject::disconnect(aim, SIGNAL(rowsRemoved(QModelIndex,int,int)),
+ q, SLOT(_q_rowsRemoved(QModelIndex,int,int)));
++ QObject::disconnect(aim, SIGNAL(columnsInserted(QModelIndex,int,int)), q,
++ SLOT(_q_columnsInserted(QModelIndex,int,int)));
++ QObject::disconnect(aim, SIGNAL(columnsRemoved(QModelIndex,int,int)), q,
++ SLOT(_q_columnsRemoved(QModelIndex,int,int)));
++ QObject::disconnect(aim, SIGNAL(columnsMoved(QModelIndex,int,int,QModelIndex,int)), q,
++ SLOT(_q_columnsMoved(QModelIndex,int,int,QModelIndex,int)));
+ QObject::disconnect(aim, SIGNAL(dataChanged(QModelIndex,QModelIndex,QVector<int>)),
+ q, SLOT(_q_dataChanged(QModelIndex,QModelIndex,QVector<int>)));
+ QObject::disconnect(aim, SIGNAL(rowsMoved(QModelIndex,int,int,QModelIndex,int)),
+@@ -1973,6 +1985,38 @@ void QQmlDelegateModel::_q_rowsMoved(
+ }
+ }
+
++void QQmlDelegateModel::_q_columnsInserted(const QModelIndex &parent, int begin, int end)
++{
++ Q_D(QQmlDelegateModel);
++ Q_UNUSED(end);
++ if (parent == d->m_adaptorModel.rootIndex && begin == 0) {
++ // mark all items as changed
++ _q_itemsChanged(0, d->m_count, QVector<int>());
++ }
++}
++
++void QQmlDelegateModel::_q_columnsRemoved(const QModelIndex &parent, int begin, int end)
++{
++ Q_D(QQmlDelegateModel);
++ Q_UNUSED(end);
++ if (parent == d->m_adaptorModel.rootIndex && begin == 0) {
++ // mark all items as changed
++ _q_itemsChanged(0, d->m_count, QVector<int>());
++ }
++}
++
++void QQmlDelegateModel::_q_columnsMoved(const QModelIndex &parent, int start, int end,
++ const QModelIndex &destination, int column)
++{
++ Q_D(QQmlDelegateModel);
++ Q_UNUSED(end);
++ if ((parent == d->m_adaptorModel.rootIndex && start == 0)
++ || (destination == d->m_adaptorModel.rootIndex && column == 0)) {
++ // mark all items as changed
++ _q_itemsChanged(0, d->m_count, QVector<int>());
++ }
++}
++
+ void QQmlDelegateModel::_q_dataChanged(const QModelIndex &begin, const QModelIndex &end, const QVector<int> &roles)
+ {
+ Q_D(QQmlDelegateModel);
+diff --git a/qtdeclarative/src/qmlmodels/qqmldelegatemodel_p.h b/qtdeclarative/src/qmlmodels/qqmldelegatemodel_p.h
+index 8aab4badca..d140bfbaaf 100644
+--- a/qtdeclarative/src/qmlmodels/qqmldelegatemodel_p.h
++++ b/qtdeclarative/src/qmlmodels/qqmldelegatemodel_p.h
+@@ -152,6 +152,9 @@ private Q_SLOTS:
+ void _q_itemsMoved(int from, int to, int count);
+ void _q_modelReset();
+ void _q_rowsInserted(const QModelIndex &,int,int);
++ void _q_columnsInserted(const QModelIndex &, int, int);
++ void _q_columnsRemoved(const QModelIndex &, int, int);
++ void _q_columnsMoved(const QModelIndex &, int, int, const QModelIndex &, int);
+ void _q_rowsAboutToBeRemoved(const QModelIndex &parent, int begin, int end);
+ void _q_rowsRemoved(const QModelIndex &,int,int);
+ void _q_rowsMoved(const QModelIndex &, int, int, const QModelIndex &, int);
+diff --git a/qtdeclarative/src/quick/accessible/qaccessiblequickitem.cpp b/qtdeclarative/src/quick/accessible/qaccessiblequickitem.cpp
+index 85719fdc80..78e2ab302c 100644
+--- a/qtdeclarative/src/quick/accessible/qaccessiblequickitem.cpp
++++ b/qtdeclarative/src/quick/accessible/qaccessiblequickitem.cpp
+@@ -46,6 +46,7 @@
+ #include "QtQuick/private/qquicktextinput_p.h"
+ #include "QtQuick/private/qquickaccessibleattached_p.h"
+ #include "QtQuick/qquicktextdocument.h"
++#include "QtQuick/qquickrendercontrol.h"
+ QT_BEGIN_NAMESPACE
+
+ #if QT_CONFIG(accessibility)
+@@ -57,7 +58,19 @@ QAccessibleQuickItem::QAccessibleQuickItem(QQuickItem *item)
+
+ QWindow *QAccessibleQuickItem::window() const
+ {
+- return item()->window();
++ QQuickWindow *window = item()->window();
++
++ // For QQuickWidget the above window will be the offscreen QQuickWindow,
++ // which is not a part of the accessibility tree. Detect this case and
++ // return the window for the QQuickWidget instead.
++ if (window && !window->handle()) {
++ if (QQuickRenderControl *renderControl = QQuickWindowPrivate::get(window)->renderControl) {
++ if (QWindow *renderWindow = renderControl->renderWindow(nullptr))
++ return renderWindow;
++ }
++ }
++
++ return window;
+ }
+
+ int QAccessibleQuickItem::childCount() const
+@@ -113,19 +126,15 @@ QAccessibleInterface *QAccessibleQuickItem::childAt(int x, int y) const
+ QAccessibleInterface *QAccessibleQuickItem::parent() const
+ {
+ QQuickItem *parent = item()->parentItem();
+- QQuickWindow *window = item()->window();
+- QQuickItem *ci = window ? window->contentItem() : nullptr;
++ QQuickWindow *itemWindow = item()->window();
++ QQuickItem *ci = itemWindow ? itemWindow->contentItem() : nullptr;
+ while (parent && !QQuickItemPrivate::get(parent)->isAccessible && parent != ci)
+ parent = parent->parentItem();
+
+ if (parent) {
+ if (parent == ci) {
+- // Jump out to the scene widget if the parent is the root item.
+- // There are two root items, QQuickWindow::rootItem and
+- // QQuickView::declarativeRoot. The former is the true root item,
+- // but is not a part of the accessibility tree. Check if we hit
+- // it here and return an interface for the scene instead.
+- return QAccessible::queryAccessibleInterface(window);
++ // Jump out to the window if the parent is the root item
++ return QAccessible::queryAccessibleInterface(window());
+ } else {
+ while (parent && !parent->d_func()->isAccessible)
+ parent = parent->parentItem();
+@@ -188,7 +197,7 @@ QAccessible::State QAccessibleQuickItem::state() const
+ QRect viewRect_ = viewRect();
+ QRect itemRect = rect();
+
+- if (viewRect_.isNull() || itemRect.isNull() || !item()->window() || !item()->window()->isVisible() ||!item()->isVisible() || qFuzzyIsNull(item()->opacity()))
++ if (viewRect_.isNull() || itemRect.isNull() || !window() || !window()->isVisible() ||!item()->isVisible() || qFuzzyIsNull(item()->opacity()))
+ state.invisible = true;
+ if (!viewRect_.intersects(itemRect))
+ state.offscreen = true;
+@@ -201,6 +210,10 @@ QAccessible::State QAccessibleQuickItem::state() const
+ if (role() == QAccessible::EditableText)
+ if (auto ti = qobject_cast<QQuickTextInput *>(item()))
+ state.passwordEdit = ti->echoMode() != QQuickTextInput::Normal;
++ if (!item()->isEnabled()) {
++ state.focusable = false;
++ state.disabled = true;
++ }
+ return state;
+ }
+
+diff --git a/qtdeclarative/src/quick/accessible/qaccessiblequickview_p.h b/qtdeclarative/src/quick/accessible/qaccessiblequickview_p.h
+index 39ffcaf39c..8baa01330c 100644
+--- a/qtdeclarative/src/quick/accessible/qaccessiblequickview_p.h
++++ b/qtdeclarative/src/quick/accessible/qaccessiblequickview_p.h
+@@ -58,7 +58,7 @@ QT_BEGIN_NAMESPACE
+
+ #if QT_CONFIG(accessibility)
+
+-class QAccessibleQuickWindow : public QAccessibleObject
++class Q_QUICK_EXPORT QAccessibleQuickWindow : public QAccessibleObject
+ {
+ public:
+ QAccessibleQuickWindow(QQuickWindow *object);
+diff --git a/qtdeclarative/src/quick/items/qquickdrag.cpp b/qtdeclarative/src/quick/items/qquickdrag.cpp
+index 8321fcfeed..383078b3b9 100644
+--- a/qtdeclarative/src/quick/items/qquickdrag.cpp
++++ b/qtdeclarative/src/quick/items/qquickdrag.cpp
+@@ -481,7 +481,9 @@ void QQuickDragAttached::setKeys(const QStringList &keys)
+ \qmlattachedproperty stringlist QtQuick::Drag::mimeData
+ \since 5.2
+
+- This property holds a map of mimeData that is used during startDrag.
++ This property holds a map from mime type to data that is used during startDrag.
++ The mime data needs to be a \c string, or an \c ArrayBuffer with the data encoded
++ according to the mime type.
+ */
+
+ QVariantMap QQuickDragAttached::mimeData() const
+@@ -766,8 +768,12 @@ Qt::DropAction QQuickDragAttachedPrivate::startDrag(Qt::DropActions supportedAct
+ QDrag *drag = new QDrag(source ? source : q);
+ QMimeData *mimeData = new QMimeData();
+
+- for (auto it = externalMimeData.cbegin(), end = externalMimeData.cend(); it != end; ++it)
+- mimeData->setData(it.key(), it.value().toString().toUtf8());
++ for (auto it = externalMimeData.cbegin(), end = externalMimeData.cend(); it != end; ++it) {
++ if (static_cast<QMetaType::Type>(it.value().type()) == QMetaType::QByteArray)
++ mimeData->setData(it.key(), it.value().toByteArray());
++ else
++ mimeData->setData(it.key(), it.value().toString().toUtf8());
++ }
+
+ drag->setMimeData(mimeData);
+ if (pixmapLoader.isReady()) {
+diff --git a/qtdeclarative/src/quick/items/qquickitem.cpp b/qtdeclarative/src/quick/items/qquickitem.cpp
+index 75f1457816..dec0ae19ae 100644
+--- a/qtdeclarative/src/quick/items/qquickitem.cpp
++++ b/qtdeclarative/src/quick/items/qquickitem.cpp
+@@ -59,6 +59,7 @@
+ #include <QtCore/private/qnumeric_p.h>
+ #include <QtGui/qpa/qplatformtheme.h>
+ #include <QtCore/qloggingcategory.h>
++#include <QtCore/private/qduplicatetracker_p.h>
+
+ #include <private/qqmlglobal_p.h>
+ #include <private/qqmlengine_p.h>
+@@ -2326,6 +2327,7 @@ QQuickItem::QQuickItem(QQuickItemPrivate &dd, QQuickItem *parent)
+ QQuickItem::~QQuickItem()
+ {
+ Q_D(QQuickItem);
++ d->inDestructor = true;
+
+ if (d->windowRefCount > 1)
+ d->windowRefCount = 1; // Make sure window is set to null in next call to derefWindow().
+@@ -2526,6 +2528,7 @@ QQuickItem* QQuickItemPrivate::nextPrevItemInTabFocusChain(QQuickItem *item, boo
+ QQuickItem *current = item;
+ qCDebug(DBG_FOCUS) << "QQuickItemPrivate::nextPrevItemInTabFocusChain: startItem:" << startItem;
+ qCDebug(DBG_FOCUS) << "QQuickItemPrivate::nextPrevItemInTabFocusChain: firstFromItem:" << firstFromItem;
++ QDuplicateTracker<QQuickItem *> cycleDetector;
+ do {
+ qCDebug(DBG_FOCUS) << "QQuickItemPrivate::nextPrevItemInTabFocusChain: current:" << current;
+ qCDebug(DBG_FOCUS) << "QQuickItemPrivate::nextPrevItemInTabFocusChain: from:" << from;
+@@ -2592,7 +2595,10 @@ QQuickItem* QQuickItemPrivate::nextPrevItemInTabFocusChain(QQuickItem *item, boo
+ // traversed all of the chain (by compare the [current] item with [startItem])
+ // Since the [startItem] might be promoted to its parent if it is invisible,
+ // we still have to check [current] item with original start item
+- if ((current == startItem || current == originalStartItem) && from == firstFromItem) {
++ // We might also run into a cycle before we reach firstFromItem again
++ // but note that we have to ignore current if we are meant to skip it
++ if (((current == startItem || current == originalStartItem) && from == firstFromItem) ||
++ (!skip && cycleDetector.hasSeen(current))) {
+ // wrapped around, avoid endless loops
+ if (item == contentItem) {
+ qCDebug(DBG_FOCUS) << "QQuickItemPrivate::nextPrevItemInTabFocusChain: looped, return contentItem";
+@@ -2689,9 +2695,8 @@ void QQuickItem::setParentItem(QQuickItem *parentItem)
+
+ const bool wasVisible = isVisible();
+ op->removeChild(this);
+- if (wasVisible) {
++ if (wasVisible && !op->inDestructor)
+ emit oldParentItem->visibleChildrenChanged();
+- }
+ } else if (d->window) {
+ QQuickWindowPrivate::get(d->window)->parentlessItems.remove(this);
+ }
+@@ -2768,8 +2773,9 @@ void QQuickItem::setParentItem(QQuickItem *parentItem)
+
+ d->itemChange(ItemParentHasChanged, d->parentItem);
+
+- emit parentChanged(d->parentItem);
+- if (isVisible() && d->parentItem)
++ if (!d->inDestructor)
++ emit parentChanged(d->parentItem);
++ if (isVisible() && d->parentItem && !QQuickItemPrivate::get(d->parentItem)->inDestructor)
+ emit d->parentItem->visibleChildrenChanged();
+ }
+
+@@ -2965,7 +2971,8 @@ void QQuickItemPrivate::removeChild(QQuickItem *child)
+
+ itemChange(QQuickItem::ItemChildRemovedChange, child);
+
+- emit q->childrenChanged();
++ if (!inDestructor)
++ emit q->childrenChanged();
+ }
+
+ void QQuickItemPrivate::refWindow(QQuickWindow *c)
+@@ -3194,6 +3201,7 @@ QQuickItemPrivate::QQuickItemPrivate()
+ , touchEnabled(false)
+ #endif
+ , hasCursorHandler(false)
++ , inDestructor(false)
+ , dirtyAttributes(0)
+ , nextDirtyItem(nullptr)
+ , prevDirtyItem(nullptr)
+@@ -5120,6 +5128,13 @@ void QQuickItem::componentComplete()
+ d->addToDirtyList();
+ QQuickWindowPrivate::get(d->window)->dirtyItem(this);
+ }
++
++#if QT_CONFIG(accessibility)
++ if (d->isAccessible && d->effectiveVisible) {
++ QAccessibleEvent ev(this, QAccessible::ObjectShow);
++ QAccessible::updateAccessibility(&ev);
++ }
++#endif
+ }
+
+ QQuickStateGroup *QQuickItemPrivate::_states()
+@@ -6106,9 +6121,11 @@ bool QQuickItemPrivate::setEffectiveVisibleRecur(bool newEffectiveVisible)
+ QAccessible::updateAccessibility(&ev);
+ }
+ #endif
+- emit q->visibleChanged();
+- if (childVisibilityChanged)
+- emit q->visibleChildrenChanged();
++ if (!inDestructor) {
++ emit q->visibleChanged();
++ if (childVisibilityChanged)
++ emit q->visibleChildrenChanged();
++ }
+
+ return true; // effective visibility DID change
+ }
+@@ -6157,6 +6174,15 @@ void QQuickItemPrivate::setEffectiveEnableRecur(QQuickItem *scope, bool newEffec
+ }
+
+ itemChange(QQuickItem::ItemEnabledHasChanged, effectiveEnable);
++#if QT_CONFIG(accessibility)
++ if (isAccessible) {
++ QAccessible::State changedState;
++ changedState.disabled = true;
++ changedState.focusable = true;
++ QAccessibleStateChangeEvent ev(q, changedState);
++ QAccessible::updateAccessibility(&ev);
++ }
++#endif
+ emit q->enabledChanged();
+ }
+
+diff --git a/qtdeclarative/src/quick/items/qquickitem_p.h b/qtdeclarative/src/quick/items/qquickitem_p.h
+index 841d91bb40..ade8fb61f2 100644
+--- a/qtdeclarative/src/quick/items/qquickitem_p.h
++++ b/qtdeclarative/src/quick/items/qquickitem_p.h
+@@ -472,6 +472,7 @@ public:
+ bool replayingPressEvent:1;
+ bool touchEnabled:1;
+ bool hasCursorHandler:1;
++ quint32 inDestructor:1; // has entered ~QQuickItem
+
+ enum DirtyType {
+ TransformOrigin = 0x00000001,
+diff --git a/qtdeclarative/src/quick/items/qquickitemview.cpp b/qtdeclarative/src/quick/items/qquickitemview.cpp
+index 010a0152e1..f8ad168a17 100644
+--- a/qtdeclarative/src/quick/items/qquickitemview.cpp
++++ b/qtdeclarative/src/quick/items/qquickitemview.cpp
+@@ -1785,7 +1785,7 @@ void QQuickItemViewPrivate::refill(qreal from, qreal to)
+
+ do {
+ bufferPause.stop();
+- if (currentChanges.hasPendingChanges() || bufferedChanges.hasPendingChanges()) {
++ if (currentChanges.hasPendingChanges() || bufferedChanges.hasPendingChanges() || currentChanges.active) {
+ currentChanges.reset();
+ bufferedChanges.reset();
+ releaseVisibleItems(reusableFlag);
+diff --git a/qtdeclarative/src/quick/items/qquickmousearea_p_p.h b/qtdeclarative/src/quick/items/qquickmousearea_p_p.h
+index fba383e268..0d63618622 100644
+--- a/qtdeclarative/src/quick/items/qquickmousearea_p_p.h
++++ b/qtdeclarative/src/quick/items/qquickmousearea_p_p.h
+@@ -61,7 +61,6 @@ QT_BEGIN_NAMESPACE
+
+ class QQuickMouseEvent;
+ class QQuickMouseArea;
+-class QQuickPointerMask;
+ class QQuickMouseAreaPrivate : public QQuickItemPrivate
+ {
+ Q_DECLARE_PUBLIC(QQuickMouseArea)
+@@ -100,7 +99,6 @@ public:
+ #if QT_CONFIG(quick_draganddrop)
+ QQuickDrag *drag;
+ #endif
+- QPointer<QQuickPointerMask> mask;
+ QPointF startScene;
+ QPointF targetStartPos;
+ QPointF lastPos;
+diff --git a/qtdeclarative/src/quick/items/qquicktext.cpp b/qtdeclarative/src/quick/items/qquicktext.cpp
+index 6230186933..e823ca1095 100644
+--- a/qtdeclarative/src/quick/items/qquicktext.cpp
++++ b/qtdeclarative/src/quick/items/qquicktext.cpp
+@@ -2168,7 +2168,7 @@ void QQuickText::resetMaximumLineCount()
+ <img src="" align="top,middle,bottom" width="" height=""> - inline images
+ <ol type="">, <ul type=""> and <li> - ordered and unordered lists
+ <pre></pre> - preformatted
+- > < &
++ > < & " '
+ \endcode
+
+ \c Text.StyledText parser is strict, requiring tags to be correctly nested.
+diff --git a/qtdeclarative/src/quick/scenegraph/qsgrhidistancefieldglyphcache.cpp b/qtdeclarative/src/quick/scenegraph/qsgrhidistancefieldglyphcache.cpp
+index eb4db0f85e..2325a2665b 100644
+--- a/qtdeclarative/src/quick/scenegraph/qsgrhidistancefieldglyphcache.cpp
++++ b/qtdeclarative/src/quick/scenegraph/qsgrhidistancefieldglyphcache.cpp
+@@ -446,7 +446,7 @@ bool QSGRhiDistanceFieldGlyphCache::loadPregeneratedCache(const QRawFont &font)
+
+ const char *textureRecord = allocatorData;
+ for (int i = 0; i < textureCount; ++i, textureRecord += Qtdf::TextureRecordSize) {
+- if (textureRecord + Qtdf::TextureRecordSize > qtdfTableEnd) {
++ if (qtdfTableEnd - textureRecord < Qtdf::TextureRecordSize) {
+ qWarning("qtdf table too small in font '%s'.",
+ qPrintable(font.familyName()));
+ return false;
+@@ -462,7 +462,7 @@ bool QSGRhiDistanceFieldGlyphCache::loadPregeneratedCache(const QRawFont &font)
+
+ const char *glyphRecord = textureRecord;
+ for (quint32 i = 0; i < glyphCount; ++i, glyphRecord += Qtdf::GlyphRecordSize) {
+- if (glyphRecord + Qtdf::GlyphRecordSize > qtdfTableEnd) {
++ if (qtdfTableEnd - glyphRecord < Qtdf:: GlyphRecordSize) {
+ qWarning("qtdf table too small in font '%s'.",
+ qPrintable(font.familyName()));
+ return false;
+@@ -512,8 +512,8 @@ bool QSGRhiDistanceFieldGlyphCache::loadPregeneratedCache(const QRawFont &font)
+
+ int width = texInfo->allocatedArea.width();
+ int height = texInfo->allocatedArea.height();
+- qint64 size = width * height;
+- if (reinterpret_cast<const char *>(textureData + size) > qtdfTableEnd) {
++ qint64 size = qint64(width) * height;
++ if (qtdfTableEnd - reinterpret_cast<const char *>(textureData) < size) {
+ qWarning("qtdf table too small in font '%s'.",
+ qPrintable(font.familyName()));
+ return false;
+diff --git a/qtdeclarative/src/quick/util/qquickstyledtext.cpp b/qtdeclarative/src/quick/util/qquickstyledtext.cpp
+index d531fc9205..a25af90414 100644
+--- a/qtdeclarative/src/quick/util/qquickstyledtext.cpp
++++ b/qtdeclarative/src/quick/util/qquickstyledtext.cpp
+@@ -564,6 +564,8 @@ void QQuickStyledTextPrivate::parseEntity(const QChar *&ch, const QString &textI
+ textOut += QChar(60);
+ else if (entity == QLatin1String("amp"))
+ textOut += QChar(38);
++ else if (entity == QLatin1String("apos"))
++ textOut += QChar(39);
+ else if (entity == QLatin1String("quot"))
+ textOut += QChar(34);
+ else if (entity == QLatin1String("nbsp"))
+diff --git a/qtdeclarative/src/quickwidgets/qaccessiblequickwidget.cpp b/qtdeclarative/src/quickwidgets/qaccessiblequickwidget.cpp
+new file mode 100644
+index 0000000000..8a1c901880
+--- /dev/null
++++ b/qtdeclarative/src/quickwidgets/qaccessiblequickwidget.cpp
+@@ -0,0 +1,110 @@
++/****************************************************************************
++**
++** Copyright (C) 2021 The Qt Company Ltd.
++** Contact: https://www.qt.io/licensing/
++**
++** This file is part of the QtQuick module of the Qt Toolkit.
++**
++** $QT_BEGIN_LICENSE:LGPL$
++** Commercial License Usage
++** Licensees holding valid commercial Qt licenses may use this file in
++** accordance with the commercial license agreement provided with the
++** Software or, alternatively, in accordance with the terms contained in
++** a written agreement between you and The Qt Company. For licensing terms
++** and conditions see https://www.qt.io/terms-conditions. For further
++** information use the contact form at https://www.qt.io/contact-us.
++**
++** GNU Lesser General Public License Usage
++** Alternatively, this file may be used under the terms of the GNU Lesser
++** General Public License version 3 as published by the Free Software
++** Foundation and appearing in the file LICENSE.LGPL3 included in the
++** packaging of this file. Please review the following information to
++** ensure the GNU Lesser General Public License version 3 requirements
++** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
++**
++** GNU General Public License Usage
++** Alternatively, this file may be used under the terms of the GNU
++** General Public License version 2.0 or (at your option) the GNU General
++** Public license version 3 or any later version approved by the KDE Free
++** Qt Foundation. The licenses are as published by the Free Software
++** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
++** included in the packaging of this file. Please review the following
++** information to ensure the GNU General Public License requirements will
++** be met: https://www.gnu.org/licenses/gpl-2.0.html and
++** https://www.gnu.org/licenses/gpl-3.0.html.
++**
++** $QT_END_LICENSE$
++**
++****************************************************************************/
++
++#include "qaccessiblequickwidget_p.h"
++
++#include "qquickwidget_p.h"
++
++QT_BEGIN_NAMESPACE
++
++#if QT_CONFIG(accessibility)
++
++QAccessibleQuickWidget::QAccessibleQuickWidget(QQuickWidget* widget)
++: QAccessibleWidget(widget)
++, m_accessibleWindow(QQuickWidgetPrivate::get(widget)->offscreenWindow)
++{
++ // NOTE: m_accessibleWindow is a QAccessibleQuickWindow, and not a
++ // QAccessibleQuickWidgetOffscreenWindow (defined below). This means
++ // it will return the Quick item child interfaces, which is what's needed here
++ // (unlike QAccessibleQuickWidgetOffscreenWindow, which will report 0 children).
++}
++
++QAccessibleInterface *QAccessibleQuickWidget::child(int index) const
++{
++ return m_accessibleWindow.child(index);
++}
++
++int QAccessibleQuickWidget::childCount() const
++{
++ return m_accessibleWindow.childCount();
++}
++
++int QAccessibleQuickWidget::indexOfChild(const QAccessibleInterface *iface) const
++{
++ return m_accessibleWindow.indexOfChild(iface);
++}
++
++QAccessibleInterface *QAccessibleQuickWidget::childAt(int x, int y) const
++{
++ return m_accessibleWindow.childAt(x, y);
++}
++
++QAccessibleQuickWidgetOffscreenWindow::QAccessibleQuickWidgetOffscreenWindow(QQuickWindow *window)
++:QAccessibleQuickWindow(window)
++{
++
++}
++
++QAccessibleInterface *QAccessibleQuickWidgetOffscreenWindow::child(int index) const
++{
++ Q_UNUSED(index);
++ return nullptr;
++}
++
++int QAccessibleQuickWidgetOffscreenWindow::childCount() const
++{
++ return 0;
++}
++
++int QAccessibleQuickWidgetOffscreenWindow::indexOfChild(const QAccessibleInterface *iface) const
++{
++ Q_UNUSED(iface);
++ return -1;
++}
++
++QAccessibleInterface *QAccessibleQuickWidgetOffscreenWindow::QAccessibleQuickWidgetOffscreenWindow::childAt(int x, int y) const
++{
++ Q_UNUSED(x);
++ Q_UNUSED(y);
++ return nullptr;
++}
++
++#endif // accessibility
++
++QT_END_NAMESPACE
+diff --git a/qtdeclarative/src/quickwidgets/qaccessiblequickwidget_p.h b/qtdeclarative/src/quickwidgets/qaccessiblequickwidget_p.h
+new file mode 100644
+index 0000000000..7c2ab930e0
+--- /dev/null
++++ b/qtdeclarative/src/quickwidgets/qaccessiblequickwidget_p.h
+@@ -0,0 +1,95 @@
++/****************************************************************************
++**
++** Copyright (C) 2021 The Qt Company Ltd.
++** Contact: https://www.qt.io/licensing/
++**
++** This file is part of the QtQuick module of the Qt Toolkit.
++**
++** $QT_BEGIN_LICENSE:LGPL$
++** Commercial License Usage
++** Licensees holding valid commercial Qt licenses may use this file in
++** accordance with the commercial license agreement provided with the
++** Software or, alternatively, in accordance with the terms contained in
++** a written agreement between you and The Qt Company. For licensing terms
++** and conditions see https://www.qt.io/terms-conditions. For further
++** information use the contact form at https://www.qt.io/contact-us.
++**
++** GNU Lesser General Public License Usage
++** Alternatively, this file may be used under the terms of the GNU Lesser
++** General Public License version 3 as published by the Free Software
++** Foundation and appearing in the file LICENSE.LGPL3 included in the
++** packaging of this file. Please review the following information to
++** ensure the GNU Lesser General Public License version 3 requirements
++** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
++**
++** GNU General Public License Usage
++** Alternatively, this file may be used under the terms of the GNU
++** General Public License version 2.0 or (at your option) the GNU General
++** Public license version 3 or any later version approved by the KDE Free
++** Qt Foundation. The licenses are as published by the Free Software
++** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
++** included in the packaging of this file. Please review the following
++** information to ensure the GNU General Public License requirements will
++** be met: https://www.gnu.org/licenses/gpl-2.0.html and
++** https://www.gnu.org/licenses/gpl-3.0.html.
++**
++** $QT_END_LICENSE$
++**
++****************************************************************************/
++
++#ifndef QACCESSIBLEQUICKWIDGET_H
++#define QACCESSIBLEQUICKWIDGET_H
++
++//
++// W A R N I N G
++// -------------
++//
++// This file is not part of the Qt API. It exists purely as an
++// implementation detail. This header file may change from version to
++// version without notice, or even be removed.
++//
++// We mean it.
++//
++
++#include "qquickwidget.h"
++#include <QtWidgets/qaccessiblewidget.h>
++
++#include <private/qaccessiblequickview_p.h>
++
++QT_BEGIN_NAMESPACE
++
++#if QT_CONFIG(accessibility)
++
++// These classes implement the QQuickWiget accessibility switcharoo,
++// where the child items of the QQuickWidgetOffscreenWindow are reported
++// as child accessible interfaces of the QAccessibleQuickWidget.
++class QAccessibleQuickWidget: public QAccessibleWidget
++{
++public:
++ QAccessibleQuickWidget(QQuickWidget* widget);
++
++ QAccessibleInterface *child(int index) const override;
++ int childCount() const override;
++ int indexOfChild(const QAccessibleInterface *iface) const override;
++ QAccessibleInterface *childAt(int x, int y) const override;
++
++private:
++ QAccessibleQuickWindow m_accessibleWindow;
++ Q_DISABLE_COPY(QAccessibleQuickWidget)
++};
++
++class QAccessibleQuickWidgetOffscreenWindow: public QAccessibleQuickWindow
++{
++public:
++ QAccessibleQuickWidgetOffscreenWindow(QQuickWindow *window);
++ QAccessibleInterface *child(int index) const override;
++ int childCount() const override;
++ int indexOfChild(const QAccessibleInterface *iface) const override;
++ QAccessibleInterface *childAt(int x, int y) const override;
++};
++
++#endif // accessibility
++
++QT_END_NAMESPACE
++
++#endif
+diff --git a/qtdeclarative/src/quickwidgets/qaccessiblequickwidgetfactory.cpp b/qtdeclarative/src/quickwidgets/qaccessiblequickwidgetfactory.cpp
+new file mode 100644
+index 0000000000..7ba88a1769
+--- /dev/null
++++ b/qtdeclarative/src/quickwidgets/qaccessiblequickwidgetfactory.cpp
+@@ -0,0 +1,60 @@
++/****************************************************************************
++**
++** Copyright (C) 2021 The Qt Company Ltd.
++** Contact: https://www.qt.io/licensing/
++**
++** This file is part of the QtQuick module of the Qt Toolkit.
++**
++** $QT_BEGIN_LICENSE:LGPL$
++** Commercial License Usage
++** Licensees holding valid commercial Qt licenses may use this file in
++** accordance with the commercial license agreement provided with the
++** Software or, alternatively, in accordance with the terms contained in
++** a written agreement between you and The Qt Company. For licensing terms
++** and conditions see https://www.qt.io/terms-conditions. For further
++** information use the contact form at https://www.qt.io/contact-us.
++**
++** GNU Lesser General Public License Usage
++** Alternatively, this file may be used under the terms of the GNU Lesser
++** General Public License version 3 as published by the Free Software
++** Foundation and appearing in the file LICENSE.LGPL3 included in the
++** packaging of this file. Please review the following information to
++** ensure the GNU Lesser General Public License version 3 requirements
++** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
++**
++** GNU General Public License Usage
++** Alternatively, this file may be used under the terms of the GNU
++** General Public License version 2.0 or (at your option) the GNU General
++** Public license version 3 or any later version approved by the KDE Free
++** Qt Foundation. The licenses are as published by the Free Software
++** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
++** included in the packaging of this file. Please review the following
++** information to ensure the GNU General Public License requirements will
++** be met: https://www.gnu.org/licenses/gpl-2.0.html and
++** https://www.gnu.org/licenses/gpl-3.0.html.
++**
++** $QT_END_LICENSE$
++**
++****************************************************************************/
++
++#include "qaccessiblequickwidgetfactory_p.h"
++#include "qaccessiblequickwidget_p.h"
++
++QT_BEGIN_NAMESPACE
++
++#if QT_CONFIG(accessibility)
++
++QAccessibleInterface *qAccessibleQuickWidgetFactory(const QString &classname, QObject *object)
++{
++ if (classname == QLatin1String("QQuickWidget")) {
++ return new QAccessibleQuickWidget(qobject_cast<QQuickWidget *>(object));
++ } else if (classname == QLatin1String("QQuickWidgetOffscreenWindow")) {
++ return new QAccessibleQuickWidgetOffscreenWindow(qobject_cast<QQuickWindow *>(object));
++ }
++ return 0;
++}
++
++#endif // accessibility
++
++QT_END_NAMESPACE
++
+diff --git a/qtdeclarative/src/quickwidgets/qaccessiblequickwidgetfactory_p.h b/qtdeclarative/src/quickwidgets/qaccessiblequickwidgetfactory_p.h
+new file mode 100644
+index 0000000000..8c63b09f81
+--- /dev/null
++++ b/qtdeclarative/src/quickwidgets/qaccessiblequickwidgetfactory_p.h
+@@ -0,0 +1,66 @@
++/****************************************************************************
++**
++** Copyright (C) 2021 The Qt Company Ltd.
++** Contact: https://www.qt.io/licensing/
++**
++** This file is part of the QtQuick module of the Qt Toolkit.
++**
++** $QT_BEGIN_LICENSE:LGPL$
++** Commercial License Usage
++** Licensees holding valid commercial Qt licenses may use this file in
++** accordance with the commercial license agreement provided with the
++** Software or, alternatively, in accordance with the terms contained in
++** a written agreement between you and The Qt Company. For licensing terms
++** and conditions see https://www.qt.io/terms-conditions. For further
++** information use the contact form at https://www.qt.io/contact-us.
++**
++** GNU Lesser General Public License Usage
++** Alternatively, this file may be used under the terms of the GNU Lesser
++** General Public License version 3 as published by the Free Software
++** Foundation and appearing in the file LICENSE.LGPL3 included in the
++** packaging of this file. Please review the following information to
++** ensure the GNU Lesser General Public License version 3 requirements
++** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
++**
++** GNU General Public License Usage
++** Alternatively, this file may be used under the terms of the GNU
++** General Public License version 2.0 or (at your option) the GNU General
++** Public license version 3 or any later version approved by the KDE Free
++** Qt Foundation. The licenses are as published by the Free Software
++** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
++** included in the packaging of this file. Please review the following
++** information to ensure the GNU General Public License requirements will
++** be met: https://www.gnu.org/licenses/gpl-2.0.html and
++** https://www.gnu.org/licenses/gpl-3.0.html.
++**
++** $QT_END_LICENSE$
++**
++****************************************************************************/
++
++#include <QtGui/qaccessible.h>
++
++#ifndef QACCESSIBLEQUICKWIDGETFACTORY_H
++#define QACCESSIBLEQUICKWIDGETFACTORY_H
++
++//
++// W A R N I N G
++// -------------
++//
++// This file is not part of the Qt API. It exists purely as an
++// implementation detail. This header file may change from version to
++// version without notice, or even be removed.
++//
++// We mean it.
++//
++
++QT_BEGIN_NAMESPACE
++
++#if QT_CONFIG(accessibility)
++
++QAccessibleInterface *qAccessibleQuickWidgetFactory(const QString &classname, QObject *object);
++
++#endif
++
++QT_END_NAMESPACE
++
++#endif
+diff --git a/qtdeclarative/src/quickwidgets/qquickwidget.cpp b/qtdeclarative/src/quickwidgets/qquickwidget.cpp
+index 39780f8de3..9c97b43518 100644
+--- a/qtdeclarative/src/quickwidgets/qquickwidget.cpp
++++ b/qtdeclarative/src/quickwidgets/qquickwidget.cpp
+@@ -39,6 +39,7 @@
+
+ #include "qquickwidget.h"
+ #include "qquickwidget_p.h"
++#include "qaccessiblequickwidgetfactory_p.h"
+
+ #include "private/qquickwindow_p.h"
+ #include "private/qquickitem_p.h"
+@@ -75,9 +76,16 @@
+
+ QT_BEGIN_NAMESPACE
+
++QQuickWidgetOffscreenWindow::QQuickWidgetOffscreenWindow(QQuickWindowPrivate &dd, QQuickRenderControl *control)
++:QQuickWindow(dd, control)
++{
++ setTitle(QString::fromLatin1("Offscreen"));
++ setObjectName(QString::fromLatin1("QQuickOffScreenWindow"));
++}
++
+ // override setVisble to prevent accidental offscreen window being created
+ // by base class.
+-class QQuickOffcreenWindowPrivate: public QQuickWindowPrivate {
++class QQuickWidgetOffscreenWindowPrivate: public QQuickWindowPrivate {
+ public:
+ void setVisible(bool visible) override {
+ Q_Q(QWindow);
+@@ -105,9 +113,8 @@ void QQuickWidgetPrivate::init(QQmlEngine* e)
+ Q_Q(QQuickWidget);
+
+ renderControl = new QQuickWidgetRenderControl(q);
+- offscreenWindow = new QQuickWindow(*new QQuickOffcreenWindowPrivate(),renderControl);
+- offscreenWindow->setTitle(QString::fromLatin1("Offscreen"));
+- offscreenWindow->setObjectName(QString::fromLatin1("QQuickOffScreenWindow"));
++ offscreenWindow = new QQuickWidgetOffscreenWindow(*new QQuickWidgetOffscreenWindowPrivate(), renderControl);
++ offscreenWindow->setScreen(q->screen());
+ // Do not call create() on offscreenWindow.
+
+ // Check if the Software Adaptation is being used
+@@ -138,6 +145,10 @@ void QQuickWidgetPrivate::init(QQmlEngine* e)
+ QWidget::connect(offscreenWindow, &QQuickWindow::focusObjectChanged, q, &QQuickWidget::propagateFocusObjectChanged);
+ QObject::connect(renderControl, SIGNAL(renderRequested()), q, SLOT(triggerUpdate()));
+ QObject::connect(renderControl, SIGNAL(sceneChanged()), q, SLOT(triggerUpdate()));
++
++#if QT_CONFIG(accessibility)
++ QAccessible::installFactory(&qAccessibleQuickWidgetFactory);
++#endif
+ }
+
+ void QQuickWidgetPrivate::ensureEngine() const
+@@ -901,9 +912,7 @@ void QQuickWidgetPrivate::createContext()
+
+ context = new QOpenGLContext;
+ context->setFormat(offscreenWindow->requestedFormat());
+- const QWindow *win = q->window()->windowHandle();
+- if (win && win->screen())
+- context->setScreen(win->screen());
++ context->setScreen(q->screen());
+ QOpenGLContext *shareContext = qt_gl_global_share_context();
+ if (!shareContext)
+ shareContext = QWidgetPrivate::get(q->window())->shareContext();
+@@ -1520,19 +1529,16 @@ bool QQuickWidget::event(QEvent *e)
+ d->handleWindowChange();
+ break;
+
+- case QEvent::ScreenChangeInternal:
+- if (QWindow *window = this->window()->windowHandle()) {
+- QScreen *newScreen = window->screen();
+-
+- if (d->offscreenWindow)
+- d->offscreenWindow->setScreen(newScreen);
+- if (d->offscreenSurface)
+- d->offscreenSurface->setScreen(newScreen);
++ case QEvent::ScreenChangeInternal: {
++ QScreen *newScreen = screen();
++ if (d->offscreenWindow)
++ d->offscreenWindow->setScreen(newScreen);
++ if (d->offscreenSurface)
++ d->offscreenSurface->setScreen(newScreen);
+ #if QT_CONFIG(opengl)
+- if (d->context)
+- d->context->setScreen(newScreen);
++ if (d->context)
++ d->context->setScreen(newScreen);
+ #endif
+- }
+
+ if (d->useSoftwareRenderer
+ #if QT_CONFIG(opengl)
+@@ -1545,7 +1551,7 @@ bool QQuickWidget::event(QEvent *e)
+ d->render(true);
+ }
+ break;
+-
++ }
+ case QEvent::Show:
+ case QEvent::Move:
+ d->updatePosition();
+diff --git a/qtdeclarative/src/quickwidgets/qquickwidget_p.h b/qtdeclarative/src/quickwidgets/qquickwidget_p.h
+index 881f7f9220..1a946bcc71 100644
+--- a/qtdeclarative/src/quickwidgets/qquickwidget_p.h
++++ b/qtdeclarative/src/quickwidgets/qquickwidget_p.h
+@@ -148,6 +148,14 @@ public:
+ bool forceFullUpdate;
+ };
+
++class QQuickWidgetOffscreenWindow: public QQuickWindow
++{
++ Q_OBJECT
++
++public:
++ QQuickWidgetOffscreenWindow(QQuickWindowPrivate &dd, QQuickRenderControl *control);
++};
++
+ QT_END_NAMESPACE
+
+ #endif // QQuickWidget_P_H
+diff --git a/qtdeclarative/src/quickwidgets/quickwidgets.pro b/qtdeclarative/src/quickwidgets/quickwidgets.pro
+index 2438e577ae..85d156b8a3 100644
+--- a/qtdeclarative/src/quickwidgets/quickwidgets.pro
++++ b/qtdeclarative/src/quickwidgets/quickwidgets.pro
+@@ -7,9 +7,13 @@ DEFINES += QT_NO_URL_CAST_FROM_STRING QT_NO_INTEGER_EVENT_COORDINATES QT_NO_FO
+ HEADERS += \
+ qquickwidget.h \
+ qquickwidget_p.h \
+- qtquickwidgetsglobal.h
++ qtquickwidgetsglobal.h \
++ qaccessiblequickwidget_p.h \
++ qaccessiblequickwidgetfactory_p.h
+
+ SOURCES += \
+- qquickwidget.cpp
++ qquickwidget.cpp \
++ qaccessiblequickwidget.cpp \
++ qaccessiblequickwidgetfactory.cpp
+
+ load(qt_module)
+diff --git a/qtdeclarative/tests/auto/qml/qjsengine/tst_qjsengine.cpp b/qtdeclarative/tests/auto/qml/qjsengine/tst_qjsengine.cpp
+index 3b7d74df63..b75bf820d5 100644
+--- a/qtdeclarative/tests/auto/qml/qjsengine/tst_qjsengine.cpp
++++ b/qtdeclarative/tests/auto/qml/qjsengine/tst_qjsengine.cpp
+@@ -102,6 +102,7 @@ private slots:
+ void valueConversion_RegularExpression();
+ void castWithMultipleInheritance();
+ void collectGarbage();
++ void collectGarbageNestedWrappersTwoEngines();
+ void gcWithNestedDataStructure();
+ void stacktrace();
+ void numberParsing_data();
+@@ -1809,6 +1810,44 @@ void tst_QJSEngine::collectGarbage()
+ QVERIFY(ptr.isNull());
+ }
+
++class TestObjectContainer : public QObject
++{
++ Q_OBJECT
++ Q_PROPERTY(QObject *dummy MEMBER m_dummy CONSTANT)
++
++public:
++ TestObjectContainer() : m_dummy(new QObject(this)) {}
++
++private:
++ QObject *m_dummy;
++};
++
++void tst_QJSEngine::collectGarbageNestedWrappersTwoEngines()
++{
++ QJSEngine engine1;
++ QJSEngine engine2;
++
++ TestObjectContainer container;
++ QQmlEngine::setObjectOwnership(&container, QQmlEngine::CppOwnership);
++
++ engine1.globalObject().setProperty("foobar", engine1.newQObject(&container));
++ engine2.globalObject().setProperty("foobar", engine2.newQObject(&container));
++
++ engine1.evaluate("foobar.dummy.baz = 42");
++ engine2.evaluate("foobar.dummy.baz = 43");
++
++ QCOMPARE(engine1.evaluate("foobar.dummy.baz").toInt(), 42);
++ QCOMPARE(engine2.evaluate("foobar.dummy.baz").toInt(), 43);
++
++ engine1.collectGarbage();
++ engine2.collectGarbage();
++
++ // The GC should not collect dummy object wrappers neither in engine1 nor engine2, we
++ // verify that by checking whether the baz property still has its previous value.
++ QCOMPARE(engine1.evaluate("foobar.dummy.baz").toInt(), 42);
++ QCOMPARE(engine2.evaluate("foobar.dummy.baz").toInt(), 43);
++}
++
+ void tst_QJSEngine::gcWithNestedDataStructure()
+ {
+ // The GC must be able to traverse deeply nested objects, otherwise this
+diff --git a/qtdeclarative/tests/auto/qml/qqmldelegatemodel/data/redrawUponColumnChange.qml b/qtdeclarative/tests/auto/qml/qqmldelegatemodel/data/redrawUponColumnChange.qml
+new file mode 100644
+index 0000000000..206133bb39
+--- /dev/null
++++ b/qtdeclarative/tests/auto/qml/qqmldelegatemodel/data/redrawUponColumnChange.qml
+@@ -0,0 +1,11 @@
++import QtQuick 2.8
++
++ListView {
++ id: root
++ width: 200
++ height: 200
++
++ delegate: Text {
++ text: display
++ }
++}
+diff --git a/qtdeclarative/tests/auto/qml/qqmldelegatemodel/tst_qqmldelegatemodel.cpp b/qtdeclarative/tests/auto/qml/qqmldelegatemodel/tst_qqmldelegatemodel.cpp
+index 35f1e2c94d..1722447830 100644
+--- a/qtdeclarative/tests/auto/qml/qqmldelegatemodel/tst_qqmldelegatemodel.cpp
++++ b/qtdeclarative/tests/auto/qml/qqmldelegatemodel/tst_qqmldelegatemodel.cpp
+@@ -27,6 +27,8 @@
+ ****************************************************************************/
+
+ #include <QtTest/qtest.h>
++#include <QtCore/QConcatenateTablesProxyModel>
++#include <QtGui/QStandardItemModel>
+ #include <QtQml/qqmlcomponent.h>
+ #include <QtQmlModels/private/qqmldelegatemodel_p.h>
+ #include <QtQuick/qquickview.h>
+@@ -47,6 +49,7 @@ private slots:
+ void filterOnGroup_removeWhenCompleted();
+ void qtbug_86017();
+ void contextAccessedByHandler();
++ void redrawUponColumnChange();
+ };
+
+ class AbstractItemModel : public QAbstractItemModel
+@@ -186,6 +189,30 @@ void tst_QQmlDelegateModel::contextAccessedByHandler()
+ QVERIFY(root->property("works").toBool());
+ }
+
++void tst_QQmlDelegateModel::redrawUponColumnChange()
++{
++ QStandardItemModel m1;
++ m1.appendRow({
++ new QStandardItem("Banana"),
++ new QStandardItem("Coconut"),
++ });
++
++ QQuickView view(testFileUrl("redrawUponColumnChange.qml"));
++ QCOMPARE(view.status(), QQuickView::Ready);
++ view.show();
++ QQuickItem *root = view.rootObject();
++ root->setProperty("model", QVariant::fromValue<QObject *>(&m1));
++
++ QObject *item = root->property("currentItem").value<QObject *>();
++ QVERIFY(item);
++ QCOMPARE(item->property("text").toString(), "Banana");
++
++ QVERIFY(root);
++ m1.removeColumn(0);
++
++ QCOMPARE(item->property("text").toString(), "Coconut");
++}
++
+ QTEST_MAIN(tst_QQmlDelegateModel)
+
+ #include "tst_qqmldelegatemodel.moc"
+diff --git a/qtdeclarative/tests/auto/qml/qv4mm/tst_qv4mm.cpp b/qtdeclarative/tests/auto/qml/qv4mm/tst_qv4mm.cpp
+index 5d635aa63b..824fd89e5b 100644
+--- a/qtdeclarative/tests/auto/qml/qv4mm/tst_qv4mm.cpp
++++ b/qtdeclarative/tests/auto/qml/qv4mm/tst_qv4mm.cpp
+@@ -76,10 +76,10 @@ void tst_qv4mm::multiWrappedQObjects()
+ QCOMPARE(engine1.memoryManager->m_pendingFreedObjectWrapperValue.size(), 1);
+ QCOMPARE(engine2.memoryManager->m_pendingFreedObjectWrapperValue.size(), 0);
+
+- // Moves the additional WeakValue from m_multiplyWrappedQObjects to
+- // m_pendingFreedObjectWrapperValue. It's still alive after all.
++ // The additional WeakValue from m_multiplyWrappedQObjects hasn't been moved
++ // to m_pendingFreedObjectWrapperValue yet. It's still alive after all.
+ engine1.memoryManager->runGC();
+- QCOMPARE(engine1.memoryManager->m_pendingFreedObjectWrapperValue.size(), 2);
++ QCOMPARE(engine1.memoryManager->m_pendingFreedObjectWrapperValue.size(), 1);
+
+ // engine2 doesn't own the object as engine1 was the first to wrap it above.
+ // Therefore, no effect here.
+diff --git a/qtdeclarative/tests/auto/quick/qquickitem2/data/activeFocusOnTab_infiniteLoop3.qml b/qtdeclarative/tests/auto/quick/qquickitem2/data/activeFocusOnTab_infiniteLoop3.qml
+new file mode 100644
+index 0000000000..889e480f3b
+--- /dev/null
++++ b/qtdeclarative/tests/auto/quick/qquickitem2/data/activeFocusOnTab_infiniteLoop3.qml
+@@ -0,0 +1,13 @@
++import QtQuick 2.6
++
++Item {
++ visible: true
++ Item {
++ visible: false
++ Item {
++ objectName: "hiddenChild"
++ activeFocusOnTab: true
++ focus: true
++ }
++ }
++}
+diff --git a/qtdeclarative/tests/auto/quick/qquickitem2/tst_qquickitem.cpp b/qtdeclarative/tests/auto/quick/qquickitem2/tst_qquickitem.cpp
+index c8f251dbe1..c8ef36ee68 100644
+--- a/qtdeclarative/tests/auto/quick/qquickitem2/tst_qquickitem.cpp
++++ b/qtdeclarative/tests/auto/quick/qquickitem2/tst_qquickitem.cpp
+@@ -67,6 +67,7 @@ private slots:
+ void activeFocusOnTab10();
+ void activeFocusOnTab_infiniteLoop_data();
+ void activeFocusOnTab_infiniteLoop();
++ void activeFocusOnTab_infiniteLoopControls();
+
+ void nextItemInFocusChain();
+ void nextItemInFocusChain2();
+@@ -1057,6 +1058,17 @@ void tst_QQuickItem::activeFocusOnTab_infiniteLoop()
+ QCOMPARE(item, window->rootObject());
+ }
+
++
++void tst_QQuickItem::activeFocusOnTab_infiniteLoopControls()
++{
++ auto source = testFileUrl("activeFocusOnTab_infiniteLoop3.qml");
++ QScopedPointer<QQuickView>window(new QQuickView());
++ window->setSource(source);
++ window->show();
++ QVERIFY(window->errors().isEmpty());
++ QTest::keyClick(window.get(), Qt::Key_Tab); // should not hang
++}
++
+ void tst_QQuickItem::nextItemInFocusChain()
+ {
+ if (!qt_tab_all_widgets())
+Submodule qtdoc c0c7bf07...79d6ef69:
+Submodule qtimageformats 2dcf2899..abe44c0f:
+diff --git a/qtimageformats/src/plugins/imageformats/icns/qicnshandler.cpp b/qtimageformats/src/plugins/imageformats/icns/qicnshandler.cpp
+index dde783c..1bf9074 100644
+--- a/qtimageformats/src/plugins/imageformats/icns/qicnshandler.cpp
++++ b/qtimageformats/src/plugins/imageformats/icns/qicnshandler.cpp
+@@ -462,8 +462,12 @@ static bool parseIconEntryInfo(ICNSEntry &icon)
+ if (isIconCompressed(icon))
+ return true;
+ // Icon depth:
+- if (!depth.isEmpty())
+- icon.depth = ICNSEntry::Depth(depth.toUInt());
++ if (!depth.isEmpty()) {
++ const uint depthUInt = depth.toUInt();
++ if (depthUInt > 32)
++ return false;
++ icon.depth = ICNSEntry::Depth(depthUInt);
++ }
+ // Try mono if depth not found
+ if (icon.depth == ICNSEntry::DepthUnknown)
+ icon.depth = ICNSEntry::DepthMono;
+@@ -515,6 +519,9 @@ static bool parseIconEntryInfo(ICNSEntry &icon)
+ }
+ icon.height = icon.width;
+ }
++ // Sanity check
++ if (icon.width == 0 || icon.width > 4096)
++ return false;
+ return true;
+ }
+
+@@ -685,7 +692,7 @@ bool QICNSHandler::canRead() const
+ bool QICNSHandler::read(QImage *outImage)
+ {
+ QImage img;
+- if (!ensureScanned()) {
++ if (!ensureScanned() || m_currentIconIndex >= m_icons.size()) {
+ qWarning("QICNSHandler::read(): The device wasn't parsed properly!");
+ return false;
+ }
+@@ -892,7 +899,7 @@ bool QICNSHandler::scanDevice()
+ return false;
+
+ const qint64 blockDataOffset = device()->pos();
+- if (!isBlockHeaderValid(blockHeader)) {
++ if (!isBlockHeaderValid(blockHeader, ICNSBlockHeaderSize + filelength - blockDataOffset)) {
+ qWarning("QICNSHandler::scanDevice(): Failed, bad header at pos %s. OSType \"%s\", length %u",
+ QByteArray::number(blockDataOffset).constData(),
+ nameFromOSType(blockHeader.ostype).constData(), blockHeader.length);
+@@ -927,11 +934,14 @@ bool QICNSHandler::scanDevice()
+ case ICNSBlockHeader::TypeOdrp:
+ // Icns container seems to have an embedded icon variant container
+ // Let's start a scan for entries
+- while (device()->pos() < nextBlockOffset) {
++ while (!stream.atEnd() && device()->pos() < nextBlockOffset) {
+ ICNSBlockHeader icon;
+ stream >> icon;
++ if (stream.status() != QDataStream::Ok)
++ return false;
+ // Check for incorrect variant entry header and stop scan
+- if (!isBlockHeaderValid(icon, blockDataLength))
++ quint64 remaining = blockDataLength - (device()->pos() - blockDataOffset);
++ if (!isBlockHeaderValid(icon, ICNSBlockHeaderSize + remaining))
+ break;
+ if (!addEntry(icon, device()->pos(), blockHeader.ostype))
+ return false;
+@@ -1003,7 +1013,7 @@ bool QICNSHandler::scanDevice()
+ break;
+ }
+ }
+- return true;
++ return (m_icons.size() > 0);
+ }
+
+ const ICNSEntry &QICNSHandler::getIconMask(const ICNSEntry &icon) const
+diff --git a/qtimageformats/src/plugins/imageformats/jp2/qjp2handler.cpp b/qtimageformats/src/plugins/imageformats/jp2/qjp2handler.cpp
+index 5082023..cb34374 100644
+--- a/qtimageformats/src/plugins/imageformats/jp2/qjp2handler.cpp
++++ b/qtimageformats/src/plugins/imageformats/jp2/qjp2handler.cpp
+@@ -43,6 +43,7 @@
+ #include "qimage.h"
+ #include "qvariant.h"
+ #include "qcolor.h"
++#include "qimagereader.h"
+
+ #include <jasper/jasper.h>
+ #include <math.h> // for pow
+@@ -333,16 +334,46 @@ private:
+ Jpeg2000JasperReader::Jpeg2000JasperReader(QIODevice *iod, SubFormat format)
+ : jasperOk(true), ioDevice(iod), format(format), hasAlpha(false)
+ {
++#if JAS_VERSION_MAJOR < 3
+ if (jas_init()) {
+ jasperOk = false;
+ qDebug("Jasper Library initialization failed");
+ }
++#else
++ jas_conf_clear();
++#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
++ jas_conf_set_max_mem_usage(QImageReader::allocationLimit() * 1024 * 1024);
++#else
++ // 128MB seems to be enough.
++ jas_conf_set_max_mem_usage(128 * 1024 * 1024);
++#endif
++ if (jas_init_library()) {
++ jasperOk = false;
++ qDebug("Jasper library initialization failed");
++ }
++ if (jas_init_thread()) {
++ jas_cleanup_library();
++ jasperOk = false;
++ qDebug("Jasper thread initialization failed");
++ }
++#endif
+ }
+
+ Jpeg2000JasperReader::~Jpeg2000JasperReader()
+ {
++#if JAS_VERSION_MAJOR < 3
+ if (jasperOk)
+ jas_cleanup();
++#else
++ if (jasperOk) {
++ if (jas_cleanup_thread()) {
++ qDebug("Jasper thread cleanup failed");
++ }
++ if (jas_cleanup_library()) {
++ qDebug("Jasper library cleanup failed");
++ }
++ }
++#endif
+ }
+
+ /*! \internal
+@@ -857,7 +888,7 @@ bool Jpeg2000JasperReader::write(const QImage &image, int quality)
+ }
+
+ // Open an empty jasper stream that grows automatically
+- jas_stream_t * memory_stream = jas_stream_memopen(0, -1);
++ jas_stream_t * memory_stream = jas_stream_memopen(0, 0);
+
+ // Jasper wants a non-const string.
+ char *str = qstrdup(jasperFormatString.toLatin1().constData());
+diff --git a/qtimageformats/src/plugins/imageformats/tiff/qtiffhandler.cpp b/qtimageformats/src/plugins/imageformats/tiff/qtiffhandler.cpp
+index 1386750..ac8956c 100644
+--- a/qtimageformats/src/plugins/imageformats/tiff/qtiffhandler.cpp
++++ b/qtimageformats/src/plugins/imageformats/tiff/qtiffhandler.cpp
+@@ -361,6 +361,8 @@ bool QTiffHandler::read(QImage *image)
+ }
+
+ TIFF *const tiff = d->tiff;
++ if (TIFFIsTiled(tiff) && TIFFTileSize64(tiff) > uint64_t(image->sizeInBytes())) // Corrupt image
++ return false;
+ const quint32 width = d->size.width();
+ const quint32 height = d->size.height();
+
+diff --git a/qtimageformats/src/plugins/imageformats/webp/qwebphandler.cpp b/qtimageformats/src/plugins/imageformats/webp/qwebphandler.cpp
+index 82d38cb..d02eb05 100644
+--- a/qtimageformats/src/plugins/imageformats/webp/qwebphandler.cpp
++++ b/qtimageformats/src/plugins/imageformats/webp/qwebphandler.cpp
+@@ -45,6 +45,7 @@
+ #include <qdebug.h>
+ #include <qpainter.h>
+ #include <qvariant.h>
++#include <QtEndian>
+
+ static const int riffHeaderSize = 12; // RIFF_HEADER_SIZE from webp/format_constants.h
+
+@@ -102,21 +103,23 @@ bool QWebpHandler::ensureScanned() const
+
+ m_scanState = ScanError;
+
+- if (device()->isSequential()) {
+- qWarning() << "Sequential devices are not supported";
++ QWebpHandler *that = const_cast<QWebpHandler *>(this);
++ const int headerBytesNeeded = sizeof(WebPBitstreamFeatures);
++ QByteArray header = device()->peek(headerBytesNeeded);
++ if (header.size() < headerBytesNeeded)
+ return false;
+- }
+
+- qint64 oldPos = device()->pos();
+- device()->seek(0);
+-
+- QWebpHandler *that = const_cast<QWebpHandler *>(this);
+- QByteArray header = device()->peek(sizeof(WebPBitstreamFeatures));
++ // We do no random access during decoding, just a readAll() of the whole image file. So if
++ // if it is all available already, we can accept a sequential device. The riff header contains
++ // the file size minus 8 bytes header
++ qint64 byteSize = qFromLittleEndian<quint32>(header.constData() + 4);
++ if (device()->isSequential() && device()->bytesAvailable() < byteSize + 8) {
++ qWarning() << "QWebpHandler: Insufficient data available in sequential device";
++ return false;
++ }
+ if (WebPGetFeatures((const uint8_t*)header.constData(), header.size(), &(that->m_features)) == VP8_STATUS_OK) {
+ if (m_features.has_animation) {
+ // For animation, we have to read and scan whole file to determine loop count and images count
+- device()->seek(oldPos);
+-
+ if (that->ensureDemuxer()) {
+ that->m_loop = WebPDemuxGetI(m_demuxer, WEBP_FF_LOOP_COUNT);
+ that->m_frameCount = WebPDemuxGetI(m_demuxer, WEBP_FF_FRAME_COUNT);
+@@ -126,17 +129,13 @@ bool QWebpHandler::ensureScanned() const
+ if (that->m_features.has_alpha)
+ that->m_composited->fill(Qt::transparent);
+
+- // We do not reset device position since we have read in all data
+ m_scanState = ScanSuccess;
+- return true;
+ }
+ } else {
+ m_scanState = ScanSuccess;
+ }
+ }
+
+- device()->seek(oldPos);
+-
+ return m_scanState == ScanSuccess;
+ }
+
+@@ -159,7 +158,7 @@ bool QWebpHandler::ensureDemuxer()
+
+ bool QWebpHandler::read(QImage *image)
+ {
+- if (!ensureScanned() || device()->isSequential() || !ensureDemuxer())
++ if (!ensureScanned() || !ensureDemuxer())
+ return false;
+
+ QRect prevFrameRect;
+Submodule qtlocation 98a5c511..f991e28c:
+diff --git a/qtlocation/src/location/configure.json b/qtlocation/src/location/configure.json
+index 6d01a9a3..d1e623a1 100644
+--- a/qtlocation/src/location/configure.json
++++ b/qtlocation/src/location/configure.json
+@@ -9,7 +9,7 @@
+ "label": "Qt.labs.location experimental QML plugin",
+ "purpose": "Provides experimental QtLocation QML types",
+ "section": "Location",
+- "condition": "config.opengl",
++ "condition": "features.opengl",
+ "output": [ "privateFeature" ]
+ },
+ "geoservices_osm": {
+diff --git a/qtlocation/src/location/labs/qsg/qgeomapobjectqsgsupport.cpp b/qtlocation/src/location/labs/qsg/qgeomapobjectqsgsupport.cpp
+index a978573d..11e1466f 100644
+--- a/qtlocation/src/location/labs/qsg/qgeomapobjectqsgsupport.cpp
++++ b/qtlocation/src/location/labs/qsg/qgeomapobjectqsgsupport.cpp
+@@ -158,7 +158,7 @@ void QGeoMapObjectQSGSupport::updateMapObjects(QSGNode *root, QQuickWindow *wind
+ if (!root)
+ return;
+
+- if (m_mapObjectsRootNode && m_mapObjectsRootNode->parent())
++ if (m_mapObjectsRootNode && !m_mapObjectsRootNode->parent())
+ root->appendChildNode(m_mapObjectsRootNode.get());
+
+ if (!m_mapObjectsRootNode) {
+diff --git a/qtlocation/src/plugins/geoservices/esri/geocodingmanagerengine_esri.cpp b/qtlocation/src/plugins/geoservices/esri/geocodingmanagerengine_esri.cpp
+index 5a40467e..d123c6a8 100644
+--- a/qtlocation/src/plugins/geoservices/esri/geocodingmanagerengine_esri.cpp
++++ b/qtlocation/src/plugins/geoservices/esri/geocodingmanagerengine_esri.cpp
+@@ -59,8 +59,10 @@ QT_BEGIN_NAMESPACE
+ static const QString kPrefixEsri(QStringLiteral("esri."));
+ static const QString kParamUserAgent(kPrefixEsri + QStringLiteral("useragent"));
+
+-static const QString kUrlGeocode(QStringLiteral("http://geocode.arcgis.com/arcgis/rest/services/World/GeocodeServer/findAddressCandidates"));
+-static const QString kUrlReverseGeocode(QStringLiteral("http://geocode.arcgis.com/arcgis/rest/services/World/GeocodeServer/reverseGeocode"));
++static const QString kUrlGeocode(QStringLiteral("https://geocode.arcgis.com/arcgis/rest/services/"
++ "World/GeocodeServer/findAddressCandidates"));
++static const QString kUrlReverseGeocode(QStringLiteral(
++ "https://geocode.arcgis.com/arcgis/rest/services/World/GeocodeServer/reverseGeocode"));
+
+ static QString addressToQuery(const QGeoAddress &address)
+ {
+diff --git a/qtlocation/src/plugins/geoservices/esri/georoutejsonparser_esri.cpp b/qtlocation/src/plugins/geoservices/esri/georoutejsonparser_esri.cpp
+index 17492d94..96c12b1b 100644
+--- a/qtlocation/src/plugins/geoservices/esri/georoutejsonparser_esri.cpp
++++ b/qtlocation/src/plugins/geoservices/esri/georoutejsonparser_esri.cpp
+@@ -46,7 +46,8 @@
+
+ QT_BEGIN_NAMESPACE
+
+-// JSON reference: http://resources.arcgis.com/en/help/arcgis-rest-api/#/Route_service_with_synchronous_execution/02r300000036000000/
++// JSON reference:
++// https://resources.arcgis.com/en/help/arcgis-rest-api/#/Route_service_with_synchronous_execution/02r300000036000000/
+
+ static const QString kErrorMessage(QStringLiteral("Error %1: %2."));
+ static const QString kErrorJson(QStringLiteral("Error: invalide JSON document."));
+diff --git a/qtlocation/src/plugins/geoservices/esri/georoutereply_esri.cpp b/qtlocation/src/plugins/geoservices/esri/georoutereply_esri.cpp
+index 8cadfb29..92b6bb13 100644
+--- a/qtlocation/src/plugins/geoservices/esri/georoutereply_esri.cpp
++++ b/qtlocation/src/plugins/geoservices/esri/georoutereply_esri.cpp
+@@ -44,7 +44,8 @@
+
+ QT_BEGIN_NAMESPACE
+
+-// JSON reference: http://resources.arcgis.com/en/help/arcgis-rest-api/#/Route_service_with_synchronous_execution/02r300000036000000/
++// JSON reference:
++// https://resources.arcgis.com/en/help/arcgis-rest-api/#/Route_service_with_synchronous_execution/02r300000036000000/
+
+ GeoRouteReplyEsri::GeoRouteReplyEsri(QNetworkReply *reply, const QGeoRouteRequest &request,
+ QObject *parent) :
+diff --git a/qtlocation/src/plugins/geoservices/esri/georoutingmanagerengine_esri.cpp b/qtlocation/src/plugins/geoservices/esri/georoutingmanagerengine_esri.cpp
+index 0e6bc2c7..ed613f4b 100644
+--- a/qtlocation/src/plugins/geoservices/esri/georoutingmanagerengine_esri.cpp
++++ b/qtlocation/src/plugins/geoservices/esri/georoutingmanagerengine_esri.cpp
+@@ -48,7 +48,8 @@ static const QString kPrefixEsri(QStringLiteral("esri."));
+ static const QString kParamUserAgent(kPrefixEsri + QStringLiteral("useragent"));
+ static const QString kParamToken(kPrefixEsri + QStringLiteral("token"));
+
+-static const QString kUrlRouting(QStringLiteral("http://route.arcgis.com/arcgis/rest/services/World/Route/NAServer/Route_World/solve"));
++static const QString kUrlRouting(QStringLiteral(
++ "https://route.arcgis.com/arcgis/rest/services/World/Route/NAServer/Route_World/solve"));
+
+ GeoRoutingManagerEngineEsri::GeoRoutingManagerEngineEsri(const QVariantMap ¶meters,
+ QGeoServiceProvider::Error *error,
+@@ -70,7 +71,8 @@ GeoRoutingManagerEngineEsri::~GeoRoutingManagerEngineEsri()
+ {
+ }
+
+-// REST reference: http://resources.arcgis.com/en/help/arcgis-rest-api/index.html#//02r300000036000000
++// REST reference:
++// https://resources.arcgis.com/en/help/arcgis-rest-api/index.html#//02r300000036000000
+
+ QGeoRouteReply *GeoRoutingManagerEngineEsri::calculateRoute(const QGeoRouteRequest &request)
+ {
+@@ -125,7 +127,7 @@ void GeoRoutingManagerEngineEsri::replyError(QGeoRouteReply::Error errorCode, co
+ QString GeoRoutingManagerEngineEsri::preferedDirectionLangage()
+ {
+ // list of supported langages is defined in:
+- // http://resources.arcgis.com/en/help/arcgis-rest-api/index.html#//02r300000036000000
++ // https://resources.arcgis.com/en/help/arcgis-rest-api/index.html#//02r300000036000000
+ const QStringList supportedLanguages = {
+ "ar", // Generate directions in Arabic
+ "cs", // Generate directions in Czech
+diff --git a/qtlocation/src/plugins/geoservices/esri/geotiledmappingmanagerengine_esri.cpp b/qtlocation/src/plugins/geoservices/esri/geotiledmappingmanagerengine_esri.cpp
+index 5d15835d..24148f95 100644
+--- a/qtlocation/src/plugins/geoservices/esri/geotiledmappingmanagerengine_esri.cpp
++++ b/qtlocation/src/plugins/geoservices/esri/geotiledmappingmanagerengine_esri.cpp
+@@ -230,7 +230,8 @@ QGeoMap *GeoTiledMappingManagerEngineEsri::createMap()
+ // ${y} = Y
+ // ${token} = Token
+
+-// template = 'http://services.arcgisonline.com/ArcGIS/rest/services/World_Topo_Map/MapServer/tile/{{z}}/{{y}}/{{x}}.png'
++// template =
++// 'https://services.arcgisonline.com/ArcGIS/rest/services/World_Topo_Map/MapServer/tile/{{z}}/{{y}}/{{x}}.png'
+
+ bool GeoTiledMappingManagerEngineEsri::initializeMapSources(QGeoServiceProvider::Error *error,
+ QString *errorString,
+diff --git a/qtlocation/src/plugins/geoservices/esri/maps.json b/qtlocation/src/plugins/geoservices/esri/maps.json
+index 8167ae7d..862e087d 100644
+--- a/qtlocation/src/plugins/geoservices/esri/maps.json
++++ b/qtlocation/src/plugins/geoservices/esri/maps.json
+@@ -6,8 +6,8 @@
+ "description": "ArcGIS Online World Street Map",
+ "mobile": true,
+ "night": false,
+- "url": "http://services.arcgisonline.com/ArcGIS/rest/services/World_Street_Map/MapServer",
+- "copyrightText": "© <a href='http://www.arcgis.com/home/item.html?id=3b93337983e9436f8db950e38a8629af'>Esri</a> contributors"
++ "url": "https://services.arcgisonline.com/ArcGIS/rest/services/World_Street_Map/MapServer",
++ "copyrightText": "© <a href='https://www.arcgis.com/home/item.html?id=3b93337983e9436f8db950e38a8629af'>Esri</a> contributors"
+ },
+
+ {
+@@ -16,8 +16,8 @@
+ "": "ArcGIS Online World Imagery",
+ "mobile": true,
+ "night": false,
+- "url": "http://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer",
+- "copyrightText": "© <a href='http://www.arcgis.com/home/item.html?id=10df2279f9684e4a9f6a7f08febac2a9'>Esri</a> contributors"
++ "url": "https://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer",
++ "copyrightText": "© <a href='https://www.arcgis.com/home/item.html?id=10df2279f9684e4a9f6a7f08febac2a9'>Esri</a> contributors"
+ },
+
+ {
+@@ -26,8 +26,8 @@
+ "description": "ArcGIS Online World Terrain Base",
+ "mobile": false,
+ "night": false,
+- "url": "http://server.arcgisonline.com/ArcGIS/rest/services/World_Terrain_Base/MapServer",
+- "copyrightText": "© <a href='http://www.arcgis.com/home/item.html?id=c61ad8ab017d49e1a82f580ee1298931'>Esri</a> contributors"
++ "url": "https://server.arcgisonline.com/ArcGIS/rest/services/World_Terrain_Base/MapServer",
++ "copyrightText": "© <a href='https://www.arcgis.com/home/item.html?id=c61ad8ab017d49e1a82f580ee1298931'>Esri</a> contributors"
+ },
+
+ {
+@@ -36,8 +36,8 @@
+ "description": "ArcGIS Online World Topography",
+ "mobile": true,
+ "night": false,
+- "url": "http://server.arcgisonline.com/ArcGIS/rest/services/World_Topo_Map/MapServer",
+- "copyrightText": "© <a href='http://www.arcgis.com/home/item.html?id=30e5fe3149c34df1ba922e6f5bbf808f'>Esri</a> contributors"
++ "url": "https://server.arcgisonline.com/ArcGIS/rest/services/World_Topo_Map/MapServer",
++ "copyrightText": "© <a href='https://www.arcgis.com/home/item.html?id=30e5fe3149c34df1ba922e6f5bbf808f'>Esri</a> contributors"
+ },
+
+ {
+@@ -46,8 +46,8 @@
+ "description": "This map presents land cover and detailed topographic maps for the United States.",
+ "mobile": true,
+ "night": false,
+- "url": "http://services.arcgisonline.com/ArcGIS/rest/services/USA_Topo_Maps/MapServer",
+- "copyrightText": "© <a href='http://www.arcgis.com/home/item.html?id=99cd5fbd98934028802b4f797c4b1732'>Esri</a> contributors"
++ "url": "https://services.arcgisonline.com/ArcGIS/rest/services/USA_Topo_Maps/MapServer",
++ "copyrightText": "© <a href='https://www.arcgis.com/home/item.html?id=99cd5fbd98934028802b4f797c4b1732'>Esri</a> contributors"
+ },
+
+ {
+@@ -56,8 +56,8 @@
+ "description": "National Geographic World Map",
+ "mobile": false,
+ "night": false,
+- "url": "http://services.arcgisonline.com/ArcGIS/rest/services/NatGeo_World_Map/MapServer",
+- "copyrightText": "© <a href='http://www.arcgis.com/home/item.html?id=b9b1b422198944fbbd5250b3241691b6'>Esri</a> contributors"
++ "url": "https://services.arcgisonline.com/ArcGIS/rest/services/NatGeo_World_Map/MapServer",
++ "copyrightText": "© <a href='https://www.arcgis.com/home/item.html?id=b9b1b422198944fbbd5250b3241691b6'>Esri</a> contributors"
+ },
+
+ {
+@@ -66,8 +66,8 @@
+ "description": "Thematic content providing a neutral background with minimal colors",
+ "mobile": true,
+ "night": false,
+- "url": "http://services.arcgisonline.com/ArcGIS/rest/services/Canvas/World_Light_Gray_Base/MapServer",
+- "copyrightText": "© <a href='http://www.arcgis.com/home/item.html?id=ed712cb1db3e4bae9e85329040fb9a49'>Esri</a> contributors"
++ "url": "https://services.arcgisonline.com/ArcGIS/rest/services/Canvas/World_Light_Gray_Base/MapServer",
++ "copyrightText": "© <a href='https://www.arcgis.com/home/item.html?id=ed712cb1db3e4bae9e85329040fb9a49'>Esri</a> contributors"
+ },
+
+ {
+@@ -76,8 +76,8 @@
+ "description": "Natural Earth physical map for the world",
+ "mobile": false,
+ "night": false,
+- "url": "http://server.arcgisonline.com/ArcGIS/rest/services/World_Physical_Map/MapServer",
+- "copyrightText": "© <a href='http://www.arcgis.com/home/item.html?id=c4ec722a1cd34cf0a23904aadf8923a0'>Esri</a> contributors"
++ "url": "https://server.arcgisonline.com/ArcGIS/rest/services/World_Physical_Map/MapServer",
++ "copyrightText": "© <a href='https://www.arcgis.com/home/item.html?id=c4ec722a1cd34cf0a23904aadf8923a0'>Esri</a> contributors"
+ },
+
+ {
+@@ -86,8 +86,8 @@
+ "description": "Portrays surface elevation as shaded relief",
+ "mobile": false,
+ "night": false,
+- "url": "http://server.arcgisonline.com/ArcGIS/rest/services/World_Shaded_Relief/MapServer",
+- "copyrightText": "© <a href='http://www.arcgis.com/home/item.html?id=9c5370d0b54f4de1b48a3792d7377ff2'>Esri</a> contributors"
++ "url": "https://server.arcgisonline.com/ArcGIS/rest/services/World_Shaded_Relief/MapServer",
++ "copyrightText": "© <a href='https://www.arcgis.com/home/item.html?id=9c5370d0b54f4de1b48a3792d7377ff2'>Esri</a> contributors"
+ },
+
+ {
+@@ -96,8 +96,8 @@
+ "description": "This map is designed to be used as a basemap by marine GIS professionals and as a reference map by anyone interested in ocean data",
+ "mobile": false,
+ "night": false,
+- "url": "http://server.arcgisonline.com/arcgis/rest/services/Ocean/World_Ocean_Base/MapServer",
+- "copyrightText": "© <a href='http://www.arcgis.com/home/item.html?id=1e126e7520f9466c9ca28b8f28b5e500'>Esri</a> contributors"
++ "url": "https://server.arcgisonline.com/arcgis/rest/services/Ocean/World_Ocean_Base/MapServer",
++ "copyrightText": "© <a href='https://www.arcgis.com/home/item.html?id=1e126e7520f9466c9ca28b8f28b5e500'>Esri</a> contributors"
+ },
+
+ {
+@@ -106,8 +106,8 @@
+ "description": "Thematic content providing a neutral background with minimal colors",
+ "mobile": false,
+ "night": true,
+- "url": "http://services.arcgisonline.com/ArcGIS/rest/services/Canvas/World_Dark_Gray_Base/MapServer",
+- "copyrightText": "© <a href='http://www.arcgis.com/home/item.html?id=a284a9b99b3446a3910d4144a50990f6'>Esri</a> contributors"
++ "url": "https://services.arcgisonline.com/ArcGIS/rest/services/Canvas/World_Dark_Gray_Base/MapServer",
++ "copyrightText": "© <a href='https://www.arcgis.com/home/item.html?id=a284a9b99b3446a3910d4144a50990f6'>Esri</a> contributors"
+ },
+
+ {
+@@ -116,8 +116,8 @@
+ "description": "DeLorme’s topographic basemap is a seamless global data set that portrays transportation, hydrography, jurisdiction boundaries, and major geographic features",
+ "mobile": false,
+ "night": false,
+- "url": "http://server.arcgisonline.com/ArcGIS/rest/services/Specialty/DeLorme_World_Base_Map/MapServer",
+- "copyrightText": "© <a href='http://www.arcgis.com/home/item.html?id=b165c3df453e4be6b5ac4fdb241effbe'>Esri</a> contributors"
++ "url": "https://server.arcgisonline.com/ArcGIS/rest/services/Specialty/DeLorme_World_Base_Map/MapServer",
++ "copyrightText": "© <a href='https://www.arcgis.com/home/item.html?id=b165c3df453e4be6b5ac4fdb241effbe'>Esri</a> contributors"
+ }
+ ]
+ }
+diff --git a/qtlocation/src/plugins/geoservices/esri/placemanagerengine_esri.cpp b/qtlocation/src/plugins/geoservices/esri/placemanagerengine_esri.cpp
+index 3858ddf5..af66f28e 100644
+--- a/qtlocation/src/plugins/geoservices/esri/placemanagerengine_esri.cpp
++++ b/qtlocation/src/plugins/geoservices/esri/placemanagerengine_esri.cpp
+@@ -63,8 +63,10 @@ static const QString kCountriesKey(QStringLiteral("detailedCountries"));
+ static const QString kLocalizedNamesKey(QStringLiteral("localizedNames"));
+ static const QString kMaxLocationsKey(QStringLiteral("maxLocations"));
+
+-static const QUrl kUrlGeocodeServer("http://geocode.arcgis.com/arcgis/rest/services/World/GeocodeServer?f=pjson");
+-static const QUrl kUrlFindAddressCandidates("http://geocode.arcgis.com/arcgis/rest/services/World/GeocodeServer/findAddressCandidates");
++static const QUrl kUrlGeocodeServer(
++ "https://geocode.arcgis.com/arcgis/rest/services/World/GeocodeServer?f=pjson");
++static const QUrl kUrlFindAddressCandidates("https://geocode.arcgis.com/arcgis/rest/services/World/"
++ "GeocodeServer/findAddressCandidates");
+
+ PlaceManagerEngineEsri::PlaceManagerEngineEsri(const QVariantMap ¶meters, QGeoServiceProvider::Error *error,
+ QString *errorString) :
+Submodule qtmultimedia f0344079..0d7cc33a:
+diff --git a/qtmultimedia/src/plugins/pulseaudio/qaudioinput_pulse.cpp b/qtmultimedia/src/plugins/pulseaudio/qaudioinput_pulse.cpp
+index 2b5325132..b68b4af1b 100644
+--- a/qtmultimedia/src/plugins/pulseaudio/qaudioinput_pulse.cpp
++++ b/qtmultimedia/src/plugins/pulseaudio/qaudioinput_pulse.cpp
+@@ -402,6 +402,8 @@ int QPulseAudioInput::bytesReady() const
+
+ qint64 QPulseAudioInput::read(char *data, qint64 len)
+ {
++ Q_ASSERT(data != nullptr || len == 0);
++
+ m_bytesAvailable = checkBytesReady();
+
+ setError(QAudio::NoError);
+@@ -411,7 +413,8 @@ qint64 QPulseAudioInput::read(char *data, qint64 len)
+
+ if (!m_pullMode && !m_tempBuffer.isEmpty()) {
+ readBytes = qMin(static_cast<int>(len), m_tempBuffer.size());
+- memcpy(data, m_tempBuffer.constData(), readBytes);
++ if (readBytes)
++ memcpy(data, m_tempBuffer.constData(), readBytes);
+ m_totalTimeValue += readBytes;
+
+ if (readBytes < m_tempBuffer.size()) {
+@@ -502,9 +505,10 @@ qint64 QPulseAudioInput::read(char *data, qint64 len)
+
+ void QPulseAudioInput::applyVolume(const void *src, void *dest, int len)
+ {
++ Q_ASSERT((src && dest) || len == 0);
+ if (m_volume < 1.f)
+ QAudioHelperInternal::qMultiplySamples(m_volume, m_format, src, dest, len);
+- else
++ else if (len)
+ memcpy(dest, src, len);
+ }
+
+Submodule qtpim 02efef5e...f9a8f0fc (commits not present)
+Submodule qtquick3d b85cf622..47defc8b:
+diff --git a/qtquick3d/src/plugins/assetimporters/assimp/assimp.pro b/qtquick3d/src/plugins/assetimporters/assimp/assimp.pro
+index ca5c499e..174a075b 100644
+--- a/qtquick3d/src/plugins/assetimporters/assimp/assimp.pro
++++ b/qtquick3d/src/plugins/assetimporters/assimp/assimp.pro
+@@ -10,7 +10,7 @@ QT_FOR_CONFIG += assetimporters-private
+ include($$OUT_PWD/../qtassetimporters-config.pri)
+
+ qtConfig(system-assimp):!if(cross_compile:host_build) {
+- QMAKE_USE_PRIVATE += assimp
++ QMAKE_USE_PRIVATE += quick3d-assimp
+ } else {
+ include(../../../3rdparty/assimp/assimp.pri)
+ }
+Submodule qtquickcontrols2 3a657dc0..56ce8233:
+diff --git a/qtquickcontrols2/src/imports/platform/widgets/qwidgetplatformmenu.cpp b/qtquickcontrols2/src/imports/platform/widgets/qwidgetplatformmenu.cpp
+index e5fe734f7..e36922775 100644
+--- a/qtquickcontrols2/src/imports/platform/widgets/qwidgetplatformmenu.cpp
++++ b/qtquickcontrols2/src/imports/platform/widgets/qwidgetplatformmenu.cpp
+@@ -38,6 +38,7 @@
+ #include "qwidgetplatformmenuitem_p.h"
+
+ #include <QtGui/qwindow.h>
++#include <QtGui/private/qhighdpiscaling_p.h>
+ #include <QtWidgets/qmenu.h>
+ #include <QtWidgets/qaction.h>
+
+@@ -145,7 +146,7 @@ void QWidgetPlatformMenu::showPopup(const QWindow *window, const QRect &targetRe
+
+ QPoint targetPos = targetRect.bottomLeft();
+ if (window)
+- targetPos = window->mapToGlobal(targetPos);
++ targetPos = window->mapToGlobal(QHighDpi::fromNativeLocalPosition(targetPos, window));
+
+ const QWidgetPlatformMenuItem *widgetItem = qobject_cast<const QWidgetPlatformMenuItem *>(item);
+ m_menu->popup(targetPos, widgetItem ? widgetItem->action() : nullptr);
+diff --git a/qtquickcontrols2/src/quicktemplates2/qquickabstractbutton.cpp b/qtquickcontrols2/src/quicktemplates2/qquickabstractbutton.cpp
+index 950e4e099..b81fbea0b 100644
+--- a/qtquickcontrols2/src/quicktemplates2/qquickabstractbutton.cpp
++++ b/qtquickcontrols2/src/quicktemplates2/qquickabstractbutton.cpp
+@@ -387,6 +387,17 @@ void QQuickAbstractButtonPrivate::itemImplicitHeightChanged(QQuickItem *item)
+ emit q->implicitIndicatorHeightChanged();
+ }
+
++void QQuickAbstractButtonPrivate::itemDestroyed(QQuickItem *item)
++{
++ Q_Q(QQuickAbstractButton);
++ QQuickControlPrivate::itemDestroyed(item);
++ if (item == indicator) {
++ indicator = nullptr;
++ emit q->implicitIndicatorWidthChanged();
++ emit q->implicitIndicatorHeightChanged();
++ }
++}
++
+ QQuickAbstractButton *QQuickAbstractButtonPrivate::findCheckedButton() const
+ {
+ Q_Q(const QQuickAbstractButton);
+@@ -1176,6 +1187,12 @@ QAccessible::Role QQuickAbstractButton::accessibleRole() const
+ }
+ return QAccessible::Button;
+ }
++
++void QQuickAbstractButton::accessiblePressAction()
++{
++ Q_D(QQuickAbstractButton);
++ d->trigger();
++}
+ #endif
+
+ QT_END_NAMESPACE
+diff --git a/qtquickcontrols2/src/quicktemplates2/qquickabstractbutton_p.h b/qtquickcontrols2/src/quicktemplates2/qquickabstractbutton_p.h
+index 0fa48980e..ab66220d0 100644
+--- a/qtquickcontrols2/src/quicktemplates2/qquickabstractbutton_p.h
++++ b/qtquickcontrols2/src/quicktemplates2/qquickabstractbutton_p.h
+@@ -209,6 +209,7 @@ protected:
+ #if QT_CONFIG(accessibility)
+ void accessibilityActiveChanged(bool active) override;
+ QAccessible::Role accessibleRole() const override;
++ Q_INVOKABLE void accessiblePressAction();
+ #endif
+
+ private:
+diff --git a/qtquickcontrols2/src/quicktemplates2/qquickabstractbutton_p_p.h b/qtquickcontrols2/src/quicktemplates2/qquickabstractbutton_p_p.h
+index 9291c1a87..b729720f2 100644
+--- a/qtquickcontrols2/src/quicktemplates2/qquickabstractbutton_p_p.h
++++ b/qtquickcontrols2/src/quicktemplates2/qquickabstractbutton_p_p.h
+@@ -109,6 +109,7 @@ public:
+
+ void itemImplicitWidthChanged(QQuickItem *item) override;
+ void itemImplicitHeightChanged(QQuickItem *item) override;
++ void itemDestroyed(QQuickItem *item) override;
+
+ // copied from qabstractbutton.cpp
+ static const int AUTO_REPEAT_DELAY = 300;
+diff --git a/qtquickcontrols2/src/quicktemplates2/qquickaction.cpp b/qtquickcontrols2/src/quicktemplates2/qquickaction.cpp
+index 2041e7741..8610cdfae 100644
+--- a/qtquickcontrols2/src/quicktemplates2/qquickaction.cpp
++++ b/qtquickcontrols2/src/quicktemplates2/qquickaction.cpp
+@@ -145,7 +145,7 @@ int QQuickActionPrivate::ShortcutEntry::shortcutId() const
+
+ void QQuickActionPrivate::ShortcutEntry::grab(const QKeySequence &shortcut, bool enabled)
+ {
+- if (shortcut.isEmpty())
++ if (shortcut.isEmpty() || m_shortcutId)
+ return;
+
+ Qt::ShortcutContext context = Qt::WindowShortcut; // TODO
+diff --git a/qtquickcontrols2/src/quicktemplates2/qquickcontainer.cpp b/qtquickcontrols2/src/quicktemplates2/qquickcontainer.cpp
+index f38c2b09c..6eed2a024 100644
+--- a/qtquickcontrols2/src/quicktemplates2/qquickcontainer.cpp
++++ b/qtquickcontrols2/src/quicktemplates2/qquickcontainer.cpp
+@@ -225,6 +225,7 @@ void QQuickContainerPrivate::cleanup()
+ QObject::disconnect(contentModel, &QQmlObjectModel::countChanged, q, &QQuickContainer::countChanged);
+ QObject::disconnect(contentModel, &QQmlObjectModel::childrenChanged, q, &QQuickContainer::contentChildrenChanged);
+ delete contentModel;
++ contentModel = nullptr;
+ }
+
+ QQuickItem *QQuickContainerPrivate::itemAt(int index) const
+@@ -436,7 +437,7 @@ void QQuickContainerPrivate::contentChildren_clear(QQmlListProperty<QQuickItem>
+ void QQuickContainerPrivate::updateContentWidth()
+ {
+ Q_Q(QQuickContainer);
+- if (hasContentWidth || qFuzzyCompare(contentWidth, implicitContentWidth))
++ if (hasContentWidth || qFuzzyCompare(contentWidth, implicitContentWidth) || !contentModel)
+ return;
+
+ contentWidth = implicitContentWidth;
+@@ -446,7 +447,7 @@ void QQuickContainerPrivate::updateContentWidth()
+ void QQuickContainerPrivate::updateContentHeight()
+ {
+ Q_Q(QQuickContainer);
+- if (hasContentHeight || qFuzzyCompare(contentHeight, implicitContentHeight))
++ if (hasContentHeight || qFuzzyCompare(contentHeight, implicitContentHeight) || !contentModel)
+ return;
+
+ contentHeight = implicitContentHeight;
+diff --git a/qtquickcontrols2/src/quicktemplates2/qquickcontrol.cpp b/qtquickcontrols2/src/quicktemplates2/qquickcontrol.cpp
+index bbbd0e622..1f4b47343 100644
+--- a/qtquickcontrols2/src/quicktemplates2/qquickcontrol.cpp
++++ b/qtquickcontrols2/src/quicktemplates2/qquickcontrol.cpp
+@@ -845,6 +845,13 @@ void QQuickControlPrivate::executeBackground(bool complete)
+ quickCompleteDeferred(q, backgroundName(), background);
+ }
+
++/*
++ \internal
++
++ Hides an item that was replaced by a newer one, rather than
++ deleting it, as the item is typically created in QML and hence
++ we don't own it.
++*/
+ void QQuickControlPrivate::hideOldItem(QQuickItem *item)
+ {
+ if (!item)
+@@ -863,6 +870,29 @@ void QQuickControlPrivate::hideOldItem(QQuickItem *item)
+ #endif
+ }
+
++/*
++ \internal
++
++ Named "unhide" because it's used for cases where an item
++ that was previously hidden by \l hideOldItem() wants to be
++ shown by a control again, such as a ScrollBar in ScrollView.
++*/
++void QQuickControlPrivate::unhideOldItem(QQuickControl *control, QQuickItem *item)
++{
++ Q_ASSERT(item);
++ qCDebug(lcItemManagement) << "unhiding old item" << item;
++
++ item->setVisible(true);
++ item->setParentItem(control);
++
++#if QT_CONFIG(accessibility)
++ // Add the item back in to the accessibility tree.
++ QQuickAccessibleAttached *accessible = accessibleAttached(item);
++ if (accessible)
++ accessible->setIgnored(false);
++#endif
++}
++
+ void QQuickControlPrivate::updateBaselineOffset()
+ {
+ Q_Q(QQuickControl);
+diff --git a/qtquickcontrols2/src/quicktemplates2/qquickcontrol_p_p.h b/qtquickcontrols2/src/quicktemplates2/qquickcontrol_p_p.h
+index 8e979079e..a6e624c91 100644
+--- a/qtquickcontrols2/src/quicktemplates2/qquickcontrol_p_p.h
++++ b/qtquickcontrols2/src/quicktemplates2/qquickcontrol_p_p.h
+@@ -173,6 +173,7 @@ public:
+ virtual void executeBackground(bool complete = false);
+
+ static void hideOldItem(QQuickItem *item);
++ static void unhideOldItem(QQuickControl *control, QQuickItem *item);
+
+ void updateBaselineOffset();
+
+diff --git a/qtquickcontrols2/src/quicktemplates2/qquickdialogbuttonbox.cpp b/qtquickcontrols2/src/quicktemplates2/qquickdialogbuttonbox.cpp
+index e6db14eb5..6197d1547 100644
+--- a/qtquickcontrols2/src/quicktemplates2/qquickdialogbuttonbox.cpp
++++ b/qtquickcontrols2/src/quicktemplates2/qquickdialogbuttonbox.cpp
+@@ -237,7 +237,7 @@ static QRectF alignedRect(Qt::LayoutDirection direction, Qt::Alignment alignment
+ void QQuickDialogButtonBoxPrivate::resizeContent()
+ {
+ Q_Q(QQuickDialogButtonBox);
+- if (!contentItem)
++ if (!contentItem || !contentModel)
+ return;
+
+ QRectF geometry = q->boundingRect().adjusted(q->leftPadding(), q->topPadding(), -q->rightPadding(), -q->bottomPadding());
+@@ -322,6 +322,9 @@ void QQuickDialogButtonBoxPrivate::updateLayout()
+ qreal QQuickDialogButtonBoxPrivate::getContentWidth() const
+ {
+ Q_Q(const QQuickDialogButtonBox);
++ if (!contentModel)
++ return 0;
++
+ const int count = contentModel->count();
+ const qreal totalSpacing = qMax(0, count - 1) * spacing;
+ qreal totalWidth = totalSpacing;
+@@ -341,6 +344,9 @@ qreal QQuickDialogButtonBoxPrivate::getContentWidth() const
+ qreal QQuickDialogButtonBoxPrivate::getContentHeight() const
+ {
+ Q_Q(const QQuickDialogButtonBox);
++ if (!contentModel)
++ return 0;
++
+ const int count = contentModel->count();
+ qreal maxHeight = 0;
+ for (int i = 0; i < count; ++i) {
+diff --git a/qtquickcontrols2/src/quicktemplates2/qquickoverlay.cpp b/qtquickcontrols2/src/quicktemplates2/qquickoverlay.cpp
+index 91bd59184..0ce518f84 100644
+--- a/qtquickcontrols2/src/quicktemplates2/qquickoverlay.cpp
++++ b/qtquickcontrols2/src/quicktemplates2/qquickoverlay.cpp
+@@ -399,8 +399,11 @@ void QQuickOverlay::itemChange(ItemChange change, const ItemChangeData &data)
+ Q_D(QQuickOverlay);
+ QQuickItem::itemChange(change, data);
+
+- if (change == ItemChildAddedChange || change == ItemChildRemovedChange)
++ if (change == ItemChildAddedChange || change == ItemChildRemovedChange) {
+ setVisible(!d->allDrawers.isEmpty() || !childItems().isEmpty());
++ if (data.item->parent() == d->mouseGrabberPopup)
++ d->setMouseGrabberPopup(nullptr);
++ }
+ }
+
+ void QQuickOverlay::geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry)
+diff --git a/qtquickcontrols2/src/quicktemplates2/qquickscrollbar.cpp b/qtquickcontrols2/src/quicktemplates2/qquickscrollbar.cpp
+index 4e2f509db..1c4b308cd 100644
+--- a/qtquickcontrols2/src/quicktemplates2/qquickscrollbar.cpp
++++ b/qtquickcontrols2/src/quicktemplates2/qquickscrollbar.cpp
+@@ -797,6 +797,14 @@ void QQuickScrollBarAttachedPrivate::initHorizontal()
+ if (parent && parent == flickable->parentItem())
+ horizontal->stackAfter(flickable);
+
++ // If a scroll bar was previously hidden (due to e.g. setting a new contentItem
++ // on a ScrollView), we need to make sure that we un-hide it.
++ // We don't bother checking if the item is actually the old one, because
++ // if it's not, all of the things the function does (setting parent, visibility, etc.)
++ // should be no-ops anyway.
++ if (auto control = qobject_cast<QQuickControl*>(q_ptr->parent()))
++ QQuickControlPrivate::unhideOldItem(control, horizontal);
++
+ layoutHorizontal();
+ horizontal->setSize(area->property("widthRatio").toReal());
+ horizontal->setPosition(area->property("xPosition").toReal());
+@@ -818,6 +826,9 @@ void QQuickScrollBarAttachedPrivate::initVertical()
+ if (parent && parent == flickable->parentItem())
+ vertical->stackAfter(flickable);
+
++ if (auto control = qobject_cast<QQuickControl*>(q_ptr->parent()))
++ QQuickControlPrivate::unhideOldItem(control, vertical);
++
+ layoutVertical();
+ vertical->setSize(area->property("heightRatio").toReal());
+ vertical->setPosition(area->property("yPosition").toReal());
+diff --git a/qtquickcontrols2/tests/auto/controls/data/tst_scrollview.qml b/qtquickcontrols2/tests/auto/controls/data/tst_scrollview.qml
+index 0e8b08352..cd4931184 100644
+--- a/qtquickcontrols2/tests/auto/controls/data/tst_scrollview.qml
++++ b/qtquickcontrols2/tests/auto/controls/data/tst_scrollview.qml
+@@ -576,4 +576,51 @@ TestCase {
+ verify(newHorizontalScrollBar.visible)
+ verify(!oldHorizontalScrollBar.visible)
+ }
++
++ Component {
++ id: bindingToContentItemAndStandaloneFlickable
++
++ Item {
++ width: 200
++ height: 200
++
++ property alias scrollView: scrollView
++
++ ScrollView {
++ id: scrollView
++ anchors.fill: parent
++ contentItem: listView
++
++ property Item someBinding: contentItem
++ }
++ ListView {
++ id: listView
++ model: 10
++ delegate: ItemDelegate {
++ text: modelData
++ width: listView.width
++ }
++ }
++ }
++ }
++
++ // Tests that scroll bars show up for a ScrollView where
++ // - its contentItem is declared as a standalone, separate item
++ // - there is a binding to contentItem (which causes a default Flickable to be created)
++ function test_bindingToContentItemAndStandaloneFlickable() {
++ let root = createTemporaryObject(bindingToContentItemAndStandaloneFlickable, testCase)
++ verify(root)
++
++ let control = root.scrollView
++ let verticalScrollBar = control.ScrollBar.vertical
++ let horizontalScrollBar = control.ScrollBar.horizontal
++ compare(verticalScrollBar.parent, control)
++ compare(horizontalScrollBar.parent, control)
++ verify(verticalScrollBar.visible)
++ verify(horizontalScrollBar.visible)
++
++ mouseDrag(verticalScrollBar, verticalScrollBar.width / 2, verticalScrollBar.height / 2, 0, 50)
++ verify(verticalScrollBar.active)
++ verify(horizontalScrollBar.active)
++ }
+ }
+diff --git a/qtquickcontrols2/tests/auto/controls/data/tst_switch.qml b/qtquickcontrols2/tests/auto/controls/data/tst_switch.qml
+index b3fab41ca..10b6baa02 100644
+--- a/qtquickcontrols2/tests/auto/controls/data/tst_switch.qml
++++ b/qtquickcontrols2/tests/auto/controls/data/tst_switch.qml
+@@ -608,4 +608,27 @@ TestCase {
+ mouseClick(control.indicator)
+ verify(control.activeFocus)
+ }
++
++ Component {
++ id: deletionOrder1
++ Item {
++ Image { id: innerImage }
++ Switch { indicator: innerImage }
++ }
++ }
++
++ Component {
++ id: deletionOrder2
++ Item {
++ Switch { indicator: innerImage }
++ Image { id: innerImage }
++ }
++ }
++
++ function test_deletionOrder() {
++ var control1 = createTemporaryObject(deletionOrder1, testCase)
++ verify(control1)
++ var control2 = createTemporaryObject(deletionOrder2, testCase)
++ verify(control2)
++ }
+ }
+diff --git a/qtquickcontrols2/tests/auto/qquickpopup/data/releaseAfterExitTransition.qml b/qtquickcontrols2/tests/auto/qquickpopup/data/releaseAfterExitTransition.qml
+new file mode 100644
+index 000000000..9e4598b9f
+--- /dev/null
++++ b/qtquickcontrols2/tests/auto/qquickpopup/data/releaseAfterExitTransition.qml
+@@ -0,0 +1,78 @@
++/****************************************************************************
++**
++** Copyright (C) 2021 The Qt Company Ltd.
++** Contact: https://www.qt.io/licensing/
++**
++** This file is part of the test suite of the Qt Toolkit.
++**
++** $QT_BEGIN_LICENSE:BSD$
++** Commercial License Usage
++** Licensees holding valid commercial Qt licenses may use this file in
++** accordance with the commercial license agreement provided with the
++** Software or, alternatively, in accordance with the terms contained in
++** a written agreement between you and The Qt Company. For licensing terms
++** and conditions see https://www.qt.io/terms-conditions. For further
++** information use the contact form at https://www.qt.io/contact-us.
++**
++** BSD License Usage
++** Alternatively, you may use this file under the terms of the BSD license
++** as follows:
++**
++** "Redistribution and use in source and binary forms, with or without
++** modification, are permitted provided that the following conditions are
++** met:
++** * Redistributions of source code must retain the above copyright
++** notice, this list of conditions and the following disclaimer.
++** * Redistributions in binary form must reproduce the above copyright
++** notice, this list of conditions and the following disclaimer in
++** the documentation and/or other materials provided with the
++** distribution.
++** * Neither the name of The Qt Company Ltd nor the names of its
++** contributors may be used to endorse or promote products derived
++** from this software without specific prior written permission.
++**
++**
++** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
++** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
++** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
++** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
++** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
++** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
++** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
++** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
++** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
++** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
++** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
++**
++** $QT_END_LICENSE$
++**
++****************************************************************************/
++
++import QtQuick 2.15
++import QtQuick.Controls 2.15
++
++ApplicationWindow {
++ id: window
++ width: 400
++ height: 400
++ title: "releaseAfterExitTransition"
++
++ property alias popup: popup
++ property alias modalPopup: modalPopup
++
++ Popup {
++ id: popup
++ y: parent.height - height
++ width: 50
++ height: 50
++ }
++
++ Popup {
++ id: modalPopup
++ modal: true
++ y: parent.height - height
++ width: 50
++ height: 50
++ exit: Transition { PauseAnimation { duration: 100 } }
++ }
++}
+diff --git a/qtquickcontrols2/tests/auto/qquickpopup/tst_qquickpopup.cpp b/qtquickcontrols2/tests/auto/qquickpopup/tst_qquickpopup.cpp
+index 54952d128..3d50e2dd4 100644
+--- a/qtquickcontrols2/tests/auto/qquickpopup/tst_qquickpopup.cpp
++++ b/qtquickcontrols2/tests/auto/qquickpopup/tst_qquickpopup.cpp
+@@ -100,6 +100,7 @@ private slots:
+ void invisibleToolTipOpen();
+ void centerInOverlayWithinStackViewItem();
+ void destroyDuringExitTransition();
++ void releaseAfterExitTransition();
+ };
+
+ void tst_QQuickPopup::initTestCase()
+@@ -1575,6 +1576,34 @@ void tst_QQuickPopup::destroyDuringExitTransition()
+ QVERIFY(!button->isDown());
+ }
+
++void tst_QQuickPopup::releaseAfterExitTransition()
++{
++ QQuickApplicationHelper helper(this, "releaseAfterExitTransition.qml");
++ QVERIFY2(helper.ready, helper.failureMessage());
++
++ QQuickWindow *window = helper.window;
++ window->show();
++ QVERIFY(QTest::qWaitForWindowActive(window));
++
++ QQuickOverlay *overlay = QQuickOverlay::overlay(window);
++ QQuickPopup *modalPopup = window->property("modalPopup").value<QQuickPopup *>();
++ QQuickPopup *popup = window->property("popup").value<QQuickPopup *>();
++
++ modalPopup->open();
++ QTRY_VERIFY(modalPopup->isOpened());
++
++ QTest::mousePress(window, Qt::LeftButton, Qt::NoModifier, QPoint(1, 1));
++ // wait until the transition is finished and the overlay hides itself
++ QTRY_VERIFY(!overlay->isVisible());
++ QTest::mouseRelease(window, Qt::LeftButton, Qt::NoModifier, QPoint(1, 1));
++
++ popup->open();
++ QTRY_VERIFY(popup->isOpened());
++ QTest::mouseClick(window, Qt::LeftButton, Qt::NoModifier, QPoint(1, 1));
++ QTRY_VERIFY(!popup->isOpened());
++}
++
++
+ QTEST_QUICKCONTROLS_MAIN(tst_QQuickPopup)
+
+ #include "tst_qquickpopup.moc"
+Submodule qtscript 5be95f96...4d8e4bd2 (commits not present)
+Submodule qtspeech 17fc9fde..255845e2:
+diff --git a/qtspeech/src/plugins/tts/speechdispatcher/qtexttospeech_speechd.cpp b/qtspeech/src/plugins/tts/speechdispatcher/qtexttospeech_speechd.cpp
+index 6eb74b8..bcc7dd1 100644
+--- a/qtspeech/src/plugins/tts/speechdispatcher/qtexttospeech_speechd.cpp
++++ b/qtspeech/src/plugins/tts/speechdispatcher/qtexttospeech_speechd.cpp
+@@ -357,7 +357,9 @@ QVector<QLocale> QTextToSpeechEngineSpeechd::availableLocales() const
+
+ QVector<QVoice> QTextToSpeechEngineSpeechd::availableVoices() const
+ {
+- return m_voices.values(m_currentLocale.name()).toVector();
++ QList<QVoice> resultList = m_voices.values(m_currentLocale.name());
++ std::reverse(resultList.begin(), resultList.end());
++ return resultList.toVector();
+ }
+
+ // We have no way of knowing our own client_id since speech-dispatcher seems to be incomplete
+Submodule qtsvg 0c05780e..a7a0f249:
+diff --git a/qtsvg/src/plugins/imageformats/svg/qsvgiohandler.cpp b/qtsvg/src/plugins/imageformats/svg/qsvgiohandler.cpp
+index 561e77e..12e0574 100644
+--- a/qtsvg/src/plugins/imageformats/svg/qsvgiohandler.cpp
++++ b/qtsvg/src/plugins/imageformats/svg/qsvgiohandler.cpp
+@@ -191,6 +191,8 @@ bool QSvgIOHandler::read(QImage *image)
+ }
+ }
+ if (!finalSize.isEmpty()) {
++ if (qMax(finalSize.width(), finalSize.height()) > 0xffff)
++ return false; // Assume corrupted file
+ image->fill(d->backColor.rgba());
+ QPainter p(image);
+ d->r.render(&p, bounds);
+diff --git a/qtsvg/src/svg/qsvghandler.cpp b/qtsvg/src/svg/qsvghandler.cpp
+index a5f877f..8dda563 100644
+--- a/qtsvg/src/svg/qsvghandler.cpp
++++ b/qtsvg/src/svg/qsvghandler.cpp
+@@ -1393,9 +1393,10 @@ static void parseFont(QSvgNode *node,
+ case FontSizeNone:
+ break;
+ case FontSizeValue: {
+- QSvgHandler::LengthType dummy; // should always be pixel size
+- fontStyle->setSize(qMin(parseLength(attributes.fontSize, dummy, handler),
+- qreal(0xffff)));
++ QSvgHandler::LengthType type;
++ qreal fs = parseLength(attributes.fontSize, type, handler);
++ fs = convertToPixels(fs, true, type);
++ fontStyle->setSize(qMin(fs, qreal(0xffff)));
+ }
+ break;
+ default:
+@@ -2513,6 +2514,8 @@ static bool parseAnimateTransformNode(QSvgNode *parent,
+ ++s;
+ }
+ }
++ if (vals.count() % 3 != 0)
++ return false;
+
+ bool ok = true;
+ int begin = parseClockValue(beginStr, &ok);
+@@ -2576,6 +2579,8 @@ static QSvgNode *createCircleNode(QSvgNode *parent,
+ qreal ncx = toDouble(cx);
+ qreal ncy = toDouble(cy);
+ qreal nr = toDouble(r);
++ if (nr < 0.0)
++ return nullptr;
+
+ QRectF rect(ncx-nr, ncy-nr, nr*2, nr*2);
+ QSvgNode *circle = new QSvgCircle(parent, rect);
+@@ -3046,15 +3051,16 @@ static QSvgStyleProperty *createRadialGradientNode(QSvgNode *node,
+
+ qreal ncx = 0.5;
+ qreal ncy = 0.5;
+- qreal nr = 0.5;
+ if (!cx.isEmpty())
+ ncx = toDouble(cx);
+ if (!cy.isEmpty())
+ ncy = toDouble(cy);
++
++ qreal nr = 0.0;
+ if (!r.isEmpty())
+ nr = toDouble(r);
+- if (nr < 0.5)
+- nr = 0.5;
++ if (nr <= 0.0)
++ return nullptr;
+
+ qreal nfx = ncx;
+ if (!fx.isEmpty())
+@@ -3350,7 +3356,9 @@ static QSvgNode *createTextNode(QSvgNode *parent,
+ //### editable and rotate not handled
+ QSvgHandler::LengthType type;
+ qreal nx = parseLength(x, type, handler);
++ nx = convertToPixels(nx, true, type);
+ qreal ny = parseLength(y, type, handler);
++ ny = convertToPixels(ny, true, type);
+
+ QSvgNode *text = new QSvgText(parent, QPointF(nx, ny));
+ return text;
+@@ -3691,9 +3699,7 @@ void QSvgHandler::parse()
+ case QXmlStreamReader::EndElement:
+ endElement(xml->name());
+ ++remainingUnfinishedElements;
+- // if we are using somebody else's qxmlstreamreader
+- // we should not read until the end of the stream
+- done = !m_ownsReader && (xml->name() == QLatin1String("svg"));
++ done = (xml->name() == QLatin1String("svg"));
+ break;
+ case QXmlStreamReader::Characters:
+ characters(xml->text());
+diff --git a/qtsvg/src/svg/qsvgstructure.cpp b/qtsvg/src/svg/qsvgstructure.cpp
+index b89608b..89c9e4e 100644
+--- a/qtsvg/src/svg/qsvgstructure.cpp
++++ b/qtsvg/src/svg/qsvgstructure.cpp
+@@ -255,9 +255,13 @@ inline static bool isSupportedSvgFeature(const QString &str)
+ };
+
+ if (str.length() <= MAX_WORD_LENGTH && str.length() >= MIN_WORD_LENGTH) {
++ const char16_t unicode44 = str.at(44).unicode();
++ const char16_t unicode45 = str.at(45).unicode();
++ if (unicode44 >= sizeof(asso_values) || unicode45 >= sizeof(asso_values))
++ return false;
+ const int key = str.length()
+- + asso_values[str.at(45).unicode()]
+- + asso_values[str.at(44).unicode()];
++ + asso_values[unicode45]
++ + asso_values[unicode44];
+ if (key <= MAX_HASH_VALUE && key >= 0)
+ return str == QLatin1String(wordlist[key]);
+ }
+diff --git a/qtsvg/src/svg/qsvgtinydocument.cpp b/qtsvg/src/svg/qsvgtinydocument.cpp
+index 63d0797..19e7154 100644
+--- a/qtsvg/src/svg/qsvgtinydocument.cpp
++++ b/qtsvg/src/svg/qsvgtinydocument.cpp
+@@ -433,8 +433,16 @@ void QSvgTinyDocument::draw(QPainter *p, QSvgExtraStates &)
+ draw(p);
+ }
+
++static bool isValidMatrix(const QTransform &transform)
++{
++ qreal determinant = transform.determinant();
++ return qIsFinite(determinant);
++}
++
+ void QSvgTinyDocument::mapSourceToTarget(QPainter *p, const QRectF &targetRect, const QRectF &sourceRect)
+ {
++ QTransform oldTransform = p->worldTransform();
++
+ QRectF target = targetRect;
+ if (target.isEmpty()) {
+ QPaintDevice *dev = p->device();
+@@ -487,6 +495,9 @@ void QSvgTinyDocument::mapSourceToTarget(QPainter *p, const QRectF &targetRect,
+ }
+ #endif
+ }
++
++ if (!isValidMatrix(p->worldTransform()))
++ p->setWorldTransform(oldTransform);
+ }
+
+ QRectF QSvgTinyDocument::boundsOnElement(const QString &id) const
+diff --git a/qtsvg/tests/auto/qsvgrenderer/tst_qsvgrenderer.cpp b/qtsvg/tests/auto/qsvgrenderer/tst_qsvgrenderer.cpp
+index 36c76ec..db71e02 100644
+--- a/qtsvg/tests/auto/qsvgrenderer/tst_qsvgrenderer.cpp
++++ b/qtsvg/tests/auto/qsvgrenderer/tst_qsvgrenderer.cpp
+@@ -86,6 +86,8 @@ private slots:
+ void oss_fuzz_23731();
+ void oss_fuzz_24131();
+ void oss_fuzz_24738();
++ void illegalAnimateTransform_data();
++ void illegalAnimateTransform();
+
+ #ifndef QT_NO_COMPRESS
+ void testGzLoading();
+@@ -1646,5 +1648,22 @@ void tst_QSvgRenderer::oss_fuzz_24738()
+ QSvgRenderer().load(QByteArray("<svg><path d=\"a 2 1e-212.....\">"));
+ }
+
++void tst_QSvgRenderer::illegalAnimateTransform_data()
++{
++ QTest::addColumn<QByteArray>("svg");
++
++ QTest::newRow("case1") << QByteArray("<svg><animateTransform type=\"rotate\" begin=\"1\" dur=\"2\" values=\"8,0,5,0\">");
++ QTest::newRow("case2") << QByteArray("<svg><animateTransform type=\"rotate\" begin=\"1\" dur=\"2\" values=\"1,2\">");
++ QTest::newRow("case3") << QByteArray("<svg><animateTransform type=\"rotate\" begin=\"1\" dur=\"2\" from=\".. 5 2\" to=\"f\">");
++ QTest::newRow("case4") << QByteArray("<svg><animateTransform type=\"scale\" begin=\"1\" dur=\"2\" by=\"--,..\">");
++}
++
++void tst_QSvgRenderer::illegalAnimateTransform()
++{
++ QFETCH(QByteArray, svg);
++ QSvgRenderer renderer;
++ QVERIFY(!renderer.load(svg)); // also shouldn't assert
++}
++
+ QTEST_MAIN(tst_QSvgRenderer)
+ #include "tst_qsvgrenderer.moc"
+Submodule qttools 6914f7c8..090e526e:
+diff --git a/qttools/src/assistant/qhelpgenerator/helpgenerator.cpp b/qttools/src/assistant/qhelpgenerator/helpgenerator.cpp
+index feab1e2d5..cbfb82507 100644
+--- a/qttools/src/assistant/qhelpgenerator/helpgenerator.cpp
++++ b/qttools/src/assistant/qhelpgenerator/helpgenerator.cpp
+@@ -445,7 +445,9 @@ bool HelpGeneratorPrivate::insertFiles(const QStringList &files, const QString &
+ if (filterSetId < 0)
+ return false;
+ ++filterSetId;
+- for (int attId : qAsConst(filterAtts)) {
++ QList<int> attValues = filterAtts.values();
++ std::sort(attValues.begin(), attValues.end());
++ for (int attId : qAsConst(attValues)) {
+ m_query->prepare(QLatin1String("INSERT INTO FileAttributeSetTable "
+ "VALUES(?, ?)"));
+ m_query->bindValue(0, filterSetId);
+Submodule qtwayland dfb0129c..2904e1b3:
+diff --git a/qtwayland/src/client/configure.json b/qtwayland/src/client/configure.json
+index 2f424580..29222357 100644
+--- a/qtwayland/src/client/configure.json
++++ b/qtwayland/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/qtwayland/src/client/global/qwaylandclientextension.cpp b/qtwayland/src/client/global/qwaylandclientextension.cpp
+index 125b1e19..edccfe63 100644
+--- a/qtwayland/src/client/global/qwaylandclientextension.cpp
++++ b/qtwayland/src/client/global/qwaylandclientextension.cpp
+@@ -74,7 +74,10 @@ void QWaylandClientExtensionPrivate::handleRegistryGlobal(void *data, ::wl_regis
+ void QWaylandClientExtension::addRegistryListener()
+ {
+ Q_D(QWaylandClientExtension);
+- d->waylandIntegration->display()->addRegistryListener(&QWaylandClientExtensionPrivate::handleRegistryGlobal, this);
++ if (!d->registered) {
++ d->waylandIntegration->display()->addRegistryListener(&QWaylandClientExtensionPrivate::handleRegistryGlobal, this);
++ d->registered = true;
++ }
+ }
+
+ QWaylandClientExtension::QWaylandClientExtension(const int ver)
+@@ -88,6 +91,13 @@ QWaylandClientExtension::QWaylandClientExtension(const int ver)
+ QMetaObject::invokeMethod(this, "addRegistryListener", Qt::QueuedConnection);
+ }
+
++QWaylandClientExtension::~QWaylandClientExtension()
++{
++ Q_D(QWaylandClientExtension);
++ if (d->registered && !QCoreApplication::closingDown())
++ d->waylandIntegration->display()->removeListener(&QWaylandClientExtensionPrivate::handleRegistryGlobal, this);
++}
++
+ QtWaylandClient::QWaylandIntegration *QWaylandClientExtension::integration() const
+ {
+ Q_D(const QWaylandClientExtension);
+diff --git a/qtwayland/src/client/global/qwaylandclientextension.h b/qtwayland/src/client/global/qwaylandclientextension.h
+index 98272e57..5bd28398 100644
+--- a/qtwayland/src/client/global/qwaylandclientextension.h
++++ b/qtwayland/src/client/global/qwaylandclientextension.h
+@@ -63,6 +63,7 @@ class Q_WAYLAND_CLIENT_EXPORT QWaylandClientExtension : public QObject
+ Q_PROPERTY(bool active READ isActive NOTIFY activeChanged)
+ public:
+ QWaylandClientExtension(const int version);
++ ~QWaylandClientExtension();
+
+ QtWaylandClient::QWaylandIntegration *integration() const;
+ int version() const;
+diff --git a/qtwayland/src/client/global/qwaylandclientextension_p.h b/qtwayland/src/client/global/qwaylandclientextension_p.h
+index 69cc46a0..9091efbe 100644
+--- a/qtwayland/src/client/global/qwaylandclientextension_p.h
++++ b/qtwayland/src/client/global/qwaylandclientextension_p.h
+@@ -68,6 +68,7 @@ public:
+ QtWaylandClient::QWaylandIntegration *waylandIntegration = nullptr;
+ int version = -1;
+ bool active = false;
++ bool registered = false;
+ };
+
+ class Q_WAYLAND_CLIENT_EXPORT QWaylandClientExtensionTemplatePrivate : public QWaylandClientExtensionPrivate
+diff --git a/qtwayland/src/client/qwaylanddatadevice.cpp b/qtwayland/src/client/qwaylanddatadevice.cpp
+index 7e2e3308..e3e60ed5 100644
+--- a/qtwayland/src/client/qwaylanddatadevice.cpp
++++ b/qtwayland/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,7 +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::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;
+@@ -152,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;
+ }
+@@ -162,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();
+ }
+ }
+
+@@ -186,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,
+@@ -197,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()
+@@ -235,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());
+
+@@ -246,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)
+
+@@ -277,14 +296,10 @@ void QWaylandDataDevice::selectionSourceCancelled()
+ #if QT_CONFIG(draganddrop)
+ void QWaylandDataDevice::dragSourceCancelled()
+ {
++ static_cast<QWaylandDrag *>(QGuiApplicationPrivate::platformIntegration()->drag())->finishDrag();
+ 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));
+@@ -297,6 +312,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/qtwayland/src/client/qwaylanddatadevice_p.h b/qtwayland/src/client/qwaylanddatadevice_p.h
+index 16c3ad28..801dcc2c 100644
+--- a/qtwayland/src/client/qwaylanddatadevice_p.h
++++ b/qtwayland/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/qtwayland/src/client/qwaylanddatadevicemanager.cpp b/qtwayland/src/client/qwaylanddatadevicemanager.cpp
+index 35d67307..6dc4f77f 100644
+--- a/qtwayland/src/client/qwaylanddatadevicemanager.cpp
++++ b/qtwayland/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/qtwayland/src/client/qwaylanddatadevicemanager_p.h b/qtwayland/src/client/qwaylanddatadevicemanager_p.h
+index bd05c0fb..510d9be4 100644
+--- a/qtwayland/src/client/qwaylanddatadevicemanager_p.h
++++ b/qtwayland/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/qtwayland/src/client/qwaylanddataoffer.cpp b/qtwayland/src/client/qwaylanddataoffer.cpp
+index 2297e8a1..fe0ea8c9 100644
+--- a/qtwayland/src/client/qwaylanddataoffer.cpp
++++ b/qtwayland/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)
+ {
+@@ -163,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");
+diff --git a/qtwayland/src/client/qwaylanddataoffer_p.h b/qtwayland/src/client/qwaylanddataoffer_p.h
+index 9cf1483c..6f667398 100644
+--- a/qtwayland/src/client/qwaylanddataoffer_p.h
++++ b/qtwayland/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/qtwayland/src/client/qwaylanddatasource.cpp b/qtwayland/src/client/qwaylanddatasource.cpp
+index f45122fb..5599cbd4 100644
+--- a/qtwayland/src/client/qwaylanddatasource.cpp
++++ b/qtwayland/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/qtwayland/src/client/qwaylanddatasource_p.h b/qtwayland/src/client/qwaylanddatasource_p.h
+index 25afff79..96f07bc3 100644
+--- a/qtwayland/src/client/qwaylanddatasource_p.h
++++ b/qtwayland/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/qtwayland/src/client/qwaylanddisplay.cpp b/qtwayland/src/client/qwaylanddisplay.cpp
+index f10c1f79..c01e238b 100644
+--- a/qtwayland/src/client/qwaylanddisplay.cpp
++++ b/qtwayland/src/client/qwaylanddisplay.cpp
+@@ -85,10 +85,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)
+@@ -158,17 +351,16 @@ 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)
+ {
++ if (m_eventThread)
++ m_eventThread->stop();
++
++ if (m_frameEventQueueThread)
++ m_frameEventQueueThread->stop();
++
+ if (mSyncCallback)
+ wl_callback_destroy(mSyncCallback);
+
+@@ -187,6 +379,21 @@ 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
++// 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()
+@@ -203,98 +410,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
+@@ -345,7 +491,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));
+@@ -354,7 +500,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));
+@@ -369,6 +515,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));
+@@ -427,6 +575,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;
+ }
+@@ -452,9 +607,10 @@ void QWaylandDisplay::addRegistryListener(RegistryListener listener, void *data)
+
+ void QWaylandDisplay::removeListener(RegistryListener listener, void *data)
+ {
+- std::remove_if(mRegistryListeners.begin(), mRegistryListeners.end(), [=](Listener l){
++ auto iter = std::remove_if(mRegistryListeners.begin(), mRegistryListeners.end(), [=](Listener l){
+ return (l.listener == listener && l.data == data);
+ });
++ mRegistryListeners.erase(iter, mRegistryListeners.end());
+ }
+
+ uint32_t QWaylandDisplay::currentTimeMillisec()
+@@ -467,50 +623,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
+@@ -574,14 +689,10 @@ void QWaylandDisplay::handleKeyboardFocusChanged(QWaylandInputDevice *inputDevic
+ if (mLastKeyboardFocus == keyboardFocus)
+ return;
+
+- if (mWaylandIntegration->mShellIntegration) {
+- mWaylandIntegration->mShellIntegration->handleKeyboardFocusChanged(keyboardFocus, mLastKeyboardFocus);
+- } else {
+- if (keyboardFocus)
+- handleWindowActivated(keyboardFocus);
+- if (mLastKeyboardFocus)
+- handleWindowDeactivated(mLastKeyboardFocus);
+- }
++ if (keyboardFocus)
++ handleWindowActivated(keyboardFocus);
++ if (mLastKeyboardFocus)
++ handleWindowDeactivated(mLastKeyboardFocus);
+
+ mLastKeyboardFocus = keyboardFocus;
+ }
+@@ -600,6 +711,19 @@ void QWaylandDisplay::handleWaylandSync()
+ QWindow *activeWindow = mActiveWindows.empty() ? nullptr : mActiveWindows.last()->window();
+ if (activeWindow != QGuiApplication::focusWindow())
+ QWindowSystemInterface::handleWindowActivated(activeWindow);
++
++ if (!activeWindow) {
++ if (lastInputDevice()) {
++#if QT_CONFIG(clipboard)
++ if (auto *dataDevice = lastInputDevice()->dataDevice())
++ dataDevice->invalidateSelectionOffer();
++#endif
++#if QT_CONFIG(wayland_client_primary_selection)
++ if (auto *device = lastInputDevice()->primarySelectionDevice())
++ device->invalidateSelectionOffer();
++#endif
++ }
++ }
+ }
+
+ const wl_callback_listener QWaylandDisplay::syncCallbackListener = {
+@@ -626,6 +750,13 @@ QWaylandInputDevice *QWaylandDisplay::defaultInputDevice() const
+ return mInputDevices.isEmpty() ? 0 : mInputDevices.first();
+ }
+
++bool QWaylandDisplay::isKeyboardAvailable() const
++{
++ return std::any_of(
++ mInputDevices.constBegin(), mInputDevices.constEnd(),
++ [this](const QWaylandInputDevice *device) { return device->keyboard() != nullptr; });
++}
++
+ #if QT_CONFIG(cursor)
+
+ QWaylandCursor *QWaylandDisplay::waylandCursor()
+@@ -652,4 +783,6 @@ QWaylandCursorTheme *QWaylandDisplay::loadCursorTheme(const QString &name, int p
+
+ } // namespace QtWaylandClient
+
++#include "qwaylanddisplay.moc"
++
+ QT_END_NAMESPACE
+diff --git a/qtwayland/src/client/qwaylanddisplay_p.h b/qtwayland/src/client/qwaylanddisplay_p.h
+index 3b092bc8..42bc661d 100644
+--- a/qtwayland/src/client/qwaylanddisplay_p.h
++++ b/qtwayland/src/client/qwaylanddisplay_p.h
+@@ -109,6 +109,7 @@ class QWaylandSurface;
+ class QWaylandShellIntegration;
+ class QWaylandCursor;
+ class QWaylandCursorTheme;
++class EventThread;
+
+ typedef void (*RegistryListener)(void *data,
+ struct wl_registry *registry,
+@@ -120,15 +121,11 @@ 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;
+
++ void initialize();
++
+ #if QT_CONFIG(xkbcommon)
+ struct xkb_context *xkbContext() const { return mXkbContext.get(); }
+ #endif
+@@ -210,11 +207,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();
+@@ -237,6 +234,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;
+@@ -273,11 +273,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/qtwayland/src/client/qwaylanddnd.cpp b/qtwayland/src/client/qwaylanddnd.cpp
+index 6535aa16..7c53f5fa 100644
+--- a/qtwayland/src/client/qwaylanddnd.cpp
++++ b/qtwayland/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
+@@ -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)
+@@ -103,33 +106,41 @@ 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);
++
++ if (drag())
++ drag()->deleteLater();
++}
++
++bool QWaylandDrag::ownsDragObject() const
++{
++ return true;
+ }
+
+ }
+diff --git a/qtwayland/src/client/qwaylanddnd_p.h b/qtwayland/src/client/qwaylanddnd_p.h
+index 474fe2ab..46f629ac 100644
+--- a/qtwayland/src/client/qwaylanddnd_p.h
++++ b/qtwayland/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;
+@@ -82,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;
+diff --git a/qtwayland/src/client/qwaylandinputdevice.cpp b/qtwayland/src/client/qwaylandinputdevice.cpp
+index 613fe862..4b90de84 100644
+--- a/qtwayland/src/client/qwaylandinputdevice.cpp
++++ b/qtwayland/src/client/qwaylandinputdevice.cpp
+@@ -685,6 +685,11 @@ public:
+
+ void QWaylandInputDevice::Pointer::pointer_leave(uint32_t time, struct wl_surface *surface)
+ {
++ invalidateFocus();
++ mButtons = Qt::NoButton;
++
++ mParent->mTime = time;
++
+ // The event may arrive after destroying the window, indicated by
+ // a null surface.
+ if (!surface)
+@@ -696,11 +701,6 @@ void QWaylandInputDevice::Pointer::pointer_leave(uint32_t time, struct wl_surfac
+
+ if (!QWaylandWindow::mouseGrab())
+ setFrameEvent(new LeaveEvent(window, mSurfacePos, mGlobalPos));
+-
+- invalidateFocus();
+- mButtons = Qt::NoButton;
+-
+- mParent->mTime = time;
+ }
+
+ class MotionEvent : public QWaylandPointerEvent
+@@ -1300,14 +1300,6 @@ void QWaylandInputDevice::Keyboard::handleFocusDestroyed()
+ void QWaylandInputDevice::Keyboard::handleFocusLost()
+ {
+ mFocus = nullptr;
+-#if QT_CONFIG(clipboard)
+- if (auto *dataDevice = mParent->dataDevice())
+- dataDevice->invalidateSelectionOffer();
+-#endif
+-#if QT_CONFIG(wayland_client_primary_selection)
+- if (auto *device = mParent->primarySelectionDevice())
+- device->invalidateSelectionOffer();
+-#endif
+ mParent->mQDisplay->handleKeyboardFocusChanged(mParent);
+ mRepeatTimer.stop();
+ }
+@@ -1396,6 +1388,7 @@ void QWaylandInputDevice::Touch::touch_cancel()
+ if (touchExt)
+ touchExt->touchCanceled();
+
++ mFocus = nullptr;
+ QWindowSystemInterface::handleTouchCancelEvent(nullptr, mParent->mTouchDevice);
+ }
+
+diff --git a/qtwayland/src/client/qwaylandintegration.cpp b/qtwayland/src/client/qwaylandintegration.cpp
+index c53ccb78..54861600 100644
+--- a/qtwayland/src/client/qwaylandintegration.cpp
++++ b/qtwayland/src/client/qwaylandintegration.cpp
+@@ -125,6 +125,9 @@ QWaylandIntegration::QWaylandIntegration()
+ #endif
+
+ reconfigureInputContext();
++
++ QWaylandWindow::fixedToplevelPositions =
++ !qEnvironmentVariableIsSet("QT_WAYLAND_DISABLE_FIXED_POSITIONS");
+ }
+
+ QWaylandIntegration::~QWaylandIntegration()
+@@ -192,14 +195,18 @@ QAbstractEventDispatcher *QWaylandIntegration::createEventDispatcher() const
+
+ void QWaylandIntegration::initialize()
+ {
++ mDisplay->initEventThread();
++
++ // 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()));
+
+- 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()));
+-
+ // Qt does not support running with no screens
+ mDisplay->ensureScreen();
+ }
+@@ -262,6 +269,14 @@ QWaylandDisplay *QWaylandIntegration::display() const
+ return mDisplay.data();
+ }
+
++Qt::KeyboardModifiers QWaylandIntegration::queryKeyboardModifiers() const
++{
++ if (auto *seat = mDisplay->currentInputDevice()) {
++ return seat->modifiers();
++ }
++ return Qt::NoModifier;
++}
++
+ QList<int> QWaylandIntegration::possibleKeys(const QKeyEvent *event) const
+ {
+ if (auto *seat = mDisplay->currentInputDevice())
+@@ -479,7 +494,7 @@ void QWaylandIntegration::reconfigureInputContext()
+ }
+ #endif
+
+- qCDebug(lcQpaWayland) << "using input method:" << inputContext()->metaObject()->className();
++ qCDebug(lcQpaWayland) << "using input method:" << (inputContext() ? inputContext()->metaObject()->className() : "<none>");
+ }
+
+ QWaylandShellIntegration *QWaylandIntegration::createShellIntegration(const QString &integrationName)
+diff --git a/qtwayland/src/client/qwaylandintegration_p.h b/qtwayland/src/client/qwaylandintegration_p.h
+index ff70ae25..73b80658 100644
+--- a/qtwayland/src/client/qwaylandintegration_p.h
++++ b/qtwayland/src/client/qwaylandintegration_p.h
+@@ -107,6 +107,8 @@ public:
+
+ QWaylandDisplay *display() const;
+
++ Qt::KeyboardModifiers queryKeyboardModifiers() const override;
++
+ QList<int> possibleKeys(const QKeyEvent *event) const override;
+
+ QStringList themeNames() const override;
+diff --git a/qtwayland/src/client/qwaylandprimaryselectionv1.cpp b/qtwayland/src/client/qwaylandprimaryselectionv1.cpp
+index 832f9678..ea508771 100644
+--- a/qtwayland/src/client/qwaylandprimaryselectionv1.cpp
++++ b/qtwayland/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)
+diff --git a/qtwayland/src/client/qwaylandscreen.cpp b/qtwayland/src/client/qwaylandscreen.cpp
+index 6cb337de..5537dafd 100644
+--- a/qtwayland/src/client/qwaylandscreen.cpp
++++ b/qtwayland/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))
+@@ -72,7 +72,7 @@ QWaylandScreen::QWaylandScreen(QWaylandDisplay *waylandDisplay, int version, uin
+ qCWarning(lcQpaWayland) << "wl_output done event not supported by compositor,"
+ << "QScreen may not work correctly";
+ mWaylandDisplay->forceRoundTrip(); // Give the compositor a chance to send geometry etc.
+- mOutputDone = true; // Fake the done event
++ mProcessedEvents |= OutputDoneEvent; // Fake the done event
+ maybeInitialize();
+ }
+ }
+@@ -81,16 +81,29 @@ 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
++{
++ uint ret = OutputDoneEvent;
++
++ if (mWaylandDisplay->xdgOutputManager()) {
++ ret |= XdgOutputNameEvent;
++
++ if (mWaylandDisplay->xdgOutputManager()->version() < 3)
++ ret |= XdgOutputDoneEvent;
++ }
++ return ret;
+ }
+
+ void QWaylandScreen::maybeInitialize()
+ {
+ Q_ASSERT(!mInitialized);
+
+- if (!mOutputDone)
+- return;
+-
+- if (mWaylandDisplay->xdgOutputManager() && !mXdgOutputDone)
++ const uint requiredEvents = this->requiredEvents();
++ if ((mProcessedEvents & requiredEvents) != requiredEvents)
+ return;
+
+ mInitialized = true;
+@@ -276,9 +289,8 @@ void QWaylandScreen::output_scale(int32_t factor)
+
+ void QWaylandScreen::output_done()
+ {
+- mOutputDone = true;
+- if (zxdg_output_v1::isInitialized() && mWaylandDisplay->xdgOutputManager()->version() >= 3)
+- mXdgOutputDone = true;
++ mProcessedEvents |= OutputDoneEvent;
++
+ if (mInitialized) {
+ updateOutputProperties();
+ if (zxdg_output_v1::isInitialized())
+@@ -339,7 +351,7 @@ void QWaylandScreen::zxdg_output_v1_done()
+ if (Q_UNLIKELY(mWaylandDisplay->xdgOutputManager()->version() >= 3))
+ qWarning(lcQpaWayland) << "zxdg_output_v1.done received on version 3 or newer, this is most likely a bug in the compositor";
+
+- mXdgOutputDone = true;
++ mProcessedEvents |= XdgOutputDoneEvent;
+ if (mInitialized)
+ updateXdgOutputProperties();
+ else
+@@ -348,7 +360,11 @@ void QWaylandScreen::zxdg_output_v1_done()
+
+ void QWaylandScreen::zxdg_output_v1_name(const QString &name)
+ {
++ if (Q_UNLIKELY(mInitialized))
++ qWarning(lcQpaWayland) << "zxdg_output_v1.name received after output has been initialized, this is most likely a bug in the compositor";
++
+ mOutputName = name;
++ mProcessedEvents |= XdgOutputNameEvent;
+ }
+
+ void QWaylandScreen::updateXdgOutputProperties()
+diff --git a/qtwayland/src/client/qwaylandscreen_p.h b/qtwayland/src/client/qwaylandscreen_p.h
+index df1c94f2..050cfdc0 100644
+--- a/qtwayland/src/client/qwaylandscreen_p.h
++++ b/qtwayland/src/client/qwaylandscreen_p.h
+@@ -116,6 +116,13 @@ public:
+ static QWaylandScreen *fromWlOutput(::wl_output *output);
+
+ private:
++ enum Event : uint {
++ XdgOutputDoneEvent = 0x1,
++ OutputDoneEvent = 0x2,
++ XdgOutputNameEvent = 0x4,
++ };
++ uint requiredEvents() const;
++
+ void output_mode(uint32_t flags, int width, int height, int refresh) override;
+ void output_geometry(int32_t x, int32_t y,
+ int32_t width, int32_t height,
+@@ -148,8 +155,7 @@ private:
+ QSize mPhysicalSize;
+ QString mOutputName;
+ Qt::ScreenOrientation m_orientation = Qt::PrimaryOrientation;
+- bool mOutputDone = false;
+- bool mXdgOutputDone = false;
++ uint mProcessedEvents = 0;
+ bool mInitialized = false;
+
+ #if QT_CONFIG(cursor)
+diff --git a/qtwayland/src/client/qwaylandshmbackingstore.cpp b/qtwayland/src/client/qwaylandshmbackingstore.cpp
+index dc7ff670..41cffdf7 100644
+--- a/qtwayland/src/client/qwaylandshmbackingstore.cpp
++++ b/qtwayland/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
+@@ -74,8 +78,10 @@ QWaylandShmBuffer::QWaylandShmBuffer(QWaylandDisplay *display,
+ int alloc = stride * size.height();
+ int fd = -1;
+
+-#ifdef SYS_memfd_create
+- fd = syscall(SYS_memfd_create, "wayland-shm", MFD_CLOEXEC);
++#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);
+ #endif
+
+ QScopedPointer<QFile> filePointer;
+diff --git a/qtwayland/src/client/qwaylandwindow.cpp b/qtwayland/src/client/qwaylandwindow.cpp
+index cb82857a..fb2c59dc 100644
+--- a/qtwayland/src/client/qwaylandwindow.cpp
++++ b/qtwayland/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,9 +94,6 @@ QWaylandWindow::QWaylandWindow(QWindow *window, QWaylandDisplay *display)
+
+ QWaylandWindow::~QWaylandWindow()
+ {
+- mDisplay->destroyFrameQueue(mFrameQueue);
+- mDisplay->handleWindowDestroyed(this);
+-
+ delete mWindowDecoration;
+
+ if (mSurface)
+@@ -243,6 +239,7 @@ bool QWaylandWindow::shouldCreateSubSurface() const
+
+ void QWaylandWindow::reset()
+ {
++ closeChildPopups();
+ delete mShellSurface;
+ mShellSurface = nullptr;
+ delete mSubSurfaceWindow;
+@@ -255,17 +252,22 @@ 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();
+ mQueuedBuffer = nullptr;
++
++ mDisplay->handleWindowDestroyed(this);
+ }
+
+ QWaylandWindow *QWaylandWindow::fromWlSurface(::wl_surface *surface)
+@@ -351,19 +353,25 @@ 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()) {
+ 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());
+@@ -374,7 +382,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)
+@@ -399,21 +407,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);
+@@ -433,10 +426,7 @@ void QWaylandWindow::setVisible(bool visible)
+ lastVisible = visible;
+
+ if (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
+@@ -444,7 +434,6 @@ void QWaylandWindow::setVisible(bool visible)
+ // QWaylandShmBackingStore::beginPaint().
+ } else {
+ sendExposeEvent(QRect());
+- closePopups(this);
+ reset();
+ }
+ }
+@@ -556,12 +545,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();
+
+@@ -583,7 +572,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)
+@@ -619,8 +612,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();
+@@ -635,42 +634,53 @@ 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);
+- 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();
+
+ // 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;
+- };
++ 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();
++ };
+
++ 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();
+ }
+
+ 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";
+@@ -868,6 +878,17 @@ bool QWaylandWindow::createDecoration()
+ subsurf->set_position(pos.x() + m.left(), pos.y() + m.top());
+ }
+ sendExposeEvent(QRect(QPoint(), geometry().size()));
++
++ // This is a special case where the buffer is recreated, but since
++ // the content rect remains the same, the widgets remain the same
++ // size and are not redrawn, leaving the new buffer empty. As a simple
++ // work-around, we trigger a full extra update whenever the client-side
++ // window decorations are toggled while the window is showing.
++ // Note: createDecoration() is sometimes called from the render thread
++ // of Qt Quick. This is essentially wrong and could potentially cause problems,
++ // but until the underlying issue has been fixed, we have to use invokeMethod()
++ // here to avoid asserts.
++ QMetaObject::invokeMethod(window(), &QWindow::requestUpdate);
+ }
+
+ return mWindowDecoration;
+@@ -1023,6 +1044,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) {
+@@ -1094,10 +1122,18 @@ bool QWaylandWindow::setMouseGrabEnabled(bool grab)
+ return true;
+ }
+
++Qt::WindowStates QWaylandWindow::windowStates() const
++{
++ return mLastReportedWindowStates;
++}
++
+ void QWaylandWindow::handleWindowStatesChanged(Qt::WindowStates states)
+ {
+ createDecoration();
+- QWindowSystemInterface::handleWindowStateChanged(window(), states, mLastReportedWindowStates);
++ Qt::WindowStates statesWithoutActive = states & ~Qt::WindowActive;
++ Qt::WindowStates lastStatesWithoutActive = mLastReportedWindowStates & ~Qt::WindowActive;
++ QWindowSystemInterface::handleWindowStateChanged(window(), statesWithoutActive,
++ lastStatesWithoutActive);
+ mLastReportedWindowStates = states;
+ }
+
+@@ -1139,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()
+@@ -1160,8 +1201,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
+@@ -1174,7 +1218,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);
+ }
+@@ -1185,19 +1234,18 @@ void QWaylandWindow::requestUpdate()
+ void QWaylandWindow::handleUpdate()
+ {
+ qCDebug(lcWaylandBackingstore) << "handleUpdate" << QThread::currentThread();
++
+ // TODO: Should sync subsurfaces avoid requesting frame callbacks?
+ QReadLocker lock(&mSurfaceLock);
+ if (!mSurface)
+ return;
+
+- if (mFrameCallback) {
+- wl_callback_destroy(mFrameCallback);
+- mFrameCallback = nullptr;
+- }
++ QMutexLocker locker(&mFrameSyncMutex);
++ if (mWaitingForFrameCallback)
++ return;
+
+- 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);
++ 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);
+@@ -1207,6 +1255,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);
+@@ -1267,6 +1317,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/qtwayland/src/client/qwaylandwindow_p.h b/qtwayland/src/client/qwaylandwindow_p.h
+index 01337cff..2f219d8c 100644
+--- a/qtwayland/src/client/qwaylandwindow_p.h
++++ b/qtwayland/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;
+@@ -148,6 +151,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;
+@@ -206,6 +210,10 @@ public:
+ void handleUpdate();
+ void deliverUpdateRequest() override;
+
++ void addChildPopup(QWaylandWindow* child);
++ void removeChildPopup(QWaylandWindow* child);
++ void closeChildPopups();
++
+ public slots:
+ void applyConfigure();
+
+@@ -215,7 +223,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;
+@@ -225,13 +237,14 @@ protected:
+ Qt::MouseButtons mMousePressedInContentArea = Qt::NoButton;
+
+ 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;
+- QWaylandDisplay::FrameQueue mFrameQueue;
++ 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;
+
+ // True when we have called deliverRequestUpdate, but the client has not yet attached a new buffer
+@@ -261,6 +274,8 @@ protected:
+ QWaylandBuffer *mQueuedBuffer = nullptr;
+ QRegion mQueuedBufferDamage;
+
++ QList<QPointer<QWaylandWindow>> mChildPopups;
++
+ private:
+ void setGeometry_helper(const QRect &rect);
+ void initWindow();
+@@ -283,12 +298,10 @@ private:
+ QRect mLastExposeGeometry;
+
+ static const wl_callback_listener callbackListener;
+- void handleFrameCallback();
++ void handleFrameCallback(struct ::wl_callback* callback);
+
+ static QWaylandWindow *mMouseGrab;
+
+- mutable QReadWriteLock mSurfaceLock;
+-
+ friend class QWaylandSubSurface;
+ };
+
+diff --git a/qtwayland/src/client/shellintegration/qwaylandshellintegration_p.h b/qtwayland/src/client/shellintegration/qwaylandshellintegration_p.h
+index ccad0048..4cc9b3b8 100644
+--- a/qtwayland/src/client/shellintegration/qwaylandshellintegration_p.h
++++ b/qtwayland/src/client/shellintegration/qwaylandshellintegration_p.h
+@@ -73,11 +73,10 @@ public:
+ return true;
+ }
+ virtual QWaylandShellSurface *createShellSurface(QWaylandWindow *window) = 0;
++ // kept for binary compat with layer-shell-qt
+ virtual void handleKeyboardFocusChanged(QWaylandWindow *newFocus, QWaylandWindow *oldFocus) {
+- if (newFocus)
+- m_display->handleWindowActivated(newFocus);
+- if (oldFocus)
+- m_display->handleWindowDeactivated(oldFocus);
++ Q_UNUSED(newFocus);
++ Q_UNUSED(oldFocus);
+ }
+ virtual void *nativeResourceForWindow(const QByteArray &resource, QWindow *window) {
+ Q_UNUSED(resource);
+diff --git a/qtwayland/src/compositor/configure.json b/qtwayland/src/compositor/configure.json
+index bcfd5215..da95d07b 100644
+--- a/qtwayland/src/compositor/configure.json
++++ b/qtwayland/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"
+ }
+ },
+
+diff --git a/qtwayland/src/hardwareintegration/client/wayland-egl/qwaylandeglwindow.cpp b/qtwayland/src/hardwareintegration/client/wayland-egl/qwaylandeglwindow.cpp
+index 7889f575..64140672 100644
+--- a/qtwayland/src/hardwareintegration/client/wayland-egl/qwaylandeglwindow.cpp
++++ b/qtwayland/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>
+@@ -124,6 +125,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();
+@@ -131,14 +133,16 @@ void QWaylandEglWindow::updateSurface(bool create)
+ if (!disableResizeCheck) {
+ wl_egl_window_get_attached_size(m_waylandEglWindow, ¤t_width, ¤t_height);
+ }
+- if (disableResizeCheck || (current_width != sizeWithMargins.width() || current_height != sizeWithMargins.height())) {
++ if (disableResizeCheck || (current_width != sizeWithMargins.width() || current_height != sizeWithMargins.height()) || m_requestedSize != sizeWithMargins) {
+ wl_egl_window_resize(m_waylandEglWindow, sizeWithMargins.width(), sizeWithMargins.height(), mOffset.x(), mOffset.y());
++ m_requestedSize = sizeWithMargins;
+ mOffset = QPoint();
+
+ 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;
+ }
+
+ if (!m_eglSurface && m_waylandEglWindow && create) {
+diff --git a/qtwayland/src/hardwareintegration/client/wayland-egl/qwaylandeglwindow.h b/qtwayland/src/hardwareintegration/client/wayland-egl/qwaylandeglwindow.h
+index 5b1f4d56..0079dfef 100644
+--- a/qtwayland/src/hardwareintegration/client/wayland-egl/qwaylandeglwindow.h
++++ b/qtwayland/src/hardwareintegration/client/wayland-egl/qwaylandeglwindow.h
+@@ -88,6 +88,7 @@ private:
+ mutable QOpenGLFramebufferObject *m_contentFBO = nullptr;
+
+ QSurfaceFormat m_format;
++ QSize m_requestedSize;
+ };
+
+ }
+diff --git a/qtwayland/src/hardwareintegration/compositor/linux-dmabuf-unstable-v1/linuxdmabuf.h b/qtwayland/src/hardwareintegration/compositor/linux-dmabuf-unstable-v1/linuxdmabuf.h
+index 56a710c3..c6a8b6c6 100644
+--- a/qtwayland/src/hardwareintegration/compositor/linux-dmabuf-unstable-v1/linuxdmabuf.h
++++ b/qtwayland/src/hardwareintegration/compositor/linux-dmabuf-unstable-v1/linuxdmabuf.h
+@@ -41,6 +41,8 @@
+ #include <QtCore/QTextStream>
+ #include <QtGui/QOpenGLTexture>
+
++#include <array>
++
+ #include <EGL/egl.h>
+ #include <EGL/eglext.h>
+
+diff --git a/qtwayland/src/plugins/decorations/bradient/main.cpp b/qtwayland/src/plugins/decorations/bradient/main.cpp
+index e75fda3c..fa885143 100644
+--- a/qtwayland/src/plugins/decorations/bradient/main.cpp
++++ b/qtwayland/src/plugins/decorations/bradient/main.cpp
+@@ -164,13 +164,10 @@ void QWaylandBradientDecoration::paint(QPaintDevice *device)
+ // Window icon
+ QIcon icon = waylandWindow()->windowIcon();
+ if (!icon.isNull()) {
+- QPixmap pixmap = icon.pixmap(QSize(128, 128));
+- QPixmap scaled = pixmap.scaled(22, 22, Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
+-
+ QRectF iconRect(0, 0, 22, 22);
+- p.drawPixmap(iconRect.adjusted(margins().left() + BUTTON_SPACING, 4,
+- margins().left() + BUTTON_SPACING, 4),
+- scaled, iconRect);
++ iconRect.adjust(margins().left() + BUTTON_SPACING, 4,
++ margins().left() + BUTTON_SPACING, 4),
++ icon.paint(&p, iconRect.toRect());
+ }
+
+ // Window title
+diff --git a/qtwayland/src/plugins/shellintegration/xdg-shell-v5/qwaylandxdgpopupv5.cpp b/qtwayland/src/plugins/shellintegration/xdg-shell-v5/qwaylandxdgpopupv5.cpp
+index 85d25e3c..60bdd491 100644
+--- a/qtwayland/src/plugins/shellintegration/xdg-shell-v5/qwaylandxdgpopupv5.cpp
++++ b/qtwayland/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/qtwayland/src/plugins/shellintegration/xdg-shell-v5/qwaylandxdgpopupv5_p.h b/qtwayland/src/plugins/shellintegration/xdg-shell-v5/qwaylandxdgpopupv5_p.h
+index 7494f6a6..d85f130b 100644
+--- a/qtwayland/src/plugins/shellintegration/xdg-shell-v5/qwaylandxdgpopupv5_p.h
++++ b/qtwayland/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/qtwayland/src/plugins/shellintegration/xdg-shell-v5/qwaylandxdgshellv5.cpp b/qtwayland/src/plugins/shellintegration/xdg-shell-v5/qwaylandxdgshellv5.cpp
+index 7e242c4a..def8452a 100644
+--- a/qtwayland/src/plugins/shellintegration/xdg-shell-v5/qwaylandxdgshellv5.cpp
++++ b/qtwayland/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/qtwayland/src/plugins/shellintegration/xdg-shell-v5/qwaylandxdgshellv5integration.cpp b/qtwayland/src/plugins/shellintegration/xdg-shell-v5/qwaylandxdgshellv5integration.cpp
+index 4e25949f..cfc60939 100644
+--- a/qtwayland/src/plugins/shellintegration/xdg-shell-v5/qwaylandxdgshellv5integration.cpp
++++ b/qtwayland/src/plugins/shellintegration/xdg-shell-v5/qwaylandxdgshellv5integration.cpp
+@@ -85,13 +85,6 @@ QWaylandShellSurface *QWaylandXdgShellV5Integration::createShellSurface(QWayland
+ return m_xdgShell->createXdgSurface(window);
+ }
+
+-void QWaylandXdgShellV5Integration::handleKeyboardFocusChanged(QWaylandWindow *newFocus, QWaylandWindow *oldFocus) {
+- if (newFocus && qobject_cast<QWaylandXdgPopupV5 *>(newFocus->shellSurface()))
+- m_display->handleWindowActivated(newFocus);
+- if (oldFocus && qobject_cast<QWaylandXdgPopupV5 *>(oldFocus->shellSurface()))
+- m_display->handleWindowDeactivated(oldFocus);
+-}
+-
+ }
+
+ QT_END_NAMESPACE
+diff --git a/qtwayland/src/plugins/shellintegration/xdg-shell-v5/qwaylandxdgshellv5integration_p.h b/qtwayland/src/plugins/shellintegration/xdg-shell-v5/qwaylandxdgshellv5integration_p.h
+index ce6bdb9e..aed88670 100644
+--- a/qtwayland/src/plugins/shellintegration/xdg-shell-v5/qwaylandxdgshellv5integration_p.h
++++ b/qtwayland/src/plugins/shellintegration/xdg-shell-v5/qwaylandxdgshellv5integration_p.h
+@@ -67,7 +67,6 @@ public:
+ QWaylandXdgShellV5Integration() {}
+ bool initialize(QWaylandDisplay *display) override;
+ QWaylandShellSurface *createShellSurface(QWaylandWindow *window) override;
+- void handleKeyboardFocusChanged(QWaylandWindow *newFocus, QWaylandWindow *oldFocus) override;
+
+ private:
+ QScopedPointer<QWaylandXdgShellV5> m_xdgShell;
+diff --git a/qtwayland/src/plugins/shellintegration/xdg-shell-v6/qwaylandxdgshellv6.cpp b/qtwayland/src/plugins/shellintegration/xdg-shell-v6/qwaylandxdgshellv6.cpp
+index 8c371661..151c78e3 100644
+--- a/qtwayland/src/plugins/shellintegration/xdg-shell-v6/qwaylandxdgshellv6.cpp
++++ b/qtwayland/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/qtwayland/src/plugins/shellintegration/xdg-shell-v6/qwaylandxdgshellv6integration.cpp b/qtwayland/src/plugins/shellintegration/xdg-shell-v6/qwaylandxdgshellv6integration.cpp
+index 03164316..e8da8ba1 100644
+--- a/qtwayland/src/plugins/shellintegration/xdg-shell-v6/qwaylandxdgshellv6integration.cpp
++++ b/qtwayland/src/plugins/shellintegration/xdg-shell-v6/qwaylandxdgshellv6integration.cpp
+@@ -68,20 +68,6 @@ QWaylandShellSurface *QWaylandXdgShellV6Integration::createShellSurface(QWayland
+ return m_xdgShell->getXdgSurface(window);
+ }
+
+-void QWaylandXdgShellV6Integration::handleKeyboardFocusChanged(QWaylandWindow *newFocus, QWaylandWindow *oldFocus)
+-{
+- if (newFocus) {
+- auto *xdgSurface = qobject_cast<QWaylandXdgSurfaceV6 *>(newFocus->shellSurface());
+- if (xdgSurface && !xdgSurface->handlesActiveState())
+- m_display->handleWindowActivated(newFocus);
+- }
+- if (oldFocus && qobject_cast<QWaylandXdgSurfaceV6 *>(oldFocus->shellSurface())) {
+- auto *xdgSurface = qobject_cast<QWaylandXdgSurfaceV6 *>(oldFocus->shellSurface());
+- if (xdgSurface && !xdgSurface->handlesActiveState())
+- m_display->handleWindowDeactivated(oldFocus);
+- }
+-}
+-
+ }
+
+ QT_END_NAMESPACE
+diff --git a/qtwayland/src/plugins/shellintegration/xdg-shell-v6/qwaylandxdgshellv6integration_p.h b/qtwayland/src/plugins/shellintegration/xdg-shell-v6/qwaylandxdgshellv6integration_p.h
+index 261f8cbb..c1bcd5c6 100644
+--- a/qtwayland/src/plugins/shellintegration/xdg-shell-v6/qwaylandxdgshellv6integration_p.h
++++ b/qtwayland/src/plugins/shellintegration/xdg-shell-v6/qwaylandxdgshellv6integration_p.h
+@@ -65,7 +65,6 @@ public:
+ QWaylandXdgShellV6Integration() {}
+ bool initialize(QWaylandDisplay *display) override;
+ QWaylandShellSurface *createShellSurface(QWaylandWindow *window) override;
+- void handleKeyboardFocusChanged(QWaylandWindow *newFocus, QWaylandWindow *oldFocus) override;
+
+ private:
+ QScopedPointer<QWaylandXdgShellV6> m_xdgShell;
+diff --git a/qtwayland/src/plugins/shellintegration/xdg-shell/qwaylandxdgshell.cpp b/qtwayland/src/plugins/shellintegration/xdg-shell/qwaylandxdgshell.cpp
+index f3e3c330..fa6d5808 100644
+--- a/qtwayland/src/plugins/shellintegration/xdg-shell/qwaylandxdgshell.cpp
++++ b/qtwayland/src/plugins/shellintegration/xdg-shell/qwaylandxdgshell.cpp
+@@ -67,11 +67,6 @@ QWaylandXdgSurface::Toplevel::Toplevel(QWaylandXdgSurface *xdgSurface)
+
+ QWaylandXdgSurface::Toplevel::~Toplevel()
+ {
+- if (m_applied.states & Qt::WindowActive) {
+- QWaylandWindow *window = m_xdgSurface->window();
+- window->display()->handleWindowDeactivated(window);
+- }
+-
+ // The protocol spec requires that the decoration object is deleted before xdg_toplevel.
+ delete m_decoration;
+ m_decoration = nullptr;
+@@ -85,16 +80,15 @@ void QWaylandXdgSurface::Toplevel::applyConfigure()
+ if (!(m_applied.states & (Qt::WindowMaximized|Qt::WindowFullScreen)))
+ 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)
++ && !m_xdgSurface->m_window->display()->isKeyboardAvailable())
+ 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)
++ && !m_xdgSurface->m_window->display()->isKeyboardAvailable())
+ m_xdgSurface->m_window->display()->handleWindowDeactivated(m_xdgSurface->m_window);
+
+- // TODO: none of the other plugins send WindowActive either, but is it on purpose?
+- Qt::WindowStates statesWithoutActive = m_pending.states & ~Qt::WindowActive;
+-
+- m_xdgSurface->m_window->handleWindowStatesChanged(statesWithoutActive);
++ m_xdgSurface->m_window->handleWindowStatesChanged(m_pending.states);
+
+ if (m_pending.size.isEmpty()) {
+ // An empty size in the configure means it's up to the client to choose the size
+@@ -105,8 +99,6 @@ void QWaylandXdgSurface::Toplevel::applyConfigure()
+ m_xdgSurface->m_window->resizeFromApplyConfigure(m_pending.size);
+ }
+
+- m_xdgSurface->setSizeHints();
+-
+ m_applied = m_pending;
+ qCDebug(lcQpaWayland) << "Applied pending xdg_toplevel configure event:" << m_applied.size << m_applied.states;
+ }
+@@ -203,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()
+@@ -216,10 +213,24 @@ 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
++ QWindow *leave = nullptr;
++ if (m_xdgSurface && m_xdgSurface->window())
++ leave = m_xdgSurface->window()->window();
++ QWindowSystemInterface::handleLeaveEvent(leave);
++
++ if (QWindow *enter = QGuiApplication::topLevelAt(QCursor::pos()))
++ QWindowSystemInterface::handleEnterEvent(enter, enter->mapFromGlobal(QCursor::pos()), QCursor::pos());
+ }
+ }
+
+@@ -257,6 +268,7 @@ QWaylandXdgSurface::QWaylandXdgSurface(QWaylandXdgShell *shell, ::xdg_surface *s
+ m_toplevel->set_parent(parentXdgSurface->m_toplevel->object());
+ }
+ }
++ setSizeHints();
+ }
+
+ QWaylandXdgSurface::~QWaylandXdgSurface()
+@@ -400,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
+@@ -414,8 +424,9 @@ void QWaylandXdgSurface::setPopup(QWaylandWindow *parent)
+ positioner->set_anchor(QtWayland::xdg_positioner::anchor_top_left);
+ positioner->set_gravity(QtWayland::xdg_positioner::gravity_bottom_right);
+ positioner->set_size(m_window->geometry().width(), m_window->geometry().height());
+- m_popup = new Popup(this, parentXdgSurface, positioner);
++ m_popup = new Popup(this, parent, positioner);
+ positioner->destroy();
++
+ delete positioner;
+ }
+
+@@ -437,6 +448,23 @@ void QWaylandXdgSurface::setGrabPopup(QWaylandWindow *parent, QWaylandInputDevic
+ }
+ setPopup(parent);
+ m_popup->grab(device, serial);
++
++ // Synthesize Qt enter/leave events for popup
++ if (!parent)
++ return;
++ QWindow *current = QGuiApplication::topLevelAt(QCursor::pos());
++ QWindow *leave = parent->window();
++ if (current != leave)
++ return;
++
++ QWindowSystemInterface::handleLeaveEvent(leave);
++
++ QWindow *enter = nullptr;
++ if (m_popup && m_popup->m_xdgSurface && m_popup->m_xdgSurface->window())
++ enter = m_popup->m_xdgSurface->window()->window();
++
++ if (enter)
++ QWindowSystemInterface::handleEnterEvent(enter, enter->mapFromGlobal(QCursor::pos()), QCursor::pos());
+ }
+
+ void QWaylandXdgSurface::xdg_surface_configure(uint32_t serial)
+diff --git a/qtwayland/src/plugins/shellintegration/xdg-shell/qwaylandxdgshell_p.h b/qtwayland/src/plugins/shellintegration/xdg-shell/qwaylandxdgshell_p.h
+index 96785205..4b518f0a 100644
+--- a/qtwayland/src/plugins/shellintegration/xdg-shell/qwaylandxdgshell_p.h
++++ b/qtwayland/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/qtwayland/src/plugins/shellintegration/xdg-shell/qwaylandxdgshellintegration.cpp b/qtwayland/src/plugins/shellintegration/xdg-shell/qwaylandxdgshellintegration.cpp
+index 8769d971..da0dd6a7 100644
+--- a/qtwayland/src/plugins/shellintegration/xdg-shell/qwaylandxdgshellintegration.cpp
++++ b/qtwayland/src/plugins/shellintegration/xdg-shell/qwaylandxdgshellintegration.cpp
+@@ -69,20 +69,6 @@ QWaylandShellSurface *QWaylandXdgShellIntegration::createShellSurface(QWaylandWi
+ return m_xdgShell->getXdgSurface(window);
+ }
+
+-void QWaylandXdgShellIntegration::handleKeyboardFocusChanged(QWaylandWindow *newFocus, QWaylandWindow *oldFocus)
+-{
+- if (newFocus) {
+- auto *xdgSurface = qobject_cast<QWaylandXdgSurface *>(newFocus->shellSurface());
+- if (xdgSurface && !xdgSurface->handlesActiveState())
+- m_display->handleWindowActivated(newFocus);
+- }
+- if (oldFocus && qobject_cast<QWaylandXdgSurface *>(oldFocus->shellSurface())) {
+- auto *xdgSurface = qobject_cast<QWaylandXdgSurface *>(oldFocus->shellSurface());
+- if (xdgSurface && !xdgSurface->handlesActiveState())
+- m_display->handleWindowDeactivated(oldFocus);
+- }
+-}
+-
+ }
+
+ QT_END_NAMESPACE
+diff --git a/qtwayland/src/plugins/shellintegration/xdg-shell/qwaylandxdgshellintegration_p.h b/qtwayland/src/plugins/shellintegration/xdg-shell/qwaylandxdgshellintegration_p.h
+index b6caa6c9..2f929f98 100644
+--- a/qtwayland/src/plugins/shellintegration/xdg-shell/qwaylandxdgshellintegration_p.h
++++ b/qtwayland/src/plugins/shellintegration/xdg-shell/qwaylandxdgshellintegration_p.h
+@@ -65,7 +65,6 @@ public:
+ QWaylandXdgShellIntegration() {}
+ bool initialize(QWaylandDisplay *display) override;
+ QWaylandShellSurface *createShellSurface(QWaylandWindow *window) override;
+- void handleKeyboardFocusChanged(QWaylandWindow *newFocus, QWaylandWindow *oldFocus) override;
+
+ private:
+ QScopedPointer<QWaylandXdgShell> m_xdgShell;
+diff --git a/qtwayland/src/shared/qwaylandinputmethodeventbuilder.cpp b/qtwayland/src/shared/qwaylandinputmethodeventbuilder.cpp
+index 526d0ef4..f50ccf30 100644
+--- a/qtwayland/src/shared/qwaylandinputmethodeventbuilder.cpp
++++ b/qtwayland/src/shared/qwaylandinputmethodeventbuilder.cpp
+@@ -39,7 +39,10 @@
+
+ #include "qwaylandinputmethodeventbuilder_p.h"
+
++#include <QBrush>
++#include <QGuiApplication>
+ #include <QInputMethod>
++#include <QPalette>
+ #include <QTextCharFormat>
+
+ #ifdef QT_BUILD_WAYLANDCOMPOSITOR_LIB
+@@ -81,32 +84,38 @@ void QWaylandInputMethodEventBuilder::addPreeditStyling(uint32_t index, uint32_t
+ QTextCharFormat format;
+
+ switch (style) {
+- case 0:
+- case 1:
++ case ZWP_TEXT_INPUT_V2_PREEDIT_STYLE_NONE:
++ break;
++ case ZWP_TEXT_INPUT_V2_PREEDIT_STYLE_DEFAULT:
++ case ZWP_TEXT_INPUT_V2_PREEDIT_STYLE_UNDERLINE:
+ format.setFontUnderline(true);
+ format.setUnderlineStyle(QTextCharFormat::SingleUnderline);
+ m_preeditStyles.append(QInputMethodEvent::Attribute(QInputMethodEvent::TextFormat, index, length, format));
+ break;
+- case 2:
+- case 3:
++ case ZWP_TEXT_INPUT_V2_PREEDIT_STYLE_ACTIVE:
++ case ZWP_TEXT_INPUT_V2_PREEDIT_STYLE_INACTIVE:
+ format.setFontWeight(QFont::Bold);
+ format.setFontUnderline(true);
+ format.setUnderlineStyle(QTextCharFormat::SingleUnderline);
+ m_preeditStyles.append(QInputMethodEvent::Attribute(QInputMethodEvent::TextFormat, index, length, format));
+ break;
+- case 4:
+- format.setFontUnderline(true);
+- format.setUnderlineStyle(QTextCharFormat::SingleUnderline);
+- m_preeditStyles.append(QInputMethodEvent::Attribute(QInputMethodEvent::TextFormat, index, length, format));
++ case ZWP_TEXT_INPUT_V2_PREEDIT_STYLE_HIGHLIGHT:
++ case ZWP_TEXT_INPUT_V2_PREEDIT_STYLE_SELECTION:
++ {
++ format.setFontUnderline(true);
++ format.setUnderlineStyle(QTextCharFormat::SingleUnderline);
++ QPalette palette = qApp->palette();
++ format.setBackground(QBrush(palette.color(QPalette::Active, QPalette::Highlight)));
++ format.setForeground(QBrush(palette.color(QPalette::Active, QPalette::HighlightedText)));
++ m_preeditStyles.append(QInputMethodEvent::Attribute(QInputMethodEvent::TextFormat, index, length, format));
++ }
+ break;
+- case 5:
++ case ZWP_TEXT_INPUT_V2_PREEDIT_STYLE_INCORRECT:
+ format.setFontUnderline(true);
+ format.setUnderlineStyle(QTextCharFormat::WaveUnderline);
+ format.setUnderlineColor(QColor(Qt::red));
+ m_preeditStyles.append(QInputMethodEvent::Attribute(QInputMethodEvent::TextFormat, index, length, format));
+ break;
+-// case QtWayland::wl_text_input::preedit_style_selection:
+-// case QtWayland::wl_text_input::preedit_style_none:
+ default:
+ break;
+ }
+@@ -153,7 +162,7 @@ QInputMethodEvent QWaylandInputMethodEventBuilder::buildPreedit(const QString &t
+
+ if (m_preeditCursor < 0) {
+ attributes.append(QInputMethodEvent::Attribute(QInputMethodEvent::Cursor, 0, 0, QVariant()));
+- } else if (m_preeditCursor > 0) {
++ } else {
+ attributes.append(QInputMethodEvent::Attribute(QInputMethodEvent::Cursor, indexFromWayland(text, m_preeditCursor), 1, QVariant()));
+ }
+
+diff --git a/qtwayland/src/shared/qwaylandmimehelper.cpp b/qtwayland/src/shared/qwaylandmimehelper.cpp
+index a5fdd34d..e2fe1928 100644
+--- a/qtwayland/src/shared/qwaylandmimehelper.cpp
++++ b/qtwayland/src/shared/qwaylandmimehelper.cpp
+@@ -60,7 +60,7 @@ QByteArray QWaylandMimeHelper::getByteArray(QMimeData *mimeData, const QString &
+ buf.open(QIODevice::ReadWrite);
+ QByteArray fmt = "BMP";
+ if (mimeType.startsWith(QLatin1String("image/"))) {
+- QByteArray imgFmt = mimeType.mid(6).toUpper().toLatin1();
++ QByteArray imgFmt = mimeType.mid(6).toLower().toLatin1();
+ if (QImageWriter::supportedImageFormats().contains(imgFmt))
+ fmt = imgFmt;
+ }
+@@ -74,7 +74,7 @@ QByteArray QWaylandMimeHelper::getByteArray(QMimeData *mimeData, const QString &
+ QList<QUrl> urls = mimeData->urls();
+ for (int i = 0; i < urls.count(); ++i) {
+ content.append(urls.at(i).toEncoded());
+- content.append('\n');
++ content.append("\r\n");
+ }
+ } else {
+ content = mimeData->data(mimeType);
+diff --git a/qtwayland/tests/auto/client/datadevicev1/tst_datadevicev1.cpp b/qtwayland/tests/auto/client/datadevicev1/tst_datadevicev1.cpp
+index 1568b3b9..067410d0 100644
+--- a/qtwayland/tests/auto/client/datadevicev1/tst_datadevicev1.cpp
++++ b/qtwayland/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:
+diff --git a/qtwayland/tests/auto/client/seatv5/tst_seatv5.cpp b/qtwayland/tests/auto/client/seatv5/tst_seatv5.cpp
+index 9312c2e5..2ea382f1 100644
+--- a/qtwayland/tests/auto/client/seatv5/tst_seatv5.cpp
++++ b/qtwayland/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, Qt::TouchPointPressed);
++ QCOMPARE(e.touchPoints.length(), 1);
++ QCOMPARE(e.touchPoints.first().pos(), 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/qtwayland/tests/auto/client/shared/corecompositor.cpp b/qtwayland/tests/auto/client/shared/corecompositor.cpp
+index 5c6c83ba..fa9b7662 100644
+--- a/qtwayland/tests/auto/client/shared/corecompositor.cpp
++++ b/qtwayland/tests/auto/client/shared/corecompositor.cpp
+@@ -27,6 +27,7 @@
+ ****************************************************************************/
+
+ #include "corecompositor.h"
++#include <thread>
+
+ namespace MockCompositor {
+
+diff --git a/qtwayland/tests/auto/client/shared/coreprotocol.cpp b/qtwayland/tests/auto/client/shared/coreprotocol.cpp
+index 0d988521..d1a2e7cb 100644
+--- a/qtwayland/tests/auto/client/shared/coreprotocol.cpp
++++ b/qtwayland/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/qtwayland/tests/auto/client/shared/coreprotocol.h b/qtwayland/tests/auto/client/shared/coreprotocol.h
+index a1af137a..210d8ddb 100644
+--- a/qtwayland/tests/auto/client/shared/coreprotocol.h
++++ b/qtwayland/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)
+ {}
+@@ -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;
+ };
+diff --git a/qtwayland/tests/auto/client/shared_old/mockcompositor.cpp b/qtwayland/tests/auto/client/shared_old/mockcompositor.cpp
+index a415cbf5..b1d3d07d 100644
+--- a/qtwayland/tests/auto/client/shared_old/mockcompositor.cpp
++++ b/qtwayland/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/qtwayland/tests/auto/client/shared_old/mocksurface.cpp b/qtwayland/tests/auto/client/shared_old/mocksurface.cpp
+index e9df5f90..c3246e4a 100644
+--- a/qtwayland/tests/auto/client/shared_old/mocksurface.cpp
++++ b/qtwayland/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/qtwayland/tests/auto/client/shared_old/mocksurface.h b/qtwayland/tests/auto/client/shared_old/mocksurface.h
+index 949dc23d..d176837e 100644
+--- a/qtwayland/tests/auto/client/shared_old/mocksurface.h
++++ b/qtwayland/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;
+diff --git a/qtwayland/tests/auto/client/surface/tst_surface.cpp b/qtwayland/tests/auto/client/surface/tst_surface.cpp
+index 95e4e609..60c672ce 100644
+--- a/qtwayland/tests/auto/client/surface/tst_surface.cpp
++++ b/qtwayland/tests/auto/client/surface/tst_surface.cpp
+@@ -129,6 +129,10 @@ void tst_surface::waitForFrameCallbackGl()
+ // Make sure we follow frame callbacks for some frames
+ for (int i = 0; i < 5; ++i) {
+ xdgPingAndWaitForPong(); // Make sure things have happened on the client
++ if (!qEnvironmentVariableIntValue("QT_WAYLAND_DISABLE_WINDOWDECORATION") && i == 0) {
++ QCOMPARE(bufferSpy.count(), 1);
++ bufferSpy.removeFirst();
++ }
+ exec([&] {
+ QVERIFY(bufferSpy.empty()); // Make sure no extra buffers have arrived
+ QVERIFY(!xdgToplevel()->surface()->m_waitingFrameCallbacks.empty());
+diff --git a/qtwayland/tests/auto/client/xdgshell/tst_xdgshell.cpp b/qtwayland/tests/auto/client/xdgshell/tst_xdgshell.cpp
+index 2277bbb8..747875b4 100644
+--- a/qtwayland/tests/auto/client/xdgshell/tst_xdgshell.cpp
++++ b/qtwayland/tests/auto/client/xdgshell/tst_xdgshell.cpp
+@@ -31,6 +31,7 @@
+ #include <QtGui/QOpenGLWindow>
+ #include <QtGui/qpa/qplatformnativeinterface.h>
+ #include <QtWaylandClient/private/wayland-wayland-client-protocol.h>
++#include <QtWaylandClient/private/qwaylandwindow_p.h>
+
+ using namespace MockCompositor;
+
+@@ -45,6 +46,7 @@ private slots:
+ void configureStates();
+ void popup();
+ void tooltipOnPopup();
++ void tooltipAndSiblingPopup();
+ void switchPopups();
+ void hidePopupParent();
+ void pongs();
+@@ -138,6 +140,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();
+@@ -154,9 +157,12 @@ void tst_xdgshell::configureStates()
+ // 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
+
+-// QEXPECT_FAIL("", "configure has already been acked, we shouldn't have to wait for isActive", Continue);
+-// QVERIFY(window.isActive());
+- QTRY_VERIFY(window.isActive()); // Just make sure it eventually get's set correctly
++ // window.windowstate() is driven by keyboard focus, however for decorations we want to follow
++ // XDGShell this is internal to QtWayland so it is queried directly
++ auto waylandWindow = static_cast<QtWaylandClient::QWaylandWindow *>(window.handle());
++ Q_ASSERT(waylandWindow);
++ QTRY_VERIFY(waylandWindow->windowStates().testFlag(
++ Qt::WindowActive)); // Just make sure it eventually get's set correctly
+
+ const QSize screenSize(640, 480);
+ const uint maximizedSerial = exec([=] {
+@@ -186,6 +192,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()
+@@ -340,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()
+ {
+@@ -505,7 +598,7 @@ void tst_xdgshell::minMaxSize()
+ window.show();
+ QCOMPOSITOR_TRY_VERIFY(xdgToplevel());
+
+- exec([=] { xdgToplevel()->sendCompleteConfigure(); });
++ // we don't roundtrip with our configuration the initial commit should be correct
+
+ QCOMPOSITOR_TRY_COMPARE(xdgToplevel()->m_committed.minSize, QSize(100, 100));
+ QCOMPOSITOR_TRY_COMPARE(xdgToplevel()->m_committed.maxSize, QSize(1000, 1000));
+Submodule qtwebchannel 618422ee..f8949655:
+diff --git a/qtwebchannel/src/webchannel/qmetaobjectpublisher.cpp b/qtwebchannel/src/webchannel/qmetaobjectpublisher.cpp
+index 536eb5c..898d769 100644
+--- a/qtwebchannel/src/webchannel/qmetaobjectpublisher.cpp
++++ b/qtwebchannel/src/webchannel/qmetaobjectpublisher.cpp
+@@ -186,8 +186,6 @@ Q_DECLARE_TYPEINFO(OverloadResolutionCandidate, Q_MOVABLE_TYPE);
+ QMetaObjectPublisher::QMetaObjectPublisher(QWebChannel *webChannel)
+ : QObject(webChannel)
+ , webChannel(webChannel)
+- , signalHandler(this)
+- , clientIsIdle(false)
+ , blockUpdates(false)
+ , propertyUpdatesInitialized(false)
+ {
+@@ -301,17 +299,17 @@ QJsonObject QMetaObjectPublisher::classInfoForObject(const QObject *object, QWeb
+ return data;
+ }
+
+-void QMetaObjectPublisher::setClientIsIdle(bool isIdle)
++void QMetaObjectPublisher::setClientIsIdle(bool isIdle, QWebChannelAbstractTransport *transport)
+ {
+- if (clientIsIdle == isIdle) {
+- return;
+- }
+- clientIsIdle = isIdle;
+- if (!isIdle && timer.isActive()) {
+- timer.stop();
+- } else if (isIdle && !timer.isActive()) {
+- timer.start(PROPERTY_UPDATE_INTERVAL, this);
+- }
++ transportState[transport].clientIsIdle = isIdle;
++ if (isIdle)
++ sendEnqueuedPropertyUpdates(transport);
++}
++
++bool QMetaObjectPublisher::isClientIdle(QWebChannelAbstractTransport *transport)
++{
++ auto found = transportState.find(transport);
++ return found != transportState.end() && found.value().clientIsIdle;
+ }
+
+ QJsonObject QMetaObjectPublisher::initializeClient(QWebChannelAbstractTransport *transport)
+@@ -333,6 +331,7 @@ QJsonObject QMetaObjectPublisher::initializeClient(QWebChannelAbstractTransport
+
+ void QMetaObjectPublisher::initializePropertyUpdates(const QObject *const object, const QJsonObject &objectInfo)
+ {
++ auto *signalHandler = signalHandlerFor(object);
+ foreach (const QJsonValue &propertyInfoVar, objectInfo[KEY_PROPERTIES].toArray()) {
+ const QJsonArray &propertyInfo = propertyInfoVar.toArray();
+ if (propertyInfo.size() < 2) {
+@@ -353,19 +352,19 @@ void QMetaObjectPublisher::initializePropertyUpdates(const QObject *const object
+
+ // Only connect for a property update once
+ if (connectedProperties.isEmpty()) {
+- signalHandler.connectTo(object, signalIndex);
++ signalHandler->connectTo(object, signalIndex);
+ }
+
+ connectedProperties.insert(propertyIndex);
+ }
+
+ // also always connect to destroyed signal
+- signalHandler.connectTo(object, s_destroyedSignalIndex);
++ signalHandler->connectTo(object, s_destroyedSignalIndex);
+ }
+
+ void QMetaObjectPublisher::sendPendingPropertyUpdates()
+ {
+- if (blockUpdates || !clientIsIdle || pendingPropertyUpdates.isEmpty()) {
++ if (blockUpdates) {
+ return;
+ }
+
+@@ -415,18 +414,19 @@ void QMetaObjectPublisher::sendPendingPropertyUpdates()
+
+ // data does not contain specific updates
+ if (!data.isEmpty()) {
+- setClientIsIdle(false);
+-
+ message[KEY_DATA] = data;
+- broadcastMessage(message);
++ enqueueBroadcastMessage(message);
+ }
+
+ // send every property update which is not supposed to be broadcasted
+ const QHash<QWebChannelAbstractTransport*, QJsonArray>::const_iterator suend = specificUpdates.constEnd();
+ for (QHash<QWebChannelAbstractTransport*, QJsonArray>::const_iterator it = specificUpdates.constBegin(); it != suend; ++it) {
+ message[KEY_DATA] = it.value();
+- it.key()->sendMessage(message);
++ enqueueMessage(message, it.key());
+ }
++
++ for (auto state = transportState.begin(); state != transportState.end(); ++state)
++ sendEnqueuedPropertyUpdates(state.key());
+ }
+
+ QVariant QMetaObjectPublisher::invokeMethod(QObject *const object, const QMetaMethod &method,
+@@ -572,7 +572,7 @@ void QMetaObjectPublisher::signalEmitted(const QObject *object, const int signal
+ }
+ } else {
+ pendingPropertyUpdates[object][signalIndex] = arguments;
+- if (clientIsIdle && !blockUpdates && !timer.isActive()) {
++ if (!blockUpdates && !timer.isActive()) {
+ timer.start(PROPERTY_UPDATE_INTERVAL, this);
+ }
+ }
+@@ -590,7 +590,7 @@ void QMetaObjectPublisher::objectDestroyed(const QObject *object)
+ // only remove from handler when we initialized the property updates
+ // cf: https://bugreports.qt.io/browse/QTBUG-60250
+ if (propertyUpdatesInitialized) {
+- signalHandler.remove(object);
++ signalHandlerFor(object)->remove(object);
+ signalToPropertyMap.remove(object);
+ }
+ pendingPropertyUpdates.remove(object);
+@@ -852,6 +852,52 @@ void QMetaObjectPublisher::broadcastMessage(const QJsonObject &message) const
+ }
+ }
+
++void QMetaObjectPublisher::enqueueBroadcastMessage(const QJsonObject &message)
++{
++ if (webChannel->d_func()->transports.isEmpty()) {
++ qWarning("QWebChannel is not connected to any transports, cannot send message: %s",
++ QJsonDocument(message).toJson().constData());
++ return;
++ }
++
++ for (auto *transport : webChannel->d_func()->transports) {
++ auto &state = transportState[transport];
++ state.queuedMessages.append(message);
++ }
++}
++
++void QMetaObjectPublisher::enqueueMessage(const QJsonObject &message,
++ QWebChannelAbstractTransport *transport)
++{
++ auto &state = transportState[transport];
++ state.queuedMessages.append(message);
++}
++
++void QMetaObjectPublisher::sendEnqueuedPropertyUpdates(QWebChannelAbstractTransport *transport)
++{
++ auto found = transportState.find(transport);
++ if (found != transportState.end() && found.value().clientIsIdle
++ && !found.value().queuedMessages.isEmpty()) {
++
++ // If the client is connected with an in-process transport, it can
++ // happen that a message triggers a subsequent property change. In
++ // that case, we need to ensure that the queued messages have already
++ // been cleared; otherwise the recursive call will send everythig again.
++ // Case in point: The qmlwebchannel tests fail if we don't clear the
++ // queued messages before sending them out.
++ // For that same reason set the client to "busy" (aka non-idle) just
++ // right before sending out the messages; otherwise a potential
++ // "Idle" type message will not correctly restore the Idle state.
++ const auto messages = std::move(found.value().queuedMessages);
++ Q_ASSERT(found.value().queuedMessages.isEmpty());
++ found.value().clientIsIdle = false;
++
++ for (const auto &message : messages) {
++ transport->sendMessage(message);
++ }
++ }
++}
++
+ void QMetaObjectPublisher::handleMessage(const QJsonObject &message, QWebChannelAbstractTransport *transport)
+ {
+ if (!webChannel->d_func()->transports.contains(transport)) {
+@@ -866,7 +912,7 @@ void QMetaObjectPublisher::handleMessage(const QJsonObject &message, QWebChannel
+
+ const MessageType type = toType(message.value(KEY_TYPE));
+ if (type == TypeIdle) {
+- setClientIsIdle(true);
++ setClientIsIdle(true, transport);
+ } else if (type == TypeInit) {
+ if (!message.contains(KEY_ID)) {
+ qWarning("JSON message object is missing the id property: %s",
+@@ -913,9 +959,9 @@ void QMetaObjectPublisher::handleMessage(const QJsonObject &message, QWebChannel
+ return;
+ transport->sendMessage(createResponse(message.value(KEY_ID), wrapResult(result, transport)));
+ } else if (type == TypeConnectToSignal) {
+- signalHandler.connectTo(object, message.value(KEY_SIGNAL).toInt(-1));
++ signalHandlerFor(object)->connectTo(object, message.value(KEY_SIGNAL).toInt(-1));
+ } else if (type == TypeDisconnectFromSignal) {
+- signalHandler.disconnectFrom(object, message.value(KEY_SIGNAL).toInt(-1));
++ signalHandlerFor(object)->disconnectFrom(object, message.value(KEY_SIGNAL).toInt(-1));
+ } else if (type == TypeSetProperty) {
+ setProperty(object, message.value(KEY_PROPERTY).toInt(-1),
+ message.value(KEY_VALUE));
+@@ -931,6 +977,7 @@ void QMetaObjectPublisher::setBlockUpdates(bool block)
+ blockUpdates = block;
+
+ if (!blockUpdates) {
++ timer.start(PROPERTY_UPDATE_INTERVAL, this);
+ sendPendingPropertyUpdates();
+ } else if (timer.isActive()) {
+ timer.stop();
+@@ -948,4 +995,15 @@ void QMetaObjectPublisher::timerEvent(QTimerEvent *event)
+ }
+ }
+
++SignalHandler<QMetaObjectPublisher> *QMetaObjectPublisher::signalHandlerFor(const QObject *object)
++{
++ auto thread = object->thread();
++ auto it = signalHandlers.find(thread);
++ if (it == signalHandlers.end()) {
++ it = signalHandlers.emplace(thread, this).first;
++ it->second.moveToThread(thread);
++ }
++ return &it->second;
++}
++
+ QT_END_NAMESPACE
+diff --git a/qtwebchannel/src/webchannel/qmetaobjectpublisher_p.h b/qtwebchannel/src/webchannel/qmetaobjectpublisher_p.h
+index bbd9875..4713ef1 100644
+--- a/qtwebchannel/src/webchannel/qmetaobjectpublisher_p.h
++++ b/qtwebchannel/src/webchannel/qmetaobjectpublisher_p.h
+@@ -59,6 +59,9 @@
+ #include <QBasicTimer>
+ #include <QPointer>
+ #include <QJsonObject>
++#include <QQueue>
++
++#include <unordered_map>
+
+ #include "qwebchannelglobal.h"
+
+@@ -109,17 +112,36 @@ public:
+ */
+ void broadcastMessage(const QJsonObject &message) const;
+
++ /**
++ * Enqueue the given @p message to all known transports.
++ */
++ void enqueueBroadcastMessage(const QJsonObject &message);
++
++ /**
++ * Enqueue the given @p message to @p transport.
++ */
++ void enqueueMessage(const QJsonObject &message, QWebChannelAbstractTransport *transport);
++
++ /**
++ * If client for given @p transport is idle, send queued messaged to @p transport and then mark
++ * the client as not idle.
++ */
++ void sendEnqueuedPropertyUpdates(QWebChannelAbstractTransport *transport);
++
+ /**
+ * Serialize the QMetaObject of @p object and return it in JSON form.
+ */
+ QJsonObject classInfoForObject(const QObject *object, QWebChannelAbstractTransport *transport);
+
+ /**
+- * Set the client to idle or busy, based on the value of @p isIdle.
+- *
+- * When the value changed, start/stop the property update timer accordingly.
++ * Set the client to idle or busy for a single @p transport, based on the value of @p isIdle.
++ */
++ void setClientIsIdle(bool isIdle, QWebChannelAbstractTransport *transport);
++
++ /**
++ * Check that client is idle for @p transport.
+ */
+- void setClientIsIdle(bool isIdle);
++ bool isClientIdle(QWebChannelAbstractTransport *transport);
+
+ /**
+ * Initialize clients by sending them the class information of the registered objects.
+@@ -272,10 +294,18 @@ private:
+ friend class TestWebChannel;
+
+ QWebChannel *webChannel;
+- SignalHandler<QMetaObjectPublisher> signalHandler;
++ std::unordered_map<const QThread*, SignalHandler<QMetaObjectPublisher>> signalHandlers;
++ SignalHandler<QMetaObjectPublisher> *signalHandlerFor(const QObject *object);
+
+- // true when the client is idle, false otherwise
+- bool clientIsIdle;
++ struct TransportState
++ {
++ TransportState() : clientIsIdle(false) { }
++ // true when the client is idle, false otherwise
++ bool clientIsIdle;
++ // messages to send
++ QQueue<QJsonObject> queuedMessages;
++ };
++ QHash<QWebChannelAbstractTransport *, TransportState> transportState;
+
+ // true when no property updates should be sent, false otherwise
+ bool blockUpdates;
+diff --git a/qtwebchannel/src/webchannel/signalhandler_p.h b/qtwebchannel/src/webchannel/signalhandler_p.h
+index 27afadb..d77373c 100644
+--- a/qtwebchannel/src/webchannel/signalhandler_p.h
++++ b/qtwebchannel/src/webchannel/signalhandler_p.h
+@@ -56,6 +56,7 @@
+ #include <QVector>
+ #include <QMetaMethod>
+ #include <QDebug>
++#include <QThread>
+
+ QT_BEGIN_NAMESPACE
+
+@@ -71,6 +72,7 @@ static const int s_destroyedSignalIndex = QObject::staticMetaObject.indexOfMetho
+ template<class Receiver>
+ class SignalHandler : public QObject
+ {
++ Q_DISABLE_COPY(SignalHandler)
+ public:
+ SignalHandler(Receiver *receiver, QObject *parent = 0);
+
+@@ -268,6 +270,7 @@ int SignalHandler<Receiver>::qt_metacall(QMetaObject::Call call, int methodId, v
+ if (call == QMetaObject::InvokeMetaMethod) {
+ const QObject *object = sender();
+ Q_ASSERT(object);
++ Q_ASSERT(QThread::currentThread() == object->thread());
+ Q_ASSERT(senderSignalIndex() == methodId);
+ Q_ASSERT(m_connectionsCounter.contains(object));
+ Q_ASSERT(m_connectionsCounter.value(object).contains(methodId));
+diff --git a/qtwebchannel/tests/auto/qml/testwebchannel.cpp b/qtwebchannel/tests/auto/qml/testwebchannel.cpp
+index 9891687..3ca81c2 100644
+--- a/qtwebchannel/tests/auto/qml/testwebchannel.cpp
++++ b/qtwebchannel/tests/auto/qml/testwebchannel.cpp
+@@ -46,7 +46,11 @@ TestWebChannel::~TestWebChannel()
+
+ bool TestWebChannel::clientIsIdle() const
+ {
+- return QWebChannel::d_func()->publisher->clientIsIdle;
++ for (auto *transport : QWebChannel::d_func()->transports) {
++ if (QWebChannel::d_func()->publisher->isClientIdle(transport))
++ return true;
++ }
++ return false;
+ }
+
+ QT_END_NAMESPACE
+diff --git a/qtwebchannel/tests/auto/webchannel/tst_webchannel.cpp b/qtwebchannel/tests/auto/webchannel/tst_webchannel.cpp
+index 181da9e..37f989a 100644
+--- a/qtwebchannel/tests/auto/webchannel/tst_webchannel.cpp
++++ b/qtwebchannel/tests/auto/webchannel/tst_webchannel.cpp
+@@ -785,7 +785,7 @@ void TestWebChannel::testTransportWrapObjectProperties()
+ DummyTransport *dummyTransport = new DummyTransport(this);
+ channel.connectTo(dummyTransport);
+ channel.d_func()->publisher->initializeClient(dummyTransport);
+- channel.d_func()->publisher->setClientIsIdle(true);
++ channel.d_func()->publisher->setClientIsIdle(true, dummyTransport);
+
+ QCOMPARE(channel.d_func()->publisher->transportedWrappedObjects.size(), 0);
+
+@@ -943,8 +943,6 @@ void TestWebChannel::testInfiniteRecursion()
+
+ void TestWebChannel::testAsyncObject()
+ {
+- QSKIP("This test is broken. See QTBUG-80729");
+-
+ QWebChannel channel;
+ channel.connectTo(m_dummyTransport);
+
+@@ -990,6 +988,50 @@ void TestWebChannel::testAsyncObject()
+ thread.wait();
+ }
+
++void TestWebChannel::testPropertyMultipleTransports()
++{
++ DummyTransport transport1;
++ DummyTransport transport2;
++
++ QWebChannel channel;
++ QMetaObjectPublisher *publisher = channel.d_func()->publisher;
++
++ TestObject testObj;
++ testObj.setObjectName("testObject");
++ channel.registerObject(testObj.objectName(), &testObj);
++ channel.connectTo(&transport1);
++ channel.connectTo(&transport2);
++
++ testObj.setProp("Hello");
++
++ publisher->initializeClient(&transport1);
++ publisher->initializeClient(&transport2);
++ publisher->setClientIsIdle(true, &transport1);
++ QCOMPARE(publisher->isClientIdle(&transport1), true);
++ QCOMPARE(publisher->isClientIdle(&transport2), false);
++ QVERIFY(transport1.messagesSent().isEmpty());
++ QVERIFY(transport2.messagesSent().isEmpty());
++
++ testObj.setProp("World");
++ QTRY_COMPARE_WITH_TIMEOUT(transport1.messagesSent().size(), 1u, 2000);
++ QCOMPARE(transport2.messagesSent().size(), 0u);
++ publisher->setClientIsIdle(true, &transport2);
++ QTRY_COMPARE_WITH_TIMEOUT(transport2.messagesSent().size(), 1u, 2000);
++ QCOMPARE(publisher->isClientIdle(&transport1), false);
++ QCOMPARE(publisher->isClientIdle(&transport2), false);
++
++ testObj.setProp("!!!");
++ publisher->setClientIsIdle(true, &transport2);
++ QCOMPARE(publisher->isClientIdle(&transport2), true);
++ QCOMPARE(publisher->isClientIdle(&transport1), false);
++ QTRY_COMPARE_WITH_TIMEOUT(transport2.messagesSent().size(), 2u, 2000);
++ QCOMPARE(transport1.messagesSent().size(), 1u);
++ publisher->setClientIsIdle(true, &transport1);
++ QTRY_COMPARE_WITH_TIMEOUT(transport1.messagesSent().size(), 2u, 2000);
++ QCOMPARE(publisher->isClientIdle(&transport1), false);
++ QCOMPARE(publisher->isClientIdle(&transport2), false);
++}
++
+ class FunctionWrapper : public QObject
+ {
+ Q_OBJECT
+@@ -1082,7 +1124,7 @@ void TestWebChannel::benchInitializeClients()
+
+ publisher->propertyUpdatesInitialized = false;
+ publisher->signalToPropertyMap.clear();
+- publisher->signalHandler.clear();
++ publisher->signalHandlers.clear();
+ }
+ }
+
+@@ -1107,7 +1149,7 @@ void TestWebChannel::benchPropertyUpdates()
+ obj->change();
+ }
+
+- channel.d_func()->publisher->clientIsIdle = true;
++ channel.d_func()->publisher->setClientIsIdle(true, m_dummyTransport);
+ channel.d_func()->publisher->sendPendingPropertyUpdates();
+ }
+ }
+diff --git a/qtwebchannel/tests/auto/webchannel/tst_webchannel.h b/qtwebchannel/tests/auto/webchannel/tst_webchannel.h
+index eae21f4..dd4e690 100644
+--- a/qtwebchannel/tests/auto/webchannel/tst_webchannel.h
++++ b/qtwebchannel/tests/auto/webchannel/tst_webchannel.h
+@@ -348,6 +348,7 @@ private slots:
+ void testJsonToVariant();
+ void testInfiniteRecursion();
+ void testAsyncObject();
++ void testPropertyMultipleTransports();
+ void testDeletionDuringMethodInvocation_data();
+ void testDeletionDuringMethodInvocation();
+
+Submodule qtwebengine f328054d...38e0df6c (commits not present)
+Submodule qtwebsockets 65850954..63fb8da1:
+diff --git a/qtwebsockets/src/websockets/qwebsocketdataprocessor.cpp b/qtwebsockets/src/websockets/qwebsocketdataprocessor.cpp
+index 2affdd5..95f1194 100644
+--- a/qtwebsockets/src/websockets/qwebsocketdataprocessor.cpp
++++ b/qtwebsockets/src/websockets/qwebsocketdataprocessor.cpp
+@@ -273,6 +273,7 @@ void QWebSocketDataProcessor::clear()
+ if (!m_pConverterState)
+ m_pConverterState = new QTextCodec::ConverterState(QTextCodec::ConvertInvalidToNull |
+ QTextCodec::IgnoreHeader);
++ frame.clear();
+ }
+
+ /*!
+diff --git a/qtwebsockets/src/websockets/qwebsocketprotocol.cpp b/qtwebsockets/src/websockets/qwebsocketprotocol.cpp
+index df87a93..d0465f1 100644
+--- a/qtwebsockets/src/websockets/qwebsocketprotocol.cpp
++++ b/qtwebsockets/src/websockets/qwebsocketprotocol.cpp
+@@ -210,7 +210,7 @@ void QWebSocketProtocol::mask(char *payload, quint64 size, quint32 maskingKey)
+ quint8((maskingKey & 0x0000FF00u) >> 8),
+ quint8((maskingKey & 0x000000FFu))
+ };
+- int i = 0;
++ quint64 i = 0;
+ while (size-- > 0)
+ *payload++ ^= mask[i++ % 4];
+ }
diff --git a/srcpkgs/qt5/template b/srcpkgs/qt5/template
index e0463e1c9198..ca1800ce9dc2 100644
--- a/srcpkgs/qt5/template
+++ b/srcpkgs/qt5/template
@@ -2,11 +2,11 @@
#
# revbump libqtxdg after bumping patch version
pkgname=qt5
-version=5.15.7+20221119
+version=5.15.8
+revision=1
+build_style=meta
# commit f8c9fb304bc3e53b3aa07f962cd74e9160decccc
# base repo: https://invent.kde.org/qt/qt/qt5
-revision=4
-build_style=meta
hostmakedepends="cmake clang flex perl glib-devel pkg-config
python re2c ruby which"
makedepends="SDL2-devel Vulkan-Headers alsa-lib-devel double-conversion-devel
@@ -29,8 +29,9 @@ homepage="https://qt.io/"
# tarball is generated with `git archive-all qt5-$version.tar.gz`
# to keep the size smaller qtwebengine, qtwebview, qtdocgallery, qtactiveqt and qtpim
# can be marked with the export-ignore attribute
-distfiles="https://void.johnnynator.dev/distfiles/qt5-${version}.tar.gz"
-checksum=9d57af471c78029a362276b7c99108ea009f511bb9ba6ff6cb884f6ddd255e9f
+#distfiles="https://void.johnnynator.dev/distfiles/qt5-${version}.tar.gz"
+distfiles="https://download.qt.io/archive/qt/5.15/${version}/single/qt-everywhere-opensource-src-${version}.tar.xz"
+checksum=776a9302c336671f9406a53bd30b8e36f825742b2ec44a57c08217bff0fa86b9
python_version=2 #unverified
replaces="qt5-doc<5.6.0 qt5-quick1<5.6.0 qt5-quick1-devel<5.6.0 qt5-webkit<5.6.0 qt5-webkit-devel<5.6.0
qt5-enginio<5.7.1 qt5-enginio-devel<5.7.1 qt5-plugin-gtk<5.7.1 qt5-canvas3d<5.13.0"
@@ -248,7 +249,6 @@ do_configure() {
# opts+=" -v"
opts+=" -skip qtwebengine"
opts+=" -skip qtwebview"
- opts+=" -skip qtdocgallery"
opts+=" -skip qtpim"
opts+=" -skip qtsystems"
opts+=" -skip qtspeech"
From 243808bd9edf9d2e9aa1c2c47b10788c9fb5e3bc Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:51 -0400
Subject: [PATCH 078/140] qt6-multimedia: revbump for ffmpeg-6.0
---
srcpkgs/qt6-multimedia/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/qt6-multimedia/template b/srcpkgs/qt6-multimedia/template
index d89e7d54eb5a..aae15e57ca7b 100644
--- a/srcpkgs/qt6-multimedia/template
+++ b/srcpkgs/qt6-multimedia/template
@@ -1,7 +1,7 @@
# Template file for 'qt6-multimedia'
pkgname=qt6-multimedia
version=6.4.2
-revision=1
+revision=2
build_style=cmake
configure_args="-DQT_FEATURE_gstreamer=ON"
hostmakedepends="perl qt6-declarative-host-tools pkg-config qt6-shadertools"
From b449adc5aa076cf311de40280e84695934936eae Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:51 -0400
Subject: [PATCH 079/140] qtav: revbump for ffmpeg4-4.4.3
---
srcpkgs/qtav/template | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/srcpkgs/qtav/template b/srcpkgs/qtav/template
index 34c30b2c0c78..2d00ad104355 100644
--- a/srcpkgs/qtav/template
+++ b/srcpkgs/qtav/template
@@ -1,10 +1,10 @@
# Template file for 'qtav'
pkgname=qtav
version=1.13.0
-revision=1
+revision=2
build_style=qmake
hostmakedepends="qt5-qmake qt5-host-tools"
-makedepends="ffmpeg-devel libass-devel libopenal-devel
+makedepends="ffmpeg4-devel libass-devel libopenal-devel
libva-glx-devel libXv-devel pulseaudio-devel
qt5-declarative-devel qt5-svg-devel
qt5-quickcontrols"
From 8c0bee263f98a53f6db0763061f97426ea35b626 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:51 -0400
Subject: [PATCH 080/140] qtox: revbump for ffmpeg-6.0
---
srcpkgs/qtox/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/qtox/template b/srcpkgs/qtox/template
index 16019d7eaec9..5cea0b11b697 100644
--- a/srcpkgs/qtox/template
+++ b/srcpkgs/qtox/template
@@ -1,7 +1,7 @@
# Template file for 'qtox'
pkgname=qtox
version=1.17.6
-revision=2
+revision=3
build_style=cmake
configure_args="-DUPDATE_CHECK=OFF
-DGIT_DESCRIBE=${version}
From f7fdc24e1c895554fa026ee749d0f91e46dddc4c Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:51 -0400
Subject: [PATCH 081/140] retroarch: revbump for ffmpeg-6.0
---
srcpkgs/retroarch/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/retroarch/template b/srcpkgs/retroarch/template
index 240d3df9db00..6d0b16ae2598 100644
--- a/srcpkgs/retroarch/template
+++ b/srcpkgs/retroarch/template
@@ -1,7 +1,7 @@
# Template file for 'retroarch'
pkgname=retroarch
version=1.14.0
-revision=1
+revision=2
build_style=configure
configure_args="--prefix=/usr --sysconfdir=/etc --enable-networking
--enable-udev --disable-builtinflac --disable-builtinglslang
From e363ee33255297653e813ab0f446ac68a55f4697 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:51 -0400
Subject: [PATCH 082/140] scrcpy: revbump for ffmpeg-6.0
---
srcpkgs/scrcpy/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/scrcpy/template b/srcpkgs/scrcpy/template
index ee6e698e387f..8ada5ca4323f 100644
--- a/srcpkgs/scrcpy/template
+++ b/srcpkgs/scrcpy/template
@@ -1,7 +1,7 @@
# Template file for 'scrcpy'
pkgname=scrcpy
version=2.0
-revision=1
+revision=2
build_style=meson
configure_args="-Dcompile_server=false
-Dprebuilt_server=/usr/share/scrcpy/scrcpy-server-v${version}"
From 0d6211e15b869331b1a5191c9306b3d696bc7e16 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:51 -0400
Subject: [PATCH 083/140] spek-alternative: revbump for ffmpeg4-4.4.3
---
srcpkgs/spek-alternative/template | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/srcpkgs/spek-alternative/template b/srcpkgs/spek-alternative/template
index d65086b8f008..05246f1b8d0c 100644
--- a/srcpkgs/spek-alternative/template
+++ b/srcpkgs/spek-alternative/template
@@ -1,11 +1,11 @@
# Template file for 'spek-alternative'
pkgname=spek-alternative
version=0.8.2.3
-revision=1
+revision=2
build_style=gnu-configure
hostmakedepends="automake gettext-devel intltool libtool pkg-config wxWidgets-common"
-makedepends="ffmpeg-devel wxWidgets-gtk3-devel"
-depends="ffmpeg"
+makedepends="ffmpeg4-devel wxWidgets-gtk3-devel"
+depends="ffmpeg4"
short_desc="Acoustic spectrum analyser"
maintainer="Kartik Singh <kartik.ynwa@gmail.com>"
license="GPL-3.0-or-later"
From c526e1d75ba5268c9afaacbbd3fb32a0f399f11e Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:51 -0400
Subject: [PATCH 084/140] ssr: revbump for ffmpeg4-4.4.3
---
srcpkgs/ssr/template | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/srcpkgs/ssr/template b/srcpkgs/ssr/template
index b055b9ec0774..3448ca110eb0 100644
--- a/srcpkgs/ssr/template
+++ b/srcpkgs/ssr/template
@@ -1,11 +1,11 @@
# Template file for 'ssr'
pkgname=ssr
version=0.4.4
-revision=1
+revision=2
build_style=cmake
configure_args="-DWITH_QT5=ON"
hostmakedepends="pkg-config"
-makedepends="alsa-lib-devel ffmpeg-devel glu-devel jack-devel pulseaudio-devel
+makedepends="alsa-lib-devel ffmpeg4-devel glu-devel jack-devel pulseaudio-devel
qt5-tools-devel qt5-x11extras-devel libXinerama-devel v4l-utils-devel"
depends="desktop-file-utils hicolor-icon-theme"
short_desc="Simple Screen Recorder for programs and games"
From ad869ddfe565baf6bd473877e418b46d3ca0e9d0 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:51 -0400
Subject: [PATCH 085/140] sumo: revbump for ffmpeg-6.0
---
srcpkgs/sumo/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/sumo/template b/srcpkgs/sumo/template
index 0f9b9ec815f5..a3fe134aa5ac 100644
--- a/srcpkgs/sumo/template
+++ b/srcpkgs/sumo/template
@@ -1,7 +1,7 @@
# Template file for 'sumo'
pkgname=sumo
version=1.12.0
-revision=5
+revision=6
build_style=cmake
hostmakedepends="libgdal-tools pkg-config swig python3-setuptools"
makedepends="python3-devel ffmpeg-devel fox-devel gl2ps-devel libgdal-devel
From 5dcacf56e71d86ee8cf59cbb48b6732bbefd8c7c Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:52 -0400
Subject: [PATCH 086/140] synfig: revbump for ffmpeg4-4.4.3
---
srcpkgs/synfig/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/synfig/template b/srcpkgs/synfig/template
index 5f5f5bb3f4b2..9b4d9adf09c6 100644
--- a/srcpkgs/synfig/template
+++ b/srcpkgs/synfig/template
@@ -7,7 +7,7 @@ build_style=gnu-configure
configure_args="--with-boost-libdir=${XBPS_CROSS_BASE}/usr/lib"
hostmakedepends="boost-build ImageMagick pkg-config intltool"
makedepends="ETL gettext-devel libxml++-devel mlt-devel libmagick-devel
- libmng-devel boost-build boost-devel libopenexr-devel ffmpeg-devel"
+ libmng-devel boost-build boost-devel libopenexr-devel ffmpeg4-devel"
depends="ImageMagick"
short_desc="CLI 2D vector and timeline-based animation software"
maintainer="Orphaned <orphan@voidlinux.org>"
From a78827d2407e80c64db4e8438e857f7d27a308e5 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:52 -0400
Subject: [PATCH 087/140] telegram-desktop: revbump for ffmpeg-6.0
---
srcpkgs/telegram-desktop/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/telegram-desktop/template b/srcpkgs/telegram-desktop/template
index aae9f3135100..7943b36f0b8a 100644
--- a/srcpkgs/telegram-desktop/template
+++ b/srcpkgs/telegram-desktop/template
@@ -1,7 +1,7 @@
# Template file for 'telegram-desktop'
pkgname=telegram-desktop
version=4.6.5
-revision=1
+revision=2
build_style=cmake
build_helper="qemu"
configure_args="-DTDESKTOP_API_ID=209235
From d934199f8a52091dab168b5432da8aad7fa73bfb Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:52 -0400
Subject: [PATCH 088/140] tg_owt: revbump for ffmpeg-6.0
---
srcpkgs/tg_owt/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/tg_owt/template b/srcpkgs/tg_owt/template
index 97d195ddb34a..551614b24956 100644
--- a/srcpkgs/tg_owt/template
+++ b/srcpkgs/tg_owt/template
@@ -1,7 +1,7 @@
# Template file for 'tg_owt'
pkgname=tg_owt
version=0.0.0.20230107
-revision=1
+revision=2
_commit=5098730b9eb6173f0b52068fe2555b7c1015123a
_libyuv_commit=00950840d1c9bcbb3eb6ebc5aac5793e71166c8b
_abseil_commit=8c0b94e793a66495e0b1f34a5eb26bd7dc672db0
From 8c60e54421041010ed4005f495221f7526a17bd5 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:52 -0400
Subject: [PATCH 089/140] timg: revbump for ffmpeg-6.0
---
srcpkgs/timg/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/timg/template b/srcpkgs/timg/template
index 91f1516b2597..334443d3f9bb 100644
--- a/srcpkgs/timg/template
+++ b/srcpkgs/timg/template
@@ -1,7 +1,7 @@
# Template file for 'timg'
pkgname=timg
version=1.4.4
-revision=1
+revision=2
build_style=cmake
configure_args="-DWITH_OPENSLIDE_SUPPORT=off -Wno-dev"
hostmakedepends="pkg-config git"
From 4c9545e835a32247661a1e7dd5f1404e6afd747d Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:52 -0400
Subject: [PATCH 090/140] tvheadend: revbump for ffmpeg4-4.4.3
---
srcpkgs/tvheadend/template | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/srcpkgs/tvheadend/template b/srcpkgs/tvheadend/template
index e6b16d7ccf3b..46b52b6fb7f9 100644
--- a/srcpkgs/tvheadend/template
+++ b/srcpkgs/tvheadend/template
@@ -1,14 +1,14 @@
# Template file for 'tvheadend'
pkgname=tvheadend
version=4.2.8
-revision=6
+revision=7
build_style=gnu-configure
configure_args="--enable-dvbscan --disable-ffmpeg_static
--disable-hdhomerun_static --disable-bintray_cache --disable-libx264_static
--disable-libx265_static --disable-libvpx_static --disable-libtheora_static
--disable-libvorbis_static --disable-libfdkaac_static"
hostmakedepends="gettext pkg-config python git which"
-makedepends="avahi-libs-devel openssl-devel zlib-devel libcurl-devel ffmpeg-devel"
+makedepends="avahi-libs-devel openssl-devel zlib-devel libcurl-devel ffmpeg4-devel"
short_desc="TV streaming server"
maintainer="lemmi <lemmi@nerd2nerd.org>"
license="GPL-3.0-only"
From 69bb06023efd670a285e47f599dc51584ac8f966 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:52 -0400
Subject: [PATCH 091/140] unpaper: update to 7.0.0.
---
srcpkgs/unpaper/template | 16 ++++++++--------
1 file changed, 8 insertions(+), 8 deletions(-)
diff --git a/srcpkgs/unpaper/template b/srcpkgs/unpaper/template
index 38ed47a58401..1ff910e722af 100644
--- a/srcpkgs/unpaper/template
+++ b/srcpkgs/unpaper/template
@@ -1,13 +1,13 @@
# Template file for 'unpaper'
pkgname=unpaper
-version=6.1
-revision=3
-build_style=gnu-configure
+version=7.0.0
+revision=1
+build_style=meson
+hostmakedepends="pkg-config meson libxslt"
+makedepends="ffmpeg-devel python3-Sphinx"
+short_desc="Post-processing tool for scanned sheets of paper"
maintainer="Orphaned <orphan@voidlinux.org>"
-hostmakedepends="pkg-config libxslt"
-makedepends="ffmpeg-devel"
-license="GPL-2"
+license="GPL-2.0-or-later"
homepage="https://www.flameeyes.eu/projects/unpaper"
-short_desc="A post-processing tool for scanned sheets of paper"
distfiles="https://www.flameeyes.eu/files/${pkgname}-${version}.tar.xz"
-checksum=237c84f5da544b3f7709827f9f12c37c346cdf029b1128fb4633f9bafa5cb930
+checksum=2575fbbf26c22719d1cb882b59602c9900c7f747118ac130883f63419be46a80
From 4e67bf542e96aac453bf8ec2d59148e5d3aa592d Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:52 -0400
Subject: [PATCH 092/140] vba-m: revbump for ffmpeg-6.0
---
srcpkgs/vba-m/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/vba-m/template b/srcpkgs/vba-m/template
index ba153e0b58ca..aa6093645e97 100644
--- a/srcpkgs/vba-m/template
+++ b/srcpkgs/vba-m/template
@@ -2,7 +2,7 @@
pkgname=vba-m
reverts=1292_2
version=2.1.5
-revision=1
+revision=2
build_style=cmake
configure_args="-DENABLE_GTK=TRUE -DENABLE_FFMPEG=TRUE -DENABLE_LINK=TRUE -DCMAKE_BUILD_TYPE=Release"
hostmakedepends="gettext pkg-config unzip zip yasm wxWidgets-gtk3-devel"
From 5b8eb943b36d218a4465a6b615435c312c9038f3 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:52 -0400
Subject: [PATCH 093/140] vice: revbump for ffmpeg4-4.4.3
---
srcpkgs/vice/template | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/srcpkgs/vice/template b/srcpkgs/vice/template
index 0924767cfcfb..5981e45149d0 100644
--- a/srcpkgs/vice/template
+++ b/srcpkgs/vice/template
@@ -1,7 +1,7 @@
# Template file for 'vice'
pkgname=vice
version=3.5
-revision=1
+revision=2
build_style=gnu-configure
configure_args="
$(vopt_enable sdl2 sdlui2)
@@ -28,7 +28,7 @@ makedepends="
$(vopt_if gtk3 gtk+3-devel)
$(vopt_if gtk3 pulseaudio-devel)
$(vopt_if gtk3 pango-devel)
- $(vopt_if ffmpeg ffmpeg-devel)"
+ $(vopt_if ffmpeg ffmpeg4-devel)"
short_desc="Emulator for C64, C128, CBM-II, PET, VIC20, Plus4 and C16"
maintainer="Orphaned <orphan@voidlinux.org>"
license="GPL-2.0-or-later"
From 8a6bd700919fe4060bf0d5e81125ea6ad2ee0e5b Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:52 -0400
Subject: [PATCH 094/140] waypipe: revbump for ffmpeg-6.0
---
srcpkgs/waypipe/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/waypipe/template b/srcpkgs/waypipe/template
index 5c4161900060..1a46fe27f7d8 100644
--- a/srcpkgs/waypipe/template
+++ b/srcpkgs/waypipe/template
@@ -1,7 +1,7 @@
# Template file for 'waypipe'
pkgname=waypipe
version=0.8.4
-revision=1
+revision=2
build_style=meson
# lto is off because it causes linking errors in armv6l and armv7l (due to NEON)
configure_args="-Dwerror=false -Dwith_dmabuf=enabled -Dwith_lz4=enabled
From 5fbbe4c7bb60be4d10a49d7c3e4c106f6b875a8a Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:52 -0400
Subject: [PATCH 095/140] wf-recorder: revbump for ffmpeg-6.0
---
srcpkgs/wf-recorder/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/wf-recorder/template b/srcpkgs/wf-recorder/template
index e278eb001600..5d014a5f28af 100644
--- a/srcpkgs/wf-recorder/template
+++ b/srcpkgs/wf-recorder/template
@@ -1,7 +1,7 @@
# Template file for 'wf-recorder'
pkgname=wf-recorder
version=0.3.0
-revision=1
+revision=2
build_style=meson
hostmakedepends="pkg-config scdoc wayland-devel"
makedepends="wayland-protocols wayland-devel ffmpeg-devel x264-devel
From 28739e7d39594854accdd2efd50bbb3bde779496 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:52 -0400
Subject: [PATCH 096/140] xpra: revbump for ffmpeg-6.0
---
srcpkgs/xpra/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/xpra/template b/srcpkgs/xpra/template
index 38f83283b1e5..b6e01ff0a813 100644
--- a/srcpkgs/xpra/template
+++ b/srcpkgs/xpra/template
@@ -1,7 +1,7 @@
# Template file for 'xpra'
pkgname=xpra
version=4.4.4
-revision=1
+revision=2
build_style=python3-module
make_build_args="--without-cuda_kernels --without-cuda_rebuild"
make_install_args="$(vopt_with docs) ${make_build_args}"
From b9af0da7e2afed91c8f8ba4271ceaed945fb599b Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Fri, 31 Mar 2023 09:07:40 -0400
Subject: [PATCH 097/140] nv-codec-headers: update to 12.0.16.0
---
srcpkgs/nv-codec-headers/template | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/srcpkgs/nv-codec-headers/template b/srcpkgs/nv-codec-headers/template
index 3d422a61e489..251e057f826f 100644
--- a/srcpkgs/nv-codec-headers/template
+++ b/srcpkgs/nv-codec-headers/template
@@ -1,6 +1,6 @@
# Template file for 'nv-codec-headers'
pkgname=nv-codec-headers
-version=11.1.5.1
+version=12.0.16.0
revision=1
build_style=gnu-makefile
short_desc="FFmpeg version of headers required to interface with Nvidias codec APIs"
@@ -8,7 +8,7 @@ maintainer="Orphaned <orphan@voidlinux.org>"
license="MIT"
homepage="http://git.videolan.org/?p=ffmpeg/nv-codec-headers.git"
distfiles="https://github.com/FFmpeg/nv-codec-headers/archive/n${version}.tar.gz"
-checksum=d095fbd56aa93772471a323be0ebe65504a0f43f06c76a30b6d25da77b06ae9c
+checksum=2a1533b65f55f9da52956faf0627ed3b74868ac0c7f269990edd21369113b48f
post_install() {
sed -n '4,25p' include/ffnvcodec/nvEncodeAPI.h > LICENSE
From 5f816524af23f848c4a899b0a7d51f011d7abeef Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Fri, 31 Mar 2023 09:08:40 -0400
Subject: [PATCH 098/140] openimagedenoise: revbump for ffmpeg-6.0
---
srcpkgs/openimagedenoise/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/openimagedenoise/template b/srcpkgs/openimagedenoise/template
index db5ccdb055cc..cb90045afb63 100644
--- a/srcpkgs/openimagedenoise/template
+++ b/srcpkgs/openimagedenoise/template
@@ -1,7 +1,7 @@
# Template file for 'openimagedenoise'
pkgname=openimagedenoise
version=1.4.3
-revision=1
+revision=2
archs="x86_64*"
build_style=cmake
hostmakedepends="ispc python3"
From e89f4bff512b9aa7c683b42e4a01474fea5924ac Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Sun, 19 Mar 2023 10:58:01 -0400
Subject: [PATCH 099/140] gst-libav: update to 1.22.1
---
srcpkgs/gst-libav/template | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/srcpkgs/gst-libav/template b/srcpkgs/gst-libav/template
index f082bd211c65..a2c97bfbcdb9 100644
--- a/srcpkgs/gst-libav/template
+++ b/srcpkgs/gst-libav/template
@@ -1,7 +1,7 @@
# Template file for 'gst-libav'
pkgname=gst-libav
-version=1.20.3
-revision=2
+version=1.22.1
+revision=1
build_style=meson
hostmakedepends="pkg-config yasm"
makedepends="orc-devel gst-plugins-base1-devel ffmpeg-devel"
@@ -11,7 +11,7 @@ maintainer="Orphaned <orphan@voidlinux.org>"
license="LGPL-2.0-or-later"
homepage="https://gstreamer.freedesktop.org"
distfiles="${homepage}/src/${pkgname}/${pkgname}-${version}.tar.xz"
-checksum=3fedd10560fcdfaa1b6462cbf79a38c4e7b57d7f390359393fc0cef6dbf27dfe
+checksum=c958e825dc3ac3b7a481f8db5268131a1cd701312385c2d803dc63c8e460b5fb
case "$XBPS_TARGET_MACHINE" in
*-musl) # Required by musl for M_SQRT1_2
From 84aeee6cebac0ee164261d5bdbe4535a8198f992 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Sun, 19 Mar 2023 10:58:18 -0400
Subject: [PATCH 100/140] gst-omx: update to 1.22.1
---
srcpkgs/gst-omx/template | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/srcpkgs/gst-omx/template b/srcpkgs/gst-omx/template
index 893535c463da..76692c2a13f6 100644
--- a/srcpkgs/gst-omx/template
+++ b/srcpkgs/gst-omx/template
@@ -1,6 +1,6 @@
# Template file for 'gst-omx'
pkgname=gst-omx
-version=1.20.3
+version=1.22.1
revision=1
build_style=meson
configure_args="-Dexamples=disabled -Dtarget=generic"
@@ -11,4 +11,4 @@ maintainer="Orphaned <orphan@voidlinux.org>"
license="LGPL-2.1-only"
homepage="https://gstreamer.freedesktop.org"
distfiles="${homepage}/src/${pkgname}/${pkgname}-${version}.tar.xz"
-checksum=8db48040bb41f09edf8d17ff6d16c54888d7777ba4501c2c69f0083350ea9a15
+checksum=2d37f60cd33e68dcef0bcd09b2dd8a0b2eb3ab6d6ac172dca46f70eb02756687
From 579e709bae9f9292a1e3e0e93077f4f73eb62fb6 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Sun, 19 Mar 2023 10:59:04 -0400
Subject: [PATCH 101/140] gst-plugins-bad1: update to 1.22.1
---
common/shlibs | 1 +
srcpkgs/gst-plugins-bad1/template | 2 +-
2 files changed, 2 insertions(+), 1 deletion(-)
diff --git a/common/shlibs b/common/shlibs
index d0d328b09ef9..42744a55b1fc 100644
--- a/common/shlibs
+++ b/common/shlibs
@@ -1147,6 +1147,7 @@ libgstpbutils-1.0.so.0 gst-plugins-base1-1.0.0_1
libgstriff-1.0.so.0 gst-plugins-base1-1.0.0_1
libgstapp-1.0.so.0 gst-plugins-base1-1.0.0_1
libgstallocators-1.0.so.0 gst-plugins-base1-1.1.1_1
+libgsttranscoder-1.0.so.0 gst-plugins-bad1-1.22.1_1
libgstphotography-1.0.so.0 gst-plugins-bad1-1.18.3_2
libgstsignalprocessor-1.0.so.0 gst-plugins-bad1-1.18.3_2
libgstbasevideo-1.0.so.0 gst-plugins-bad1-1.18.3_2
diff --git a/srcpkgs/gst-plugins-bad1/template b/srcpkgs/gst-plugins-bad1/template
index 5a9d5387e0d4..7f272f915ac4 100644
--- a/srcpkgs/gst-plugins-bad1/template
+++ b/srcpkgs/gst-plugins-bad1/template
@@ -36,7 +36,7 @@ maintainer="Orphaned <orphan@voidlinux.org>"
license="GPL-2.0-or-later, LGPL-2.1-or-later"
homepage="https://gstreamer.freedesktop.org"
distfiles="${homepage}/src/${pkgname/1/}/${pkgname/1/}-${version}.tar.xz"
-checksum=7a11c13b55dd1d2386dd902219e41cbfcdda8e1e0aa3e738186c95074b35da4f
+checksum=2f39b6f222d98666f9ff420a00233e336949953a846237c2bfafc8805f509f0e
build_options="gir gme wayland"
build_options_default="gir wayland"
From 561e0442961149466adfb7a3839bf97a97bd2cf4 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Sun, 19 Mar 2023 10:59:04 -0400
Subject: [PATCH 102/140] gst-plugins-ugly1: update to 1.22.1
---
srcpkgs/gst-plugins-ugly1/template | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/srcpkgs/gst-plugins-ugly1/template b/srcpkgs/gst-plugins-ugly1/template
index e254fd40f869..5647c012c9fe 100644
--- a/srcpkgs/gst-plugins-ugly1/template
+++ b/srcpkgs/gst-plugins-ugly1/template
@@ -1,6 +1,6 @@
# Template file for 'gst-plugins-ugly1'
pkgname=gst-plugins-ugly1
-version=1.20.3
+version=1.22.1
revision=1
build_style=meson
configure_args="-Damrnb=disabled -Damrwbdec=disabled -Dsidplay=disabled"
@@ -15,4 +15,4 @@ maintainer="Orphaned <orphan@voidlinux.org>"
license="LGPL-2.1-or-later"
homepage="https://gstreamer.freedesktop.org"
distfiles="${homepage}/src/${pkgname/1/}/${pkgname/1/}-${version}.tar.xz"
-checksum=8caa20789a09c304b49cf563d33cca9421b1875b84fcc187e4a385fa01d6aefd
+checksum=4ab3d9e13481bce1ca3c7c4bb1f65dce4f0bb40fb1cac4416e8c06dd648815c2
From 0f97b05ddc9eb9235451b25a34ac604ab725925a Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Sun, 19 Mar 2023 10:59:31 -0400
Subject: [PATCH 103/140] gst-editing-services: update to 1.22.1
---
srcpkgs/gst1-editing-services/template | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/srcpkgs/gst1-editing-services/template b/srcpkgs/gst1-editing-services/template
index 673b46970f24..f2045ad6043c 100644
--- a/srcpkgs/gst1-editing-services/template
+++ b/srcpkgs/gst1-editing-services/template
@@ -1,6 +1,6 @@
# Template file for 'gst1-editing-services'
pkgname=gst1-editing-services
-version=1.20.3
+version=1.22.1
revision=1
build_style=meson
build_helper="gir"
@@ -12,7 +12,7 @@ maintainer="Toyam Cox <Vaelatern@gmail.com>"
license="LGPL-2.0-or-later"
homepage="https://gstreamer.freedesktop.org"
distfiles="${homepage}/src/${pkgname/gst1/gst}/${pkgname/gst1/gst}-${version}.tar.xz"
-checksum=5fd896de69fbe24421eb6b0ff8d2f8b4c3cba3f3025ceacd302172f39a8abaa2
+checksum=0f9e5e08ef80a4b9a0e971c5f032b13c71aa6fef236265c2d615456e15161438
do_check() {
: # Tests fail in older versions as well
From cd8a349305d0ccff5b3384def8b79a450420e092 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Sun, 19 Mar 2023 11:00:00 -0400
Subject: [PATCH 104/140] gst-rtsp-server: update to 1.22.1
---
srcpkgs/gst-rtsp-server/template | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/srcpkgs/gst-rtsp-server/template b/srcpkgs/gst-rtsp-server/template
index 8ceea8d34b4b..ded9a69a2e9d 100644
--- a/srcpkgs/gst-rtsp-server/template
+++ b/srcpkgs/gst-rtsp-server/template
@@ -1,7 +1,7 @@
# Template file for 'gst-rtsp-server'
pkgname=gst-rtsp-server
-version=1.20.3
-revision=3
+version=1.22.1
+revision=1
build_style=meson
hostmakedepends="pkg-config python3"
makedepends="glib-devel gst-plugins-bad1-devel gobject-introspection
@@ -10,5 +10,5 @@ short_desc="GStreamer multimedia graph framework - rtsp server"
maintainer="1is7ac3 <isaac.qa13@gmail.com>"
license="LGPL-2.1-or-later"
homepage="https://gstreamer.freedesktop.org"
-distfiles="https://gstreamer.freedesktop.org/src/gst-rtsp-server/gst-rtsp-server-${version}.tar.xz"
-checksum=ee402718be9b127f0e5e66ca4c1b4f42e4926ec93ba307b7ccca5dc6cc9794ca
+distfiles="${homepage}/src/${pkgname}/${pkgname}-${version}.tar.xz"
+checksum=4e0b972608f67d5d8f5363c827cfcf132b0e00877be6f1905358d514249b05a3
From 2fdc537fd1bf61ae4f40ee702d328a95b8a57e33 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Sun, 19 Mar 2023 11:00:39 -0400
Subject: [PATCH 105/140] gst1-python3: update to 1.22.1
---
srcpkgs/gst1-python3/template | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/srcpkgs/gst1-python3/template b/srcpkgs/gst1-python3/template
index 3f564ac64b93..7a8d094ef61f 100644
--- a/srcpkgs/gst1-python3/template
+++ b/srcpkgs/gst1-python3/template
@@ -1,7 +1,7 @@
# Template file for 'gst1-python3'
pkgname=gst1-python3
-version=1.20.3
-revision=2
+version=1.22.1
+revision=1
build_style=meson
hostmakedepends="pkg-config python3"
makedepends="libglib-devel python3-devel python3-gobject-devel gst-plugins-base1-devel"
@@ -11,4 +11,4 @@ maintainer="Orphaned <orphan@voidlinux.org>"
license="LGPL-2.1-or-later"
homepage="https://gstreamer.freedesktop.org"
distfiles="${homepage}/src/gst-python/gst-python-${version}.tar.xz"
-checksum=db348120eae955b8cc4de3560a7ea06e36d6e1ddbaa99a7ad96b59846601cfdc
+checksum=96008a441d685a64275a515b893ccad0fea1d560c43acd0763533e17f3a13ebb
From 833e3fd54f170d0b369cfcf286d582a44bb514c5 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Sun, 19 Mar 2023 11:00:46 -0400
Subject: [PATCH 106/140] gstreamer-vaapi: update to 1.22.1
---
srcpkgs/gstreamer-vaapi/template | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/srcpkgs/gstreamer-vaapi/template b/srcpkgs/gstreamer-vaapi/template
index 3cc4e057559a..c100d99e9af1 100644
--- a/srcpkgs/gstreamer-vaapi/template
+++ b/srcpkgs/gstreamer-vaapi/template
@@ -1,6 +1,6 @@
# Template file for 'gstreamer-vaapi'
pkgname=gstreamer-vaapi
-version=1.20.3
+version=1.22.1
revision=1
build_style=meson
hostmakedepends="pkg-config"
@@ -11,7 +11,7 @@ license="LGPL-2.1-or-later"
homepage="https://gstreamer.freedesktop.org"
changelog="https://raw.githubusercontent.com/GStreamer/gstreamer-vaapi/master/ChangeLog"
distfiles="${homepage}/src/gstreamer-vaapi/gstreamer-vaapi-${version}.tar.xz"
-checksum=6ee99eb316abdde9ad37002915bd8c3867918f6fdc74b7cf2ac4c1ae0d690b45
+checksum=423b57db7fc5f9137dadf17cb3853a47438d63cd4ba6889a882e63fb5be997bc
pre_check() {
# Seems to need certain hardware to pass
From 334be539b615310766f23dc5b2006e96522fd01a Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Sun, 19 Mar 2023 11:00:51 -0400
Subject: [PATCH 107/140] gstreamer1: update to 1.22.1
---
srcpkgs/gstreamer1/template | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/srcpkgs/gstreamer1/template b/srcpkgs/gstreamer1/template
index ae8a49cb20e8..362fe82faec3 100644
--- a/srcpkgs/gstreamer1/template
+++ b/srcpkgs/gstreamer1/template
@@ -1,6 +1,6 @@
# Template file for 'gstreamer1'
pkgname=gstreamer1
-version=1.20.3
+version=1.22.1
revision=1
build_style=meson
build_helper="gir"
@@ -16,7 +16,7 @@ maintainer="Orphaned <orphan@voidlinux.org>"
license="LGPL-2.0-or-later"
homepage="https://gstreamer.freedesktop.org"
distfiles="${homepage}/src/gstreamer/gstreamer-${version}.tar.xz"
-checksum=607daf64bbbd5fb18af9d17e21c0d22c4d702fffe83b23cb22d1b1af2ca23a2a
+checksum=cd3ca759f926763615fdfcea63c9761198c42889bc0615ceec73e22b24fde771
pre_check() {
# gst_gstdatetime is known to fail according to LFS
From 73bb4eaf21c8d50e16a04a767919c59550b86938 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Sun, 19 Mar 2023 10:59:04 -0400
Subject: [PATCH 108/140] gst-plugins-good1: update to 1.22.1
---
srcpkgs/gst-plugins-good1/template | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/srcpkgs/gst-plugins-good1/template b/srcpkgs/gst-plugins-good1/template
index 1f5e620ce1fd..00baa6732c75 100644
--- a/srcpkgs/gst-plugins-good1/template
+++ b/srcpkgs/gst-plugins-good1/template
@@ -1,6 +1,6 @@
# Template file for 'gst-plugins-good1'
pkgname=gst-plugins-good1
-version=1.20.3
+version=1.22.1
revision=1
build_style=meson
configure_args="-Ddv=disabled -Ddv1394=disabled -Dshout2=disabled -Dqt5=enabled
@@ -22,7 +22,7 @@ maintainer="Orphaned <orphan@voidlinux.org>"
license="LGPL-2.1-or-later"
homepage="https://gstreamer.freedesktop.org"
distfiles="${homepage}/src/${pkgname/1/}/${pkgname/1/}-${version}.tar.xz"
-checksum=f8f3c206bf5cdabc00953920b47b3575af0ef15e9f871c0b6966f6d0aa5868b7
+checksum=44f9104654b4fd042aebe90932ab92e7ff7d8460fbc05b23dad87dffe70974cc
build_options="gtk3 wayland"
build_options_default="gtk3 wayland"
From dd7301d1f6ed28c8a63ccf6cc43a94810d19c2aa Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Sun, 19 Mar 2023 10:59:04 -0400
Subject: [PATCH 109/140] gst-plugins-base1: update to 1.22.1
---
srcpkgs/gst-plugins-base1/template | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/srcpkgs/gst-plugins-base1/template b/srcpkgs/gst-plugins-base1/template
index 29e8f76bd1fe..6d2cad16f985 100644
--- a/srcpkgs/gst-plugins-base1/template
+++ b/srcpkgs/gst-plugins-base1/template
@@ -1,6 +1,6 @@
# Template file for 'gst-plugins-base1'
pkgname=gst-plugins-base1
-version=1.20.3
+version=1.22.1
revision=1
build_style=meson
build_helper="gir"
@@ -22,7 +22,7 @@ maintainer="Orphaned <orphan@voidlinux.org>"
license="GPL-2.0-or-later, LGPL-2.0-or-later"
homepage="https://gstreamer.freedesktop.org"
distfiles="${homepage}/src/${pkgname/1/}/${pkgname/1/}-${version}.tar.xz"
-checksum=7e30b3dd81a70380ff7554f998471d6996ff76bbe6fc5447096f851e24473c9f
+checksum=59bcaeacc5646b8dbdcfa4ef20ca6e818dd234910efb4cee1bbea441a3801c69
build_options="cdparanoia gir sndio wayland"
build_options_default="cdparanoia gir wayland"
From d94174d2b6dbc98f15b0c6fb60ea57b5fd755bcc Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Fri, 16 Dec 2022 09:25:22 -0500
Subject: [PATCH 110/140] intel-gmmlib: update to 22.3.3
---
srcpkgs/intel-gmmlib/template | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/srcpkgs/intel-gmmlib/template b/srcpkgs/intel-gmmlib/template
index 8ed6ed3cf56c..2605226152e5 100644
--- a/srcpkgs/intel-gmmlib/template
+++ b/srcpkgs/intel-gmmlib/template
@@ -1,6 +1,6 @@
# Template file for 'intel-gmmlib'
pkgname=intel-gmmlib
-version=22.2.0
+version=22.3.3
revision=1
archs="i686* x86_64*"
build_style=cmake
@@ -18,7 +18,7 @@ maintainer="Stefano Ragni <st3r4g@protonmail.com>"
license="MIT"
homepage="https://github.com/intel/gmmlib"
distfiles="https://github.com/intel/gmmlib/archive/intel-gmmlib-${version}.tar.gz"
-checksum=0b2253894c6fc8455b6d7c5e87e6504a76d6f60ea192e1445c2f93164bf529c0
+checksum=86651bd2803c9f0afd82471bec784e65d2b418dee315a053d22215eb2a679be7
lib32disabled=yes
From 581d0d241961c40d8050a3b4105060998c836a67 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Fri, 16 Dec 2022 09:25:47 -0500
Subject: [PATCH 111/140] intel-media-driver: update to 22.6.4
---
...mmon-Enable-MMC-in-free-kernel-build.patch | 125 ++++++++++++++++++
.../intel-media-driver/patches/execinfo.patch | 58 --------
srcpkgs/intel-media-driver/template | 4 +-
3 files changed, 127 insertions(+), 60 deletions(-)
create mode 100644 srcpkgs/intel-media-driver/patches/0001-Media-Common-Enable-MMC-in-free-kernel-build.patch
delete mode 100644 srcpkgs/intel-media-driver/patches/execinfo.patch
diff --git a/srcpkgs/intel-media-driver/patches/0001-Media-Common-Enable-MMC-in-free-kernel-build.patch b/srcpkgs/intel-media-driver/patches/0001-Media-Common-Enable-MMC-in-free-kernel-build.patch
new file mode 100644
index 000000000000..525fb688722c
--- /dev/null
+++ b/srcpkgs/intel-media-driver/patches/0001-Media-Common-Enable-MMC-in-free-kernel-build.patch
@@ -0,0 +1,125 @@
+From e68feab7db036838d9521ba3b9f00717c37c024c Mon Sep 17 00:00:00 2001
+From: JayYang <jay.yang@intel.com>
+Date: Tue, 21 Mar 2023 17:17:55 +0800
+Subject: [PATCH] [Media Common] Enable MMC in free kernel build
+
+Add mmc build definition in free kernel build
+---
+ media_driver/agnostic/gen9/codec/hal/media_srcs.cmake | 2 +-
+ media_driver/cmake/linux/media_feature_flags_linux.cmake | 3 +--
+ .../media_interfaces_m9_bxt/media_interfaces_g9_bxt.cpp | 2 +-
+ .../media_interfaces_m9_cfl/media_interfaces_g9_cfl.cpp | 2 +-
+ .../media_interfaces_m9_glk/media_interfaces_g9_glk.cpp | 2 +-
+ .../media_interfaces_m9_kbl/media_interfaces_g9_kbl.cpp | 2 +-
+ .../media_interfaces_m9_skl/media_interfaces_g9_skl.cpp | 2 +-
+ 7 files changed, 7 insertions(+), 8 deletions(-)
+
+diff --git a/media_driver/agnostic/gen9/codec/hal/media_srcs.cmake b/media_driver/agnostic/gen9/codec/hal/media_srcs.cmake
+index 8bb36bafe..78902a22d 100644
+--- a/media_driver/agnostic/gen9/codec/hal/media_srcs.cmake
++++ b/media_driver/agnostic/gen9/codec/hal/media_srcs.cmake
+@@ -27,7 +27,7 @@ set(TMP_1_HEADERS_
+ ${CMAKE_CURRENT_LIST_DIR}/codechal_hw_g9_X.h
+ )
+
+-if(${MMC_Supported} STREQUAL "yes")
++if(${MMC_Supported} STREQUAL "yes" AND ENABLE_NONFREE_KERNELS AND ENABLE_KERNELS)
+ set(TMP_1_SOURCES_
+ ${TMP_1_SOURCES_}
+ ${CMAKE_CURRENT_LIST_DIR}/codechal_memdecomp_g9.cpp
+diff --git a/media_driver/cmake/linux/media_feature_flags_linux.cmake b/media_driver/cmake/linux/media_feature_flags_linux.cmake
+index de0ca853f..8121ea60c 100644
+--- a/media_driver/cmake/linux/media_feature_flags_linux.cmake
++++ b/media_driver/cmake/linux/media_feature_flags_linux.cmake
+@@ -35,7 +35,6 @@ if(NOT ENABLE_KERNELS OR NOT ENABLE_NONFREE_KERNELS)
+ bs_set_if_undefined(HEVC_Encode_VME_Supported "no")
+ bs_set_if_undefined(MPEG2_Encode_VME_Supported "no")
+ bs_set_if_undefined(CMRT_HEVC_ENC_FEI_Supported "no")
+- bs_set_if_undefined(MMC_Supported "no")
+ bs_set_if_undefined(VC1_Decode_Supported "no")
+ bs_set_if_undefined(Decode_Processing_Supported "no")
+ bs_set_if_undefined(Kernel_Auto_Denoise_Supported "no")
+@@ -46,7 +45,6 @@ else()
+ bs_set_if_undefined(HEVC_Encode_VME_Supported "${Encode_VME_Supported}")
+ bs_set_if_undefined(MPEG2_Encode_VME_Supported "${Encode_VME_Supported}")
+ bs_set_if_undefined(CMRT_HEVC_ENC_FEI_Supported "yes")
+- bs_set_if_undefined(MMC_Supported "yes")
+ bs_set_if_undefined(VC1_Decode_Supported "yes")
+ bs_set_if_undefined(Decode_Processing_Supported "yes")
+ bs_set_if_undefined(Kernel_Auto_Denoise_Supported "yes")
+@@ -64,6 +62,7 @@ bs_set_if_undefined(VP9_Decode_Supported "yes")
+ bs_set_if_undefined(VP_SFC_Supported "yes")
+ bs_set_if_undefined(Common_Encode_Supported "yes")
+ bs_set_if_undefined(Media_Scalability_Supported "yes")
++bs_set_if_undefined(MMC_Supported "yes")
+
+ # features controlled by global flag Encode_VDEnc_Supported
+ bs_set_if_undefined(AVC_Encode_VDEnc_Supported "${Encode_VDEnc_Supported}")
+diff --git a/media_driver/media_interface/media_interfaces_m9_bxt/media_interfaces_g9_bxt.cpp b/media_driver/media_interface/media_interfaces_m9_bxt/media_interfaces_g9_bxt.cpp
+index 3f306ee2a..8e4c0f532 100644
+--- a/media_driver/media_interface/media_interfaces_m9_bxt/media_interfaces_g9_bxt.cpp
++++ b/media_driver/media_interface/media_interfaces_m9_bxt/media_interfaces_g9_bxt.cpp
+@@ -135,7 +135,7 @@ MOS_STATUS MhwInterfacesG9Bxt::Initialize(
+
+ return MOS_STATUS_SUCCESS;
+ }
+-#ifdef _MMC_SUPPORTED
++#if defined(_MMC_SUPPORTED) && defined(ENABLE_KERNELS) && !defined(_FULL_OPEN_SOURCE)
+ static bool bxtRegisteredMmd =
+ MediaFactory<uint32_t, MmdDevice>::
+ Register<MmdDeviceG9Bxt>((uint32_t)IGFX_BROXTON);
+diff --git a/media_driver/media_interface/media_interfaces_m9_cfl/media_interfaces_g9_cfl.cpp b/media_driver/media_interface/media_interfaces_m9_cfl/media_interfaces_g9_cfl.cpp
+index b8fa1eec0..84e0fad1d 100644
+--- a/media_driver/media_interface/media_interfaces_m9_cfl/media_interfaces_g9_cfl.cpp
++++ b/media_driver/media_interface/media_interfaces_m9_cfl/media_interfaces_g9_cfl.cpp
+@@ -44,7 +44,7 @@ static bool cflRegisteredMhw =
+ MediaFactory<uint32_t, MhwInterfaces>::
+ Register<MhwInterfacesG9Kbl>((uint32_t)IGFX_COFFEELAKE);
+
+-#ifdef _MMC_SUPPORTED
++#if defined(_MMC_SUPPORTED) && defined(ENABLE_KERNELS) && !defined(_FULL_OPEN_SOURCE)
+ static bool cflRegisteredMmd =
+ MediaFactory<uint32_t, MmdDevice>::
+ Register<MmdDeviceG9Kbl>((uint32_t)IGFX_COFFEELAKE);
+diff --git a/media_driver/media_interface/media_interfaces_m9_glk/media_interfaces_g9_glk.cpp b/media_driver/media_interface/media_interfaces_m9_glk/media_interfaces_g9_glk.cpp
+index de81e6091..2638cb3a6 100644
+--- a/media_driver/media_interface/media_interfaces_m9_glk/media_interfaces_g9_glk.cpp
++++ b/media_driver/media_interface/media_interfaces_m9_glk/media_interfaces_g9_glk.cpp
+@@ -65,7 +65,7 @@ static bool glkRegisteredMhw =
+ MediaFactory<uint32_t, MhwInterfaces>::
+ Register<MhwInterfacesG9Kbl>((uint32_t)IGFX_GEMINILAKE);
+
+-#ifdef _MMC_SUPPORTED
++#if defined(_MMC_SUPPORTED) && defined(ENABLE_KERNELS) && !defined(_FULL_OPEN_SOURCE)
+ static bool glkRegisteredMmd =
+ MediaFactory<uint32_t, MmdDevice>::
+ Register<MmdDeviceG9Kbl>((uint32_t)IGFX_GEMINILAKE);
+diff --git a/media_driver/media_interface/media_interfaces_m9_kbl/media_interfaces_g9_kbl.cpp b/media_driver/media_interface/media_interfaces_m9_kbl/media_interfaces_g9_kbl.cpp
+index 99d786185..4e9c6e7f1 100644
+--- a/media_driver/media_interface/media_interfaces_m9_kbl/media_interfaces_g9_kbl.cpp
++++ b/media_driver/media_interface/media_interfaces_m9_kbl/media_interfaces_g9_kbl.cpp
+@@ -131,7 +131,7 @@ MOS_STATUS MhwInterfacesG9Kbl::Initialize(
+
+ return MOS_STATUS_SUCCESS;
+ }
+-#ifdef _MMC_SUPPORTED
++#if defined(_MMC_SUPPORTED) && defined(ENABLE_KERNELS) && !defined(_FULL_OPEN_SOURCE)
+ static bool kblRegisteredMmd =
+ MediaFactory<uint32_t, MmdDevice>::
+ Register<MmdDeviceG9Kbl>((uint32_t)IGFX_KABYLAKE);
+diff --git a/media_driver/media_interface/media_interfaces_m9_skl/media_interfaces_g9_skl.cpp b/media_driver/media_interface/media_interfaces_m9_skl/media_interfaces_g9_skl.cpp
+index e2520edf7..4b0012c64 100644
+--- a/media_driver/media_interface/media_interfaces_m9_skl/media_interfaces_g9_skl.cpp
++++ b/media_driver/media_interface/media_interfaces_m9_skl/media_interfaces_g9_skl.cpp
+@@ -139,7 +139,7 @@ MOS_STATUS MhwInterfacesG9Skl::Initialize(
+
+ return MOS_STATUS_SUCCESS;
+ }
+-#ifdef _MMC_SUPPORTED
++#if defined(_MMC_SUPPORTED) && defined(ENABLE_KERNELS) && !defined(_FULL_OPEN_SOURCE)
+ static bool sklRegisteredMmd =
+ MediaFactory<uint32_t, MmdDevice>::
+ Register<MmdDeviceG9Skl>((uint32_t)IGFX_SKYLAKE);
+--
+2.40.0
+
diff --git a/srcpkgs/intel-media-driver/patches/execinfo.patch b/srcpkgs/intel-media-driver/patches/execinfo.patch
deleted file mode 100644
index 25d21192d5a1..000000000000
--- a/srcpkgs/intel-media-driver/patches/execinfo.patch
+++ /dev/null
@@ -1,58 +0,0 @@
-From b17354142563b45e0ebf427485591426481368fd Mon Sep 17 00:00:00 2001
-From: Bernd Kuhls <bernd.kuhls@t-online.de>
-Date: Fri, 29 Jul 2022 19:51:39 +0200
-Subject: [PATCH] Fix uClibc build
-
-uClibc does not provide execinfo.h
----
- CMakeLists.txt | 6 ++++++
- .../linux/common/os/osservice/mos_utilities_specific.cpp | 4 ++++
- 2 files changed, 10 insertions(+)
-
-diff --git a/CMakeLists.txt b/CMakeLists.txt
-index 053904748..4a3f0869e 100755
---- a/CMakeLists.txt
-+++ b/CMakeLists.txt
-@@ -53,6 +53,12 @@ option (BUILD_CMRTLIB "Build and Install cmrtlib together with media driver" ON)
-
- option (ENABLE_PRODUCTION_KMD "Enable Production KMD header files" OFF)
-
-+include(CheckIncludeFileCXX)
-+check_include_file_cxx("execinfo.h" HAVE_EXECINFO)
-+if (HAVE_EXECINFO)
-+ add_definitions(-DHAVE_EXECINFO)
-+endif()
-+
- include(GNUInstallDirs)
-
- if (BUILD_CMRTLIB AND NOT CMAKE_WDDM_LINUX)
-diff --git a/media_softlet/linux/common/os/osservice/mos_utilities_specific.cpp b/media_softlet/linux/common/os/osservice/mos_utilities_specific.cpp
-index bde216b83..120b02d55 100644
---- a/media_softlet/linux/common/os/osservice/mos_utilities_specific.cpp
-+++ b/media_softlet/linux/common/os/osservice/mos_utilities_specific.cpp
-@@ -34,7 +34,9 @@
- #include <signal.h>
- #include <unistd.h> // fork
- #include <algorithm>
-+#ifdef HAVE_EXECINFO
- #include <execinfo.h> // backtrace
-+#endif
- #include <sys/types.h>
- #include <sys/stat.h> // fstat
- #include <sys/ipc.h> // System V IPC
-@@ -2473,6 +2475,7 @@ void MosUtilities::MosTraceEvent(
- MOS_FreeMemory(pTraceBuf);
- }
- }
-+#ifdef HAVE_EXECINFO
- if (m_mosTraceFilter & (1ULL << TR_KEY_CALL_STACK))
- {
- // reserve space for header and stack size field.
-@@ -2492,6 +2495,7 @@ void MosUtilities::MosTraceEvent(
- size_t ret = write(MosUtilitiesSpecificNext::m_mosTraceFd, traceBuf, nLen);
- }
- }
-+#endif
- }
- return;
- }
diff --git a/srcpkgs/intel-media-driver/template b/srcpkgs/intel-media-driver/template
index 1ca94569e117..1735b90c65ce 100644
--- a/srcpkgs/intel-media-driver/template
+++ b/srcpkgs/intel-media-driver/template
@@ -1,6 +1,6 @@
# Template file for 'intel-media-driver'
pkgname=intel-media-driver
-version=22.5.3
+version=22.6.4
revision=1
archs="x86_64*"
build_style=cmake
@@ -12,7 +12,7 @@ maintainer="Stefano Ragni <st3r4g@protonmail.com>"
license="MIT, BSD-3-Clause"
homepage="https://github.com/intel/media-driver"
distfiles="https://github.com/intel/media-driver/archive/intel-media-${version}.tar.gz"
-checksum=65652b365d48be3c9f0b3c561502952b92ee5fcc587520b88d0d752cf2a6a3b5
+checksum=0c04b9d74b92de41fd409b62913ce4afd799236c0b6bc1983a496990764e5d90
build_options="nonfree"
desc_option_nonfree="Enable nonfree kernels"
From a926b907c751c2f377a8e5ab0d2a326b5599bb97 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Fri, 16 Dec 2022 09:31:43 -0500
Subject: [PATCH 112/140] New package: onevpl-2023.1.2
---
common/shlibs | 1 +
srcpkgs/onevpl-devel | 1 +
srcpkgs/onevpl/template | 34 ++++++++++++++++++++++++++++++++++
3 files changed, 36 insertions(+)
create mode 120000 srcpkgs/onevpl-devel
create mode 100644 srcpkgs/onevpl/template
diff --git a/common/shlibs b/common/shlibs
index 42744a55b1fc..f1675bacfe8b 100644
--- a/common/shlibs
+++ b/common/shlibs
@@ -879,6 +879,7 @@ libwebp.so.7 libwebp-0.6.0_1
libwebpmux.so.3 libwebp-0.6.0_1
libwebpdemux.so.2 libwebp-0.5.0_1
libwebpdecoder.so.3 libwebp-0.6.0_1
+libvpl.so.2 onevpl-2023.1.2_1
libva-x11.so.2 libva-2.13.0_1
libva.so.2 libva-2.13.0_1
libva-glx.so.2 libva-glx-2.13.0_1
diff --git a/srcpkgs/onevpl-devel b/srcpkgs/onevpl-devel
new file mode 120000
index 000000000000..e2306500b487
--- /dev/null
+++ b/srcpkgs/onevpl-devel
@@ -0,0 +1 @@
+onevpl
\ No newline at end of file
diff --git a/srcpkgs/onevpl/template b/srcpkgs/onevpl/template
new file mode 100644
index 000000000000..85c7c2da85ce
--- /dev/null
+++ b/srcpkgs/onevpl/template
@@ -0,0 +1,34 @@
+# Template file for 'onevpl'
+pkgname=onevpl
+version=2023.1.2
+revision=1
+archs="x86_64*"
+build_style=cmake
+configure_args="
+ -DCMAKE_BUILD_TYPE=Release -Wno-dev
+ -DBUILD_PYTHON_BINDING:BOOL='OFF'
+ -DBUILD_EXAMPLES:BOOL='OFF'
+ -DBUILD_TESTS:BOOL='ON'
+ -DINSTALL_EXAMPLE_CODE:BOOL='OFF'"
+hostmakedepends="cmake libX11 python wayland-protocols pkg-config"
+makedepends="libva-devel libX11-devel wayland-devel"
+short_desc="Intel oneAPI Video Processing library"
+maintainer="zlice <zlice555@gmail.com>"
+license="MIT"
+homepage="https://www.intel.com/content/www/us/en/developer/tools/oneapi/onevpl.html"
+distfiles="https://github.com/oneapi-src/oneVPL/archive/v${version}/${pkgname}-${version}.tar.gz"
+checksum=b2261cca174ce1815f3d47c647921ab17f68267c69c1e2444ff27aab7d199cbb
+
+post_install() {
+ vlicense LICENSE
+}
+
+onevpl-devel_package() {
+ depends="${makedepends} ${sourcepkg}-${version}_${revision}"
+ short_desc+=" - development files"
+ pkg_install() {
+ vmove usr/include
+ vmove usr/lib/pkgconfig
+ vmove "usr/lib/*.so"
+ }
+}
From 4f4223a028a8bf07168ed56e336d44ca1c76974d Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Fri, 16 Dec 2022 15:27:04 -0500
Subject: [PATCH 113/140] New package: onevpl-intel-gpu-22.6.4
---
srcpkgs/onevpl-intel-gpu-devel | 1 +
srcpkgs/onevpl-intel-gpu/template | 27 +++++++++++++++++++++++++++
2 files changed, 28 insertions(+)
create mode 120000 srcpkgs/onevpl-intel-gpu-devel
create mode 100644 srcpkgs/onevpl-intel-gpu/template
diff --git a/srcpkgs/onevpl-intel-gpu-devel b/srcpkgs/onevpl-intel-gpu-devel
new file mode 120000
index 000000000000..47920ceecf91
--- /dev/null
+++ b/srcpkgs/onevpl-intel-gpu-devel
@@ -0,0 +1 @@
+onevpl-intel-gpu
\ No newline at end of file
diff --git a/srcpkgs/onevpl-intel-gpu/template b/srcpkgs/onevpl-intel-gpu/template
new file mode 100644
index 000000000000..f14acb728a54
--- /dev/null
+++ b/srcpkgs/onevpl-intel-gpu/template
@@ -0,0 +1,27 @@
+# Template file for 'onevpl-intel-gpu'
+pkgname=onevpl-intel-gpu
+version=22.6.4
+revision=1
+archs="x86_64*"
+build_style=cmake
+configure_args="-Wno-dev -DCMAKE_BUILD_TYPE=Release"
+hostmakedepends="cmake pkg-config"
+makedepends="libdrm-devel libva-devel onevpl-devel"
+short_desc="Runtime implementation of oneVPL API for Intel Gen GPUs"
+maintainer="zlice <zlice555@gmail.com>"
+license="MIT"
+homepage="https://github.com/oneapi-src/oneVPL-intel-gpu"
+changelog="https://github.com/oneapi-src/oneVPL-intel-gpu/blob/main/CHANGELOG.md"
+distfiles="https://github.com/oneapi-src/oneVPL-intel-gpu/archive/refs/tags/intel-onevpl-${version}.tar.gz"
+checksum=74b0979dcb2af1b7c68edb8cbcb02d539de511090b12fac50652cbacd707c4e6
+
+post_install() {
+ vlicense LICENSE
+}
+
+onevpl-intel-gpu-devel_package() {
+ short_desc+=" - development files"
+ pkg_install() {
+ vmove usr/lib/pkgconfig
+ }
+}
From dff0b2e32e0009d234c97ec23c1746bfa0d7c893 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Sun, 18 Dec 2022 01:40:15 -0500
Subject: [PATCH 114/140] igt-gpu-tools: update to version 1.27 revbump idk
remove
---
...-loading-failure-in-resolve-function.patch | 63 -------------------
srcpkgs/igt-gpu-tools/patches/musl.patch | 20 ++++++
srcpkgs/igt-gpu-tools/template | 4 +-
3 files changed, 22 insertions(+), 65 deletions(-)
delete mode 100644 srcpkgs/igt-gpu-tools/patches/i-g-t-Fix-global-symbol-loading-failure-in-resolve-function.patch
diff --git a/srcpkgs/igt-gpu-tools/patches/i-g-t-Fix-global-symbol-loading-failure-in-resolve-function.patch b/srcpkgs/igt-gpu-tools/patches/i-g-t-Fix-global-symbol-loading-failure-in-resolve-function.patch
deleted file mode 100644
index 0c3b554d9949..000000000000
--- a/srcpkgs/igt-gpu-tools/patches/i-g-t-Fix-global-symbol-loading-failure-in-resolve-function.patch
+++ /dev/null
@@ -1,63 +0,0 @@
-diff --git lib/igt_halffloat.c lib/igt_halffloat.c
-index 08ab05fc..e5e8a5bd 100644
---- a/lib/igt_halffloat.c
-+++ b/lib/igt_halffloat.c
-@@ -24,6 +24,19 @@
-
- #include <assert.h>
- #include <math.h>
-+#include <stdbool.h>
-+
-+#ifdef HAVE_CPUID_H
-+#include <cpuid.h>
-+#else
-+#define __get_cpuid_max(x, y) 0
-+#define __cpuid(level, a, b, c, d) a = b = c = d = 0
-+#define __cpuid_count(level, count, a, b, c, d) a = b = c = d = 0
-+#endif
-+
-+#ifndef bit_F16C
-+#define bit_F16C (1 << 29)
-+#endif
-
- #include "igt_halffloat.h"
- #include "igt_x86.h"
-@@ -182,6 +195,20 @@ static void half_to_float_f16c(const uint16_t *h, float *f, unsigned int num)
-
- #pragma GCC pop_options
-
-+static bool f16c_is_supported(void)
-+{
-+ unsigned max = __get_cpuid_max(0, NULL);
-+ unsigned eax, ebx, ecx, edx;
-+
-+ if (max >= 1) {
-+ __cpuid(1, eax, ebx, ecx, edx);
-+
-+ if (ecx & bit_F16C)
-+ return true;
-+ }
-+ return false;
-+}
-+
- static void float_to_half(const float *f, uint16_t *h, unsigned int num)
- {
- for (int i = 0; i < num; i++)
-@@ -196,7 +223,7 @@ static void half_to_float(const uint16_t *h, float *f, unsigned int num)
-
- static void (*resolve_float_to_half(void))(const float *f, uint16_t *h, unsigned int num)
- {
-- if (igt_x86_features() & F16C)
-+ if (f16c_is_supported())
- return float_to_half_f16c;
-
- return float_to_half;
-@@ -207,7 +234,7 @@ void igt_float_to_half(const float *f, uint16_t *h, unsigned int num)
-
- static void (*resolve_half_to_float(void))(const uint16_t *h, float *f, unsigned int num)
- {
-- if (igt_x86_features() & F16C)
-+ if (f16c_is_supported())
- return half_to_float_f16c;
-
- return half_to_float;
diff --git a/srcpkgs/igt-gpu-tools/patches/musl.patch b/srcpkgs/igt-gpu-tools/patches/musl.patch
index 615afdb8f8ea..4de6e0cfd898 100644
--- a/srcpkgs/igt-gpu-tools/patches/musl.patch
+++ b/srcpkgs/igt-gpu-tools/patches/musl.patch
@@ -191,6 +191,7 @@ index 74935430..0dc87d8c 100644
+++ b/tests/i915/i915_pm_rpm.c
@@ -27,6 +27,7 @@
+<<<<<<< HEAD
#include "config.h"
+#include <limits.h> // PATH_MAX
@@ -293,3 +294,22 @@ index 0faf3fc8..f6bd970e 100644
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
+=======
+ fbo = bo->map;
+lib/ioctl_wrappers.c.new
+--- a/benchmarks/gem_exec_tracer.c 2022-12-18 10:32:15.742341964 -0500
++++ b/benchmarks/gem_exec_tracer.c 2022-12-18 10:32:09.862211372 -0500
+@@ -275,7 +275,11 @@
+ DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_GEM_EXECBUFFER2, struct drm_i915_gem_execbuffer2)
+
+ int
++#if defined(__GLIBC__) || defined(__FreeBSD__)
+ ioctl(int fd, unsigned long request, ...)
++#else
++ioctl(int fd, int request, ...)
++#endif
+ {
+ struct trace *t, **p;
+ va_list args;
+
+>>>>>>> 60301ae02f (igt-gpu-tools: update to version 1.26)
diff --git a/srcpkgs/igt-gpu-tools/template b/srcpkgs/igt-gpu-tools/template
index 225e2c79118a..1376c39d5d5b 100644
--- a/srcpkgs/igt-gpu-tools/template
+++ b/srcpkgs/igt-gpu-tools/template
@@ -1,7 +1,7 @@
# Template file for 'igt-gpu-tools'
pkgname=igt-gpu-tools
version=1.27.1
-revision=1
+revision=2
build_style=meson
configure_args="-Db_ndebug=false -Ddocs=disabled"
hostmakedepends="pkg-config flex peg python3-docutils"
@@ -13,7 +13,7 @@ maintainer="Orphaned <orphan@voidlinux.org>"
license="MIT"
homepage="https://gitlab.freedesktop.org/drm/igt-gpu-tools"
changelog="https://gitlab.freedesktop.org/drm/igt-gpu-tools/-/raw/master/NEWS"
-distfiles="${XORG_SITE}/app/igt-gpu-tools-${version}.tar.xz"
+distfiles="${XORG_SITE}/app/${pkgname}-${version}.tar.xz"
checksum=93b9a4816ed22b5145bb61024314c8a65caeea991ce93027643f1d40723bf417
# tests don't behave in containers
make_check=ci-skip
From 2c2bbb3c048d7bb1e2ca260cda3c5157ca280e39 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Mon, 3 Apr 2023 23:30:28 -0400
Subject: [PATCH 115/140] freecad: revbump for qt5-webengine-5.15.13
---
srcpkgs/freecad/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/freecad/template b/srcpkgs/freecad/template
index f62023ee8ce4..e301f32d3540 100644
--- a/srcpkgs/freecad/template
+++ b/srcpkgs/freecad/template
@@ -1,7 +1,7 @@
# Template file for 'freecad'
pkgname=freecad
version=0.20.2
-revision=3
+revision=4
build_style=cmake
_inst_prefix=/usr/lib/${pkgname}
From 2bd9f40dec77c0ba7b9444e116a063fb91985f89 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Mon, 3 Apr 2023 23:31:45 -0400
Subject: [PATCH 116/140] shotcut: revbump for mlt7-7.14.0
---
srcpkgs/shotcut/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/shotcut/template b/srcpkgs/shotcut/template
index 32583277dab2..8d8a7a0ebdeb 100644
--- a/srcpkgs/shotcut/template
+++ b/srcpkgs/shotcut/template
@@ -1,7 +1,7 @@
# Template file for 'shotcut'
pkgname=shotcut
version=22.12.21
-revision=1
+revision=2
build_style=cmake
configure_args="-DSHOTCUT_VERSION=${version}"
hostmakedepends="pkg-config qt5-tools-devel"
From 3eed630d5259d8b3a12ad23f11835b4d9a93c9c9 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Mon, 3 Apr 2023 23:33:30 -0400
Subject: [PATCH 117/140] shiboken2: revbump for qt5-5.15.8
---
srcpkgs/shiboken2/patches/importlib-machinery-bypass.patch | 1 +
srcpkgs/shiboken2/template | 2 +-
2 files changed, 2 insertions(+), 1 deletion(-)
create mode 120000 srcpkgs/shiboken2/patches/importlib-machinery-bypass.patch
diff --git a/srcpkgs/shiboken2/patches/importlib-machinery-bypass.patch b/srcpkgs/shiboken2/patches/importlib-machinery-bypass.patch
new file mode 120000
index 000000000000..efcf3249bd88
--- /dev/null
+++ b/srcpkgs/shiboken2/patches/importlib-machinery-bypass.patch
@@ -0,0 +1 @@
+../../python3-pyside2/patches/importlib-machinery-bypass.patch
\ No newline at end of file
diff --git a/srcpkgs/shiboken2/template b/srcpkgs/shiboken2/template
index 084ecc3ba1e1..2a21998997eb 100644
--- a/srcpkgs/shiboken2/template
+++ b/srcpkgs/shiboken2/template
@@ -1,7 +1,7 @@
# Template file for 'shiboken2'
pkgname=shiboken2
version=5.15.7
-revision=1
+revision=2
_pkgname="pyside-setup-opensource-src-${version}"
build_wrksrc="sources/shiboken2"
build_style=cmake
From 2f77e3b7f56f7a56b451c4adda302eb53776308f Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Mon, 3 Apr 2023 23:33:53 -0400
Subject: [PATCH 118/140] python3-pyside2: update to 5.15.8
---
.../patches/importlib-machinery-bypass.patch | 15 +++++++++++++++
srcpkgs/python3-pyside2/template | 9 +++++----
2 files changed, 20 insertions(+), 4 deletions(-)
create mode 100644 srcpkgs/python3-pyside2/patches/importlib-machinery-bypass.patch
diff --git a/srcpkgs/python3-pyside2/patches/importlib-machinery-bypass.patch b/srcpkgs/python3-pyside2/patches/importlib-machinery-bypass.patch
new file mode 100644
index 000000000000..64c429584776
--- /dev/null
+++ b/srcpkgs/python3-pyside2/patches/importlib-machinery-bypass.patch
@@ -0,0 +1,15 @@
+Using this prevents an error around line 220 below it.
+"AttributeError: module 'importlib' has no attribute 'machinery'"
+The old backup logic is in place and compiles without issues.
+--- a/sources/shiboken2/libshiboken/embed/signature_bootstrap.py 2023-04-02 23:09:34.688912402 -0400
++++ b/sources/shiboken2/libshiboken/embed/signature_bootstrap.py 2023-04-02 23:10:03.395529582 -0400
+@@ -170,9 +170,6 @@
+
+ # 'zipstring_sequence' comes from signature.cpp
+ zipbytes = base64.b64decode(''.join(zipstring_sequence))
+- if sys.version_info[0] >= 3:
+- vzip = zipfile.ZipFile(io.BytesIO(zipbytes))
+- return sys.meta_path, EmbeddableZipImporter(vzip)
+
+ # Old version for Python 2.7, only.
+ import os
diff --git a/srcpkgs/python3-pyside2/template b/srcpkgs/python3-pyside2/template
index 50e6ff260d3b..b50e62bd215d 100644
--- a/srcpkgs/python3-pyside2/template
+++ b/srcpkgs/python3-pyside2/template
@@ -1,11 +1,12 @@
# Template file for 'python3-pyside2'
pkgname=python3-pyside2
-version=5.15.5
-revision=2
+version=5.15.8
+revision=1
_pkgname="pyside-setup-opensource-src-${version}"
build_wrksrc="sources/pyside2"
build_style=cmake
-configure_args="-DPYTHON_EXECUTABLE=/usr/bin/python"
+configure_args="-DPYTHON_EXECUTABLE=/usr/bin/python -DCMAKE_BUILD_TYPE=None
+ -DBUILD_TESTS=OFF"
hostmakedepends="cmake python3 shiboken2"
makedepends="python3-devel libshiboken2-devel qt5-devel
qt5-multimedia-devel qt5-tools-devel qt5-plugin-mysql qt5-plugin-odbc
@@ -23,7 +24,7 @@ maintainer="yopito <pierre.bourgin@free.fr>"
license="LGPL-3.0-or-later"
homepage="https://wiki.qt.io/Qt_for_Python"
distfiles="https://download.qt.io/official_releases/QtForPython/pyside2/PySide2-${version}-src/${_pkgname}.tar.xz"
-checksum=3920a4fb353300260c9bc46ff70f1fb975c5e7efa22e9d51222588928ce19b33
+checksum=23436302c8deb5b4cbc769b205d09604e38ba83b40708efccb7bd8c9af6f6b5d
build_options="webengine"
desc_option_webengine="Build Qt5 WebEngine bindings"
From 5db97d4908ebb421d36aeaacf8363326ea4aff84 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Tue, 4 Apr 2023 11:14:35 -0400
Subject: [PATCH 119/140] konqueror: revbump for ffmpeg-6.0
---
srcpkgs/konqueror/template | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/srcpkgs/konqueror/template b/srcpkgs/konqueror/template
index d8d0e73a78ab..c5bdba601d3c 100644
--- a/srcpkgs/konqueror/template
+++ b/srcpkgs/konqueror/template
@@ -1,11 +1,11 @@
# Template file for 'konqueror'
pkgname=konqueror
version=23.04.0
-revision=1
+revision=2
build_style=cmake
configure_args="-DDESKTOPTOJSON_EXECUTABLE=/usr/bin/desktoptojson"
hostmakedepends="extra-cmake-modules python3 qt5-host-tools qt5-qmake kdoctools
-kcoreaddons kconfig gettext"
+ kcoreaddons kconfig gettext"
makedepends="qt5-devel qt5-webengine-devel qt5-declarative-devel
qt5-webchannel-devel qt5-location-devel kcmutils-devel kdelibs4support-devel
karchive-devel khtml-devel kdesu-devel kactivities5-devel"
From 4bc29eab751cd1209cab63f8c9621d5f16ca0a25 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Tue, 4 Apr 2023 11:14:58 -0400
Subject: [PATCH 120/140] qt5-speech: revbump for qt5-5.15.8
---
srcpkgs/qt5-speech/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/qt5-speech/template b/srcpkgs/qt5-speech/template
index 3ecd10d50650..2d7d4d4d2453 100644
--- a/srcpkgs/qt5-speech/template
+++ b/srcpkgs/qt5-speech/template
@@ -1,7 +1,7 @@
# Template file for 'qt5-speech'
pkgname=qt5-speech
version=5.15.7
-revision=2
+revision=3
_commit=d32f4a479d38a11f547598004b975f4356424a16
build_style=qmake
configure_args="-- -flite -flite-alsa -speechd"
From ad7e46e354c4f6db0dca5fd8104c4138bf5dbb3a Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Tue, 4 Apr 2023 18:38:50 -0400
Subject: [PATCH 121/140] qt5_styleplugins: revbump for qt5-5.15.8
---
srcpkgs/qt5-styleplugins/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/qt5-styleplugins/template b/srcpkgs/qt5-styleplugins/template
index 96ed97d12cd2..30d93660a2a4 100644
--- a/srcpkgs/qt5-styleplugins/template
+++ b/srcpkgs/qt5-styleplugins/template
@@ -1,7 +1,7 @@
# Template file for 'qt5-styleplugins'
pkgname=qt5-styleplugins
version=5.0.0
-revision=20
+revision=21
_gitrev=335dbece103e2cbf6c7cf819ab6672c2956b17b3
build_style=qmake
hostmakedepends="pkg-config qt5-host-tools qt5-qmake"
From 5f2a93b834e886c0abb6b9b903c9b2cf988770b7 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Thu, 27 Apr 2023 21:58:35 -0400
Subject: [PATCH 122/140] blender: update to 3.5.1
---
srcpkgs/blender/patches/numpy-2.24.patch | 22 ----------------------
srcpkgs/blender/template | 13 +++++++------
2 files changed, 7 insertions(+), 28 deletions(-)
delete mode 100644 srcpkgs/blender/patches/numpy-2.24.patch
diff --git a/srcpkgs/blender/patches/numpy-2.24.patch b/srcpkgs/blender/patches/numpy-2.24.patch
deleted file mode 100644
index 716315b74be7..000000000000
--- a/srcpkgs/blender/patches/numpy-2.24.patch
+++ /dev/null
@@ -1,22 +0,0 @@
-From 74e6e07cf7c67b55d384db72f5aa3892db8a3da6 Mon Sep 17 00:00:00 2001
-From: oreo639 <oreo6391@gmail.com>
-Date: Tue, 17 Jan 2023 14:36:54 -0800
-Subject: [PATCH] Remove usage of deprecated np.bool alias
-
----
- addons/io_scene_gltf2/blender/imp/gltf2_blender_mesh.py | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-diff --git a/addons/io_scene_gltf2/blender/imp/gltf2_blender_mesh.py b/addons/io_scene_gltf2/blender/imp/gltf2_blender_mesh.py
-index 6366434a6..8160c9e99 100644
---- a/release/scripts/addons/io_scene_gltf2/blender/imp/gltf2_blender_mesh.py
-+++ b/release/scripts/addons/io_scene_gltf2/blender/imp/gltf2_blender_mesh.py
-@@ -620,7 +620,7 @@ def set_poly_smoothing(gltf, pymesh, mesh, vert_normals, loop_vidxs):
- # Try to guess which polys should be flat based on the fact that all the
- # loop normals for a flat poly are = the poly's normal.
-
-- poly_smooths = np.empty(num_polys, dtype=np.bool)
-+ poly_smooths = np.empty(num_polys, dtype=bool)
-
- poly_normals = np.empty(num_polys * 3, dtype=np.float32)
- mesh.polygons.foreach_get('normal', poly_normals)
diff --git a/srcpkgs/blender/template b/srcpkgs/blender/template
index d18bc88838ff..900bc17937c3 100644
--- a/srcpkgs/blender/template
+++ b/srcpkgs/blender/template
@@ -1,7 +1,7 @@
# Template file for 'blender'
pkgname=blender
-version=3.4.1
-revision=4
+version=3.5.1
+revision=1
archs="x86_64* ppc64*"
build_style="cmake"
pycompile_dirs="/usr/share/blender/${version%.*}/scripts"
@@ -9,8 +9,8 @@ configure_args="-DWITH_INSTALL_PORTABLE=OFF -DWITH_PYTHON_INSTALL=OFF
-DWITH_JACK=ON -DWITH_CODEC_FFMPEG=ON -DWITH_CODEC_SNDFILE=ON -DWITH_OPENMP=ON
-DWITH_FFTW3=ON -DWITH_MOD_OCEANSIM=ON -DWITH_CYCLES_EMBREE=OFF -DWITH_OPENCOLORIO=ON
-DWITH_IMAGE_OPENEXR=ON -DWITH_IMAGE_OPENJPEG=ON -DWITH_OPENSUBDIV=ON
- -DWITH_OPENCOLLADA=ON -DWITH_SYSTEM_GLEW=ON -DWITH_OPENVDB=ON -DWITH_ALEMBIC=ON
- -DWITH_GHOST_X11=ON -DWITH_GHOST_WAYLAND=ON -DWITH_GHOST_LIBDECOR=ON
+ -DWITH_OPENCOLLADA=ON -DWITH_OPENVDB=ON -DWITH_ALEMBIC=ON
+ -DWITH_GHOST_X11=ON -DWITH_GHOST_WAYLAND=ON -DWITH_GHOST_WAYLAND_LIBDECOR=ON
-DWITH_BUILDINFO=OFF -DPYTHON_VERSION=${py3_ver} -DPYTHON_LIBPATH=/usr/lib
-DPYTHON_LIBRARY='python${py3_ver}${py3_abiver}'
-DPYTHON_INCLUDE_DIRS=/${py3_inc}"
@@ -22,14 +22,15 @@ makedepends="libgomp-devel libpng-devel tiff-devel python3-devel glu-devel
opencolorio-devel opencollada-devel python3-numpy libXrender-devel
OpenSubdiv-devel tbb-devel libxml2-devel openvdb-devel alembic-devel
pugixml-devel libXxf86vm-devel libepoxy-devel gmp-devel gmpxx-devel
- wayland-protocols wayland-devel libxkbcommon-devel libdecor-devel"
+ wayland-protocols wayland-devel libxkbcommon-devel libdecor-devel
+ level-zero-devel"
depends="desktop-file-utils hicolor-icon-theme"
short_desc="3D graphics creation suite"
maintainer="Enno Boland <gottox@voidlinux.org>"
license="GPL-3.0-or-later"
homepage="https://www.blender.org"
distfiles="https://download.blender.org/source/blender-${version}.tar.xz"
-checksum=247c4c1228270c9010f4721c985cb5b628ab50abcf9f2678630737142eeb91c3
+checksum=bd7428c7e6cba5a900216269c32111dffaabaf1bdb5472f231965e615174a809
python_version=3
LDFLAGS="-Wl,-z,stack-size=2097152"
# Blender tests are executed against a system installation of blender. This
From 3e3c48aee8f35f41a582362881c9eea1be7355f3 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Thu, 27 Apr 2023 20:41:10 -0400
Subject: [PATCH 123/140] New package: level-zero-1.10.0
---
srcpkgs/level-zero-devel | 1 +
srcpkgs/level-zero/template | 28 ++++++++++++++++++++++++++++
2 files changed, 29 insertions(+)
create mode 120000 srcpkgs/level-zero-devel
create mode 100644 srcpkgs/level-zero/template
diff --git a/srcpkgs/level-zero-devel b/srcpkgs/level-zero-devel
new file mode 120000
index 000000000000..96ee8adf7303
--- /dev/null
+++ b/srcpkgs/level-zero-devel
@@ -0,0 +1 @@
+level-zero
\ No newline at end of file
diff --git a/srcpkgs/level-zero/template b/srcpkgs/level-zero/template
new file mode 100644
index 000000000000..4631c8c67505
--- /dev/null
+++ b/srcpkgs/level-zero/template
@@ -0,0 +1,28 @@
+# Template file for 'level-zero'
+pkgname=level-zero
+version=1.10.0
+revision=1
+archs="x86_64*"
+build_style=cmake
+hostmakedepends="cmake"
+makedepends="llvm clang clang-tools-extra SPIRV-LLVM-Translator-devel"
+short_desc="oneAPI Level Zero Specification"
+maintainer="Zlice <zlice555@gmail.com>"
+license="NCSA"
+homepage="https://github.com/oneapi-src/level-zero"
+distfiles="${homepage}/archive/refs/tags/v${version}.tar.gz"
+checksum=2811e4128ff6114020d0a147c2769b9b2e782e68ad49827685c33b9e716bf6ab
+
+post_install() {
+ vlicense LICENSE
+}
+
+level-zero-devel_package() {
+ depends="${makedepends} ${sourcepkg}-${version}_${revision}"
+ short_desc+=" - development files"
+ pkg_install() {
+ vmove usr/include
+ vmove usr/lib/pkgconfig
+ vmove "usr/lib/*.so"
+ }
+}
From cd065f6f42d3251e2e56b3b84ad601d6f20de263 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Tue, 28 Mar 2023 19:54:49 -0400
Subject: [PATCH 124/140] New package: intel-metrics-library 1.0.133
---
srcpkgs/intel-metrics-library/template | 19 +++++++++++++++++++
1 file changed, 19 insertions(+)
create mode 100644 srcpkgs/intel-metrics-library/template
diff --git a/srcpkgs/intel-metrics-library/template b/srcpkgs/intel-metrics-library/template
new file mode 100644
index 000000000000..50f1a6079d7b
--- /dev/null
+++ b/srcpkgs/intel-metrics-library/template
@@ -0,0 +1,19 @@
+# Template file for 'intel-metrics-library'
+pkgname=intel-metrics-library
+version=1.0.133
+revision=1
+archs="x86_64*"
+build_style=cmake
+configure_args="-Wdev-no -DCMAKE_BUILD_TYPE=Release"
+hostmakedepends="cmake"
+makedepends="libdrm-devel"
+short_desc="Helper library that provides access to GPU performance counters"
+maintainer="Zlice <zlice555@gmail.com>"
+license="MIT"
+homepage="https://github.com/intel/metrics-library"
+distfiles="${homepage}/archive/refs/tags/metrics-library-${version}.tar.gz"
+checksum=83f7b2de3af5ffd2f1b487df8836e6d212e11668bd958bebae622a483fb1231f
+
+post_install() {
+ vlicense LICENSE.md
+}
From 0f23b9cb3a79a851b40412710dcc01a9525c41c0 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Tue, 28 Mar 2023 19:54:18 -0400
Subject: [PATCH 125/140] New package: intel-metrics-discovery 1.12.163
---
srcpkgs/intel-metrics-discovery/template | 19 +++++++++++++++++++
1 file changed, 19 insertions(+)
create mode 100644 srcpkgs/intel-metrics-discovery/template
diff --git a/srcpkgs/intel-metrics-discovery/template b/srcpkgs/intel-metrics-discovery/template
new file mode 100644
index 000000000000..6083595e273c
--- /dev/null
+++ b/srcpkgs/intel-metrics-discovery/template
@@ -0,0 +1,19 @@
+# Template file for 'intel-metrics-discovery'
+pkgname=intel-metrics-discovery
+version=1.12.163
+revision=1
+archs="x86_64*"
+build_style=cmake
+configure_args="-Wdev-no -DCMAKE_BUILD_TYPE=Release"
+hostmakedepends="cmake"
+makedepends="libdrm-devel"
+short_desc="Helper library that provides access to GPU performance data"
+maintainer="Zlice <zlice555@gmail.com>"
+license="MIT"
+homepage="https://github.com/intel/metrics-discovery"
+distfiles="${homepage}/archive/refs/tags/metrics-discovery-${version}.tar.gz"
+checksum=6dfe8d11c58625bf3ebf656ec2a95dc96bbb05705ec71c6c3c3dd0ef5cd2319c
+
+post_install() {
+ vlicense LICENSE.md
+}
From 3727c79cb0e858a389626ca599bea657f8cfbcd1 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Sun, 26 Mar 2023 10:48:34 -0400
Subject: [PATCH 126/140] New package: intel-graphics-compiler-1.0.13463.18
---
srcpkgs/intel-graphics-compiler/template | 22 ++++++++++++++++++++++
1 file changed, 22 insertions(+)
create mode 100644 srcpkgs/intel-graphics-compiler/template
diff --git a/srcpkgs/intel-graphics-compiler/template b/srcpkgs/intel-graphics-compiler/template
new file mode 100644
index 000000000000..44d38214f929
--- /dev/null
+++ b/srcpkgs/intel-graphics-compiler/template
@@ -0,0 +1,22 @@
+# Template file for 'intel-graphics-compiler'
+pkgname=intel-graphics-compiler
+version=1.0.13463.18
+revision=1
+archs="x86_64*"
+build_style=cmake
+configure_args="-Wno-dev -DIGC_OPTION__LLVM_PREFERRED_VERSION=15.0.7 -DCCLANG_FROM_SYSTEM=ON
+ -DIGC_OPTION__SPIRV_TOOLS_MODE=Prebuilds -DIGC_OPTION__USE_PREINSTALLED_SPRIV_HEADERS=ON
+ -DIGC_OPTION__VC_INTRINSICS_MODE=Prebuilds"
+hostmakedepends="flex bison zlib-devel libzstd-devel cmake"
+makedepends="llvm clang clang-tools-extra intel-opencl-clang intel-vc-intrinsics
+ lld lld-devel SPIRV-Headers SPIRV-LLVM-Translator-devel SPIRV-Tools-devel"
+short_desc="LLVM based compiler for OpenCL targeting Intel"
+maintainer="Zlice <zlice555@gmail.com>"
+license="MIT"
+homepage="https://github.com/intel/intel-graphics-compiler"
+distfiles="${homepage}/archive/refs/tags/igc-${version}.tar.gz"
+checksum=0b960878a5feffd6aa10197c48bf73a0a3a19d0105428d48163e91db0444070a
+
+post_install() {
+ vlicense LICENSE.md
+}
From c697b135df60a4bba1d41f5ad63d28d0cbc078a2 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Sun, 26 Mar 2023 10:48:05 -0400
Subject: [PATCH 127/140] New package: intel-compute-runtime-23.09.25812.14
---
srcpkgs/intel-compute-runtime/template | 22 ++++++++++++++++++++++
1 file changed, 22 insertions(+)
create mode 100644 srcpkgs/intel-compute-runtime/template
diff --git a/srcpkgs/intel-compute-runtime/template b/srcpkgs/intel-compute-runtime/template
new file mode 100644
index 000000000000..1132b830d348
--- /dev/null
+++ b/srcpkgs/intel-compute-runtime/template
@@ -0,0 +1,22 @@
+# Template file for 'intel-compute-runtime'
+pkgname=intel-compute-runtime
+version=23.09.25812.14
+revision=1
+archs="x86_64"
+build_style=cmake
+configure_args="-Wno-dev -DNEO_SKIP_UNIT_TESTS=1 -DSUPPORT_DG1=ON -DSUPPORT_DG2=ON"
+hostmakedepends="cmake pkg-config"
+makedepends="gcc intel-gmmlib-devel libva-devel ocl-icd-devel
+ intel-opencl-clang intel-graphics-compiler level-zero-devel
+ intel-metrics-library intel-metrics-discovery"
+depends="intel-graphics-compiler"
+short_desc="Intel Graphics Compute Runtime for oneAPI Level Zero and OpenCL"
+maintainer="Zlice <zlice555@gmail.com>"
+license="MIT"
+homepage="https://github.com/intel/compute-runtime"
+distfiles="${homepage}/archive/refs/tags/${version}.tar.gz"
+checksum=abe2e6d9d2ac771d5f42ee2357ce897ca3b00dc6185c06f3f62772f729c7f8e1
+
+post_install() {
+ vlicense LICENSE.md
+}
From dd9aaf4b83d14b721956071b8134f9dd1fca7b68 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Sun, 26 Mar 2023 10:46:58 -0400
Subject: [PATCH 128/140] New package: intel-vc-intrinsics-0.12.3
---
srcpkgs/intel-vc-intrinsics/template | 21 +++++++++++++++++++++
1 file changed, 21 insertions(+)
create mode 100644 srcpkgs/intel-vc-intrinsics/template
diff --git a/srcpkgs/intel-vc-intrinsics/template b/srcpkgs/intel-vc-intrinsics/template
new file mode 100644
index 000000000000..129482bdf985
--- /dev/null
+++ b/srcpkgs/intel-vc-intrinsics/template
@@ -0,0 +1,21 @@
+# Template file for 'intel-vc-intrinsics'
+pkgname=intel-vc-intrinsics
+version=0.12.3
+revision=1
+archs="x86_64*"
+build_style=cmake
+configure_args="-Wno-dev -DLLVM_DIR=/usr/lib/cmake/llvm -DCMAKE_BUILD_TYPE=Release"
+hostmakedepends="cmake python"
+makedepends="llvm clang clang-tools-extra"
+short_desc="Set of intrinsics on top of core LLVM IR"
+maintainer="Zlice <zlice555@gmail.com>"
+license="MIT"
+homepage="https://github.com/intel/vc-intrinsics"
+distfiles="${homepage}/archive/refs/tags/v${version}.tar.gz"
+checksum=ed1c0d968cb2f8ee7b2840a14c3261639f1700e844fb7d2a89856babffd5e1d1
+
+# TODO: license isn't bundled in tar?
+# just added 2 days ago... mar 24th 2023
+#post_install() {
+# vlicense LICENSE.md
+#}
From b7df15baf1bcf650ccd41e3d069995f6d53939c2 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Sun, 26 Mar 2023 10:46:11 -0400
Subject: [PATCH 129/140] New package: intel-opencl-clang-15.0.0
---
common/shlibs | 1 +
srcpkgs/intel-opencl-clang/template | 18 ++++++++++++++++++
2 files changed, 19 insertions(+)
create mode 100644 srcpkgs/intel-opencl-clang/template
diff --git a/common/shlibs b/common/shlibs
index f1675bacfe8b..f2d1be3d8514 100644
--- a/common/shlibs
+++ b/common/shlibs
@@ -1008,6 +1008,7 @@ libLLVM-15.so libllvm15-15.0.7_1
libLLVMSPIRVLib.so.15 SPIRV-LLVM-Translator-15.0.0_1
libomp.so.5 libomp-15.0.7_1
libomptarget.so.15 libomp-15.0.7_1
+libopencl-clang.so.15 intel-opencl-clang-15.0.0_1
libisofs.so.6 libisofs-0.6.24_1
libmpack.so.0 libmpack-1.0.5_1
libGeoIP.so.1 libgeoip-1.4.8_1
diff --git a/srcpkgs/intel-opencl-clang/template b/srcpkgs/intel-opencl-clang/template
new file mode 100644
index 000000000000..e6f09f6ad724
--- /dev/null
+++ b/srcpkgs/intel-opencl-clang/template
@@ -0,0 +1,18 @@
+# Template file for 'intel-opencl-clang'
+pkgname=intel-opencl-clang
+version=15.0.0
+revision=1
+archs="x86_64*"
+build_style=cmake
+hostmakedepends="cmake"
+makedepends="llvm clang clang-tools-extra SPIRV-LLVM-Translator-devel"
+short_desc="LLVM linked opencl-clang"
+maintainer="Zlice <zlice555@gmail.com>"
+license="NCSA"
+homepage="https://github.com/intel/opencl-clang"
+distfiles="${homepage}/archive/refs/tags/v${version}.tar.gz"
+checksum=ea179674e52bc8c658e2655f76be467f7052f7d2c37ebcfdb102dce645ad1411
+
+post_install() {
+ vlicense LICENSE
+}
From 5612d4e634f39abf6cc187e27c5db5a3b27efefb Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Sun, 30 Apr 2023 20:22:25 -0400
Subject: [PATCH 130/140] gstreamer1: update to 1.22.2
---
srcpkgs/gstreamer1/template | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/srcpkgs/gstreamer1/template b/srcpkgs/gstreamer1/template
index 362fe82faec3..571148f2ff33 100644
--- a/srcpkgs/gstreamer1/template
+++ b/srcpkgs/gstreamer1/template
@@ -1,6 +1,6 @@
# Template file for 'gstreamer1'
pkgname=gstreamer1
-version=1.22.1
+version=1.22.2
revision=1
build_style=meson
build_helper="gir"
@@ -16,7 +16,7 @@ maintainer="Orphaned <orphan@voidlinux.org>"
license="LGPL-2.0-or-later"
homepage="https://gstreamer.freedesktop.org"
distfiles="${homepage}/src/gstreamer/gstreamer-${version}.tar.xz"
-checksum=cd3ca759f926763615fdfcea63c9761198c42889bc0615ceec73e22b24fde771
+checksum=b2afe73603921c608ba48969dbb7d743776744bfe5d8059ece241137b7f88e21
pre_check() {
# gst_gstdatetime is known to fail according to LFS
From 41c3c5a97b5d0506744cf961858e8829fb7cb13b Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Sun, 30 Apr 2023 20:22:26 -0400
Subject: [PATCH 131/140] gst-plugins-base1: update to 1.22.2
---
srcpkgs/gst-plugins-base1/template | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/srcpkgs/gst-plugins-base1/template b/srcpkgs/gst-plugins-base1/template
index 6d2cad16f985..2f20ea819849 100644
--- a/srcpkgs/gst-plugins-base1/template
+++ b/srcpkgs/gst-plugins-base1/template
@@ -1,6 +1,6 @@
# Template file for 'gst-plugins-base1'
pkgname=gst-plugins-base1
-version=1.22.1
+version=1.22.2
revision=1
build_style=meson
build_helper="gir"
@@ -22,7 +22,7 @@ maintainer="Orphaned <orphan@voidlinux.org>"
license="GPL-2.0-or-later, LGPL-2.0-or-later"
homepage="https://gstreamer.freedesktop.org"
distfiles="${homepage}/src/${pkgname/1/}/${pkgname/1/}-${version}.tar.xz"
-checksum=59bcaeacc5646b8dbdcfa4ef20ca6e818dd234910efb4cee1bbea441a3801c69
+checksum=eb65120c4ee79b7a153c3c1972d5c0158c2151877cc51ec7725bba5749679d49
build_options="cdparanoia gir sndio wayland"
build_options_default="cdparanoia gir wayland"
From 365ad737dd9435d192b5345f04258ca929a40923 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Sun, 30 Apr 2023 20:22:26 -0400
Subject: [PATCH 132/140] gst-plugins-good1: update to 1.22.2
---
srcpkgs/gst-plugins-good1/template | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/srcpkgs/gst-plugins-good1/template b/srcpkgs/gst-plugins-good1/template
index 00baa6732c75..5d0fe1bfe284 100644
--- a/srcpkgs/gst-plugins-good1/template
+++ b/srcpkgs/gst-plugins-good1/template
@@ -1,6 +1,6 @@
# Template file for 'gst-plugins-good1'
pkgname=gst-plugins-good1
-version=1.22.1
+version=1.22.2
revision=1
build_style=meson
configure_args="-Ddv=disabled -Ddv1394=disabled -Dshout2=disabled -Dqt5=enabled
@@ -22,7 +22,7 @@ maintainer="Orphaned <orphan@voidlinux.org>"
license="LGPL-2.1-or-later"
homepage="https://gstreamer.freedesktop.org"
distfiles="${homepage}/src/${pkgname/1/}/${pkgname/1/}-${version}.tar.xz"
-checksum=44f9104654b4fd042aebe90932ab92e7ff7d8460fbc05b23dad87dffe70974cc
+checksum=7c8cc59425f2b232f60ca7d13e56edd615da4f711e73dd01a7cffa46e6bc0cdd
build_options="gtk3 wayland"
build_options_default="gtk3 wayland"
From 93dbba9600b15a8fb2767c8395503a1422357232 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Sun, 30 Apr 2023 20:22:26 -0400
Subject: [PATCH 133/140] gst-plugins-bad1: update to 1.22.2
---
srcpkgs/gst-plugins-bad1/template | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/srcpkgs/gst-plugins-bad1/template b/srcpkgs/gst-plugins-bad1/template
index 7f272f915ac4..77bf79981c20 100644
--- a/srcpkgs/gst-plugins-bad1/template
+++ b/srcpkgs/gst-plugins-bad1/template
@@ -1,7 +1,7 @@
# Template file for 'gst-plugins-bad1'
pkgname=gst-plugins-bad1
-version=1.22.1
-revision=2
+version=1.22.2
+revision=1
build_helper="gir"
build_style=meson
configure_args="-Dpackage-origin=https://voidlinux.org -Ddoc=disabled
@@ -36,7 +36,7 @@ maintainer="Orphaned <orphan@voidlinux.org>"
license="GPL-2.0-or-later, LGPL-2.1-or-later"
homepage="https://gstreamer.freedesktop.org"
distfiles="${homepage}/src/${pkgname/1/}/${pkgname/1/}-${version}.tar.xz"
-checksum=2f39b6f222d98666f9ff420a00233e336949953a846237c2bfafc8805f509f0e
+checksum=3d8faf1ce3402c8535ce3a8c4e1a6c960e4b5655dbda6b55943db9ac79022d0f
build_options="gir gme wayland"
build_options_default="gir wayland"
From b2cac7368f15838526ca2eccdf02b4b5e6261ce9 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Sun, 30 Apr 2023 20:22:26 -0400
Subject: [PATCH 134/140] gst-plugins-ugly1: update to 1.22.2
---
srcpkgs/gst-plugins-ugly1/template | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/srcpkgs/gst-plugins-ugly1/template b/srcpkgs/gst-plugins-ugly1/template
index 5647c012c9fe..85ae64bc7a0a 100644
--- a/srcpkgs/gst-plugins-ugly1/template
+++ b/srcpkgs/gst-plugins-ugly1/template
@@ -1,6 +1,6 @@
# Template file for 'gst-plugins-ugly1'
pkgname=gst-plugins-ugly1
-version=1.22.1
+version=1.22.2
revision=1
build_style=meson
configure_args="-Damrnb=disabled -Damrwbdec=disabled -Dsidplay=disabled"
@@ -15,4 +15,4 @@ maintainer="Orphaned <orphan@voidlinux.org>"
license="LGPL-2.1-or-later"
homepage="https://gstreamer.freedesktop.org"
distfiles="${homepage}/src/${pkgname/1/}/${pkgname/1/}-${version}.tar.xz"
-checksum=4ab3d9e13481bce1ca3c7c4bb1f65dce4f0bb40fb1cac4416e8c06dd648815c2
+checksum=8f30f44db0bd063709bf6fbe55138e3a98af0abcb61c360f35582bbe10e80691
From 1f9274630e726512c53e6e8110e1d25bdcbb8edc Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Sun, 30 Apr 2023 20:22:26 -0400
Subject: [PATCH 135/140] gst-omx: update to 1.22.2
---
srcpkgs/gst-omx/template | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/srcpkgs/gst-omx/template b/srcpkgs/gst-omx/template
index 76692c2a13f6..5ad54cc7b9d8 100644
--- a/srcpkgs/gst-omx/template
+++ b/srcpkgs/gst-omx/template
@@ -1,6 +1,6 @@
# Template file for 'gst-omx'
pkgname=gst-omx
-version=1.22.1
+version=1.22.2
revision=1
build_style=meson
configure_args="-Dexamples=disabled -Dtarget=generic"
@@ -11,4 +11,4 @@ maintainer="Orphaned <orphan@voidlinux.org>"
license="LGPL-2.1-only"
homepage="https://gstreamer.freedesktop.org"
distfiles="${homepage}/src/${pkgname}/${pkgname}-${version}.tar.xz"
-checksum=2d37f60cd33e68dcef0bcd09b2dd8a0b2eb3ab6d6ac172dca46f70eb02756687
+checksum=1b0c57f2cc4ddeec5e7f0c436e502f06665c4e93c73261855b94e04fc94337b2
From 740c292b2c608703a0f4d746699c618ae5dfb632 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Sun, 30 Apr 2023 20:22:26 -0400
Subject: [PATCH 136/140] gst-rtsp-server: update to 1.22.2
---
srcpkgs/gst-rtsp-server/template | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/srcpkgs/gst-rtsp-server/template b/srcpkgs/gst-rtsp-server/template
index ded9a69a2e9d..2f0c0c45ff82 100644
--- a/srcpkgs/gst-rtsp-server/template
+++ b/srcpkgs/gst-rtsp-server/template
@@ -1,6 +1,6 @@
# Template file for 'gst-rtsp-server'
pkgname=gst-rtsp-server
-version=1.22.1
+version=1.22.2
revision=1
build_style=meson
hostmakedepends="pkg-config python3"
@@ -11,4 +11,4 @@ maintainer="1is7ac3 <isaac.qa13@gmail.com>"
license="LGPL-2.1-or-later"
homepage="https://gstreamer.freedesktop.org"
distfiles="${homepage}/src/${pkgname}/${pkgname}-${version}.tar.xz"
-checksum=4e0b972608f67d5d8f5363c827cfcf132b0e00877be6f1905358d514249b05a3
+checksum=2be4aecfb88710100ea7115ed0216403e8094344ebf146094271b8d4d73828bf
From 02f59c15c30a6bca2e3da44d555661823ef6c0d0 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Sun, 30 Apr 2023 20:22:26 -0400
Subject: [PATCH 137/140] gst1-editing-services: update to 1.22.2
---
srcpkgs/gst1-editing-services/template | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/srcpkgs/gst1-editing-services/template b/srcpkgs/gst1-editing-services/template
index f2045ad6043c..102440f7f253 100644
--- a/srcpkgs/gst1-editing-services/template
+++ b/srcpkgs/gst1-editing-services/template
@@ -1,6 +1,6 @@
# Template file for 'gst1-editing-services'
pkgname=gst1-editing-services
-version=1.22.1
+version=1.22.2
revision=1
build_style=meson
build_helper="gir"
@@ -12,7 +12,7 @@ maintainer="Toyam Cox <Vaelatern@gmail.com>"
license="LGPL-2.0-or-later"
homepage="https://gstreamer.freedesktop.org"
distfiles="${homepage}/src/${pkgname/gst1/gst}/${pkgname/gst1/gst}-${version}.tar.xz"
-checksum=0f9e5e08ef80a4b9a0e971c5f032b13c71aa6fef236265c2d615456e15161438
+checksum=453b1464fc3857de269a7cb0ebd966afe02171d97bef672a0b8a0a6d43e0cebf
do_check() {
: # Tests fail in older versions as well
From fece21e2cedb4e5a130571d7f77ef54c94d24e38 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Sun, 30 Apr 2023 20:22:26 -0400
Subject: [PATCH 138/140] gst1-python3: update to 1.22.2
---
srcpkgs/gst1-python3/template | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/srcpkgs/gst1-python3/template b/srcpkgs/gst1-python3/template
index 7a8d094ef61f..789e40f036ea 100644
--- a/srcpkgs/gst1-python3/template
+++ b/srcpkgs/gst1-python3/template
@@ -1,6 +1,6 @@
# Template file for 'gst1-python3'
pkgname=gst1-python3
-version=1.22.1
+version=1.22.2
revision=1
build_style=meson
hostmakedepends="pkg-config python3"
@@ -11,4 +11,4 @@ maintainer="Orphaned <orphan@voidlinux.org>"
license="LGPL-2.1-or-later"
homepage="https://gstreamer.freedesktop.org"
distfiles="${homepage}/src/gst-python/gst-python-${version}.tar.xz"
-checksum=96008a441d685a64275a515b893ccad0fea1d560c43acd0763533e17f3a13ebb
+checksum=bef2b3d82ce4be46b775b1bb56305c1003ee01b535a53a82f9fe8924972153ad
From 559168bb24897305a7ed05002fe3dde79af6c88c Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Sun, 30 Apr 2023 20:22:26 -0400
Subject: [PATCH 139/140] gstreamer-vaapi: update to 1.22.2
---
srcpkgs/gstreamer-vaapi/template | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/srcpkgs/gstreamer-vaapi/template b/srcpkgs/gstreamer-vaapi/template
index c100d99e9af1..0a5ee8b1ca3f 100644
--- a/srcpkgs/gstreamer-vaapi/template
+++ b/srcpkgs/gstreamer-vaapi/template
@@ -1,6 +1,6 @@
# Template file for 'gstreamer-vaapi'
pkgname=gstreamer-vaapi
-version=1.22.1
+version=1.22.2
revision=1
build_style=meson
hostmakedepends="pkg-config"
@@ -11,7 +11,7 @@ license="LGPL-2.1-or-later"
homepage="https://gstreamer.freedesktop.org"
changelog="https://raw.githubusercontent.com/GStreamer/gstreamer-vaapi/master/ChangeLog"
distfiles="${homepage}/src/gstreamer-vaapi/gstreamer-vaapi-${version}.tar.xz"
-checksum=423b57db7fc5f9137dadf17cb3853a47438d63cd4ba6889a882e63fb5be997bc
+checksum=d2e642f9745f97d9f73a7f5085e7659a9a31fe209b774e6e45dae041b435df06
pre_check() {
# Seems to need certain hardware to pass
From 7cead1792cd0cf5d055e429b3f7222bf996b9985 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Sun, 30 Apr 2023 20:22:26 -0400
Subject: [PATCH 140/140] gst-libav: update to 1.22.2
---
srcpkgs/gst-libav/template | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/srcpkgs/gst-libav/template b/srcpkgs/gst-libav/template
index a2c97bfbcdb9..8c72fc3e97ee 100644
--- a/srcpkgs/gst-libav/template
+++ b/srcpkgs/gst-libav/template
@@ -1,6 +1,6 @@
# Template file for 'gst-libav'
pkgname=gst-libav
-version=1.22.1
+version=1.22.2
revision=1
build_style=meson
hostmakedepends="pkg-config yasm"
@@ -11,7 +11,7 @@ maintainer="Orphaned <orphan@voidlinux.org>"
license="LGPL-2.0-or-later"
homepage="https://gstreamer.freedesktop.org"
distfiles="${homepage}/src/${pkgname}/${pkgname}-${version}.tar.xz"
-checksum=c958e825dc3ac3b7a481f8db5268131a1cd701312385c2d803dc63c8e460b5fb
+checksum=fcaaf9878fe8f3bc82317ef13a1558824cb68df1f8968c6797f556c5e33bcffd
case "$XBPS_TARGET_MACHINE" in
*-musl) # Required by musl for M_SQRT1_2
^ permalink raw reply [flat|nested] 175+ messages in thread
* Re: ffmpeg6 split
2023-05-05 13:20 [PR PATCH] ffmpeg6 split zlice
2023-05-05 13:27 ` [PR PATCH] [Updated] " zlice
@ 2023-05-05 13:53 ` zlice
2023-05-05 18:04 ` [PR PATCH] [Updated] " zlice
` (171 subsequent siblings)
173 siblings, 0 replies; 175+ messages in thread
From: zlice @ 2023-05-05 13:53 UTC (permalink / raw)
To: ml
[-- Attachment #1: Type: text/plain, Size: 479 bytes --]
New comment by zlice on void-packages repository
https://github.com/void-linux/void-packages/pull/43761#issuecomment-1536296485
Comment:
xlint questions
```
============ qt5 ===============
qt5:35: verify python_version and remove "#unverified"
qt5:529: use <pkgname>-doc subpackage for documentation
```
what counts as 'verified' for python?
does doc pkg need changed? looks like a separate package (still on 5.15.2 and out of sync with current qt5 5.15.7)
^ permalink raw reply [flat|nested] 175+ messages in thread
* Re: [PR PATCH] [Updated] ffmpeg6 split
2023-05-05 13:20 [PR PATCH] ffmpeg6 split zlice
2023-05-05 13:27 ` [PR PATCH] [Updated] " zlice
2023-05-05 13:53 ` zlice
@ 2023-05-05 18:04 ` zlice
2023-05-07 19:26 ` paper42
` (170 subsequent siblings)
173 siblings, 0 replies; 175+ messages in thread
From: zlice @ 2023-05-05 18:04 UTC (permalink / raw)
To: ml
[-- Attachment #1: Type: text/plain, Size: 2793 bytes --]
There is an updated pull request by zlice against master on the void-packages repository
https://github.com/zlice/void-packages ffmpeg6-split
https://github.com/void-linux/void-packages/pull/43761
ffmpeg6 split
[ci skip]
#### Testing the changes
- I tested the changes in this PR: **YES**
main testing has been vaapi in Firefox Nightly and enc/dec in Shotcut on Intel A770
#### New package
- This new package conforms to the [package requirements](https://github.com/void-linux/void-packages/blob/master/CONTRIBUTING.md#package-requirements): **YES**
#### Local build testing
- I built this PR locally for my native architecture, **x86_64**
#### Discussion
Continuation of https://github.com/void-linux/void-packages/pull/36315
`libavresample` is deprecated, but marked as a dependency when trying to build other packages and install `ffmpeg`(5). I think the right way to handle this is make a meta package and the add to removals?
##### Commit naming / misc
Commits are 'dirty' right now, running with [gstreamer 1.22.1 updates](https://github.com/void-linux/void-packages/pull/42861) and [Intel OpenCL](https://github.com/void-linux/void-packages/pull/43084). This will also make [intel packages pr](https://github.com/void-linux/void-packages/pull/41132) obsolete.
Maintainer for previous ffmpeg(4) was orphaned, I can put my name in there if that matters, though I don't exactly see myself keeping up on ffmpeg.
This updates QT5 which looks like it is usually hosted by Johnny. Not sure if there's any reason to stay there or these sources are fine.
##### STILL FFMPEG4
These are a mix of emulators, games and/or older packages.
- attract (multiple patches in master)
- audacity (3.2.x+ should work but requires wxWidgets dev 3.1.x)
- ccextractor (master patches? no release)
- vice
- kodi
- mlt
- synfig (mlt)
- tvheadend
- ssr
- spek-alternative
- ppsspp
- olive
- moc
- mediastreamer
- libextractor
- idjc
- hedgewars
- ffmpegthumbnailer
- ffmpegthumbs
- deadbeef
- omxplayer
- qtav (fork has ffmpeg 5 patch - https://github.com/cmguo/QtAV)
- `vlc` (vlc4 will support ffmpeg5, there's a patch to build 3.x with ffmpeg5 but it will lack vaapi)
- `osg` (OpenSceneGraph plus `xine-lib`)
- `ytmdl` ? not sure but it uses `python3-ffmpeg-python` which being 6-8yr old I imagine is ffmpeg4
##### HAVE NOT BUILT YET
- omxplayer (rpi only?)
- kodi (big, but ffmpeg4)
##### UPDATED (for ffmpeg5)
- unpaper: update to 7.0.0.
- guvcview: update to 2.0.8.
- qt5: update to 5.15.8
- qt5-webengine: update to 5.18.13
- shiboken2: revbump for qt5.15.8 (patch)
- python3-pyside2: update to 5.15.8 (patch)
A patch file from https://github.com/void-linux/void-packages/pull/43761.patch is attached
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: github-pr-ffmpeg6-split-43761.patch --]
[-- Type: text/x-diff, Size: 820169 bytes --]
From ffbaac24c1cbec506af20e9f5e044cc19d9a7e29 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 19:55:46 -0400
Subject: [PATCH 001/130] ffmpeg: update to 6.0.
---
common/shlibs | 26 +++++---
srcpkgs/ffmpeg/files/altivec.patch | 60 -------------------
.../patches/armv5tel-floating-point.patch | 18 ------
.../workaround-mesa-readeon-vaapi-bug.patch | 28 ---------
srcpkgs/ffmpeg/template | 31 +++++-----
5 files changed, 33 insertions(+), 130 deletions(-)
delete mode 100644 srcpkgs/ffmpeg/files/altivec.patch
delete mode 100644 srcpkgs/ffmpeg/patches/armv5tel-floating-point.patch
delete mode 100644 srcpkgs/ffmpeg/patches/workaround-mesa-readeon-vaapi-bug.patch
diff --git a/common/shlibs b/common/shlibs
index 8c47e79b8c43..d650f2a3045d 100644
--- a/common/shlibs
+++ b/common/shlibs
@@ -390,15 +390,23 @@ libid3tag.so.0 libid3tag-0.15.1b_1
libgif.so.7 giflib-5.1.0_1
libImlib2.so.1 imlib2-1.4.2_1
libmp3lame.so.0 lame-3.98.2_1
-libavdevice.so.58 libavdevice-4.0_1
-libavformat.so.58 libavformat-4.0_1
-libswscale.so.5 libswscale-4.0_1
-libswresample.so.3 libswresample-4.0_1
-libavresample.so.4 libavresample-4.0_1
-libpostproc.so.55 libpostproc-4.0_1
-libavcodec.so.58 libavcodec-4.0_1
-libavutil.so.56 libavutil-4.0_1
-libavfilter.so.7 libavfilter-4.0_1
+libavdevice.so.60 libavdevice-6.0_1
+libavformat.so.60 libavformat-6.0_1
+libswscale.so.7 libswscale-6.0_1
+libswresample.so.4 libswresample-6.0_1
+libpostproc.so.57 libpostproc-6.0_1
+libavcodec.so.60 libavcodec-6.0_1
+libavutil.so.58 libavutil-6.0_1
+libavfilter.so.9 libavfilter-6.0_1
+libavdevice.so.58 libavdevice4-4.0_1
+libavformat.so.58 libavformat4-4.0_1
+libswscale.so.5 libswscale4-4.0_1
+libswresample.so.3 libswresample4-4.0_1
+libavresample.so.4 libavresample4-4.0_1
+libpostproc.so.55 libpostproc4-4.0_1
+libavcodec.so.58 libavcodec4-4.0_1
+libavutil.so.56 libavutil4-4.0_1
+libavfilter.so.7 libavfilter4-4.0_1
libSDL-1.2.so.0 SDL-1.2.14_1
libSDL_image-1.2.so.0 SDL_image-1.2.10_1
libx264.so.157 x264-20190507.2245_1
diff --git a/srcpkgs/ffmpeg/files/altivec.patch b/srcpkgs/ffmpeg/files/altivec.patch
deleted file mode 100644
index 9c5720046332..000000000000
--- a/srcpkgs/ffmpeg/files/altivec.patch
+++ /dev/null
@@ -1,60 +0,0 @@
-revert some altivec specific change on all ppc* except ppc64le*
-
-q66: "We should also throw in a revert of FFmpeg/FFmpeg@3a557c5 but only
-conditionally, for ppc* but not ppc64le* (the new code is valid for
-POWER8 VSX which LE targets as a baseline but not BE)"
-
-
-This reverts commit 3a557c5d88b7b15b5954ba2743febb055549b536.
----
- libswscale/ppc/yuv2rgb_altivec.c | 24 ++++++++++++++++++++----
- 1 file changed, 20 insertions(+), 4 deletions(-)
-
-diff --git a/libswscale/ppc/yuv2rgb_altivec.c b/libswscale/ppc/yuv2rgb_altivec.c
-index 536545293d..c1e2852adb 100644
---- a/libswscale/ppc/yuv2rgb_altivec.c
-+++ b/libswscale/ppc/yuv2rgb_altivec.c
-@@ -305,6 +305,9 @@ static int altivec_ ## name(SwsContext *c, const unsigned char **in, \
- vector signed short R1, G1, B1; \
- vector unsigned char R, G, B; \
- \
-+ const vector unsigned char *y1ivP, *y2ivP, *uivP, *vivP; \
-+ vector unsigned char align_perm; \
-+ \
- vector signed short lCY = c->CY; \
- vector signed short lOY = c->OY; \
- vector signed short lCRV = c->CRV; \
-@@ -335,13 +338,26 @@ static int altivec_ ## name(SwsContext *c, const unsigned char **in, \
- vec_dstst(oute, (0x02000002 | (((w * 3 + 32) / 32) << 16)), 1); \
- \
- for (j = 0; j < w / 16; j++) { \
-- y0 = vec_xl(0, y1i); \
-+ y1ivP = (const vector unsigned char *) y1i; \
-+ y2ivP = (const vector unsigned char *) y2i; \
-+ uivP = (const vector unsigned char *) ui; \
-+ vivP = (const vector unsigned char *) vi; \
-+ \
-+ align_perm = vec_lvsl(0, y1i); \
-+ y0 = (vector unsigned char) \
-+ vec_perm(y1ivP[0], y1ivP[1], align_perm); \
- \
-- y1 = vec_xl(0, y2i); \
-+ align_perm = vec_lvsl(0, y2i); \
-+ y1 = (vector unsigned char) \
-+ vec_perm(y2ivP[0], y2ivP[1], align_perm); \
- \
-- u = (vector signed char) vec_xl(0, ui); \
-+ align_perm = vec_lvsl(0, ui); \
-+ u = (vector signed char) \
-+ vec_perm(uivP[0], uivP[1], align_perm); \
- \
-- v = (vector signed char) vec_xl(0, vi); \
-+ align_perm = vec_lvsl(0, vi); \
-+ v = (vector signed char) \
-+ vec_perm(vivP[0], vivP[1], align_perm); \
- \
- u = (vector signed char) \
- vec_sub(u, \
---
-2.27.0
-
diff --git a/srcpkgs/ffmpeg/patches/armv5tel-floating-point.patch b/srcpkgs/ffmpeg/patches/armv5tel-floating-point.patch
deleted file mode 100644
index 9a55178c74f0..000000000000
--- a/srcpkgs/ffmpeg/patches/armv5tel-floating-point.patch
+++ /dev/null
@@ -1,18 +0,0 @@
---- a/libavfilter/vf_drawtext.c 2017-10-26 21:03:03.000000000 +0200
-+++ b/libavfilter/vf_drawtext.c 2017-11-21 11:06:49.602284422 +0100
-@@ -39,6 +39,15 @@
- #endif
- #include <fenv.h>
-
-+#if (FE_ALL_EXCEPT == 0)
-+/* E.g. ARM soft float does not define these */
-+#define FE_INVALID 0
-+#define FE_DIVBYZERO 0
-+#define FE_OVERFLOW 0
-+#define FE_UNDERFLOW 0
-+#define FE_INEXACT 0
-+#endif
-+
- #if CONFIG_LIBFONTCONFIG
- #include <fontconfig/fontconfig.h>
- #endif
diff --git a/srcpkgs/ffmpeg/patches/workaround-mesa-readeon-vaapi-bug.patch b/srcpkgs/ffmpeg/patches/workaround-mesa-readeon-vaapi-bug.patch
deleted file mode 100644
index 00e3f68a415b..000000000000
--- a/srcpkgs/ffmpeg/patches/workaround-mesa-readeon-vaapi-bug.patch
+++ /dev/null
@@ -1,28 +0,0 @@
-From 811d290844206fc73dc39c3e5b67d5d895baedf8 Mon Sep 17 00:00:00 2001
-From: Rainer Hochecker <fernetmenta@online.de>
-Date: Sat, 26 Jan 2019 19:48:35 +0100
-Subject: [PATCH] avcodec/vaapi_h264: skip decode if pic has no slices
-
-This fixes / workarounds https://bugs.freedesktop.org/show_bug.cgi?id=105368.
-It was hit frequently when watching h264 channels received via DVB-X.
-Corresponding kodi bug: https://github.com/xbmc/xbmc/issues/15704
----
- libavcodec/vaapi_h264.c | 5 +++++
- 1 file changed, 5 insertions(+)
-
-diff --git a/libavcodec/vaapi_h264.c b/libavcodec/vaapi_h264.c
-index 5854587a255..f12fdc457a4 100644
---- a/libavcodec/vaapi_h264.c
-+++ b/libavcodec/vaapi_h264.c
-@@ -317,6 +317,11 @@ static int vaapi_h264_end_frame(AVCodecContext *avctx)
- H264SliceContext *sl = &h->slice_ctx[0];
- int ret;
-
-+ if (pic->nb_slices == 0) {
-+ ret = AVERROR_INVALIDDATA;
-+ goto finish;
-+ }
-+
- ret = ff_vaapi_decode_issue(avctx, pic);
- if (ret < 0)
- goto finish;
diff --git a/srcpkgs/ffmpeg/template b/srcpkgs/ffmpeg/template
index 23a3d5c9967b..3d99e5173697 100644
--- a/srcpkgs/ffmpeg/template
+++ b/srcpkgs/ffmpeg/template
@@ -1,15 +1,15 @@
# Template file for 'ffmpeg'
# audacity also needs to be bumped when a new ffmpeg version bumps libavformat's soname!
pkgname=ffmpeg
-version=4.4.3
-revision=2
+version=6.0
+revision=1
short_desc="Decoding, encoding and streaming software"
maintainer="Orphaned <orphan@voidlinux.org>"
license="GPL-3.0-or-later"
homepage="https://www.ffmpeg.org"
changelog="https://raw.githubusercontent.com/FFmpeg/FFmpeg/master/Changelog"
distfiles="https://www.ffmpeg.org/releases/ffmpeg-${version}.tar.xz"
-checksum=6c5b6c195e61534766a0b5fe16acc919170c883362612816d0a1c7f4f947006e
+checksum=57be87c22d9b49c112b6d24bc67d42508660e6b718b3db89c44e47e289137082
hostmakedepends="pkg-config perl yasm"
makedepends="zlib-devel bzip2-devel freetype-devel alsa-lib-devel libXfixes-devel
@@ -26,12 +26,13 @@ makedepends="zlib-devel bzip2-devel freetype-devel alsa-lib-devel libXfixes-deve
$(vopt_if webp libwebp-devel) $(vopt_if sofa libmysofa-devel)
$(vopt_if drm libdrm-devel) $(vopt_if svtav1 libsvt-av1-devel)
$(vopt_if srt srt-devel) $(vopt_if rist librist-devel)
- $(vopt_if vulkan 'vulkan-loader Vulkan-Headers')
+ $(vopt_if vulkan 'vulkan-loader Vulkan-Headers Vulkan-Tools Vulkan-ValidationLayers')
+ $(vopt_if onevpl 'onevpl onevpl-devel')
$(vopt_if nvenc nv-codec-headers) $(vopt_if nvdec nv-codec-headers)"
depends="ffplay>=${version}_${revision}"
build_options="x265 v4l2 vaapi vdpau vpx fdk_aac aom nvenc sndio pulseaudio
- dav1d zimg webp sofa vulkan drm svtav1 srt rist nvdec"
+ dav1d zimg webp sofa vulkan drm svtav1 srt rist nvdec onevpl"
build_options_default="x265 v4l2 vpx aom sndio pulseaudio dav1d webp vulkan drm srt rist"
desc_option_srt="Enable support for SRT (Secure, Reliable, Transport)"
desc_option_rist="Enable support for RIST (Reliable Internet Stream Transport)"
@@ -39,7 +40,8 @@ desc_option_sofa="Enable support for AES SOFA"
desc_option_webp="Enable support for WebP"
case "$XBPS_TARGET_MACHINE" in
- i686*|x86_64*) build_options_default+=" vaapi vdpau nvenc nvdec";;
+ i686*) build_options_default+=" vaapi vdpau nvenc nvdec";;
+ x86_64*) build_options_default+=" vaapi vdpau nvenc nvdec onevpl";;
ppc64*) build_options_default+=" vaapi vdpau";;
mips*) CFLAGS="-mnan=legacy";;
esac
@@ -114,18 +116,19 @@ do_configure() {
$(vopt_enable x265 libx265) \
$(vopt_enable v4l2 libv4l2) \
$(vopt_enable aom libaom) $(vopt_enable vaapi) $(vopt_enable vdpau) \
- --enable-libbs2b --enable-avresample --enable-libvidstab \
+ --enable-libbs2b --enable-libvidstab \
$(vopt_enable dav1d libdav1d) \
$(vopt_enable zimg libzimg) \
$(vopt_enable webp libwebp) \
$(vopt_enable sofa libmysofa) \
$(vopt_enable vulkan) \
+ $(vopt_enable onevpl libvpl) \
$(vopt_enable drm libdrm) \
$(vopt_enable svtav1 libsvtav1) \
$(vopt_enable srt libsrt) \
$(vopt_enable rist librist) \
- $(vopt_if nvenc '--enable-nvenc') \
- $(vopt_if nvdec '--enable-nvdec')
+ $(vopt_enable nvenc nvenc) \
+ $(vopt_enable nvdec nvdec)
}
do_build() {
make ${makejobs}
@@ -148,10 +151,8 @@ libavdevice_package() {
}
}
libavresample_package() {
- short_desc="FFmpeg audio resampling library"
- pkg_install() {
- vmove "usr/lib/libavresample.so.*"
- }
+ short_desc="Package deprecated, removal needed"
+ build_style=meta
}
libavformat_package() {
short_desc="FFmpeg file format library"
@@ -198,9 +199,9 @@ ffmpeg-devel_package() {
libavfilter>=${version}_${revision}
libpostproc>=${version}_${revision}
libswscale>=${version}_${revision}
- libswresample>=${version}_${revision}
- libavresample>=${version}_${revision}"
+ libswresample>=${version}_${revision}"
short_desc+=" - development files"
+ conflicts="ffmpeg4-devel"
pkg_install() {
vmove usr/include
vmove usr/lib/pkgconfig
From caec8fdc7829c01b67fc37fa84b9d7a84fc14761 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 19:56:22 -0400
Subject: [PATCH 002/130] New package: ffmpeg4-4.4.3.
---
srcpkgs/ffmpeg4-devel | 1 +
srcpkgs/ffmpeg4/files/altivec.patch | 60 +++++
.../patches/armv5tel-floating-point.patch | 18 ++
.../workaround-mesa-readeon-vaapi-bug.patch | 28 +++
srcpkgs/ffmpeg4/template | 214 ++++++++++++++++++
srcpkgs/libavcodec4 | 1 +
srcpkgs/libavdevice4 | 1 +
srcpkgs/libavfilter4 | 1 +
srcpkgs/libavformat4 | 1 +
srcpkgs/libavresample4 | 1 +
srcpkgs/libavutil4 | 1 +
srcpkgs/libpostproc4 | 1 +
srcpkgs/libswresample4 | 1 +
srcpkgs/libswscale4 | 1 +
14 files changed, 330 insertions(+)
create mode 120000 srcpkgs/ffmpeg4-devel
create mode 100644 srcpkgs/ffmpeg4/files/altivec.patch
create mode 100644 srcpkgs/ffmpeg4/patches/armv5tel-floating-point.patch
create mode 100644 srcpkgs/ffmpeg4/patches/workaround-mesa-readeon-vaapi-bug.patch
create mode 100644 srcpkgs/ffmpeg4/template
create mode 120000 srcpkgs/libavcodec4
create mode 120000 srcpkgs/libavdevice4
create mode 120000 srcpkgs/libavfilter4
create mode 120000 srcpkgs/libavformat4
create mode 120000 srcpkgs/libavresample4
create mode 120000 srcpkgs/libavutil4
create mode 120000 srcpkgs/libpostproc4
create mode 120000 srcpkgs/libswresample4
create mode 120000 srcpkgs/libswscale4
diff --git a/srcpkgs/ffmpeg4-devel b/srcpkgs/ffmpeg4-devel
new file mode 120000
index 000000000000..887f354e7c6b
--- /dev/null
+++ b/srcpkgs/ffmpeg4-devel
@@ -0,0 +1 @@
+ffmpeg4
\ No newline at end of file
diff --git a/srcpkgs/ffmpeg4/files/altivec.patch b/srcpkgs/ffmpeg4/files/altivec.patch
new file mode 100644
index 000000000000..9c5720046332
--- /dev/null
+++ b/srcpkgs/ffmpeg4/files/altivec.patch
@@ -0,0 +1,60 @@
+revert some altivec specific change on all ppc* except ppc64le*
+
+q66: "We should also throw in a revert of FFmpeg/FFmpeg@3a557c5 but only
+conditionally, for ppc* but not ppc64le* (the new code is valid for
+POWER8 VSX which LE targets as a baseline but not BE)"
+
+
+This reverts commit 3a557c5d88b7b15b5954ba2743febb055549b536.
+---
+ libswscale/ppc/yuv2rgb_altivec.c | 24 ++++++++++++++++++++----
+ 1 file changed, 20 insertions(+), 4 deletions(-)
+
+diff --git a/libswscale/ppc/yuv2rgb_altivec.c b/libswscale/ppc/yuv2rgb_altivec.c
+index 536545293d..c1e2852adb 100644
+--- a/libswscale/ppc/yuv2rgb_altivec.c
++++ b/libswscale/ppc/yuv2rgb_altivec.c
+@@ -305,6 +305,9 @@ static int altivec_ ## name(SwsContext *c, const unsigned char **in, \
+ vector signed short R1, G1, B1; \
+ vector unsigned char R, G, B; \
+ \
++ const vector unsigned char *y1ivP, *y2ivP, *uivP, *vivP; \
++ vector unsigned char align_perm; \
++ \
+ vector signed short lCY = c->CY; \
+ vector signed short lOY = c->OY; \
+ vector signed short lCRV = c->CRV; \
+@@ -335,13 +338,26 @@ static int altivec_ ## name(SwsContext *c, const unsigned char **in, \
+ vec_dstst(oute, (0x02000002 | (((w * 3 + 32) / 32) << 16)), 1); \
+ \
+ for (j = 0; j < w / 16; j++) { \
+- y0 = vec_xl(0, y1i); \
++ y1ivP = (const vector unsigned char *) y1i; \
++ y2ivP = (const vector unsigned char *) y2i; \
++ uivP = (const vector unsigned char *) ui; \
++ vivP = (const vector unsigned char *) vi; \
++ \
++ align_perm = vec_lvsl(0, y1i); \
++ y0 = (vector unsigned char) \
++ vec_perm(y1ivP[0], y1ivP[1], align_perm); \
+ \
+- y1 = vec_xl(0, y2i); \
++ align_perm = vec_lvsl(0, y2i); \
++ y1 = (vector unsigned char) \
++ vec_perm(y2ivP[0], y2ivP[1], align_perm); \
+ \
+- u = (vector signed char) vec_xl(0, ui); \
++ align_perm = vec_lvsl(0, ui); \
++ u = (vector signed char) \
++ vec_perm(uivP[0], uivP[1], align_perm); \
+ \
+- v = (vector signed char) vec_xl(0, vi); \
++ align_perm = vec_lvsl(0, vi); \
++ v = (vector signed char) \
++ vec_perm(vivP[0], vivP[1], align_perm); \
+ \
+ u = (vector signed char) \
+ vec_sub(u, \
+--
+2.27.0
+
diff --git a/srcpkgs/ffmpeg4/patches/armv5tel-floating-point.patch b/srcpkgs/ffmpeg4/patches/armv5tel-floating-point.patch
new file mode 100644
index 000000000000..9a55178c74f0
--- /dev/null
+++ b/srcpkgs/ffmpeg4/patches/armv5tel-floating-point.patch
@@ -0,0 +1,18 @@
+--- a/libavfilter/vf_drawtext.c 2017-10-26 21:03:03.000000000 +0200
++++ b/libavfilter/vf_drawtext.c 2017-11-21 11:06:49.602284422 +0100
+@@ -39,6 +39,15 @@
+ #endif
+ #include <fenv.h>
+
++#if (FE_ALL_EXCEPT == 0)
++/* E.g. ARM soft float does not define these */
++#define FE_INVALID 0
++#define FE_DIVBYZERO 0
++#define FE_OVERFLOW 0
++#define FE_UNDERFLOW 0
++#define FE_INEXACT 0
++#endif
++
+ #if CONFIG_LIBFONTCONFIG
+ #include <fontconfig/fontconfig.h>
+ #endif
diff --git a/srcpkgs/ffmpeg4/patches/workaround-mesa-readeon-vaapi-bug.patch b/srcpkgs/ffmpeg4/patches/workaround-mesa-readeon-vaapi-bug.patch
new file mode 100644
index 000000000000..00e3f68a415b
--- /dev/null
+++ b/srcpkgs/ffmpeg4/patches/workaround-mesa-readeon-vaapi-bug.patch
@@ -0,0 +1,28 @@
+From 811d290844206fc73dc39c3e5b67d5d895baedf8 Mon Sep 17 00:00:00 2001
+From: Rainer Hochecker <fernetmenta@online.de>
+Date: Sat, 26 Jan 2019 19:48:35 +0100
+Subject: [PATCH] avcodec/vaapi_h264: skip decode if pic has no slices
+
+This fixes / workarounds https://bugs.freedesktop.org/show_bug.cgi?id=105368.
+It was hit frequently when watching h264 channels received via DVB-X.
+Corresponding kodi bug: https://github.com/xbmc/xbmc/issues/15704
+---
+ libavcodec/vaapi_h264.c | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+diff --git a/libavcodec/vaapi_h264.c b/libavcodec/vaapi_h264.c
+index 5854587a255..f12fdc457a4 100644
+--- a/libavcodec/vaapi_h264.c
++++ b/libavcodec/vaapi_h264.c
+@@ -317,6 +317,11 @@ static int vaapi_h264_end_frame(AVCodecContext *avctx)
+ H264SliceContext *sl = &h->slice_ctx[0];
+ int ret;
+
++ if (pic->nb_slices == 0) {
++ ret = AVERROR_INVALIDDATA;
++ goto finish;
++ }
++
+ ret = ff_vaapi_decode_issue(avctx, pic);
+ if (ret < 0)
+ goto finish;
diff --git a/srcpkgs/ffmpeg4/template b/srcpkgs/ffmpeg4/template
new file mode 100644
index 000000000000..7bc64bb39f41
--- /dev/null
+++ b/srcpkgs/ffmpeg4/template
@@ -0,0 +1,214 @@
+# Template file for 'ffmpeg4'
+# audacity also needs to be bumped when a new ffmpeg version bumps libavformat's soname!
+pkgname=ffmpeg4
+version=4.4.3
+revision=1
+short_desc="Decoding, encoding and streaming software - ffmpeg4 libraries only"
+maintainer="Orphaned <orphan@voidlinux.org>"
+license="GPL-3.0-or-later"
+homepage="https://www.ffmpeg.org"
+changelog="https://raw.githubusercontent.com/FFmpeg/FFmpeg/master/Changelog"
+distfiles="https://www.ffmpeg.org/releases/ffmpeg-${version}.tar.xz"
+checksum=6c5b6c195e61534766a0b5fe16acc919170c883362612816d0a1c7f4f947006e
+
+hostmakedepends="pkg-config perl yasm"
+makedepends="zlib-devel bzip2-devel freetype-devel alsa-lib-devel libXfixes-devel
+ libXext-devel libXvMC-devel libxcb-devel lame-devel libtheora-devel
+ libvorbis-devel x264-devel xvidcore-devel jack-devel SDL2-devel
+ libcdio-paranoia-devel librtmp-devel libmodplug-devel gnutls-devel
+ speex-devel celt-devel harfbuzz-devel libass-devel opus-devel ocl-icd-devel
+ libbs2b-devel libvidstab-devel $(vopt_if pulseaudio pulseaudio-devel)
+ $(vopt_if vaapi libva-devel) $(vopt_if vdpau libvdpau-devel)
+ $(vopt_if x265 x265-devel) $(vopt_if v4l2 v4l-utils-devel)
+ $(vopt_if fdk_aac fdk-aac-devel) $(vopt_if vpx libvpx-devel)
+ $(vopt_if aom libaom-devel) $(vopt_if sndio sndio-devel)
+ $(vopt_if dav1d libdav1d-devel) $(vopt_if zimg zimg-devel)
+ $(vopt_if webp libwebp-devel) $(vopt_if sofa libmysofa-devel)
+ $(vopt_if drm libdrm-devel) $(vopt_if svtav1 libsvt-av1-devel)
+ $(vopt_if srt srt-devel) $(vopt_if rist librist-devel)
+ $(vopt_if vulkan 'vulkan-loader Vulkan-Headers')
+ $(vopt_if nvenc nv-codec-headers) $(vopt_if nvdec nv-codec-headers)"
+
+build_options="x265 v4l2 vaapi vdpau vpx fdk_aac aom nvenc sndio pulseaudio
+ dav1d zimg webp sofa vulkan drm svtav1 srt rist nvdec"
+build_options_default="x265 v4l2 vpx aom sndio pulseaudio dav1d webp vulkan drm srt rist"
+
+desc_option_srt="Enable support for SRT (Secure, Reliable, Transport)"
+desc_option_rist="Enable support for RIST (Reliable Internet Stream Transport)"
+desc_option_sofa="Enable support for AES SOFA"
+desc_option_webp="Enable support for WebP"
+
+case "$XBPS_TARGET_MACHINE" in
+ i686*|x86_64*) build_options_default+=" vaapi vdpau nvenc nvdec";;
+ ppc64*) build_options_default+=" vaapi vdpau";;
+ mips*) CFLAGS="-mnan=legacy";;
+esac
+
+if [ "$XBPS_TARGET_WORDSIZE" != "32" ]; then
+ build_options_default+=" svtav1"
+fi
+
+if [ "$XBPS_TARGET_NO_ATOMIC8" ]; then
+ makedepends+=" libatomic-devel"
+fi
+
+_apply_patch() {
+ local args="$1" pname="$(basename $2)"
+
+ if [ ! -f ".${pname}_done" ]; then
+ patch -N $args -i $2
+ touch .${pname}_done
+ fi
+}
+
+post_patch() {
+ case "$XBPS_TARGET_MACHINE" in
+ ppc64le*) ;;
+ ppc*) _apply_patch -p1 ${FILESDIR}/altivec.patch ;;
+ esac
+}
+
+do_configure() {
+ # Fix gcc on x86_64-musl only
+ if [ "$XBPS_TARGET_MACHINE" = "x86_64-musl" ]; then
+ sed -i configure -e "s;_cflags_speed='-O3';_cflags_speed='-O2';"
+ fi
+
+ if [ "$CROSS_BUILD" ]; then
+ case "$XBPS_TARGET_MACHINE" in
+ arm*) _arch="arm";;
+ aarch64*) _arch="aarch64";;
+ mips*) _arch="mips";;
+ ppc64*) _arch="ppc64";;
+ ppc*) _arch="ppc";;
+ *) _arch="${XBPS_TARGET_MACHINE%%-musl}";;
+ esac
+
+ _args+=" --enable-cross-compile
+ --sysroot=$XBPS_CROSS_BASE
+ --cross-prefix=${XBPS_CROSS_TRIPLET}-
+ --target-os=linux --arch=${_arch}"
+ fi
+
+ case "$XBPS_TARGET_MACHINE" in
+ ppc|ppc-musl) _args+=" --disable-altivec";;
+ esac
+
+ if [ "$XBPS_TARGET_NO_ATOMIC8" ]; then
+ _args+=" --extra-libs=-latomic"
+ fi
+
+ ./configure --prefix=/usr --disable-debug --enable-gpl --enable-gnutls \
+ --disable-stripping \
+ --enable-libcdio --enable-version3 --enable-runtime-cpudetect \
+ --enable-libmp3lame --enable-libvorbis --enable-libxvid \
+ --enable-libx264 $(vopt_enable vpx libvpx) --enable-libtheora \
+ --enable-shared --enable-static --enable-libxcb \
+ $(vopt_enable pulseaudio libpulse) --enable-libfreetype --enable-libmodplug \
+ --enable-libspeex --enable-libcelt --enable-libass \
+ --enable-libopus --enable-librtmp --enable-libjack \
+ $(vopt_if fdk_aac '--enable-nonfree --enable-libfdk-aac') \
+ --disable-libopencore_amrnb --disable-libopencore_amrwb \
+ --disable-libopenjpeg \
+ --enable-postproc --enable-opencl ${_args} \
+ $(vopt_enable x265 libx265) \
+ $(vopt_enable v4l2 libv4l2) \
+ $(vopt_enable aom libaom) $(vopt_enable vaapi) $(vopt_enable vdpau) \
+ --enable-libbs2b --enable-avresample --enable-libvidstab \
+ $(vopt_enable dav1d libdav1d) \
+ $(vopt_enable zimg libzimg) \
+ $(vopt_enable webp libwebp) \
+ $(vopt_enable sofa libmysofa) \
+ $(vopt_enable vulkan) \
+ $(vopt_enable drm libdrm) \
+ $(vopt_enable svtav1 libsvtav1) \
+ $(vopt_enable srt libsrt) \
+ $(vopt_enable rist librist) \
+ $(vopt_if nvenc '--enable-nvenc') \
+ $(vopt_if nvdec '--enable-nvdec')
+}
+do_build() {
+ make ${makejobs}
+ make doc/ff{mpeg,play}.1
+}
+do_install() {
+ make DESTDIR=${DESTDIR} install install-man
+ rm -rf ${DESTDIR}/usr/bin
+}
+
+libavcodec4_package() {
+ short_desc="FFmpeg codec library"
+ pkg_install() {
+ vmove "usr/lib/libavcodec.so.*"
+ }
+}
+libavdevice4_package() {
+ short_desc="FFmpeg device handling library"
+ pkg_install() {
+ vmove "usr/lib/libavdevice.so.*"
+ }
+}
+libavresample4_package() {
+ short_desc="FFmpeg audio resampling library"
+ pkg_install() {
+ vmove "usr/lib/libavresample.so.*"
+ }
+}
+libavformat4_package() {
+ short_desc="FFmpeg file format library"
+ pkg_install() {
+ vmove "usr/lib/libavformat.so.*"
+ }
+}
+libavutil4_package() {
+ short_desc="FFmpeg utility library"
+ pkg_install() {
+ vmove "usr/lib/libavutil.so.*"
+ }
+}
+libavfilter4_package() {
+ short_desc="FFmpeg audio/video filter library"
+ pkg_install() {
+ vmove "usr/lib/libavfilter.so.*"
+ }
+}
+libpostproc4_package() {
+ short_desc="FFmpeg video postprocessing library"
+ pkg_install() {
+ vmove "usr/lib/libpostproc.so.*"
+ }
+}
+libswscale4_package() {
+ short_desc="FFmpeg video scaling library"
+ pkg_install() {
+ vmove "usr/lib/libswscale.so.*"
+ }
+}
+libswresample4_package() {
+ short_desc="FFmpeg video resampling library"
+ pkg_install() {
+ vmove "usr/lib/libswresample.so.*"
+ }
+}
+ffmpeg4-devel_package() {
+ depends="
+ libavcodec4>=${version}_${revision}
+ libavdevice4>=${version}_${revision}
+ libavformat4>=${version}_${revision}
+ libavutil4>=${version}_${revision}
+ libavfilter4>=${version}_${revision}
+ libpostproc4>=${version}_${revision}
+ libswscale4>=${version}_${revision}
+ libswresample4>=${version}_${revision}
+ libavresample4>=${version}_${revision}"
+ short_desc+=" - development files"
+ conflicts="ffmpeg-devel"
+ pkg_install() {
+ vmove usr/include
+ vmove usr/lib/pkgconfig
+ vmove usr/lib/*.a
+ vmove usr/lib/*.so
+ vmove usr/share/ffmpeg/examples
+ vmove usr/share/man/man3
+ }
+}
diff --git a/srcpkgs/libavcodec4 b/srcpkgs/libavcodec4
new file mode 120000
index 000000000000..887f354e7c6b
--- /dev/null
+++ b/srcpkgs/libavcodec4
@@ -0,0 +1 @@
+ffmpeg4
\ No newline at end of file
diff --git a/srcpkgs/libavdevice4 b/srcpkgs/libavdevice4
new file mode 120000
index 000000000000..887f354e7c6b
--- /dev/null
+++ b/srcpkgs/libavdevice4
@@ -0,0 +1 @@
+ffmpeg4
\ No newline at end of file
diff --git a/srcpkgs/libavfilter4 b/srcpkgs/libavfilter4
new file mode 120000
index 000000000000..887f354e7c6b
--- /dev/null
+++ b/srcpkgs/libavfilter4
@@ -0,0 +1 @@
+ffmpeg4
\ No newline at end of file
diff --git a/srcpkgs/libavformat4 b/srcpkgs/libavformat4
new file mode 120000
index 000000000000..887f354e7c6b
--- /dev/null
+++ b/srcpkgs/libavformat4
@@ -0,0 +1 @@
+ffmpeg4
\ No newline at end of file
diff --git a/srcpkgs/libavresample4 b/srcpkgs/libavresample4
new file mode 120000
index 000000000000..887f354e7c6b
--- /dev/null
+++ b/srcpkgs/libavresample4
@@ -0,0 +1 @@
+ffmpeg4
\ No newline at end of file
diff --git a/srcpkgs/libavutil4 b/srcpkgs/libavutil4
new file mode 120000
index 000000000000..887f354e7c6b
--- /dev/null
+++ b/srcpkgs/libavutil4
@@ -0,0 +1 @@
+ffmpeg4
\ No newline at end of file
diff --git a/srcpkgs/libpostproc4 b/srcpkgs/libpostproc4
new file mode 120000
index 000000000000..887f354e7c6b
--- /dev/null
+++ b/srcpkgs/libpostproc4
@@ -0,0 +1 @@
+ffmpeg4
\ No newline at end of file
diff --git a/srcpkgs/libswresample4 b/srcpkgs/libswresample4
new file mode 120000
index 000000000000..887f354e7c6b
--- /dev/null
+++ b/srcpkgs/libswresample4
@@ -0,0 +1 @@
+ffmpeg4
\ No newline at end of file
diff --git a/srcpkgs/libswscale4 b/srcpkgs/libswscale4
new file mode 120000
index 000000000000..887f354e7c6b
--- /dev/null
+++ b/srcpkgs/libswscale4
@@ -0,0 +1 @@
+ffmpeg4
\ No newline at end of file
From a37b7dc3b9232c27eec1a6ea51f4eeb57d38793c Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 19:59:04 -0400
Subject: [PATCH 003/130] opencv: update to 4.7.0.
---
common/shlibs | 104 ++++++++++++++++++++--------------------
srcpkgs/opencv/template | 8 ++--
2 files changed, 56 insertions(+), 56 deletions(-)
diff --git a/common/shlibs b/common/shlibs
index d650f2a3045d..4626cfda810b 100644
--- a/common/shlibs
+++ b/common/shlibs
@@ -2137,58 +2137,58 @@ libcapstone.so.4 capstone-4.0_1
libhavege.so.2 libhaveged-1.9.11_1
libnih.so.1 libnih-1.0.3_1
libnih-dbus.so.1 libnih-1.0.3_1
-libopencv_quality.so.406 libopencv-4.6.0_1
-libopencv_reg.so.406 libopencv-4.6.0_1
-libopencv_surface_matching.so.406 libopencv-4.6.0_1
-libopencv_xphoto.so.406 libopencv-4.6.0_1
-libopencv_freetype.so.406 libopencv-4.6.0_1
-libopencv_fuzzy.so.406 libopencv-4.6.0_1
-libopencv_hfs.so.406 libopencv-4.6.0_1
-libopencv_img_hash.so.406 libopencv-4.6.0_1
-libopencv_line_descriptor.so.406 libopencv-4.6.0_1
-libopencv_saliency.so.406 libopencv-4.6.0_1
-libopencv_structured_light.so.406 libopencv-4.6.0_1
-libopencv_aruco.so.406 libopencv-4.6.0_1
-libopencv_bgsegm.so.406 libopencv-4.6.0_1
-libopencv_bioinspired.so.406 libopencv-4.6.0_1
-libopencv_ccalib.so.406 libopencv-4.6.0_1
-libopencv_face.so.406 libopencv-4.6.0_1
-libopencv_tracking.so.406 libopencv-4.6.0_1
-libopencv_xfeatures2d.so.406 libopencv-4.6.0_1
-libopencv_optflow.so.406 libopencv-4.6.0_1
-libopencv_ximgproc.so.406 libopencv-4.6.0_1
-libopencv_plot.so.406 libopencv-4.6.0_1
-libopencv_text.so.406 libopencv-4.6.0_1
-libopencv_ml.so.406 libopencv-4.6.0_1
-libopencv_objdetect.so.406 libopencv-4.6.0_1
-libopencv_dnn.so.406 libopencv-4.6.0_1
-libopencv_shape.so.406 libopencv-4.6.0_1
-libopencv_stitching.so.406 libopencv-4.6.0_1
-libopencv_photo.so.406 libopencv-4.6.0_1
-libopencv_video.so.406 libopencv-4.6.0_1
-libopencv_calib3d.so.406 libopencv-4.6.0_1
-libopencv_features2d.so.406 libopencv-4.6.0_1
-libopencv_flann.so.406 libopencv-4.6.0_1
-libopencv_highgui.so.406 libopencv-4.6.0_1
-libopencv_videoio.so.406 libopencv-4.6.0_1
-libopencv_imgcodecs.so.406 libopencv-4.6.0_1
-libopencv_imgproc.so.406 libopencv-4.6.0_1
-libopencv_core.so.406 libopencv-4.6.0_1
-libopencv_superres.so.406 libopencv-4.6.0_1
-libopencv_videostab.so.406 libopencv-4.6.0_1
-libopencv_gapi.so.406 libopencv-4.6.0_1
-libopencv_xobjdetect.so.406 libopencv-4.6.0_1
-libopencv_datasets.so.406 libopencv-4.6.0_1
-libopencv_dnn_objdetect.so.406 libopencv-4.6.0_1
-libopencv_dnn_superres.so.406 libopencv-4.6.0_1
-libopencv_dpm.so.406 libopencv-4.6.0_1
-libopencv_phase_unwrapping.so.406 libopencv-4.6.0_1
-libopencv_stereo.so.406 libopencv-4.6.0_1
-libopencv_rapid.so.406 libopencv-4.6.0_1
-libopencv_intensity_transform.so.406 libopencv-4.6.0_1
-libopencv_alphamat.so.406 libopencv-4.6.0_1
-libopencv_barcode.so.406 libopencv-4.6.0_1
-libopencv_mcc.so.406 libopencv-4.6.0_1
+libopencv_quality.so.407 libopencv-4.7.0_1
+libopencv_reg.so.407 libopencv-4.7.0_1
+libopencv_surface_matching.so.407 libopencv-4.7.0_1
+libopencv_xphoto.so.407 libopencv-4.7.0_1
+libopencv_freetype.so.407 libopencv-4.7.0_1
+libopencv_fuzzy.so.407 libopencv-4.7.0_1
+libopencv_hfs.so.407 libopencv-4.7.0_1
+libopencv_img_hash.so.407 libopencv-4.7.0_1
+libopencv_line_descriptor.so.407 libopencv-4.7.0_1
+libopencv_saliency.so.407 libopencv-4.7.0_1
+libopencv_structured_light.so.407 libopencv-4.7.0_1
+libopencv_aruco.so.407 libopencv-4.7.0_1
+libopencv_bgsegm.so.407 libopencv-4.7.0_1
+libopencv_bioinspired.so.407 libopencv-4.7.0_1
+libopencv_ccalib.so.407 libopencv-4.7.0_1
+libopencv_face.so.407 libopencv-4.7.0_1
+libopencv_tracking.so.407 libopencv-4.7.0_1
+libopencv_xfeatures2d.so.407 libopencv-4.7.0_1
+libopencv_optflow.so.407 libopencv-4.7.0_1
+libopencv_ximgproc.so.407 libopencv-4.7.0_1
+libopencv_plot.so.407 libopencv-4.7.0_1
+libopencv_text.so.407 libopencv-4.7.0_1
+libopencv_ml.so.407 libopencv-4.7.0_1
+libopencv_objdetect.so.407 libopencv-4.7.0_1
+libopencv_dnn.so.407 libopencv-4.7.0_1
+libopencv_shape.so.407 libopencv-4.7.0_1
+libopencv_stitching.so.407 libopencv-4.7.0_1
+libopencv_photo.so.407 libopencv-4.7.0_1
+libopencv_video.so.407 libopencv-4.7.0_1
+libopencv_calib3d.so.407 libopencv-4.7.0_1
+libopencv_features2d.so.407 libopencv-4.7.0_1
+libopencv_flann.so.407 libopencv-4.7.0_1
+libopencv_highgui.so.407 libopencv-4.7.0_1
+libopencv_videoio.so.407 libopencv-4.7.0_1
+libopencv_imgcodecs.so.407 libopencv-4.7.0_1
+libopencv_imgproc.so.407 libopencv-4.7.0_1
+libopencv_core.so.407 libopencv-4.7.0_1
+libopencv_superres.so.407 libopencv-4.7.0_1
+libopencv_videostab.so.407 libopencv-4.7.0_1
+libopencv_gapi.so.407 libopencv-4.7.0_1
+libopencv_xobjdetect.so.407 libopencv-4.7.0_1
+libopencv_datasets.so.407 libopencv-4.7.0_1
+libopencv_dnn_objdetect.so.407 libopencv-4.7.0_1
+libopencv_dnn_superres.so.407 libopencv-4.7.0_1
+libopencv_dpm.so.407 libopencv-4.7.0_1
+libopencv_phase_unwrapping.so.407 libopencv-4.7.0_1
+libopencv_stereo.so.407 libopencv-4.7.0_1
+libopencv_rapid.so.407 libopencv-4.7.0_1
+libopencv_intensity_transform.so.407 libopencv-4.7.0_1
+libopencv_alphamat.so.407 libopencv-4.7.0_1
+libopencv_barcode.so.407 libopencv-4.7.0_1
+libopencv_mcc.so.407 libopencv-4.7.0_1
libuniconf.so.4.6 wvstreams-4.6.1_20
libwvbase.so.4.6 wvstreams-4.6.1_20
libwvutils.so.4.6 wvstreams-4.6.1_20
diff --git a/srcpkgs/opencv/template b/srcpkgs/opencv/template
index 69c635b1ad2b..41f3183f1582 100644
--- a/srcpkgs/opencv/template
+++ b/srcpkgs/opencv/template
@@ -1,7 +1,7 @@
# Template file for 'opencv'
pkgname=opencv
-version=4.6.0
-revision=4
+version=4.7.0
+revision=1
create_wrksrc=yes
build_wrksrc=${pkgname}-${version}
build_style=cmake
@@ -24,8 +24,8 @@ homepage="https://opencv.org"
changelog="https://github.com/opencv/opencv/wiki/ChangeLog"
distfiles="https://github.com/opencv/opencv/archive/${version}.tar.gz
https://github.com/opencv/opencv_contrib/archive/${version}.tar.gz>contrib.tar.gz"
-checksum="1ec1cba65f9f20fe5a41fda1586e01c70ea0c9a6d7b67c9e13edf0cfe2239277
- 1777d5fd2b59029cf537e5fd6f8aa68d707075822f90bde683fcde086f85f7a7"
+checksum="8df0079cdbe179748a18d44731af62a245a45ebf5085223dc03133954c662973
+ 42df840cf9055e59d0e22c249cfb19f04743e1bdad113d31b1573d3934d62584"
patch_args="-Np1 -d ${build_wrksrc}"
# tests hang indenfinitely, even with test data included
make_check=no
From a5e4379112147403f438aa80abd927ef981d6622 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 19:59:45 -0400
Subject: [PATCH 004/130] actiona: revbump for opencv-4.7.0
---
srcpkgs/actiona/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/actiona/template b/srcpkgs/actiona/template
index cf5f0b7a2ae6..0d899311e6df 100644
--- a/srcpkgs/actiona/template
+++ b/srcpkgs/actiona/template
@@ -1,7 +1,7 @@
# Template file for 'actiona'
pkgname=actiona
version=3.10.1
-revision=2
+revision=3
build_style=qmake
configure_args="PKGCONFIG_OPENCV=opencv4"
hostmakedepends="pkg-config qt5-plugin-mysql qt5-qmake qt5-host-tools"
From 05bfd896fff01a798a900405963c7b3d715aad3f Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 19:59:45 -0400
Subject: [PATCH 005/130] gmic: revbump for opencv-4.7.0
---
srcpkgs/gmic/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/gmic/template b/srcpkgs/gmic/template
index 24a9c7218fdf..0bb4034d5cc8 100644
--- a/srcpkgs/gmic/template
+++ b/srcpkgs/gmic/template
@@ -1,7 +1,7 @@
# Template file for 'gmic'
pkgname=gmic
version=3.1.6
-revision=3
+revision=4
_zart_hash=34ebf6cce0bafb98abe57cec83c4a02cd1abeca0
create_wrksrc=yes
build_wrksrc="src"
From d62b8494305bd86f25fd3bb637aab62c58d7077d Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 19:59:46 -0400
Subject: [PATCH 006/130] qimgv: revbump for opencv-4.7.0
---
srcpkgs/qimgv/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/qimgv/template b/srcpkgs/qimgv/template
index 7eb30db33992..dd341dfe1bfc 100644
--- a/srcpkgs/qimgv/template
+++ b/srcpkgs/qimgv/template
@@ -1,7 +1,7 @@
# Template file for 'qimgv'
pkgname=qimgv
version=1.0.2
-revision=2
+revision=3
build_style=cmake
configure_args="$(vopt_if video -DVIDEO_SUPPORT=ON -DVIDEO_SUPPORT=OFF)
$(vopt_if scale -DOPENCV_SUPPORT=ON -DOPENCV_SUPPORT=OFF)
From 137e1c39f6e9311d5484ac6a2862e7a7d306ec5b Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 19:59:46 -0400
Subject: [PATCH 007/130] retroshare: revbump for opencv-4.7.0
---
srcpkgs/retroshare/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/retroshare/template b/srcpkgs/retroshare/template
index 8a0786c21a08..72023fa98b75 100644
--- a/srcpkgs/retroshare/template
+++ b/srcpkgs/retroshare/template
@@ -1,7 +1,7 @@
# Template file for 'retroshare'
pkgname=retroshare
version=0.6.6
-revision=2
+revision=4
build_style=qmake
#XXX broadcast feature requires an ancient udp-discovery-cpp which either needs
# to be fetched+patched (FTBFS) here or packaged :/
From c6c67ed88de0e31a68b4641d938e6e1b4622c14d Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 19:59:46 -0400
Subject: [PATCH 008/130] siril: revbump for opencv-4.7.0
---
srcpkgs/siril/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/siril/template b/srcpkgs/siril/template
index e88f30fb6178..84332f79d060 100644
--- a/srcpkgs/siril/template
+++ b/srcpkgs/siril/template
@@ -1,7 +1,7 @@
# Template file for 'siril'
pkgname=siril
version=0.9.12
-revision=9
+revision=10
build_style=gnu-configure
hostmakedepends="pkg-config intltool autoconf automake gettext-devel"
makedepends="fftw-devel libconfig-devel libopencv-devel libffms2-devel
From a466efdc189d9cf3c2808a23e4ea227fa0e2779c Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 19:59:46 -0400
Subject: [PATCH 009/130] waifu2x-converter-cpp: revbump for opencv-4.7.0
---
srcpkgs/waifu2x-converter-cpp/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/waifu2x-converter-cpp/template b/srcpkgs/waifu2x-converter-cpp/template
index 8c095d0d7bab..aa52d8c981a8 100644
--- a/srcpkgs/waifu2x-converter-cpp/template
+++ b/srcpkgs/waifu2x-converter-cpp/template
@@ -1,7 +1,7 @@
# Template file for 'waifu2x-converter-cpp'
pkgname=waifu2x-converter-cpp
version=5.2.4
-revision=2
+revision=3
build_style=cmake
configure_args="-DINSTALL_MODELS=ON"
hostmakedepends="pkg-config"
From cce1f5df16330e2aa15321c5a09a318f9837f102 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:00:38 -0400
Subject: [PATCH 010/130] vlc: revbump for ffmpeg4-4.4.3
---
srcpkgs/vlc/template | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/srcpkgs/vlc/template b/srcpkgs/vlc/template
index 210762b0a7e2..855ca5238662 100644
--- a/srcpkgs/vlc/template
+++ b/srcpkgs/vlc/template
@@ -1,7 +1,7 @@
# Template file for 'vlc'
pkgname=vlc
version=3.0.18
-revision=3
+revision=4
build_style=gnu-configure
configure_args="--disable-gme --disable-libtar --enable-jack
--enable-live555 --disable-fluidsynth --enable-dvdread
@@ -25,7 +25,7 @@ lib32disabled=yes
hostmakedepends="automake libtool pkg-config flex gettext libgcrypt-devel
live555-devel gettext-devel $(vopt_if lua lua52) $(vopt_if chromecast protobuf)"
makedepends="
- avahi-libs-devel dbus-glib-devel faad2-devel ffmpeg-devel freefont-ttf
+ avahi-libs-devel dbus-glib-devel faad2-devel ffmpeg4-devel freefont-ttf
gnutls-devel jack-devel liba52-devel libass-devel libbluray-devel
libcdio-devel libdca-devel libdvbpsi-devel libdvdnav-devel libmad-devel
libmatroska-devel libmodplug-devel libmpcdec-devel libmpeg2-devel
From e2766771b4ed2de122cd5c9c1a0b60d0a76c14e4 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:00:55 -0400
Subject: [PATCH 011/130] osg: revbump for ffmpeg4-4.4.3
---
srcpkgs/osg/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/osg/template b/srcpkgs/osg/template
index a9ebbd287933..755793f7e11b 100644
--- a/srcpkgs/osg/template
+++ b/srcpkgs/osg/template
@@ -8,7 +8,7 @@ build_helper="qemu"
configure_args="-DLIB_POSTFIX="
hostmakedepends="pkg-config xrandr"
makedepends="MesaLib-devel gtkglext-devel libcurl-devel giflib-devel librsvg-devel
- jasper-devel tiff-devel libgdal-devel libgta-devel ffmpeg-devel xine-lib-devel
+ jasper-devel tiff-devel libgdal-devel libgta-devel ffmpeg4-devel xine-lib-devel
SDL2-devel gst-plugins-base1-devel
$(vopt_if openexr libopenexr-devel)
$(vopt_if poppler poppler-glib-devel)
From 29df97a8351c4cdfab145c8bb6c69988666472ca Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:13 -0400
Subject: [PATCH 012/130] xine-lib: revbump for ffmpeg4-4.4.3
---
srcpkgs/xine-lib/template | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/srcpkgs/xine-lib/template b/srcpkgs/xine-lib/template
index f713eff49b07..ed6194c17d11 100644
--- a/srcpkgs/xine-lib/template
+++ b/srcpkgs/xine-lib/template
@@ -1,6 +1,6 @@
# Template file for 'xine-lib'
pkgname=xine-lib
-version=1.2.12
+version=1.2.13
revision=1
build_style=gnu-configure
configure_args="--disable-vcd --disable-gnomevfs --without-esound --disable-dxr3
@@ -8,7 +8,7 @@ configure_args="--disable-vcd --disable-gnomevfs --without-esound --disable-dxr3
hostmakedepends="automake gettext-devel libtool pkg-config perl"
makedepends="
zlib-devel alsa-lib-devel libxcb-devel libSM-devel libXext-devel libXv-devel
- libXvMC-devel liba52-devel libmad-devel ffmpeg-devel pulseaudio-devel
+ libXvMC-devel liba52-devel libmad-devel ffmpeg4-devel pulseaudio-devel
jack-devel samba-devel libflac-devel libmodplug-devel libmpcdec-devel
speex-devel libtheora-devel libvorbis-devel libdca-devel faad2-devel
libcdio-devel libbluray-devel aalib-devel libcaca-devel libXinerama-devel
@@ -19,7 +19,7 @@ license="GPL-2.0-or-later, LGPL-2.0-or-later"
homepage="http://www.xine-project.org"
changelog="https://sourceforge.net/projects/xine/files/xine-lib/${version}/README.txt/view"
distfiles="${SOURCEFORGE_SITE}/xine/${pkgname}-${version}.tar.xz"
-checksum=d606270468e1540c2a89c0d7f5fdf11e17ecc0c2698cc0bcb1065ff26abee098
+checksum=5f10d6d718a4a51c17ed1b32b031d4f9b80b061e8276535b2be31e5ac4b75e6f
case "$XBPS_TARGET_MACHINE" in
i686-musl)
From 19ba661d425f89507e21f1f51a3457017a466dad Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:45 -0400
Subject: [PATCH 013/130] QMPlay2: revbump for ffmpeg-6.0
---
srcpkgs/QMPlay2/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/QMPlay2/template b/srcpkgs/QMPlay2/template
index ad73cbb01bae..55284c051161 100644
--- a/srcpkgs/QMPlay2/template
+++ b/srcpkgs/QMPlay2/template
@@ -1,7 +1,7 @@
# Template file for 'QMPlay2'
pkgname=QMPlay2
version=23.02.05
-revision=1
+revision=2
build_style=cmake
hostmakedepends="pkg-config qt5-qmake qt5-host-tools"
makedepends="alsa-lib-devel ffmpeg-devel libass-devel libcdio-devel libgme-devel
From a036167ecaf89a5beee24f7c6497d0b266397a2e Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:45 -0400
Subject: [PATCH 014/130] alsa-plugins: revbump for ffmpeg-6.0
---
srcpkgs/alsa-plugins/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/alsa-plugins/template b/srcpkgs/alsa-plugins/template
index 0bfa6d9fd264..a5708a7d82a8 100644
--- a/srcpkgs/alsa-plugins/template
+++ b/srcpkgs/alsa-plugins/template
@@ -1,7 +1,7 @@
# Template file for 'alsa-plugins'
pkgname=alsa-plugins
version=1.2.7.1
-revision=1
+revision=2
build_style=gnu-configure
configure_args="--disable-maemo-plugin"
hostmakedepends="pkg-config"
From 71313b3619befcb430917e14d4be820cb6219a4c Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:45 -0400
Subject: [PATCH 015/130] arcan: revbump for ffmpeg-6.0
---
srcpkgs/arcan/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/arcan/template b/srcpkgs/arcan/template
index 7be9652eccf3..ccc7df11ceac 100644
--- a/srcpkgs/arcan/template
+++ b/srcpkgs/arcan/template
@@ -2,7 +2,7 @@
# !! keep synced with: acfgfs aclip aloadimage
pkgname=arcan
version=0.6.2.1
-revision=1
+revision=2
create_wrksrc=yes
build_wrksrc=arcan/src
build_style=cmake
From edfdcc4efccb5f8152479ff34033e60d3f72fb88 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:45 -0400
Subject: [PATCH 016/130] attract: revbump for ffmpeg4-4.4.3
---
srcpkgs/attract/template | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/srcpkgs/attract/template b/srcpkgs/attract/template
index 26144e931a3c..e760bf0d18ae 100644
--- a/srcpkgs/attract/template
+++ b/srcpkgs/attract/template
@@ -1,12 +1,12 @@
# Template file for 'attract'
pkgname=attract
version=2.6.2
-revision=1
+revision=2
build_style=gnu-makefile
make_build_args="VERBOSE=1"
make_use_env=yes
hostmakedepends="pkg-config"
-makedepends="SFML-devel ffmpeg-devel fontconfig-devel glu-devel libarchive-devel
+makedepends="SFML-devel ffmpeg4-devel fontconfig-devel glu-devel libarchive-devel
libcurl-devel libjpeg-turbo-devel xine-lib rapidjson libXrandr-devel"
depends="git"
short_desc="Attract-Mode is a graphical frontend for emulators"
From 725d65813cb50a7906166422dbd529480e42b699 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:45 -0400
Subject: [PATCH 017/130] aubio: revbump for ffmpeg-6.0
---
srcpkgs/aubio/patches/ffmpeg5.patch | 25 +++++++++++++++++++++++++
srcpkgs/aubio/template | 2 +-
2 files changed, 26 insertions(+), 1 deletion(-)
create mode 100644 srcpkgs/aubio/patches/ffmpeg5.patch
diff --git a/srcpkgs/aubio/patches/ffmpeg5.patch b/srcpkgs/aubio/patches/ffmpeg5.patch
new file mode 100644
index 000000000000..aace41a6e6d9
--- /dev/null
+++ b/srcpkgs/aubio/patches/ffmpeg5.patch
@@ -0,0 +1,25 @@
+From 8a05420e5dd8c7b8b2447f82dc919765876511b3 Mon Sep 17 00:00:00 2001
+From: Paul Brossier <piem@piem.org>
+Date: Tue, 25 Jan 2022 18:30:27 +0100
+Subject: [PATCH] [source_avcodec] define FF_API_LAVF_AVCTX for libavcodec >
+ 59, thx @berolinux (closes gh-353)
+
+---
+ src/io/source_avcodec.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/src/io/source_avcodec.c b/src/io/source_avcodec.c
+index e0ae93b5..1421bd9a 100644
+--- a/src/io/source_avcodec.c
++++ b/src/io/source_avcodec.c
+@@ -68,6 +68,10 @@
+ #define AUBIO_AVCODEC_MAX_BUFFER_SIZE AV_INPUT_BUFFER_MIN_SIZE
+ #endif
+
++#if LIBAVCODEC_VERSION_MAJOR >= 59
++#define FF_API_LAVF_AVCTX 1
++#endif
++
+ struct _aubio_source_avcodec_t {
+ uint_t hop_size;
+ uint_t samplerate;
diff --git a/srcpkgs/aubio/template b/srcpkgs/aubio/template
index ad1c4b256991..7d875cc02541 100644
--- a/srcpkgs/aubio/template
+++ b/srcpkgs/aubio/template
@@ -1,7 +1,7 @@
# Template file for 'aubio'
pkgname=aubio
version=0.4.9
-revision=1
+revision=2
build_style=waf3
# XXX lash, pure and swig support.
hostmakedepends="pkg-config txt2man"
From cbef04e99d5e823be93500c2d87d96dac3a64d83 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:45 -0400
Subject: [PATCH 018/130] audacious-plugins: revbump for ffmpeg-6.0
---
.../audacious-plugins/patches/ffmpeg5.patch | 43 +++++++++++++++++++
srcpkgs/audacious-plugins/template | 2 +-
2 files changed, 44 insertions(+), 1 deletion(-)
create mode 100644 srcpkgs/audacious-plugins/patches/ffmpeg5.patch
diff --git a/srcpkgs/audacious-plugins/patches/ffmpeg5.patch b/srcpkgs/audacious-plugins/patches/ffmpeg5.patch
new file mode 100644
index 000000000000..4e5e34099d71
--- /dev/null
+++ b/srcpkgs/audacious-plugins/patches/ffmpeg5.patch
@@ -0,0 +1,43 @@
+commit 298aa371c56c2f52c25a33d9bdec4918b11cebdc
+Author: tibequadorian <tibequadorian@posteo.de>
+Date: Sat Mar 19 18:40:12 2022 +0100
+
+ audacious-plugins: rebuild against ffmpeg-5.0
+
+diff --git a/srcpkgs/audacious-plugins/patches/ffmpeg-5.0.patch b/srcpkgs/audacious-plugins/patches/ffmpeg-5.0.patch
+new file mode 100644
+index 0000000000..617c11215b
+--- /dev/null
++++ b/srcpkgs/audacious-plugins/patches/ffmpeg-5.0.patch
+@@ -0,0 +1,31 @@
++From f60beb400eeb1e4778bbfd738bc4a4ccef3de539 Mon Sep 17 00:00:00 2001
++From: John Lindgren <john@jlindgren.net>
++Date: Sat, 5 Mar 2022 12:05:34 -0500
++Subject: [PATCH] Fix build with FFmpeg 5.0
++
++---
++ src/ffaudio/ffaudio-core.cc | 4 ++--
++ 1 file changed, 2 insertions(+), 2 deletions(-)
++
++diff --git a/src/ffaudio/ffaudio-core.cc b/src/ffaudio/ffaudio-core.cc
++index 16dc63e3a..a2b95fd6c 100644
++--- a/src/ffaudio/ffaudio-core.cc
+++++ b/src/ffaudio/ffaudio-core.cc
++@@ -274,7 +274,7 @@ static AVInputFormat * get_format_by_content (const char * name, VFSFile & file)
++ AVProbeData d = {name, buf, filled};
++ score = target;
++
++- f = av_probe_input_format2 (& d, true, & score);
+++ f = (AVInputFormat *) av_probe_input_format2 (& d, true, & score);
++ if (f)
++ break;
++
++@@ -347,7 +347,7 @@ static bool find_codec (AVFormatContext * c, CodecInfo * cinfo)
++ #endif
++ if (stream && stream->codecpar && stream->codecpar->codec_type == AVMEDIA_TYPE_AUDIO)
++ {
++- AVCodec * codec = avcodec_find_decoder (stream->codecpar->codec_id);
+++ AVCodec * codec = (AVCodec *) avcodec_find_decoder (stream->codecpar->codec_id);
++
++ if (codec)
++ {
diff --git a/srcpkgs/audacious-plugins/template b/srcpkgs/audacious-plugins/template
index 88cbc1671fc6..beebfae59ed4 100644
--- a/srcpkgs/audacious-plugins/template
+++ b/srcpkgs/audacious-plugins/template
@@ -2,7 +2,7 @@
#Keep in sync with audacious!
pkgname=audacious-plugins
version=4.3.1
-revision=1
+revision=2
build_style=meson
configure_args="$(vopt_bool gtk3 gtk) $(vopt_bool gtk3)
$(vopt_bool qt) $(vopt_bool qt qt6)"
From 61fc7ecac20a36de2c43bddee7f2a9f61c6f30c2 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:45 -0400
Subject: [PATCH 019/130] audacity: revbump for ffmpeg4-4.4.3
---
srcpkgs/audacity/template | 5 ++---
1 file changed, 2 insertions(+), 3 deletions(-)
diff --git a/srcpkgs/audacity/template b/srcpkgs/audacity/template
index d509c0a89407..11e20255685b 100644
--- a/srcpkgs/audacity/template
+++ b/srcpkgs/audacity/template
@@ -1,7 +1,7 @@
# Template file for 'audacity'
pkgname=audacity
version=2.4.1
-revision=2
+revision=3
build_style=gnu-configure
configure_args="--with-ffmpeg=system --with-libsndfile=system --with-expat=system
--with-libsoxr=system --with-lame=system --with-lv2=system ac_cv_path_WX_CONFIG=wx-config-gtk3"
@@ -9,7 +9,7 @@ hostmakedepends="pkg-config cmake gettext libtool m4 which"
makedepends="jack-devel wxWidgets-gtk3-devel gtk+3-devel
libmad-devel soundtouch-devel libsoxr-devel
vamp-plugin-sdk-devel lame-devel libid3tag-devel libflac-devel
- ffmpeg-devel twolame-devel serd-devel lv2 lilv-devel suil-devel"
+ ffmpeg4-devel twolame-devel serd-devel lv2 lilv-devel suil-devel"
depends="desktop-file-utils hicolor-icon-theme"
short_desc="Graphical cross-platform audio editor"
maintainer="Orphaned <orphan@voidlinux.org>"
@@ -33,5 +33,4 @@ post_install() {
vcopy plug-ins /usr/share/audacity
rm ${DESTDIR}/usr/share/doc/audacity/LICENSE.txt
- vlicense LICENSE.txt LICENSE
}
From 296fd03bcbf8752a17ecf531c97a24c235274c9a Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:45 -0400
Subject: [PATCH 020/130] avidemux: revbump for ffmpeg-6.0
---
srcpkgs/avidemux/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/avidemux/template b/srcpkgs/avidemux/template
index 253a0243e225..557285982d2b 100644
--- a/srcpkgs/avidemux/template
+++ b/srcpkgs/avidemux/template
@@ -1,7 +1,7 @@
# Template file for 'avidemux'
pkgname=avidemux
version=2.8.0
-revision=2
+revision=3
# Can't be compiled for aarch64, arm* or mips*
archs="x86_64* i686*"
hostmakedepends="cmake pkg-config qt5-host-tools qt5-devel tar yasm"
From 73dcf788fb8b320e948fb3d71fd93cb0be5385ff Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:45 -0400
Subject: [PATCH 021/130] baresip: revbump for ffmpeg-6.0
---
srcpkgs/baresip/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/baresip/template b/srcpkgs/baresip/template
index f1bd1817048b..b21e22334316 100644
--- a/srcpkgs/baresip/template
+++ b/srcpkgs/baresip/template
@@ -1,7 +1,7 @@
# Template file for 'baresip'
pkgname=baresip
version=2.10.0
-revision=1
+revision=2
build_style=cmake
hostmakedepends="pkg-config glib-devel"
makedepends="libgsm-devel libpng-devel openssl-devel libsndfile-devel
From 7905b028d86519937d46df8bd45ca577f56a7651 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:46 -0400
Subject: [PATCH 022/130] blender: revbump for ffmpeg-6.0
---
.../patches/ffmpeg6-compat-blender.patch | 42 +++++++++++++++++++
srcpkgs/blender/template | 2 +-
2 files changed, 43 insertions(+), 1 deletion(-)
create mode 100644 srcpkgs/blender/patches/ffmpeg6-compat-blender.patch
diff --git a/srcpkgs/blender/patches/ffmpeg6-compat-blender.patch b/srcpkgs/blender/patches/ffmpeg6-compat-blender.patch
new file mode 100644
index 000000000000..d51a9c7710cc
--- /dev/null
+++ b/srcpkgs/blender/patches/ffmpeg6-compat-blender.patch
@@ -0,0 +1,42 @@
+--- a/source/blender/blenkernel/intern/writeffmpeg.c 2022-11-08 13:50:16 UTC
++++ b/source/blender/blenkernel/intern/writeffmpeg.c
+@@ -855,7 +855,7 @@ static AVStream *alloc_video_stream(FFMpegContext *con
+ 255);
+ st->avg_frame_rate = av_inv_q(c->time_base);
+
+- if (codec->capabilities & AV_CODEC_CAP_AUTO_THREADS) {
++ if (codec->capabilities & AV_CODEC_CAP_OTHER_THREADS) {
+ c->thread_count = 0;
+ }
+ else {
+--- a/source/blender/imbuf/intern/anim_movie.c 2022-11-04 00:33:07 UTC
++++ b/source/blender/imbuf/intern/anim_movie.c
+@@ -554,7 +554,7 @@ static int startffmpeg(struct anim *anim)
+ avcodec_parameters_to_context(pCodecCtx, video_stream->codecpar);
+ pCodecCtx->workaround_bugs = FF_BUG_AUTODETECT;
+
+- if (pCodec->capabilities & AV_CODEC_CAP_AUTO_THREADS) {
++ if (pCodec->capabilities & AV_CODEC_CAP_OTHER_THREADS) {
+ pCodecCtx->thread_count = 0;
+ }
+ else {
+--- a/source/blender/imbuf/intern/indexer.c 2022-11-04 00:33:07 UTC
++++ b/source/blender/imbuf/intern/indexer.c
+@@ -559,7 +559,7 @@ static struct proxy_output_ctx *alloc_proxy_output_ffm
+ av_dict_set(&codec_opts, "preset", "veryfast", 0);
+ av_dict_set(&codec_opts, "tune", "fastdecode", 0);
+
+- if (rv->codec->capabilities & AV_CODEC_CAP_AUTO_THREADS) {
++ if (rv->codec->capabilities & AV_CODEC_CAP_OTHER_THREADS) {
+ rv->c->thread_count = 0;
+ }
+ else {
+@@ -872,7 +872,7 @@ static IndexBuildContext *index_ffmpeg_create_context(
+ avcodec_parameters_to_context(context->iCodecCtx, context->iStream->codecpar);
+ context->iCodecCtx->workaround_bugs = FF_BUG_AUTODETECT;
+
+- if (context->iCodec->capabilities & AV_CODEC_CAP_AUTO_THREADS) {
++ if (context->iCodec->capabilities & AV_CODEC_CAP_OTHER_THREADS) {
+ context->iCodecCtx->thread_count = 0;
+ }
+ else {
diff --git a/srcpkgs/blender/template b/srcpkgs/blender/template
index 61b42eb2e51e..d18bc88838ff 100644
--- a/srcpkgs/blender/template
+++ b/srcpkgs/blender/template
@@ -1,7 +1,7 @@
# Template file for 'blender'
pkgname=blender
version=3.4.1
-revision=3
+revision=4
archs="x86_64* ppc64*"
build_style="cmake"
pycompile_dirs="/usr/share/blender/${version%.*}/scripts"
From a14bbcbc848ff877c99294bfbd66f0b6bcdc3a88 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:46 -0400
Subject: [PATCH 023/130] cantata: revbump for ffmpeg-6.0
---
srcpkgs/cantata/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/cantata/template b/srcpkgs/cantata/template
index 4b417d80d5c2..8a90aaa4c07a 100644
--- a/srcpkgs/cantata/template
+++ b/srcpkgs/cantata/template
@@ -1,7 +1,7 @@
# Template file for 'cantata'
pkgname=cantata
version=2.5.0
-revision=1
+revision=2
build_style=cmake
hostmakedepends="pkg-config qt5-qmake qt5-host-tools qt5-tools"
makedepends="qt5-devel qt5-tools-devel qt5-svg-devel qt5-xmlpatterns-devel
From f8dc3f795958bb41f5c7ccdbefde6eb7c9758a89 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:46 -0400
Subject: [PATCH 024/130] ccextractor: revbump for ffmpeg4-4.4.3
---
srcpkgs/ccextractor/template | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/srcpkgs/ccextractor/template b/srcpkgs/ccextractor/template
index 9abcd82852b2..6eccad5885af 100644
--- a/srcpkgs/ccextractor/template
+++ b/srcpkgs/ccextractor/template
@@ -1,12 +1,12 @@
# Template file for 'ccextractor'
pkgname=ccextractor
version=0.93
-revision=1
+revision=2
build_wrksrc="linux"
build_style=gnu-configure
configure_args="--enable-ocr --enable-hardsubx"
hostmakedepends="automake pkg-config"
-makedepends="leptonica-devel tesseract-ocr-devel ffmpeg-devel"
+makedepends="leptonica-devel tesseract-ocr-devel ffmpeg4-devel"
short_desc="Extract subtitles from video streams"
maintainer="newbluemoon <blaumolch@mailbox.org>"
license="GPL-2.0-or-later"
From 75fd1ea953931e5e7f50d6cb6a2caac1578d6c90 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:46 -0400
Subject: [PATCH 025/130] chromaprint: revbump for ffmpeg-6.0
---
srcpkgs/chromaprint/patches/ffmpeg5.patch | 569 ++++++++++++++++++++++
srcpkgs/chromaprint/template | 2 +-
2 files changed, 570 insertions(+), 1 deletion(-)
create mode 100644 srcpkgs/chromaprint/patches/ffmpeg5.patch
diff --git a/srcpkgs/chromaprint/patches/ffmpeg5.patch b/srcpkgs/chromaprint/patches/ffmpeg5.patch
new file mode 100644
index 000000000000..a9fd307a23c8
--- /dev/null
+++ b/srcpkgs/chromaprint/patches/ffmpeg5.patch
@@ -0,0 +1,569 @@
+From 8ccad6937177b1b92e40ab8f4447ea27bac009a7 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Luk=C3=A1=C5=A1=20Lalinsk=C3=BD?= <lalinsky@gmail.com>
+Date: Fri, 4 Nov 2022 21:47:38 +0100
+Subject: [PATCH] Use FFmpeg 5.x (#120)
+
+* Use FFmpeg 5.1.2 for CI builds
+
+* Build on Ubuntu 20.04
+
+* Upgrade code to FFmpeg 5.x APIs
+
+* Only set FFmpeg include dirs if building tools
+
+* No longer needed
+
+* Use ubuntu 20.04
+---
+ .github/workflows/build.yml | 6 +-
+ CMakeLists.txt | 16 --
+ package/build.sh | 4 +-
+ src/audio/ffmpeg_audio_processor.h | 2 -
+ src/audio/ffmpeg_audio_processor_avresample.h | 72 -------
+ src/audio/ffmpeg_audio_processor_swresample.h | 18 +-
+ src/audio/ffmpeg_audio_reader.h | 197 +++++++++---------
+ tests/CMakeLists.txt | 6 +
+ 8 files changed, 122 insertions(+), 199 deletions(-)
+ delete mode 100644 src/audio/ffmpeg_audio_processor_avresample.h
+
+diff --git a/CMakeLists.txt b/CMakeLists.txt
+index f8d6a32..4da2405 100644
+--- a/CMakeLists.txt
++++ b/CMakeLists.txt
+@@ -84,9 +84,6 @@ find_package(FFmpeg)
+ if(FFMPEG_LIBRARIES)
+ cmake_push_check_state(RESET)
+ set(CMAKE_REQUIRED_LIBRARIES ${FFMPEG_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT} -lm)
+- check_function_exists(av_packet_unref HAVE_AV_PACKET_UNREF)
+- check_function_exists(av_frame_alloc HAVE_AV_FRAME_ALLOC)
+- check_function_exists(av_frame_free HAVE_AV_FRAME_FREE)
+ cmake_pop_check_state()
+ endif()
+
+@@ -163,14 +160,11 @@ message(STATUS "Using ${FFT_LIB} for FFT calculations")
+ if(NOT AUDIO_PROCESSOR_LIB)
+ if(FFMPEG_LIBSWRESAMPLE_FOUND)
+ set(AUDIO_PROCESSOR_LIB "swresample")
+- elseif(FFMPEG_LIBAVRESAMPLE_FOUND)
+- set(AUDIO_PROCESSOR_LIB "avresample")
+ endif()
+ endif()
+
+ if(AUDIO_PROCESSOR_LIB STREQUAL "swresample")
+ if(FFMPEG_LIBSWRESAMPLE_FOUND)
+- set(USE_AVRESAMPLE OFF)
+ set(USE_SWRESAMPLE ON)
+ set(AUDIO_PROCESSOR_LIBRARIES ${FFMPEG_LIBSWRESAMPLE_LIBRARIES})
+ set(AUDIO_PROCESSOR_INCLUDE_DIRS ${FFMPEG_LIBSWRESAMPLE_INCLUDE_DIRS})
+@@ -178,16 +172,6 @@ if(AUDIO_PROCESSOR_LIB STREQUAL "swresample")
+ message(FATAL_ERROR "Selected ${AUDIO_PROCESSOR_LIB} for audio processing, but the library is not found")
+ endif()
+ message(STATUS "Using ${AUDIO_PROCESSOR_LIB} for audio conversion")
+-elseif(AUDIO_PROCESSOR_LIB STREQUAL "avresample")
+- if(FFMPEG_LIBAVRESAMPLE_FOUND)
+- set(USE_AVRESAMPLE ON)
+- set(USE_SWRESAMPLE OFF)
+- set(AUDIO_PROCESSOR_LIBRARIES ${FFMPEG_LIBAVRESAMPLE_LIBRARIES})
+- set(AUDIO_PROCESSOR_INCLUDE_DIRS ${FFMPEG_LIBAVRESAMPLE_INCLUDE_DIRS})
+- else()
+- message(FATAL_ERROR "Selected ${AUDIO_PROCESSOR_LIB} for audio processing, but the library is not found")
+- endif()
+- message(STATUS "Using ${AUDIO_PROCESSOR_LIB} for audio conversion")
+ else()
+ message(STATUS "Building without audio conversion support, please install FFmpeg with libswresample")
+ endif()
+diff --git a/package/build.sh b/package/build.sh
+index da631ae..b41d36e 100755
+--- a/package/build.sh
++++ b/package/build.sh
+@@ -7,8 +7,8 @@ set -eux
+
+ BASE_DIR=$(cd $(dirname $0)/.. && pwd)
+
+-FFMPEG_VERSION=4.4.1
+-FFMPEG_BUILD_TAG=v4.4.1-1
++FFMPEG_VERSION=5.1.2
++FFMPEG_BUILD_TAG=v${FFMPEG_VERSION}-1
+
+ TMP_BUILD_DIR=$BASE_DIR/$(mktemp -d build.XXXXXXXX)
+ trap 'rm -rf $TMP_BUILD_DIR' EXIT
+diff --git a/src/audio/ffmpeg_audio_processor.h b/src/audio/ffmpeg_audio_processor.h
+index 7628fc7..39f4f6d 100644
+--- a/src/audio/ffmpeg_audio_processor.h
++++ b/src/audio/ffmpeg_audio_processor.h
+@@ -10,8 +10,6 @@
+
+ #if defined(USE_SWRESAMPLE)
+ #include "audio/ffmpeg_audio_processor_swresample.h"
+-#elif defined(USE_AVRESAMPLE)
+-#include "audio/ffmpeg_audio_processor_avresample.h"
+ #else
+ #error "no audio processing library"
+ #endif
+diff --git a/src/audio/ffmpeg_audio_processor_avresample.h b/src/audio/ffmpeg_audio_processor_avresample.h
+deleted file mode 100644
+index bd85f92..0000000
+--- a/src/audio/ffmpeg_audio_processor_avresample.h
++++ /dev/null
+@@ -1,72 +0,0 @@
+-// Copyright (C) 2016 Lukas Lalinsky
+-// Distributed under the MIT license, see the LICENSE file for details.
+-
+-#ifndef CHROMAPRINT_AUDIO_FFMPEG_AUDIO_PROCESSOR_AVRESAMPLE_H_
+-#define CHROMAPRINT_AUDIO_FFMPEG_AUDIO_PROCESSOR_AVRESAMPLE_H_
+-
+-extern "C" {
+-#include <libavresample/avresample.h>
+-}
+-
+-namespace chromaprint {
+-
+-class FFmpegAudioProcessor {
+-public:
+- FFmpegAudioProcessor() {
+- m_resample_ctx = avresample_alloc_context();
+- }
+-
+- ~FFmpegAudioProcessor() {
+- avresample_free(&m_resample_ctx);
+- }
+-
+- void SetCompatibleMode() {
+- av_opt_set_int(m_resample_ctx, "filter_size", 16, 0);
+- av_opt_set_int(m_resample_ctx, "phase_shift", 8, 0);
+- av_opt_set_int(m_resample_ctx, "linear_interp", 1, 0);
+- av_opt_set_double(m_resample_ctx, "cutoff", 0.8, 0);
+- }
+-
+- void SetInputChannelLayout(int64_t channel_layout) {
+- av_opt_set_int(m_resample_ctx, "in_channel_layout", channel_layout, 0);
+- }
+-
+- void SetInputSampleFormat(AVSampleFormat sample_format) {
+- av_opt_set_int(m_resample_ctx, "in_sample_fmt", sample_format, 0);
+- }
+-
+- void SetInputSampleRate(int sample_rate) {
+- av_opt_set_int(m_resample_ctx, "in_sample_rate", sample_rate, 0);
+- }
+-
+- void SetOutputChannelLayout(int64_t channel_layout) {
+- av_opt_set_int(m_resample_ctx, "out_channel_layout", channel_layout, 0);
+- }
+-
+- void SetOutputSampleFormat(AVSampleFormat sample_format) {
+- av_opt_set_int(m_resample_ctx, "out_sample_fmt", sample_format, 0);
+- }
+-
+- void SetOutputSampleRate(int sample_rate) {
+- av_opt_set_int(m_resample_ctx, "out_sample_fmt", sample_rate, 0);
+- }
+-
+- int Init() {
+- return avresample_open(m_resample_ctx);
+- }
+-
+- int Convert(uint8_t **out, int out_count, const uint8_t **in, int in_count) {
+- return avresample_convert(m_resample_ctx, out, 0, out_count, (uint8_t **) in, 0, in_count);
+- }
+-
+- int Flush(uint8_t **out, int out_count) {
+- return avresample_read(m_resample_ctx, out, out_count);
+- }
+-
+-private:
+- AVAudioResampleContext *m_resample_ctx = nullptr;
+-};
+-
+-}; // namespace chromaprint
+-
+-#endif
+diff --git a/src/audio/ffmpeg_audio_processor_swresample.h b/src/audio/ffmpeg_audio_processor_swresample.h
+index b86266b..b1d4bea 100644
+--- a/src/audio/ffmpeg_audio_processor_swresample.h
++++ b/src/audio/ffmpeg_audio_processor_swresample.h
+@@ -28,30 +28,28 @@ public:
+ av_opt_set_double(m_swr_ctx, "cutoff", 0.8, 0);
+ }
+
+- void SetInputChannelLayout(int64_t channel_layout) {
+- av_opt_set_int(m_swr_ctx, "icl", channel_layout, 0);
+- av_opt_set_int(m_swr_ctx, "ich", av_get_channel_layout_nb_channels(channel_layout), 0);
++ void SetInputChannelLayout(AVChannelLayout *channel_layout) {
++ av_opt_set_int(m_swr_ctx, "in_channel_layout", channel_layout->u.mask, 0);
+ }
+
+ void SetInputSampleFormat(AVSampleFormat sample_format) {
+- av_opt_set_int(m_swr_ctx, "isf", sample_format, 0);
++ av_opt_set_sample_fmt(m_swr_ctx, "in_sample_fmt", sample_format, 0);
+ }
+
+ void SetInputSampleRate(int sample_rate) {
+- av_opt_set_int(m_swr_ctx, "isr", sample_rate, 0);
++ av_opt_set_int(m_swr_ctx, "in_sample_rate", sample_rate, 0);
+ }
+
+- void SetOutputChannelLayout(int64_t channel_layout) {
+- av_opt_set_int(m_swr_ctx, "ocl", channel_layout, 0);
+- av_opt_set_int(m_swr_ctx, "och", av_get_channel_layout_nb_channels(channel_layout), 0);
++ void SetOutputChannelLayout(AVChannelLayout *channel_layout) {
++ av_opt_set_int(m_swr_ctx, "out_channel_layout", channel_layout->u.mask, 0);
+ }
+
+ void SetOutputSampleFormat(AVSampleFormat sample_format) {
+- av_opt_set_int(m_swr_ctx, "osf", sample_format, 0);
++ av_opt_set_sample_fmt(m_swr_ctx, "out_sample_fmt", sample_format, 0);
+ }
+
+ void SetOutputSampleRate(int sample_rate) {
+- av_opt_set_int(m_swr_ctx, "osr", sample_rate, 0);
++ av_opt_set_int(m_swr_ctx, "out_sample_rate", sample_rate, 0);
+ }
+
+ int Init() {
+diff --git a/src/audio/ffmpeg_audio_reader.h b/src/audio/ffmpeg_audio_reader.h
+index 5550164..1c6b346 100644
+--- a/src/audio/ffmpeg_audio_reader.h
++++ b/src/audio/ffmpeg_audio_reader.h
+@@ -62,7 +62,7 @@ public:
+ bool Read(const int16_t **data, size_t *size);
+
+ bool IsOpen() const { return m_opened; }
+- bool IsFinished() const { return m_finished && !m_got_frame; }
++ bool IsFinished() const { return !m_has_more_packets && !m_has_more_frames; }
+
+ std::string GetError() const { return m_error; }
+ int GetErrorCode() const { return m_error_code; }
+@@ -74,20 +74,19 @@ private:
+ uint8_t *m_convert_buffer[1] = { nullptr };
+ int m_convert_buffer_nb_samples = 0;
+
+- AVInputFormat *m_input_fmt = nullptr;
++ const AVInputFormat *m_input_fmt = nullptr;
+ AVDictionary *m_input_opts = nullptr;
+
+ AVFormatContext *m_format_ctx = nullptr;
+ AVCodecContext *m_codec_ctx = nullptr;
+- AVFrame *m_frame = nullptr;
+ int m_stream_index = -1;
+ std::string m_error;
+ int m_error_code = 0;
+- bool m_finished = false;
+ bool m_opened = false;
+- int m_got_frame = 0;
+- AVPacket m_packet;
+- AVPacket m_packet0;
++ bool m_has_more_packets = true;
++ bool m_has_more_frames = true;
++ AVPacket *m_packet = nullptr;
++ AVFrame *m_frame = nullptr;
+
+ int m_output_sample_rate = 0;
+ int m_output_channels = 0;
+@@ -98,19 +97,12 @@ private:
+
+ inline FFmpegAudioReader::FFmpegAudioReader() {
+ av_log_set_level(AV_LOG_QUIET);
+-
+- av_init_packet(&m_packet);
+- m_packet.data = nullptr;
+- m_packet.size = 0;
+-
+- m_packet0 = m_packet;
+ }
+
+ inline FFmpegAudioReader::~FFmpegAudioReader() {
+ Close();
+ av_dict_free(&m_input_opts);
+ av_freep(&m_convert_buffer[0]);
+- av_packet_unref(&m_packet0);
+ }
+
+ inline bool FFmpegAudioReader::SetInputFormat(const char *name) {
+@@ -135,11 +127,10 @@ inline bool FFmpegAudioReader::Open(const std::string &file_name) {
+
+ Close();
+
+- av_init_packet(&m_packet);
+- m_packet.data = nullptr;
+- m_packet.size = 0;
+-
+- m_packet0 = m_packet;
++ m_packet = av_packet_alloc();
++ if (!m_packet) {
++ return false;
++ }
+
+ ret = avformat_open_input(&m_format_ctx, file_name.c_str(), m_input_fmt, &m_input_opts);
+ if (ret < 0) {
+@@ -153,26 +144,31 @@ inline bool FFmpegAudioReader::Open(const std::string &file_name) {
+ return false;
+ }
+
+- AVCodec *codec;
++ const AVCodec *codec;
+ ret = av_find_best_stream(m_format_ctx, AVMEDIA_TYPE_AUDIO, -1, -1, &codec, 0);
+ if (ret < 0) {
+ SetError("Could not find any audio stream in the file", ret);
+ return false;
+ }
+ m_stream_index = ret;
++ auto stream = m_format_ctx->streams[m_stream_index];
+
+- m_codec_ctx = m_format_ctx->streams[m_stream_index]->codec;
++ m_codec_ctx = avcodec_alloc_context3(codec);
+ m_codec_ctx->request_sample_fmt = AV_SAMPLE_FMT_S16;
+
++ ret = avcodec_parameters_to_context(m_codec_ctx, stream->codecpar);
++ if (ret < 0) {
++ SetError("Could not copy the stream parameters", ret);
++ return false;
++ }
++
+ ret = avcodec_open2(m_codec_ctx, codec, nullptr);
+ if (ret < 0) {
+ SetError("Could not open the codec", ret);
+ return false;
+ }
+
+- if (!m_codec_ctx->channel_layout) {
+- m_codec_ctx->channel_layout = av_get_default_channel_layout(m_codec_ctx->channels);
+- }
++ av_dump_format(m_format_ctx, 0, "foo", 0);
+
+ m_frame = av_frame_alloc();
+ if (!m_frame) {
+@@ -183,19 +179,23 @@ inline bool FFmpegAudioReader::Open(const std::string &file_name) {
+ m_output_sample_rate = m_codec_ctx->sample_rate;
+ }
+
+- if (!m_output_channels) {
+- m_output_channels = m_codec_ctx->channels;
++ AVChannelLayout output_channel_layout;
++ if (m_output_channels) {
++ av_channel_layout_default(&output_channel_layout, m_output_channels);
++ } else {
++ m_output_channels = m_codec_ctx->ch_layout.nb_channels;
++ av_channel_layout_default(&output_channel_layout, m_output_channels);
+ }
+
+- if (m_codec_ctx->sample_fmt != AV_SAMPLE_FMT_S16 || m_codec_ctx->channels != m_output_channels || m_codec_ctx->sample_rate != m_output_sample_rate) {
++ if (m_codec_ctx->sample_fmt != AV_SAMPLE_FMT_S16 || m_codec_ctx->ch_layout.nb_channels != m_output_channels || m_codec_ctx->sample_rate != m_output_sample_rate) {
+ m_converter.reset(new FFmpegAudioProcessor());
+ m_converter->SetCompatibleMode();
+ m_converter->SetInputSampleFormat(m_codec_ctx->sample_fmt);
+ m_converter->SetInputSampleRate(m_codec_ctx->sample_rate);
+- m_converter->SetInputChannelLayout(m_codec_ctx->channel_layout);
++ m_converter->SetInputChannelLayout(&(m_codec_ctx->ch_layout));
+ m_converter->SetOutputSampleFormat(AV_SAMPLE_FMT_S16);
+ m_converter->SetOutputSampleRate(m_output_sample_rate);
+- m_converter->SetOutputChannelLayout(av_get_default_channel_layout(m_output_channels));
++ m_converter->SetOutputChannelLayout(&output_channel_layout);
+ auto ret = m_converter->Init();
+ if (ret != 0) {
+ SetError("Could not create an audio converter instance", ret);
+@@ -203,10 +203,11 @@ inline bool FFmpegAudioReader::Open(const std::string &file_name) {
+ }
+ }
+
++ av_channel_layout_uninit(&output_channel_layout);
++
+ m_opened = true;
+- m_finished = false;
+- m_got_frame = 0;
+- m_nb_packets = 0;
++ m_has_more_packets = true;
++ m_has_more_frames = true;
+ m_decode_error = 0;
+
+ return true;
+@@ -214,6 +215,7 @@ inline bool FFmpegAudioReader::Open(const std::string &file_name) {
+
+ inline void FFmpegAudioReader::Close() {
+ av_frame_free(&m_frame);
++ av_packet_free(&m_packet);
+
+ m_stream_index = -1;
+
+@@ -252,91 +254,98 @@ inline bool FFmpegAudioReader::Read(const int16_t **data, size_t *size) {
+ return false;
+ }
+
++ *data = nullptr;
++ *size = 0;
++
+ int ret;
++ bool needs_packet = false;
+ while (true) {
+- while (m_packet.size <= 0) {
+- av_packet_unref(&m_packet0);
+- av_init_packet(&m_packet);
+- m_packet.data = nullptr;
+- m_packet.size = 0;
+- ret = av_read_frame(m_format_ctx, &m_packet);
++ while (needs_packet && m_packet->size == 0) {
++ ret = av_read_frame(m_format_ctx, m_packet);
+ if (ret < 0) {
+ if (ret == AVERROR_EOF) {
+- m_finished = true;
++ needs_packet = false;
++ m_has_more_packets = false;
+ break;
+- } else {
++ }
++ SetError("Error reading from the audio source", ret);
++ return false;
++ }
++ if (m_packet->stream_index == m_stream_index) {
++ needs_packet = false;
++ } else {
++ av_packet_unref(m_packet);
++ }
++ }
++
++ if (m_packet->size != 0) {
++ ret = avcodec_send_packet(m_codec_ctx, m_packet);
++ if (ret < 0) {
++ if (ret != AVERROR(EAGAIN)) {
+ SetError("Error reading from the audio source", ret);
+ return false;
+ }
+- }
+- m_packet0 = m_packet;
+- if (m_packet.stream_index != m_stream_index) {
+- m_packet.data = nullptr;
+- m_packet.size = 0;
+ } else {
+- m_nb_packets++;
++ av_packet_unref(m_packet);
+ }
+ }
+
+- ret = avcodec_decode_audio4(m_codec_ctx, m_frame, &m_got_frame, &m_packet);
++ ret = avcodec_receive_frame(m_codec_ctx, m_frame);
+ if (ret < 0) {
+- if (m_decode_error) {
+- SetError("Error decoding audio frame", m_decode_error);
+- return false;
++ if (ret == AVERROR_EOF) {
++ m_has_more_frames = false;
++ } else if (ret == AVERROR(EAGAIN)) {
++ if (m_has_more_packets) {
++ needs_packet = true;
++ continue;
++ } else {
++ m_has_more_frames = false;
++ }
+ }
+- m_decode_error = ret;
+- m_packet.data = nullptr;
+- m_packet.size = 0;
+- continue;
++ SetError("Error decoding the audio source", ret);
++ return false;
+ }
+
+- break;
+- }
+-
+- m_decode_error = 0;
+-
+- const int decoded = std::min(ret, m_packet.size);
+- m_packet.data += decoded;
+- m_packet.size -= decoded;
+-
+- if (m_got_frame) {
+- if (m_converter) {
+- if (m_frame->nb_samples > m_convert_buffer_nb_samples) {
+- int linsize;
+- av_freep(&m_convert_buffer[0]);
+- m_convert_buffer_nb_samples = std::max(1024 * 8, m_frame->nb_samples);
+- ret = av_samples_alloc(m_convert_buffer, &linsize, m_codec_ctx->channels, m_convert_buffer_nb_samples, AV_SAMPLE_FMT_S16, 1);
+- if (ret < 0) {
+- SetError("Couldn't allocate audio converter buffer", ret);
++ if (m_frame->nb_samples > 0) {
++ if (m_converter) {
++ if (m_frame->nb_samples > m_convert_buffer_nb_samples) {
++ int linsize;
++ av_freep(&m_convert_buffer[0]);
++ m_convert_buffer_nb_samples = std::max(1024 * 8, m_frame->nb_samples);
++ ret = av_samples_alloc(m_convert_buffer, &linsize, m_codec_ctx->ch_layout.nb_channels, m_convert_buffer_nb_samples, AV_SAMPLE_FMT_S16, 1);
++ if (ret < 0) {
++ SetError("Couldn't allocate audio converter buffer", ret);
++ return false;
++ }
++ }
++ auto nb_samples = m_converter->Convert(m_convert_buffer, m_convert_buffer_nb_samples, (const uint8_t **) m_frame->data, m_frame->nb_samples);
++ if (nb_samples < 0) {
++ SetError("Couldn't convert audio", ret);
+ return false;
+ }
+- }
+- auto nb_samples = m_converter->Convert(m_convert_buffer, m_convert_buffer_nb_samples, (const uint8_t **) m_frame->data, m_frame->nb_samples);
+- if (nb_samples < 0) {
+- SetError("Couldn't convert audio", ret);
+- return false;
+- }
+- *data = (const int16_t *) m_convert_buffer[0];
+- *size = nb_samples;
+- } else {
+- *data = (const int16_t *) m_frame->data[0];
+- *size = m_frame->nb_samples;
+- }
+- } else {
+- if (m_finished && m_converter) {
+- auto nb_samples = m_converter->Flush(m_convert_buffer, m_convert_buffer_nb_samples);
+- if (nb_samples < 0) {
+- SetError("Couldn't convert audio", ret);
+- return false;
+- } else if (nb_samples > 0) {
+- m_got_frame = 1;
+ *data = (const int16_t *) m_convert_buffer[0];
+ *size = nb_samples;
++ } else {
++ *data = (const int16_t *) m_frame->data[0];
++ *size = m_frame->nb_samples;
++ }
++ } else {
++ if (m_converter) {
++ if (IsFinished()) {
++ auto nb_samples = m_converter->Flush(m_convert_buffer, m_convert_buffer_nb_samples);
++ if (nb_samples < 0) {
++ SetError("Couldn't convert audio", ret);
++ return false;
++ } else if (nb_samples > 0) {
++ *data = (const int16_t *) m_convert_buffer[0];
++ *size = nb_samples;
++ }
++ }
+ }
+ }
+- }
+
+- return true;
++ return true;
++ }
+ }
+
+ inline void FFmpegAudioReader::SetError(const char *message, int errnum) {
+diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt
+index a2b517b..123e643 100644
+--- a/tests/CMakeLists.txt
++++ b/tests/CMakeLists.txt
+@@ -38,6 +38,12 @@ set(SRCS
+
+ if(BUILD_TOOLS)
+ set(SRCS ${SRCS} ../src/audio/ffmpeg_audio_reader_test.cpp)
++ include_directories(
++ ${FFMPEG_LIBAVFORMAT_INCLUDE_DIRS}
++ ${FFMPEG_LIBAVCODEC_INCLUDE_DIRS}
++ ${FFMPEG_LIBAVUTIL_INCLUDE_DIRS}
++ ${AUDIO_PROCESSOR_INCLUDE_DIRS}
++ )
+ link_libraries(fpcalc_libs)
+ endif()
+
+--
+2.38.1
+
+
diff --git a/srcpkgs/chromaprint/template b/srcpkgs/chromaprint/template
index 7ef7838949f3..1f7bbc70a22c 100644
--- a/srcpkgs/chromaprint/template
+++ b/srcpkgs/chromaprint/template
@@ -1,7 +1,7 @@
# Template file for 'chromaprint'
pkgname=chromaprint
version=1.5.1
-revision=1
+revision=2
build_style=cmake
configure_args="-DBUILD_TOOLS=ON"
make_check_target="check"
From eb19570c7a6ab93c60217915c0365a599d4935a2 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:46 -0400
Subject: [PATCH 026/130] chromium: revbump for ffmpeg-6.0
---
.../patches/chromium-93-ffmpeg-4.4.patch | 36 --------------
srcpkgs/chromium/patches/ffmpeg5.patch | 47 +++++++++++++++++++
srcpkgs/chromium/template | 2 +-
3 files changed, 48 insertions(+), 37 deletions(-)
delete mode 100644 srcpkgs/chromium/patches/chromium-93-ffmpeg-4.4.patch
create mode 100644 srcpkgs/chromium/patches/ffmpeg5.patch
diff --git a/srcpkgs/chromium/patches/chromium-93-ffmpeg-4.4.patch b/srcpkgs/chromium/patches/chromium-93-ffmpeg-4.4.patch
deleted file mode 100644
index f0ec736f98bc..000000000000
--- a/srcpkgs/chromium/patches/chromium-93-ffmpeg-4.4.patch
+++ /dev/null
@@ -1,36 +0,0 @@
-diff --git a/media/filters/ffmpeg_demuxer.cc b/media/filters/ffmpeg_demuxer.cc
-index ac4713b07268..492a9a37d096 100644
---- a/media/filters/ffmpeg_demuxer.cc
-+++ b/media/filters/ffmpeg_demuxer.cc
-@@ -427,11 +427,11 @@ void FFmpegDemuxerStream::EnqueuePacket(ScopedAVPacket packet) {
- scoped_refptr<DecoderBuffer> buffer;
-
- if (type() == DemuxerStream::TEXT) {
-- size_t id_size = 0;
-+ int id_size = 0;
- uint8_t* id_data = av_packet_get_side_data(
- packet.get(), AV_PKT_DATA_WEBVTT_IDENTIFIER, &id_size);
-
-- size_t settings_size = 0;
-+ int settings_size = 0;
- uint8_t* settings_data = av_packet_get_side_data(
- packet.get(), AV_PKT_DATA_WEBVTT_SETTINGS, &settings_size);
-
-@@ -443,7 +443,7 @@ void FFmpegDemuxerStream::EnqueuePacket(ScopedAVPacket packet) {
- buffer = DecoderBuffer::CopyFrom(packet->data, packet->size,
- side_data.data(), side_data.size());
- } else {
-- size_t side_data_size = 0;
-+ int side_data_size = 0;
- uint8_t* side_data = av_packet_get_side_data(
- packet.get(), AV_PKT_DATA_MATROSKA_BLOCKADDITIONAL, &side_data_size);
-
-@@ -504,7 +504,7 @@ void FFmpegDemuxerStream::EnqueuePacket(ScopedAVPacket packet) {
- packet->size - data_offset);
- }
-
-- size_t skip_samples_size = 0;
-+ int skip_samples_size = 0;
- const uint32_t* skip_samples_ptr =
- reinterpret_cast<const uint32_t*>(av_packet_get_side_data(
- packet.get(), AV_PKT_DATA_SKIP_SAMPLES, &skip_samples_size));
diff --git a/srcpkgs/chromium/patches/ffmpeg5.patch b/srcpkgs/chromium/patches/ffmpeg5.patch
new file mode 100644
index 000000000000..24e2da38e34c
--- /dev/null
+++ b/srcpkgs/chromium/patches/ffmpeg5.patch
@@ -0,0 +1,47 @@
+--- a/media/filters/ffmpeg_demuxer.cc 2023-01-23 17:33:57.366213805 +0200
++++ b/media/filters/ffmpeg_demuxer.cc 2023-01-23 17:43:09.283436983 +0200
+@@ -92,24 +92,12 @@
+
+ static base::TimeDelta ExtractStartTime(AVStream* stream) {
+ // The default start time is zero.
+- base::TimeDelta start_time;
++ base::TimeDelta start_time = kNoTimestamp;
+
+ // First try to use the |start_time| value as is.
+- if (stream->start_time != kNoFFmpegTimestamp)
++ if (stream->start_time != kNoFFmpegTimestamp) // AV_NOPTS_VALUE
+ start_time = ConvertFromTimeBase(stream->time_base, stream->start_time);
+
+- // Next try to use the first DTS value, for codecs where we know PTS == DTS
+- // (excludes all H26x codecs). The start time must be returned in PTS.
+- if (av_stream_get_first_dts(stream) != kNoFFmpegTimestamp &&
+- stream->codecpar->codec_id != AV_CODEC_ID_HEVC &&
+- stream->codecpar->codec_id != AV_CODEC_ID_H264 &&
+- stream->codecpar->codec_id != AV_CODEC_ID_MPEG4) {
+- const base::TimeDelta first_pts =
+- ConvertFromTimeBase(stream->time_base, av_stream_get_first_dts(stream));
+- if (first_pts < start_time)
+- start_time = first_pts;
+- }
+-
+ return start_time;
+ }
+
+@@ -1597,7 +1585,7 @@
+ for (const auto& stream : streams_) {
+ if (!stream || stream->IsEnabled() != enabled)
+ continue;
+- if (av_stream_get_first_dts(stream->av_stream()) == kInvalidPTSMarker)
++ if (stream->av_stream()->start_time == AV_NOPTS_VALUE)
+ continue;
+ if (!lowest_start_time_stream ||
+ stream->start_time() < lowest_start_time_stream->start_time()) {
+@@ -1618,7 +1606,7 @@
+ if (stream->type() != DemuxerStream::VIDEO)
+ continue;
+
+- if (av_stream_get_first_dts(stream->av_stream()) == kInvalidPTSMarker)
++ if (stream->av_stream()->start_time == AV_NOPTS_VALUE)
+ continue;
+
+ if (!stream->IsEnabled())
diff --git a/srcpkgs/chromium/template b/srcpkgs/chromium/template
index e50c739d3ee7..8705f2ef973f 100644
--- a/srcpkgs/chromium/template
+++ b/srcpkgs/chromium/template
@@ -2,7 +2,7 @@
pkgname=chromium
# See https://chromiumdash.appspot.com/releases?platform=Linux for the latest version
version=112.0.5615.49
-revision=1
+revision=2
archs="i686* x86_64* aarch64* armv7l*"
hostmakedepends="
$(vopt_if clang "clang lld llvm15")
From e01500d5608ba5cb9213e41f7ee470d7a5dc8f06 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:46 -0400
Subject: [PATCH 027/130] cmus: revbump for ffmpeg-6.0
---
srcpkgs/cmus/patches/ffmpeg6.patch | 12 ++++++++++++
srcpkgs/cmus/template | 2 +-
2 files changed, 13 insertions(+), 1 deletion(-)
create mode 100644 srcpkgs/cmus/patches/ffmpeg6.patch
diff --git a/srcpkgs/cmus/patches/ffmpeg6.patch b/srcpkgs/cmus/patches/ffmpeg6.patch
new file mode 100644
index 000000000000..ffa95ab81110
--- /dev/null
+++ b/srcpkgs/cmus/patches/ffmpeg6.patch
@@ -0,0 +1,12 @@
+--- a/ip/ffmpeg.c
++++ b/ip/ffmpeg.c
+@@ -202,9 +202,6 @@ static int ffmpeg_open(struct input_plugin_data *ip_data)
+ break;
+ }
+
+- if (codec->capabilities & AV_CODEC_CAP_TRUNCATED)
+- cc->flags |= AV_CODEC_FLAG_TRUNCATED;
+-
+ if (avcodec_open2(cc, codec, NULL) < 0) {
+ d_print("could not open codec: %d, %s\n", cc->codec_id, avcodec_get_name(cc->codec_id));
+ err = -IP_ERROR_UNSUPPORTED_FILE_TYPE;
diff --git a/srcpkgs/cmus/template b/srcpkgs/cmus/template
index 0fcb424ce336..05b77d0fecae 100644
--- a/srcpkgs/cmus/template
+++ b/srcpkgs/cmus/template
@@ -1,7 +1,7 @@
# Template file for 'cmus'
pkgname=cmus
version=2.10.0
-revision=1
+revision=2
build_style=configure
configure_args="prefix=/usr LD=$CC"
hostmakedepends="pkg-config"
From 7609997ec323c747e5543052e405ad2631b8047a Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:46 -0400
Subject: [PATCH 028/130] cyanrip: revbump for ffmpeg-6.0
---
srcpkgs/cyanrip/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/cyanrip/template b/srcpkgs/cyanrip/template
index 9796e3461601..5db30e020d17 100644
--- a/srcpkgs/cyanrip/template
+++ b/srcpkgs/cyanrip/template
@@ -1,7 +1,7 @@
# Template file for 'cyanrip'
pkgname=cyanrip
version=0.9.0
-revision=1
+revision=2
build_style=meson
hostmakedepends="pkg-config"
makedepends="ffmpeg-devel libcdio-devel libcdio-paranoia-devel libcurl-devel libmusicbrainz5-devel"
From f395f56ece2ed434cfb69583c6355f9f786529ab Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:46 -0400
Subject: [PATCH 029/130] deadbeef: revbump for ffmpeg4-4.4.3
---
srcpkgs/deadbeef/template | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/srcpkgs/deadbeef/template b/srcpkgs/deadbeef/template
index b664bb1b9bd9..165b3c7b9cad 100644
--- a/srcpkgs/deadbeef/template
+++ b/srcpkgs/deadbeef/template
@@ -1,14 +1,14 @@
# Template file for 'deadbeef'
pkgname=deadbeef
version=1.8.8
-revision=1
+revision=2
create_wrksrc=yes
build_style=gnu-configure
configure_args="--disable-oss --disable-lfm --disable-notify --disable-gtk2"
hostmakedepends="automake libtool gettext gettext-devel intltool pkg-config
yasm clang glib-devel"
makedepends="
- alsa-lib-devel dbus-devel faad2-devel ffmpeg-devel gtk+3-devel imlib2-devel
+ alsa-lib-devel dbus-devel faad2-devel ffmpeg4-devel gtk+3-devel imlib2-devel
jansson-devel libcddb-devel libcdio-devel libcurl-devel libflac-devel
libmad-devel libpng-devel libsamplerate-devel libsndfile-devel libvorbis-devel
libzip-devel mpg123-devel opusfile-devel pulseaudio-devel wavpack-devel"
From 043b5a8083a87b33537e057341daf2722a988009 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:46 -0400
Subject: [PATCH 030/130] dolphin-emu: revbump for ffmpeg-6.0
---
srcpkgs/dolphin-emu/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/dolphin-emu/template b/srcpkgs/dolphin-emu/template
index 7ea197ceb2a8..7aeb0a5b645e 100644
--- a/srcpkgs/dolphin-emu/template
+++ b/srcpkgs/dolphin-emu/template
@@ -1,7 +1,7 @@
# Template file for 'dolphin-emu'
pkgname=dolphin-emu
version=5.0.16101
-revision=1
+revision=2
_dolphin_commit=8ecfa537a242de74d2e372e30d9d79b14584b2fb
_mgba_commit=40d4c430fc36caeb7ea32fd39624947ed487d2f2
#Version/hash pair can be found at https://dolphin-emu.org/download/
From 8f0d668dfb5f5ffe45bd9df9a9ae00179480af60 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:46 -0400
Subject: [PATCH 031/130] droidcam-obs-plugin: revbump for ffmpeg-6.0
---
srcpkgs/droidcam-obs-plugin/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/droidcam-obs-plugin/template b/srcpkgs/droidcam-obs-plugin/template
index fc9c9bf6b9d5..fb0480754df4 100644
--- a/srcpkgs/droidcam-obs-plugin/template
+++ b/srcpkgs/droidcam-obs-plugin/template
@@ -1,7 +1,7 @@
# Template file for 'droidcam-obs-plugin'
pkgname=droidcam-obs-plugin
version=2.0.1
-revision=1
+revision=2
build_style=gnu-makefile
make_use_env=yes
make_build_args="ALLOW_STATIC=no"
From 988bd1b50dab15d8f05eb84d4f22bf71a1f91e89 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:46 -0400
Subject: [PATCH 032/130] droidcam: revbump for ffmpeg-6.0
---
srcpkgs/droidcam/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/droidcam/template b/srcpkgs/droidcam/template
index 1c3f1b8b1fc6..32a9220b79a4 100644
--- a/srcpkgs/droidcam/template
+++ b/srcpkgs/droidcam/template
@@ -1,7 +1,7 @@
# Template file for 'droidcam'
pkgname=droidcam
version=1.8.2
-revision=2
+revision=3
build_style=gnu-makefile
make_build_args="USBMUXD=-lusbmuxd-2.0 JPEG=-lturbojpeg"
hostmakedepends="pkg-config"
From 293250be8e924466fa168f937d938cdbc99c8f2b Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:46 -0400
Subject: [PATCH 033/130] electron19: revbump for ffmpeg-6.0
---
srcpkgs/electron19/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/electron19/template b/srcpkgs/electron19/template
index 068136be7623..32ce301e730c 100644
--- a/srcpkgs/electron19/template
+++ b/srcpkgs/electron19/template
@@ -1,7 +1,7 @@
# Template file for 'electron19'
pkgname=electron19
version=19.0.8
-revision=2
+revision=3
_nodever=16.14.2
_chromiumver=102.0.5005.125
archs="x86_64* aarch64* ppc64le*"
From c4b356a9232110e835daad45e661dd51d0eb1507 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:47 -0400
Subject: [PATCH 034/130] ffmpegthumbnailer: revbump for ffmpeg-6.0
---
.../ffmpegthumbnailer/patches/ffmpeg6.patch | 202 ++++++++++++++++++
srcpkgs/ffmpegthumbnailer/template | 6 +-
2 files changed, 205 insertions(+), 3 deletions(-)
create mode 100644 srcpkgs/ffmpegthumbnailer/patches/ffmpeg6.patch
diff --git a/srcpkgs/ffmpegthumbnailer/patches/ffmpeg6.patch b/srcpkgs/ffmpegthumbnailer/patches/ffmpeg6.patch
new file mode 100644
index 000000000000..363ff35a2841
--- /dev/null
+++ b/srcpkgs/ffmpegthumbnailer/patches/ffmpeg6.patch
@@ -0,0 +1,202 @@
+--- a/libffmpegthumbnailer/moviedecoder.cpp 2017-11-21 14:06:57.000000000 -0500
++++ b/libffmpegthumbnailer/moviedecoder.cpp 2023-05-05 13:14:47.946560668 -0400
+@@ -41,11 +41,6 @@
+ namespace ffmpegthumbnailer
+ {
+
+-struct SilenceLogLevel
+-{
+- SilenceLogLevel() { av_log_set_level(AV_LOG_QUIET); }
+-};
+-
+ MovieDecoder::MovieDecoder(AVFormatContext* pavContext)
+ : m_VideoStream(-1)
+ , m_pFormatContext(pavContext)
+@@ -70,8 +65,6 @@
+
+ void MovieDecoder::initialize(const string& filename, bool preferEmbeddedMetadata)
+ {
+- av_register_all();
+- avcodec_register_all();
+ avformat_network_init();
+
+ string inputFile = filename == "-" ? "pipe:" : filename;
+@@ -97,8 +90,7 @@
+ {
+ if (m_pVideoCodecContext)
+ {
+- avcodec_close(m_pVideoCodecContext);
+- m_pVideoCodecContext = nullptr;
++ avcodec_free_context(&m_pVideoCodecContext);
+ }
+
+ if ((!m_FormatContextWasGiven) && m_pFormatContext)
+@@ -152,10 +144,10 @@
+ for (unsigned int i = 0; i < m_pFormatContext->nb_streams; ++i)
+ {
+ AVStream *stream = m_pFormatContext->streams[i];
+- auto ctx = m_pFormatContext->streams[i]->codec;
+- if (ctx->codec_type == AVMEDIA_TYPE_VIDEO)
++ auto par = m_pFormatContext->streams[i]->codecpar;
++ if (par->codec_type == AVMEDIA_TYPE_VIDEO)
+ {
+- if (!preferEmbeddedMetadata || !isStillImageCodec(ctx->codec_id))
++ if (!preferEmbeddedMetadata || !isStillImageCodec(par->codec_id))
+ {
+ videoStreams.push_back(i);
+ continue;
+@@ -203,8 +195,7 @@
+ }
+
+ m_pVideoStream = m_pFormatContext->streams[m_VideoStream];
+- m_pVideoCodecContext = m_pVideoStream->codec;
+- m_pVideoCodec = avcodec_find_decoder(m_pVideoCodecContext->codec_id);
++ m_pVideoCodec = avcodec_find_decoder(m_pVideoStream->codecpar->codec_id);
+
+ if (m_pVideoCodec == nullptr)
+ {
+@@ -214,6 +205,20 @@
+ throw logic_error("Video Codec not found");
+ }
+
++ m_pVideoCodecContext = avcodec_alloc_context3(m_pVideoCodec);
++
++ if (m_pVideoCodecContext == nullptr)
++ {
++ destroy();
++ throw logic_error("Could not allocate video codec context");
++ }
++
++ if (avcodec_parameters_to_context(m_pVideoCodecContext, m_pVideoStream->codecpar) < 0)
++ {
++ destroy();
++ throw logic_error("Could not configure video codec context");
++ }
++
+ m_pVideoCodecContext->workaround_bugs = 1;
+
+ if (avcodec_open2(m_pVideoCodecContext, m_pVideoCodec, nullptr) < 0)
+@@ -386,13 +391,6 @@
+
+ void MovieDecoder::initializeFilterGraph(const AVRational& timeBase, const std::string& size, bool maintainAspectRatio)
+ {
+- static const AVPixelFormat pixelFormats[] = { AV_PIX_FMT_RGB24, AV_PIX_FMT_NONE };
+-
+- auto del = [] (AVBufferSinkParams* p) { av_freep(p); };
+- std::unique_ptr<AVBufferSinkParams, decltype(del)> buffersinkParams(av_buffersink_params_alloc(), del);
+-
+- avfilter_register_all();
+-
+ m_pFilterGraph = avfilter_graph_alloc();
+ assert(m_pFilterGraph);
+
+@@ -404,10 +402,8 @@
+
+ checkRc(avfilter_graph_create_filter(&m_pFilterSource, avfilter_get_by_name("buffer"), "thumb_buffer", ss.str().c_str(), nullptr, m_pFilterGraph),
+ "Failed to create filter source");
+- buffersinkParams->pixel_fmts = pixelFormats;
+- checkRc(avfilter_graph_create_filter(&m_pFilterSink, avfilter_get_by_name("buffersink"), "thumb_buffersink", nullptr, buffersinkParams.get(), m_pFilterGraph),
++ checkRc(avfilter_graph_create_filter(&m_pFilterSink, avfilter_get_by_name("buffersink"), "thumb_buffersink", nullptr, nullptr, m_pFilterGraph),
+ "Failed to create filter sink");
+- buffersinkParams.release();
+
+ AVFilterContext* yadifFilter = nullptr;
+ if (m_pFrame->interlaced_frame != 0)
+@@ -500,15 +496,15 @@
+ }
+
+ checkRc(av_seek_frame(m_pFormatContext, -1, timestamp, 0), "Seeking in video failed");
+- avcodec_flush_buffers(m_pFormatContext->streams[m_VideoStream]->codec);
++ avcodec_flush_buffers(m_pVideoCodecContext);
+
+ int keyFrameAttempts = 0;
+- bool gotFrame = 0;
++ bool gotFrame;
+
+ do
+ {
+ int count = 0;
+- gotFrame = 0;
++ gotFrame = false;
+
+ while (!gotFrame && count < 20)
+ {
+@@ -552,17 +548,33 @@
+ return false;
+ }
+
+- av_frame_unref(m_pFrame);
+-
+- int frameFinished;
++ int rc = avcodec_send_packet(m_pVideoCodecContext, m_pPacket);
++ if(rc == AVERROR(EAGAIN))
++ {
++ rc = 0;
++ }
+
+- int bytesDecoded = avcodec_decode_video2(m_pVideoCodecContext, m_pFrame, &frameFinished, m_pPacket);
+- if (bytesDecoded < 0)
++ if(rc == AVERROR_EOF)
++ {
++ return false;
++ }
++ else if(rc < 0)
+ {
+- throw logic_error("Failed to decode video frame: bytesDecoded < 0");
++ throw logic_error("Failed to decode video frame: avcodec_send_packet() < 0");
+ }
+
+- return frameFinished > 0;
++ rc = avcodec_receive_frame(m_pVideoCodecContext, m_pFrame);
++ switch(rc)
++ {
++ case 0:
++ return true;
++
++ case AVERROR(EAGAIN):
++ return false;
++
++ default:
++ throw logic_error("Failed to decode video frame: avcodec_receive_frame() < 0");
++ }
+ }
+
+ bool MovieDecoder::getVideoPacket()
+@@ -570,8 +582,6 @@
+ bool framesAvailable = true;
+ bool frameDecoded = false;
+
+- int attempts = 0;
+-
+ if (m_pPacket)
+ {
+ av_packet_unref(m_pPacket);
+@@ -580,6 +590,7 @@
+
+ m_pPacket = new AVPacket();
+
++
+ while (framesAvailable && !frameDecoded)
+ {
+ framesAvailable = av_read_frame(m_pFormatContext, m_pPacket) >= 0;
+@@ -644,7 +655,7 @@
+
+ int32_t MovieDecoder::getStreamRotation()
+ {
+- int32_t* matrix = reinterpret_cast<int32_t*>(av_stream_get_side_data(m_pVideoStream, AV_PKT_DATA_DISPLAYMATRIX, nullptr));
++ auto matrix = reinterpret_cast<int32_t*>(av_stream_get_side_data(m_pVideoStream, AV_PKT_DATA_DISPLAYMATRIX, nullptr));
+ if (matrix)
+ {
+ auto angle = lround(av_display_rotation_get(matrix));
+
+--- a/libffmpegthumbnailer/moviedecoder.h 2017-11-12 04:23:38.000000000 -0500
++++ b/libffmpegthumbnailer/moviedecoder.h 2023-05-05 13:26:07.095529911 -0400
+@@ -78,7 +78,7 @@
+ int m_VideoStream;
+ AVFormatContext* m_pFormatContext;
+ AVCodecContext* m_pVideoCodecContext;
+- AVCodec* m_pVideoCodec;
++ const AVCodec* m_pVideoCodec;
+ AVFilterGraph* m_pFilterGraph;
+ AVFilterContext* m_pFilterSource;
+ AVFilterContext* m_pFilterSink;
diff --git a/srcpkgs/ffmpegthumbnailer/template b/srcpkgs/ffmpegthumbnailer/template
index 039eea7622b3..35d546018d12 100644
--- a/srcpkgs/ffmpegthumbnailer/template
+++ b/srcpkgs/ffmpegthumbnailer/template
@@ -1,7 +1,7 @@
# Template file for 'ffmpegthumbnailer'
pkgname=ffmpegthumbnailer
version=2.2.2
-revision=1
+revision=2
build_style=cmake
hostmakedepends="pkg-config"
makedepends="libpng-devel libjpeg-turbo-devel ffmpeg-devel"
@@ -9,8 +9,8 @@ depends="ffmpeg"
short_desc="Lightweight video thumbnailer"
maintainer="Orphaned <orphan@voidlinux.org>"
license="GPL-2.0-or-later"
-homepage="https://github.com/dirkvdb/${pkgname}"
-distfiles="${homepage}/releases/download/${version}/${pkgname}-${version}.tar.bz2"
+homepage="https://github.com/dirkvdb"
+distfiles="${homepage}/${pkgname}/releases/download/${version}/${pkgname}-${version}.tar.bz2"
checksum=1cb24059c38223f657b300c84dd80491b7040d4b69471c4fea69be862bc99b5b
post_install() {
From 918e33d6659ef4a53ddecca8ed6b1c1dabd9f26c Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:47 -0400
Subject: [PATCH 035/130] ffmpegthumbs: revbump for ffmpeg-6.0
---
srcpkgs/ffmpegthumbs/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/ffmpegthumbs/template b/srcpkgs/ffmpegthumbs/template
index 5f0b9414dada..11b88193528f 100644
--- a/srcpkgs/ffmpegthumbs/template
+++ b/srcpkgs/ffmpegthumbs/template
@@ -1,7 +1,7 @@
# Template file for 'ffmpegthumbs'
pkgname=ffmpegthumbs
version=22.12.1
-revision=1
+revision=2
build_style=cmake
hostmakedepends="extra-cmake-modules kcoreaddons kconfig-devel
pkg-config qt5-host-tools qt5-qmake gettext"
From f77ceace89411e604d42a87f18b48e6b08fbd38d Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:47 -0400
Subject: [PATCH 036/130] ffms2: revbump for ffmpeg-6.0
---
srcpkgs/ffms2/patches/ffmpeg5.patch | 424 ++++++++++++++++++++++++++++
srcpkgs/ffms2/template | 2 +-
2 files changed, 425 insertions(+), 1 deletion(-)
create mode 100644 srcpkgs/ffms2/patches/ffmpeg5.patch
diff --git a/srcpkgs/ffms2/patches/ffmpeg5.patch b/srcpkgs/ffms2/patches/ffmpeg5.patch
new file mode 100644
index 000000000000..1479fabcafcb
--- /dev/null
+++ b/srcpkgs/ffms2/patches/ffmpeg5.patch
@@ -0,0 +1,424 @@
+From 45673149e9a2f5586855ad472e3059084eaa36b1 Mon Sep 17 00:00:00 2001
+From: Derek Buitenhuis <derek.buitenhuis@gmail.com>
+Date: Tue, 4 May 2021 14:41:21 +0100
+Subject: [PATCH] Use auto for AVCodec
+
+The geniuses over at FFmpeg decided to constify this API, so old
+versions of the library will return AVCodec *, while new versions
+of the libary will return const AVCodec *, which, in C++, are not
+OK to convert between.
+
+Rather than use some macro hell in ffmscompat.h, we can work around
+this by using auto.
+
+Gross.
+
+Signed-off-by: Derek Buitenhuis <derek.buitenhuis@gmail.com>
+---
+ src/core/audiosource.cpp | 2 +-
+ src/core/indexing.cpp | 6 +++---
+ src/core/videosource.cpp | 2 +-
+ 3 files changed, 5 insertions(+), 5 deletions(-)
+
+diff --git a/src/core/audiosource.cpp b/src/core/audiosource.cpp
+index e4ce97c..ac09666 100644
+--- a/src/core/audiosource.cpp
++++ b/src/core/audiosource.cpp
+@@ -469,7 +469,7 @@ void FFMS_AudioSource::OpenFile() {
+
+ LAVFOpenFile(SourceFile.c_str(), FormatContext, TrackNumber);
+
+- AVCodec *Codec = avcodec_find_decoder(FormatContext->streams[TrackNumber]->codecpar->codec_id);
++ auto *Codec = avcodec_find_decoder(FormatContext->streams[TrackNumber]->codecpar->codec_id);
+ if (Codec == nullptr)
+ throw FFMS_Exception(FFMS_ERROR_DECODING, FFMS_ERROR_CODEC,
+ "Audio codec not found");
+diff --git a/src/core/indexing.cpp b/src/core/indexing.cpp
+index e547c5a..59fb4e8 100644
+--- a/src/core/indexing.cpp
++++ b/src/core/indexing.cpp
+@@ -384,7 +384,7 @@ FFMS_TrackType FFMS_Indexer::GetTrackType(int Track) {
+ }
+
+ const char *FFMS_Indexer::GetTrackCodec(int Track) {
+- AVCodec *codec = avcodec_find_decoder(FormatContext->streams[Track]->codecpar->codec_id);
++ auto *codec = avcodec_find_decoder(FormatContext->streams[Track]->codecpar->codec_id);
+ return codec ? codec->name : nullptr;
+ }
+
+@@ -402,7 +402,7 @@ FFMS_Index *FFMS_Indexer::DoIndexing() {
+ UseDTS);
+
+ if (IndexMask.count(i) && FormatContext->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
+- AVCodec *VideoCodec = avcodec_find_decoder(FormatContext->streams[i]->codecpar->codec_id);
++ auto *VideoCodec = avcodec_find_decoder(FormatContext->streams[i]->codecpar->codec_id);
+ if (!VideoCodec) {
+ FormatContext->streams[i]->discard = AVDISCARD_ALL;
+ IndexMask.erase(i);
+@@ -433,7 +433,7 @@ FFMS_Index *FFMS_Indexer::DoIndexing() {
+ IndexMask.insert(i);
+ }
+ } else if (IndexMask.count(i) && FormatContext->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) {
+- AVCodec *AudioCodec = avcodec_find_decoder(FormatContext->streams[i]->codecpar->codec_id);
++ auto *AudioCodec = avcodec_find_decoder(FormatContext->streams[i]->codecpar->codec_id);
+ if (AudioCodec == nullptr)
+ throw FFMS_Exception(FFMS_ERROR_CODEC, FFMS_ERROR_UNSUPPORTED,
+ "Audio codec not found");
+diff --git a/src/core/videosource.cpp b/src/core/videosource.cpp
+index b889970..8956c22 100644
+--- a/src/core/videosource.cpp
++++ b/src/core/videosource.cpp
+@@ -171,7 +171,7 @@ FFMS_VideoSource::FFMS_VideoSource(const char *SourceFile, FFMS_Index &Index, in
+
+ LAVFOpenFile(SourceFile, FormatContext, VideoTrack);
+
+- AVCodec *Codec = avcodec_find_decoder(FormatContext->streams[VideoTrack]->codecpar->codec_id);
++ auto *Codec = avcodec_find_decoder(FormatContext->streams[VideoTrack]->codecpar->codec_id);
+ if (Codec == nullptr)
+ throw FFMS_Exception(FFMS_ERROR_DECODING, FFMS_ERROR_CODEC,
+ "Video codec not found");
+--
+2.40.0
+
+From 96cbf38ea9381829a1314f432a2c60495dcefaad Mon Sep 17 00:00:00 2001
+From: Derek Buitenhuis <derek.buitenhuis@gmail.com>
+Date: Tue, 4 May 2021 14:12:41 +0100
+Subject: [PATCH] all: Update AVPacket API usage
+
+AVPackets must all be on the heap now, since it is no longer
+part of the libav* ABI.
+
+Signed-off-by: Derek Buitenhuis <derek.buitenhuis@gmail.com>
+---
+ src/core/audiosource.cpp | 16 ++++++----
+ src/core/indexing.cpp | 63 ++++++++++++++++++++++------------------
+ src/core/indexing.h | 4 +--
+ src/core/utils.cpp | 6 ----
+ src/core/utils.h | 1 -
+ src/core/videosource.cpp | 30 ++++++++++---------
+ 6 files changed, 64 insertions(+), 56 deletions(-)
+
+diff --git a/src/core/audiosource.cpp b/src/core/audiosource.cpp
+index 37cf9ae..e4ce97c 100644
+--- a/src/core/audiosource.cpp
++++ b/src/core/audiosource.cpp
+@@ -285,10 +285,15 @@ FFMS_AudioSource::AudioBlock *FFMS_AudioSource::CacheBlock(CacheIterator &pos) {
+ int FFMS_AudioSource::DecodeNextBlock(CacheIterator *pos) {
+ CurrentFrame = &Frames[PacketNumber];
+
+- AVPacket Packet;
+- if (!ReadPacket(&Packet))
++ AVPacket *Packet = av_packet_alloc();
++ if (!Packet)
++ throw FFMS_Exception(FFMS_ERROR_PARSER, FFMS_ERROR_ALLOCATION_FAILED,
++ "Could not allocate packet.");
++ if (!ReadPacket(Packet)) {
++ av_packet_free(&Packet);
+ throw FFMS_Exception(FFMS_ERROR_PARSER, FFMS_ERROR_UNKNOWN,
+ "ReadPacket unexpectedly failed to read a packet");
++ }
+
+ // ReadPacket may have changed the packet number
+ CurrentFrame = &Frames[PacketNumber];
+@@ -297,8 +302,9 @@ int FFMS_AudioSource::DecodeNextBlock(CacheIterator *pos) {
+ int NumberOfSamples = 0;
+ AudioBlock *CachedBlock = nullptr;
+
+- int Ret = avcodec_send_packet(CodecContext, &Packet);
+- av_packet_unref(&Packet);
++ int Ret = avcodec_send_packet(CodecContext, Packet);
++ av_packet_unref(Packet);
++ av_packet_free(&Packet);
+
+ av_frame_unref(DecodeFrame);
+ Ret = avcodec_receive_frame(CodecContext, DecodeFrame);
+@@ -513,8 +519,6 @@ void FFMS_AudioSource::Seek() {
+ }
+
+ bool FFMS_AudioSource::ReadPacket(AVPacket *Packet) {
+- InitNullPacket(*Packet);
+-
+ while (av_read_frame(FormatContext, Packet) >= 0) {
+ if (Packet->stream_index == TrackNumber) {
+ // Required because not all audio packets, especially in ogg, have a pts. Use the previous valid packet's pts instead.
+diff --git a/src/core/indexing.cpp b/src/core/indexing.cpp
+index 23fb95b..e547c5a 100644
+--- a/src/core/indexing.cpp
++++ b/src/core/indexing.cpp
+@@ -320,7 +320,7 @@ void FFMS_Indexer::CheckAudioProperties(int Track, AVCodecContext *Context) {
+ }
+ }
+
+-void FFMS_Indexer::ParseVideoPacket(SharedAVContext &VideoContext, AVPacket &pkt, int *RepeatPict,
++void FFMS_Indexer::ParseVideoPacket(SharedAVContext &VideoContext, AVPacket *pkt, int *RepeatPict,
+ int *FrameType, bool *Invisible, enum AVPictureStructure *LastPicStruct) {
+ if (VideoContext.Parser) {
+ uint8_t *OB;
+@@ -330,8 +330,8 @@ void FFMS_Indexer::ParseVideoPacket(SharedAVContext &VideoContext, AVPacket &pkt
+ av_parser_parse2(VideoContext.Parser,
+ VideoContext.CodecContext,
+ &OB, &OBSize,
+- pkt.data, pkt.size,
+- pkt.pts, pkt.dts, pkt.pos);
++ pkt->data, pkt->size,
++ pkt->pts, pkt->dts, pkt->pos);
+
+ // H.264 (PAFF) and HEVC may have one field per packet, so we need to track
+ // when we have a full or half frame available, and mark one of them as
+@@ -351,15 +351,15 @@ void FFMS_Indexer::ParseVideoPacket(SharedAVContext &VideoContext, AVPacket &pkt
+
+ *RepeatPict = VideoContext.Parser->repeat_pict;
+ *FrameType = VideoContext.Parser->pict_type;
+- *Invisible = (IncompleteFrame || VideoContext.Parser->repeat_pict < 0 || (pkt.flags & AV_PKT_FLAG_DISCARD));
++ *Invisible = (IncompleteFrame || VideoContext.Parser->repeat_pict < 0 || (pkt->flags & AV_PKT_FLAG_DISCARD));
+ } else {
+- *Invisible = !!(pkt.flags & AV_PKT_FLAG_DISCARD);
++ *Invisible = !!(pkt->flags & AV_PKT_FLAG_DISCARD);
+ }
+
+ if (VideoContext.CodecContext->codec_id == AV_CODEC_ID_VP8)
+- ParseVP8(pkt.data[0], Invisible, FrameType);
++ ParseVP8(pkt->data[0], Invisible, FrameType);
+ else if (VideoContext.CodecContext->codec_id == AV_CODEC_ID_VP9)
+- ParseVP9(pkt.data[0], Invisible, FrameType);
++ ParseVP9(pkt->data[0], Invisible, FrameType);
+ }
+
+ void FFMS_Indexer::Free() {
+@@ -458,32 +458,36 @@ FFMS_Index *FFMS_Indexer::DoIndexing() {
+ }
+ }
+
+- AVPacket Packet;
+- InitNullPacket(Packet);
++ AVPacket *Packet = av_packet_alloc();
++ if (!Packet)
++ throw FFMS_Exception(FFMS_ERROR_CODEC, FFMS_ERROR_ALLOCATION_FAILED,
++ "Could not allocate packet.");
+ std::vector<int64_t> LastValidTS(FormatContext->nb_streams, AV_NOPTS_VALUE);
+
+ int64_t filesize = avio_size(FormatContext->pb);
+ enum AVPictureStructure LastPicStruct = AV_PICTURE_STRUCTURE_UNKNOWN;
+- while (av_read_frame(FormatContext, &Packet) >= 0) {
++ while (av_read_frame(FormatContext, Packet) >= 0) {
+ // Update progress
+ // FormatContext->pb can apparently be NULL when opening images.
+ if (IC && FormatContext->pb) {
+- if ((*IC)(FormatContext->pb->pos, filesize, ICPrivate))
++ if ((*IC)(FormatContext->pb->pos, filesize, ICPrivate)) {
++ av_packet_free(&Packet);
+ throw FFMS_Exception(FFMS_ERROR_CANCELLED, FFMS_ERROR_USER,
+ "Cancelled by user");
++ }
+ }
+- if (!IndexMask.count(Packet.stream_index)) {
+- av_packet_unref(&Packet);
++ if (!IndexMask.count(Packet->stream_index)) {
++ av_packet_unref(Packet);
+ continue;
+ }
+
+- int Track = Packet.stream_index;
++ int Track = Packet->stream_index;
+ FFMS_Track &TrackInfo = (*TrackIndices)[Track];
+- bool KeyFrame = !!(Packet.flags & AV_PKT_FLAG_KEY);
++ bool KeyFrame = !!(Packet->flags & AV_PKT_FLAG_KEY);
+ ReadTS(Packet, LastValidTS[Track], (*TrackIndices)[Track].UseDTS);
+
+ if (FormatContext->streams[Track]->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
+- int64_t PTS = TrackInfo.UseDTS ? Packet.dts : Packet.pts;
++ int64_t PTS = TrackInfo.UseDTS ? Packet->dts : Packet->pts;
+ if (PTS == AV_NOPTS_VALUE) {
+ // VPx alt-refs are output as packets which lack timestmps or durations, since
+ // they are invisible. Currently, the timestamp mangling code in libavformat
+@@ -495,9 +499,11 @@ FFMS_Index *FFMS_Indexer::DoIndexing() {
+ // FFMS2 currently sorts packets by PTS, which will break decoding, otherwise.
+ bool HasAltRefs = (FormatContext->streams[Track]->codecpar->codec_id == AV_CODEC_ID_VP8 ||
+ FormatContext->streams[Track]->codecpar->codec_id == AV_CODEC_ID_VP9);
+- if (Packet.duration == 0 && !HasAltRefs)
++ if (Packet->duration == 0 && !HasAltRefs) {
++ av_packet_free(&Packet);
+ throw FFMS_Exception(FFMS_ERROR_INDEXING, FFMS_ERROR_PARSER,
+ "Invalid packet pts, dts, and duration");
++ }
+
+ if (TrackInfo.empty())
+ PTS = 0;
+@@ -513,7 +519,7 @@ FFMS_Index *FFMS_Indexer::DoIndexing() {
+ ParseVideoPacket(AVContexts[Track], Packet, &RepeatPict, &FrameType, &Invisible, &LastPicStruct);
+
+ TrackInfo.AddVideoFrame(PTS, RepeatPict, KeyFrame,
+- FrameType, Packet.pos, Invisible);
++ FrameType, Packet->pos, Invisible);
+ } else if (FormatContext->streams[Track]->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) {
+ // For video seeking timestamps are used only if all packets have
+ // timestamps, while for audio they're used if any have timestamps,
+@@ -522,28 +528,29 @@ FFMS_Index *FFMS_Indexer::DoIndexing() {
+ TrackInfo.HasTS = true;
+
+ int64_t StartSample = AVContexts[Track].CurrentSample;
+- uint32_t SampleCount = IndexAudioPacket(Track, &Packet, AVContexts[Track], *TrackIndices);
++ uint32_t SampleCount = IndexAudioPacket(Track, Packet, AVContexts[Track], *TrackIndices);
+ TrackInfo.SampleRate = AVContexts[Track].CodecContext->sample_rate;
+
+ TrackInfo.AddAudioFrame(LastValidTS[Track],
+- StartSample, SampleCount, KeyFrame, Packet.pos, Packet.flags & AV_PKT_FLAG_DISCARD);
++ StartSample, SampleCount, KeyFrame, Packet->pos, Packet->flags & AV_PKT_FLAG_DISCARD);
+ }
+
+- if (!(Packet.flags & AV_PKT_FLAG_DISCARD))
+- TrackInfo.LastDuration = Packet.duration;
++ if (!(Packet->flags & AV_PKT_FLAG_DISCARD))
++ TrackInfo.LastDuration = Packet->duration;
+
+- av_packet_unref(&Packet);
++ av_packet_unref(Packet);
+ }
++ av_packet_free(&Packet);
+
+ TrackIndices->Finalize(AVContexts, FormatContext->iformat->name);
+ return TrackIndices.release();
+ }
+
+-void FFMS_Indexer::ReadTS(const AVPacket &Packet, int64_t &TS, bool &UseDTS) {
+- if (!UseDTS && Packet.pts != AV_NOPTS_VALUE)
+- TS = Packet.pts;
++void FFMS_Indexer::ReadTS(const AVPacket *Packet, int64_t &TS, bool &UseDTS) {
++ if (!UseDTS && Packet->pts != AV_NOPTS_VALUE)
++ TS = Packet->pts;
+ if (TS == AV_NOPTS_VALUE)
+ UseDTS = true;
+- if (UseDTS && Packet.dts != AV_NOPTS_VALUE)
+- TS = Packet.dts;
++ if (UseDTS && Packet->dts != AV_NOPTS_VALUE)
++ TS = Packet->dts;
+ }
+diff --git a/src/core/indexing.h b/src/core/indexing.h
+index 3cfc3c3..5c06868 100644
+--- a/src/core/indexing.h
++++ b/src/core/indexing.h
+@@ -80,10 +80,10 @@ private:
+ int64_t Filesize;
+ uint8_t Digest[20];
+
+- void ReadTS(const AVPacket &Packet, int64_t &TS, bool &UseDTS);
++ void ReadTS(const AVPacket *Packet, int64_t &TS, bool &UseDTS);
+ void CheckAudioProperties(int Track, AVCodecContext *Context);
+ uint32_t IndexAudioPacket(int Track, AVPacket *Packet, SharedAVContext &Context, FFMS_Index &TrackIndices);
+- void ParseVideoPacket(SharedAVContext &VideoContext, AVPacket &pkt, int *RepeatPict, int *FrameType, bool *Invisible, enum AVPictureStructure *LastPicStruct);
++ void ParseVideoPacket(SharedAVContext &VideoContext, AVPacket *pkt, int *RepeatPict, int *FrameType, bool *Invisible, enum AVPictureStructure *LastPicStruct);
+ void Free();
+ public:
+ FFMS_Indexer(const char *Filename);
+diff --git a/src/core/utils.cpp b/src/core/utils.cpp
+index ce67533..8a2e997 100644
+--- a/src/core/utils.cpp
++++ b/src/core/utils.cpp
+@@ -62,12 +62,6 @@ void ClearErrorInfo(FFMS_ErrorInfo *ErrorInfo) {
+ }
+ }
+
+-void InitNullPacket(AVPacket &pkt) {
+- av_init_packet(&pkt);
+- pkt.data = nullptr;
+- pkt.size = 0;
+-}
+-
+ void FillAP(FFMS_AudioProperties &AP, AVCodecContext *CTX, FFMS_Track &Frames) {
+ AP.SampleFormat = static_cast<FFMS_SampleFormat>(av_get_packed_sample_fmt(CTX->sample_fmt));
+ AP.BitsPerSample = av_get_bytes_per_sample(CTX->sample_fmt) * 8;
+diff --git a/src/core/utils.h b/src/core/utils.h
+index 9819dc7..003ab79 100644
+--- a/src/core/utils.h
++++ b/src/core/utils.h
+@@ -58,7 +58,6 @@ std::unique_ptr<T> make_unique(Args&&... args) {
+ }
+
+ void ClearErrorInfo(FFMS_ErrorInfo *ErrorInfo);
+-void InitNullPacket(AVPacket &pkt);
+ void FillAP(FFMS_AudioProperties &AP, AVCodecContext *CTX, FFMS_Track &Frames);
+
+ void LAVFOpenFile(const char *SourceFile, AVFormatContext *&FormatContext, int Track);
+diff --git a/src/core/videosource.cpp b/src/core/videosource.cpp
+index 06bd161..b889970 100644
+--- a/src/core/videosource.cpp
++++ b/src/core/videosource.cpp
+@@ -673,30 +673,34 @@ void FFMS_VideoSource::DecodeNextFrame(int64_t &AStartTime, int64_t &Pos) {
+ if (HasPendingDelayedFrames())
+ return;
+
+- AVPacket Packet;
+- InitNullPacket(Packet);
+-
+- while (ReadFrame(&Packet) >= 0) {
+- if (Packet.stream_index != VideoTrack) {
+- av_packet_unref(&Packet);
++ AVPacket *Packet = av_packet_alloc();
++ if (!Packet)
++ throw FFMS_Exception(FFMS_ERROR_DECODING, FFMS_ERROR_ALLOCATION_FAILED,
++ "Could not allocate packet.");
++
++ while (ReadFrame(Packet) >= 0) {
++ if (Packet->stream_index != VideoTrack) {
++ av_packet_unref(Packet);
+ continue;
+ }
+
+ if (AStartTime < 0)
+- AStartTime = Frames.UseDTS ? Packet.dts : Packet.pts;
++ AStartTime = Frames.UseDTS ? Packet->dts : Packet->pts;
+
+ if (Pos < 0)
+- Pos = Packet.pos;
++ Pos = Packet->pos;
+
+- bool FrameFinished = DecodePacket(&Packet);
+- av_packet_unref(&Packet);
+- if (FrameFinished)
++ bool FrameFinished = DecodePacket(Packet);
++ av_packet_unref(Packet);
++ if (FrameFinished) {
++ av_packet_free(&Packet);
+ return;
++ }
+ }
+
+ // Flush final frames
+- InitNullPacket(Packet);
+- DecodePacket(&Packet);
++ DecodePacket(Packet);
++ av_packet_free(&Packet);
+ }
+
+ bool FFMS_VideoSource::SeekTo(int n, int SeekOffset) {
+--
+2.40.0
+
+From bf9e03e9e08534c024e5a744a6437c4aac160201 Mon Sep 17 00:00:00 2001
+From: Derek Buitenhuis <derek.buitenhuis@gmail.com>
+Date: Tue, 4 May 2021 14:20:47 +0100
+Subject: [PATCH 2/3] configure: Remove deprecated API use
+
+Signed-off-by: Derek Buitenhuis <derek.buitenhuis@gmail.com>
+---
+ configure.ac | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/configure.ac b/configure.ac
+index b35ef80bc..d19714d0f 100644
+--- a/configure.ac
++++ b/configure.ac
+@@ -102,10 +102,10 @@ CFLAGS="$_CFLAGS $FFMPEG_CFLAGS"
+
+ AC_DEFUN([TEST_FFMPEG],
+ [AC_LINK_IFELSE([AC_LANG_PROGRAM([[
+- #include <libavcodec/avcodec.h>
++ #include <libavformat/avformat.h>
+ #include <libswscale/swscale.h>
+ ]],[[
+- avcodec_register_all();
++ avformat_network_init();
+ swscale_version();
+ ]])], [eval $1=yes], [eval $1=no])
+ ])
+
diff --git a/srcpkgs/ffms2/template b/srcpkgs/ffms2/template
index 68e8a0c14bce..2acfadac44b3 100644
--- a/srcpkgs/ffms2/template
+++ b/srcpkgs/ffms2/template
@@ -1,7 +1,7 @@
# Template file for 'ffms2'
pkgname=ffms2
version=2.40
-revision=1
+revision=2
build_style=gnu-configure
configure_args="--enable-shared --disable-static"
hostmakedepends="pkg-config autoconf automake libtool"
From 721e2f6a8c1a2493894fe79100b676737cb08acb Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:47 -0400
Subject: [PATCH 037/130] freerdp: revbump for ffmpeg-6.0
---
.../freerdp/patches/ffmpeg6_aa2cb9aa.patch | 42 +++++++++++++++++++
srcpkgs/freerdp/template | 2 +-
2 files changed, 43 insertions(+), 1 deletion(-)
create mode 100644 srcpkgs/freerdp/patches/ffmpeg6_aa2cb9aa.patch
diff --git a/srcpkgs/freerdp/patches/ffmpeg6_aa2cb9aa.patch b/srcpkgs/freerdp/patches/ffmpeg6_aa2cb9aa.patch
new file mode 100644
index 000000000000..a4324da3a882
--- /dev/null
+++ b/srcpkgs/freerdp/patches/ffmpeg6_aa2cb9aa.patch
@@ -0,0 +1,42 @@
+From aa2cb9aa5ff5562433598ba168a466e0752bca0e Mon Sep 17 00:00:00 2001
+From: akallabeth <akallabeth@posteo.net>
+Date: Tue, 14 Feb 2023 07:48:54 +0100
+Subject: [PATCH] Fixed #8686: Update h264 to use new FFMPEG API
+
+---
+ channels/tsmf/client/ffmpeg/tsmf_ffmpeg.c | 2 ++
+ libfreerdp/codec/h264_ffmpeg.c | 2 ++
+ 2 files changed, 4 insertions(+)
+
+diff --git a/channels/tsmf/client/ffmpeg/tsmf_ffmpeg.c b/channels/tsmf/client/ffmpeg/tsmf_ffmpeg.c
+index 339462d865f..beea80b7a1e 100644
+--- a/channels/tsmf/client/ffmpeg/tsmf_ffmpeg.c
++++ b/channels/tsmf/client/ffmpeg/tsmf_ffmpeg.c
+@@ -239,8 +239,10 @@ static BOOL tsmf_ffmpeg_init_stream(ITSMFDecoder* decoder, const TS_AM_MEDIA_TYP
+ }
+ }
+
++#if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(59, 18, 100)
+ if (mdecoder->codec->capabilities & AV_CODEC_CAP_TRUNCATED)
+ mdecoder->codec_context->flags |= AV_CODEC_FLAG_TRUNCATED;
++#endif
+
+ return TRUE;
+ }
+diff --git a/libfreerdp/codec/h264_ffmpeg.c b/libfreerdp/codec/h264_ffmpeg.c
+index 8a23db2473c..896a333019b 100644
+--- a/libfreerdp/codec/h264_ffmpeg.c
++++ b/libfreerdp/codec/h264_ffmpeg.c
+@@ -615,10 +615,12 @@ static BOOL libavcodec_init(H264_CONTEXT* h264)
+ goto EXCEPTION;
+ }
+
++#if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(59, 18, 100)
+ if (sys->codecDecoder->capabilities & AV_CODEC_CAP_TRUNCATED)
+ {
+ sys->codecDecoderContext->flags |= AV_CODEC_FLAG_TRUNCATED;
+ }
++#endif
+
+ #ifdef WITH_VAAPI
+
diff --git a/srcpkgs/freerdp/template b/srcpkgs/freerdp/template
index 25e8aa9677f0..4d51c8189902 100644
--- a/srcpkgs/freerdp/template
+++ b/srcpkgs/freerdp/template
@@ -1,7 +1,7 @@
# Template file for 'freerdp'
pkgname=freerdp
version=2.10.0
-revision=1
+revision=2
build_style=cmake
configure_args="-DWITH_ALSA=ON -DWITH_CUPS=OFF -DWITH_FFMPEG=ON
-DWITH_GSTREAMER_0_10=OFF -DWITH_GSTREAMER_1_0=OFF -DWITH_JPEG=ON
From 0dbcc9e5e081a28b0a97af8a0308f4a287757864 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:47 -0400
Subject: [PATCH 038/130] gerbera: revbump for ffmpeg-6.0
---
srcpkgs/gerbera/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/gerbera/template b/srcpkgs/gerbera/template
index ae14f35c767c..2dc0ac0ce03b 100644
--- a/srcpkgs/gerbera/template
+++ b/srcpkgs/gerbera/template
@@ -1,7 +1,7 @@
# Template file for 'gerbera'
pkgname=gerbera
version=1.12.1
-revision=1
+revision=2
build_style=cmake
configure_args="-DWITH_SYSTEMD=0 -DWITH_AVCODEC=1"
hostmakedepends="pkg-config"
From 61d514fe75b9cd65401aa37806e4e39c4277fc50 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:47 -0400
Subject: [PATCH 039/130] goldendict: revbump for ffmpeg-6.0
---
srcpkgs/goldendict/patches/ffmpeg4.patch | 21 --
srcpkgs/goldendict/patches/ffmpeg5.patch | 232 +++++++++++++++++++++++
srcpkgs/goldendict/template | 2 +-
3 files changed, 233 insertions(+), 22 deletions(-)
delete mode 100644 srcpkgs/goldendict/patches/ffmpeg4.patch
create mode 100644 srcpkgs/goldendict/patches/ffmpeg5.patch
diff --git a/srcpkgs/goldendict/patches/ffmpeg4.patch b/srcpkgs/goldendict/patches/ffmpeg4.patch
deleted file mode 100644
index f045fa27f54b..000000000000
--- a/srcpkgs/goldendict/patches/ffmpeg4.patch
+++ /dev/null
@@ -1,21 +0,0 @@
---- a/ffmpegaudio.cc.orig 2018-05-09 22:16:13.480659958 +0200
-+++ b/ffmpegaudio.cc 2018-05-09 22:16:50.748322790 +0200
-@@ -143,7 +143,7 @@
- return false;
- }
-
-- unsigned char * avioBuffer = ( unsigned char * )av_malloc( kBufferSize + FF_INPUT_BUFFER_PADDING_SIZE );
-+ unsigned char * avioBuffer = ( unsigned char * )av_malloc( kBufferSize + AV_INPUT_BUFFER_PADDING_SIZE );
- if ( !avioBuffer )
- {
- errorString = QObject::tr( "av_malloc() failed." );
-@@ -380,7 +380,7 @@
- }
-
- if ( !Qt4x5::AtomicInt::loadAcquire( isCancelled_ ) &&
-- codecContext_->codec->capabilities & CODEC_CAP_DELAY )
-+ codecContext_->codec->capabilities & AV_CODEC_CAP_DELAY )
- {
- av_init_packet( &packet );
- int gotFrame = 0;
-
diff --git a/srcpkgs/goldendict/patches/ffmpeg5.patch b/srcpkgs/goldendict/patches/ffmpeg5.patch
new file mode 100644
index 000000000000..7cfc98ada368
--- /dev/null
+++ b/srcpkgs/goldendict/patches/ffmpeg5.patch
@@ -0,0 +1,232 @@
+From 03bbe01b79a1f07a6780cb60f23a087104c5d77b Mon Sep 17 00:00:00 2001
+From: Abs62 <ottomann@yandex.ru>
+Date: Fri, 30 Mar 2018 22:53:24 +0300
+Subject: [PATCH] Fix warnings while compile with FFMpeg 3.4.2 (issue #978)
+
+---
+ ffmpegaudio.cc | 68 +++++++++++++++++++++++++++++++++++++++++++++-----
+ 1 file changed, 62 insertions(+), 6 deletions(-)
+
+diff --git a/ffmpegaudio.cc b/ffmpegaudio.cc
+index ed1172bdd..56e8f788e 100644
+--- a/ffmpegaudio.cc
++++ b/ffmpegaudio.cc
+@@ -91,6 +91,7 @@ struct DecoderContext
+ QByteArray audioData_;
+ QDataStream audioDataStream_;
+ AVFormatContext * formatContext_;
++ AVCodec * codec_;
+ AVCodecContext * codecContext_;
+ AVIOContext * avioContext_;
+ AVStream * audioStream_;
+@@ -114,6 +115,7 @@ DecoderContext::DecoderContext( QByteArray const & audioData, QAtomicInt & isCan
+ audioData_( audioData ),
+ audioDataStream_( audioData_ ),
+ formatContext_( NULL ),
++ codec_( NULL ),
+ codecContext_( NULL ),
+ avioContext_( NULL ),
+ audioStream_( NULL ),
+@@ -143,7 +145,11 @@ bool DecoderContext::openCodec( QString & errorString )
+ return false;
+ }
+
++#if LIBAVCODEC_VERSION_MAJOR < 56 || ( LIBAVCODEC_VERSION_MAJOR == 56 && LIBAVCODEC_VERSION_MINOR < 56 )
+ unsigned char * avioBuffer = ( unsigned char * )av_malloc( kBufferSize + FF_INPUT_BUFFER_PADDING_SIZE );
++#else
++ unsigned char * avioBuffer = ( unsigned char * )av_malloc( kBufferSize + AV_INPUT_BUFFER_PADDING_SIZE );
++#endif
+ if ( !avioBuffer )
+ {
+ errorString = QObject::tr( "av_malloc() failed." );
+@@ -186,7 +192,11 @@ bool DecoderContext::openCodec( QString & errorString )
+ // Find audio stream, use the first audio stream if available
+ for ( unsigned i = 0; i < formatContext_->nb_streams; i++ )
+ {
++#if LIBAVCODEC_VERSION_MAJOR < 57 || ( LIBAVCODEC_VERSION_MAJOR == 57 && LIBAVCODEC_VERSION_MINOR < 33 )
+ if ( formatContext_->streams[i]->codec->codec_type == AVMEDIA_TYPE_AUDIO )
++#else
++ if ( formatContext_->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_AUDIO )
++#endif
+ {
+ audioStream_ = formatContext_->streams[i];
+ break;
+@@ -198,22 +208,38 @@ bool DecoderContext::openCodec( QString & errorString )
+ return false;
+ }
+
++#if LIBAVCODEC_VERSION_MAJOR < 57 || ( LIBAVCODEC_VERSION_MAJOR == 57 && LIBAVCODEC_VERSION_MINOR < 33 )
+ codecContext_ = audioStream_->codec;
+- AVCodec * codec = avcodec_find_decoder( codecContext_->codec_id );
+- if ( !codec )
++ codec_ = avcodec_find_decoder( codecContext_->codec_id );
++ if ( !codec_ )
+ {
+ errorString = QObject::tr( "Codec [id: %1] not found." ).arg( codecContext_->codec_id );
+ return false;
+ }
++#else
++ codec_ = avcodec_find_decoder( audioStream_->codecpar->codec_id );
++ if ( !codec_ )
++ {
++ errorString = QObject::tr( "Codec [id: %1] not found." ).arg( audioStream_->codecpar->codec_id );
++ return false;
++ }
++ codecContext_ = avcodec_alloc_context3( codec_ );
++ if ( !codecContext_ )
++ {
++ errorString = QObject::tr( "avcodec_alloc_context3() failed." );
++ return false;
++ }
++ avcodec_parameters_to_context( codecContext_, audioStream_->codecpar );
++#endif
+
+- ret = avcodec_open2( codecContext_, codec, NULL );
++ ret = avcodec_open2( codecContext_, codec_, NULL );
+ if ( ret < 0 )
+ {
+ errorString = QObject::tr( "avcodec_open2() failed: %1." ).arg( avErrorString( ret ) );
+ return false;
+ }
+
+- av_log( NULL, AV_LOG_INFO, "Codec open: %s: channels: %d, rate: %d, format: %s\n", codec->long_name,
++ av_log( NULL, AV_LOG_INFO, "Codec open: %s: channels: %d, rate: %d, format: %s\n", codec_->long_name,
+ codecContext_->channels, codecContext_->sample_rate, av_get_sample_fmt_name( codecContext_->sample_fmt ) );
+ return true;
+ }
+@@ -252,10 +278,13 @@ void DecoderContext::closeCodec()
+
+ // Closing a codec context without prior avcodec_open2() will result in
+ // a crash in ffmpeg
+- if ( audioStream_ && audioStream_->codec && audioStream_->codec->codec )
++ if ( audioStream_ && codecContext_ && codec_ )
+ {
+ audioStream_->discard = AVDISCARD_ALL;
+- avcodec_close( audioStream_->codec );
++ avcodec_close( codecContext_ );
++#if LIBAVCODEC_VERSION_MAJOR > 57 || ( LIBAVCODEC_VERSION_MAJOR == 57 && LIBAVCODEC_VERSION_MINOR >= 33 )
++ avcodec_free_context( &codecContext_ );
++#endif
+ }
+
+ avformat_close_input( &formatContext_ );
+@@ -356,6 +385,7 @@ bool DecoderContext::play( QString & errorString )
+ if ( packet.stream_index == audioStream_->index )
+ {
+ AVPacket pack = packet;
++#if LIBAVCODEC_VERSION_MAJOR < 57 || ( LIBAVCODEC_VERSION_MAJOR == 57 && LIBAVCODEC_VERSION_MINOR < 37 )
+ int gotFrame = 0;
+ do
+ {
+@@ -370,6 +400,19 @@ bool DecoderContext::play( QString & errorString )
+ pack.data += len;
+ }
+ while( pack.size > 0 );
++#else
++ int ret = avcodec_send_packet( codecContext_, &pack );
++ /* read all the output frames (in general there may be any number of them) */
++ while( ret >= 0 )
++ {
++ ret = avcodec_receive_frame( codecContext_, frame);
++
++ if ( Qt4x5::AtomicInt::loadAcquire( isCancelled_ ) || ret < 0 )
++ break;
++
++ playFrame( frame );
++ }
++#endif
+ }
+ // av_free_packet() must be called after each call to av_read_frame()
+ #if LIBAVCODEC_VERSION_MAJOR < 57 || ( LIBAVCODEC_VERSION_MAJOR == 57 && LIBAVCODEC_VERSION_MINOR < 7 )
+@@ -379,6 +422,7 @@ bool DecoderContext::play( QString & errorString )
+ #endif
+ }
+
++#if LIBAVCODEC_VERSION_MAJOR < 57 || ( LIBAVCODEC_VERSION_MAJOR == 57 && LIBAVCODEC_VERSION_MINOR < 37 )
+ if ( !Qt4x5::AtomicInt::loadAcquire( isCancelled_ ) &&
+ codecContext_->codec->capabilities & CODEC_CAP_DELAY )
+ {
+@@ -391,6 +435,18 @@ bool DecoderContext::play( QString & errorString )
+ playFrame( frame );
+ }
+ }
++#else
++ /* flush the decoder */
++ av_init_packet( &packet );
++ int ret = avcodec_send_packet(codecContext_, &packet );
++ while( ret >= 0 )
++ {
++ ret = avcodec_receive_frame(codecContext_, frame);
++ if ( Qt4x5::AtomicInt::loadAcquire( isCancelled_ ) || ret < 0 )
++ break;
++ playFrame( frame );
++ }
++#endif
+
+ #if LIBAVCODEC_VERSION_MAJOR < 54
+ av_free( frame );
+32
+srcpkgs/goldendict/patches/ffmpeg5-2.patch
+Comment on this file
+@@ -0,0 +1,32 @@
+From 966f4a8b78e6324b930e5a50f2bb930bd87e565e Mon Sep 17 00:00:00 2001
+From: Abs62 <ottomann@yandex.ru>
+Date: Fri, 27 Sep 2019 17:00:52 +0300
+Subject: [PATCH] FFmpeg player: Fix some crashes on broken files
+
+---
+ ffmpegaudio.cc | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/ffmpegaudio.cc b/ffmpegaudio.cc
+index 56e8f788e..415fc79cb 100644
+--- a/ffmpegaudio.cc
++++ b/ffmpegaudio.cc
+@@ -51,7 +51,9 @@ AudioService & AudioService::instance()
+
+ AudioService::AudioService()
+ {
++#if LIBAVFORMAT_VERSION_MAJOR < 58 || ( LIBAVFORMAT_VERSION_MAJOR == 58 && LIBAVFORMAT_VERSION_MINOR < 9 )
+ av_register_all();
++#endif
+ ao_initialize();
+ }
+
+@@ -438,6 +440,8 @@ bool DecoderContext::play( QString & errorString )
+ #else
+ /* flush the decoder */
+ av_init_packet( &packet );
++ packet.data = NULL;
++ packet.size = 0;
+ int ret = avcodec_send_packet(codecContext_, &packet );
+ while( ret >= 0 )
+ {
+25
+srcpkgs/goldendict/patches/ffmpeg5-3.patch
+Comment on this file
+@@ -0,0 +1,25 @@
+From 8acb288c9e9bdb3c6bf2e803954dd3b6ac273c05 Mon Sep 17 00:00:00 2001
+From: Liao Junxuan <mikeljx@126.com>
+Date: Sun, 20 Feb 2022 12:28:05 +0800
+Subject: [PATCH] add support for ffmpeg 5.0
+
+---
+ ffmpegaudio.cc | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/ffmpegaudio.cc b/ffmpegaudio.cc
+index d550f4a77..7948d2187 100644
+--- a/ffmpegaudio.cc
++++ b/ffmpegaudio.cc
+@@ -94,7 +94,11 @@ struct DecoderContext
+ QByteArray audioData_;
+ QDataStream audioDataStream_;
+ AVFormatContext * formatContext_;
++#if LIBAVCODEC_VERSION_MAJOR < 59
+ AVCodec * codec_;
++#else
++ const AVCodec * codec_;
++#endif
+ AVCodecContext * codecContext_;
+ AVIOContext * avioContext_;
+ AVStream * audioStream_;
diff --git a/srcpkgs/goldendict/template b/srcpkgs/goldendict/template
index 4544ae710ee6..2ca4185e538a 100644
--- a/srcpkgs/goldendict/template
+++ b/srcpkgs/goldendict/template
@@ -9,7 +9,7 @@ makedepends="tiff-devel qt5-devel libvorbis-devel zlib-devel
libXtst-devel hunspell-devel qt5-tools-devel qt5-declarative-devel
qt5-webkit-devel lzo-devel bzip2-devel libao-devel qt5-svg-devel
libeb-devel qt5-x11extras-devel ffmpeg-devel liblzma-devel"
-short_desc="A feature-rich dictionary lookup program"
+short_desc="Feature-rich dictionary lookup program"
maintainer="John <me@johnnynator.dev>"
license="GPL-3.0-or-later"
homepage="http://goldendict.org/"
From 7d398cd286b6e22925247c6ec580b0484844fd28 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:47 -0400
Subject: [PATCH 040/130] gst-libav: revbump for ffmpeg-6.0
---
srcpkgs/gst-libav/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/gst-libav/template b/srcpkgs/gst-libav/template
index e9a79dc650a5..f082bd211c65 100644
--- a/srcpkgs/gst-libav/template
+++ b/srcpkgs/gst-libav/template
@@ -1,7 +1,7 @@
# Template file for 'gst-libav'
pkgname=gst-libav
version=1.20.3
-revision=1
+revision=2
build_style=meson
hostmakedepends="pkg-config yasm"
makedepends="orc-devel gst-plugins-base1-devel ffmpeg-devel"
From 32630cb243147451a602f2d7d6f89a25821b7971 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:47 -0400
Subject: [PATCH 041/130] gst-plugins-bad1: revbump for ffmpeg-6.0
---
srcpkgs/gst-plugins-bad1/template | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/srcpkgs/gst-plugins-bad1/template b/srcpkgs/gst-plugins-bad1/template
index f55f82fd4c77..5a9d5387e0d4 100644
--- a/srcpkgs/gst-plugins-bad1/template
+++ b/srcpkgs/gst-plugins-bad1/template
@@ -1,7 +1,7 @@
# Template file for 'gst-plugins-bad1'
pkgname=gst-plugins-bad1
-version=1.20.3
-revision=3
+version=1.22.1
+revision=2
build_helper="gir"
build_style=meson
configure_args="-Dpackage-origin=https://voidlinux.org -Ddoc=disabled
From 53fee738687fe8fd2896c8300dea3bd822873407 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:47 -0400
Subject: [PATCH 042/130] gst-rtsp-server: revbump for ffmpeg-6.0
---
srcpkgs/gst-rtsp-server/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/gst-rtsp-server/template b/srcpkgs/gst-rtsp-server/template
index 33cd64ceb95e..8ceea8d34b4b 100644
--- a/srcpkgs/gst-rtsp-server/template
+++ b/srcpkgs/gst-rtsp-server/template
@@ -1,7 +1,7 @@
# Template file for 'gst-rtsp-server'
pkgname=gst-rtsp-server
version=1.20.3
-revision=2
+revision=3
build_style=meson
hostmakedepends="pkg-config python3"
makedepends="glib-devel gst-plugins-bad1-devel gobject-introspection
From a6400cfa1bc4aa203d8e14b04ebd9cd9429c2e42 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:47 -0400
Subject: [PATCH 043/130] guvcview: update to 2.0.8.
---
srcpkgs/guvcview/patches/fix-include.patch | 10 ++++++++++
srcpkgs/guvcview/template | 5 ++---
2 files changed, 12 insertions(+), 3 deletions(-)
create mode 100644 srcpkgs/guvcview/patches/fix-include.patch
diff --git a/srcpkgs/guvcview/patches/fix-include.patch b/srcpkgs/guvcview/patches/fix-include.patch
new file mode 100644
index 000000000000..503c2af3b78c
--- /dev/null
+++ b/srcpkgs/guvcview/patches/fix-include.patch
@@ -0,0 +1,10 @@
+--- a/guvcview/guvcview.c
++++ b/guvcview/guvcview.c
+@@ -28,6 +28,7 @@
+ #include <sys/stat.h>
+ #include <sys/resource.h>
+ #include <errno.h>
++#include <locale.h>
+
+ #include "gview.h"
+ #include "gviewv4l2core.h"
diff --git a/srcpkgs/guvcview/template b/srcpkgs/guvcview/template
index 345cf6006f24..86a7fd619612 100644
--- a/srcpkgs/guvcview/template
+++ b/srcpkgs/guvcview/template
@@ -1,8 +1,7 @@
# Template file for 'guvcview'
pkgname=guvcview
-version=2.0.7
+version=2.0.8
revision=1
-create_wrksrc=yes
build_style=gnu-configure
configure_args="--disable-static --disable-debian-menu"
hostmakedepends="pkg-config intltool autoconf automake libtool glib-devel"
@@ -14,7 +13,7 @@ maintainer="Orphaned <orphan@voidlinux.org>"
license="GPL-3.0-or-later"
homepage="http://guvcview.sourceforge.net/"
distfiles="${SOURCEFORGE_SITE}/${pkgname}/${pkgname}-src-${version}.tar.bz2"
-checksum=f47d51fbd06e44eeaa1a82f4a153c927527c90d94514197a70b2956028cc8ad4
+checksum=a21f4e448286666cf27bafef5290cc953a0a1796b752e5bbe521266dc1230c81
post_patch() {
sed '31a#include <locale.h>' -i guvcview/guvcview.c
From fdf02069028eeacf58bdc7825a2e6d9c8c5fb5e6 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:48 -0400
Subject: [PATCH 044/130] handbrake: update to 1.6.1
---
.../patches/fix-missing-x265-link-flag.patch | 11 ++++++-----
.../handbrake/patches/libhb-vpl-include.patch | 15 +++++++++++++++
srcpkgs/handbrake/template | 17 ++++++++++-------
3 files changed, 31 insertions(+), 12 deletions(-)
create mode 100644 srcpkgs/handbrake/patches/libhb-vpl-include.patch
diff --git a/srcpkgs/handbrake/patches/fix-missing-x265-link-flag.patch b/srcpkgs/handbrake/patches/fix-missing-x265-link-flag.patch
index 26db03867a0c..d6bb2eda627a 100644
--- a/srcpkgs/handbrake/patches/fix-missing-x265-link-flag.patch
+++ b/srcpkgs/handbrake/patches/fix-missing-x265-link-flag.patch
@@ -1,14 +1,15 @@
--- a/gtk/configure.ac
+++ b/gtk/configure.ac
@@ -203,7 +203,7 @@
-
+
AM_CONDITIONAL([MINGW], [test "x$mingw_flag" = "xyes"])
-
--HB_LIBS="$HB_LIBS -lhandbrake -lavformat -lavfilter -lavcodec -lavutil -ldav1d -lswresample -lpostproc -ldvdnav -ldvdread -lmp3lame -lvorbis -lvorbisenc -logg -lswscale -ltheoraenc -ltheoradec -lvpx -lz -lbz2 -lbluray -lass -lfontconfig -lfreetype -lxml2 -ljansson -lopus -lspeex -lturbojpeg -llzma -lzimg"
-+HB_LIBS="$HB_LIBS -lhandbrake -lavformat -lavfilter -lavcodec -lavutil -ldav1d -lswresample -lpostproc -ldvdnav -ldvdread -lmp3lame -lvorbis -lvorbisenc -logg -lswscale -ltheoraenc -ltheoradec -lvpx -lz -lbz2 -lbluray -lass -lfontconfig -lfreetype -lxml2 -ljansson -lopus -lspeex -lturbojpeg -llzma -lzimg -ldl"
+
+-HB_LIBS="$HB_LIBS -lhandbrake -lavformat -lavfilter -lavcodec -lavutil -ldav1d -lswresample -lpostproc -ldvdnav -ldvdread -lmp3lame -lvorbis -lvorbisenc -logg -lswscale -ltheoraenc -ltheoradec -lvpx -lz -lbz2 -lbluray -lass -lfontconfig -lfreetype -lxml2 -ljansson -lopus -lspeex -lturbojpeg -llzma -lzimg -lSvtAv1Enc"
++HB_LIBS="$HB_LIBS -lhandbrake -lavformat -lavfilter -lavcodec -lavutil -ldav1d -lswresample -lpostproc -ldvdnav -ldvdread -lmp3lame -lvorbis -lvorbisenc -logg -lswscale -ltheoraenc -ltheoradec -lvpx -lz -lbz2 -lbluray -lass -lfontconfig -lfreetype -lxml2 -ljansson -lopus -lspeex -lturbojpeg -llzma -lzimg -lSvtAv1Enc -ldl"
HB_CPPFLAGS="$HB_CPPFLAGS $HBINC"
-
+
PKG_CHECK_MODULES([x264], [x264], sys_x264=yes, sys_x264=no)
+
--- a/test/module.defs
+++ b/test/module.defs
@@ -69,6 +69,9 @@
diff --git a/srcpkgs/handbrake/patches/libhb-vpl-include.patch b/srcpkgs/handbrake/patches/libhb-vpl-include.patch
new file mode 100644
index 000000000000..298f9f4ab28f
--- /dev/null
+++ b/srcpkgs/handbrake/patches/libhb-vpl-include.patch
@@ -0,0 +1,15 @@
+--- a/libhb/module.defs 2023-01-22 11:36:49.000000000 -0500
++++ b/libhb/module.defs 2023-04-03 22:37:52.395467010 -0400
+@@ -46,11 +46,7 @@
+ LIBHB.GCC.I += $(LIBHB.build/) $(CONTRIB.build/)include
+
+ ifeq (1,$(FEATURE.qsv))
+- ifeq ($(HOST.system),freebsd))
+- LIBHB.GCC.I += $(LOCALBASE)/include/vpl
+- else
+- LIBHB.GCC.I += $(CONTRIB.build/)include/vpl
+- endif
++ LIBHB.GCC.I += /usr/include/vpl
+ endif
+
+ ifneq (,$(filter $(HOST.system),freebsd netbsd openbsd))
diff --git a/srcpkgs/handbrake/template b/srcpkgs/handbrake/template
index ca5e4571e49c..c32cb1bfa31f 100644
--- a/srcpkgs/handbrake/template
+++ b/srcpkgs/handbrake/template
@@ -1,10 +1,10 @@
# Template file for 'handbrake'
pkgname=handbrake
-version=1.5.1
+version=1.6.1
revision=1
build_style=gnu-configure
configure_args="--force --disable-gtk-update-checks --disable-df-fetch --harden
- $(vopt_enable fdk_aac fdk-aac) $(vopt_enable nvenc)"
+ $(vopt_enable fdk_aac fdk-aac) $(vopt_enable nvenc) $(vopt_enable qsv)"
make_build_args="-C ${XBPS_TRIPLET}"
make_install_args="-C ${XBPS_TRIPLET}"
hostmakedepends="automake cmake gettext-devel glib-devel intltool libtool m4 meson nasm pkg-config python3"
@@ -12,8 +12,11 @@ makedepends="bzip2-devel ffmpeg-devel gst-plugins-base1-devel gtk+3-devel
jansson-devel lame-devel libass-devel libbluray-devel libdav1d-devel
libdvdnav-devel libdvdread-devel libgudev-devel libnuma-devel
libsamplerate-devel libtheora-devel libvorbis-devel libvpx-devel libxml2-devel
- opus-devel speex-devel x264-devel x265-devel zimg-devel
+ opus-devel speex-devel x264-devel x265-devel zimg-devel libsvt-av1-devel
$(vopt_if fdk_aac fdk-aac-devel)
+ $(vopt_if qsv libva-devel)
+ $(vopt_if qsv libdrm-devel)
+ $(vopt_if qsv onevpl-devel)
$(vopt_if nvenc nv-codec-headers)"
depends="desktop-file-utils gst-plugins-good1 hicolor-icon-theme"
short_desc="Multithreaded video transcoder"
@@ -21,15 +24,15 @@ maintainer="Enno Boland <gottox@voidlinux.org>"
license="GPL-2.0-only"
homepage="https://handbrake.fr/"
distfiles="https://github.com/HandBrake/HandBrake/releases/download/${version}/HandBrake-${version}-source.tar.bz2"
-checksum=3999fe06d5309c819799a73a968a8ec3840e7840c2b64af8f5cdb7fd8c9430f0
+checksum=94ccfe03db917a91650000c510f7fd53f844da19f19ad4b4be1b8f6bc31a8d4c
nocross=yes
-build_options="fdk_aac nvenc"
+build_options="fdk_aac nvenc qsv"
case "$XBPS_TARGET_MACHINE" in
x86_64*|i686*)
CFLAGS="-msse"
- build_options_default="nvenc"
+ build_options_default="nvenc qsv"
;;
esac
@@ -37,7 +40,7 @@ pre_configure() {
# use system libraries, don't download them
rm -rf contrib/
for module in fdk-aac ffmpeg libbluray libdav1d libdvdnav libdvdread nvenc \
- x265 zimg; do
+ x265 zimg svt-av1 libvpl; do
vsed -i "/MODULES += contrib\/${module}/d" make/include/main.defs
done
}
From bc2255e2e79f55ecb68171082b9f76e2585ce737 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:48 -0400
Subject: [PATCH 045/130] hedgewars: revbump for ffmpeg4-4.4.3
---
srcpkgs/hedgewars/template | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/srcpkgs/hedgewars/template b/srcpkgs/hedgewars/template
index 419f29b98b44..926fe4fe3e68 100644
--- a/srcpkgs/hedgewars/template
+++ b/srcpkgs/hedgewars/template
@@ -1,13 +1,13 @@
# Template file for 'hedgewars'
pkgname=hedgewars
version=1.0.2
-revision=1
+revision=2
build_style=cmake
configure_args="-DNOSERVER=1 -DDATA_INSTALL_DIR=/usr/share/${pkgname}
-DPHYSFS_SYSTEM=1 -DMINIMAL_FLAGS=1"
make_cmd=make
hostmakedepends="lua51 pkg-config qt5-qmake qt5-host-tools"
-makedepends="ffmpeg-devel lua51-devel physfs-devel qt5-tools-devel SDL2_image-devel
+makedepends="ffmpeg4-devel lua51-devel physfs-devel qt5-tools-devel SDL2_image-devel
SDL2_mixer-devel SDL2_net-devel SDL2_ttf-devel"
depends="libfreeglut"
short_desc="Funny turn-based artillery game, featuring fighting Hedgehogs!"
From 9d1d459dbc95409d29ad1bac85aebf2bb4c399b0 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:48 -0400
Subject: [PATCH 046/130] idjc: revbump for ffmpeg4-4.4.3
---
srcpkgs/idjc/template | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/srcpkgs/idjc/template b/srcpkgs/idjc/template
index df60318b3db9..36a75baf597c 100644
--- a/srcpkgs/idjc/template
+++ b/srcpkgs/idjc/template
@@ -1,11 +1,11 @@
# Template file for 'idjc'
pkgname=idjc
version=0.9.1
-revision=3
+revision=4
build_style=gnu-configure
hostmakedepends="pkg-config git python3 automake gettext-devel libtool"
makedepends="libvorbis-devel libogg-devel jack-devel libsamplerate-devel
- libflac-devel libsndfile-devel mpg123-devel ffmpeg-devel speex-devel
+ libflac-devel libsndfile-devel mpg123-devel ffmpeg4-devel speex-devel
glib-devel pixman-devel lame-devel python3-gobject-devel libshout-idjc-devel
opus-devel twolame-devel python3-mutagen python3-devel"
depends="python3-gobject python3-mutagen desktop-file-utils shared-mime-info python3-dbus jack"
From 3f928f7428ba5ea94fd367b9277b2e2cb685c2cc Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:48 -0400
Subject: [PATCH 047/130] kfilemetadata5: revbump for ffmpeg-6.0
---
srcpkgs/kfilemetadata5/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/kfilemetadata5/template b/srcpkgs/kfilemetadata5/template
index 8980121fbc69..f662a2043f93 100644
--- a/srcpkgs/kfilemetadata5/template
+++ b/srcpkgs/kfilemetadata5/template
@@ -1,7 +1,7 @@
# Template file for 'kfilemetadata5'
pkgname=kfilemetadata5
version=5.105.0
-revision=1
+revision=2
build_style=cmake
hostmakedepends="kcoreaddons extra-cmake-modules pkg-config qt5-host-tools qt5-qmake
gettext kcoreaddons python3"
From 371cd612b32c8686d46748955936e662f7801e03 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:48 -0400
Subject: [PATCH 048/130] kid3: revbump for ffmpeg-6.0
---
srcpkgs/kid3/patches/ffmpeg5.patch | 17 +++++++++++++++++
srcpkgs/kid3/template | 2 +-
2 files changed, 18 insertions(+), 1 deletion(-)
create mode 100644 srcpkgs/kid3/patches/ffmpeg5.patch
diff --git a/srcpkgs/kid3/patches/ffmpeg5.patch b/srcpkgs/kid3/patches/ffmpeg5.patch
new file mode 100644
index 000000000000..135fc50e07c9
--- /dev/null
+++ b/srcpkgs/kid3/patches/ffmpeg5.patch
@@ -0,0 +1,17 @@
+# https://aur.archlinux.org/cgit/aur.git/diff/ffmpeg5.patch?h=kid3-cli&id=12410a74906612e7efc0ec8fbce739b4a0fef7e7
+diff --git a/src/plugins/acoustidimport/ffmpegfingerprintdecoder.cpp b/src/plugins/acoustidimport/ffmpegfingerprintdecoder.cpp
+index e156d424..e12b9abd 100644
+--- a/src/plugins/acoustidimport/ffmpegfingerprintdecoder.cpp
++++ b/src/plugins/acoustidimport/ffmpegfingerprintdecoder.cpp
+@@ -232,7 +232,11 @@ private:
+ friend class Format;
+ friend class Converter;
+ AVCodecContext* m_ptr;
++#if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(59, 0, 0)
+ AVCodec* m_impl;
++#else
++ const AVCodec* m_impl;
++#endif
+ AVFrame* m_frame;
+ bool m_opened;
+ };
diff --git a/srcpkgs/kid3/template b/srcpkgs/kid3/template
index 456206d90e16..f32f9decb0e7 100644
--- a/srcpkgs/kid3/template
+++ b/srcpkgs/kid3/template
@@ -1,7 +1,7 @@
# Template file for 'kid3'
pkgname=kid3
version=3.9.1
-revision=2
+revision=3
build_style=cmake
configure_args="-DWITH_APPS='CLI;$(vopt_if KDE KDE Qt)'
-DWITH_DOCBOOKDIR=/usr/share/xsl/docbook -DWITH_FLAC=$(vopt_if flac ON OFF)
From 61afb904246d983debeed8c02da3e892c6a37328 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:48 -0400
Subject: [PATCH 049/130] kodi: revbump for ffmpeg4-4.4.3
---
srcpkgs/kodi/template | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/srcpkgs/kodi/template b/srcpkgs/kodi/template
index 8057964d78a3..6cc1874be7ba 100644
--- a/srcpkgs/kodi/template
+++ b/srcpkgs/kodi/template
@@ -1,7 +1,7 @@
# Template file for 'kodi'
pkgname=kodi
version=19.4
-revision=6
+revision=7
_codename="Matrix"
build_style=cmake
configure_args="-DWITH_FFMPEG=/usr -DENABLE_LDGOLD=OFF
@@ -54,7 +54,7 @@ makedepends="
libmad-devel fontconfig-devel libXinerama-devel libsamplerate-devel libmms-devel
enca-devel boost-devel libcurl-devel libva-devel libvdpau-devel libass-devel
libbluetooth-devel yajl-devel libplist-devel librtmp-devel tinyxml-devel
- taglib-devel libcap-devel lame-devel libbluray-devel libnfs-devel ffmpeg-devel
+ taglib-devel libcap-devel lame-devel libbluray-devel libnfs-devel ffmpeg4-devel
giflib-devel libxslt-devel gnutls-devel libssh-devel libmicrohttpd-devel
libcec-devel dcadec-devel flatbuffers-devel fmt-devel lcms2-devel
libfstrcmp-devel rapidjson libcdio-paranoia spdlog libwaylandpp-devel
From e1c52794a0b6e3ad8ee8b41919b0e16107087d06 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:48 -0400
Subject: [PATCH 050/130] kpipewire: revbump for ffmpeg-6.0
---
srcpkgs/kpipewire/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/kpipewire/template b/srcpkgs/kpipewire/template
index 467ab823a5e1..51827f24db9e 100644
--- a/srcpkgs/kpipewire/template
+++ b/srcpkgs/kpipewire/template
@@ -1,7 +1,7 @@
# Template file for 'kpipewire'
pkgname=kpipewire
version=5.27.4
-revision=1
+revision=2
build_style=cmake
hostmakedepends="extra-cmake-modules plasma-wayland-protocols gettext
qt5-qmake qt5-host-tools pkg-config wayland-devel kcoreaddons
From b03af67a50d20cf146e22f133c658e3ec0dade18 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:48 -0400
Subject: [PATCH 051/130] libextractor: revbump for ffmpeg4-4.4.3
---
srcpkgs/libextractor/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/libextractor/template b/srcpkgs/libextractor/template
index ddd4790f93e8..1fb9ca56a96a 100644
--- a/srcpkgs/libextractor/template
+++ b/srcpkgs/libextractor/template
@@ -7,7 +7,7 @@ configure_args="--disable-static"
hostmakedepends="pkg-config"
makedepends="zlib-devel bzip2-devel exiv2-devel tiff-devel libpng-devel
libjpeg-turbo-devel libvorbis-devel libflac-devel giflib-devel libmpeg2-devel
- ffmpeg-devel gtk+3-devel libltdl-devel libarchive-devel file-devel libgsf-devel"
+ ffmpeg4-devel gtk+3-devel libltdl-devel libarchive-devel file-devel libgsf-devel"
short_desc="Library used to extract meta data from files"
maintainer="Martin Riese <grauehaare@gmx.de>"
license="GPL-3.0-or-later"
From df50383e265c2289cd46743fe699d4725d92e57e Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:48 -0400
Subject: [PATCH 052/130] libopenal: revbump for ffmpeg-6.0
---
srcpkgs/libopenal/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/libopenal/template b/srcpkgs/libopenal/template
index 77218f9e539d..3f49ed75a1fd 100644
--- a/srcpkgs/libopenal/template
+++ b/srcpkgs/libopenal/template
@@ -1,7 +1,7 @@
# Template file for 'libopenal'
pkgname=libopenal
version=1.22.2
-revision=1
+revision=2
build_style=cmake
configure_args="-DALSOFT_EXAMPLES=OFF"
hostmakedepends="pkg-config"
From 0353b6f44b6099de27824920ba2150110b2a255d Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:48 -0400
Subject: [PATCH 053/130] libopenshot: revbump for ffmpeg-6.0
---
srcpkgs/libopenshot/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/libopenshot/template b/srcpkgs/libopenshot/template
index db831f69b474..81aa0d7136d9 100644
--- a/srcpkgs/libopenshot/template
+++ b/srcpkgs/libopenshot/template
@@ -1,7 +1,7 @@
# Template file for 'libopenshot'
pkgname=libopenshot
version=0.3.0
-revision=1
+revision=2
build_style=cmake
# Builds fail with Ruby-2.4.1
configure_args="-DENABLE_RUBY=OFF -DUSE_SYSTEM_JSONCPP=ON"
From 1fd7f1d30239c7d4255c763933b66fcd5a3d7ef4 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:48 -0400
Subject: [PATCH 054/130] loudgain: revbump for ffmpeg-6.0
---
srcpkgs/loudgain/patches/ffmpeg5.patch | 11 +++++++++++
srcpkgs/loudgain/template | 2 +-
2 files changed, 12 insertions(+), 1 deletion(-)
create mode 100644 srcpkgs/loudgain/patches/ffmpeg5.patch
diff --git a/srcpkgs/loudgain/patches/ffmpeg5.patch b/srcpkgs/loudgain/patches/ffmpeg5.patch
new file mode 100644
index 000000000000..16d4510ee98f
--- /dev/null
+++ b/srcpkgs/loudgain/patches/ffmpeg5.patch
@@ -0,0 +1,11 @@
+--- a/src/scan.c 2019-09-06 11:31:19.000000000 -0400
++++ b/src/scan.c 2023-03-23 11:15:40.867968521 -0400
+@@ -69,8 +69,6 @@
+ * It is now useless
+ * https://github.com/FFmpeg/FFmpeg/blob/70d25268c21cbee5f08304da95be1f647c630c15/doc/APIchanges#L86
+ */
+- if (avformat_version() < AV_VERSION_INT(58,9,100))
+- av_register_all();
+
+ av_log_set_callback(scan_av_log);
+
diff --git a/srcpkgs/loudgain/template b/srcpkgs/loudgain/template
index da4f2d56e94c..4d6bf29efb4f 100644
--- a/srcpkgs/loudgain/template
+++ b/srcpkgs/loudgain/template
@@ -1,7 +1,7 @@
# Template file for 'loudgain'
pkgname=loudgain
version=0.6.8
-revision=2
+revision=3
build_style=cmake
hostmakedepends="pkg-config"
makedepends="libebur128-devel taglib-devel ffmpeg-devel"
From 0f4dc1b5d3b60b94b29bac5fbdfda3d6e13d560e Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:48 -0400
Subject: [PATCH 055/130] mediastreamer: revbump for ffmpeg4-4.4.3
---
srcpkgs/mediastreamer/template | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/srcpkgs/mediastreamer/template b/srcpkgs/mediastreamer/template
index d0e97e858e29..1bde031443a5 100644
--- a/srcpkgs/mediastreamer/template
+++ b/srcpkgs/mediastreamer/template
@@ -1,11 +1,11 @@
# Template file for 'mediastreamer'
pkgname=mediastreamer
version=5.2.6
-revision=1
+revision=2
build_style=cmake
configure_args="-DENABLE_STRICT=0 -DENABLE_UNIT_TESTS=0"
hostmakedepends="python3"
-makedepends="bzrtp-devel ffmpeg-devel glew-devel libXv-devel libsrtp-devel
+makedepends="bzrtp-devel ffmpeg4-devel glew-devel libXv-devel libsrtp-devel
libupnp-devel libvpx-devel mbedtls-devel opus-devel ortp-devel pulseaudio-devel
libtheora-devel speex-devel v4l-utils-devel bcg729-devel bcmatroska2-devel libgsm-devel"
# zxing-cpp-devel (1.2.0 probably not compatible, check again after updaing xzing)
From 138bc14ebf333f30e1e2101ab30afaac832df141 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:48 -0400
Subject: [PATCH 056/130] mgba: revbump for ffmpeg-6.0
---
srcpkgs/mgba/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/mgba/template b/srcpkgs/mgba/template
index ae0504311eee..d31295a0cd3d 100644
--- a/srcpkgs/mgba/template
+++ b/srcpkgs/mgba/template
@@ -1,7 +1,7 @@
# Template file for 'mgba'
pkgname=mgba
version=0.10.2
-revision=1
+revision=2
build_style=cmake
hostmakedepends="pkg-config qt5-host-tools qt5-qmake desktop-file-utils"
makedepends="SDL2-devel ffmpeg-devel libedit-devel libepoxy-devel libmagick-devel
From f75acfadd38a353b6ecd7e9f3b69a5bd13e11e17 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:48 -0400
Subject: [PATCH 057/130] minidlna: revbump for ffmpeg-6.0
---
srcpkgs/minidlna/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/minidlna/template b/srcpkgs/minidlna/template
index e8081b1cbc67..9ee9714861fd 100644
--- a/srcpkgs/minidlna/template
+++ b/srcpkgs/minidlna/template
@@ -1,7 +1,7 @@
# Template file for 'minidlna'
pkgname=minidlna
version=1.3.2
-revision=1
+revision=2
build_style=gnu-configure
configure_args="
--sbindir=/usr/bin
From 699fd1cee259b79098be209e1614706dce560d0c Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:49 -0400
Subject: [PATCH 058/130] mixxx: revbump for ffmpeg-6.0
---
srcpkgs/mixxx/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/mixxx/template b/srcpkgs/mixxx/template
index 619ddca0d332..4b9ea00d3fb3 100644
--- a/srcpkgs/mixxx/template
+++ b/srcpkgs/mixxx/template
@@ -1,7 +1,7 @@
# Template file for 'mixxx'
pkgname=mixxx
version=2.3.3
-revision=1
+revision=2
build_style=cmake
configure_args="-DCMAKE_BUILD_TYPE=Release"
hostmakedepends="extra-cmake-modules pkg-config protobuf qt5-host-tools qt5-devel"
From c4f98926577c8592593634403ee0a9b151bedcaf Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:49 -0400
Subject: [PATCH 059/130] mlt: revbump for ffmpeg4-4.4.3
---
srcpkgs/mlt/template | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/srcpkgs/mlt/template b/srcpkgs/mlt/template
index 8933eb4e7bb9..73353fedafb5 100644
--- a/srcpkgs/mlt/template
+++ b/srcpkgs/mlt/template
@@ -1,14 +1,14 @@
# Template file for 'mlt'
pkgname=mlt
version=6.26.1
-revision=1
+revision=2
build_style=configure
configure_args="--prefix=/usr --libdir=/usr/lib$XBPS_TARGET_WORDSIZE
--enable-gpl --enable-gpl3 --disable-swfdec --without-kde
--swig-languages=python"
hostmakedepends="doxygen pkg-config ladspa-sdk swig python3 which"
# XXX: movit vid.stab
-makedepends="alsa-lib-devel ffmpeg-devel gtk+-devel jack-devel ladspa-sdk
+makedepends="alsa-lib-devel ffmpeg4-devel gtk+-devel jack-devel ladspa-sdk
libexif-devel libsamplerate-devel libxml2-devel sox-devel SDL_image-devel
fftw-devel frei0r-plugins python3-devel pulseaudio-devel movit-devel
libvidstab-devel libatomic-devel"
From dd538e534b5c67d5245cacc14727f059483b73dc Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:49 -0400
Subject: [PATCH 060/130] moc: revbump for ffmpeg4-4.4.3
---
srcpkgs/moc/template | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/srcpkgs/moc/template b/srcpkgs/moc/template
index c42be650a1d2..d4f0eefbad52 100644
--- a/srcpkgs/moc/template
+++ b/srcpkgs/moc/template
@@ -1,10 +1,10 @@
# Template file for 'moc'
pkgname=moc
version=2.5.2
-revision=6
+revision=7
build_style=gnu-configure
hostmakedepends="pkg-config"
-makedepends="db-devel ncurses-devel libcurl-devel popt-devel ffmpeg-devel
+makedepends="db-devel ncurses-devel libcurl-devel popt-devel ffmpeg4-devel
jack-devel alsa-lib-devel libltdl-devel libflac-devel libvorbis-devel
libmad-devel libmpcdec-devel libmodplug-devel libid3tag-devel faad2-devel
taglib-devel libsndfile-devel wavpack-devel speex-devel libsamplerate-devel
From 57cf5902a476c912b7325800c3296de92f926abf Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:49 -0400
Subject: [PATCH 061/130] motion: revbump for ffmpeg-6.0
---
srcpkgs/motion/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/motion/template b/srcpkgs/motion/template
index 3cf3c3035c5b..7dca12d851e3 100644
--- a/srcpkgs/motion/template
+++ b/srcpkgs/motion/template
@@ -1,7 +1,7 @@
# Template file for 'motion'
pkgname=motion
version=4.5.1
-revision=1
+revision=2
build_style=gnu-configure
hostmakedepends="automake pkg-config gettext-devel tar"
makedepends="ffmpeg-devel libmicrohttpd-devel v4l-utils-devel gettext-devel"
From 31a6f2e7ec900f70d634fcf6a705e32cb22b211b Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:49 -0400
Subject: [PATCH 062/130] mpv: revbump for ffmpeg-6.0
---
srcpkgs/mpv/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/mpv/template b/srcpkgs/mpv/template
index e163c496c6eb..d4fefbf5e3c7 100644
--- a/srcpkgs/mpv/template
+++ b/srcpkgs/mpv/template
@@ -1,7 +1,7 @@
# Template file for 'mpv'
pkgname=mpv
version=0.35.1
-revision=2
+revision=3
build_style=meson
configure_args="-Dcdda=enabled -Ddvbin=enabled -Ddvdnav=enabled
-Dlibmpv=true -Dcplugins=enabled
From 86fc1c173567bcae442c969a91ec348d61cc4c96 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:49 -0400
Subject: [PATCH 063/130] musikcube: revbump for ffmpeg-6.0
---
srcpkgs/musikcube/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/musikcube/template b/srcpkgs/musikcube/template
index 4b7930041126..7cd65cf76b77 100644
--- a/srcpkgs/musikcube/template
+++ b/srcpkgs/musikcube/template
@@ -1,7 +1,7 @@
# Template file for 'musikcube'
pkgname=musikcube
version=0.99.4
-revision=1
+revision=2
build_style=cmake
make_cmd=make
configure_args="-DNO_NCURSESW=1"
From 408659e0c076564e0ceb705814fe4cf09f9d9a5d Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:49 -0400
Subject: [PATCH 064/130] notcurses: revbump for ffmpeg-6.0
---
srcpkgs/notcurses/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/notcurses/template b/srcpkgs/notcurses/template
index 6dd8a091319f..3110c30c9aff 100644
--- a/srcpkgs/notcurses/template
+++ b/srcpkgs/notcurses/template
@@ -1,7 +1,7 @@
# Template file for 'notcurses'
pkgname=notcurses
version=3.0.9
-revision=1
+revision=2
build_style=cmake
configure_args="-DUSE_STATIC=ON $(vopt_bool man USE_PANDOC)"
hostmakedepends="pkg-config $(vopt_if man pandoc)"
From 8ae0ad0ba65f21a43c9d480ed6ba1f2e3e4c88d3 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:49 -0400
Subject: [PATCH 065/130] obs: revbump for ffmpeg-6.0
---
srcpkgs/obs/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/obs/template b/srcpkgs/obs/template
index 89fd11297c3f..3cf49e414bf3 100644
--- a/srcpkgs/obs/template
+++ b/srcpkgs/obs/template
@@ -1,7 +1,7 @@
# Template file for 'obs'
pkgname=obs
version=29.1.0
-revision=1
+revision=2
archs="i686* x86_64* ppc64le* aarch64*"
build_style=cmake
configure_args="-DOBS_VERSION_OVERRIDE=${version} -DENABLE_JACK=ON
From 79ddcb5a840212dc4d5270609d0ab5e13c4db873 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:49 -0400
Subject: [PATCH 066/130] olive: revbump for ffmpeg4-4.4.3
---
srcpkgs/olive/template | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/srcpkgs/olive/template b/srcpkgs/olive/template
index 12a46936c990..5c2917b9c512 100644
--- a/srcpkgs/olive/template
+++ b/srcpkgs/olive/template
@@ -1,10 +1,10 @@
# Template file for 'olive'
pkgname=olive
version=0.1.2
-revision=2
+revision=3
build_style=qmake
hostmakedepends="qt5-qmake qt5-host-tools pkg-config"
-makedepends="qt5-devel qt5-multimedia-devel qt5-svg-devel ffmpeg-devel frei0r-plugins"
+makedepends="qt5-devel qt5-multimedia-devel qt5-svg-devel ffmpeg4-devel frei0r-plugins"
short_desc="Non-linear video editor"
maintainer="Orphaned <orphan@voidlinux.org>"
license="GPL-3.0-or-later"
From 0b87b076c92d42447dd26377c985603d170050bf Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:49 -0400
Subject: [PATCH 067/130] omxplayer: revbump for ffmpeg4-4.4.3
---
srcpkgs/omxplayer/template | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/srcpkgs/omxplayer/template b/srcpkgs/omxplayer/template
index e70bf7873d4d..0e9bc70e7c8e 100644
--- a/srcpkgs/omxplayer/template
+++ b/srcpkgs/omxplayer/template
@@ -1,10 +1,10 @@
# Template file for 'omxplayer'
pkgname=omxplayer
version=20190102
-revision=1
+revision=2
short_desc="Commandline OMX player for the Raspberry Pi"
maintainer="Orphaned <orphan@voidlinux.org>"
-license="GPL-2"
+license="GPL-2.0-or-later"
homepage="https://github.com/popcornmix/omxplayer"
_commit="f06235cc9690a6d58187514452df8cf8fcdaacec"
@@ -15,7 +15,7 @@ checksum=af2d9450f8947842ea8c401fe9f71eec444013ebbdee29f2ac828c9c493c1329
archs="armv6l* armv7l*"
build_style=gnu-makefile
hostmakedepends="curl pkg-config"
-makedepends="alsa-lib-devel rpi-userland-devel pcre-devel boost-devel freetype-devel ffmpeg-devel dbus-devel"
+makedepends="alsa-lib-devel rpi-userland-devel pcre-devel boost-devel freetype-devel ffmpeg4-devel dbus-devel"
depends="freefont-ttf"
do_build() {
From 1a11d959c884c346c5e1064d23682bd21fd8686f Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:50 -0400
Subject: [PATCH 068/130] openimageio: revbump for ffmpeg-6.0
---
common/shlibs | 2 ++
srcpkgs/openimageio/template | 2 +-
2 files changed, 3 insertions(+), 1 deletion(-)
diff --git a/common/shlibs b/common/shlibs
index 4626cfda810b..d0d328b09ef9 100644
--- a/common/shlibs
+++ b/common/shlibs
@@ -2262,6 +2262,8 @@ libxmp.so.4 libxmp-4.3.7_1
libKF5ThreadWeaver.so.5 threadweaver-5.26.0_1
libOpenImageIO_Util.so.2.4 openimageio-2.4.9.0_1
libOpenImageIO.so.2.4 openimageio-2.4.9.0_1
+libOpenImageIO_Util.so.2.4 openimageio-2.4.8.1_1
+libOpenImageIO.so.2.4 openimageio-2.4.8.1_1
libOpenColorIO.so.2.1 opencolorio-2.1.2_1
libpystring.so.1 pystring-1.1.3_1
libyaml-cpp.so.0.7 yaml-cpp-0.7.0_1
diff --git a/srcpkgs/openimageio/template b/srcpkgs/openimageio/template
index b661bbf7ba57..9b38ace50f7e 100644
--- a/srcpkgs/openimageio/template
+++ b/srcpkgs/openimageio/template
@@ -1,7 +1,7 @@
# Template file for 'openimageio'
pkgname=openimageio
version=2.4.9.0
-revision=2
+revision=3
build_style=cmake
build_helper=qemu
configure_args="-DUSE_QT=0 -DUSE_PYTHON=0 -DOIIO_BUILD_TESTS=0
From 3026e678068d54d93aebf877ce36d8fee72269a9 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:50 -0400
Subject: [PATCH 069/130] openmw: revbump for ffmpeg-6.0
---
srcpkgs/openmw/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/openmw/template b/srcpkgs/openmw/template
index 5251a0283dc1..e3771c7aaf1a 100644
--- a/srcpkgs/openmw/template
+++ b/srcpkgs/openmw/template
@@ -1,7 +1,7 @@
# Template file for 'openmw'
pkgname=openmw
version=0.47.0
-revision=4
+revision=5
build_style=cmake
_recast_commit=e75adf86f91eb3082220085e42dda62679f9a3ea
_bullet_tag=3.17
From 022169bb0f72ad568fa8f3e5c8cac4b7fa55be0e Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:50 -0400
Subject: [PATCH 070/130] openshot: revbump for ffmpeg-6.0
---
srcpkgs/openshot/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/openshot/template b/srcpkgs/openshot/template
index 322717d40abc..c074e0338773 100644
--- a/srcpkgs/openshot/template
+++ b/srcpkgs/openshot/template
@@ -1,7 +1,7 @@
# Template file for 'openshot'
pkgname=openshot
version=3.0.0
-revision=1
+revision=2
build_style=python3-module
hostmakedepends="python3 python3-setuptools"
makedepends="ffmpeg-devel python3-PyQt5"
From 5610dc8aba6649bcd39c3ddfa1bfc5a190347145 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:50 -0400
Subject: [PATCH 071/130] opentoonz: revbump for ffmpeg-6.0
---
srcpkgs/opentoonz/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/opentoonz/template b/srcpkgs/opentoonz/template
index ee9f7603f55f..3e81834ca0ed 100644
--- a/srcpkgs/opentoonz/template
+++ b/srcpkgs/opentoonz/template
@@ -1,7 +1,7 @@
# Template file for 'opentoonz'
pkgname=opentoonz
version=1.6.0
-revision=2
+revision=3
build_wrksrc="toonz/sources"
build_style=cmake
make_cmd=make
From 0c13172e51699fe67cfb8743be727f109708b0cd Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:50 -0400
Subject: [PATCH 072/130] pianobar: revbump for ffmpeg-6.0
---
srcpkgs/pianobar/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/pianobar/template b/srcpkgs/pianobar/template
index a9b29e91993f..81efcd122c4d 100644
--- a/srcpkgs/pianobar/template
+++ b/srcpkgs/pianobar/template
@@ -1,7 +1,7 @@
# Template file for 'pianobar'
pkgname=pianobar
version=2022.04.01
-revision=1
+revision=2
build_style=gnu-makefile
make_build_args="V=1"
hostmakedepends="pkg-config"
From a9bf6c2d4099cc48888b533e15368fc721c6eb4c Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:50 -0400
Subject: [PATCH 073/130] ppsspp: revbump for ffmpeg4-4.4.3
---
srcpkgs/ppsspp/template | 7 +++----
1 file changed, 3 insertions(+), 4 deletions(-)
diff --git a/srcpkgs/ppsspp/template b/srcpkgs/ppsspp/template
index 7984a733d4be..15a42fd2c993 100644
--- a/srcpkgs/ppsspp/template
+++ b/srcpkgs/ppsspp/template
@@ -1,7 +1,7 @@
# Template file for 'ppsspp'
pkgname=ppsspp
version=1.14.4
-revision=1
+revision=2
_glslang_commit=dc11adde23c455a24e13dd54de9b4ede8bdd7db8
_SPIRV_Cross_commit=9acb9ec31f5a8ef80ea6b994bb77be787b08d3d1
_armips_commit=6719edebaae03330ee5441d9b28280672edf00d5
@@ -13,7 +13,7 @@ configure_args="-DHEADLESS=1 -DUSE_SYSTEM_FFMPEG=1 -DUNITTEST=ON
-DUSING_QT_UI=$(vopt_if qt ON OFF) -DUSE_SYSTEM_ZSTD=ON
-DARMIPS_USE_STD_FILESYSTEM=ON"
hostmakedepends="pkg-config python3 $(vopt_if qt qt5-host-tools)"
-makedepends="zlib-devel glew-devel ffmpeg-devel libzip-devel
+makedepends="zlib-devel glew-devel ffmpeg4-devel libzip-devel
snappy-devel rapidjson libpng-devel libzstd-devel
$(vopt_if sdl2 SDL2-devel) $(vopt_if wayland wayland-devel)
$(vopt_if qt 'qt5-devel qt5-multimedia-devel')"
@@ -62,13 +62,12 @@ post_extract() {
mv ${wrksrc}/miniupnp-${_miniupnp_commit} ${wrksrc}/ext/miniupnp
}
-post_patch(){
+post_patch() {
# disable git versioning
vsed -e 's|find_package(Git)|# &|' -i git-version.cmake
}
do_install() {
- vlicense LICENSE.TXT
vinstall icons/icon.svg 644 usr/share/pixmaps ppsspp.svg
vinstall Qt/PPSSPP.desktop 644 usr/share/applications
vbin build/PPSSPPHeadless ppsspp-headless
From 94edb0bf9d442ca44546dd97b5ccd2fe332de92d Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:50 -0400
Subject: [PATCH 074/130] pqiv: revbump for ffmpeg-6.0
---
srcpkgs/pqiv/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/pqiv/template b/srcpkgs/pqiv/template
index 542fc27a2d32..9308d949b6a1 100644
--- a/srcpkgs/pqiv/template
+++ b/srcpkgs/pqiv/template
@@ -1,7 +1,7 @@
# Template file for 'pqiv'
pkgname=pqiv
version=2.12
-revision=1
+revision=2
build_style=gnu-makefile
hostmakedepends="pkg-config"
makedepends="glib-devel gtk+3-devel $(vopt_if ffmpeg ffmpeg-devel)
From 85a642c07b68e57e8ee76cdc50bd4ac4c7278b24 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:50 -0400
Subject: [PATCH 075/130] qmmp: revbump for ffmpeg-6.0
---
srcpkgs/qmmp/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/qmmp/template b/srcpkgs/qmmp/template
index 26c661ed16be..a150d7441c7a 100644
--- a/srcpkgs/qmmp/template
+++ b/srcpkgs/qmmp/template
@@ -1,7 +1,7 @@
# Template file for 'qmmp'
pkgname=qmmp
version=1.6.1
-revision=1
+revision=2
build_style=cmake
configure_args="-DUSE_HAL:BOOL=FALSE -DQMMP_DEFAULT_UI:STRING=simple"
hostmakedepends="pkg-config qt5-host-tools qt5-qmake"
From 168c9e6bf95c3e1703c0850b7d3ea42ac142ad1a Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:50 -0400
Subject: [PATCH 076/130] qt5-webengine: update to 5.15.13
---
.../chromium-media-filters-cpp14.patch | 11 ++
srcpkgs/qt5-webengine/patches/ffmpeg5.patch | 179 ++++++++++++++++++
srcpkgs/qt5-webengine/template | 10 +-
3 files changed, 195 insertions(+), 5 deletions(-)
create mode 100644 srcpkgs/qt5-webengine/patches/chromium-media-filters-cpp14.patch
create mode 100644 srcpkgs/qt5-webengine/patches/ffmpeg5.patch
diff --git a/srcpkgs/qt5-webengine/patches/chromium-media-filters-cpp14.patch b/srcpkgs/qt5-webengine/patches/chromium-media-filters-cpp14.patch
new file mode 100644
index 000000000000..04adc540f2cb
--- /dev/null
+++ b/srcpkgs/qt5-webengine/patches/chromium-media-filters-cpp14.patch
@@ -0,0 +1,11 @@
+--- a/src/3rdparty/chromium/media/filters/BUILD.gn 2023-02-27 13:32:59.000000000 -0500
++++ b/src/3rdparty/chromium/media/filters/BUILD.gn 2023-04-02 17:21:39.204066384 -0400
+@@ -96,6 +96,8 @@
+ "//ui/gfx/geometry:geometry",
+ ]
+
++ cflags_cc = [ "-std=c++14" ]
++
+ libs = []
+
+ if (proprietary_codecs) {
diff --git a/srcpkgs/qt5-webengine/patches/ffmpeg5.patch b/srcpkgs/qt5-webengine/patches/ffmpeg5.patch
new file mode 100644
index 000000000000..ac55e1634423
--- /dev/null
+++ b/srcpkgs/qt5-webengine/patches/ffmpeg5.patch
@@ -0,0 +1,179 @@
+--- a/src/3rdparty/chromium/media/filters/ffmpeg_demuxer.cc 2023-04-02 16:50:57.732547446 -0400
++++ b/src/3rdparty/chromium/media/filters/ffmpeg_demuxer.cc 2023-04-02 16:50:09.486478995 -0400
+@@ -57,6 +57,8 @@
+
+ namespace {
+
++constexpr int64_t kRelativeTsBase = static_cast<int64_t>(0x7ffeffffffffffff);
++
+ void SetAVStreamDiscard(AVStream* stream, AVDiscard discard) {
+ DCHECK(stream);
+ stream->discard = discard;
+@@ -90,24 +92,12 @@
+
+ static base::TimeDelta ExtractStartTime(AVStream* stream) {
+ // The default start time is zero.
+- base::TimeDelta start_time;
++ base::TimeDelta start_time = kNoTimestamp;
+
+ // First try to use the |start_time| value as is.
+ if (stream->start_time != kNoFFmpegTimestamp)
+ start_time = ConvertFromTimeBase(stream->time_base, stream->start_time);
+
+- // Next try to use the first DTS value, for codecs where we know PTS == DTS
+- // (excludes all H26x codecs). The start time must be returned in PTS.
+- if (stream->first_dts != kNoFFmpegTimestamp &&
+- stream->codecpar->codec_id != AV_CODEC_ID_HEVC &&
+- stream->codecpar->codec_id != AV_CODEC_ID_H264 &&
+- stream->codecpar->codec_id != AV_CODEC_ID_MPEG4) {
+- const base::TimeDelta first_pts =
+- ConvertFromTimeBase(stream->time_base, stream->first_dts);
+- if (first_pts < start_time)
+- start_time = first_pts;
+- }
+-
+ return start_time;
+ }
+
+@@ -408,11 +398,11 @@
+ scoped_refptr<DecoderBuffer> buffer;
+
+ if (type() == DemuxerStream::TEXT) {
+- int id_size = 0;
++ size_t id_size = 0;
+ uint8_t* id_data = av_packet_get_side_data(
+ packet.get(), AV_PKT_DATA_WEBVTT_IDENTIFIER, &id_size);
+
+- int settings_size = 0;
++ size_t settings_size = 0;
+ uint8_t* settings_data = av_packet_get_side_data(
+ packet.get(), AV_PKT_DATA_WEBVTT_SETTINGS, &settings_size);
+
+@@ -424,7 +414,7 @@
+ buffer = DecoderBuffer::CopyFrom(packet->data, packet->size,
+ side_data.data(), side_data.size());
+ } else {
+- int side_data_size = 0;
++ size_t side_data_size = 0;
+ uint8_t* side_data = av_packet_get_side_data(
+ packet.get(), AV_PKT_DATA_MATROSKA_BLOCKADDITIONAL, &side_data_size);
+
+@@ -485,7 +475,7 @@
+ packet->size - data_offset);
+ }
+
+- int skip_samples_size = 0;
++ size_t skip_samples_size = 0;
+ const uint32_t* skip_samples_ptr =
+ reinterpret_cast<const uint32_t*>(av_packet_get_side_data(
+ packet.get(), AV_PKT_DATA_SKIP_SAMPLES, &skip_samples_size));
+@@ -1587,6 +1577,8 @@
+ for (const auto& stream : streams_) {
+ if (!stream || stream->IsEnabled() != enabled)
+ continue;
++ if (stream->av_stream()->start_time == AV_NOPTS_VALUE)
++ continue;
+ if (!lowest_start_time_stream ||
+ stream->start_time() < lowest_start_time_stream->start_time()) {
+ lowest_start_time_stream = stream.get();
+@@ -1604,6 +1596,8 @@
+ if (stream && stream->type() == DemuxerStream::VIDEO &&
+ stream->IsEnabled()) {
+ video_stream = stream.get();
++ if (stream->av_stream()->start_time == AV_NOPTS_VALUE)
++ continue;
+ if (video_stream->start_time() <= seek_time) {
+ return video_stream;
+ }
+diff -Naurp qtwebengine-5.15.10.orig/src/3rdparty/chromium/media/ffmpeg/ffmpeg_common.h qtwebengine-5.15.10/src/3rdparty/chromium/media/ffmpeg/ffmpeg_common.h
+--- a/src/3rdparty/chromium/media/ffmpeg/ffmpeg_common.h 2022-05-23 06:38:40.000000000 -0500
++++ b/src/3rdparty/chromium/media/ffmpeg/ffmpeg_common.h 2022-07-11 22:12:47.917192788 -0500
+@@ -29,6 +29,7 @@ extern "C" {
+ #include <libavformat/avformat.h>
+ #include <libavformat/avio.h>
+ #include <libavutil/avutil.h>
++#include <libavutil/channel_layout.h>
+ #include <libavutil/imgutils.h>
+ #include <libavutil/log.h>
+ #include <libavutil/mastering_display_metadata.h>
+diff -Naurp qtwebengine-5.15.10.orig/src/3rdparty/chromium/media/filters/audio_file_reader.cc qtwebengine-5.15.10/src/3rdparty/chromium/media/filters/audio_file_reader.cc
+--- a/src/3rdparty/chromium/media/filters/audio_file_reader.cc 2022-05-23 06:38:40.000000000 -0500
++++ b/src/3rdparty/chromium/media/filters/audio_file_reader.cc 2022-07-11 22:12:47.917192788 -0500
+@@ -85,7 +85,7 @@ bool AudioFileReader::OpenDemuxer() {
+ }
+
+ bool AudioFileReader::OpenDecoder() {
+- AVCodec* codec = avcodec_find_decoder(codec_context_->codec_id);
++ const AVCodec* codec = avcodec_find_decoder(codec_context_->codec_id);
+ if (codec) {
+ // MP3 decodes to S16P which we don't support, tell it to use S16 instead.
+ if (codec_context_->sample_fmt == AV_SAMPLE_FMT_S16P)
+diff -Naurp qtwebengine-5.15.10.orig/src/3rdparty/chromium/media/filters/ffmpeg_audio_decoder.cc qtwebengine-5.15.10/src/3rdparty/chromium/media/filters/ffmpeg_audio_decoder.cc
+--- a/src/3rdparty/chromium/media/filters/ffmpeg_audio_decoder.cc 2022-05-23 06:38:40.000000000 -0500
++++ b/src/3rdparty/chromium/media/filters/ffmpeg_audio_decoder.cc 2022-07-11 22:12:47.917192788 -0500
+@@ -329,7 +329,7 @@ bool FFmpegAudioDecoder::ConfigureDecode
+ }
+ }
+
+- AVCodec* codec = avcodec_find_decoder(codec_context_->codec_id);
++ const AVCodec* codec = avcodec_find_decoder(codec_context_->codec_id);
+ if (!codec ||
+ avcodec_open2(codec_context_.get(), codec, &codec_options) < 0) {
+ DLOG(ERROR) << "Could not initialize audio decoder: "
+diff -Naurp qtwebengine-5.15.10.orig/src/3rdparty/chromium/media/filters/ffmpeg_glue.cc qtwebengine-5.15.10/src/3rdparty/chromium/media/filters/ffmpeg_glue.cc
+--- a/src/3rdparty/chromium/media/filters/ffmpeg_glue.cc 2022-05-23 06:38:40.000000000 -0500
++++ b/src/3rdparty/chromium/media/filters/ffmpeg_glue.cc 2022-07-11 22:12:47.918192779 -0500
+@@ -59,7 +59,6 @@ static int64_t AVIOSeekOperation(void* o
+ }
+
+ void FFmpegGlue::InitializeFFmpeg() {
+- av_register_all();
+ }
+
+ static void LogContainer(bool is_local_file,
+@@ -95,9 +94,6 @@ FFmpegGlue::FFmpegGlue(FFmpegURLProtocol
+ // Enable fast, but inaccurate seeks for MP3.
+ format_context_->flags |= AVFMT_FLAG_FAST_SEEK;
+
+- // Ensures we can read out various metadata bits like vp8 alpha.
+- format_context_->flags |= AVFMT_FLAG_KEEP_SIDE_DATA;
+-
+ // Ensures format parsing errors will bail out. From an audit on 11/2017, all
+ // instances were real failures. Solves bugs like http://crbug.com/710791.
+ format_context_->error_recognition |= AV_EF_EXPLODE;
+diff -Naurp qtwebengine-5.15.10.orig/src/3rdparty/chromium/media/filters/ffmpeg_video_decoder.cc qtwebengine-5.15.10/src/3rdparty/chromium/media/filters/ffmpeg_video_decoder.cc
+--- a/src/3rdparty/chromium/media/filters/ffmpeg_video_decoder.cc 2022-05-23 06:38:40.000000000 -0500
++++ b/src/3rdparty/chromium/media/filters/ffmpeg_video_decoder.cc 2022-07-11 22:12:47.918192779 -0500
+@@ -391,7 +391,7 @@ bool FFmpegVideoDecoder::ConfigureDecode
+ if (decode_nalus_)
+ codec_context_->flags2 |= AV_CODEC_FLAG2_CHUNKS;
+
+- AVCodec* codec = avcodec_find_decoder(codec_context_->codec_id);
++ const AVCodec* codec = avcodec_find_decoder(codec_context_->codec_id);
+ if (!codec || avcodec_open2(codec_context_.get(), codec, NULL) < 0) {
+ ReleaseFFmpegResources();
+ return false;
+diff -Naurp qtwebengine-5.15.10.orig/src/3rdparty/chromium/media/filters/media_file_checker.cc qtwebengine-5.15.10/src/3rdparty/chromium/media/filters/media_file_checker.cc
+--- a/src/3rdparty/chromium/media/filters/media_file_checker.cc 2022-05-23 06:38:40.000000000 -0500
++++ b/src/3rdparty/chromium/media/filters/media_file_checker.cc 2022-07-11 22:12:47.918192779 -0500
+@@ -68,7 +68,7 @@ bool MediaFileChecker::Start(base::TimeD
+ auto context = AVStreamToAVCodecContext(format_context->streams[i]);
+ if (!context)
+ continue;
+- AVCodec* codec = avcodec_find_decoder(cp->codec_id);
++ const AVCodec* codec = avcodec_find_decoder(cp->codec_id);
+ if (codec && avcodec_open2(context.get(), codec, nullptr) >= 0) {
+ auto loop = std::make_unique<FFmpegDecodingLoop>(context.get());
+ stream_contexts[i] = {std::move(context), std::move(loop)};
+diff -Naurp qtwebengine-5.15.10.orig/src/3rdparty/chromium/third_party/webrtc/modules/video_coding/codecs/h264/h264_decoder_impl.cc qtwebengine-5.15.10/src/3rdparty/chromium/third_party/webrtc/modules/video_coding/codecs/h264/h264_decoder_impl.cc
+--- a/src/3rdparty/chromium/third_party/webrtc/modules/video_coding/codecs/h264/h264_decoder_impl.cc 2022-05-23 06:38:40.000000000 -0500
++++ b/src/3rdparty/chromium/third_party/webrtc/modules/video_coding/codecs/h264/h264_decoder_impl.cc 2022-07-11 22:12:47.918192779 -0500
+@@ -203,7 +203,7 @@ int32_t H264DecoderImpl::InitDecode(cons
+ // a pointer |this|.
+ av_context_->opaque = this;
+
+- AVCodec* codec = avcodec_find_decoder(av_context_->codec_id);
++ const AVCodec* codec = avcodec_find_decoder(av_context_->codec_id);
+ if (!codec) {
+ // This is an indication that FFmpeg has not been initialized or it has not
+ // been compiled/initialized with the correct set of codecs.
diff --git a/srcpkgs/qt5-webengine/template b/srcpkgs/qt5-webengine/template
index 0a71484208bc..095ab67701e4 100644
--- a/srcpkgs/qt5-webengine/template
+++ b/srcpkgs/qt5-webengine/template
@@ -1,9 +1,9 @@
# Template file for 'qt5-webengine'
pkgname=qt5-webengine
-version=5.15.11
-revision=2
+version=5.15.13
+revision=1
_version="${version}-lts"
-_chromium_commit=be349eaf62e77955791d7bf29f893f1e8a37daf4
+_chromium_commit=e48df7803c7c98b0b2471c94057d32e44a301ad5
archs="x86_64* i686* armv[67]* ppc64* aarch64*"
create_wrksrc=yes
build_style=qmake
@@ -32,8 +32,8 @@ license="GPL-3.0-or-later, LGPL-3.0-or-later"
homepage="https://qt.io/"
distfiles="https://github.com/qt/qtwebengine/archive/v${_version}.tar.gz
https://github.com/qt/qtwebengine-chromium/archive/${_chromium_commit}.tar.gz"
-checksum="aa7466356c450c5f5870f979b93cd7e7e62da1165c328ffcab1a9928db18ad67
- 6f47ed8ab8cc062411f6f206da6353bc8263d6ed6d6290c689a05c01d91f646b"
+checksum="4b59838ed75ef788b59e1e412535a0e42dd9d311661fdeadb191b581ba815c63
+ a91686562b1d4e8b220e0bbcbab5feb64630e2de974b35ac034bf388af771a6c"
no_generic_pkgconfig_link=yes
build_options="sndio pipewire"
From 28cb7c6dcffc726776dd6d2bdb0b9315cf86335d Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:51 -0400
Subject: [PATCH 077/130] qt5: update to 5.15.8
---
...erywhere-opensource-src-5.15.8-kf5-1.patch | 12913 ++++++++++++++++
srcpkgs/qt5/template | 12 +-
2 files changed, 12919 insertions(+), 6 deletions(-)
create mode 100644 srcpkgs/qt5/patches/qt-everywhere-opensource-src-5.15.8-kf5-1.patch
diff --git a/srcpkgs/qt5/patches/qt-everywhere-opensource-src-5.15.8-kf5-1.patch b/srcpkgs/qt5/patches/qt-everywhere-opensource-src-5.15.8-kf5-1.patch
new file mode 100644
index 000000000000..966c98bcd3bb
--- /dev/null
+++ b/srcpkgs/qt5/patches/qt-everywhere-opensource-src-5.15.8-kf5-1.patch
@@ -0,0 +1,12913 @@
+Submitted By: Pierre Labastie <pierre_dot_labastie_at_neuf_dot_fr>
+Date: 2023-01-05
+Initial Package Version: 5.15.8
+Upstream Status: Applied (according to KDE)
+Origin: KDE patch set
+Description: Patch set maintained by the KDE folks
+see https://dot.kde.org/2021/04/06/announcing-kdes-qt-5-patch-collection
+Patch generated using the procedure in
+https://wiki.linuxfromscratch.org/blfs/ticket/17476#comment:3
+
+Submodule qtbase 4ee4fc18..9cf586d6:
+diff --git a/qtbase/mkspecs/common/android/qplatformdefs.h b/qtbase/mkspecs/common/android/qplatformdefs.h
+index f75bc4093b..2bd59410d4 100644
+--- a/qtbase/mkspecs/common/android/qplatformdefs.h
++++ b/qtbase/mkspecs/common/android/qplatformdefs.h
+@@ -144,11 +144,7 @@
+ #define QT_SIGNAL_ARGS int
+ #define QT_SIGNAL_IGNORE SIG_IGN
+
+-#if defined(__GLIBC__) && (__GLIBC__ >= 2)
+ #define QT_SOCKLEN_T socklen_t
+-#else
+-#define QT_SOCKLEN_T int
+-#endif
+
+ #if defined(_XOPEN_SOURCE) && (_XOPEN_SOURCE >= 500)
+ #define QT_SNPRINTF ::snprintf
+diff --git a/qtbase/mkspecs/features/mac/sdk.mk b/qtbase/mkspecs/features/mac/sdk.mk
+index f30b5830b4..a32ceacb6c 100644
+--- a/qtbase/mkspecs/features/mac/sdk.mk
++++ b/qtbase/mkspecs/features/mac/sdk.mk
+@@ -1,6 +1,6 @@
+
+ ifeq ($(QT_MAC_SDK_NO_VERSION_CHECK),)
+- CHECK_SDK_COMMAND = /usr/bin/xcrun --sdk $(EXPORT_QMAKE_MAC_SDK) -show-sdk-version 2>&1
++ CHECK_SDK_COMMAND = /usr/bin/xcrun --sdk $(EXPORT_QMAKE_MAC_SDK) -show-sdk-version 2>/dev/null
+ CURRENT_MAC_SDK_VERSION := $(shell DEVELOPER_DIR=$(EXPORT_QMAKE_XCODE_DEVELOPER_PATH) $(CHECK_SDK_COMMAND))
+ ifneq ($(CURRENT_MAC_SDK_VERSION),$(EXPORT_QMAKE_MAC_SDK_VERSION))
+ # We don't want to complain about out of date SDK unless the target needs to be remade.
+diff --git a/qtbase/mkspecs/linux-clang/qplatformdefs.h b/qtbase/mkspecs/linux-clang/qplatformdefs.h
+index a818d973f0..c1ab72fbc6 100644
+--- a/qtbase/mkspecs/linux-clang/qplatformdefs.h
++++ b/qtbase/mkspecs/linux-clang/qplatformdefs.h
+@@ -79,14 +79,6 @@
+ #define QT_USE_XOPEN_LFS_EXTENSIONS
+ #include "../common/posix/qplatformdefs.h"
+
+-#undef QT_SOCKLEN_T
+-
+-#if defined(__GLIBC__) && (__GLIBC__ >= 2)
+-#define QT_SOCKLEN_T socklen_t
+-#else
+-#define QT_SOCKLEN_T int
+-#endif
+-
+ #if defined(_XOPEN_SOURCE) && (_XOPEN_SOURCE >= 500)
+ #define QT_SNPRINTF ::snprintf
+ #define QT_VSNPRINTF ::vsnprintf
+diff --git a/qtbase/mkspecs/linux-g++/qplatformdefs.h b/qtbase/mkspecs/linux-g++/qplatformdefs.h
+index 13523f0702..4d2750d9ec 100644
+--- a/qtbase/mkspecs/linux-g++/qplatformdefs.h
++++ b/qtbase/mkspecs/linux-g++/qplatformdefs.h
+@@ -79,14 +79,6 @@
+ #define QT_USE_XOPEN_LFS_EXTENSIONS
+ #include "../common/posix/qplatformdefs.h"
+
+-#undef QT_SOCKLEN_T
+-
+-#if defined(__GLIBC__) && (__GLIBC__ < 2)
+-#define QT_SOCKLEN_T int
+-#else
+-#define QT_SOCKLEN_T socklen_t
+-#endif
+-
+ #if defined(_XOPEN_SOURCE) && (_XOPEN_SOURCE >= 500)
+ #define QT_SNPRINTF ::snprintf
+ #define QT_VSNPRINTF ::vsnprintf
+diff --git a/qtbase/mkspecs/linux-llvm/qplatformdefs.h b/qtbase/mkspecs/linux-llvm/qplatformdefs.h
+index dc750ab1ef..d3cc39b47f 100644
+--- a/qtbase/mkspecs/linux-llvm/qplatformdefs.h
++++ b/qtbase/mkspecs/linux-llvm/qplatformdefs.h
+@@ -80,14 +80,6 @@
+ #define QT_USE_XOPEN_LFS_EXTENSIONS
+ #include "../common/posix/qplatformdefs.h"
+
+-#undef QT_SOCKLEN_T
+-
+-#if defined(__GLIBC__) && (__GLIBC__ >= 2)
+-#define QT_SOCKLEN_T socklen_t
+-#else
+-#define QT_SOCKLEN_T int
+-#endif
+-
+ #if defined(_XOPEN_SOURCE) && (_XOPEN_SOURCE >= 500)
+ #define QT_SNPRINTF ::snprintf
+ #define QT_VSNPRINTF ::vsnprintf
+diff --git a/qtbase/mkspecs/linux-lsb-g++/qplatformdefs.h b/qtbase/mkspecs/linux-lsb-g++/qplatformdefs.h
+index 4c4e53da2a..83baffb3e3 100644
+--- a/qtbase/mkspecs/linux-lsb-g++/qplatformdefs.h
++++ b/qtbase/mkspecs/linux-lsb-g++/qplatformdefs.h
+@@ -85,16 +85,9 @@
+ #include "../common/posix/qplatformdefs.h"
+
+ #undef QT_OPEN_LARGEFILE
+-#undef QT_SOCKLEN_T
+
+ #define QT_OPEN_LARGEFILE 0
+
+-#if defined(__GLIBC__) && (__GLIBC__ >= 2)
+-#define QT_SOCKLEN_T socklen_t
+-#else
+-#define QT_SOCKLEN_T int
+-#endif
+-
+ #ifndef SIOCGIFBRDADDR
+ # define SIOCGIFBRDADDR 0x8919
+ #endif
+diff --git a/qtbase/mkspecs/lynxos-g++/qplatformdefs.h b/qtbase/mkspecs/lynxos-g++/qplatformdefs.h
+index 4339ea2b23..6007af0055 100644
+--- a/qtbase/mkspecs/lynxos-g++/qplatformdefs.h
++++ b/qtbase/mkspecs/lynxos-g++/qplatformdefs.h
+@@ -72,14 +72,6 @@
+
+ #include "../common/posix/qplatformdefs.h"
+
+-#undef QT_SOCKLEN_T
+-
+-#if defined(__GLIBC__) && (__GLIBC__ >= 2)
+-#define QT_SOCKLEN_T socklen_t
+-#else
+-#define QT_SOCKLEN_T int
+-#endif
+-
+ #if defined(_XOPEN_SOURCE) && (_XOPEN_SOURCE >= 500)
+ #define QT_SNPRINTF ::snprintf
+ #define QT_VSNPRINTF ::vsnprintf
+diff --git a/qtbase/src/3rdparty/angle/src/libANGLE/HandleAllocator.cpp b/qtbase/src/3rdparty/angle/src/libANGLE/HandleAllocator.cpp
+index c3c184258f..32af3f8f29 100644
+--- a/qtbase/src/3rdparty/angle/src/libANGLE/HandleAllocator.cpp
++++ b/qtbase/src/3rdparty/angle/src/libANGLE/HandleAllocator.cpp
+@@ -10,6 +10,7 @@
+ #include "libANGLE/HandleAllocator.h"
+
+ #include <algorithm>
++#include <limits>
+
+ #include "common/debug.h"
+
+diff --git a/qtbase/src/3rdparty/forkfd/forkfd_linux.c b/qtbase/src/3rdparty/forkfd/forkfd_linux.c
+index ffe0e9a5e2..b1f5408d11 100644
+--- a/qtbase/src/3rdparty/forkfd/forkfd_linux.c
++++ b/qtbase/src/3rdparty/forkfd/forkfd_linux.c
+@@ -82,7 +82,8 @@ static int sys_clone(unsigned long cloneflags, int *ptid)
+ return syscall(__NR_clone, cloneflags, child_stack, stack_size, ptid, newtls, ctid);
+ #elif defined(__arc__) || defined(__arm__) || defined(__aarch64__) || defined(__mips__) || \
+ defined(__nds32__) || defined(__hppa__) || defined(__powerpc__) || defined(__i386__) || \
+- defined(__x86_64__) || defined(__xtensa__) || defined(__alpha__) || defined(__riscv)
++ defined(__x86_64__) || defined(__xtensa__) || defined(__alpha__) || defined(__riscv) || \
++ defined(__loongarch__)
+ /* ctid and newtls are inverted on CONFIG_CLONE_BACKWARDS architectures,
+ * but since both values are 0, there's no harm. */
+ return syscall(__NR_clone, cloneflags, child_stack, ptid, ctid, newtls);
+diff --git a/qtbase/src/android/jar/src/org/qtproject/qt5/android/QtNative.java b/qtbase/src/android/jar/src/org/qtproject/qt5/android/QtNative.java
+index 5792b5b2f5..2f74750fcf 100644
+--- a/qtbase/src/android/jar/src/org/qtproject/qt5/android/QtNative.java
++++ b/qtbase/src/android/jar/src/org/qtproject/qt5/android/QtNative.java
+@@ -116,6 +116,7 @@ public class QtNative
+ public static QtThread m_qtThread = new QtThread();
+ private static HashMap<String, Uri> m_cachedUris = new HashMap<String, Uri>();
+ private static ArrayList<String> m_knownDirs = new ArrayList<String>();
++ private static final String NoPermissionErrorMessage = "No permissions to open Uri";
+
+ private static final Runnable runPendingCppRunnablesRunnable = new Runnable() {
+ @Override
+@@ -193,11 +194,10 @@ public class QtNative
+ return iterUri;
+ }
+
+- // Android 6 and earlier could still manage to open the file so we can return the
+- // parsed uri here
+- if (Build.VERSION.SDK_INT < 24)
+- return parsedUri;
+- return null;
++ // if we only have transient permissions on uri all the above will fail,
++ // but we will be able to read the file anyway, so continue with uri here anyway
++ // and check for SecurityExceptions later
++ return parsedUri;
+ } catch (SecurityException e) {
+ e.printStackTrace();
+ return null;
+@@ -244,7 +244,7 @@ public class QtNative
+ int error = -1;
+
+ if (uri == null) {
+- Log.e(QtTAG, "openFdForContentUrl(): No permissions to open Uri");
++ Log.e(QtTAG, "openFdForContentUrl(): " + NoPermissionErrorMessage);
+ return error;
+ }
+
+@@ -254,12 +254,13 @@ public class QtNative
+ return fdDesc.detachFd();
+ } catch (FileNotFoundException e) {
+ e.printStackTrace();
+- return error;
+ } catch (IllegalArgumentException e) {
+ Log.e(QtTAG, "openFdForContentUrl(): Invalid Uri");
+ e.printStackTrace();
+- return error;
++ } catch (SecurityException e) {
++ Log.e(QtTAG, NoPermissionErrorMessage);
+ }
++ return error;
+ }
+
+ public static long getSize(Context context, String contentUrl)
+@@ -270,7 +271,7 @@ public class QtNative
+ uri = getUriWithValidPermission(context, contentUrl, "r");
+
+ if (uri == null) {
+- Log.e(QtTAG, "getSize(): No permissions to open Uri");
++ Log.e(QtTAG, NoPermissionErrorMessage);
+ return size;
+ } else if (!m_cachedUris.containsKey(contentUrl)) {
+ m_cachedUris.put(contentUrl, uri);
+@@ -288,12 +289,13 @@ public class QtNative
+ } catch (IllegalArgumentException e) {
+ Log.e(QtTAG, "getSize(): Invalid Uri");
+ e.printStackTrace();
+- return size;
+ } catch (UnsupportedOperationException e) {
+ Log.e(QtTAG, "getSize(): Unsupported operation for given Uri");
+ e.printStackTrace();
+- return size;
++ } catch (SecurityException e) {
++ Log.e(QtTAG, NoPermissionErrorMessage);
+ }
++ return size;
+ }
+
+ public static boolean checkFileExists(Context context, String contentUrl)
+@@ -303,7 +305,7 @@ public class QtNative
+ if (uri == null)
+ uri = getUriWithValidPermission(context, contentUrl, "r");
+ if (uri == null) {
+- Log.e(QtTAG, "checkFileExists(): No permissions to open Uri");
++ Log.e(QtTAG, NoPermissionErrorMessage);
+ return exists;
+ } else {
+ if (!m_cachedUris.containsKey(contentUrl))
+@@ -321,12 +323,13 @@ public class QtNative
+ } catch (IllegalArgumentException e) {
+ Log.e(QtTAG, "checkFileExists(): Invalid Uri");
+ e.printStackTrace();
+- return exists;
+ } catch (UnsupportedOperationException e) {
+ Log.e(QtTAG, "checkFileExists(): Unsupported operation for given Uri");
+ e.printStackTrace();
+- return false;
++ } catch (SecurityException e) {
++ Log.e(QtTAG, NoPermissionErrorMessage);
+ }
++ return exists;
+ }
+
+ public static boolean checkIfWritable(Context context, String contentUrl)
+@@ -344,7 +347,7 @@ public class QtNative
+ uri = getUriWithValidPermission(context, contentUrl, "r");
+ }
+ if (uri == null) {
+- Log.e(QtTAG, "isDir(): No permissions to open Uri");
++ Log.e(QtTAG, NoPermissionErrorMessage);
+ return isDir;
+ } else {
+ if (!m_cachedUris.containsKey(contentUrl))
+@@ -374,12 +377,13 @@ public class QtNative
+ } catch (IllegalArgumentException e) {
+ Log.e(QtTAG, "checkIfDir(): Invalid Uri");
+ e.printStackTrace();
+- return false;
+ } catch (UnsupportedOperationException e) {
+ Log.e(QtTAG, "checkIfDir(): Unsupported operation for given Uri");
+ e.printStackTrace();
+- return false;
++ } catch (SecurityException e) {
++ Log.e(QtTAG, NoPermissionErrorMessage);
+ }
++ return false;
+ }
+ public static String[] listContentsFromTreeUri(Context context, String contentUrl)
+ {
+diff --git a/qtbase/src/concurrent/qtconcurrentreducekernel.h b/qtbase/src/concurrent/qtconcurrentreducekernel.h
+index 8f9a938952..a98dedef2e 100644
+--- a/qtbase/src/concurrent/qtconcurrentreducekernel.h
++++ b/qtbase/src/concurrent/qtconcurrentreducekernel.h
+@@ -212,11 +212,13 @@ public:
+
+ inline bool shouldThrottle()
+ {
++ std::lock_guard<QMutex> locker(mutex);
+ return (resultsMapSize > (ReduceQueueThrottleLimit * threadCount));
+ }
+
+ inline bool shouldStartThread()
+ {
++ std::lock_guard<QMutex> locker(mutex);
+ return (resultsMapSize <= (ReduceQueueStartLimit * threadCount));
+ }
+ };
+diff --git a/qtbase/src/concurrent/qtconcurrentthreadengine.cpp b/qtbase/src/concurrent/qtconcurrentthreadengine.cpp
+index ea6ce3ac42..7f91a2ba68 100644
+--- a/qtbase/src/concurrent/qtconcurrentthreadengine.cpp
++++ b/qtbase/src/concurrent/qtconcurrentthreadengine.cpp
+@@ -176,6 +176,39 @@ void ThreadEngineBase::startSingleThreaded()
+ finish();
+ }
+
++void ThreadEngineBase::startBlocking()
++{
++ start();
++ barrier.acquire();
++ startThreads();
++
++ bool throttled = false;
++#ifndef QT_NO_EXCEPTIONS
++ try {
++#endif
++ while (threadFunction() == ThrottleThread) {
++ if (threadThrottleExit()) {
++ throttled = true;
++ break;
++ }
++ }
++#ifndef QT_NO_EXCEPTIONS
++ } catch (QException &e) {
++ handleException(e);
++ } catch (...) {
++ handleException(QUnhandledException());
++ }
++#endif
++
++ if (throttled == false) {
++ barrier.release();
++ }
++
++ barrier.wait();
++ finish();
++ exceptionStore.throwPossibleException();
++}
++
+ void ThreadEngineBase::startThread()
+ {
+ startThreadInternal();
+diff --git a/qtbase/src/concurrent/qtconcurrentthreadengine.h b/qtbase/src/concurrent/qtconcurrentthreadengine.h
+index 7c30cebdbc..a4c8548cc4 100644
+--- a/qtbase/src/concurrent/qtconcurrentthreadengine.h
++++ b/qtbase/src/concurrent/qtconcurrentthreadengine.h
+@@ -91,6 +91,7 @@ public:
+ ThreadEngineBase();
+ virtual ~ThreadEngineBase();
+ void startSingleThreaded();
++ void startBlocking();
+ void startThread();
+ bool isCanceled();
+ void waitForResume();
+@@ -143,6 +144,15 @@ public:
+ return result();
+ }
+
++ // Runs the user algorithm using multiple threads.
++ // This function blocks until the algorithm is finished,
++ // and then returns the result.
++ T *startBlocking()
++ {
++ ThreadEngineBase::startBlocking();
++ return result();
++ }
++
+ // Runs the user algorithm using multiple threads.
+ // Does not block, returns a future.
+ QFuture<T> startAsynchronously()
+@@ -223,6 +233,13 @@ class ThreadEngineStarter : public ThreadEngineStarterBase<T>
+ public:
+ ThreadEngineStarter(TypedThreadEngine *eng)
+ : Base(eng) { }
++
++ T startBlocking()
++ {
++ T t = *this->threadEngine->startBlocking();
++ delete this->threadEngine;
++ return t;
++ }
+ };
+
+ // Full template specialization where T is void.
+@@ -232,6 +249,12 @@ class ThreadEngineStarter<void> : public ThreadEngineStarterBase<void>
+ public:
+ ThreadEngineStarter(ThreadEngine<void> *_threadEngine)
+ : ThreadEngineStarterBase<void>(_threadEngine) {}
++
++ void startBlocking()
++ {
++ this->threadEngine->startBlocking();
++ delete this->threadEngine;
++ }
+ };
+
+ //! [qtconcurrentthreadengine-1]
+diff --git a/qtbase/src/corelib/animation/qvariantanimation.cpp b/qtbase/src/corelib/animation/qvariantanimation.cpp
+index 98b02f0202..eac1524107 100644
+--- a/qtbase/src/corelib/animation/qvariantanimation.cpp
++++ b/qtbase/src/corelib/animation/qvariantanimation.cpp
+@@ -276,7 +276,9 @@ void QVariantAnimationPrivate::setCurrentValueForProgress(const qreal progress)
+
+ const qreal startProgress = currentInterval.start.first;
+ const qreal endProgress = currentInterval.end.first;
+- const qreal localProgress = (progress - startProgress) / (endProgress - startProgress);
++ const qreal localProgress =
++ qIsNull(progress - startProgress) ? 0.0 // avoid 0/0 below
++ /* else */ : (progress - startProgress) / (endProgress - startProgress);
+
+ QVariant ret = q->interpolated(currentInterval.start.second,
+ currentInterval.end.second,
+diff --git a/qtbase/src/corelib/global/qnamespace.h b/qtbase/src/corelib/global/qnamespace.h
+index ad4150b317..bf19b1627b 100644
+--- a/qtbase/src/corelib/global/qnamespace.h
++++ b/qtbase/src/corelib/global/qnamespace.h
+@@ -1864,7 +1864,7 @@ public:
+ QT_Q_ENUM(TimerType)
+ QT_Q_ENUM(ScrollPhase)
+ QT_Q_ENUM(MouseEventSource)
+- QT_Q_FLAG(MouseEventFlag)
++ QT_Q_FLAG(MouseEventFlags)
+ QT_Q_ENUM(ChecksumType)
+ QT_Q_ENUM(HighDpiScaleFactorRoundingPolicy)
+ QT_Q_ENUM(TabFocusBehavior)
+diff --git a/qtbase/src/corelib/global/qrandom.cpp b/qtbase/src/corelib/global/qrandom.cpp
+index 10672c1f92..25f87c7e6a 100644
+--- a/qtbase/src/corelib/global/qrandom.cpp
++++ b/qtbase/src/corelib/global/qrandom.cpp
+@@ -383,7 +383,6 @@ struct QRandomGenerator::SystemAndGlobalGenerators
+
+ constexpr SystemAndGlobalGenerators g = {};
+ Q_UNUSED(g);
+- Q_STATIC_ASSERT(std::is_literal_type<SystemAndGlobalGenerators>::value);
+ #endif
+ }
+
+diff --git a/qtbase/src/corelib/io/qbuffer.cpp b/qtbase/src/corelib/io/qbuffer.cpp
+index 595fcd2724..032c0ddd4b 100644
+--- a/qtbase/src/corelib/io/qbuffer.cpp
++++ b/qtbase/src/corelib/io/qbuffer.cpp
+@@ -41,6 +41,8 @@
+ #include <QtCore/qmetaobject.h>
+ #include "private/qiodevice_p.h"
+
++#include <limits>
++
+ QT_BEGIN_NAMESPACE
+
+ /** QBufferPrivate **/
+@@ -366,7 +368,9 @@ qint64 QBuffer::size() const
+ bool QBuffer::seek(qint64 pos)
+ {
+ Q_D(QBuffer);
+- if (pos > d->buf->size() && isWritable()) {
++ const auto oldBufSize = d->buf->size();
++ constexpr qint64 MaxSeekPos = (std::numeric_limits<decltype(oldBufSize)>::max)();
++ if (pos <= MaxSeekPos && pos > oldBufSize && isWritable()) {
+ if (seek(d->buf->size())) {
+ const qint64 gapSize = pos - d->buf->size();
+ if (write(QByteArray(gapSize, 0)) != gapSize) {
+@@ -377,7 +381,7 @@ bool QBuffer::seek(qint64 pos)
+ return false;
+ }
+ } else if (pos > d->buf->size() || pos < 0) {
+- qWarning("QBuffer::seek: Invalid pos: %d", int(pos));
++ qWarning("QBuffer::seek: Invalid pos: %lld", pos);
+ return false;
+ }
+ return QIODevice::seek(pos);
+diff --git a/qtbase/src/corelib/io/qfilesystemengine_win.cpp b/qtbase/src/corelib/io/qfilesystemengine_win.cpp
+index 81d3a71986..c86ed1f9b0 100644
+--- a/qtbase/src/corelib/io/qfilesystemengine_win.cpp
++++ b/qtbase/src/corelib/io/qfilesystemengine_win.cpp
+@@ -664,14 +664,14 @@ QFileSystemEntry QFileSystemEngine::absoluteName(const QFileSystemEntry &entry)
+ return QFileSystemEntry(ret, QFileSystemEntry::FromInternalPath());
+ }
+
+-#if defined(Q_CC_MINGW) && WINVER < 0x0602 // Windows 8 onwards
++#if defined(Q_CC_MINGW) && WINVER < 0x0602 && _WIN32_WINNT < _WIN32_WINNT_WIN8 // Windows 8 onwards
+
+ typedef struct _FILE_ID_INFO {
+ ULONGLONG VolumeSerialNumber;
+ FILE_ID_128 FileId;
+ } FILE_ID_INFO, *PFILE_ID_INFO;
+
+-#endif // if defined (Q_CC_MINGW) && WINVER < 0x0602
++#endif // if defined(Q_CC_MINGW) && WINVER < 0x0602 && _WIN32_WINNT < _WIN32_WINNT_WIN8
+
+ // File ID for Windows up to version 7 and FAT32 drives
+ static inline QByteArray fileId(HANDLE handle)
+diff --git a/qtbase/src/corelib/io/qfilesystemwatcher_inotify.cpp b/qtbase/src/corelib/io/qfilesystemwatcher_inotify.cpp
+index 94d9d06bcb..27e0b13b0b 100644
+--- a/qtbase/src/corelib/io/qfilesystemwatcher_inotify.cpp
++++ b/qtbase/src/corelib/io/qfilesystemwatcher_inotify.cpp
+@@ -366,7 +366,9 @@ void QInotifyFileSystemWatcherEngine::readFromInotify()
+ // qDebug("QInotifyFileSystemWatcherEngine::readFromInotify");
+
+ int buffSize = 0;
+- ioctl(inotifyFd, FIONREAD, (char *) &buffSize);
++ if (ioctl(inotifyFd, FIONREAD, (char *) &buffSize) == -1 || buffSize == 0)
++ return;
++
+ QVarLengthArray<char, 4096> buffer(buffSize);
+ buffSize = read(inotifyFd, buffer.data(), buffSize);
+ char *at = buffer.data();
+diff --git a/qtbase/src/corelib/io/qlockfile_win.cpp b/qtbase/src/corelib/io/qlockfile_win.cpp
+index 277f8d4230..38ecef5550 100644
+--- a/qtbase/src/corelib/io/qlockfile_win.cpp
++++ b/qtbase/src/corelib/io/qlockfile_win.cpp
+@@ -48,6 +48,8 @@
+ #include "QtCore/qdebug.h"
+ #include "QtCore/qthread.h"
+
++#include "private/qsystemlibrary_p.h"
++
+ QT_BEGIN_NAMESPACE
+
+ static inline bool fileExists(const wchar_t *fileName)
+@@ -150,7 +152,7 @@ QString QLockFilePrivate::processNameByPid(qint64 pid)
+ #if !defined(Q_OS_WINRT)
+ typedef DWORD (WINAPI *GetModuleFileNameExFunc)(HANDLE, HMODULE, LPTSTR, DWORD);
+
+- HMODULE hPsapi = LoadLibraryA("psapi");
++ HMODULE hPsapi = QSystemLibrary::load(L"psapi");
+ if (!hPsapi)
+ return QString();
+ GetModuleFileNameExFunc qGetModuleFileNameEx = reinterpret_cast<GetModuleFileNameExFunc>(
+diff --git a/qtbase/src/corelib/io/qprocess_unix.cpp b/qtbase/src/corelib/io/qprocess_unix.cpp
+index 50390e57f5..15c8f30745 100644
+--- a/qtbase/src/corelib/io/qprocess_unix.cpp
++++ b/qtbase/src/corelib/io/qprocess_unix.cpp
+@@ -1,7 +1,7 @@
+ /****************************************************************************
+ **
+ ** Copyright (C) 2016 The Qt Company Ltd.
+-** Copyright (C) 2016 Intel Corporation.
++** Copyright (C) 2022 Intel Corporation.
+ ** Contact: https://www.qt.io/licensing/
+ **
+ ** This file is part of the QtCore module of the Qt Toolkit.
+@@ -422,14 +422,15 @@ void QProcessPrivate::startProcess()
+ // Add the program name to the argument list.
+ argv[0] = nullptr;
+ if (!program.contains(QLatin1Char('/'))) {
++ // findExecutable() returns its argument if it's an absolute path,
++ // otherwise it searches $PATH; returns empty if not found (we handle
++ // that case much later)
+ const QString &exeFilePath = QStandardPaths::findExecutable(program);
+- if (!exeFilePath.isEmpty()) {
+- const QByteArray &tmp = QFile::encodeName(exeFilePath);
+- argv[0] = ::strdup(tmp.constData());
+- }
+- }
+- if (!argv[0])
++ const QByteArray &tmp = QFile::encodeName(exeFilePath);
++ argv[0] = ::strdup(tmp.constData());
++ } else {
+ argv[0] = ::strdup(encodedProgramName.constData());
++ }
+
+ // Add every argument to the list
+ for (int i = 0; i < arguments.count(); ++i)
+@@ -983,15 +984,16 @@ bool QProcessPrivate::startDetached(qint64 *pid)
+ envp = _q_dupEnvironment(environment.d.constData()->vars, &envc);
+ }
+
+- QByteArray tmp;
+ if (!program.contains(QLatin1Char('/'))) {
++ // findExecutable() returns its argument if it's an absolute path,
++ // otherwise it searches $PATH; returns empty if not found (we handle
++ // that case much later)
+ const QString &exeFilePath = QStandardPaths::findExecutable(program);
+- if (!exeFilePath.isEmpty())
+- tmp = QFile::encodeName(exeFilePath);
++ const QByteArray &tmp = QFile::encodeName(exeFilePath);
++ argv[0] = ::strdup(tmp.constData());
++ } else {
++ argv[0] = ::strdup(QFile::encodeName(program));
+ }
+- if (tmp.isEmpty())
+- tmp = QFile::encodeName(program);
+- argv[0] = tmp.data();
+
+ if (envp)
+ qt_safe_execve(argv[0], argv, envp);
+diff --git a/qtbase/src/corelib/itemmodels/qabstractitemmodel.cpp b/qtbase/src/corelib/itemmodels/qabstractitemmodel.cpp
+index 3a79c502af..997a634e76 100644
+--- a/qtbase/src/corelib/itemmodels/qabstractitemmodel.cpp
++++ b/qtbase/src/corelib/itemmodels/qabstractitemmodel.cpp
+@@ -3196,9 +3196,8 @@ bool QAbstractItemModel::beginMoveColumns(const QModelIndex &sourceParent, int s
+ destinationChange.needsAdjust = destinationParent.isValid() && destinationParent.row() >= sourceLast && destinationParent.parent() == sourceParent;
+ d->changes.push(destinationChange);
+
+- d->itemsAboutToBeMoved(sourceParent, sourceFirst, sourceLast, destinationParent, destinationChild, Qt::Horizontal);
+-
+ emit columnsAboutToBeMoved(sourceParent, sourceFirst, sourceLast, destinationParent, destinationChild, QPrivateSignal());
++ d->itemsAboutToBeMoved(sourceParent, sourceFirst, sourceLast, destinationParent, destinationChild, Qt::Horizontal);
+ return true;
+ }
+
+@@ -3231,7 +3230,6 @@ void QAbstractItemModel::endMoveColumns()
+ adjustedSource = createIndex(adjustedSource.row(), adjustedSource.column() + numMoved, adjustedSource.internalPointer());
+
+ d->itemsMoved(adjustedSource, removeChange.first, removeChange.last, adjustedDestination, insertChange.first, Qt::Horizontal);
+-
+ emit columnsMoved(adjustedSource, removeChange.first, removeChange.last, adjustedDestination, insertChange.first, QPrivateSignal());
+ }
+
+diff --git a/qtbase/src/corelib/itemmodels/qsortfilterproxymodel.cpp b/qtbase/src/corelib/itemmodels/qsortfilterproxymodel.cpp
+index dc6379d9fb..c5e287ee84 100644
+--- a/qtbase/src/corelib/itemmodels/qsortfilterproxymodel.cpp
++++ b/qtbase/src/corelib/itemmodels/qsortfilterproxymodel.cpp
+@@ -939,8 +939,9 @@ void QSortFilterProxyModelPrivate::insert_source_items(
+ q->beginInsertColumns(proxy_parent, proxy_start, proxy_end);
+ }
+
+- for (int i = 0; i < source_items.size(); ++i)
+- proxy_to_source.insert(proxy_start + i, source_items.at(i));
++ // TODO: use the range QList::insert() overload once it is implemented (QTBUG-58633).
++ proxy_to_source.insert(proxy_start, source_items.size(), 0);
++ std::copy(source_items.cbegin(), source_items.cend(), proxy_to_source.begin() + proxy_start);
+
+ build_source_to_proxy_mapping(proxy_to_source, source_to_proxy);
+
+@@ -3123,8 +3124,9 @@ bool QSortFilterProxyModel::filterAcceptsRow(int source_row, const QModelIndex &
+
+ if (d->filter_data.isEmpty())
+ return true;
++
++ int column_count = d->model->columnCount(source_parent);
+ if (d->filter_column == -1) {
+- int column_count = d->model->columnCount(source_parent);
+ for (int column = 0; column < column_count; ++column) {
+ QModelIndex source_index = d->model->index(source_row, column, source_parent);
+ QString key = d->model->data(source_index, d->filter_role).toString();
+@@ -3133,9 +3135,10 @@ bool QSortFilterProxyModel::filterAcceptsRow(int source_row, const QModelIndex &
+ }
+ return false;
+ }
+- QModelIndex source_index = d->model->index(source_row, d->filter_column, source_parent);
+- if (!source_index.isValid()) // the column may not exist
++
++ if (d->filter_column >= column_count) // the column may not exist
+ return true;
++ QModelIndex source_index = d->model->index(source_row, d->filter_column, source_parent);
+ QString key = d->model->data(source_index, d->filter_role).toString();
+ return d->filter_data.hasMatch(key);
+ }
+diff --git a/qtbase/src/corelib/kernel/qcoreapplication.cpp b/qtbase/src/corelib/kernel/qcoreapplication.cpp
+index ca2864df83..132b2eae52 100644
+--- a/qtbase/src/corelib/kernel/qcoreapplication.cpp
++++ b/qtbase/src/corelib/kernel/qcoreapplication.cpp
+@@ -1157,7 +1157,7 @@ static bool doNotify(QObject *receiver, QEvent *event)
+ bool QCoreApplicationPrivate::sendThroughApplicationEventFilters(QObject *receiver, QEvent *event)
+ {
+ // We can't access the application event filters outside of the main thread (race conditions)
+- Q_ASSERT(receiver->d_func()->threadData.loadRelaxed()->thread.loadAcquire() == mainThread());
++ Q_ASSERT(receiver->d_func()->threadData.loadAcquire()->thread.loadRelaxed() == mainThread());
+
+ if (extraData) {
+ // application event filters are only called for objects in the GUI thread
+diff --git a/qtbase/src/corelib/kernel/qobject.cpp b/qtbase/src/corelib/kernel/qobject.cpp
+index 1eb79138d9..36cd780ee1 100644
+--- a/qtbase/src/corelib/kernel/qobject.cpp
++++ b/qtbase/src/corelib/kernel/qobject.cpp
+@@ -1010,7 +1010,7 @@ QObject::~QObject()
+ emit destroyed(this);
+ }
+
+- if (d->declarativeData) {
++ if (!d->isDeletingChildren && d->declarativeData) {
+ if (static_cast<QAbstractDeclarativeDataImpl*>(d->declarativeData)->ownedByQml1) {
+ if (QAbstractDeclarativeData::destroyed_qml1)
+ QAbstractDeclarativeData::destroyed_qml1(d->declarativeData, this);
+@@ -1580,7 +1580,7 @@ void QObject::moveToThread(QThread *targetThread)
+
+ QThreadData *currentData = QThreadData::current();
+ QThreadData *targetData = targetThread ? QThreadData::get2(targetThread) : nullptr;
+- QThreadData *thisThreadData = d->threadData.loadRelaxed();
++ QThreadData *thisThreadData = d->threadData.loadAcquire();
+ if (!thisThreadData->thread.loadAcquire() && currentData == targetData) {
+ // one exception to the rule: we allow moving objects with no thread affinity to the current thread
+ currentData = d->threadData;
+@@ -2620,7 +2620,7 @@ int QObject::receivers(const char *signal) const
+ if (!d->isSignalConnected(signal_index))
+ return receivers;
+
+- if (d->declarativeData && QAbstractDeclarativeData::receivers) {
++ if (!d->isDeletingChildren && d->declarativeData && QAbstractDeclarativeData::receivers) {
+ receivers += QAbstractDeclarativeData::receivers(d->declarativeData, this,
+ signal_index);
+ }
+diff --git a/qtbase/src/corelib/kernel/qobject_p.h b/qtbase/src/corelib/kernel/qobject_p.h
+index 0b827a52ca..13ffb88999 100644
+--- a/qtbase/src/corelib/kernel/qobject_p.h
++++ b/qtbase/src/corelib/kernel/qobject_p.h
+@@ -444,7 +444,7 @@ inline void QObjectPrivate::checkForIncompatibleLibraryVersion(int version) cons
+
+ inline bool QObjectPrivate::isDeclarativeSignalConnected(uint signal_index) const
+ {
+- return declarativeData && QAbstractDeclarativeData::isSignalConnected
++ return !isDeletingChildren && declarativeData && QAbstractDeclarativeData::isSignalConnected
+ && QAbstractDeclarativeData::isSignalConnected(declarativeData, q_func(), signal_index);
+ }
+
+diff --git a/qtbase/src/corelib/kernel/qtranslator.cpp b/qtbase/src/corelib/kernel/qtranslator.cpp
+index 2812ffb7ea..bc0177c5ec 100644
+--- a/qtbase/src/corelib/kernel/qtranslator.cpp
++++ b/qtbase/src/corelib/kernel/qtranslator.cpp
+@@ -902,7 +902,7 @@ static QString getMessage(const uchar *m, const uchar *end, const char *context,
+ goto end;
+ case Tag_Translation: {
+ int len = read32(m);
+- if (len % 1)
++ if (len & 1)
+ return QString();
+ m += 4;
+ if (!numerus--) {
+diff --git a/qtbase/src/corelib/mimetypes/qmimedatabase.cpp b/qtbase/src/corelib/mimetypes/qmimedatabase.cpp
+index 9de22cef33..ff868a3268 100644
+--- a/qtbase/src/corelib/mimetypes/qmimedatabase.cpp
++++ b/qtbase/src/corelib/mimetypes/qmimedatabase.cpp
+@@ -389,20 +389,23 @@ QMimeType QMimeDatabasePrivate::mimeTypeForFileNameAndData(const QString &fileNa
+ // Disambiguate conflicting extensions (if magic matching found something)
+ if (candidateByData.isValid() && magicAccuracy > 0) {
+ const QString sniffedMime = candidateByData.name();
+- // If the sniffedMime matches a glob match, use it
++ // If the sniffedMime matches a highest-weight glob match, use it
+ if (candidatesByName.m_matchingMimeTypes.contains(sniffedMime)) {
+ *accuracyPtr = 100;
+ return candidateByData;
+ }
+- for (const QString &m : qAsConst(candidatesByName.m_matchingMimeTypes)) {
++ for (const QString &m : qAsConst(candidatesByName.m_allMatchingMimeTypes)) {
+ if (inherits(m, sniffedMime)) {
+ // We have magic + pattern pointing to this, so it's a pretty good match
+ *accuracyPtr = 100;
+ return mimeTypeForName(m);
+ }
+ }
+- *accuracyPtr = magicAccuracy;
+- return candidateByData;
++ if (candidatesByName.m_allMatchingMimeTypes.isEmpty()) {
++ // No glob, use magic
++ *accuracyPtr = magicAccuracy;
++ return candidateByData;
++ }
+ }
+ }
+
+diff --git a/qtbase/src/corelib/mimetypes/qmimeglobpattern.cpp b/qtbase/src/corelib/mimetypes/qmimeglobpattern.cpp
+index a81112d227..fa8f4c545d 100644
+--- a/qtbase/src/corelib/mimetypes/qmimeglobpattern.cpp
++++ b/qtbase/src/corelib/mimetypes/qmimeglobpattern.cpp
+@@ -83,7 +83,10 @@ void QMimeGlobMatchResult::addMatch(const QString &mimeType, int weight, const Q
+ }
+ if (!m_matchingMimeTypes.contains(mimeType)) {
+ m_matchingMimeTypes.append(mimeType);
+- m_allMatchingMimeTypes.append(mimeType);
++ if (replace)
++ m_allMatchingMimeTypes.prepend(mimeType); // highest-weight first
++ else
++ m_allMatchingMimeTypes.append(mimeType);
+ m_knownSuffixLength = knownSuffixLength;
+ }
+ }
+@@ -94,7 +97,7 @@ QMimeGlobPattern::PatternType QMimeGlobPattern::detectPatternType(const QString
+ if (!patternLength)
+ return OtherPattern;
+
+- const bool starCount = pattern.count(QLatin1Char('*')) == 1;
++ const int starCount = pattern.count(QLatin1Char('*'));
+ const bool hasSquareBracket = pattern.indexOf(QLatin1Char('[')) != -1;
+ const bool hasQuestionMark = pattern.indexOf(QLatin1Char('?')) != -1;
+
+@@ -106,10 +109,10 @@ QMimeGlobPattern::PatternType QMimeGlobPattern::detectPatternType(const QString
+ // Patterns like "README*" (well this is currently the only one like that...)
+ if (pattern.at(patternLength - 1) == QLatin1Char('*'))
+ return PrefixPattern;
+- }
+- // Names without any wildcards like "README"
+- if (starCount == 0)
++ } else if (starCount == 0) {
++ // Names without any wildcards like "README"
+ return LiteralPattern;
++ }
+ }
+
+ if (pattern == QLatin1String("[0-9][0-9][0-9].vdr"))
+diff --git a/qtbase/src/corelib/mimetypes/qmimeprovider.cpp b/qtbase/src/corelib/mimetypes/qmimeprovider.cpp
+index 258dddf8cb..4642d0f2d0 100644
+--- a/qtbase/src/corelib/mimetypes/qmimeprovider.cpp
++++ b/qtbase/src/corelib/mimetypes/qmimeprovider.cpp
+@@ -244,15 +244,18 @@ void QMimeBinaryProvider::addFileNameMatches(const QString &fileName, QMimeGlobM
+ const QString lowerFileName = fileName.toLower();
+ // Check literals (e.g. "Makefile")
+ matchGlobList(result, m_cacheFile, m_cacheFile->getUint32(PosLiteralListOffset), fileName);
+- // Check complex globs (e.g. "callgrind.out[0-9]*")
+- matchGlobList(result, m_cacheFile, m_cacheFile->getUint32(PosGlobListOffset), fileName);
+ // Check the very common *.txt cases with the suffix tree
+- const int reverseSuffixTreeOffset = m_cacheFile->getUint32(PosReverseSuffixTreeOffset);
+- const int numRoots = m_cacheFile->getUint32(reverseSuffixTreeOffset);
+- const int firstRootOffset = m_cacheFile->getUint32(reverseSuffixTreeOffset + 4);
+- matchSuffixTree(result, m_cacheFile, numRoots, firstRootOffset, lowerFileName, lowerFileName.length() - 1, false);
++ if (result.m_matchingMimeTypes.isEmpty()) {
++ const int reverseSuffixTreeOffset = m_cacheFile->getUint32(PosReverseSuffixTreeOffset);
++ const int numRoots = m_cacheFile->getUint32(reverseSuffixTreeOffset);
++ const int firstRootOffset = m_cacheFile->getUint32(reverseSuffixTreeOffset + 4);
++ matchSuffixTree(result, m_cacheFile, numRoots, firstRootOffset, lowerFileName, lowerFileName.length() - 1, false);
++ if (result.m_matchingMimeTypes.isEmpty())
++ matchSuffixTree(result, m_cacheFile, numRoots, firstRootOffset, fileName, fileName.length() - 1, true);
++ }
++ // Check complex globs (e.g. "callgrind.out[0-9]*" or "README*")
+ if (result.m_matchingMimeTypes.isEmpty())
+- matchSuffixTree(result, m_cacheFile, numRoots, firstRootOffset, fileName, fileName.length() - 1, true);
++ matchGlobList(result, m_cacheFile, m_cacheFile->getUint32(PosGlobListOffset), fileName);
+ }
+
+ void QMimeBinaryProvider::matchGlobList(QMimeGlobMatchResult &result, CacheFile *cacheFile, int off, const QString &fileName)
+diff --git a/qtbase/src/corelib/serialization/qjsonparser.cpp b/qtbase/src/corelib/serialization/qjsonparser.cpp
+index 17e6f111ab..2e40b6c8fb 100644
+--- a/qtbase/src/corelib/serialization/qjsonparser.cpp
++++ b/qtbase/src/corelib/serialization/qjsonparser.cpp
+@@ -379,10 +379,30 @@ error:
+ return QCborValue();
+ }
+
++// We need to retain the _last_ value for any duplicate keys and we need to deref containers.
++// Therefore the manual implementation of std::unique().
++template<typename Iterator, typename Compare, typename Assign>
++static Iterator customAssigningUniqueLast(Iterator first, Iterator last,
++ Compare compare, Assign assign)
++{
++ first = std::adjacent_find(first, last, compare);
++ if (first == last)
++ return last;
++
++ Iterator result = first;
++ while (++first != last) {
++ if (!compare(*result, *first))
++ ++result;
++ if (result != first)
++ assign(*result, *first);
++ }
++
++ return ++result;
++}
++
+ static void sortContainer(QCborContainerPrivate *container)
+ {
+ using Forward = QJsonPrivate::KeyIterator;
+- using Reverse = std::reverse_iterator<Forward>;
+ using Value = Forward::value_type;
+
+ auto compare = [container](const Value &a, const Value &b)
+@@ -420,17 +440,31 @@ static void sortContainer(QCborContainerPrivate *container)
+ }
+ };
+
+- std::sort(Forward(container->elements.begin()), Forward(container->elements.end()),
+- [&compare](const Value &a, const Value &b) { return compare(a, b) < 0; });
++ // The elements' containers are owned by the outer container, not by the elements themselves.
++ auto move = [](Forward::reference target, Forward::reference source)
++ {
++ QtCbor::Element &targetValue = target.value();
++
++ // If the target has a container, deref it before overwriting, so that we don't leak.
++ if (targetValue.flags & QtCbor::Element::IsContainer)
++ targetValue.container->deref();
++
++ // Do not move, so that we can clear the value afterwards.
++ target = source;
++
++ // Clear the source value, so that we don't store the same container twice.
++ source.value() = QtCbor::Element();
++ };
++
++ std::stable_sort(
++ Forward(container->elements.begin()), Forward(container->elements.end()),
++ [&compare](const Value &a, const Value &b) { return compare(a, b) < 0; });
+
+- // We need to retain the _last_ value for any duplicate keys. Therefore the reverse dance here.
+- auto it = std::unique(Reverse(container->elements.end()), Reverse(container->elements.begin()),
+- [&compare](const Value &a, const Value &b) {
+- return compare(a, b) == 0;
+- }).base().elementsIterator();
++ Forward result = customAssigningUniqueLast(
++ Forward(container->elements.begin()), Forward(container->elements.end()),
++ [&compare](const Value &a, const Value &b) { return compare(a, b) == 0; }, move);
+
+- // The erase from beginning is expensive but hopefully rare.
+- container->elements.erase(container->elements.begin(), it);
++ container->elements.erase(result.elementsIterator(), container->elements.end());
+ }
+
+
+diff --git a/qtbase/src/corelib/serialization/qxmlstream.cpp b/qtbase/src/corelib/serialization/qxmlstream.cpp
+index b2f846544d..7cd457ba3a 100644
+--- a/qtbase/src/corelib/serialization/qxmlstream.cpp
++++ b/qtbase/src/corelib/serialization/qxmlstream.cpp
+@@ -980,7 +980,7 @@ inline uint QXmlStreamReaderPrivate::peekChar()
+ bool QXmlStreamReaderPrivate::scanUntil(const char *str, short tokenToInject)
+ {
+ int pos = textBuffer.size();
+- int oldLineNumber = lineNumber;
++ const auto oldLineNumber = lineNumber;
+
+ uint c;
+ while ((c = getChar()) != StreamEOF) {
+diff --git a/qtbase/src/corelib/text/qstring.cpp b/qtbase/src/corelib/text/qstring.cpp
+index 3e88ab4859..8deeae47bb 100644
+--- a/qtbase/src/corelib/text/qstring.cpp
++++ b/qtbase/src/corelib/text/qstring.cpp
+@@ -12312,7 +12312,7 @@ static qsizetype qLastIndexOf(Haystack haystack0, qsizetype from,
+ const auto needle = needle0.data();
+ const auto *end = haystack;
+ haystack += from;
+- const std::size_t sl_minus_1 = sl - 1;
++ const std::size_t sl_minus_1 = sl ? sl - 1 : 0;
+ const auto *n = needle + sl_minus_1;
+ const auto *h = haystack + sl_minus_1;
+ std::size_t hashNeedle = 0, hashHaystack = 0;
+diff --git a/qtbase/src/corelib/text/qstringiterator_p.h b/qtbase/src/corelib/text/qstringiterator_p.h
+index 219589b6e4..1d0c66cc78 100644
+--- a/qtbase/src/corelib/text/qstringiterator_p.h
++++ b/qtbase/src/corelib/text/qstringiterator_p.h
+@@ -61,6 +61,8 @@ class QStringIterator
+ {
+ QString::const_iterator i, pos, e;
+ Q_STATIC_ASSERT((std::is_same<QString::const_iterator, const QChar *>::value));
++ static bool less(const QChar *lhs, const QChar *rhs) noexcept
++ { return std::less<QString::const_iterator>{}(lhs, rhs); }
+ public:
+ explicit QStringIterator(QStringView string, qsizetype idx = 0)
+ : i(string.begin()),
+@@ -95,7 +97,8 @@ public:
+
+ inline void setPosition(QString::const_iterator position)
+ {
+- Q_ASSERT_X(i <= position && position <= e, Q_FUNC_INFO, "position out of bounds");
++ Q_ASSERT_X(!less(position, i) && !less(e, position),
++ Q_FUNC_INFO, "position out of bounds");
+ pos = position;
+ }
+
+@@ -103,7 +106,7 @@ public:
+
+ inline bool hasNext() const
+ {
+- return pos < e;
++ return less(pos, e);
+ }
+
+ inline void advance()
+@@ -120,16 +123,20 @@ public:
+ {
+ Q_ASSERT_X(hasNext(), Q_FUNC_INFO, "iterator hasn't a next item");
+
+- if (Q_UNLIKELY((pos++)->isHighSurrogate()))
++ if (Q_UNLIKELY((pos++)->isHighSurrogate())) {
++ Q_ASSERT(hasNext() && pos->isLowSurrogate());
+ ++pos;
++ }
+ }
+
+ inline uint peekNextUnchecked() const
+ {
+ Q_ASSERT_X(hasNext(), Q_FUNC_INFO, "iterator hasn't a next item");
+
+- if (Q_UNLIKELY(pos->isHighSurrogate()))
++ if (Q_UNLIKELY(pos->isHighSurrogate())) {
++ Q_ASSERT(less(pos + 1, e) && pos[1].isLowSurrogate());
+ return QChar::surrogateToUcs4(pos[0], pos[1]);
++ }
+
+ return pos->unicode();
+ }
+@@ -155,8 +162,10 @@ public:
+ Q_ASSERT_X(hasNext(), Q_FUNC_INFO, "iterator hasn't a next item");
+
+ const QChar cur = *pos++;
+- if (Q_UNLIKELY(cur.isHighSurrogate()))
++ if (Q_UNLIKELY(cur.isHighSurrogate())) {
++ Q_ASSERT(hasNext() && pos->isLowSurrogate());
+ return QChar::surrogateToUcs4(cur, *pos++);
++ }
+ return cur.unicode();
+ }
+
+@@ -166,7 +175,7 @@ public:
+
+ const QChar uc = *pos++;
+ if (Q_UNLIKELY(uc.isSurrogate())) {
+- if (Q_LIKELY(uc.isHighSurrogate() && pos < e && pos->isLowSurrogate()))
++ if (Q_LIKELY(uc.isHighSurrogate() && hasNext() && pos->isLowSurrogate()))
+ return QChar::surrogateToUcs4(uc, *pos++);
+ return invalidAs;
+ }
+@@ -178,7 +187,7 @@ public:
+
+ inline bool hasPrevious() const
+ {
+- return pos > i;
++ return less(i, pos);
+ }
+
+ inline void recede()
+@@ -196,16 +205,20 @@ public:
+ {
+ Q_ASSERT_X(hasPrevious(), Q_FUNC_INFO, "iterator hasn't a previous item");
+
+- if (Q_UNLIKELY((--pos)->isLowSurrogate()))
++ if (Q_UNLIKELY((--pos)->isLowSurrogate())) {
++ Q_ASSERT(hasPrevious() && pos[-1].isHighSurrogate());
+ --pos;
++ }
+ }
+
+ inline uint peekPreviousUnchecked() const
+ {
+ Q_ASSERT_X(hasPrevious(), Q_FUNC_INFO, "iterator hasn't a previous item");
+
+- if (Q_UNLIKELY(pos[-1].isLowSurrogate()))
++ if (Q_UNLIKELY(pos[-1].isLowSurrogate())) {
++ Q_ASSERT(less(i + 1, pos) && pos[-2].isHighSurrogate());
+ return QChar::surrogateToUcs4(pos[-2], pos[-1]);
++ }
+ return pos[-1].unicode();
+ }
+
+@@ -230,8 +243,10 @@ public:
+ Q_ASSERT_X(hasPrevious(), Q_FUNC_INFO, "iterator hasn't a previous item");
+
+ const QChar cur = *--pos;
+- if (Q_UNLIKELY(cur.isLowSurrogate()))
++ if (Q_UNLIKELY(cur.isLowSurrogate())) {
++ Q_ASSERT(hasPrevious() && pos[-1].isHighSurrogate());
+ return QChar::surrogateToUcs4(*--pos, cur);
++ }
+ return cur.unicode();
+ }
+
+@@ -241,7 +256,7 @@ public:
+
+ const QChar uc = *--pos;
+ if (Q_UNLIKELY(uc.isSurrogate())) {
+- if (Q_LIKELY(uc.isLowSurrogate() && pos > i && pos[-1].isHighSurrogate()))
++ if (Q_LIKELY(uc.isLowSurrogate() && hasPrevious() && pos[-1].isHighSurrogate()))
+ return QChar::surrogateToUcs4(*--pos, uc);
+ return invalidAs;
+ }
+diff --git a/qtbase/src/corelib/thread/qfutex_p.h b/qtbase/src/corelib/thread/qfutex_p.h
+index f287b752d7..e294537787 100644
+--- a/qtbase/src/corelib/thread/qfutex_p.h
++++ b/qtbase/src/corelib/thread/qfutex_p.h
+@@ -52,6 +52,7 @@
+ //
+
+ #include <qglobal.h>
++#include <QtCore/qtsan_impl.h>
+
+ QT_BEGIN_NAMESPACE
+
+@@ -106,16 +107,13 @@ namespace QtLinuxFutex {
+ inline int _q_futex(int *addr, int op, int val, quintptr val2 = 0,
+ int *addr2 = nullptr, int val3 = 0) noexcept
+ {
+- // A futex call ensures total ordering on the futex words
+- // (in either success or failure of the call). Instruct TSAN accordingly,
+- // as TSAN does not understand the futex(2) syscall.
+- _q_tsan_release(addr, addr2);
++ QtTsan::futexRelease(addr, addr2);
+
+ // we use __NR_futex because some libcs (like Android's bionic) don't
+ // provide SYS_futex etc.
+ int result = syscall(__NR_futex, addr, op | FUTEX_PRIVATE_FLAG, val, val2, addr2, val3);
+
+- _q_tsan_acquire(addr, addr2);
++ QtTsan::futexAcquire(addr, addr2);
+
+ return result;
+ }
+diff --git a/qtbase/src/corelib/thread/qmutex.cpp b/qtbase/src/corelib/thread/qmutex.cpp
+index 310d1cb14f..7097122d8e 100644
+--- a/qtbase/src/corelib/thread/qmutex.cpp
++++ b/qtbase/src/corelib/thread/qmutex.cpp
+@@ -152,6 +152,7 @@ public:
+
+ /*!
+ \enum QMutex::RecursionMode
++ \obsolete Use QRecursiveMutex to create a recursive mutex.
+
+ \value Recursive In this mode, a thread can lock the same mutex
+ multiple times and the mutex won't be unlocked
+@@ -173,6 +174,7 @@ public:
+
+ /*!
+ Constructs a new mutex. The mutex is created in an unlocked state.
++ \obsolete Use QRecursiveMutex to create a recursive mutex.
+
+ If \a mode is QMutex::Recursive, a thread can lock the same mutex
+ multiple times and the mutex won't be unlocked until a
+@@ -197,7 +199,7 @@ QMutex::QMutex(RecursionMode mode)
+ QMutex::~QMutex()
+ {
+ QMutexData *d = d_ptr.loadRelaxed();
+- if (isRecursive()) {
++ if (QBasicMutex::isRecursive()) {
+ delete static_cast<QRecursiveMutexPrivate *>(d);
+ } else if (d) {
+ #ifndef QT_LINUX_FUTEX
+diff --git a/qtbase/src/corelib/thread/qmutex.h b/qtbase/src/corelib/thread/qmutex.h
+index 73c9e00663..1bae573a03 100644
+--- a/qtbase/src/corelib/thread/qmutex.h
++++ b/qtbase/src/corelib/thread/qmutex.h
+@@ -42,6 +42,7 @@
+
+ #include <QtCore/qglobal.h>
+ #include <QtCore/qatomic.h>
++#include <QtCore/qtsan_impl.h>
+ #include <new>
+
+ #if __has_include(<chrono>)
+@@ -77,19 +78,37 @@ public:
+
+ // BasicLockable concept
+ inline void lock() QT_MUTEX_LOCK_NOEXCEPT {
++ QtTsan::mutexPreLock(this, 0u);
++
+ if (!fastTryLock())
+ lockInternal();
++
++ QtTsan::mutexPostLock(this, 0u, 0);
+ }
+
+ // BasicLockable concept
+ inline void unlock() noexcept {
+ Q_ASSERT(d_ptr.loadRelaxed()); //mutex must be locked
++
++ QtTsan::mutexPreUnlock(this, 0u);
++
+ if (!fastTryUnlock())
+ unlockInternal();
++
++ QtTsan::mutexPostUnlock(this, 0u);
+ }
+
+ bool tryLock() noexcept {
+- return fastTryLock();
++ unsigned tsanFlags = QtTsan::TryLock;
++ QtTsan::mutexPreLock(this, tsanFlags);
++
++ const bool success = fastTryLock();
++
++ if (!success)
++ tsanFlags |= QtTsan::TryLockFailed;
++ QtTsan::mutexPostLock(this, tsanFlags, 0);
++
++ return success;
+ }
+
+ // Lockable concept
+@@ -134,8 +153,16 @@ public:
+ #else
+ QMutex() { d_ptr.storeRelaxed(nullptr); }
+ #endif
++#if QT_DEPRECATED_SINCE(5,15)
+ enum RecursionMode { NonRecursive, Recursive };
++ QT_DEPRECATED_VERSION_X(5, 15, "Use QRecursiveMutex instead of a recursive QMutex")
+ explicit QMutex(RecursionMode mode);
++
++ QT_DEPRECATED_VERSION_X(5, 15, "Use QRecursiveMutex instead of a recursive QMutex")
++ bool isRecursive() const noexcept
++ { return QBasicMutex::isRecursive(); }
++#endif
++
+ ~QMutex();
+
+ // BasicLockable concept
+@@ -166,9 +193,6 @@ public:
+ }
+ #endif
+
+- bool isRecursive() const noexcept
+- { return QBasicMutex::isRecursive(); }
+-
+ private:
+ Q_DISABLE_COPY(QMutex)
+ friend class QMutexLocker;
+diff --git a/qtbase/src/corelib/thread/qreadwritelock.cpp b/qtbase/src/corelib/thread/qreadwritelock.cpp
+index 8c28507d5a..9dd8503116 100644
+--- a/qtbase/src/corelib/thread/qreadwritelock.cpp
++++ b/qtbase/src/corelib/thread/qreadwritelock.cpp
+@@ -155,7 +155,7 @@ QReadWriteLock::QReadWriteLock(RecursionMode recursionMode)
+ */
+ QReadWriteLock::~QReadWriteLock()
+ {
+- auto d = d_ptr.loadRelaxed();
++ auto d = d_ptr.loadAcquire();
+ if (isUncontendedLocked(d)) {
+ qWarning("QReadWriteLock: destroying locked QReadWriteLock");
+ return;
+@@ -445,7 +445,7 @@ void QReadWriteLock::unlock()
+ /*! \internal Helper for QWaitCondition::wait */
+ QReadWriteLock::StateForWaitCondition QReadWriteLock::stateForWaitCondition() const
+ {
+- QReadWriteLockPrivate *d = d_ptr.loadRelaxed();
++ QReadWriteLockPrivate *d = d_ptr.loadAcquire();
+ switch (quintptr(d) & StateMask) {
+ case StateLockedForRead: return LockedForRead;
+ case StateLockedForWrite: return LockedForWrite;
+@@ -453,6 +453,7 @@ QReadWriteLock::StateForWaitCondition QReadWriteLock::stateForWaitCondition() co
+
+ if (!d)
+ return Unlocked;
++ const auto lock = qt_scoped_lock(d->mutex);
+ if (d->writerCount > 1)
+ return RecursivelyLocked;
+ else if (d->writerCount == 1)
+diff --git a/qtbase/src/corelib/thread/qsemaphore.cpp b/qtbase/src/corelib/thread/qsemaphore.cpp
+index 1d01fc1b28..3ecdee3747 100644
+--- a/qtbase/src/corelib/thread/qsemaphore.cpp
++++ b/qtbase/src/corelib/thread/qsemaphore.cpp
+@@ -354,7 +354,12 @@ void QSemaphore::release(int n)
+ quintptr nn = unsigned(n);
+ if (futexHasWaiterCount)
+ nn |= quint64(nn) << 32; // token count replicated in high word
+- quintptr prevValue = u.fetchAndAddRelease(nn);
++ quintptr prevValue = u.loadRelaxed();
++ quintptr newValue;
++ do { // loop just to ensure the operations are done atomically
++ newValue = prevValue + nn;
++ newValue &= (futexNeedsWakeAllBit - 1);
++ } while (!u.testAndSetRelease(prevValue, newValue, prevValue));
+ if (futexNeedsWake(prevValue)) {
+ #ifdef FUTEX_OP
+ if (futexHasWaiterCount) {
+@@ -376,7 +381,6 @@ void QSemaphore::release(int n)
+ quint32 oparg = 0;
+ quint32 cmp = FUTEX_OP_CMP_NE;
+ quint32 cmparg = 0;
+- u.fetchAndAndRelease(futexNeedsWakeAllBit - 1);
+ futexWakeOp(*futexLow32(&u), n, INT_MAX, *futexHigh32(&u), FUTEX_OP(op, oparg, cmp, cmparg));
+ return;
+ }
+@@ -388,7 +392,6 @@ void QSemaphore::release(int n)
+ // its acquisition anyway, so it has to wait;
+ // 2) it did not see the new counter value, in which case its
+ // futexWait will fail.
+- u.fetchAndAndRelease(futexNeedsWakeAllBit - 1);
+ if (futexHasWaiterCount) {
+ futexWakeAll(*futexLow32(&u));
+ futexWakeAll(*futexHigh32(&u));
+diff --git a/qtbase/src/corelib/thread/qthread_p.h b/qtbase/src/corelib/thread/qthread_p.h
+index b2d1628e6e..f32f6f0460 100644
+--- a/qtbase/src/corelib/thread/qthread_p.h
++++ b/qtbase/src/corelib/thread/qthread_p.h
+@@ -174,7 +174,7 @@ public:
+ int returnCode;
+
+ uint stackSize;
+- QThread::Priority priority;
++ std::underlying_type<QThread::Priority>::type priority;
+
+ static QThread *threadForId(int id);
+
+@@ -213,6 +213,13 @@ public:
+ QCoreApplication::instance()->postEvent(q_ptr, new QEvent(QEvent::Quit));
+ }
+ }
++
++#ifndef Q_OS_INTEGRITY
++private:
++ // Used in QThread(Private)::start to avoid racy access to QObject::objectName,
++ // unset afterwards. On INTEGRITY we set the thread name before starting it.
++ QString objectName;
++#endif
+ };
+
+ #else // QT_CONFIG(thread)
+diff --git a/qtbase/src/corelib/thread/qthread_unix.cpp b/qtbase/src/corelib/thread/qthread_unix.cpp
+index 56a8e0a038..610117a640 100644
+--- a/qtbase/src/corelib/thread/qthread_unix.cpp
++++ b/qtbase/src/corelib/thread/qthread_unix.cpp
+@@ -169,8 +169,7 @@ static void set_thread_data(QThreadData *data)
+
+ static void clear_thread_data()
+ {
+- currentThreadData = nullptr;
+- pthread_setspecific(current_thread_data_key, nullptr);
++ set_thread_data(nullptr);
+ }
+
+ template <typename T>
+@@ -296,7 +295,7 @@ void *QThreadPrivate::start(void *arg)
+ QMutexLocker locker(&thr->d_func()->mutex);
+
+ // do we need to reset the thread priority?
+- if (int(thr->d_func()->priority) & ThreadPriorityResetFlag) {
++ if (thr->d_func()->priority & ThreadPriorityResetFlag) {
+ thr->d_func()->setPriority(QThread::Priority(thr->d_func()->priority & ~ThreadPriorityResetFlag));
+ }
+
+@@ -316,10 +315,10 @@ void *QThreadPrivate::start(void *arg)
+ // Sets the name of the current thread. We can only do this
+ // when the thread is starting, as we don't have a cross
+ // platform way of setting the name of an arbitrary thread.
+- if (Q_LIKELY(thr->objectName().isEmpty()))
++ if (Q_LIKELY(thr->d_func()->objectName.isEmpty()))
+ setCurrentThreadName(thr->metaObject()->className());
+ else
+- setCurrentThreadName(thr->objectName().toLocal8Bit());
++ setCurrentThreadName(std::exchange(thr->d_func()->objectName, {}).toLocal8Bit());
+ }
+ #endif
+
+@@ -671,7 +670,7 @@ void QThread::start(Priority priority)
+ // could not set scheduling hints, fallback to inheriting them
+ // we'll try again from inside the thread
+ pthread_attr_setinheritsched(&attr, PTHREAD_INHERIT_SCHED);
+- d->priority = Priority(priority | ThreadPriorityResetFlag);
++ d->priority = static_cast<std::underlying_type<QThread::Priority>::type>(priority) | ThreadPriorityResetFlag;
+ }
+ break;
+ }
+@@ -702,7 +701,10 @@ void QThread::start(Priority priority)
+ pthread_attr_setthreadname(&attr, metaObject()->className());
+ else
+ pthread_attr_setthreadname(&attr, objectName().toLocal8Bit());
++#else
++ d->objectName = objectName();
+ #endif
++
+ pthread_t threadId;
+ int code = pthread_create(&threadId, &attr, QThreadPrivate::start, this);
+ if (code == EPERM) {
+diff --git a/qtbase/src/corelib/thread/qthread_win.cpp b/qtbase/src/corelib/thread/qthread_win.cpp
+index bc70e3178a..4e76972498 100644
+--- a/qtbase/src/corelib/thread/qthread_win.cpp
++++ b/qtbase/src/corelib/thread/qthread_win.cpp
+@@ -394,10 +394,9 @@ unsigned int __stdcall QT_ENSURE_STACK_ALIGNED_FOR_SSE QThreadPrivate::start(voi
+
+ #if !defined(QT_NO_DEBUG) && defined(Q_CC_MSVC) && !defined(Q_OS_WINRT)
+ // sets the name of the current thread.
+- QByteArray objectName = thr->objectName().toLocal8Bit();
+- qt_set_thread_name(HANDLE(-1),
+- objectName.isEmpty() ?
+- thr->metaObject()->className() : objectName.constData());
++ qt_set_thread_name(HANDLE(-1), thr->d_func()->objectName.isEmpty()
++ ? thr->metaObject()->className()
++ : std::exchange(thr->d_func()->objectName, {}).toLocal8Bit().constData());
+ #endif
+
+ emit thr->started(QThread::QPrivateSignal());
+@@ -503,6 +502,7 @@ void QThread::start(Priority priority)
+ if (d->running)
+ return;
+
++ d->objectName = objectName();
+ d->running = true;
+ d->finished = false;
+ d->exited = false;
+@@ -548,7 +548,7 @@ void QThread::start(Priority priority)
+
+ int prio;
+ d->priority = priority;
+- switch (d->priority) {
++ switch (priority) {
+ case IdlePriority:
+ prio = THREAD_PRIORITY_IDLE;
+ break;
+@@ -686,7 +686,7 @@ void QThreadPrivate::setPriority(QThread::Priority threadPriority)
+
+ int prio;
+ priority = threadPriority;
+- switch (priority) {
++ switch (threadPriority) {
+ case QThread::IdlePriority:
+ prio = THREAD_PRIORITY_IDLE;
+ break;
+diff --git a/qtbase/src/corelib/thread/qtsan_impl.h b/qtbase/src/corelib/thread/qtsan_impl.h
+new file mode 100644
+index 0000000000..580a738b91
+--- /dev/null
++++ b/qtbase/src/corelib/thread/qtsan_impl.h
+@@ -0,0 +1,115 @@
++/****************************************************************************
++**
++** Copyright (C) 2017 Intel Corporation.
++** Copyright (C) 2022 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Giuseppe D'Angelo <giuseppe.dangelo@kdab.com>
++** Contact: https://www.qt.io/licensing/
++**
++** This file is part of the QtCore module of the Qt Toolkit.
++**
++** $QT_BEGIN_LICENSE:LGPL$
++** Commercial License Usage
++** Licensees holding valid commercial Qt licenses may use this file in
++** accordance with the commercial license agreement provided with the
++** Software or, alternatively, in accordance with the terms contained in
++** a written agreement between you and The Qt Company. For licensing terms
++** and conditions see https://www.qt.io/terms-conditions. For further
++** information use the contact form at https://www.qt.io/contact-us.
++**
++** GNU Lesser General Public License Usage
++** Alternatively, this file may be used under the terms of the GNU Lesser
++** General Public License version 3 as published by the Free Software
++** Foundation and appearing in the file LICENSE.LGPL3 included in the
++** packaging of this file. Please review the following information to
++** ensure the GNU Lesser General Public License version 3 requirements
++** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
++**
++** GNU General Public License Usage
++** Alternatively, this file may be used under the terms of the GNU
++** General Public License version 2.0 or (at your option) the GNU General
++** Public license version 3 or any later version approved by the KDE Free
++** Qt Foundation. The licenses are as published by the Free Software
++** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
++** included in the packaging of this file. Please review the following
++** information to ensure the GNU General Public License requirements will
++** be met: https://www.gnu.org/licenses/gpl-2.0.html and
++** https://www.gnu.org/licenses/gpl-3.0.html.
++**
++** $QT_END_LICENSE$
++**
++****************************************************************************/
++
++#ifndef QTSAN_IMPL_H
++#define QTSAN_IMPL_H
++
++#include <QtCore/qglobal.h>
++
++#if (__has_feature(thread_sanitizer) || defined(__SANITIZE_THREAD__)) && __has_include(<sanitizer/tsan_interface.h>)
++# define QT_BUILDING_UNDER_TSAN
++# include <sanitizer/tsan_interface.h>
++#endif
++
++QT_BEGIN_NAMESPACE
++
++namespace QtTsan {
++#ifdef QT_BUILDING_UNDER_TSAN
++inline void futexAcquire(void *addr, void *addr2 = nullptr)
++{
++ // A futex call ensures total ordering on the futex words
++ // (in either success or failure of the call). Instruct TSAN accordingly,
++ // as TSAN does not understand the futex(2) syscall (or equivalent).
++ ::__tsan_acquire(addr);
++ if (addr2)
++ ::__tsan_acquire(addr2);
++}
++
++inline void futexRelease(void *addr, void *addr2 = nullptr)
++{
++ if (addr2)
++ ::__tsan_release(addr2);
++ ::__tsan_release(addr);
++}
++
++inline void mutexPreLock(void *addr, unsigned flags)
++{
++ ::__tsan_mutex_pre_lock(addr, flags);
++}
++
++inline void mutexPostLock(void *addr, unsigned flags, int recursion)
++{
++ ::__tsan_mutex_post_lock(addr, flags, recursion);
++}
++
++inline void mutexPreUnlock(void *addr, unsigned flags)
++{
++ ::__tsan_mutex_pre_unlock(addr, flags);
++}
++
++inline void mutexPostUnlock(void *addr, unsigned flags)
++{
++ ::__tsan_mutex_post_unlock(addr, flags);
++}
++
++enum : unsigned {
++ MutexWriteReentrant = ::__tsan_mutex_write_reentrant,
++ TryLock = ::__tsan_mutex_try_lock,
++ TryLockFailed = ::__tsan_mutex_try_lock_failed,
++};
++#else
++inline void futexAcquire(void *, void * = nullptr) {}
++inline void futexRelease(void *, void * = nullptr) {}
++
++enum : unsigned {
++ MutexWriteReentrant,
++ TryLock,
++ TryLockFailed,
++};
++inline void mutexPreLock(void *, unsigned) {}
++inline void mutexPostLock(void *, unsigned, int) {}
++inline void mutexPreUnlock(void *, unsigned) {}
++inline void mutexPostUnlock(void *, unsigned) {}
++#endif // QT_BUILDING_UNDER_TSAN
++} // namespace QtTsan
++
++QT_END_NAMESPACE
++
++#endif // QTSAN_IMPL_H
+diff --git a/qtbase/src/corelib/thread/qwaitcondition_unix.cpp b/qtbase/src/corelib/thread/qwaitcondition_unix.cpp
+index 88b058f410..0f1da4dc9b 100644
+--- a/qtbase/src/corelib/thread/qwaitcondition_unix.cpp
++++ b/qtbase/src/corelib/thread/qwaitcondition_unix.cpp
+@@ -213,7 +213,7 @@ bool QWaitCondition::wait(QMutex *mutex, QDeadlineTimer deadline)
+ {
+ if (! mutex)
+ return false;
+- if (mutex->isRecursive()) {
++ if (static_cast<QBasicMutex *>(mutex)->isRecursive()) {
+ qWarning("QWaitCondition: cannot wait on recursive mutexes");
+ return false;
+ }
+diff --git a/qtbase/src/corelib/time/qdatetime.cpp b/qtbase/src/corelib/time/qdatetime.cpp
+index ec12569e3f..2c0b098079 100644
+--- a/qtbase/src/corelib/time/qdatetime.cpp
++++ b/qtbase/src/corelib/time/qdatetime.cpp
+@@ -43,6 +43,7 @@
+ #if QT_CONFIG(datetimeparser)
+ #include "private/qdatetimeparser_p.h"
+ #endif
++#include <private/qnumeric_p.h>
+
+ #include "qdatastream.h"
+ #include "qset.h"
+@@ -1429,9 +1430,11 @@ QDate QDate::addDays(qint64 ndays) const
+ if (isNull())
+ return QDate();
+
+- // Due to limits on minJd() and maxJd() we know that any overflow
+- // will be invalid and caught by fromJulianDay().
+- return fromJulianDay(jd + ndays);
++ qint64 r;
++ if (Q_UNLIKELY(add_overflow(jd, ndays, &r)))
++ return QDate();
++ else
++ return fromJulianDay(r);
+ }
+
+ /*!
+diff --git a/qtbase/src/corelib/time/qtimezone.cpp b/qtbase/src/corelib/time/qtimezone.cpp
+index 0309e43e52..3d451696a1 100644
+--- a/qtbase/src/corelib/time/qtimezone.cpp
++++ b/qtbase/src/corelib/time/qtimezone.cpp
+@@ -1,6 +1,6 @@
+ /****************************************************************************
+ **
+-** Copyright (C) 2013 John Layt <jlayt@kde.org>
++** Copyright (C) 2020 John Layt <jlayt@kde.org>
+ ** Contact: https://www.qt.io/licensing/
+ **
+ ** This file is part of the QtCore module of the Qt Toolkit.
+@@ -975,9 +975,15 @@ QList<QByteArray> QTimeZone::windowsIdToIanaIds(const QByteArray &windowsId,
+ }
+
+ #ifndef QT_NO_DATASTREAM
++// Invalid, as an IANA ID: too long, starts with - and has other invalid characters in it
++static inline QString invalidId() { return QStringLiteral("-No Time Zone Specified!"); }
++
+ QDataStream &operator<<(QDataStream &ds, const QTimeZone &tz)
+ {
+- tz.d->serialize(ds);
++ if (tz.isValid())
++ tz.d->serialize(ds);
++ else
++ ds << invalidId();
+ return ds;
+ }
+
+@@ -985,7 +991,9 @@ QDataStream &operator>>(QDataStream &ds, QTimeZone &tz)
+ {
+ QString ianaId;
+ ds >> ianaId;
+- if (ianaId == QLatin1String("OffsetFromUtc")) {
++ if (ianaId == invalidId()) {
++ tz = QTimeZone();
++ } else if (ianaId == QLatin1String("OffsetFromUtc")) {
+ int utcOffset;
+ QString name;
+ QString abbreviation;
+diff --git a/qtbase/src/corelib/time/qtimezoneprivate_tz.cpp b/qtbase/src/corelib/time/qtimezoneprivate_tz.cpp
+index b1611d7ddb..a7a6a72ccf 100644
+--- a/qtbase/src/corelib/time/qtimezoneprivate_tz.cpp
++++ b/qtbase/src/corelib/time/qtimezoneprivate_tz.cpp
+@@ -42,6 +42,7 @@
+ #include "qtimezone.h"
+ #include "qtimezoneprivate_p.h"
+ #include "private/qlocale_tools_p.h"
++#include "private/qlocking_p.h"
+
+ #include <QtCore/QDataStream>
+ #include <QtCore/QDateTime>
+@@ -62,6 +63,10 @@
+
+ QT_BEGIN_NAMESPACE
+
++#if QT_CONFIG(icu)
++static QBasicMutex s_icu_mutex;
++#endif
++
+ /*
+ Private
+
+@@ -670,6 +675,9 @@ QTzTimeZonePrivate::~QTzTimeZonePrivate()
+
+ QTzTimeZonePrivate *QTzTimeZonePrivate::clone() const
+ {
++#if QT_CONFIG(icu)
++ const auto lock = qt_scoped_lock(s_icu_mutex);
++#endif
+ return new QTzTimeZonePrivate(*this);
+ }
+
+@@ -913,12 +921,14 @@ QString QTzTimeZonePrivate::displayName(qint64 atMSecsSinceEpoch,
+ const QLocale &locale) const
+ {
+ #if QT_CONFIG(icu)
++ auto lock = qt_unique_lock(s_icu_mutex);
+ if (!m_icu)
+ m_icu = new QIcuTimeZonePrivate(m_id);
+ // TODO small risk may not match if tran times differ due to outdated files
+ // TODO Some valid TZ names are not valid ICU names, use translation table?
+ if (m_icu->isValid())
+ return m_icu->displayName(atMSecsSinceEpoch, nameType, locale);
++ lock.unlock();
+ #else
+ Q_UNUSED(nameType)
+ Q_UNUSED(locale)
+@@ -932,12 +942,14 @@ QString QTzTimeZonePrivate::displayName(QTimeZone::TimeType timeType,
+ const QLocale &locale) const
+ {
+ #if QT_CONFIG(icu)
++ auto lock = qt_unique_lock(s_icu_mutex);
+ if (!m_icu)
+ m_icu = new QIcuTimeZonePrivate(m_id);
+ // TODO small risk may not match if tran times differ due to outdated files
+ // TODO Some valid TZ names are not valid ICU names, use translation table?
+ if (m_icu->isValid())
+ return m_icu->displayName(timeType, nameType, locale);
++ lock.unlock();
+ #else
+ Q_UNUSED(timeType)
+ Q_UNUSED(nameType)
+diff --git a/qtbase/src/corelib/tools/qarraydata.h b/qtbase/src/corelib/tools/qarraydata.h
+index dcd95924c1..d01739e7e6 100644
+--- a/qtbase/src/corelib/tools/qarraydata.h
++++ b/qtbase/src/corelib/tools/qarraydata.h
+@@ -42,6 +42,7 @@
+
+ #include <QtCore/qrefcount.h>
+ #include <string.h>
++#include <cstdint>
+
+ QT_BEGIN_NAMESPACE
+
+@@ -58,14 +59,14 @@ struct Q_CORE_EXPORT QArrayData
+ {
+ Q_ASSERT(size == 0
+ || offset < 0 || size_t(offset) >= sizeof(QArrayData));
+- return reinterpret_cast<char *>(this) + offset;
++ return reinterpret_cast<void *> (reinterpret_cast<uintptr_t>(this) + offset);
+ }
+
+ const void *data() const
+ {
+ Q_ASSERT(size == 0
+ || offset < 0 || size_t(offset) >= sizeof(QArrayData));
+- return reinterpret_cast<const char *>(this) + offset;
++ return reinterpret_cast<void *> (reinterpret_cast<uintptr_t>(this) + offset);
+ }
+
+ // This refers to array data mutability, not "header data" represented by
+diff --git a/qtbase/src/corelib/tools/qfreelist_p.h b/qtbase/src/corelib/tools/qfreelist_p.h
+index 5ba23b344b..9974102136 100644
+--- a/qtbase/src/corelib/tools/qfreelist_p.h
++++ b/qtbase/src/corelib/tools/qfreelist_p.h
+@@ -161,7 +161,7 @@ class QFreeList
+ return i;
+ x -= size;
+ }
+- Q_ASSERT(false);
++ Q_UNREACHABLE();
+ return -1;
+ }
+
+diff --git a/qtbase/src/corelib/tools/qversionnumber.h b/qtbase/src/corelib/tools/qversionnumber.h
+index d43b86ba51..2843f2b043 100644
+--- a/qtbase/src/corelib/tools/qversionnumber.h
++++ b/qtbase/src/corelib/tools/qversionnumber.h
+@@ -273,10 +273,10 @@ public:
+
+ Q_REQUIRED_RESULT Q_CORE_EXPORT QString toString() const;
+ #if QT_STRINGVIEW_LEVEL < 2
+- Q_REQUIRED_RESULT Q_CORE_EXPORT static Q_DECL_PURE_FUNCTION QVersionNumber fromString(const QString &string, int *suffixIndex = nullptr);
++ Q_REQUIRED_RESULT Q_CORE_EXPORT static QVersionNumber fromString(const QString &string, int *suffixIndex = nullptr);
+ #endif
+- Q_REQUIRED_RESULT Q_CORE_EXPORT static Q_DECL_PURE_FUNCTION QVersionNumber fromString(QLatin1String string, int *suffixIndex = nullptr);
+- Q_REQUIRED_RESULT Q_CORE_EXPORT static Q_DECL_PURE_FUNCTION QVersionNumber fromString(QStringView string, int *suffixIndex = nullptr);
++ Q_REQUIRED_RESULT Q_CORE_EXPORT static QVersionNumber fromString(QLatin1String string, int *suffixIndex = nullptr);
++ Q_REQUIRED_RESULT Q_CORE_EXPORT static QVersionNumber fromString(QStringView string, int *suffixIndex = nullptr);
+
+ private:
+ #ifndef QT_NO_DATASTREAM
+diff --git a/qtbase/src/dbus/qdbusintegrator.cpp b/qtbase/src/dbus/qdbusintegrator.cpp
+index 5b66ce971b..28a3b0ffea 100644
+--- a/qtbase/src/dbus/qdbusintegrator.cpp
++++ b/qtbase/src/dbus/qdbusintegrator.cpp
+@@ -1135,7 +1135,13 @@ void QDBusConnectionPrivate::closeConnection()
+ }
+ }
+
+- qDeleteAll(pendingCalls);
++ for (auto it = pendingCalls.begin(); it != pendingCalls.end(); ++it) {
++ auto call = *it;
++ if (!call->ref.deref()) {
++ delete call;
++ }
++ }
++ pendingCalls.clear();
+
+ // Disconnect all signals from signal hooks and from the object tree to
+ // avoid QObject::destroyed being sent to dbus daemon thread which has
+@@ -2584,6 +2590,11 @@ QDBusConnectionPrivate::findMetaObject(const QString &service, const QString &pa
+ if (mo)
+ return mo;
+ }
++ if (path.isEmpty()) {
++ error = QDBusError(QDBusError::InvalidObjectPath, QLatin1String("Object path cannot be empty"));
++ lastError = error;
++ return nullptr;
++ }
+
+ // introspect the target object
+ QDBusMessage msg = QDBusMessage::createMethodCall(service, path,
+diff --git a/qtbase/src/dbus/qdbusmetaobject.cpp b/qtbase/src/dbus/qdbusmetaobject.cpp
+index 5265568f42..7e9f0f1acc 100644
+--- a/qtbase/src/dbus/qdbusmetaobject.cpp
++++ b/qtbase/src/dbus/qdbusmetaobject.cpp
+@@ -210,6 +210,9 @@ QDBusMetaObjectGenerator::findType(const QByteArray &signature,
+ } else if (signature == "a{ss}") {
+ result.name = "QMap<QString,QString>";
+ type = qMetaTypeId<QMap<QString, QString> >();
++ } else if (signature == "aay") {
++ result.name = "QByteArrayList";
++ type = qMetaTypeId<QByteArrayList>();
+ } else {
+ result.name = "{D-Bus type \"" + signature + "\"}";
+ type = registerComplexDBusType(result.name);
+diff --git a/qtbase/src/gui/accessible/qaccessible.cpp b/qtbase/src/gui/accessible/qaccessible.cpp
+index d705bfccb5..0caf3c808c 100644
+--- a/qtbase/src/gui/accessible/qaccessible.cpp
++++ b/qtbase/src/gui/accessible/qaccessible.cpp
+@@ -54,6 +54,7 @@
+ #include <QtCore/qdebug.h>
+ #include <QtCore/qloggingcategory.h>
+ #include <QtCore/qmetaobject.h>
++#include <QtCore/private/qmetaobject_p.h>
+ #include <QtCore/qhash.h>
+ #include <private/qfactoryloader_p.h>
+
+@@ -681,6 +682,25 @@ QAccessibleInterface *QAccessible::queryAccessibleInterface(QObject *object)
+ // Create a QAccessibleInterface for the object class. Start by the most
+ // derived class and walk up the class hierarchy.
+ const QMetaObject *mo = object->metaObject();
++ const auto *objectPriv = QObjectPrivate::get(object);
++ /*
++ We do not want to cache each and every QML metaobject (Button_QMLTYPE_124,
++ Button_QMLTYPE_125, etc.). Those dynamic metaobjects shouldn't have an
++ accessible interface in any case. Instead, we start the whole checking
++ with the first non-dynamic meta-object. To avoid potential regressions
++ in other areas of Qt that also use dynamic metaobjects, we only do this
++ for objects that are QML-related (approximated by checking whether they
++ have ddata set).
++ */
++ const bool qmlRelated = !objectPriv->isDeletingChildren &&
++ objectPriv->declarativeData;
++ while (qmlRelated && mo) {
++ auto mop = QMetaObjectPrivate::get(mo);
++ if (!mop || !(mop->flags & DynamicMetaObject))
++ break;
++
++ mo = mo->superClass();
++ };
+ while (mo) {
+ const QString cn = QLatin1String(mo->className());
+
+@@ -696,14 +716,15 @@ QAccessibleInterface *QAccessible::queryAccessibleInterface(QObject *object)
+ // Find a QAccessiblePlugin (factory) for the class name. If there's
+ // no entry in the cache try to create it using the plugin loader.
+ if (!qAccessiblePlugins()->contains(cn)) {
++ QAccessiblePlugin *factory = nullptr; // 0 means "no plugin found". This is cached as well.
+ const int index = loader()->indexOf(cn);
+- if (index != -1) {
+- QAccessiblePlugin *factory = qobject_cast<QAccessiblePlugin *>(loader()->instance(index));
+- qAccessiblePlugins()->insert(cn, factory);
+- }
++ if (index != -1)
++ factory = qobject_cast<QAccessiblePlugin *>(loader()->instance(index));
++ qAccessiblePlugins()->insert(cn, factory);
+ }
+
+ // At this point the cache should contain a valid factory pointer or 0:
++ Q_ASSERT(qAccessiblePlugins()->contains(cn));
+ QAccessiblePlugin *factory = qAccessiblePlugins()->value(cn);
+ if (factory) {
+ QAccessibleInterface *result = factory->create(cn, object);
+diff --git a/qtbase/src/gui/configure.json b/qtbase/src/gui/configure.json
+index 1f08795c57..12c95742d2 100644
+--- a/qtbase/src/gui/configure.json
++++ b/qtbase/src/gui/configure.json
+@@ -834,7 +834,8 @@
+ "// embedded devices, are not intended to be used together with X. EGL support",
+ "// has to be disabled in plugins like xcb in this case since the native display,",
+ "// window and pixmap types will be different than what an X-based platform",
+- "// plugin would expect."
++ "// plugin would expect.",
++ "#define USE_X11"
+ ],
+ "include": [ "EGL/egl.h", "X11/Xlib.h" ],
+ "main": [
+diff --git a/qtbase/src/gui/image/qbmphandler.cpp b/qtbase/src/gui/image/qbmphandler.cpp
+index 96f1e8cb1d..0e73bbbdb0 100644
+--- a/qtbase/src/gui/image/qbmphandler.cpp
++++ b/qtbase/src/gui/image/qbmphandler.cpp
+@@ -150,16 +150,42 @@ static QDataStream &operator<<(QDataStream &s, const BMP_INFOHDR &bi)
+ return s;
+ }
+
+-static int calc_shift(uint mask)
++static uint calc_shift(uint mask)
+ {
+- int result = 0;
+- while (mask && !(mask & 1)) {
++ uint result = 0;
++ while ((mask >= 0x100) || (!(mask & 1) && mask)) {
+ result++;
+ mask >>= 1;
+ }
+ return result;
+ }
+
++static uint calc_scale(uint low_mask)
++{
++ uint result = 8;
++ while (low_mask && result) {
++ result--;
++ low_mask >>= 1;
++ }
++ return result;
++}
++
++static inline uint apply_scale(uint value, uint scale)
++{
++ if (!(scale & 0x07)) // return immediately if scale == 8 or 0
++ return value;
++
++ uint filled = 8 - scale;
++ uint result = value << scale;
++
++ do {
++ result |= result >> filled;
++ filled <<= 1;
++ } while (filled < 8);
++
++ return result;
++}
++
+ static bool read_dib_fileheader(QDataStream &s, BMP_FILEHDR &bf)
+ {
+ // read BMP file header
+@@ -222,14 +248,14 @@ static bool read_dib_body(QDataStream &s, const BMP_INFOHDR &bi, qint64 offset,
+ uint green_mask = 0;
+ uint blue_mask = 0;
+ uint alpha_mask = 0;
+- int red_shift = 0;
+- int green_shift = 0;
+- int blue_shift = 0;
+- int alpha_shift = 0;
+- int red_scale = 0;
+- int green_scale = 0;
+- int blue_scale = 0;
+- int alpha_scale = 0;
++ uint red_shift = 0;
++ uint green_shift = 0;
++ uint blue_shift = 0;
++ uint alpha_shift = 0;
++ uint red_scale = 0;
++ uint green_scale = 0;
++ uint blue_scale = 0;
++ uint alpha_scale = 0;
+
+ if (!d->isSequential())
+ d->seek(startpos + BMP_FILEHDR_SIZE + bi.biSize); // goto start of colormap or masks
+@@ -308,19 +334,19 @@ static bool read_dib_body(QDataStream &s, const BMP_INFOHDR &bi, qint64 offset,
+ red_shift = calc_shift(red_mask);
+ if (((red_mask >> red_shift) + 1) == 0)
+ return false;
+- red_scale = 256 / ((red_mask >> red_shift) + 1);
++ red_scale = calc_scale(red_mask >> red_shift);
+ green_shift = calc_shift(green_mask);
+ if (((green_mask >> green_shift) + 1) == 0)
+ return false;
+- green_scale = 256 / ((green_mask >> green_shift) + 1);
++ green_scale = calc_scale(green_mask >> green_shift);
+ blue_shift = calc_shift(blue_mask);
+ if (((blue_mask >> blue_shift) + 1) == 0)
+ return false;
+- blue_scale = 256 / ((blue_mask >> blue_shift) + 1);
++ blue_scale = calc_scale(blue_mask >> blue_shift);
+ alpha_shift = calc_shift(alpha_mask);
+ if (((alpha_mask >> alpha_shift) + 1) == 0)
+ return false;
+- alpha_scale = 256 / ((alpha_mask >> alpha_shift) + 1);
++ alpha_scale = calc_scale(alpha_mask >> alpha_shift);
+ } else if (comp == BMP_RGB && (nbits == 24 || nbits == 32)) {
+ blue_mask = 0x000000ff;
+ green_mask = 0x0000ff00;
+@@ -328,17 +354,15 @@ static bool read_dib_body(QDataStream &s, const BMP_INFOHDR &bi, qint64 offset,
+ blue_shift = 0;
+ green_shift = 8;
+ red_shift = 16;
+- blue_scale = green_scale = red_scale = 1;
++ blue_scale = green_scale = red_scale = 0;
+ } else if (comp == BMP_RGB && nbits == 16) {
+ blue_mask = 0x001f;
+ green_mask = 0x03e0;
+ red_mask = 0x7c00;
+ blue_shift = 0;
+- green_shift = 2;
+- red_shift = 7;
+- red_scale = 1;
+- green_scale = 1;
+- blue_scale = 8;
++ green_shift = 5;
++ red_shift = 10;
++ blue_scale = green_scale = red_scale = 3;
+ }
+
+ #if 0
+@@ -544,10 +568,10 @@ static bool read_dib_body(QDataStream &s, const BMP_INFOHDR &bi, qint64 offset,
+ c |= *(uchar*)(b+2)<<16;
+ if (nbits > 24)
+ c |= *(uchar*)(b+3)<<24;
+- *p++ = qRgba(((c & red_mask) >> red_shift) * red_scale,
+- ((c & green_mask) >> green_shift) * green_scale,
+- ((c & blue_mask) >> blue_shift) * blue_scale,
+- transp ? ((c & alpha_mask) >> alpha_shift) * alpha_scale : 0xff);
++ *p++ = qRgba(apply_scale((c & red_mask) >> red_shift, red_scale),
++ apply_scale((c & green_mask) >> green_shift, green_scale),
++ apply_scale((c & blue_mask) >> blue_shift, blue_scale),
++ transp ? apply_scale((c & alpha_mask) >> alpha_shift, alpha_scale) : 0xff);
+ b += nbits/8;
+ }
+ }
+diff --git a/qtbase/src/gui/image/qimage.cpp b/qtbase/src/gui/image/qimage.cpp
+index 7152ac1607..0df772564c 100644
+--- a/qtbase/src/gui/image/qimage.cpp
++++ b/qtbase/src/gui/image/qimage.cpp
+@@ -4694,6 +4694,8 @@ QImage QImage::smoothScaled(int w, int h) const {
+ static QImage rotated90(const QImage &image)
+ {
+ QImage out(image.height(), image.width(), image.format());
++ if (out.isNull())
++ return out;
+ copyMetadata(&out, image);
+ if (image.colorCount() > 0)
+ out.setColorTable(image.colorTable());
+@@ -4722,6 +4724,8 @@ static QImage rotated180(const QImage &image)
+ return image.mirrored(true, true);
+
+ QImage out(image.width(), image.height(), image.format());
++ if (out.isNull())
++ return out;
+ copyMetadata(&out, image);
+ if (image.colorCount() > 0)
+ out.setColorTable(image.colorTable());
+@@ -4734,6 +4738,8 @@ static QImage rotated180(const QImage &image)
+ static QImage rotated270(const QImage &image)
+ {
+ QImage out(image.height(), image.width(), image.format());
++ if (out.isNull())
++ return out;
+ copyMetadata(&out, image);
+ if (image.colorCount() > 0)
+ out.setColorTable(image.colorTable());
+diff --git a/qtbase/src/gui/kernel/qcursor.cpp b/qtbase/src/gui/kernel/qcursor.cpp
+index d6ccaff8ed..455088241c 100644
+--- a/qtbase/src/gui/kernel/qcursor.cpp
++++ b/qtbase/src/gui/kernel/qcursor.cpp
+@@ -251,7 +251,8 @@ void QCursor::setPos(QScreen *screen, int x, int y)
+ {
+ if (screen) {
+ if (QPlatformCursor *cursor = screen->handle()->cursor()) {
+- const QPoint devicePos = QHighDpi::toNativePixels(QPoint(x, y), screen);
++ const QPoint pos(x, y);
++ const QPoint devicePos = QHighDpi::toNativePixels(pos, screen->virtualSiblingAt(pos));
+ // Need to check, since some X servers generate null mouse move
+ // events, causing looping in applications which call setPos() on
+ // every mouse move event.
+diff --git a/qtbase/src/gui/kernel/qhighdpiscaling.cpp b/qtbase/src/gui/kernel/qhighdpiscaling.cpp
+index 9bbf2773a9..3ac4a4d8b6 100644
+--- a/qtbase/src/gui/kernel/qhighdpiscaling.cpp
++++ b/qtbase/src/gui/kernel/qhighdpiscaling.cpp
+@@ -580,9 +580,8 @@ void QHighDpiScaling::setScreenFactor(QScreen *screen, qreal factor)
+ else
+ qNamedScreenScaleFactors()->insert(name, factor);
+
+- // hack to force re-evaluation of screen geometry
+ if (screen->handle())
+- screen->d_func()->setPlatformScreen(screen->handle()); // updates geometries based on scale factor
++ screen->d_func()->updateLogicalDpi();
+ }
+
+ QPoint QHighDpiScaling::mapPositionToNative(const QPoint &pos, const QPlatformScreen *platformScreen)
+diff --git a/qtbase/src/gui/kernel/qkeysequence.cpp b/qtbase/src/gui/kernel/qkeysequence.cpp
+index a75b8ef920..4f2d294739 100644
+--- a/qtbase/src/gui/kernel/qkeysequence.cpp
++++ b/qtbase/src/gui/kernel/qkeysequence.cpp
+@@ -701,6 +701,10 @@ static const struct {
+ { Qt::Key_TouchpadToggle, QT_TRANSLATE_NOOP("QShortcut", "Touchpad Toggle") },
+ { Qt::Key_TouchpadOn, QT_TRANSLATE_NOOP("QShortcut", "Touchpad On") },
+ { Qt::Key_TouchpadOff, QT_TRANSLATE_NOOP("QShortcut", "Touchpad Off") },
++ { Qt::Key_Shift, QT_TRANSLATE_NOOP("QShortcut", "Shift") },
++ { Qt::Key_Control, QT_TRANSLATE_NOOP("QShortcut", "Control") },
++ { Qt::Key_Alt, QT_TRANSLATE_NOOP("QShortcut", "Alt") },
++ { Qt::Key_Meta, QT_TRANSLATE_NOOP("QShortcut", "Meta") },
+
+ };
+ static Q_CONSTEXPR int numKeyNames = sizeof keyname / sizeof *keyname;
+diff --git a/qtbase/src/gui/kernel/qplatformservices.cpp b/qtbase/src/gui/kernel/qplatformservices.cpp
+index fdc6a6c4aa..ac47f98c5d 100644
+--- a/qtbase/src/gui/kernel/qplatformservices.cpp
++++ b/qtbase/src/gui/kernel/qplatformservices.cpp
+@@ -55,6 +55,19 @@ QT_BEGIN_NAMESPACE
+ \brief The QPlatformServices provides the backend for desktop-related functionality.
+ */
+
++/*!
++ \enum QPlatformServices::Capability
++
++ Capabilities are used to determine a specific platform service's availability.
++
++ \value ColorPickingFromScreen The platform natively supports color picking from screen.
++ This capability indicates that the platform supports "opaque" color picking, where the
++ platform implements a complete user experience for color picking and outputs a color.
++ This is in contrast to the application implementing the color picking user experience
++ (taking care of showing a cross hair, instructing the platform integration to obtain
++ the color at a given pixel, etc.). The related service function is pickColor().
++ */
++
+ QPlatformServices::QPlatformServices()
+ { }
+
+@@ -85,5 +98,16 @@ QByteArray QPlatformServices::desktopEnvironment() const
+ return QByteArray("UNKNOWN");
+ }
+
++QPlatformServiceColorPicker *QPlatformServices::colorPicker(QWindow *parent)
++{
++ Q_UNUSED(parent);
++ return nullptr;
++}
++
++bool QPlatformServices::hasCapability(Capability capability) const
++{
++ Q_UNUSED(capability)
++ return false;
++}
+
+ QT_END_NAMESPACE
+diff --git a/qtbase/src/gui/kernel/qplatformservices.h b/qtbase/src/gui/kernel/qplatformservices.h
+index 5de96cfa7d..a8b2a4ce71 100644
+--- a/qtbase/src/gui/kernel/qplatformservices.h
++++ b/qtbase/src/gui/kernel/qplatformservices.h
+@@ -50,16 +50,32 @@
+ //
+
+ #include <QtGui/qtguiglobal.h>
++#include <QtCore/qobject.h>
+
+ QT_BEGIN_NAMESPACE
+
+ class QUrl;
++class QWindow;
++
++class Q_GUI_EXPORT QPlatformServiceColorPicker : public QObject
++{
++ Q_OBJECT
++public:
++ using QObject::QObject;
++ virtual void pickColor() = 0;
++Q_SIGNALS:
++ void colorPicked(const QColor &color);
++};
+
+ class Q_GUI_EXPORT QPlatformServices
+ {
+ public:
+ Q_DISABLE_COPY_MOVE(QPlatformServices)
+
++ enum Capability {
++ ColorPicking,
++ };
++
+ QPlatformServices();
+ virtual ~QPlatformServices() { }
+
+@@ -67,6 +83,10 @@ public:
+ virtual bool openDocument(const QUrl &url);
+
+ virtual QByteArray desktopEnvironment() const;
++
++ virtual bool hasCapability(Capability capability) const;
++
++ virtual QPlatformServiceColorPicker *colorPicker(QWindow *parent = nullptr);
+ };
+
+ QT_END_NAMESPACE
+diff --git a/qtbase/src/gui/kernel/qplatformtheme.cpp b/qtbase/src/gui/kernel/qplatformtheme.cpp
+index 71521c0339..2325873245 100644
+--- a/qtbase/src/gui/kernel/qplatformtheme.cpp
++++ b/qtbase/src/gui/kernel/qplatformtheme.cpp
+@@ -163,6 +163,8 @@ QT_BEGIN_NAMESPACE
+
+ \value ShowShortcutsInContextMenus (bool) Whether to display shortcut key sequences in context menus.
+
++ \value ButtonPressKeys (QList<Qt::Key>) A list of keys that can be used to press buttons via keyboard input.
++
+ \sa themeHint(), QStyle::pixelMetric()
+ */
+
+@@ -563,6 +565,8 @@ QVariant QPlatformTheme::defaultThemeHint(ThemeHint hint)
+ }
+ case MouseQuickSelectionThreshold:
+ return QVariant(10);
++ case ButtonPressKeys:
++ return QVariant::fromValue(QList<Qt::Key>({ Qt::Key_Space, Qt::Key_Select }));
+ }
+ return QVariant();
+ }
+diff --git a/qtbase/src/gui/kernel/qplatformtheme.h b/qtbase/src/gui/kernel/qplatformtheme.h
+index 3185fc4541..7e6c9d5740 100644
+--- a/qtbase/src/gui/kernel/qplatformtheme.h
++++ b/qtbase/src/gui/kernel/qplatformtheme.h
+@@ -120,7 +120,8 @@ public:
+ TouchDoubleTapDistance,
+ ShowShortcutsInContextMenus,
+ IconFallbackSearchPaths,
+- MouseQuickSelectionThreshold
++ MouseQuickSelectionThreshold,
++ ButtonPressKeys
+ };
+
+ enum DialogType {
+diff --git a/qtbase/src/gui/kernel/qscreen.cpp b/qtbase/src/gui/kernel/qscreen.cpp
+index 8e0eb35116..5d172a58dd 100644
+--- a/qtbase/src/gui/kernel/qscreen.cpp
++++ b/qtbase/src/gui/kernel/qscreen.cpp
+@@ -77,6 +77,12 @@ QScreen::QScreen(QPlatformScreen *screen)
+ d->setPlatformScreen(screen);
+ }
+
++void QScreenPrivate::updateLogicalDpi()
++{
++ logicalDpi = QPlatformScreen::overrideDpi(platformScreen->logicalDpi());
++ updateGeometriesWithSignals(); // updates geometries based on scale factor
++}
++
+ void QScreenPrivate::updateGeometriesWithSignals()
+ {
+ const QRect oldGeometry = geometry;
+diff --git a/qtbase/src/gui/kernel/qscreen_p.h b/qtbase/src/gui/kernel/qscreen_p.h
+index 7da542c25e..e50fc3190b 100644
+--- a/qtbase/src/gui/kernel/qscreen_p.h
++++ b/qtbase/src/gui/kernel/qscreen_p.h
+@@ -70,6 +70,7 @@ public:
+ geometry = platformScreen->deviceIndependentGeometry();
+ availableGeometry = QHighDpi::fromNative(platformScreen->availableGeometry(), QHighDpiScaling::factor(platformScreen), geometry.topLeft());
+ }
++ void updateLogicalDpi();
+
+ void updatePrimaryOrientation();
+ void updateGeometriesWithSignals();
+diff --git a/qtbase/src/gui/painting/qblendfunctions_p.h b/qtbase/src/gui/painting/qblendfunctions_p.h
+index 080da98ec4..6997d62b3c 100644
+--- a/qtbase/src/gui/painting/qblendfunctions_p.h
++++ b/qtbase/src/gui/painting/qblendfunctions_p.h
+@@ -246,25 +246,32 @@ void qt_transform_image_rasterize(DestT *destPixels, int dbpl,
+ int dudx, int dvdx, int dudy, int dvdy, int u0, int v0,
+ Blender blender)
+ {
+- int fromY = qMax(qRound(topY), clip.top());
+- int toY = qMin(qRound(bottomY), clip.top() + clip.height());
++ qint64 fromY = qMax(qRound(topY), clip.top());
++ qint64 toY = qMin(qRound(bottomY), clip.top() + clip.height());
+ if (fromY >= toY)
+ return;
+
+ qreal leftSlope = (bottomLeft.x - topLeft.x) / (bottomLeft.y - topLeft.y);
+ qreal rightSlope = (bottomRight.x - topRight.x) / (bottomRight.y - topRight.y);
+- int dx_l = int(leftSlope * 0x10000);
+- int dx_r = int(rightSlope * 0x10000);
+- int x_l = int((topLeft.x + (qreal(0.5) + fromY - topLeft.y) * leftSlope + qreal(0.5)) * 0x10000);
+- int x_r = int((topRight.x + (qreal(0.5) + fromY - topRight.y) * rightSlope + qreal(0.5)) * 0x10000);
+-
+- int fromX, toX, x1, x2, u, v, i, ii;
++ qint64 dx_l = qint64(leftSlope * 0x10000);
++ qint64 dx_r = qint64(rightSlope * 0x10000);
++ qint64 x_l = qint64((topLeft.x + (qreal(0.5) + fromY - topLeft.y) * leftSlope + qreal(0.5)) * 0x10000);
++ qint64 x_r = qint64((topRight.x + (qreal(0.5) + fromY - topRight.y) * rightSlope + qreal(0.5)) * 0x10000);
++
++ qint64 sourceRectTop = qint64(sourceRect.top());
++ qint64 sourceRectLeft = qint64(sourceRect.left());
++ qint64 sourceRectWidth = qint64(sourceRect.width());
++ qint64 sourceRectHeight = qint64(sourceRect.height());
++ qint64 clipLeft = qint64(clip.left());
++ qint64 clipWidth = qint64(clip.width());
++
++ qint64 fromX, toX, x1, x2, u, v, i, ii;
+ DestT *line;
+- for (int y = fromY; y < toY; ++y) {
++ for (qint64 y = fromY; y < toY; ++y) {
+ line = reinterpret_cast<DestT *>(reinterpret_cast<uchar *>(destPixels) + y * dbpl);
+
+- fromX = qMax(x_l >> 16, clip.left());
+- toX = qMin(x_r >> 16, clip.left() + clip.width());
++ fromX = qMax(x_l >> 16, clipLeft);
++ toX = qMin(x_r >> 16, clipLeft + clipWidth);
+ if (fromX < toX) {
+ // Because of rounding, we can get source coordinates outside the source image.
+ // Clamp these coordinates to the source rect to avoid segmentation fault and
+@@ -275,10 +282,10 @@ void qt_transform_image_rasterize(DestT *destPixels, int dbpl,
+ u = x1 * dudx + y * dudy + u0;
+ v = x1 * dvdx + y * dvdy + v0;
+ for (; x1 < toX; ++x1) {
+- int uu = u >> 16;
+- int vv = v >> 16;
+- if (uu >= sourceRect.left() && uu < sourceRect.left() + sourceRect.width()
+- && vv >= sourceRect.top() && vv < sourceRect.top() + sourceRect.height()) {
++ qint64 uu = u >> 16;
++ qint64 vv = v >> 16;
++ if (uu >= sourceRectLeft && uu < sourceRectLeft + sourceRectWidth
++ && vv >= sourceRectTop && vv < sourceRectTop + sourceRectHeight) {
+ break;
+ }
+ u += dudx;
+@@ -290,10 +297,10 @@ void qt_transform_image_rasterize(DestT *destPixels, int dbpl,
+ u = (x2 - 1) * dudx + y * dudy + u0;
+ v = (x2 - 1) * dvdx + y * dvdy + v0;
+ for (; x2 > x1; --x2) {
+- int uu = u >> 16;
+- int vv = v >> 16;
+- if (uu >= sourceRect.left() && uu < sourceRect.left() + sourceRect.width()
+- && vv >= sourceRect.top() && vv < sourceRect.top() + sourceRect.height()) {
++ qint64 uu = u >> 16;
++ qint64 vv = v >> 16;
++ if (uu >= sourceRectLeft && uu < sourceRectLeft + sourceRectWidth
++ && vv >= sourceRectTop && vv < sourceRectTop + sourceRectHeight) {
+ break;
+ }
+ u -= dudx;
+@@ -308,8 +315,8 @@ void qt_transform_image_rasterize(DestT *destPixels, int dbpl,
+ // Beginning of the scan line, with per-pixel checks.
+ i = x1 - fromX;
+ while (i) {
+- int uu = qBound(sourceRect.left(), u >> 16, sourceRect.left() + sourceRect.width() - 1);
+- int vv = qBound(sourceRect.top(), v >> 16, sourceRect.top() + sourceRect.height() - 1);
++ qint64 uu = qBound(sourceRectLeft, u >> 16, sourceRectLeft + sourceRectWidth - 1);
++ qint64 vv = qBound(sourceRectTop, v >> 16, sourceRectTop + sourceRectHeight - 1);
+ blender.write(line, reinterpret_cast<const SrcT *>(reinterpret_cast<const uchar *>(srcPixels) + vv * sbpl)[uu]);
+ u += dudx;
+ v += dvdx;
+@@ -348,8 +355,8 @@ void qt_transform_image_rasterize(DestT *destPixels, int dbpl,
+ // End of the scan line, with per-pixel checks.
+ i = toX - x2;
+ while (i) {
+- int uu = qBound(sourceRect.left(), u >> 16, sourceRect.left() + sourceRect.width() - 1);
+- int vv = qBound(sourceRect.top(), v >> 16, sourceRect.top() + sourceRect.height() - 1);
++ qint64 uu = qBound(sourceRectLeft, u >> 16, sourceRectLeft + sourceRectWidth - 1);
++ qint64 vv = qBound(sourceRectTop, v >> 16, sourceRectTop + sourceRectHeight - 1);
+ blender.write(line, reinterpret_cast<const SrcT *>(reinterpret_cast<const uchar *>(srcPixels) + vv * sbpl)[uu]);
+ u += dudx;
+ v += dvdx;
+diff --git a/qtbase/src/gui/painting/qcolortrclut_p.h b/qtbase/src/gui/painting/qcolortrclut_p.h
+index 76a6a60803..24fd522e6c 100644
+--- a/qtbase/src/gui/painting/qcolortrclut_p.h
++++ b/qtbase/src/gui/painting/qcolortrclut_p.h
+@@ -118,6 +118,7 @@ public:
+ return QRgba64::fromRgba64(r, g, b, qAlpha(rgb32) * 257);
+ #endif
+ }
++ QRgba64 toLinear64(QRgba64) const = delete;
+
+ QRgb toLinear(QRgb rgb32) const
+ {
+diff --git a/qtbase/src/gui/painting/qdrawhelper.cpp b/qtbase/src/gui/painting/qdrawhelper.cpp
+index a61793508a..5ba2d277b7 100644
+--- a/qtbase/src/gui/painting/qdrawhelper.cpp
++++ b/qtbase/src/gui/painting/qdrawhelper.cpp
+@@ -6091,7 +6091,7 @@ static inline void alphargbblend_argb32(quint32 *dst, uint coverage, const QRgba
+ static inline void rgbBlendPixel(QRgba64 &dst, int coverage, QRgba64 slinear, const QColorTrcLut *colorProfile)
+ {
+ // Do a gammacorrected RGB alphablend...
+- const QRgba64 dlinear = colorProfile ? colorProfile->toLinear64(dst) : dst;
++ const QRgba64 dlinear = colorProfile ? colorProfile->toLinear(dst) : dst;
+
+ QRgba64 blend = rgbBlend(dlinear, slinear, coverage);
+
+diff --git a/qtbase/src/gui/painting/qpaintengine_raster.cpp b/qtbase/src/gui/painting/qpaintengine_raster.cpp
+index 283923de52..f08eb9cbee 100644
+--- a/qtbase/src/gui/painting/qpaintengine_raster.cpp
++++ b/qtbase/src/gui/painting/qpaintengine_raster.cpp
+@@ -560,31 +560,6 @@ void QRasterPaintEngine::updateMatrix(const QTransform &matrix)
+ QRasterPaintEngineState *s = state();
+ // FALCON: get rid of this line, see drawImage call below.
+ s->matrix = matrix;
+- QTransform::TransformationType txop = s->matrix.type();
+-
+- switch (txop) {
+-
+- case QTransform::TxNone:
+- s->flags.int_xform = true;
+- break;
+-
+- case QTransform::TxTranslate:
+- s->flags.int_xform = qreal(int(s->matrix.dx())) == s->matrix.dx()
+- && qreal(int(s->matrix.dy())) == s->matrix.dy();
+- break;
+-
+- case QTransform::TxScale:
+- s->flags.int_xform = qreal(int(s->matrix.dx())) == s->matrix.dx()
+- && qreal(int(s->matrix.dy())) == s->matrix.dy()
+- && qreal(int(s->matrix.m11())) == s->matrix.m11()
+- && qreal(int(s->matrix.m22())) == s->matrix.m22();
+- break;
+-
+- default: // shear / perspective...
+- s->flags.int_xform = false;
+- break;
+- }
+-
+ s->flags.tx_noshear = qt_scaleForTransform(s->matrix, &s->txscale);
+
+ ensureOutlineMapper();
+@@ -617,7 +592,6 @@ QRasterPaintEngineState::QRasterPaintEngineState()
+ flags.bilinear = false;
+ flags.legacy_rounding = false;
+ flags.fast_text = true;
+- flags.int_xform = true;
+ flags.tx_noshear = true;
+ flags.fast_images = true;
+
+@@ -1793,7 +1767,7 @@ void QRasterPaintEngine::fill(const QVectorPath &path, const QBrush &brush)
+ QRectF cpRect = path.controlPointRect();
+ const QRectF pathDeviceRect = s->matrix.mapRect(cpRect);
+ // Skip paths that by conservative estimates are completely outside the paint device.
+- if (!pathDeviceRect.intersects(QRectF(d->deviceRect)))
++ if (!pathDeviceRect.intersects(QRectF(d->deviceRect)) || !pathDeviceRect.isValid())
+ return;
+
+ ProcessSpans blend = d->getBrushFunc(pathDeviceRect, &s->brushData);
+diff --git a/qtbase/src/gui/painting/qpaintengine_raster_p.h b/qtbase/src/gui/painting/qpaintengine_raster_p.h
+index 089aadc3f7..bf7363d5aa 100644
+--- a/qtbase/src/gui/painting/qpaintengine_raster_p.h
++++ b/qtbase/src/gui/painting/qpaintengine_raster_p.h
+@@ -111,7 +111,6 @@ public:
+ uint bilinear : 1;
+ uint legacy_rounding : 1;
+ uint fast_text : 1;
+- uint int_xform : 1;
+ uint tx_noshear : 1;
+ uint fast_images : 1;
+ };
+diff --git a/qtbase/src/gui/painting/qpainterpath.cpp b/qtbase/src/gui/painting/qpainterpath.cpp
+index f9544a3241..d80fafeaf1 100644
+--- a/qtbase/src/gui/painting/qpainterpath.cpp
++++ b/qtbase/src/gui/painting/qpainterpath.cpp
+@@ -1253,7 +1253,7 @@ void QPainterPath::addText(const QPointF &point, const QFont &f, const QString &
+
+ if (si.analysis.flags < QScriptAnalysis::TabOrObject) {
+ QGlyphLayout glyphs = eng->shapedGlyphs(&si);
+- QFontEngine *fe = f.d->engineForScript(si.analysis.script);
++ QFontEngine *fe = eng->fontEngine(si);
+ Q_ASSERT(fe);
+ fe->addOutlineToPath(x, y, glyphs, this,
+ si.analysis.bidiLevel % 2
+diff --git a/qtbase/src/gui/painting/qpathclipper_p.h b/qtbase/src/gui/painting/qpathclipper_p.h
+index 9444a87b71..18f64c5e8c 100644
+--- a/qtbase/src/gui/painting/qpathclipper_p.h
++++ b/qtbase/src/gui/painting/qpathclipper_p.h
+@@ -156,7 +156,7 @@ public:
+ int vertex(Direction direction) const;
+
+ private:
+- int m_next[2][2];
++ int m_next[2][2] = { { -1, -1 }, { -1, -1 } };
+ };
+
+ class QPathSegments
+@@ -296,10 +296,6 @@ inline QPathEdge::QPathEdge(int a, int b)
+ , angle(0)
+ , invAngle(0)
+ {
+- m_next[0][0] = -1;
+- m_next[1][0] = -1;
+- m_next[0][0] = -1;
+- m_next[1][0] = -1;
+ }
+
+ inline int QPathEdge::next(Traversal traversal, Direction direction) const
+diff --git a/qtbase/src/gui/painting/qpdf.cpp b/qtbase/src/gui/painting/qpdf.cpp
+index 3066744f1b..2c8d3c3b53 100644
+--- a/qtbase/src/gui/painting/qpdf.cpp
++++ b/qtbase/src/gui/painting/qpdf.cpp
+@@ -2760,6 +2760,8 @@ int QPdfEnginePrivate::addBrushPattern(const QTransform &m, bool *specifyColor,
+ return gradientBrush(brush, matrix, gStateObject);
+ }
+
++ matrix = brush.transform() * matrix;
++
+ if ((!brush.isOpaque() && brush.style() < Qt::LinearGradientPattern) || opacity != 1.0)
+ *gStateObject = addConstantAlphaObject(qRound(brush.color().alpha() * opacity),
+ qRound(pen.color().alpha() * opacity));
+diff --git a/qtbase/src/gui/painting/qstroker.cpp b/qtbase/src/gui/painting/qstroker.cpp
+index cb5d395e80..3b6357a893 100644
+--- a/qtbase/src/gui/painting/qstroker.cpp
++++ b/qtbase/src/gui/painting/qstroker.cpp
+@@ -1182,6 +1182,7 @@ void QDashStroker::processCurrentSubpath()
+ // Check if the entire line should be clipped away or simplified
+ bool clipIt = clipping && !lineIntersectsRect(prev, e, clip_tl, clip_br);
+ bool skipDashing = elen * invSumLength > repetitionLimit();
++ int maxDashes = dashCount;
+ if (skipDashing || clipIt) {
+ // Cut away full dash sequences.
+ elen -= std::floor(elen * invSumLength) * sumLength;
+@@ -1196,7 +1197,7 @@ void QDashStroker::processCurrentSubpath()
+ pos = estop; // move pos to next path element
+ done = true;
+ } else { // Dash is on this line
+- pos = dpos + estart;
++ pos = --maxDashes > 0 ? dpos + estart : estop;
+ done = pos >= estop;
+ if (++idash >= dashCount)
+ idash = 0;
+diff --git a/qtbase/src/gui/painting/qt_attribution.json b/qtbase/src/gui/painting/qt_attribution.json
+index 7b16e8c211..0e87d30aa2 100644
+--- a/qtbase/src/gui/painting/qt_attribution.json
++++ b/qtbase/src/gui/painting/qt_attribution.json
+@@ -10,7 +10,7 @@
+ "Homepage": "http://www.freetype.org",
+ "License": "Freetype Project License or GNU General Public License v2.0 only",
+ "LicenseId": "FTL or GPL-2.0",
+- "LicenseFile": "../../3rdparty/freetype/docs/LICENSE.TXT",
++ "LicenseFile": "../../3rdparty/freetype/LICENSE.TXT",
+ "Copyright": "Copyright 2000-2016 by David Turner, Robert Wilhelm, and Werner Lemberg."
+ },
+ {
+diff --git a/qtbase/src/gui/rhi/qshader_p_p.h b/qtbase/src/gui/rhi/qshader_p_p.h
+index ec9d25971f..4a5a7a6d51 100644
+--- a/qtbase/src/gui/rhi/qshader_p_p.h
++++ b/qtbase/src/gui/rhi/qshader_p_p.h
+@@ -68,13 +68,13 @@ struct Q_GUI_EXPORT QShaderPrivate
+ {
+ }
+
+- QShaderPrivate(const QShaderPrivate *other)
++ QShaderPrivate(const QShaderPrivate &other)
+ : ref(1),
+- qsbVersion(other->qsbVersion),
+- stage(other->stage),
+- desc(other->desc),
+- shaders(other->shaders),
+- bindings(other->bindings)
++ qsbVersion(other.qsbVersion),
++ stage(other.stage),
++ desc(other.desc),
++ shaders(other.shaders),
++ bindings(other.bindings)
+ {
+ }
+
+diff --git a/qtbase/src/gui/rhi/qshaderdescription_p_p.h b/qtbase/src/gui/rhi/qshaderdescription_p_p.h
+index ec2b0b6b4c..3da33a8a2b 100644
+--- a/qtbase/src/gui/rhi/qshaderdescription_p_p.h
++++ b/qtbase/src/gui/rhi/qshaderdescription_p_p.h
+@@ -63,16 +63,16 @@ struct Q_GUI_EXPORT QShaderDescriptionPrivate
+ localSize[0] = localSize[1] = localSize[2] = 0;
+ }
+
+- QShaderDescriptionPrivate(const QShaderDescriptionPrivate *other)
++ QShaderDescriptionPrivate(const QShaderDescriptionPrivate &other)
+ : ref(1),
+- inVars(other->inVars),
+- outVars(other->outVars),
+- uniformBlocks(other->uniformBlocks),
+- pushConstantBlocks(other->pushConstantBlocks),
+- storageBlocks(other->storageBlocks),
+- combinedImageSamplers(other->combinedImageSamplers),
+- storageImages(other->storageImages),
+- localSize(other->localSize)
++ inVars(other.inVars),
++ outVars(other.outVars),
++ uniformBlocks(other.uniformBlocks),
++ pushConstantBlocks(other.pushConstantBlocks),
++ storageBlocks(other.storageBlocks),
++ combinedImageSamplers(other.combinedImageSamplers),
++ storageImages(other.storageImages),
++ localSize(other.localSize)
+ {
+ }
+
+diff --git a/qtbase/src/gui/text/qfontdatabase.cpp b/qtbase/src/gui/text/qfontdatabase.cpp
+index a657a8c516..4fc0100958 100644
+--- a/qtbase/src/gui/text/qfontdatabase.cpp
++++ b/qtbase/src/gui/text/qfontdatabase.cpp
+@@ -983,7 +983,7 @@ QFontEngine *loadSingleEngine(int script,
+ if (style->key.stretch != 0 && request.stretch != 0
+ && (request.styleName.isEmpty() || request.styleName != style->styleName)) {
+ def.stretch = (request.stretch * 100 + style->key.stretch / 2) / style->key.stretch;
+- } else {
++ } else if (request.stretch == QFont::AnyStretch) {
+ def.stretch = 100;
+ }
+
+diff --git a/qtbase/src/gui/text/qtextdocumentlayout.cpp b/qtbase/src/gui/text/qtextdocumentlayout.cpp
+index f3e6ea2100..72267e9380 100644
+--- a/qtbase/src/gui/text/qtextdocumentlayout.cpp
++++ b/qtbase/src/gui/text/qtextdocumentlayout.cpp
+@@ -2123,7 +2123,7 @@ void QTextDocumentLayoutPrivate::drawListItem(const QPointF &offset, QPainter *p
+ {
+ Q_Q(const QTextDocumentLayout);
+ const QTextBlockFormat blockFormat = bl.blockFormat();
+- const QTextCharFormat charFormat = QTextCursor(bl).charFormat();
++ const QTextCharFormat charFormat = bl.charFormat();
+ QFont font(charFormat.font());
+ if (q->paintDevice())
+ font = QFont(font, q->paintDevice());
+diff --git a/qtbase/src/gui/text/qtextengine.cpp b/qtbase/src/gui/text/qtextengine.cpp
+index ce4abac472..a6c66e5d2d 100644
+--- a/qtbase/src/gui/text/qtextengine.cpp
++++ b/qtbase/src/gui/text/qtextengine.cpp
+@@ -1,6 +1,6 @@
+ /****************************************************************************
+ **
+-** Copyright (C) 2016 The Qt Company Ltd.
++** Copyright (C) 2021 The Qt Company Ltd.
+ ** Contact: https://www.qt.io/licensing/
+ **
+ ** This file is part of the QtGui module of the Qt Toolkit.
+@@ -1565,6 +1565,12 @@ void QTextEngine::shapeText(int item) const
+ // Overwrite with 0 token to indicate failure
+ QGlyphLayout g = availableGlyphs(&si);
+ g.glyphs[0] = 0;
++ g.attributes[0].clusterStart = true;
++
++ ushort *log_clusters = logClusters(&si);
++ for (int i = 0; i < itemLength; ++i)
++ log_clusters[i] = 0;
++
+ return;
+ }
+
+diff --git a/qtbase/src/gui/util/qdesktopservices.cpp b/qtbase/src/gui/util/qdesktopservices.cpp
+index fbb63a9408..4d5fafaaa7 100644
+--- a/qtbase/src/gui/util/qdesktopservices.cpp
++++ b/qtbase/src/gui/util/qdesktopservices.cpp
+@@ -54,6 +54,8 @@
+ #include <qpa/qplatformintegration.h>
+ #include <qdir.h>
+
++#include <QtCore/private/qlocking_p.h>
++
+ QT_BEGIN_NAMESPACE
+
+ class QOpenUrlHandlerRegistry : public QObject
+@@ -81,6 +83,7 @@ Q_GLOBAL_STATIC(QOpenUrlHandlerRegistry, handlerRegistry)
+
+ void QOpenUrlHandlerRegistry::handlerDestroyed(QObject *handler)
+ {
++ const auto lock = qt_scoped_lock(mutex);
+ HandlerHash::Iterator it = handlers.begin();
+ while (it != handlers.end()) {
+ if (it->receiver == handler) {
+@@ -294,7 +297,8 @@ void QDesktopServices::setUrlHandler(const QString &scheme, QObject *receiver, c
+ h.name = method;
+ registry->handlers.insert(scheme.toLower(), h);
+ QObject::connect(receiver, SIGNAL(destroyed(QObject*)),
+- registry, SLOT(handlerDestroyed(QObject*)));
++ registry, SLOT(handlerDestroyed(QObject*)),
++ Qt::DirectConnection);
+ }
+
+ /*!
+diff --git a/qtbase/src/gui/util/qpkmhandler.cpp b/qtbase/src/gui/util/qpkmhandler.cpp
+index e0c3b75efe..3414f9d8ba 100644
+--- a/qtbase/src/gui/util/qpkmhandler.cpp
++++ b/qtbase/src/gui/util/qpkmhandler.cpp
+@@ -57,7 +57,7 @@ struct PkmType
+ quint32 bytesPerBlock;
+ };
+
+-static PkmType typeMap[5] = {
++static constexpr PkmType typeMap[5] = {
+ { 0x8D64, 8 }, // GL_ETC1_RGB8_OES
+ { 0x9274, 8 }, // GL_COMPRESSED_RGB8_ETC2
+ { 0, 0 }, // unused (obsolete)
+diff --git a/qtbase/src/network/access/qnetworkreplyfileimpl.cpp b/qtbase/src/network/access/qnetworkreplyfileimpl.cpp
+index b6be93147a..6e69b4c4d3 100644
+--- a/qtbase/src/network/access/qnetworkreplyfileimpl.cpp
++++ b/qtbase/src/network/access/qnetworkreplyfileimpl.cpp
+@@ -89,9 +89,10 @@ QNetworkReplyFileImpl::QNetworkReplyFileImpl(QNetworkAccessManager *manager, con
+ // we handle only local files
+ QString msg = QCoreApplication::translate("QNetworkAccessFileBackend", "Request for opening non-local file %1").arg(url.toString());
+ setError(QNetworkReply::ProtocolInvalidOperationError, msg);
++ setFinished(true); // We're finished, will emit finished() after ctor is done.
+ QMetaObject::invokeMethod(this, "errorOccurred", Qt::QueuedConnection,
+ Q_ARG(QNetworkReply::NetworkError, QNetworkReply::ProtocolInvalidOperationError));
+- fileOpenFinished(false);
++ QMetaObject::invokeMethod(this, [this](){ fileOpenFinished(false); }, Qt::QueuedConnection);
+ return;
+ }
+ #endif
+diff --git a/qtbase/src/network/access/qnetworkreplyimpl.cpp b/qtbase/src/network/access/qnetworkreplyimpl.cpp
+index bcdf6ee2f1..3b6deb82bd 100644
+--- a/qtbase/src/network/access/qnetworkreplyimpl.cpp
++++ b/qtbase/src/network/access/qnetworkreplyimpl.cpp
+@@ -680,7 +680,7 @@ void QNetworkReplyImplPrivate::appendDownstreamData(QIODevice *data)
+ // read until EOF from data
+ if (Q_UNLIKELY(copyDevice)) {
+ qCritical("QNetworkReplyImpl: copy from QIODevice already in progress -- "
+- "backend probly needs to be fixed");
++ "backend probably needs to be fixed");
+ return;
+ }
+
+diff --git a/qtbase/src/network/kernel/qauthenticator.cpp b/qtbase/src/network/kernel/qauthenticator.cpp
+index d9fe7bc47b..ccd04b294a 100644
+--- a/qtbase/src/network/kernel/qauthenticator.cpp
++++ b/qtbase/src/network/kernel/qauthenticator.cpp
+@@ -50,6 +50,7 @@
+ #include <qstring.h>
+ #include <qdatetime.h>
+ #include <qrandom.h>
++#include "private/qsystemlibrary_p.h"
+
+ #ifdef Q_OS_WIN
+ #include <qmutex.h>
+@@ -1563,7 +1564,7 @@ static bool q_SSPI_library_load()
+
+ // Initialize security interface
+ if (pSecurityFunctionTable == nullptr) {
+- securityDLLHandle = LoadLibrary(L"secur32.dll");
++ securityDLLHandle = QSystemLibrary::load(L"secur32");
+ if (securityDLLHandle != nullptr) {
+ INIT_SECURITY_INTERFACE pInitSecurityInterface =
+ reinterpret_cast<INIT_SECURITY_INTERFACE>(
+diff --git a/qtbase/src/network/kernel/qhostinfo_unix.cpp b/qtbase/src/network/kernel/qhostinfo_unix.cpp
+index 9b0a2ee669..73679c9ef1 100644
+--- a/qtbase/src/network/kernel/qhostinfo_unix.cpp
++++ b/qtbase/src/network/kernel/qhostinfo_unix.cpp
+@@ -122,7 +122,6 @@ static QFunctionPointer resolveSymbol(QLibrary &lib, const char *sym)
+
+ LibResolv::LibResolv()
+ {
+- QLibrary lib;
+ #ifdef LIBRESOLV_SO
+ lib.setFileName(QStringLiteral(LIBRESOLV_SO));
+ if (!lib.load())
+diff --git a/qtbase/src/network/socket/qsocks5socketengine.cpp b/qtbase/src/network/socket/qsocks5socketengine.cpp
+index 3a046fd116..97fadca0b3 100644
+--- a/qtbase/src/network/socket/qsocks5socketengine.cpp
++++ b/qtbase/src/network/socket/qsocks5socketengine.cpp
+@@ -1296,7 +1296,7 @@ void QSocks5SocketEnginePrivate::_q_udpSocketReadNotification()
+ int pos = 0;
+ const char *buf = inBuf.constData();
+ if (inBuf.size() < 4) {
+- QSOCKS5_D_DEBUG << "bugus udp data, discarding";
++ QSOCKS5_D_DEBUG << "bogus udp data, discarding";
+ return;
+ }
+ QSocks5RevivedDatagram datagram;
+diff --git a/qtbase/src/network/ssl/qsslcontext_openssl.cpp b/qtbase/src/network/ssl/qsslcontext_openssl.cpp
+index c9f202f573..c992da9d8e 100644
+--- a/qtbase/src/network/ssl/qsslcontext_openssl.cpp
++++ b/qtbase/src/network/ssl/qsslcontext_openssl.cpp
+@@ -409,7 +409,7 @@ init_context:
+ break;
+ case QSsl::DtlsV1_0OrLater:
+ minVersion = DTLS1_VERSION;
+- maxVersion = DTLS_MAX_VERSION;
++ maxVersion = 0;
+ break;
+ case QSsl::DtlsV1_2:
+ minVersion = DTLS1_2_VERSION;
+@@ -417,7 +417,7 @@ init_context:
+ break;
+ case QSsl::DtlsV1_2OrLater:
+ minVersion = DTLS1_2_VERSION;
+- maxVersion = DTLS_MAX_VERSION;
++ maxVersion = 0;
+ break;
+ case QSsl::TlsV1_3OrLater:
+ #ifdef TLS1_3_VERSION
+@@ -455,7 +455,7 @@ init_context:
+ }
+
+ // Enable bug workarounds.
+- long options = QSslSocketBackendPrivate::setupOpenSslOptions(configuration.protocol(), configuration.d->sslOptions);
++ qssloptions options = QSslSocketBackendPrivate::setupOpenSslOptions(configuration.protocol(), configuration.d->sslOptions);
+ q_SSL_CTX_set_options(sslContext->ctx, options);
+
+ // Tell OpenSSL to release memory early
+diff --git a/qtbase/src/network/ssl/qssldiffiehellmanparameters_openssl.cpp b/qtbase/src/network/ssl/qssldiffiehellmanparameters_openssl.cpp
+index aaf8741130..b58935372c 100644
+--- a/qtbase/src/network/ssl/qssldiffiehellmanparameters_openssl.cpp
++++ b/qtbase/src/network/ssl/qssldiffiehellmanparameters_openssl.cpp
+@@ -59,57 +59,6 @@
+
+ QT_BEGIN_NAMESPACE
+
+-#ifdef OPENSSL_NO_DEPRECATED_3_0
+-
+-static int q_DH_check(DH *dh, int *status)
+-{
+- // DH_check was first deprecated in OpenSSL 3.0.0, as low-level
+- // API; the EVP_PKEY family of functions was advised as an alternative.
+- // As of now EVP_PKEY_params_check ends up calling ... DH_check,
+- // which is good enough.
+-
+- Q_ASSERT(dh);
+- Q_ASSERT(status);
+-
+- EVP_PKEY *key = q_EVP_PKEY_new();
+- if (!key) {
+- qCWarning(lcSsl, "EVP_PKEY_new failed");
+- QSslSocketBackendPrivate::logAndClearErrorQueue();
+- return 0;
+- }
+- const auto keyDeleter = qScopeGuard([key](){
+- q_EVP_PKEY_free(key);
+- });
+- if (!q_EVP_PKEY_set1_DH(key, dh)) {
+- qCWarning(lcSsl, "EVP_PKEY_set1_DH failed");
+- QSslSocketBackendPrivate::logAndClearErrorQueue();
+- return 0;
+- }
+-
+- EVP_PKEY_CTX *keyCtx = q_EVP_PKEY_CTX_new(key, nullptr);
+- if (!keyCtx) {
+- qCWarning(lcSsl, "EVP_PKEY_CTX_new failed");
+- QSslSocketBackendPrivate::logAndClearErrorQueue();
+- return 0;
+- }
+- const auto ctxDeleter = qScopeGuard([keyCtx]{
+- q_EVP_PKEY_CTX_free(keyCtx);
+- });
+-
+- const int result = q_EVP_PKEY_param_check(keyCtx);
+- QSslSocketBackendPrivate::logAndClearErrorQueue();
+- // Note: unlike DH_check, we cannot obtain the 'status',
+- // if the 'result' is 0 (actually the result is 1 only
+- // if this 'status' was 0). We could probably check the
+- // errors from the error queue, but it's not needed anyway
+- // - see the 'isSafeDH' below, how it returns immediately
+- // on 0.
+- Q_UNUSED(status)
+-
+- return result;
+-}
+-#endif // OPENSSL_NO_DEPRECATED_3_0
+-
+ static bool isSafeDH(DH *dh)
+ {
+ int status = 0;
+diff --git a/qtbase/src/network/ssl/qsslsocket_openssl.cpp b/qtbase/src/network/ssl/qsslsocket_openssl.cpp
+index 37fad2a68f..8f6858c867 100644
+--- a/qtbase/src/network/ssl/qsslsocket_openssl.cpp
++++ b/qtbase/src/network/ssl/qsslsocket_openssl.cpp
+@@ -550,9 +550,9 @@ static void q_loadCiphersForConnection(SSL *connection, QList<QSslCipher> &ciphe
+ // Defined in qsslsocket.cpp
+ void q_setDefaultDtlsCiphers(const QList<QSslCipher> &ciphers);
+
+-long QSslSocketBackendPrivate::setupOpenSslOptions(QSsl::SslProtocol protocol, QSsl::SslOptions sslOptions)
++qssloptions QSslSocketBackendPrivate::setupOpenSslOptions(QSsl::SslProtocol protocol, QSsl::SslOptions sslOptions)
+ {
+- long options;
++ qssloptions options;
+ if (protocol == QSsl::TlsV1SslV3)
+ options = SSL_OP_ALL|SSL_OP_NO_SSLv2|SSL_OP_NO_SSLv3;
+ else if (protocol == QSsl::SecureProtocols)
+diff --git a/qtbase/src/network/ssl/qsslsocket_openssl_p.h b/qtbase/src/network/ssl/qsslsocket_openssl_p.h
+index 4103de23e8..5547589256 100644
+--- a/qtbase/src/network/ssl/qsslsocket_openssl_p.h
++++ b/qtbase/src/network/ssl/qsslsocket_openssl_p.h
+@@ -107,6 +107,12 @@
+
+ QT_BEGIN_NAMESPACE
+
++#if defined(OPENSSL_VERSION_MAJOR) && OPENSSL_VERSION_MAJOR >= 3
++typedef uint64_t qssloptions;
++#else
++typedef unsigned long qssloptions;
++#endif
++
+ struct QSslErrorEntry {
+ int code;
+ int depth;
+@@ -171,7 +177,7 @@ public:
+ QVector<QSslError> ocspErrors;
+ QByteArray ocspResponseDer;
+
+- Q_AUTOTEST_EXPORT static long setupOpenSslOptions(QSsl::SslProtocol protocol, QSsl::SslOptions sslOptions);
++ Q_AUTOTEST_EXPORT static qssloptions setupOpenSslOptions(QSsl::SslProtocol protocol, QSsl::SslOptions sslOptions);
+ static QSslCipher QSslCipher_from_SSL_CIPHER(const SSL_CIPHER *cipher);
+ static QList<QSslCertificate> STACKOFX509_to_QSslCertificates(STACK_OF(X509) *x509);
+ static QList<QSslError> verify(const QList<QSslCertificate> &certificateChain, const QString &hostName);
+diff --git a/qtbase/src/network/ssl/qsslsocket_openssl_symbols.cpp b/qtbase/src/network/ssl/qsslsocket_openssl_symbols.cpp
+index e53fb279f0..459ccd0b19 100644
+--- a/qtbase/src/network/ssl/qsslsocket_openssl_symbols.cpp
++++ b/qtbase/src/network/ssl/qsslsocket_openssl_symbols.cpp
+@@ -148,7 +148,6 @@ DEFINEFUNC(int, EVP_PKEY_up_ref, EVP_PKEY *a, a, return 0, return)
+ DEFINEFUNC2(EVP_PKEY_CTX *, EVP_PKEY_CTX_new, EVP_PKEY *pkey, pkey, ENGINE *e, e, return nullptr, return)
+ DEFINEFUNC(int, EVP_PKEY_param_check, EVP_PKEY_CTX *ctx, ctx, return 0, return)
+ DEFINEFUNC(void, EVP_PKEY_CTX_free, EVP_PKEY_CTX *ctx, ctx, return, return)
+-DEFINEFUNC(int, EVP_PKEY_base_id, EVP_PKEY *a, a, return NID_undef, return)
+ DEFINEFUNC(int, RSA_bits, RSA *a, a, return 0, return)
+ DEFINEFUNC(int, DSA_bits, DSA *a, a, return 0, return)
+ DEFINEFUNC(int, OPENSSL_sk_num, OPENSSL_STACK *a, a, return -1, return)
+@@ -158,7 +157,7 @@ DEFINEFUNC2(void, OPENSSL_sk_push, OPENSSL_STACK *a, a, void *b, b, return, DUMM
+ DEFINEFUNC(void, OPENSSL_sk_free, OPENSSL_STACK *a, a, return, DUMMYARG)
+ DEFINEFUNC2(void *, OPENSSL_sk_value, OPENSSL_STACK *a, a, int b, b, return nullptr, return)
+ DEFINEFUNC(int, SSL_session_reused, SSL *a, a, return 0, return)
+-DEFINEFUNC2(unsigned long, SSL_CTX_set_options, SSL_CTX *ctx, ctx, unsigned long op, op, return 0, return)
++DEFINEFUNC2(qssloptions, SSL_CTX_set_options, SSL_CTX *ctx, ctx, qssloptions op, op, return 0, return)
+ DEFINEFUNC(int, SSL_CTX_get_security_level, const SSL_CTX *ctx, ctx, return -1, return)
+ DEFINEFUNC2(void, SSL_CTX_set_security_level, SSL_CTX *ctx, ctx, int level, level, return, return)
+ #ifdef TLS1_3_VERSION
+@@ -371,7 +370,15 @@ DEFINEFUNC(const SSL_CIPHER *, SSL_get_current_cipher, SSL *a, a, return nullptr
+ DEFINEFUNC(int, SSL_version, const SSL *a, a, return 0, return)
+ DEFINEFUNC2(int, SSL_get_error, SSL *a, a, int b, b, return -1, return)
+ DEFINEFUNC(STACK_OF(X509) *, SSL_get_peer_cert_chain, SSL *a, a, return nullptr, return)
++
++#if defined(OPENSSL_VERSION_MAJOR) && OPENSSL_VERSION_MAJOR >= 3
++DEFINEFUNC(X509 *, SSL_get1_peer_certificate, SSL *a, a, return nullptr, return)
++DEFINEFUNC(int, EVP_PKEY_get_base_id, const EVP_PKEY *pkey, pkey, return -1, return)
++#else
+ DEFINEFUNC(X509 *, SSL_get_peer_certificate, SSL *a, a, return nullptr, return)
++DEFINEFUNC(int, EVP_PKEY_base_id, EVP_PKEY *a, a, return NID_undef, return)
++#endif // OPENSSL_VERSION_MAJOR >= 3
++
+ DEFINEFUNC(long, SSL_get_verify_result, const SSL *a, a, return -1, return)
+ DEFINEFUNC(SSL *, SSL_new, SSL_CTX *a, a, return nullptr, return)
+ DEFINEFUNC(SSL_CTX *, SSL_get_SSL_CTX, SSL *a, a, return nullptr, return)
+@@ -492,9 +499,7 @@ DEFINEFUNC(DH *, DH_new, DUMMYARG, DUMMYARG, return nullptr, return)
+ DEFINEFUNC(void, DH_free, DH *dh, dh, return, DUMMYARG)
+ DEFINEFUNC3(DH *, d2i_DHparams, DH**a, a, const unsigned char **pp, pp, long length, length, return nullptr, return)
+ DEFINEFUNC2(int, i2d_DHparams, DH *a, a, unsigned char **p, p, return -1, return)
+-#ifndef OPENSSL_NO_DEPRECATED_3_0
+ DEFINEFUNC2(int, DH_check, DH *dh, dh, int *codes, codes, return 0, return)
+-#endif // OPENSSL_NO_DEPRECATED_3_0
+ DEFINEFUNC3(BIGNUM *, BN_bin2bn, const unsigned char *s, s, int len, len, BIGNUM *ret, ret, return nullptr, return)
+
+ #ifndef OPENSSL_NO_EC
+@@ -868,7 +873,6 @@ bool q_resolveOpenSslSymbols()
+ RESOLVEFUNC(EVP_PKEY_CTX_new)
+ RESOLVEFUNC(EVP_PKEY_param_check)
+ RESOLVEFUNC(EVP_PKEY_CTX_free)
+- RESOLVEFUNC(EVP_PKEY_base_id)
+ RESOLVEFUNC(RSA_bits)
+ RESOLVEFUNC(OPENSSL_sk_new_null)
+ RESOLVEFUNC(OPENSSL_sk_push)
+@@ -1107,7 +1111,15 @@ bool q_resolveOpenSslSymbols()
+ RESOLVEFUNC(SSL_version)
+ RESOLVEFUNC(SSL_get_error)
+ RESOLVEFUNC(SSL_get_peer_cert_chain)
++
++#if defined(OPENSSL_VERSION_MAJOR) && OPENSSL_VERSION_MAJOR >= 3
++ RESOLVEFUNC(SSL_get1_peer_certificate)
++ RESOLVEFUNC(EVP_PKEY_get_base_id)
++#else
+ RESOLVEFUNC(SSL_get_peer_certificate)
++ RESOLVEFUNC(EVP_PKEY_base_id)
++#endif // OPENSSL_VERSION_MAJOR >= 3
++
+ RESOLVEFUNC(SSL_get_verify_result)
+ RESOLVEFUNC(SSL_new)
+ RESOLVEFUNC(SSL_get_SSL_CTX)
+@@ -1206,9 +1218,7 @@ bool q_resolveOpenSslSymbols()
+ RESOLVEFUNC(DH_free)
+ RESOLVEFUNC(d2i_DHparams)
+ RESOLVEFUNC(i2d_DHparams)
+-#ifndef OPENSSL_NO_DEPRECATED_3_0
+ RESOLVEFUNC(DH_check)
+-#endif // OPENSSL_NO_DEPRECATED_3_0
+ RESOLVEFUNC(BN_bin2bn)
+
+ #ifndef OPENSSL_NO_EC
+diff --git a/qtbase/src/network/ssl/qsslsocket_openssl_symbols_p.h b/qtbase/src/network/ssl/qsslsocket_openssl_symbols_p.h
+index 95e8897a3b..27aeffa18a 100644
+--- a/qtbase/src/network/ssl/qsslsocket_openssl_symbols_p.h
++++ b/qtbase/src/network/ssl/qsslsocket_openssl_symbols_p.h
+@@ -237,7 +237,6 @@ Q_AUTOTEST_EXPORT int q_EVP_PKEY_up_ref(EVP_PKEY *a);
+ EVP_PKEY_CTX *q_EVP_PKEY_CTX_new(EVP_PKEY *pkey, ENGINE *e);
+ void q_EVP_PKEY_CTX_free(EVP_PKEY_CTX *ctx);
+ int q_EVP_PKEY_param_check(EVP_PKEY_CTX *ctx);
+-int q_EVP_PKEY_base_id(EVP_PKEY *a);
+ int q_RSA_bits(RSA *a);
+ Q_AUTOTEST_EXPORT int q_OPENSSL_sk_num(OPENSSL_STACK *a);
+ Q_AUTOTEST_EXPORT void q_OPENSSL_sk_pop_free(OPENSSL_STACK *a, void (*b)(void *));
+@@ -246,7 +245,7 @@ Q_AUTOTEST_EXPORT void q_OPENSSL_sk_push(OPENSSL_STACK *st, void *data);
+ Q_AUTOTEST_EXPORT void q_OPENSSL_sk_free(OPENSSL_STACK *a);
+ Q_AUTOTEST_EXPORT void * q_OPENSSL_sk_value(OPENSSL_STACK *a, int b);
+ int q_SSL_session_reused(SSL *a);
+-unsigned long q_SSL_CTX_set_options(SSL_CTX *ctx, unsigned long op);
++qssloptions q_SSL_CTX_set_options(SSL_CTX *ctx, qssloptions op);
+ int q_OPENSSL_init_ssl(uint64_t opts, const OPENSSL_INIT_SETTINGS *settings);
+ size_t q_SSL_get_client_random(SSL *a, unsigned char *out, size_t outlen);
+ size_t q_SSL_SESSION_get_master_key(const SSL_SESSION *session, unsigned char *out, size_t outlen);
+@@ -510,7 +509,6 @@ const SSL_CIPHER *q_SSL_get_current_cipher(SSL *a);
+ int q_SSL_version(const SSL *a);
+ int q_SSL_get_error(SSL *a, int b);
+ STACK_OF(X509) *q_SSL_get_peer_cert_chain(SSL *a);
+-X509 *q_SSL_get_peer_certificate(SSL *a);
+ long q_SSL_get_verify_result(const SSL *a);
+ SSL *q_SSL_new(SSL_CTX *a);
+ SSL_CTX *q_SSL_get_SSL_CTX(SSL *a);
+@@ -582,10 +580,7 @@ DH *q_DH_new();
+ void q_DH_free(DH *dh);
+ DH *q_d2i_DHparams(DH **a, const unsigned char **pp, long length);
+ int q_i2d_DHparams(DH *a, unsigned char **p);
+-
+-#ifndef OPENSSL_NO_DEPRECATED_3_0
+ int q_DH_check(DH *dh, int *codes);
+-#endif // OPENSSL_NO_DEPRECATED_3_0
+
+ BIGNUM *q_BN_bin2bn(const unsigned char *s, int len, BIGNUM *ret);
+ #define q_SSL_CTX_set_tmp_dh(ctx, dh) q_SSL_CTX_ctrl((ctx), SSL_CTRL_SET_TMP_DH, 0, (char *)dh)
+@@ -754,6 +749,17 @@ void q_CRYPTO_free(void *str, const char *file, int line);
+ int q_SSL_CTX_get_security_level(const SSL_CTX *ctx);
+ void q_SSL_CTX_set_security_level(SSL_CTX *ctx, int level);
+
++// Here we have the ones that make difference between OpenSSL pre/post v3:
++#if defined(OPENSSL_VERSION_MAJOR) && OPENSSL_VERSION_MAJOR >= 3
++X509 *q_SSL_get1_peer_certificate(SSL *a);
++#define q_SSL_get_peer_certificate q_SSL_get1_peer_certificate
++int q_EVP_PKEY_get_base_id(const EVP_PKEY *pkey);
++#define q_EVP_PKEY_base_id q_EVP_PKEY_get_base_id
++#else
++X509 *q_SSL_get_peer_certificate(SSL *a);
++int q_EVP_PKEY_base_id(EVP_PKEY *a);
++#endif // OPENSSL_VERSION_MAJOR >= 3
++
+ QT_END_NAMESPACE
+
+ #endif
+diff --git a/qtbase/src/platformsupport/eglconvenience/qt_egl_p.h b/qtbase/src/platformsupport/eglconvenience/qt_egl_p.h
+index bf37d07fd8..dbd42fb799 100644
+--- a/qtbase/src/platformsupport/eglconvenience/qt_egl_p.h
++++ b/qtbase/src/platformsupport/eglconvenience/qt_egl_p.h
+@@ -61,7 +61,11 @@
+ # if !defined(Q_OS_INTEGRITY)
+ # define WIN_INTERFACE_CUSTOM // NV
+ # endif // Q_OS_INTEGRITY
+-#endif // QT_EGL_NO_X11
++#else // QT_EGL_NO_X11
++// If one has an eglplatform.h with https://github.com/KhronosGroup/EGL-Registry/pull/130
++// that needs USE_X11 to be defined.
++# define USE_X11
++#endif
+
+ #ifdef QT_EGL_WAYLAND
+ # define WAYLAND // NV
+diff --git a/qtbase/src/platformsupport/fontdatabases/fontconfig/qfontconfigdatabase.cpp b/qtbase/src/platformsupport/fontdatabases/fontconfig/qfontconfigdatabase.cpp
+index 159b490ce0..00aa80cd58 100644
+--- a/qtbase/src/platformsupport/fontdatabases/fontconfig/qfontconfigdatabase.cpp
++++ b/qtbase/src/platformsupport/fontdatabases/fontconfig/qfontconfigdatabase.cpp
+@@ -567,6 +567,8 @@ void QFontconfigDatabase::populateFontDatabase()
+ fonts = FcFontList(nullptr, pattern, os);
+ FcObjectSetDestroy(os);
+ FcPatternDestroy(pattern);
++ if (!fonts)
++ return;
+ }
+
+ for (int i = 0; i < fonts->nfont; i++)
+diff --git a/qtbase/src/platformsupport/input/xkbcommon/qxkbcommon.cpp b/qtbase/src/platformsupport/input/xkbcommon/qxkbcommon.cpp
+index b713c19447..7cb9a8c79a 100644
+--- a/qtbase/src/platformsupport/input/xkbcommon/qxkbcommon.cpp
++++ b/qtbase/src/platformsupport/input/xkbcommon/qxkbcommon.cpp
+@@ -95,6 +95,7 @@ static constexpr const auto KeyTbl = qMakeArray(
+ Xkb2Qt<XKB_KEY_Clear, Qt::Key_Delete>,
+ Xkb2Qt<XKB_KEY_Pause, Qt::Key_Pause>,
+ Xkb2Qt<XKB_KEY_Print, Qt::Key_Print>,
++ Xkb2Qt<XKB_KEY_Sys_Req, Qt::Key_SysReq>,
+ Xkb2Qt<0x1005FF60, Qt::Key_SysReq>, // hardcoded Sun SysReq
+ Xkb2Qt<0x1007ff00, Qt::Key_SysReq>, // hardcoded X386 SysReq
+
+@@ -471,7 +472,7 @@ QVector<xkb_keysym_t> QXkbCommon::toKeysym(QKeyEvent *event)
+ } else if (event->modifiers() & Qt::KeypadModifier) {
+ if (qtKey >= Qt::Key_0 && qtKey <= Qt::Key_9)
+ keysyms.append(XKB_KEY_KP_0 + (qtKey - Qt::Key_0));
+- } else if (isLatin(qtKey) && event->text().isUpper()) {
++ } else if (isLatin1(qtKey) && event->text().isUpper()) {
+ keysyms.append(qtKey);
+ }
+
+@@ -523,7 +524,7 @@ int QXkbCommon::keysymToQtKey(xkb_keysym_t keysym, Qt::KeyboardModifiers modifie
+ // With standard shortcuts we should prefer a latin character, this is
+ // for checks like "some qkeyevent == QKeySequence::Copy" to work even
+ // when using for example 'russian' keyboard layout.
+- if (!QXkbCommon::isLatin(keysym)) {
++ if (!QXkbCommon::isLatin1(keysym)) {
+ xkb_keysym_t latinKeysym = QXkbCommon::lookupLatinKeysym(state, code);
+ if (latinKeysym != XKB_KEY_NoSymbol)
+ keysym = latinKeysym;
+@@ -546,7 +547,7 @@ static int keysymToQtKey_internal(xkb_keysym_t keysym, Qt::KeyboardModifiers mod
+ } else if (keysym >= XKB_KEY_KP_0 && keysym <= XKB_KEY_KP_9) {
+ // numeric keypad keys
+ qtKey = Qt::Key_0 + (keysym - XKB_KEY_KP_0);
+- } else if (QXkbCommon::isLatin(keysym)) {
++ } else if (QXkbCommon::isLatin1(keysym)) {
+ qtKey = QXkbCommon::qxkbcommon_xkb_keysym_to_upper(keysym);
+ } else {
+ // check if we have a direct mapping
+@@ -678,7 +679,7 @@ QList<int> QXkbCommon::possibleKeys(xkb_state *state, const QKeyEvent *event,
+ Qt::KeyboardModifiers neededMods = ModsTbl[i];
+ if ((modifiers & neededMods) == neededMods) {
+ if (i == 8) {
+- if (isLatin(baseQtKey))
++ if (isLatin1(baseQtKey))
+ continue;
+ // add a latin key as a fall back key
+ sym = lookupLatinKeysym(state, keycode);
+@@ -733,7 +734,7 @@ void QXkbCommon::verifyHasLatinLayout(xkb_keymap *keymap)
+ for (xkb_layout_index_t layout = 0; layout < layoutCount; ++layout) {
+ for (xkb_keycode_t code = minKeycode; code < maxKeycode; ++code) {
+ xkb_keymap_key_get_syms_by_level(keymap, code, layout, 0, &keysyms);
+- if (keysyms && isLatin(keysyms[0]))
++ if (keysyms && isLatin1(keysyms[0]))
+ nrLatinKeys++;
+ if (nrLatinKeys > 10) // arbitrarily chosen threshold
+ return;
+@@ -766,7 +767,7 @@ xkb_keysym_t QXkbCommon::lookupLatinKeysym(xkb_state *state, xkb_keycode_t keyco
+ xkb_level_index_t level = xkb_state_key_get_level(state, keycode, layout);
+ if (xkb_keymap_key_get_syms_by_level(keymap, keycode, layout, level, &syms) != 1)
+ continue;
+- if (isLatin(syms[0])) {
++ if (isLatin1(syms[0])) {
+ sym = syms[0];
+ break;
+ }
+diff --git a/qtbase/src/platformsupport/input/xkbcommon/qxkbcommon_p.h b/qtbase/src/platformsupport/input/xkbcommon/qxkbcommon_p.h
+index 561eae03db..8389bd8f5a 100644
+--- a/qtbase/src/platformsupport/input/xkbcommon/qxkbcommon_p.h
++++ b/qtbase/src/platformsupport/input/xkbcommon/qxkbcommon_p.h
+@@ -94,8 +94,8 @@ public:
+ static void verifyHasLatinLayout(xkb_keymap *keymap);
+ static xkb_keysym_t lookupLatinKeysym(xkb_state *state, xkb_keycode_t keycode);
+
+- static bool isLatin(xkb_keysym_t sym) {
+- return ((sym >= 'a' && sym <= 'z') || (sym >= 'A' && sym <= 'Z'));
++ static bool isLatin1(xkb_keysym_t sym) {
++ return sym <= 0xff;
+ }
+ static bool isKeypad(xkb_keysym_t sym) {
+ return sym >= XKB_KEY_KP_Space && sym <= XKB_KEY_KP_9;
+diff --git a/qtbase/src/platformsupport/kmsconvenience/qkmsdevice.cpp b/qtbase/src/platformsupport/kmsconvenience/qkmsdevice.cpp
+index 8cd7f9b368..406f84663f 100644
+--- a/qtbase/src/platformsupport/kmsconvenience/qkmsdevice.cpp
++++ b/qtbase/src/platformsupport/kmsconvenience/qkmsdevice.cpp
+@@ -318,7 +318,7 @@ QPlatformScreen *QKmsDevice::createScreenForConnector(drmModeResPtr resources,
+
+ if (current < 0 && crtc_mode.clock != 0) {
+ modes << crtc_mode;
+- current = mode.size() - 1;
++ current = modes.size() - 1;
+ }
+
+ if (configuration == OutputConfigCurrent)
+diff --git a/qtbase/src/platformsupport/linuxaccessibility/atspiadaptor.cpp b/qtbase/src/platformsupport/linuxaccessibility/atspiadaptor.cpp
+index 9153fd20bb..255ea5e33e 100644
+--- a/qtbase/src/platformsupport/linuxaccessibility/atspiadaptor.cpp
++++ b/qtbase/src/platformsupport/linuxaccessibility/atspiadaptor.cpp
+@@ -194,6 +194,9 @@ QString AtSpiAdaptor::introspect(const QString &path) const
+ " <arg direction=\"out\" type=\"(so)\"/>\n"
+ " <annotation value=\"QSpiObjectReference\" name=\"org.qtproject.QtDBus.QtTypeName.Out0\"/>\n"
+ " </method>\n"
++ " <method name=\"GetAccessibleId\">\n"
++ " <arg direction=\"out\" type=\"s\"/>\n"
++ " </method>\n"
+ " </interface>\n"
+ );
+
+@@ -913,8 +916,17 @@ void AtSpiAdaptor::notify(QAccessibleEvent *event)
+ }
+ case QAccessible::NameChanged: {
+ if (sendObject || sendObject_property_change || sendObject_property_change_accessible_name) {
+- QString path = pathForInterface(event->accessibleInterface());
+- QVariantList args = packDBusSignalArguments(QLatin1String("accessible-name"), 0, 0, variantForPath(path));
++ QAccessibleInterface *iface = event->accessibleInterface();
++ if (!iface) {
++ qCDebug(lcAccessibilityAtspi,
++ "NameChanged event from invalid accessible.");
++ return;
++ }
++
++ QString path = pathForInterface(iface);
++ QVariantList args = packDBusSignalArguments(
++ QLatin1String("accessible-name"), 0, 0,
++ QVariant::fromValue(QDBusVariant(iface->text(QAccessible::Name))));
+ sendDBusSignal(path, QLatin1String(ATSPI_DBUS_INTERFACE_EVENT_OBJECT),
+ QLatin1String("PropertyChange"), args);
+ }
+@@ -922,8 +934,17 @@ void AtSpiAdaptor::notify(QAccessibleEvent *event)
+ }
+ case QAccessible::DescriptionChanged: {
+ if (sendObject || sendObject_property_change || sendObject_property_change_accessible_description) {
+- QString path = pathForInterface(event->accessibleInterface());
+- QVariantList args = packDBusSignalArguments(QLatin1String("accessible-description"), 0, 0, variantForPath(path));
++ QAccessibleInterface *iface = event->accessibleInterface();
++ if (!iface) {
++ qCDebug(lcAccessibilityAtspi,
++ "DescriptionChanged event from invalid accessible.");
++ return;
++ }
++
++ QString path = pathForInterface(iface);
++ QVariantList args = packDBusSignalArguments(
++ QLatin1String("accessible-description"), 0, 0,
++ QVariant::fromValue(QDBusVariant(iface->text(QAccessible::Description))));
+ sendDBusSignal(path, QLatin1String(ATSPI_DBUS_INTERFACE_EVENT_OBJECT),
+ QLatin1String("PropertyChange"), args);
+ }
+@@ -1038,7 +1059,9 @@ void AtSpiAdaptor::notify(QAccessibleEvent *event)
+ // Combo Box with AT-SPI likes to be special
+ // It requires a name-change to update caches and then selection-changed
+ QString path = pathForInterface(iface);
+- QVariantList args1 = packDBusSignalArguments(QLatin1String("accessible-name"), 0, 0, variantForPath(path));
++ QVariantList args1 = packDBusSignalArguments(
++ QLatin1String("accessible-name"), 0, 0,
++ QVariant::fromValue(QDBusVariant(iface->text(QAccessible::Name))));
+ sendDBusSignal(path, QLatin1String(ATSPI_DBUS_INTERFACE_EVENT_OBJECT),
+ QLatin1String("PropertyChange"), args1);
+ QVariantList args2 = packDBusSignalArguments(QString(), 0, 0, QVariant::fromValue(QDBusVariant(QVariant(0))));
+@@ -1358,6 +1381,26 @@ void AtSpiAdaptor::registerApplication()
+ delete registry;
+ }
+
++namespace {
++QString accessibleIdForAccessible(QAccessibleInterface *accessible)
++{
++ QString result;
++ while (accessible) {
++ if (!result.isEmpty())
++ result.prepend(QLatin1Char('.'));
++ if (auto obj = accessible->object()) {
++ const QString name = obj->objectName();
++ if (!name.isEmpty())
++ result.prepend(name);
++ else
++ result.prepend(QString::fromUtf8(obj->metaObject()->className()));
++ }
++ accessible = accessible->parent();
++ }
++ return result;
++}
++} // namespace
++
+ // Accessible
+ bool AtSpiAdaptor::accessibleInterface(QAccessibleInterface *interface, const QString &function, const QDBusMessage &message, const QDBusConnection &connection)
+ {
+@@ -1441,6 +1484,9 @@ bool AtSpiAdaptor::accessibleInterface(QAccessibleInterface *interface, const QS
+ children << ref;
+ }
+ connection.send(message.createReply(QVariant::fromValue(children)));
++ } else if (function == QLatin1String("GetAccessibleId")) {
++ sendReply(connection, message,
++ QVariant::fromValue(QDBusVariant(accessibleIdForAccessible(interface))));
+ } else {
+ qCDebug(lcAccessibilityAtspi) << "WARNING: AtSpiAdaptor::accessibleInterface does not implement " << function << message.path();
+ return false;
+diff --git a/qtbase/src/platformsupport/linuxaccessibility/dbusconnection.cpp b/qtbase/src/platformsupport/linuxaccessibility/dbusconnection.cpp
+index 45ddc8e496..cc734abc63 100644
+--- a/qtbase/src/platformsupport/linuxaccessibility/dbusconnection.cpp
++++ b/qtbase/src/platformsupport/linuxaccessibility/dbusconnection.cpp
+@@ -69,6 +69,21 @@ QT_BEGIN_NAMESPACE
+ DBusConnection::DBusConnection(QObject *parent)
+ : QObject(parent), m_a11yConnection(QString()), m_enabled(false)
+ {
++ // If the bus is explicitly set via env var it overrides everything else.
++ QByteArray addressEnv = qgetenv("AT_SPI_BUS_ADDRESS");
++ if (!addressEnv.isEmpty()) {
++ // Only connect on next loop run, connections to our enabled signal are
++ // only established after the ctor returns.
++ QMetaObject::invokeMethod(
++ this,
++ [this, addressEnv] {
++ m_enabled = true;
++ connectA11yBus(QString::fromLocal8Bit(addressEnv));
++ },
++ Qt::QueuedConnection);
++ return;
++ }
++
+ // Start monitoring if "org.a11y.Bus" is registered as DBus service.
+ QDBusConnection c = QDBusConnection::sessionBus();
+ if (!c.isConnected()) {
+diff --git a/qtbase/src/platformsupport/services/genericunix/qgenericunixservices.cpp b/qtbase/src/platformsupport/services/genericunix/qgenericunixservices.cpp
+index 1a3cab275d..2abe039126 100644
+--- a/qtbase/src/platformsupport/services/genericunix/qgenericunixservices.cpp
++++ b/qtbase/src/platformsupport/services/genericunix/qgenericunixservices.cpp
+@@ -51,6 +51,9 @@
+ #include <QtCore/QStandardPaths>
+ #include <QtCore/QUrl>
+
++#include <QtGui/QGuiApplication>
++#include <QtGui/QWindow>
++
+ #if QT_CONFIG(dbus)
+ // These QtCore includes are needed for xdg-desktop-portal support
+ #include <QtCore/private/qcore_unix_p.h>
+@@ -58,6 +61,8 @@
+ #include <QtCore/QFileInfo>
+ #include <QtCore/QUrlQuery>
+
++#include <QtGui/QColor>
++
+ #include <QtDBus/QDBusConnection>
+ #include <QtDBus/QDBusMessage>
+ #include <QtDBus/QDBusPendingCall>
+@@ -142,6 +147,8 @@ static inline bool detectWebBrowser(const QByteArray &desktop,
+ }
+
+ if (desktop == QByteArray("KDE")) {
++ if (checkExecutable(QStringLiteral("kde-open5"), browser))
++ return true;
+ // Konqueror launcher
+ if (checkExecutable(QStringLiteral("kfmclient"), browser)) {
+ browser->append(QLatin1String(" exec"));
+@@ -296,8 +303,135 @@ static inline QDBusMessage xdgDesktopPortalSendEmail(const QUrl &url)
+
+ return QDBusConnection::sessionBus().call(message);
+ }
++
++namespace {
++struct XDGDesktopColor
++{
++ double r = 0;
++ double g = 0;
++ double b = 0;
++
++ QColor toQColor() const
++ {
++ constexpr auto rgbMax = 255;
++ return { static_cast<int>(r * rgbMax), static_cast<int>(g * rgbMax),
++ static_cast<int>(b * rgbMax) };
++ }
++};
++
++const QDBusArgument &operator>>(const QDBusArgument &argument, XDGDesktopColor &myStruct)
++{
++ argument.beginStructure();
++ argument >> myStruct.r >> myStruct.g >> myStruct.b;
++ argument.endStructure();
++ return argument;
++}
++
++class XdgDesktopPortalColorPicker : public QPlatformServiceColorPicker
++{
++ Q_OBJECT
++public:
++ XdgDesktopPortalColorPicker(const QString &parentWindowId, QWindow *parent)
++ : QPlatformServiceColorPicker(parent), m_parentWindowId(parentWindowId)
++ {
++ }
++
++ void pickColor() override
++ {
++ // DBus signature:
++ // PickColor (IN s parent_window,
++ // IN a{sv} options
++ // OUT o handle)
++ // Options:
++ // handle_token (s) - A string that will be used as the last element of the @handle.
++
++ QDBusMessage message = QDBusMessage::createMethodCall(
++ QStringLiteral("org.freedesktop.portal.Desktop"), QStringLiteral("/org/freedesktop/portal/desktop"),
++ QStringLiteral("org.freedesktop.portal.Screenshot"), QStringLiteral("PickColor"));
++ message << m_parentWindowId << QVariantMap();
++
++ QDBusPendingCall pendingCall = QDBusConnection::sessionBus().asyncCall(message);
++ auto watcher = new QDBusPendingCallWatcher(pendingCall, this);
++ connect(watcher, &QDBusPendingCallWatcher::finished, this,
++ [this](QDBusPendingCallWatcher *watcher) {
++ watcher->deleteLater();
++ QDBusPendingReply<QDBusObjectPath> reply = *watcher;
++ if (reply.isError()) {
++ qWarning("DBus call to pick color failed: %s",
++ qPrintable(reply.error().message()));
++ Q_EMIT colorPicked({});
++ } else {
++ QDBusConnection::sessionBus().connect(
++ QStringLiteral("org.freedesktop.portal.Desktop"), reply.value().path(),
++ QStringLiteral("org.freedesktop.portal.Request"), QStringLiteral("Response"), this,
++ // clang-format off
++ SLOT(gotColorResponse(uint,QVariantMap))
++ // clang-format on
++ );
++ }
++ });
++ }
++
++private Q_SLOTS:
++ void gotColorResponse(uint result, const QVariantMap &map)
++ {
++ if (result != 0)
++ return;
++ XDGDesktopColor color{};
++ map.value(QStringLiteral("color")).value<QDBusArgument>() >> color;
++ Q_EMIT colorPicked(color.toQColor());
++ deleteLater();
++ }
++
++private:
++ const QString m_parentWindowId;
++};
++} // namespace
++
+ #endif // QT_CONFIG(dbus)
+
++QGenericUnixServices::QGenericUnixServices()
++{
++#if QT_CONFIG(dbus)
++ if (qEnvironmentVariableIntValue("QT_NO_XDG_DESKTOP_PORTAL") > 0) {
++ return;
++ }
++ QDBusMessage message = QDBusMessage::createMethodCall(
++ QStringLiteral("org.freedesktop.portal.Desktop"), QStringLiteral("/org/freedesktop/portal/desktop"),
++ QStringLiteral("org.freedesktop.DBus.Properties"), QStringLiteral("Get"));
++ message << QStringLiteral("org.freedesktop.portal.Screenshot")
++ << QStringLiteral("version");
++
++ QDBusPendingCall pendingCall = QDBusConnection::sessionBus().asyncCall(message);
++ auto watcher = new QDBusPendingCallWatcher(pendingCall);
++ QObject::connect(watcher, &QDBusPendingCallWatcher::finished, watcher,
++ [this](QDBusPendingCallWatcher *watcher) {
++ watcher->deleteLater();
++ QDBusPendingReply<QVariant> reply = *watcher;
++ if (!reply.isError() && reply.value().toUInt() >= 2)
++ m_hasScreenshotPortalWithColorPicking = true;
++ });
++
++#endif
++}
++
++QPlatformServiceColorPicker *QGenericUnixServices::colorPicker(QWindow *parent)
++{
++#if QT_CONFIG(dbus)
++ // Make double sure that we are in a wayland environment. In particular check
++ // WAYLAND_DISPLAY so also XWayland apps benefit from portal-based color picking.
++ // Outside wayland we'll rather rely on other means than the XDG desktop portal.
++ if (!qEnvironmentVariableIsEmpty("WAYLAND_DISPLAY")
++ || QGuiApplication::platformName().startsWith(QLatin1String("wayland"))) {
++ return new XdgDesktopPortalColorPicker(portalWindowIdentifier(parent), parent);
++ }
++ return nullptr;
++#else
++ Q_UNUSED(parent);
++ return nullptr;
++#endif
++}
++
+ QByteArray QGenericUnixServices::desktopEnvironment() const
+ {
+ static const QByteArray result = detectDesktopEnvironment();
+@@ -352,6 +486,8 @@ bool QGenericUnixServices::openDocument(const QUrl &url)
+ }
+
+ #else
++QGenericUnixServices::QGenericUnixServices() = default;
++
+ QByteArray QGenericUnixServices::desktopEnvironment() const
+ {
+ return QByteArrayLiteral("UNKNOWN");
+@@ -371,6 +507,30 @@ bool QGenericUnixServices::openDocument(const QUrl &url)
+ return false;
+ }
+
++QPlatformServiceColorPicker *QGenericUnixServices::colorPicker(QWindow *parent)
++{
++ Q_UNUSED(parent);
++ return nullptr;
++}
++
+ #endif // QT_NO_MULTIPROCESS
+
++QString QGenericUnixServices::portalWindowIdentifier(QWindow *window)
++{
++ if (QGuiApplication::platformName() == QLatin1String("xcb"))
++ return QStringLiteral("x11:") + QString::number(window->winId(), 16);
++ return QString();
++}
++
++bool QGenericUnixServices::hasCapability(Capability capability) const
++{
++ switch (capability) {
++ case Capability::ColorPicking:
++ return m_hasScreenshotPortalWithColorPicking;
++ }
++ return false;
++}
++
+ QT_END_NAMESPACE
++
++#include "qgenericunixservices.moc"
+diff --git a/qtbase/src/platformsupport/services/genericunix/qgenericunixservices_p.h b/qtbase/src/platformsupport/services/genericunix/qgenericunixservices_p.h
+index 8ac3de6f03..30924e64bd 100644
+--- a/qtbase/src/platformsupport/services/genericunix/qgenericunixservices_p.h
++++ b/qtbase/src/platformsupport/services/genericunix/qgenericunixservices_p.h
+@@ -59,16 +59,21 @@ QT_BEGIN_NAMESPACE
+ class QGenericUnixServices : public QPlatformServices
+ {
+ public:
+- QGenericUnixServices() {}
++ QGenericUnixServices();
+
+ QByteArray desktopEnvironment() const override;
+
++ bool hasCapability(Capability capability) const override;
+ bool openUrl(const QUrl &url) override;
+ bool openDocument(const QUrl &url) override;
++ QPlatformServiceColorPicker *colorPicker(QWindow *parent = nullptr) override;
++
++ virtual QString portalWindowIdentifier(QWindow *window);
+
+ private:
+ QString m_webBrowser;
+ QString m_documentLauncher;
++ bool m_hasScreenshotPortalWithColorPicking = false;
+ };
+
+ QT_END_NAMESPACE
+diff --git a/qtbase/src/platformsupport/themes/genericunix/dbusmenu/qdbusmenuconnection.cpp b/qtbase/src/platformsupport/themes/genericunix/dbusmenu/qdbusmenuconnection.cpp
+index 09470bccc6..cc7c7d4d8a 100644
+--- a/qtbase/src/platformsupport/themes/genericunix/dbusmenu/qdbusmenuconnection.cpp
++++ b/qtbase/src/platformsupport/themes/genericunix/dbusmenu/qdbusmenuconnection.cpp
+@@ -69,6 +69,7 @@ const QString MenuBarPath = QLatin1String("/MenuBar");
+ */
+ QDBusMenuConnection::QDBusMenuConnection(QObject *parent, const QString &serviceName)
+ : QObject(parent)
++ , m_serviceName(serviceName)
+ , m_connection(serviceName.isNull() ? QDBusConnection::sessionBus()
+ : QDBusConnection::connectToBus(QDBusConnection::SessionBus, serviceName))
+ , m_dbusWatcher(new QDBusServiceWatcher(StatusNotifierWatcherService, m_connection, QDBusServiceWatcher::WatchForRegistration, this))
+@@ -83,6 +84,12 @@ QDBusMenuConnection::QDBusMenuConnection(QObject *parent, const QString &service
+ #endif
+ }
+
++QDBusMenuConnection::~QDBusMenuConnection()
++{
++ if (!m_serviceName.isEmpty() && m_connection.isConnected())
++ QDBusConnection::disconnectFromBus(m_serviceName);
++}
++
+ void QDBusMenuConnection::dbusError(const QDBusError &error)
+ {
+ qWarning() << "QDBusTrayIcon encountered a D-Bus error:" << error;
+@@ -105,13 +112,7 @@ void QDBusMenuConnection::unregisterTrayIconMenu(QDBusTrayIcon *item)
+
+ bool QDBusMenuConnection::registerTrayIcon(QDBusTrayIcon *item)
+ {
+- bool success = connection().registerService(item->instanceId());
+- if (!success) {
+- qWarning() << "failed to register service" << item->instanceId();
+- return false;
+- }
+-
+- success = connection().registerObject(StatusNotifierItemPath, item);
++ bool success = connection().registerObject(StatusNotifierItemPath, item);
+ if (!success) {
+ unregisterTrayIcon(item);
+ qWarning() << "failed to register" << item->instanceId() << StatusNotifierItemPath;
+@@ -126,21 +127,18 @@ bool QDBusMenuConnection::registerTrayIcon(QDBusTrayIcon *item)
+
+ bool QDBusMenuConnection::registerTrayIconWithWatcher(QDBusTrayIcon *item)
+ {
++ Q_UNUSED(item);
+ QDBusMessage registerMethod = QDBusMessage::createMethodCall(
+ StatusNotifierWatcherService, StatusNotifierWatcherPath, StatusNotifierWatcherService,
+ QLatin1String("RegisterStatusNotifierItem"));
+- registerMethod.setArguments(QVariantList() << item->instanceId());
++ registerMethod.setArguments(QVariantList() << m_connection.baseService());
+ return m_connection.callWithCallback(registerMethod, this, SIGNAL(trayIconRegistered()), SLOT(dbusError(QDBusError)));
+ }
+
+-bool QDBusMenuConnection::unregisterTrayIcon(QDBusTrayIcon *item)
++void QDBusMenuConnection::unregisterTrayIcon(QDBusTrayIcon *item)
+ {
+ unregisterTrayIconMenu(item);
+ connection().unregisterObject(StatusNotifierItemPath);
+- bool success = connection().unregisterService(item->instanceId());
+- if (!success)
+- qWarning() << "failed to unregister service" << item->instanceId();
+- return success;
+ }
+ #endif // QT_NO_SYSTEMTRAYICON
+
+diff --git a/qtbase/src/platformsupport/themes/genericunix/dbusmenu/qdbusmenuconnection_p.h b/qtbase/src/platformsupport/themes/genericunix/dbusmenu/qdbusmenuconnection_p.h
+index f484795fbb..97bdfabb85 100644
+--- a/qtbase/src/platformsupport/themes/genericunix/dbusmenu/qdbusmenuconnection_p.h
++++ b/qtbase/src/platformsupport/themes/genericunix/dbusmenu/qdbusmenuconnection_p.h
+@@ -70,6 +70,7 @@ class QDBusMenuConnection : public QObject
+
+ public:
+ QDBusMenuConnection(QObject *parent = nullptr, const QString &serviceName = QString());
++ ~QDBusMenuConnection();
+ QDBusConnection connection() const { return m_connection; }
+ QDBusServiceWatcher *dbusWatcher() const { return m_dbusWatcher; }
+ bool isStatusNotifierHostRegistered() const { return m_statusNotifierHostRegistered; }
+@@ -78,7 +79,7 @@ public:
+ void unregisterTrayIconMenu(QDBusTrayIcon *item);
+ bool registerTrayIcon(QDBusTrayIcon *item);
+ bool registerTrayIconWithWatcher(QDBusTrayIcon *item);
+- bool unregisterTrayIcon(QDBusTrayIcon *item);
++ void unregisterTrayIcon(QDBusTrayIcon *item);
+ #endif // QT_NO_SYSTEMTRAYICON
+
+ Q_SIGNALS:
+@@ -90,6 +91,7 @@ private Q_SLOTS:
+ void dbusError(const QDBusError &error);
+
+ private:
++ QString m_serviceName;
+ QDBusConnection m_connection;
+ QDBusServiceWatcher *m_dbusWatcher;
+ bool m_statusNotifierHostRegistered;
+diff --git a/qtbase/src/platformsupport/themes/genericunix/dbustray/qdbustrayicon.cpp b/qtbase/src/platformsupport/themes/genericunix/dbustray/qdbustrayicon.cpp
+index bede70975a..76bfec5e5a 100644
+--- a/qtbase/src/platformsupport/themes/genericunix/dbustray/qdbustrayicon.cpp
++++ b/qtbase/src/platformsupport/themes/genericunix/dbustray/qdbustrayicon.cpp
+@@ -71,8 +71,12 @@ Q_LOGGING_CATEGORY(qLcTray, "qt.qpa.tray")
+ static QString iconTempPath()
+ {
+ QString tempPath = QStandardPaths::writableLocation(QStandardPaths::RuntimeLocation);
+- if (!tempPath.isEmpty())
++ if (!tempPath.isEmpty()) {
++ QString flatpakId = qEnvironmentVariable("FLATPAK_ID");
++ if (!flatpakId.isEmpty() && QFileInfo::exists(QLatin1String("/.flatpak-info")))
++ tempPath += QLatin1String("/app/") + flatpakId;
+ return tempPath;
++ }
+
+ tempPath = QStandardPaths::writableLocation(QStandardPaths::GenericCacheLocation);
+
+diff --git a/qtbase/src/platformsupport/themes/genericunix/qgenericunixthemes.cpp b/qtbase/src/platformsupport/themes/genericunix/qgenericunixthemes.cpp
+index cb1b39db64..6e01af052c 100644
+--- a/qtbase/src/platformsupport/themes/genericunix/qgenericunixthemes.cpp
++++ b/qtbase/src/platformsupport/themes/genericunix/qgenericunixthemes.cpp
+@@ -755,6 +755,9 @@ QVariant QGnomeTheme::themeHint(QPlatformTheme::ThemeHint hint) const
+ return QVariant(QChar(0x2022));
+ case QPlatformTheme::UiEffects:
+ return QVariant(int(HoverEffect));
++ case QPlatformTheme::ButtonPressKeys:
++ return QVariant::fromValue(
++ QList<Qt::Key>({ Qt::Key_Space, Qt::Key_Return, Qt::Key_Enter, Qt::Key_Select }));
+ default:
+ break;
+ }
+diff --git a/qtbase/src/plugins/platforms/eglfs/api/qeglfscursor.cpp b/qtbase/src/plugins/platforms/eglfs/api/qeglfscursor.cpp
+index 98e05195ee..1e92f43dec 100644
+--- a/qtbase/src/plugins/platforms/eglfs/api/qeglfscursor.cpp
++++ b/qtbase/src/plugins/platforms/eglfs/api/qeglfscursor.cpp
+@@ -343,8 +343,7 @@ void QEglFSCursor::paintOnScreen()
+ // screens are siblings of each other. When not enabled, the sibling list
+ // only contains m_screen itself.
+ for (QPlatformScreen *screen : m_screen->virtualSiblings()) {
+- if (screen->geometry().contains(cr.topLeft().toPoint() + m_cursor.hotSpot)
+- && QOpenGLContext::currentContext()->screen() == screen->screen())
++ if (screen->geometry().contains(cr.topLeft().toPoint() + m_cursor.hotSpot))
+ {
+ cr.translate(-screen->geometry().topLeft());
+ const QSize screenSize = screen->geometry().size();
+@@ -468,11 +467,12 @@ void QEglFSCursor::draw(const QRectF &r)
+ {
+ StateSaver stateSaver;
+
+- QEglFSCursorData &gfx = static_cast<QEglFSContext*>(QOpenGLContext::currentContext()->handle())->cursorData;
+- if (!gfx.program) {
+- // one time initialization
++ // one time initialization
++ if (!QOpenGLFunctions::d_ptr)
+ initializeOpenGLFunctions();
+
++ QEglFSCursorData &gfx = static_cast<QEglFSContext*>(QOpenGLContext::currentContext()->handle())->cursorData;
++ if (!gfx.program) {
+ createShaderPrograms();
+
+ if (!gfx.atlasTexture) {
+diff --git a/qtbase/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmseventreader.cpp b/qtbase/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmseventreader.cpp
+index 645a0ae2e9..3e0e406f1a 100644
+--- a/qtbase/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmseventreader.cpp
++++ b/qtbase/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmseventreader.cpp
+@@ -179,7 +179,7 @@ void QEglFSKmsEventReader::create(QEglFSKmsDevice *device)
+
+ m_device = device;
+
+- qCDebug(qLcEglfsKmsDebug, "Initalizing event reader for device %p fd %d",
++ qCDebug(qLcEglfsKmsDebug, "Initializing event reader for device %p fd %d",
+ m_device, m_device->fd());
+
+ m_thread = new QEglFSKmsEventReaderThread(m_device->fd());
+diff --git a/qtbase/src/plugins/platforms/offscreen/qoffscreenintegration.cpp b/qtbase/src/plugins/platforms/offscreen/qoffscreenintegration.cpp
+index 141fb68a23..d4294d425a 100644
+--- a/qtbase/src/plugins/platforms/offscreen/qoffscreenintegration.cpp
++++ b/qtbase/src/plugins/platforms/offscreen/qoffscreenintegration.cpp
+@@ -122,11 +122,13 @@ QOffscreenIntegration::QOffscreenIntegration()
+ #endif
+ m_services.reset(new QPlatformServices);
+
+- QWindowSystemInterface::handleScreenAdded(new QOffscreenScreen);
++ m_screen = new QOffscreenScreen;
++ QWindowSystemInterface::handleScreenAdded(m_screen);
+ }
+
+ QOffscreenIntegration::~QOffscreenIntegration()
+ {
++ QWindowSystemInterface::handleScreenRemoved(m_screen);
+ }
+
+ void QOffscreenIntegration::initialize()
+diff --git a/qtbase/src/plugins/platforms/offscreen/qoffscreenintegration.h b/qtbase/src/plugins/platforms/offscreen/qoffscreenintegration.h
+index 0ea90f6c2f..fe00fde07c 100644
+--- a/qtbase/src/plugins/platforms/offscreen/qoffscreenintegration.h
++++ b/qtbase/src/plugins/platforms/offscreen/qoffscreenintegration.h
+@@ -84,6 +84,7 @@ protected:
+ #endif
+ QScopedPointer<QPlatformInputContext> m_inputContext;
+ QScopedPointer<QPlatformServices> m_services;
++ QPlatformScreen *m_screen;
+ mutable QScopedPointer<QPlatformNativeInterface> m_nativeInterface;
+ };
+
+diff --git a/qtbase/src/plugins/platforms/windows/qwindowsglcontext.cpp b/qtbase/src/plugins/platforms/windows/qwindowsglcontext.cpp
+index 6fa5a8a2b3..1f49f0aefd 100644
+--- a/qtbase/src/plugins/platforms/windows/qwindowsglcontext.cpp
++++ b/qtbase/src/plugins/platforms/windows/qwindowsglcontext.cpp
+@@ -48,6 +48,7 @@
+ #include <qpa/qplatformnativeinterface.h>
+ #include <QtPlatformHeaders/qwglnativecontext.h>
+
++#include <private/qsystemlibrary_p.h>
+ #include <algorithm>
+
+ #include <wingdi.h>
+@@ -162,19 +163,25 @@ QFunctionPointer QWindowsOpengl32DLL::resolve(const char *name)
+
+ bool QWindowsOpengl32DLL::init(bool softwareRendering)
+ {
+- const QByteArray opengl32 = QByteArrayLiteral("opengl32.dll");
+- const QByteArray swopengl = QByteArrayLiteral("opengl32sw.dll");
++ const QByteArray opengl32 = QByteArrayLiteral("opengl32");
++ const QByteArray swopengl = QByteArrayLiteral("opengl32sw");
++ bool useSystemLib = false;
+
+ QByteArray openglDll = qgetenv("QT_OPENGL_DLL");
+- if (openglDll.isEmpty())
++ if (openglDll.isEmpty()) {
+ openglDll = softwareRendering ? swopengl : opengl32;
++ useSystemLib = !softwareRendering;
++ }
+
+ openglDll = openglDll.toLower();
+ m_nonOpengl32 = openglDll != opengl32;
+
+ qCDebug(lcQpaGl) << "Qt: Using WGL and OpenGL from" << openglDll;
+
+- m_lib = ::LoadLibraryA(openglDll.constData());
++ if (useSystemLib)
++ m_lib = QSystemLibrary::load((wchar_t*)(QString::fromLatin1(openglDll).utf16()));
++ else
++ m_lib = LoadLibraryA(openglDll.constData());
+ if (!m_lib) {
+ qErrnoWarning(::GetLastError(), "Failed to load %s", openglDll.constData());
+ return false;
+@@ -184,7 +191,7 @@ bool QWindowsOpengl32DLL::init(bool softwareRendering)
+ // Load opengl32.dll always. GDI functions like ChoosePixelFormat do
+ // GetModuleHandle for opengl32.dll and behave differently (and call back into
+ // opengl32) when the module is present. This is fine for dummy contexts and windows.
+- ::LoadLibraryA("opengl32.dll");
++ QSystemLibrary::load(L"opengl32");
+ }
+
+ wglCreateContext = reinterpret_cast<HGLRC (WINAPI *)(HDC)>(resolve("wglCreateContext"));
+diff --git a/qtbase/src/plugins/platforms/windows/qwindowsopengltester.cpp b/qtbase/src/plugins/platforms/windows/qwindowsopengltester.cpp
+index d7d186e804..9eb4011bf2 100644
+--- a/qtbase/src/plugins/platforms/windows/qwindowsopengltester.cpp
++++ b/qtbase/src/plugins/platforms/windows/qwindowsopengltester.cpp
+@@ -49,6 +49,7 @@
+ #include <QtCore/qstandardpaths.h>
+ #include <QtCore/qlibraryinfo.h>
+ #include <QtCore/qhash.h>
++#include <private/qsystemlibrary_p.h>
+
+ #ifndef QT_NO_OPENGL
+ #include <private/qopengl_p.h>
+@@ -396,7 +397,7 @@ bool QWindowsOpenGLTester::testDesktopGL()
+
+ // Test #1: Load opengl32.dll and try to resolve an OpenGL 2 function.
+ // This will typically fail on systems that do not have a real OpenGL driver.
+- lib = LoadLibraryA("opengl32.dll");
++ lib = QSystemLibrary::load(L"opengl32");
+ if (lib) {
+ CreateContext = reinterpret_cast<CreateContextType>(
+ reinterpret_cast<QFunctionPointer>(::GetProcAddress(lib, "wglCreateContext")));
+diff --git a/qtbase/src/plugins/platforms/xcb/nativepainting/qtessellator.cpp b/qtbase/src/plugins/platforms/xcb/nativepainting/qtessellator.cpp
+index 1afa00cfc9..118af6ce73 100644
+--- a/qtbase/src/plugins/platforms/xcb/nativepainting/qtessellator.cpp
++++ b/qtbase/src/plugins/platforms/xcb/nativepainting/qtessellator.cpp
+@@ -41,6 +41,7 @@
+
+ #include <QRect>
+ #include <QList>
++#include <QMap>
+ #include <QDebug>
+
+ #include <qmath.h>
+diff --git a/qtbase/src/plugins/platforms/xcb/qxcbconnection.cpp b/qtbase/src/plugins/platforms/xcb/qxcbconnection.cpp
+index 9e2a37a6a1..e6e175a118 100644
+--- a/qtbase/src/plugins/platforms/xcb/qxcbconnection.cpp
++++ b/qtbase/src/plugins/platforms/xcb/qxcbconnection.cpp
+@@ -488,12 +488,12 @@ void QXcbConnection::printXcbError(const char *message, xcb_generic_error_t *err
+ uint clamped_error_code = qMin<uint>(error->error_code, (sizeof(xcb_errors) / sizeof(xcb_errors[0])) - 1);
+ uint clamped_major_code = qMin<uint>(error->major_code, (sizeof(xcb_protocol_request_codes) / sizeof(xcb_protocol_request_codes[0])) - 1);
+
+- qCWarning(lcQpaXcb, "%s: %d (%s), sequence: %d, resource id: %d, major code: %d (%s), minor code: %d",
+- message,
+- int(error->error_code), xcb_errors[clamped_error_code],
+- int(error->sequence), int(error->resource_id),
+- int(error->major_code), xcb_protocol_request_codes[clamped_major_code],
+- int(error->minor_code));
++ qCDebug(lcQpaXcb, "%s: %d (%s), sequence: %d, resource id: %d, major code: %d (%s), minor code: %d",
++ message,
++ int(error->error_code), xcb_errors[clamped_error_code],
++ int(error->sequence), int(error->resource_id),
++ int(error->major_code), xcb_protocol_request_codes[clamped_major_code],
++ int(error->minor_code));
+ }
+
+ static Qt::MouseButtons translateMouseButtons(int s)
+@@ -702,6 +702,8 @@ void QXcbConnection::handleXcbEvent(xcb_generic_event_t *event)
+ QXcbVirtualDesktop *virtualDesktop = virtualDesktopForRootWindow(propertyNotify->window);
+ if (virtualDesktop)
+ virtualDesktop->updateWorkArea();
++ } else if (propertyNotify->atom == atom(QXcbAtom::_NET_SUPPORTED)) {
++ m_wmSupport->updateNetWMAtoms();
+ } else {
+ HANDLE_PLATFORM_WINDOW_EVENT(xcb_property_notify_event_t, window, handlePropertyNotifyEvent);
+ }
+@@ -750,7 +752,7 @@ void QXcbConnection::handleXcbEvent(xcb_generic_event_t *event)
+ case XCB_XKB_NEW_KEYBOARD_NOTIFY: {
+ xcb_xkb_new_keyboard_notify_event_t *ev = &xkb_event->new_keyboard_notify;
+ if (ev->changed & XCB_XKB_NKN_DETAIL_KEYCODES)
+- m_keyboard->updateKeymap(ev);
++ m_keyboard->updateKeymap();
+ break;
+ }
+ default:
+diff --git a/qtbase/src/plugins/platforms/xcb/qxcbintegration.cpp b/qtbase/src/plugins/platforms/xcb/qxcbintegration.cpp
+index 76869ced60..02d2eebb56 100644
+--- a/qtbase/src/plugins/platforms/xcb/qxcbintegration.cpp
++++ b/qtbase/src/plugins/platforms/xcb/qxcbintegration.cpp
+@@ -274,8 +274,7 @@ QPlatformWindow *QXcbIntegration::createForeignWindow(QWindow *window, WId nativ
+ #ifndef QT_NO_OPENGL
+ QPlatformOpenGLContext *QXcbIntegration::createPlatformOpenGLContext(QOpenGLContext *context) const
+ {
+- QXcbScreen *screen = static_cast<QXcbScreen *>(context->screen()->handle());
+- QXcbGlIntegration *glIntegration = screen->connection()->glIntegration();
++ QXcbGlIntegration *glIntegration = defaultConnection()->glIntegration();
+ if (!glIntegration) {
+ qWarning("QXcbIntegration: Cannot create platform OpenGL context, neither GLX nor EGL are enabled");
+ return nullptr;
+diff --git a/qtbase/src/plugins/platforms/xcb/qxcbkeyboard.cpp b/qtbase/src/plugins/platforms/xcb/qxcbkeyboard.cpp
+index efecd7e2d1..e8286381a2 100644
+--- a/qtbase/src/plugins/platforms/xcb/qxcbkeyboard.cpp
++++ b/qtbase/src/plugins/platforms/xcb/qxcbkeyboard.cpp
+@@ -365,17 +365,6 @@ void QXcbKeyboard::updateKeymap(xcb_mapping_notify_event_t *event)
+ updateKeymap();
+ }
+
+-void QXcbKeyboard::updateKeymap(xcb_xkb_new_keyboard_notify_event_t *event)
+-{
+- if (!event)
+- return;
+-
+- if (event->deviceID != event->oldDeviceID)
+- m_config = false;
+-
+- updateKeymap();
+-}
+-
+ void QXcbKeyboard::updateKeymap()
+ {
+ KeysymModifierMap keysymMods;
+@@ -383,6 +372,8 @@ void QXcbKeyboard::updateKeymap()
+ keysymMods = keysymsToModifiers();
+ updateModifiers(keysymMods);
+
++ m_config = true;
++
+ if (!m_xkbContext) {
+ m_xkbContext.reset(xkb_context_new(XKB_CONTEXT_NO_DEFAULT_INCLUDES));
+ if (!m_xkbContext) {
+@@ -398,13 +389,8 @@ void QXcbKeyboard::updateKeymap()
+ if (connection()->hasXKB()) {
+ m_xkbKeymap.reset(xkb_x11_keymap_new_from_device(m_xkbContext.get(), xcb_connection(),
+ core_device_id, XKB_KEYMAP_COMPILE_NO_FLAGS));
+- if (m_xkbKeymap) {
+- if (m_config)
+- m_xkbState.reset(xkb_state_new(m_xkbKeymap.get()));
+- else
+- m_xkbState.reset(xkb_x11_state_new_from_device(m_xkbKeymap.get(), xcb_connection(), core_device_id));
+-
+- }
++ if (m_xkbKeymap)
++ m_xkbState.reset(xkb_x11_state_new_from_device(m_xkbKeymap.get(), xcb_connection(), core_device_id));
+ } else {
+ m_xkbKeymap.reset(keymapFromCore(keysymMods));
+ if (m_xkbKeymap)
+@@ -425,8 +411,6 @@ void QXcbKeyboard::updateKeymap()
+ updateXKBMods();
+
+ QXkbCommon::verifyHasLatinLayout(m_xkbKeymap.get());
+-
+- m_config = true;
+ }
+
+ QList<int> QXcbKeyboard::possibleKeys(const QKeyEvent *event) const
+diff --git a/qtbase/src/plugins/platforms/xcb/qxcbkeyboard.h b/qtbase/src/plugins/platforms/xcb/qxcbkeyboard.h
+index b652c85fe3..0ee08aeff2 100644
+--- a/qtbase/src/plugins/platforms/xcb/qxcbkeyboard.h
++++ b/qtbase/src/plugins/platforms/xcb/qxcbkeyboard.h
+@@ -69,7 +69,6 @@ public:
+
+ Qt::KeyboardModifiers translateModifiers(int s) const;
+ void updateKeymap(xcb_mapping_notify_event_t *event);
+- void updateKeymap(xcb_xkb_new_keyboard_notify_event_t *event);
+ void updateKeymap();
+ QList<int> possibleKeys(const QKeyEvent *event) const;
+
+diff --git a/qtbase/src/plugins/platforms/xcb/qxcbwindow.cpp b/qtbase/src/plugins/platforms/xcb/qxcbwindow.cpp
+index ffda7b6a57..863e961f4c 100644
+--- a/qtbase/src/plugins/platforms/xcb/qxcbwindow.cpp
++++ b/qtbase/src/plugins/platforms/xcb/qxcbwindow.cpp
+@@ -564,11 +564,6 @@ void QXcbWindow::setGeometry(const QRect &rect)
+ {
+ QPlatformWindow::setGeometry(rect);
+
+- if (shouldDeferTask(Task::SetGeometry)) {
+- m_deferredGeometry = rect;
+- return;
+- }
+-
+ propagateSizeHints();
+
+ QXcbScreen *currentScreen = xcbScreen();
+@@ -693,9 +688,6 @@ void QXcbWindow::setVisible(bool visible)
+
+ void QXcbWindow::show()
+ {
+- if (shouldDeferTask(Task::Map))
+- return;
+-
+ if (window()->isTopLevel()) {
+
+ // update WM_NORMAL_HINTS
+@@ -706,7 +698,7 @@ void QXcbWindow::show()
+ if (isTransient(window())) {
+ const QWindow *tp = window()->transientParent();
+ if (tp && tp->handle())
+- transientXcbParent = static_cast<const QXcbWindow *>(tp->handle())->winId();
++ transientXcbParent = tp->handle()->winId();
+ // Default to client leader if there is no transient parent, else modal dialogs can
+ // be hidden by their parents.
+ if (!transientXcbParent)
+@@ -746,10 +738,6 @@ void QXcbWindow::show()
+
+ void QXcbWindow::hide()
+ {
+- if (shouldDeferTask(Task::Unmap))
+- return;
+-
+- m_wmStateValid = false;
+ xcb_unmap_window(xcb_connection(), m_window);
+
+ // send synthetic UnmapNotify event according to icccm 4.1.4
+@@ -909,9 +897,6 @@ QXcbWindow::NetWmStates QXcbWindow::netWmStates()
+
+ void QXcbWindow::setWindowFlags(Qt::WindowFlags flags)
+ {
+- if (shouldDeferTask(Task::SetWindowFlags))
+- return;
+-
+ Qt::WindowType type = static_cast<Qt::WindowType>(int(flags & Qt::WindowType_Mask));
+
+ if (type == Qt::ToolTip)
+@@ -941,8 +926,6 @@ void QXcbWindow::setWindowFlags(Qt::WindowFlags flags)
+
+ setTransparentForMouseEvents(flags & Qt::WindowTransparentForInput);
+ updateDoesNotAcceptFocus(flags & Qt::WindowDoesNotAcceptFocus);
+-
+- m_isWmManagedWindow = !(flags & Qt::X11BypassWindowManagerHint);
+ }
+
+ void QXcbWindow::setMotifWmHints(Qt::WindowFlags flags)
+@@ -1142,9 +1125,6 @@ void QXcbWindow::setWindowState(Qt::WindowStates state)
+ if (state == m_windowState)
+ return;
+
+- if (shouldDeferTask(Task::SetWindowState))
+- return;
+-
+ // unset old state
+ if (m_windowState & Qt::WindowMinimized)
+ xcb_map_window(xcb_connection(), m_window);
+@@ -1350,6 +1330,12 @@ void QXcbWindow::setWindowIcon(const QIcon &icon)
+ }
+
+ if (!icon_data.isEmpty()) {
++ // Ignore icon exceeding maximum xcb request length
++ if (icon_data.size() > xcb_get_maximum_request_length(xcb_connection())) {
++ qWarning("Ignoring window icon: Size %llu exceeds maximum xcb request length %u.",
++ icon_data.size(), xcb_get_maximum_request_length(xcb_connection()));
++ return;
++ }
+ xcb_change_property(xcb_connection(),
+ XCB_PROP_MODE_REPLACE,
+ m_window,
+@@ -1639,7 +1625,7 @@ void QXcbWindow::setWmWindowType(QXcbWindowFunctions::WmWindowTypes types, Qt::W
+ break;
+ }
+
+- if ((flags & Qt::FramelessWindowHint) && !(type & QXcbWindowFunctions::KdeOverride)) {
++ if ((flags & Qt::FramelessWindowHint) && !(types & QXcbWindowFunctions::KdeOverride)) {
+ // override netwm type - quick and easy for KDE noborder
+ atoms.append(atom(QXcbAtom::_KDE_NET_WM_WINDOW_TYPE_OVERRIDE));
+ }
+@@ -1894,10 +1880,6 @@ void QXcbWindow::handleUnmapNotifyEvent(const xcb_unmap_notify_event_t *event)
+ if (event->window == m_window) {
+ m_mapped = false;
+ QWindowSystemInterface::handleExposeEvent(window(), QRegion());
+- if (!m_isWmManagedWindow || parent()) {
+- m_wmStateValid = true;
+- handleDeferredTasks();
+- }
+ }
+ }
+
+@@ -2212,98 +2194,30 @@ void QXcbWindow::handleLeaveNotifyEvent(const xcb_leave_notify_event_t *event)
+ handleLeaveNotifyEvent(event->root_x, event->root_y, event->mode, event->detail, event->time);
+ }
+
+-bool QXcbWindow::shouldDeferTask(Task task)
+-{
+- if (m_wmStateValid)
+- return false;
+-
+- m_deferredTasks.append(task);
+- return true;
+-}
+-
+-void QXcbWindow::handleDeferredTasks()
+-{
+- Q_ASSERT(m_wmStateValid == true);
+- if (m_deferredTasks.isEmpty())
+- return;
+-
+- bool map = false;
+- bool unmap = false;
+-
+- QVector<Task> tasks;
+- for (auto taskIt = m_deferredTasks.rbegin(); taskIt != m_deferredTasks.rend(); ++taskIt) {
+- if (!tasks.contains(*taskIt))
+- tasks.prepend(*taskIt);
+- }
+-
+- for (Task task : tasks) {
+- switch (task) {
+- case Task::Map:
+- map = true;
+- unmap = false;
+- break;
+- case Task::Unmap:
+- unmap = true;
+- map = false;
+- break;
+- case Task::SetGeometry:
+- setGeometry(m_deferredGeometry);
+- break;
+- case Task::SetWindowFlags:
+- setWindowFlags(window()->flags());
+- break;
+- case Task::SetWindowState:
+- setWindowState(window()->windowState());
+- break;
+- }
+- }
+- m_deferredTasks.clear();
+-
+- if (map) {
+- Q_ASSERT(unmap == false);
+- show();
+- }
+- if (unmap) {
+- Q_ASSERT(map == false);
+- hide();
+- }
+-}
+-
+ void QXcbWindow::handlePropertyNotifyEvent(const xcb_property_notify_event_t *event)
+ {
+ connection()->setTime(event->time);
+
+- const bool wmStateChanged = event->atom == atom(QXcbAtom::WM_STATE);
+- const bool netWmStateChanged = event->atom == atom(QXcbAtom::_NET_WM_STATE);
+- if (netWmStateChanged || wmStateChanged) {
+- if (wmStateChanged && !m_wmStateValid && m_isWmManagedWindow) {
+- // ICCCM 4.1.4
+- // Clients that want to re-use a client window (e.g. by mapping it again)
+- // after withdrawing it must wait for the withdrawal to be complete before
+- // proceeding. The preferred method for doing this is for clients to wait for
+- // a window manager to update or remove the WM_STATE property.
+- m_wmStateValid = true;
+- handleDeferredTasks();
+- }
+- if (event->state == XCB_PROPERTY_DELETE)
++ const bool propertyDeleted = event->state == XCB_PROPERTY_DELETE;
++
++ if (event->atom == atom(QXcbAtom::_NET_WM_STATE) || event->atom == atom(QXcbAtom::WM_STATE)) {
++ if (propertyDeleted)
+ return;
+
+- if (wmStateChanged) {
++ Qt::WindowStates newState = Qt::WindowNoState;
++
++ if (event->atom == atom(QXcbAtom::WM_STATE)) { // WM_STATE: Quick check for 'Minimize'.
+ auto reply = Q_XCB_REPLY(xcb_get_property, xcb_connection(),
+ 0, m_window, atom(QXcbAtom::WM_STATE),
+ XCB_ATOM_ANY, 0, 1024);
+ if (reply && reply->format == 32 && reply->type == atom(QXcbAtom::WM_STATE)) {
+- auto data = static_cast<const quint32 *>(xcb_get_property_value(reply.get()));
+- if (reply->length != 0) {
+- const bool changedToWithdrawn = data[0] == XCB_ICCCM_WM_STATE_WITHDRAWN;
+- const bool changedToIconic = data[0] == XCB_ICCCM_WM_STATE_ICONIC;
+- m_minimized = changedToIconic || (changedToWithdrawn && m_minimized);
+- }
++ const quint32 *data = (const quint32 *)xcb_get_property_value(reply.get());
++ if (reply->length != 0)
++ m_minimized = (data[0] == XCB_ICCCM_WM_STATE_ICONIC
++ || (data[0] == XCB_ICCCM_WM_STATE_WITHDRAWN && m_minimized));
+ }
+ }
+
+- // _NET_WM_STATE handling
+- Qt::WindowStates newState = Qt::WindowNoState;
+ const NetWmStates states = netWmStates();
+ // _NET_WM_STATE_HIDDEN should be set by the Window Manager to indicate that a window would
+ // not be visible on the screen if its desktop/viewport were active and its coordinates were
+@@ -2325,6 +2239,7 @@ void QXcbWindow::handlePropertyNotifyEvent(const xcb_property_notify_event_t *ev
+ if ((m_windowState & Qt::WindowMinimized) && connection()->mouseGrabber() == this)
+ connection()->setMouseGrabber(nullptr);
+ }
++ return;
+ } else if (event->atom == atom(QXcbAtom::_NET_FRAME_EXTENTS)) {
+ m_dirtyFrameMargins = true;
+ }
+diff --git a/qtbase/src/plugins/platforms/xcb/qxcbwindow.h b/qtbase/src/plugins/platforms/xcb/qxcbwindow.h
+index 55af9279b1..6f5c1f5ed9 100644
+--- a/qtbase/src/plugins/platforms/xcb/qxcbwindow.h
++++ b/qtbase/src/plugins/platforms/xcb/qxcbwindow.h
+@@ -74,14 +74,6 @@ public:
+
+ Q_DECLARE_FLAGS(NetWmStates, NetWmState)
+
+- enum Task {
+- Map,
+- Unmap,
+- SetGeometry,
+- SetWindowFlags,
+- SetWindowState
+- };
+-
+ QXcbWindow(QWindow *window);
+ ~QXcbWindow();
+
+@@ -151,9 +143,6 @@ public:
+
+ QXcbWindow *toWindow() override;
+
+- bool shouldDeferTask(Task task);
+- void handleDeferredTasks();
+-
+ void handleMouseEvent(xcb_timestamp_t time, const QPoint &local, const QPoint &global,
+ Qt::KeyboardModifiers modifiers, QEvent::Type type, Qt::MouseEventSource source);
+
+@@ -292,11 +281,6 @@ protected:
+ int m_swapInterval = -1;
+
+ qreal m_sizeHintsScaleFactor = 1.0;
+-
+- bool m_wmStateValid = true;
+- QVector<Task> m_deferredTasks;
+- bool m_isWmManagedWindow = true;
+- QRect m_deferredGeometry;
+ };
+
+ class QXcbForeignWindow : public QXcbWindow
+diff --git a/qtbase/src/plugins/platformthemes/gtk3/qgtk3menu.cpp b/qtbase/src/plugins/platformthemes/gtk3/qgtk3menu.cpp
+index d9d117faeb..640b49daa0 100644
+--- a/qtbase/src/plugins/platformthemes/gtk3/qgtk3menu.cpp
++++ b/qtbase/src/plugins/platformthemes/gtk3/qgtk3menu.cpp
+@@ -85,6 +85,7 @@ QGtk3MenuItem::QGtk3MenuItem()
+ m_checkable(false),
+ m_checked(false),
+ m_enabled(true),
++ m_exclusive(false),
+ m_underline(false),
+ m_invalid(true),
+ m_menu(nullptr),
+diff --git a/qtbase/src/plugins/platformthemes/xdgdesktopportal/qxdgdesktopportalfiledialog.cpp b/qtbase/src/plugins/platformthemes/xdgdesktopportal/qxdgdesktopportalfiledialog.cpp
+index 0048bbc1e6..396e7f6d1c 100644
+--- a/qtbase/src/plugins/platformthemes/xdgdesktopportal/qxdgdesktopportalfiledialog.cpp
++++ b/qtbase/src/plugins/platformthemes/xdgdesktopportal/qxdgdesktopportalfiledialog.cpp
+@@ -102,15 +102,12 @@ const QDBusArgument &operator >>(const QDBusArgument &arg, QXdgDesktopPortalFile
+ class QXdgDesktopPortalFileDialogPrivate
+ {
+ public:
+- QXdgDesktopPortalFileDialogPrivate(QPlatformFileDialogHelper *nativeFileDialog)
++ QXdgDesktopPortalFileDialogPrivate(QPlatformFileDialogHelper *nativeFileDialog, uint fileChooserPortalVersion)
+ : nativeFileDialog(nativeFileDialog)
++ , fileChooserPortalVersion(fileChooserPortalVersion)
+ { }
+
+- WId winId = 0;
+- bool directoryMode = false;
+- bool modal = false;
+- bool multipleFiles = false;
+- bool saveFile = false;
++ QEventLoop loop;
+ QString acceptLabel;
+ QString directory;
+ QString title;
+@@ -121,19 +118,27 @@ public:
+ QString selectedMimeTypeFilter;
+ QString selectedNameFilter;
+ QStringList selectedFiles;
+- QPlatformFileDialogHelper *nativeFileDialog = nullptr;
++ std::unique_ptr<QPlatformFileDialogHelper> nativeFileDialog;
++ uint fileChooserPortalVersion = 0;
++ bool failedToOpen = false;
++ bool directoryMode = false;
++ bool multipleFiles = false;
++ bool saveFile = false;
+ };
+
+-QXdgDesktopPortalFileDialog::QXdgDesktopPortalFileDialog(QPlatformFileDialogHelper *nativeFileDialog)
++QXdgDesktopPortalFileDialog::QXdgDesktopPortalFileDialog(QPlatformFileDialogHelper *nativeFileDialog, uint fileChooserPortalVersion)
+ : QPlatformFileDialogHelper()
+- , d_ptr(new QXdgDesktopPortalFileDialogPrivate(nativeFileDialog))
++ , d_ptr(new QXdgDesktopPortalFileDialogPrivate(nativeFileDialog, fileChooserPortalVersion))
+ {
+ Q_D(QXdgDesktopPortalFileDialog);
+
+ if (d->nativeFileDialog) {
+- connect(d->nativeFileDialog, SIGNAL(accept()), this, SIGNAL(accept()));
+- connect(d->nativeFileDialog, SIGNAL(reject()), this, SIGNAL(reject()));
++ connect(d->nativeFileDialog.get(), SIGNAL(accept()), this, SIGNAL(accept()));
++ connect(d->nativeFileDialog.get(), SIGNAL(reject()), this, SIGNAL(reject()));
+ }
++
++ d->loop.connect(this, SIGNAL(accept()), SLOT(quit()));
++ d->loop.connect(this, SIGNAL(reject()), SLOT(quit()));
+ }
+
+ QXdgDesktopPortalFileDialog::~QXdgDesktopPortalFileDialog()
+@@ -177,7 +182,7 @@ void QXdgDesktopPortalFileDialog::initializeDialog()
+ setDirectory(options()->initialDirectory());
+ }
+
+-void QXdgDesktopPortalFileDialog::openPortal()
++void QXdgDesktopPortalFileDialog::openPortal(Qt::WindowFlags windowFlags, Qt::WindowModality windowModality, QWindow *parent)
+ {
+ Q_D(QXdgDesktopPortalFileDialog);
+
+@@ -185,13 +190,13 @@ void QXdgDesktopPortalFileDialog::openPortal()
+ QLatin1String("/org/freedesktop/portal/desktop"),
+ QLatin1String("org.freedesktop.portal.FileChooser"),
+ d->saveFile ? QLatin1String("SaveFile") : QLatin1String("OpenFile"));
+- QString parentWindowId = QLatin1String("x11:") + QString::number(d->winId, 16);
++ QString parentWindowId = QLatin1String("x11:") + QString::number(parent ? parent->winId() : 0, 16);
+
+ QVariantMap options;
+ if (!d->acceptLabel.isEmpty())
+ options.insert(QLatin1String("accept_label"), d->acceptLabel);
+
+- options.insert(QLatin1String("modal"), d->modal);
++ options.insert(QLatin1String("modal"), windowModality != Qt::NonModal);
+ options.insert(QLatin1String("multiple"), d->multipleFiles);
+ options.insert(QLatin1String("directory"), d->directoryMode);
+
+@@ -290,10 +295,18 @@ void QXdgDesktopPortalFileDialog::openPortal()
+
+ QDBusPendingCall pendingCall = QDBusConnection::sessionBus().asyncCall(message);
+ QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(pendingCall);
+- connect(watcher, &QDBusPendingCallWatcher::finished, this, [this] (QDBusPendingCallWatcher *watcher) {
++ connect(watcher, &QDBusPendingCallWatcher::finished, this, [=] (QDBusPendingCallWatcher *watcher) {
+ QDBusPendingReply<QDBusObjectPath> reply = *watcher;
+- if (reply.isError()) {
+- Q_EMIT reject();
++ // Any error means the dialog is not shown and we need to fallback
++ d->failedToOpen = reply.isError();
++ if (d->failedToOpen) {
++ if (d->nativeFileDialog) {
++ d->nativeFileDialog->show(windowFlags, windowModality, parent);
++ if (d->loop.isRunning())
++ d->nativeFileDialog->exec();
++ } else {
++ Q_EMIT reject();
++ }
+ } else {
+ QDBusConnection::sessionBus().connect(nullptr,
+ reply.value().path(),
+@@ -302,6 +315,7 @@ void QXdgDesktopPortalFileDialog::openPortal()
+ this,
+ SLOT(gotResponse(uint,QVariantMap)));
+ }
++ watcher->deleteLater();
+ });
+ }
+
+@@ -326,7 +340,7 @@ QUrl QXdgDesktopPortalFileDialog::directory() const
+ {
+ Q_D(const QXdgDesktopPortalFileDialog);
+
+- if (d->nativeFileDialog && (options()->fileMode() == QFileDialogOptions::Directory || options()->fileMode() == QFileDialogOptions::DirectoryOnly))
++ if (d->nativeFileDialog && useNativeFileDialog())
+ return d->nativeFileDialog->directory();
+
+ return d->directory;
+@@ -348,7 +362,7 @@ QList<QUrl> QXdgDesktopPortalFileDialog::selectedFiles() const
+ {
+ Q_D(const QXdgDesktopPortalFileDialog);
+
+- if (d->nativeFileDialog && (options()->fileMode() == QFileDialogOptions::Directory || options()->fileMode() == QFileDialogOptions::DirectoryOnly))
++ if (d->nativeFileDialog && useNativeFileDialog())
+ return d->nativeFileDialog->selectedFiles();
+
+ QList<QUrl> files;
+@@ -403,16 +417,13 @@ void QXdgDesktopPortalFileDialog::exec()
+ {
+ Q_D(QXdgDesktopPortalFileDialog);
+
+- if (d->nativeFileDialog && (options()->fileMode() == QFileDialogOptions::Directory || options()->fileMode() == QFileDialogOptions::DirectoryOnly)) {
++ if (d->nativeFileDialog && useNativeFileDialog()) {
+ d->nativeFileDialog->exec();
+ return;
+ }
+
+ // HACK we have to avoid returning until we emit that the dialog was accepted or rejected
+- QEventLoop loop;
+- loop.connect(this, SIGNAL(accept()), SLOT(quit()));
+- loop.connect(this, SIGNAL(reject()), SLOT(quit()));
+- loop.exec();
++ d->loop.exec();
+ }
+
+ void QXdgDesktopPortalFileDialog::hide()
+@@ -429,13 +440,10 @@ bool QXdgDesktopPortalFileDialog::show(Qt::WindowFlags windowFlags, Qt::WindowMo
+
+ initializeDialog();
+
+- d->modal = windowModality != Qt::NonModal;
+- d->winId = parent ? parent->winId() : 0;
+-
+- if (d->nativeFileDialog && (options()->fileMode() == QFileDialogOptions::Directory || options()->fileMode() == QFileDialogOptions::DirectoryOnly))
++ if (d->nativeFileDialog && useNativeFileDialog(OpenFallback))
+ return d->nativeFileDialog->show(windowFlags, windowModality, parent);
+
+- openPortal();
++ openPortal(windowFlags, windowModality, parent);
+
+ return true;
+ }
+@@ -465,4 +473,21 @@ void QXdgDesktopPortalFileDialog::gotResponse(uint response, const QVariantMap &
+ }
+ }
+
++bool QXdgDesktopPortalFileDialog::useNativeFileDialog(QXdgDesktopPortalFileDialog::FallbackType fallbackType) const
++{
++ Q_D(const QXdgDesktopPortalFileDialog);
++
++ if (d->failedToOpen && fallbackType != OpenFallback)
++ return true;
++
++ if (d->fileChooserPortalVersion < 3) {
++ if (options()->fileMode() == QFileDialogOptions::Directory)
++ return true;
++ else if (options()->fileMode() == QFileDialogOptions::DirectoryOnly)
++ return true;
++ }
++
++ return false;
++}
++
+ QT_END_NAMESPACE
+diff --git a/qtbase/src/plugins/platformthemes/xdgdesktopportal/qxdgdesktopportalfiledialog_p.h b/qtbase/src/plugins/platformthemes/xdgdesktopportal/qxdgdesktopportalfiledialog_p.h
+index 4f4de96ecf..65e22a5cf2 100644
+--- a/qtbase/src/plugins/platformthemes/xdgdesktopportal/qxdgdesktopportalfiledialog_p.h
++++ b/qtbase/src/plugins/platformthemes/xdgdesktopportal/qxdgdesktopportalfiledialog_p.h
+@@ -51,6 +51,11 @@ class QXdgDesktopPortalFileDialog : public QPlatformFileDialogHelper
+ Q_OBJECT
+ Q_DECLARE_PRIVATE(QXdgDesktopPortalFileDialog)
+ public:
++ enum FallbackType {
++ GenericFallback,
++ OpenFallback
++ };
++
+ enum ConditionType : uint {
+ GlobalPattern = 0,
+ MimeType = 1
+@@ -69,7 +74,7 @@ public:
+ };
+ typedef QVector<Filter> FilterList;
+
+- QXdgDesktopPortalFileDialog(QPlatformFileDialogHelper *nativeFileDialog = nullptr);
++ QXdgDesktopPortalFileDialog(QPlatformFileDialogHelper *nativeFileDialog = nullptr, uint fileChooserPortalVersion = 0);
+ ~QXdgDesktopPortalFileDialog();
+
+ bool defaultNameFilterDisables() const override;
+@@ -92,7 +97,8 @@ private Q_SLOTS:
+
+ private:
+ void initializeDialog();
+- void openPortal();
++ void openPortal(Qt::WindowFlags windowFlags, Qt::WindowModality windowModality, QWindow *parent);
++ bool useNativeFileDialog(FallbackType fallbackType = GenericFallback) const;
+
+ QScopedPointer<QXdgDesktopPortalFileDialogPrivate> d_ptr;
+ };
+diff --git a/qtbase/src/plugins/platformthemes/xdgdesktopportal/qxdgdesktopportaltheme.cpp b/qtbase/src/plugins/platformthemes/xdgdesktopportal/qxdgdesktopportaltheme.cpp
+index fb324afbd8..b809503122 100644
+--- a/qtbase/src/plugins/platformthemes/xdgdesktopportal/qxdgdesktopportaltheme.cpp
++++ b/qtbase/src/plugins/platformthemes/xdgdesktopportal/qxdgdesktopportaltheme.cpp
+@@ -111,6 +111,7 @@ QXdgDesktopPortalTheme::QXdgDesktopPortalTheme()
+ if (reply.isValid()) {
+ d->fileChooserPortalVersion = reply.value().toUInt();
+ }
++ watcher->deleteLater();
+ });
+ }
+
+@@ -152,11 +153,12 @@ QPlatformDialogHelper* QXdgDesktopPortalTheme::createPlatformDialogHelper(Dialog
+ {
+ Q_D(const QXdgDesktopPortalTheme);
+
+- if (type == FileDialog) {
++ if (type == FileDialog && d->fileChooserPortalVersion) {
+ // Older versions of FileChooser portal don't support opening directories, therefore we fallback
+ // to native file dialog opened inside the sandbox to open a directory.
+- if (d->fileChooserPortalVersion < 3 && d->baseTheme->usePlatformNativeDialog(type))
+- return new QXdgDesktopPortalFileDialog(static_cast<QPlatformFileDialogHelper*>(d->baseTheme->createPlatformDialogHelper(type)));
++ if (d->baseTheme->usePlatformNativeDialog(type))
++ return new QXdgDesktopPortalFileDialog(static_cast<QPlatformFileDialogHelper*>(d->baseTheme->createPlatformDialogHelper(type)),
++ d->fileChooserPortalVersion);
+
+ return new QXdgDesktopPortalFileDialog;
+ }
+diff --git a/qtbase/src/plugins/printsupport/cups/qcupsprintengine.cpp b/qtbase/src/plugins/printsupport/cups/qcupsprintengine.cpp
+index 43d5e119ad..1f9cbc4565 100644
+--- a/qtbase/src/plugins/printsupport/cups/qcupsprintengine.cpp
++++ b/qtbase/src/plugins/printsupport/cups/qcupsprintengine.cpp
+@@ -89,8 +89,10 @@ void QCupsPrintEngine::setProperty(PrintEnginePropertyKey key, const QVariant &v
+ break;
+ case PPK_Duplex: {
+ QPrint::DuplexMode mode = QPrint::DuplexMode(value.toInt());
+- if (mode != d->duplex && d->m_printDevice.supportedDuplexModes().contains(mode))
++ if (d->m_printDevice.supportedDuplexModes().contains(mode)) {
+ d->duplex = mode;
++ d->duplexRequestedExplicitly = true;
++ }
+ break;
+ }
+ case PPK_PrinterName:
+@@ -277,9 +279,12 @@ void QCupsPrintEnginePrivate::changePrinter(const QString &newPrinter)
+ m_printDevice.swap(printDevice);
+ printerName = m_printDevice.id();
+
+- // Check if new printer supports current settings, otherwise us defaults
+- if (duplex != QPrint::DuplexAuto && !m_printDevice.supportedDuplexModes().contains(duplex))
++ // in case a duplex value was explicitly set, check if new printer supports current value,
++ // otherwise use device default
++ if (!duplexRequestedExplicitly || !m_printDevice.supportedDuplexModes().contains(duplex)) {
+ duplex = m_printDevice.defaultDuplexMode();
++ duplexRequestedExplicitly = false;
++ }
+ QPrint::ColorMode colorMode = grayscale ? QPrint::GrayScale : QPrint::Color;
+ if (!m_printDevice.supportedColorModes().contains(colorMode))
+ grayscale = m_printDevice.defaultColorMode() == QPrint::GrayScale;
+diff --git a/qtbase/src/plugins/printsupport/cups/qcupsprintengine_p.h b/qtbase/src/plugins/printsupport/cups/qcupsprintengine_p.h
+index c021b0c643..8f81fe478d 100644
+--- a/qtbase/src/plugins/printsupport/cups/qcupsprintengine_p.h
++++ b/qtbase/src/plugins/printsupport/cups/qcupsprintengine_p.h
+@@ -100,6 +100,7 @@ private:
+ QStringList cupsOptions;
+ QString cupsTempFile;
+ QPrint::DuplexMode duplex;
++ bool duplexRequestedExplicitly = false;
+ };
+
+ QT_END_NAMESPACE
+diff --git a/qtbase/src/plugins/sqldrivers/ibase/qsql_ibase.cpp b/qtbase/src/plugins/sqldrivers/ibase/qsql_ibase.cpp
+index 67e7154fa6..40876152e5 100644
+--- a/qtbase/src/plugins/sqldrivers/ibase/qsql_ibase.cpp
++++ b/qtbase/src/plugins/sqldrivers/ibase/qsql_ibase.cpp
+@@ -817,7 +817,7 @@ bool QIBaseResultPrivate::writeArray(int column, const QList<QVariant> &list)
+ ba.resize(int(bufLen));
+
+ if (list.size() > arraySize) {
+- error = QLatin1String("Array size missmatch: size of %1 is %2, size of provided list is %3");
++ error = QLatin1String("Array size mismatch: size of %1 is %2, size of provided list is %3");
+ error = error.arg(QLatin1String(sqlname)).arg(arraySize).arg(list.size());
+ q->setLastError(QSqlError(error, QLatin1String(""), QSqlError::StatementError));
+ return false;
+diff --git a/qtbase/src/plugins/sqldrivers/mysql/qsql_mysql.cpp b/qtbase/src/plugins/sqldrivers/mysql/qsql_mysql.cpp
+index 7ca055eea2..6bc9d46755 100644
+--- a/qtbase/src/plugins/sqldrivers/mysql/qsql_mysql.cpp
++++ b/qtbase/src/plugins/sqldrivers/mysql/qsql_mysql.cpp
+@@ -223,7 +223,7 @@ public:
+ struct QMyField
+ {
+ char *outField = nullptr;
+- MYSQL_FIELD *myField = nullptr;
++ const MYSQL_FIELD *myField = nullptr;
+ QMetaType::Type type = QMetaType::UnknownType;
+ my_bool nullIndicator = false;
+ ulong bufLength = 0ul;
+@@ -361,7 +361,7 @@ static bool qIsInteger(int t)
+ void QMYSQLResultPrivate::bindBlobs()
+ {
+ int i;
+- MYSQL_FIELD *fieldInfo;
++ const MYSQL_FIELD *fieldInfo;
+ MYSQL_BIND *bind;
+
+ for(i = 0; i < fields.count(); ++i) {
+@@ -379,7 +379,6 @@ void QMYSQLResultPrivate::bindBlobs()
+ bool QMYSQLResultPrivate::bindInValues()
+ {
+ MYSQL_BIND *bind;
+- char *field;
+ int i = 0;
+
+ if (!meta)
+@@ -392,35 +391,34 @@ bool QMYSQLResultPrivate::bindInValues()
+ inBinds = new MYSQL_BIND[fields.size()];
+ memset(inBinds, 0, fields.size() * sizeof(MYSQL_BIND));
+
+- MYSQL_FIELD *fieldInfo;
++ const MYSQL_FIELD *fieldInfo;
+
+ while((fieldInfo = mysql_fetch_field(meta))) {
++ bind = &inBinds[i];
++
+ QMyField &f = fields[i];
+ f.myField = fieldInfo;
+-
++ bind->buffer_length = f.bufLength = fieldInfo->length + 1;
++ bind->buffer_type = fieldInfo->type;
+ f.type = qDecodeMYSQLType(fieldInfo->type, fieldInfo->flags);
+ if (qIsBlob(fieldInfo->type)) {
+ // the size of a blob-field is available as soon as we call
+ // mysql_stmt_store_result()
+ // after mysql_stmt_exec() in QMYSQLResult::exec()
+- fieldInfo->length = 0;
++ bind->buffer_length = f.bufLength = 0;
+ hasBlobs = true;
+ } else if (qIsInteger(f.type)) {
+- fieldInfo->length = 8;
++ bind->buffer_length = f.bufLength = 8;
+ } else {
+- fieldInfo->type = MYSQL_TYPE_STRING;
++ bind->buffer_type = MYSQL_TYPE_STRING;
+ }
+- bind = &inBinds[i];
+- field = new char[fieldInfo->length + 1];
+- memset(field, 0, fieldInfo->length + 1);
+
+- bind->buffer_type = fieldInfo->type;
+- bind->buffer = field;
+- bind->buffer_length = f.bufLength = fieldInfo->length + 1;
+ bind->is_null = &f.nullIndicator;
+ bind->length = &f.bufLength;
+ bind->is_unsigned = fieldInfo->flags & UNSIGNED_FLAG ? 1 : 0;
+- f.outField=field;
++
++ char *field = new char[bind->buffer_length + 1]{};
++ bind->buffer = f.outField = field;
+
+ ++i;
+ }
+@@ -1369,20 +1367,20 @@ bool QMYSQLDriver::open(const QString& db,
+ }
+
+ #if MYSQL_VERSION_ID >= 50007
+- if (mysql_get_client_version() >= 50503 && mysql_get_server_version(d->mysql) >= 50503) {
+- // force the communication to be utf8mb4 (only utf8mb4 supports 4-byte characters)
+- mysql_set_character_set(d->mysql, "utf8mb4");
++ // force the communication to be utf8mb4 (only utf8mb4 supports 4-byte characters)
++ if (mysql_set_character_set(d->mysql, "utf8mb4")) {
++ // this failed, try forcing it to utf (BMP only)
++ if (mysql_set_character_set(d->mysql, "utf8"))
++ qWarning() << "MySQL: Unable to set the client character set to utf8.";
+ #if QT_CONFIG(textcodec)
+- d->tc = QTextCodec::codecForName("UTF-8");
++ else
++ d->tc = codec(d->mysql);
+ #endif
+- } else
+- {
+- // force the communication to be utf8
+- mysql_set_character_set(d->mysql, "utf8");
++ }
+ #if QT_CONFIG(textcodec)
+- d->tc = codec(d->mysql);
++ else
++ d->tc = QTextCodec::codecForName("UTF-8");
+ #endif
+- }
+ #endif // MYSQL_VERSION_ID >= 50007
+
+ d->preparedQuerysEnabled = checkPreparedQueries(d->mysql);
+diff --git a/qtbase/src/printsupport/dialogs/images/print-24.png b/qtbase/src/printsupport/dialogs/images/printer-24.png
+similarity index 100%
+rename from src/printsupport/dialogs/images/print-24.png
+rename to src/printsupport/dialogs/images/printer-24.png
+diff --git a/qtbase/src/printsupport/dialogs/images/print-32.png b/qtbase/src/printsupport/dialogs/images/printer-32.png
+similarity index 100%
+rename from src/printsupport/dialogs/images/print-32.png
+rename to src/printsupport/dialogs/images/printer-32.png
+diff --git a/qtbase/src/printsupport/dialogs/images/view-page-sided-24.png b/qtbase/src/printsupport/dialogs/images/view-pages-facing-24.png
+similarity index 100%
+rename from src/printsupport/dialogs/images/view-page-sided-24.png
+rename to src/printsupport/dialogs/images/view-pages-facing-24.png
+diff --git a/qtbase/src/printsupport/dialogs/images/view-page-sided-32.png b/qtbase/src/printsupport/dialogs/images/view-pages-facing-32.png
+similarity index 100%
+rename from src/printsupport/dialogs/images/view-page-sided-32.png
+rename to src/printsupport/dialogs/images/view-pages-facing-32.png
+diff --git a/qtbase/src/printsupport/dialogs/images/view-page-multi-24.png b/qtbase/src/printsupport/dialogs/images/view-pages-overview-24.png
+similarity index 100%
+rename from src/printsupport/dialogs/images/view-page-multi-24.png
+rename to src/printsupport/dialogs/images/view-pages-overview-24.png
+diff --git a/qtbase/src/printsupport/dialogs/images/view-page-multi-32.png b/qtbase/src/printsupport/dialogs/images/view-pages-overview-32.png
+similarity index 100%
+rename from src/printsupport/dialogs/images/view-page-multi-32.png
+rename to src/printsupport/dialogs/images/view-pages-overview-32.png
+diff --git a/qtbase/src/printsupport/dialogs/images/view-page-one-24.png b/qtbase/src/printsupport/dialogs/images/view-pages-single-24.png
+similarity index 100%
+rename from src/printsupport/dialogs/images/view-page-one-24.png
+rename to src/printsupport/dialogs/images/view-pages-single-24.png
+diff --git a/qtbase/src/printsupport/dialogs/images/view-page-one-32.png b/qtbase/src/printsupport/dialogs/images/view-pages-single-32.png
+similarity index 100%
+rename from src/printsupport/dialogs/images/view-page-one-32.png
+rename to src/printsupport/dialogs/images/view-pages-single-32.png
+diff --git a/qtbase/src/printsupport/dialogs/images/fit-page-24.png b/qtbase/src/printsupport/dialogs/images/zoom-fit-page-24.png
+similarity index 100%
+rename from src/printsupport/dialogs/images/fit-page-24.png
+rename to src/printsupport/dialogs/images/zoom-fit-page-24.png
+diff --git a/qtbase/src/printsupport/dialogs/images/fit-page-32.png b/qtbase/src/printsupport/dialogs/images/zoom-fit-page-32.png
+similarity index 100%
+rename from src/printsupport/dialogs/images/fit-page-32.png
+rename to src/printsupport/dialogs/images/zoom-fit-page-32.png
+diff --git a/qtbase/src/printsupport/dialogs/images/fit-width-24.png b/qtbase/src/printsupport/dialogs/images/zoom-fit-width-24.png
+similarity index 100%
+rename from src/printsupport/dialogs/images/fit-width-24.png
+rename to src/printsupport/dialogs/images/zoom-fit-width-24.png
+diff --git a/qtbase/src/printsupport/dialogs/images/fit-width-32.png b/qtbase/src/printsupport/dialogs/images/zoom-fit-width-32.png
+similarity index 100%
+rename from src/printsupport/dialogs/images/fit-width-32.png
+rename to src/printsupport/dialogs/images/zoom-fit-width-32.png
+diff --git a/qtbase/src/printsupport/dialogs/qpagesetupdialog_unix.cpp b/qtbase/src/printsupport/dialogs/qpagesetupdialog_unix.cpp
+index 78e5b8d1ef..2a28516719 100644
+--- a/qtbase/src/printsupport/dialogs/qpagesetupdialog_unix.cpp
++++ b/qtbase/src/printsupport/dialogs/qpagesetupdialog_unix.cpp
+@@ -532,6 +532,7 @@ void QPageSetupWidget::updateWidget()
+ void QPageSetupWidget::setupPrinter() const
+ {
+ m_printer->setPageLayout(m_pageLayout);
++ m_printer->setPageOrientation(m_pageLayout.orientation());
+ #if QT_CONFIG(cups)
+ QCUPSSupport::PagesPerSheet pagesPerSheet = qvariant_cast<QCUPSSupport::PagesPerSheet>(m_ui.pagesPerSheetCombo->currentData()
+ );
+diff --git a/qtbase/src/printsupport/dialogs/qprintdialog.qrc b/qtbase/src/printsupport/dialogs/qprintdialog.qrc
+index 5a579baa55..10b8e1d341 100644
+--- a/qtbase/src/printsupport/dialogs/qprintdialog.qrc
++++ b/qtbase/src/printsupport/dialogs/qprintdialog.qrc
+@@ -1,9 +1,9 @@
+ <!DOCTYPE RCC><RCC version="1.0">
+ <qresource prefix="/qt-project.org/dialogs/qprintpreviewdialog">
+-<file>images/fit-page-24.png</file>
+-<file>images/fit-page-32.png</file>
+-<file>images/fit-width-24.png</file>
+-<file>images/fit-width-32.png</file>
++<file>images/zoom-fit-page-24.png</file>
++<file>images/zoom-fit-page-32.png</file>
++<file>images/zoom-fit-width-24.png</file>
++<file>images/zoom-fit-width-32.png</file>
+ <file>images/go-first-24.png</file>
+ <file>images/go-first-32.png</file>
+ <file>images/go-last-24.png</file>
+@@ -18,14 +18,14 @@
+ <file>images/layout-portrait-32.png</file>
+ <file>images/page-setup-24.png</file>
+ <file>images/page-setup-32.png</file>
+-<file>images/print-24.png</file>
+-<file>images/print-32.png</file>
+-<file>images/view-page-multi-24.png</file>
+-<file>images/view-page-multi-32.png</file>
+-<file>images/view-page-one-24.png</file>
+-<file>images/view-page-one-32.png</file>
+-<file>images/view-page-sided-24.png</file>
+-<file>images/view-page-sided-32.png</file>
++<file>images/printer-24.png</file>
++<file>images/printer-32.png</file>
++<file>images/view-pages-overview-24.png</file>
++<file>images/view-pages-overview-32.png</file>
++<file>images/view-pages-single-24.png</file>
++<file>images/view-pages-single-32.png</file>
++<file>images/view-pages-facing-24.png</file>
++<file>images/view-pages-facing-32.png</file>
+ <file>images/zoom-in-24.png</file>
+ <file>images/zoom-in-32.png</file>
+ <file>images/zoom-out-24.png</file>
+diff --git a/qtbase/src/printsupport/dialogs/qprintdialog_unix.cpp b/qtbase/src/printsupport/dialogs/qprintdialog_unix.cpp
+index c5b845f4ec..5a5ba1d0a8 100644
+--- a/qtbase/src/printsupport/dialogs/qprintdialog_unix.cpp
++++ b/qtbase/src/printsupport/dialogs/qprintdialog_unix.cpp
+@@ -702,13 +702,14 @@ void QPrintDialogPrivate::selectPrinter(const QPrinter::OutputFormat outputForma
+ else
+ options.grayscale->setChecked(true);
+
+- // keep duplex value explicitly set by user, if any, and selected printer supports it;
+- // use device default otherwise
++ // duplex priorities to be as follows:
++ // 1) a user-selected duplex value in the dialog has highest prority
++ // 2) duplex value set in the QPrinter
+ QPrint::DuplexMode duplex;
+ if (explicitDuplexMode != QPrint::DuplexAuto && supportedDuplexMode.contains(explicitDuplexMode))
+ duplex = explicitDuplexMode;
+ else
+- duplex = top->d->m_currentPrintDevice.defaultDuplexMode();
++ duplex = static_cast<QPrint::DuplexMode>(p->duplex());
+ switch (duplex) {
+ case QPrint::DuplexNone:
+ options.noDuplex->setChecked(true); break;
+@@ -1242,10 +1243,10 @@ void QUnixPrintWidgetPrivate::_q_printerChanged(int index)
+ QString filename = widget.filename->text();
+ widget.filename->setText(filename);
+ widget.lOutput->setEnabled(true);
+- if (optionsPane)
+- optionsPane->selectPrinter(QPrinter::PdfFormat);
+ printer->setOutputFormat(QPrinter::PdfFormat);
+ m_currentPrintDevice = QPrintDevice();
++ if (optionsPane)
++ optionsPane->selectPrinter(QPrinter::PdfFormat);
+ return;
+ }
+ }
+diff --git a/qtbase/src/printsupport/dialogs/qprintpreviewdialog.cpp b/qtbase/src/printsupport/dialogs/qprintpreviewdialog.cpp
+index 39575d5f57..23b7e89538 100644
+--- a/qtbase/src/printsupport/dialogs/qprintpreviewdialog.cpp
++++ b/qtbase/src/printsupport/dialogs/qprintpreviewdialog.cpp
+@@ -352,7 +352,7 @@ void QPrintPreviewDialogPrivate::init(QPrinter *_printer)
+ static inline void qt_setupActionIcon(QAction *action, QLatin1String name)
+ {
+ QLatin1String imagePrefix(":/qt-project.org/dialogs/qprintpreviewdialog/images/");
+- QIcon icon;
++ QIcon icon = QIcon::fromTheme(name);
+ icon.addFile(imagePrefix + name + QLatin1String("-24.png"), QSize(24, 24));
+ icon.addFile(imagePrefix + name + QLatin1String("-32.png"), QSize(32, 32));
+ action->setIcon(icon);
+@@ -383,8 +383,8 @@ void QPrintPreviewDialogPrivate::setupActions()
+ fitPageAction->setObjectName(QLatin1String("fitPageAction"));
+ fitWidthAction->setCheckable(true);
+ fitPageAction->setCheckable(true);
+- qt_setupActionIcon(fitWidthAction, QLatin1String("fit-width"));
+- qt_setupActionIcon(fitPageAction, QLatin1String("fit-page"));
++ qt_setupActionIcon(fitWidthAction, QLatin1String("zoom-fit-width"));
++ qt_setupActionIcon(fitPageAction, QLatin1String("zoom-fit-page"));
+ QObject::connect(fitGroup, SIGNAL(triggered(QAction*)), q, SLOT(_q_fit(QAction*)));
+
+ // Zoom
+@@ -410,9 +410,9 @@ void QPrintPreviewDialogPrivate::setupActions()
+ singleModeAction = modeGroup->addAction(QCoreApplication::translate("QPrintPreviewDialog", "Show single page"));
+ facingModeAction = modeGroup->addAction(QCoreApplication::translate("QPrintPreviewDialog", "Show facing pages"));
+ overviewModeAction = modeGroup->addAction(QCoreApplication::translate("QPrintPreviewDialog", "Show overview of all pages"));
+- qt_setupActionIcon(singleModeAction, QLatin1String("view-page-one"));
+- qt_setupActionIcon(facingModeAction, QLatin1String("view-page-sided"));
+- qt_setupActionIcon(overviewModeAction, QLatin1String("view-page-multi"));
++ qt_setupActionIcon(singleModeAction, QLatin1String("view-pages-single"));
++ qt_setupActionIcon(facingModeAction, QLatin1String("view-pages-facing"));
++ qt_setupActionIcon(overviewModeAction, QLatin1String("view-pages-overview"));
+ singleModeAction->setObjectName(QLatin1String("singleModeAction"));
+ facingModeAction->setObjectName(QLatin1String("facingModeAction"));
+ overviewModeAction->setObjectName(QLatin1String("overviewModeAction"));
+@@ -426,7 +426,7 @@ void QPrintPreviewDialogPrivate::setupActions()
+ printerGroup = new QActionGroup(q);
+ printAction = printerGroup->addAction(QCoreApplication::translate("QPrintPreviewDialog", "Print"));
+ pageSetupAction = printerGroup->addAction(QCoreApplication::translate("QPrintPreviewDialog", "Page setup"));
+- qt_setupActionIcon(printAction, QLatin1String("print"));
++ qt_setupActionIcon(printAction, QLatin1String("printer"));
+ qt_setupActionIcon(pageSetupAction, QLatin1String("page-setup"));
+ QObject::connect(printAction, SIGNAL(triggered(bool)), q, SLOT(_q_print()));
+ QObject::connect(pageSetupAction, SIGNAL(triggered(bool)), q, SLOT(_q_pageSetup()));
+diff --git a/qtbase/src/sql/kernel/qsqlquery.cpp b/qtbase/src/sql/kernel/qsqlquery.cpp
+index 32c6166c79..60afef10c3 100644
+--- a/qtbase/src/sql/kernel/qsqlquery.cpp
++++ b/qtbase/src/sql/kernel/qsqlquery.cpp
+@@ -1,6 +1,6 @@
+ /****************************************************************************
+ **
+-** Copyright (C) 2016 The Qt Company Ltd.
++** Copyright (C) 2022 The Qt Company Ltd.
+ ** Contact: https://www.qt.io/licensing/
+ **
+ ** This file is part of the QtSql module of the Qt Toolkit.
+@@ -377,6 +377,10 @@ bool QSqlQuery::exec(const QString& query)
+ QElapsedTimer t;
+ t.start();
+ #endif
++ if (!driver()) {
++ qWarning("QSqlQuery::exec: called before driver has been set up");
++ return false;
++ }
+ if (d->ref.loadRelaxed() != 1) {
+ bool fo = isForwardOnly();
+ *this = QSqlQuery(driver()->createResult());
+diff --git a/qtbase/src/testlib/qabstractitemmodeltester.cpp b/qtbase/src/testlib/qabstractitemmodeltester.cpp
+index 8efb9c53d4..ce062f66d7 100644
+--- a/qtbase/src/testlib/qabstractitemmodeltester.cpp
++++ b/qtbase/src/testlib/qabstractitemmodeltester.cpp
+@@ -454,7 +454,7 @@ void QAbstractItemModelTesterPrivate::parent()
+
+ // Common error test #2, make sure that a second level index has a parent
+ // that is the first level index.
+- if (model->rowCount(topIndex) > 0) {
++ if (model->rowCount(topIndex) > 0 && model->columnCount(topIndex) > 0) {
+ QModelIndex childIndex = model->index(0, 0, topIndex);
+ MODELTESTER_VERIFY(childIndex.isValid());
+ MODELTESTER_COMPARE(model->parent(childIndex), topIndex);
+diff --git a/qtbase/src/testlib/qasciikey.cpp b/qtbase/src/testlib/qasciikey.cpp
+index 9a308da2bc..93498b256f 100644
+--- a/qtbase/src/testlib/qasciikey.cpp
++++ b/qtbase/src/testlib/qasciikey.cpp
+@@ -498,6 +498,11 @@ char QTest::keyToAscii(Qt::Key key)
+ case Qt::Key_LaunchE : return 0; // = 0x10b0,
+ case Qt::Key_LaunchF : return 0; // = 0x10b1,
+
++ // Keypad navigation keys
++ case Qt::Key_Select : return 0; // = 0x01010000
++ case Qt::Key_Yes : return 0; // = 0x01010001
++ case Qt::Key_No : return 0; // = 0x01010002
++
+ default: QTEST_ASSERT(false); return 0;
+ }
+ }
+diff --git a/qtbase/src/testlib/qtestresult.cpp b/qtbase/src/testlib/qtestresult.cpp
+index 88028aac6e..2e89930776 100644
+--- a/qtbase/src/testlib/qtestresult.cpp
++++ b/qtbase/src/testlib/qtestresult.cpp
+@@ -251,7 +251,8 @@ bool QTestResult::verify(bool statement, const char *statementStr,
+ {
+ QTEST_ASSERT(statementStr);
+
+- char msg[1024] = {'\0'};
++ char msg[1024];
++ msg[0] = '\0';
+
+ if (QTestLog::verboseLevel() >= 2) {
+ qsnprintf(msg, 1024, "QVERIFY(%s)", statementStr);
+@@ -309,7 +310,8 @@ static bool compareHelper(bool success, const char *failureMsg,
+ bool hasValues = true)
+ {
+ const size_t maxMsgLen = 1024;
+- char msg[maxMsgLen] = {'\0'};
++ char msg[maxMsgLen];
++ msg[0] = '\0';
+
+ QTEST_ASSERT(expected);
+ QTEST_ASSERT(actual);
+diff --git a/qtbase/src/widgets/dialogs/qcolordialog.cpp b/qtbase/src/widgets/dialogs/qcolordialog.cpp
+index 4247731275..cb325be85c 100644
+--- a/qtbase/src/widgets/dialogs/qcolordialog.cpp
++++ b/qtbase/src/widgets/dialogs/qcolordialog.cpp
+@@ -78,7 +78,10 @@
+ #include "qwindow.h"
+
+ #include "private/qdialog_p.h"
++#include "private/qguiapplication_p.h"
+
++#include <qpa/qplatformservices.h>
++#include <qpa/qplatformintegration.h>
+ #include <algorithm>
+
+ QT_BEGIN_NAMESPACE
+@@ -1611,6 +1614,20 @@ void QColorDialogPrivate::_q_newStandard(int r, int c)
+ void QColorDialogPrivate::_q_pickScreenColor()
+ {
+ Q_Q(QColorDialog);
++
++ auto *platformServices = QGuiApplicationPrivate::platformIntegration()->services();
++ if (platformServices->hasCapability(QPlatformServices::Capability::ColorPicking)) {
++ if (auto *colorPicker = platformServices->colorPicker(q->windowHandle())) {
++ q->connect(colorPicker, &QPlatformServiceColorPicker::colorPicked, q,
++ [q, colorPicker](const QColor &color) {
++ colorPicker->deleteLater();
++ q->setCurrentColor(color);
++ });
++ colorPicker->pickColor();
++ return;
++ }
++ }
++
+ if (!colorPickingEventFilter)
+ colorPickingEventFilter = new QColorPickingEventFilter(this, q);
+ q->installEventFilter(colorPickingEventFilter);
+diff --git a/qtbase/src/widgets/itemviews/qabstractitemdelegate.cpp b/qtbase/src/widgets/itemviews/qabstractitemdelegate.cpp
+index e120817edc..8ea36b5427 100644
+--- a/qtbase/src/widgets/itemviews/qabstractitemdelegate.cpp
++++ b/qtbase/src/widgets/itemviews/qabstractitemdelegate.cpp
+@@ -400,12 +400,7 @@ bool QAbstractItemDelegate::helpEvent(QHelpEvent *event,
+ const QString tooltip = index.isValid() ?
+ d->textForRole(Qt::ToolTipRole, index.data(Qt::ToolTipRole), option.locale, precision) :
+ QString();
+- QRect rect;
+- if (index.isValid()) {
+- const QRect r = view->visualRect(index);
+- rect = QRect(view->mapToGlobal(r.topLeft()), r.size());
+- }
+- QToolTip::showText(he->globalPos(), tooltip, view, rect);
++ QToolTip::showText(he->globalPos(), tooltip, view->viewport(), option.rect);
+ event->setAccepted(!tooltip.isEmpty());
+ break;
+ }
+diff --git a/qtbase/src/widgets/itemviews/qlistview.cpp b/qtbase/src/widgets/itemviews/qlistview.cpp
+index 2b34476642..eebfaa030e 100644
+--- a/qtbase/src/widgets/itemviews/qlistview.cpp
++++ b/qtbase/src/widgets/itemviews/qlistview.cpp
+@@ -3386,6 +3386,7 @@ void QIconModeViewBase::updateContentsSize()
+ */
+ void QListView::currentChanged(const QModelIndex ¤t, const QModelIndex &previous)
+ {
++ QAbstractItemView::currentChanged(current, previous);
+ #ifndef QT_NO_ACCESSIBILITY
+ if (QAccessible::isActive()) {
+ if (current.isValid()) {
+@@ -3396,7 +3397,6 @@ void QListView::currentChanged(const QModelIndex ¤t, const QModelIndex &pr
+ }
+ }
+ #endif
+- QAbstractItemView::currentChanged(current, previous);
+ }
+
+ /*!
+diff --git a/qtbase/src/widgets/itemviews/qtableview.cpp b/qtbase/src/widgets/itemviews/qtableview.cpp
+index 934ac581b2..f79bb24249 100644
+--- a/qtbase/src/widgets/itemviews/qtableview.cpp
++++ b/qtbase/src/widgets/itemviews/qtableview.cpp
+@@ -1013,6 +1013,7 @@ void QTableViewPrivate::drawCell(QPainter *painter, const QStyleOptionViewItem &
+ int QTableViewPrivate::widthHintForIndex(const QModelIndex &index, int hint, const QStyleOptionViewItem &option) const
+ {
+ Q_Q(const QTableView);
++ const int oldHint = hint;
+ QWidget *editor = editorForIndex(index).widget.data();
+ if (editor && persistent.contains(editor)) {
+ hint = qMax(hint, editor->sizeHint().width());
+@@ -1021,6 +1022,17 @@ int QTableViewPrivate::widthHintForIndex(const QModelIndex &index, int hint, con
+ hint = qBound(min, hint, max);
+ }
+ hint = qMax(hint, q->itemDelegate(index)->sizeHint(option, index).width());
++
++ if (hasSpans()) {
++ auto span = spans.spanAt(index.column(), index.row());
++ if (span && span->m_left == index.column() && span->m_top == index.row()) {
++ // spans are screwed up when sections are moved
++ const auto left = logicalColumn(span->m_left);
++ for (int i = 1; i <= span->width(); ++i)
++ hint -= q->columnWidth(visualColumn(left + i));
++ }
++ hint = std::max(hint, oldHint);
++ }
+ return hint;
+ }
+
+@@ -1053,6 +1065,11 @@ int QTableViewPrivate::heightHintForIndex(const QModelIndex &index, int hint, QS
+ option.rect.setHeight(height);
+ option.rect.setX(q->columnViewportPosition(index.column()));
+ option.rect.setWidth(q->columnWidth(index.column()));
++ if (hasSpans()) {
++ auto span = spans.spanAt(index.column(), index.row());
++ if (span && span->m_left == index.column() && span->m_top == index.row())
++ option.rect.setWidth(std::max(option.rect.width(), visualSpanRect(*span).width()));
++ }
+ // 1px less space when grid is shown (see drawCell)
+ if (showGrid)
+ option.rect.setWidth(option.rect.width() - 1);
+diff --git a/qtbase/src/widgets/kernel/qaction.h b/qtbase/src/widgets/kernel/qaction.h
+index 258a1ea0a0..737c1e8285 100644
+--- a/qtbase/src/widgets/kernel/qaction.h
++++ b/qtbase/src/widgets/kernel/qaction.h
+@@ -81,7 +81,7 @@ class Q_WIDGETS_EXPORT QAction : public QObject
+ Q_PROPERTY(MenuRole menuRole READ menuRole WRITE setMenuRole NOTIFY changed)
+ Q_PROPERTY(bool iconVisibleInMenu READ isIconVisibleInMenu WRITE setIconVisibleInMenu NOTIFY changed)
+ Q_PROPERTY(bool shortcutVisibleInContextMenu READ isShortcutVisibleInContextMenu WRITE setShortcutVisibleInContextMenu NOTIFY changed)
+- Q_PROPERTY(Priority priority READ priority WRITE setPriority)
++ Q_PROPERTY(Priority priority READ priority WRITE setPriority NOTIFY changed)
+
+ public:
+ // note this is copied into qplatformmenu.h, which must stay in sync
+diff --git a/qtbase/src/widgets/kernel/qwidget.cpp b/qtbase/src/widgets/kernel/qwidget.cpp
+index 9eba1e001e..26f6d27e18 100644
+--- a/qtbase/src/widgets/kernel/qwidget.cpp
++++ b/qtbase/src/widgets/kernel/qwidget.cpp
+@@ -5296,7 +5296,7 @@ void QWidgetPrivate::drawWidget(QPaintDevice *pdev, const QRegion &rgn, const QP
+ QWidgetEffectSourcePrivate *sourced = static_cast<QWidgetEffectSourcePrivate *>
+ (source->d_func());
+ if (!sourced->context) {
+- const QRegion effectRgn(rgn.boundingRect());
++ const QRegion effectRgn((flags & UseEffectRegionBounds) ? rgn.boundingRect() : rgn);
+ QWidgetPaintContext context(pdev, effectRgn, offset, flags, sharedPainter, repaintManager);
+ sourced->context = &context;
+ if (!sharedPainter) {
+@@ -5328,6 +5328,7 @@ void QWidgetPrivate::drawWidget(QPaintDevice *pdev, const QRegion &rgn, const QP
+ }
+ }
+ #endif // QT_CONFIG(graphicseffect)
++ flags = flags & ~UseEffectRegionBounds;
+
+ const bool alsoOnScreen = flags & DrawPaintOnScreen;
+ const bool recursive = flags & DrawRecursive;
+diff --git a/qtbase/src/widgets/kernel/qwidget_p.h b/qtbase/src/widgets/kernel/qwidget_p.h
+index eef6b8fa2c..c432f4b5d5 100644
+--- a/qtbase/src/widgets/kernel/qwidget_p.h
++++ b/qtbase/src/widgets/kernel/qwidget_p.h
+@@ -229,7 +229,8 @@ public:
+ DontSubtractOpaqueChildren = 0x10,
+ DontDrawOpaqueChildren = 0x20,
+ DontDrawNativeChildren = 0x40,
+- DontSetCompositionMode = 0x80
++ DontSetCompositionMode = 0x80,
++ UseEffectRegionBounds = 0x100
+ };
+ Q_DECLARE_FLAGS(DrawWidgetFlags, DrawWidgetFlag)
+ Q_FLAG(DrawWidgetFlags)
+diff --git a/qtbase/src/widgets/kernel/qwidgetrepaintmanager.cpp b/qtbase/src/widgets/kernel/qwidgetrepaintmanager.cpp
+index 02880b34da..0d44e1326d 100644
+--- a/qtbase/src/widgets/kernel/qwidgetrepaintmanager.cpp
++++ b/qtbase/src/widgets/kernel/qwidgetrepaintmanager.cpp
+@@ -1018,7 +1018,8 @@ void QWidgetRepaintManager::paintAndFlush()
+
+ // Paint the rest with composition.
+ if (repaintAllWidgets || !dirtyCopy.isEmpty()) {
+- QWidgetPrivate::DrawWidgetFlags flags = QWidgetPrivate::DrawAsRoot | QWidgetPrivate::DrawRecursive;
++ QWidgetPrivate::DrawWidgetFlags flags = QWidgetPrivate::DrawAsRoot | QWidgetPrivate::DrawRecursive
++ | QWidgetPrivate::UseEffectRegionBounds;
+ tlw->d_func()->drawWidget(store->paintDevice(), dirtyCopy, QPoint(), flags, nullptr, this);
+ }
+
+diff --git a/qtbase/src/widgets/styles/qfusionstyle.cpp b/qtbase/src/widgets/styles/qfusionstyle.cpp
+index f4345d97c4..962912c838 100644
+--- a/qtbase/src/widgets/styles/qfusionstyle.cpp
++++ b/qtbase/src/widgets/styles/qfusionstyle.cpp
+@@ -1772,14 +1772,6 @@ void QFusionStyle::drawControl(ControlElement element, const QStyleOption *optio
+ proxy()->drawControl(CE_PushButtonLabel, &subopt, painter, widget);
+ }
+ break;
+- case CE_PushButtonLabel:
+- if (const QStyleOptionButton *button = qstyleoption_cast<const QStyleOptionButton *>(option)) {
+- QStyleOptionButton b(*button);
+- // no PM_ButtonShiftHorizontal and PM_ButtonShiftVertical for fusion style
+- b.state &= ~(State_On | State_Sunken);
+- QCommonStyle::drawControl(element, &b, painter, widget);
+- }
+- break;
+ case CE_MenuBarEmptyArea:
+ painter->save();
+ {
+diff --git a/qtbase/src/widgets/util/qcompleter.cpp b/qtbase/src/widgets/util/qcompleter.cpp
+index 18b24063d8..ef7207a8a3 100644
+--- a/qtbase/src/widgets/util/qcompleter.cpp
++++ b/qtbase/src/widgets/util/qcompleter.cpp
+@@ -1120,6 +1120,8 @@ void QCompleter::setModel(QAbstractItemModel *model)
+ {
+ Q_D(QCompleter);
+ QAbstractItemModel *oldModel = d->proxy->sourceModel();
++ if (oldModel == model)
++ return;
+ #if QT_CONFIG(filesystemmodel)
+ if (qobject_cast<const QFileSystemModel *>(oldModel))
+ setCompletionRole(Qt::EditRole); // QTBUG-54642, clear FileNameRole set by QFileSystemModel
+diff --git a/qtbase/src/widgets/widgets/qabstractbutton.cpp b/qtbase/src/widgets/widgets/qabstractbutton.cpp
+index a128b23950..dc40bf62fb 100644
+--- a/qtbase/src/widgets/widgets/qabstractbutton.cpp
++++ b/qtbase/src/widgets/widgets/qabstractbutton.cpp
+@@ -56,6 +56,7 @@
+ #ifndef QT_NO_ACCESSIBILITY
+ #include "qaccessible.h"
+ #endif
++#include <qpa/qplatformtheme.h>
+
+ #include <algorithm>
+
+@@ -1076,19 +1077,19 @@ void QAbstractButton::keyPressEvent(QKeyEvent *e)
+ {
+ Q_D(QAbstractButton);
+ bool next = true;
+- switch (e->key()) {
+- case Qt::Key_Enter:
+- case Qt::Key_Return:
+- e->ignore();
+- break;
+- case Qt::Key_Select:
+- case Qt::Key_Space:
+- if (!e->isAutoRepeat()) {
+- setDown(true);
+- repaint();
+- d->emitPressed();
+- }
+- break;
++
++ const auto key = static_cast<Qt::Key>(e->key());
++ const auto buttonPressKeys = QGuiApplicationPrivate::platformTheme()
++ ->themeHint(QPlatformTheme::ButtonPressKeys)
++ .value<QList<Qt::Key>>();
++ if (buttonPressKeys.contains(key) && !e->isAutoRepeat()) {
++ setDown(true);
++ repaint();
++ d->emitPressed();
++ return;
++ }
++
++ switch (key) {
+ case Qt::Key_Up:
+ next = false;
+ Q_FALLTHROUGH();
+@@ -1153,15 +1154,15 @@ void QAbstractButton::keyReleaseEvent(QKeyEvent *e)
+ if (!e->isAutoRepeat())
+ d->repeatTimer.stop();
+
+- switch (e->key()) {
+- case Qt::Key_Select:
+- case Qt::Key_Space:
+- if (!e->isAutoRepeat() && d->down)
+- d->click();
+- break;
+- default:
+- e->ignore();
++ const auto buttonPressKeys = QGuiApplicationPrivate::platformTheme()
++ ->themeHint(QPlatformTheme::ButtonPressKeys)
++ .value<QList<Qt::Key>>();
++ if (buttonPressKeys.contains(static_cast<Qt::Key>(e->key())) && !e->isAutoRepeat() && d->down) {
++ d->click();
++ return;
+ }
++
++ e->ignore();
+ }
+
+ /*!\reimp
+diff --git a/qtbase/src/widgets/widgets/qcombobox.cpp b/qtbase/src/widgets/widgets/qcombobox.cpp
+index 7a496c27e0..0a3d96647b 100644
+--- a/qtbase/src/widgets/widgets/qcombobox.cpp
++++ b/qtbase/src/widgets/widgets/qcombobox.cpp
+@@ -3352,7 +3352,23 @@ void QComboBox::keyPressEvent(QKeyEvent *e)
+
+ Move move = NoMove;
+ int newIndex = currentIndex();
+- switch (e->key()) {
++
++ bool pressLikeButton = !d->lineEdit;
++#ifdef QT_KEYPAD_NAVIGATION
++ pressLikeButton |= QApplicationPrivate::keypadNavigationEnabled() && !hasEditFocus();
++#endif
++ auto key = static_cast<Qt::Key>(e->key());
++ if (pressLikeButton) {
++ const auto buttonPressKeys = QGuiApplicationPrivate::platformTheme()
++ ->themeHint(QPlatformTheme::ButtonPressKeys)
++ .value<QList<Qt::Key>>();
++ if (buttonPressKeys.contains(key)) {
++ showPopup();
++ return;
++ }
++ }
++
++ switch (key) {
+ case Qt::Key_Up:
+ if (e->modifiers() & Qt::ControlModifier)
+ break; // pass to line edit for auto completion
+@@ -3394,26 +3410,11 @@ void QComboBox::keyPressEvent(QKeyEvent *e)
+ return;
+ }
+ break;
+- case Qt::Key_Space:
+- if (!d->lineEdit) {
+- showPopup();
+- return;
+- }
+- break;
+- case Qt::Key_Enter:
+- case Qt::Key_Return:
+ case Qt::Key_Escape:
+ if (!d->lineEdit)
+ e->ignore();
+ break;
+ #ifdef QT_KEYPAD_NAVIGATION
+- case Qt::Key_Select:
+- if (QApplicationPrivate::keypadNavigationEnabled()
+- && (!hasEditFocus() || !d->lineEdit)) {
+- showPopup();
+- return;
+- }
+- break;
+ case Qt::Key_Left:
+ case Qt::Key_Right:
+ if (QApplicationPrivate::keypadNavigationEnabled() && !hasEditFocus())
+diff --git a/qtbase/src/widgets/widgets/qdatetimeedit_p.h b/qtbase/src/widgets/widgets/qdatetimeedit_p.h
+index d36b6f8f9a..e0df5b5158 100644
+--- a/qtbase/src/widgets/widgets/qdatetimeedit_p.h
++++ b/qtbase/src/widgets/widgets/qdatetimeedit_p.h
+@@ -1,6 +1,6 @@
+ /****************************************************************************
+ **
+-** Copyright (C) 2018 The Qt Company Ltd.
++** Copyright (C) 2021 The Qt Company Ltd.
+ ** Contact: https://www.qt.io/licensing/
+ **
+ ** This file is part of the QtWidgets module of the Qt Toolkit.
+diff --git a/qtbase/src/widgets/widgets/qgroupbox.cpp b/qtbase/src/widgets/widgets/qgroupbox.cpp
+index 02a0bed325..3f3eccc370 100644
+--- a/qtbase/src/widgets/widgets/qgroupbox.cpp
++++ b/qtbase/src/widgets/widgets/qgroupbox.cpp
+@@ -54,6 +54,8 @@
+ #include "qaccessible.h"
+ #endif
+ #include <private/qwidget_p.h>
++#include <private/qguiapplication_p.h>
++#include <qpa/qplatformtheme.h>
+
+ #include "qdebug.h"
+
+@@ -360,7 +362,10 @@ bool QGroupBox::event(QEvent *e)
+ return true;
+ case QEvent::KeyPress: {
+ QKeyEvent *k = static_cast<QKeyEvent*>(e);
+- if (!k->isAutoRepeat() && (k->key() == Qt::Key_Select || k->key() == Qt::Key_Space)) {
++ const auto buttonPressKeys = QGuiApplicationPrivate::platformTheme()
++ ->themeHint(QPlatformTheme::ButtonPressKeys)
++ .value<QList<Qt::Key>>();
++ if (!k->isAutoRepeat() && buttonPressKeys.contains(static_cast<Qt::Key>(k->key()))) {
+ d->pressedControl = QStyle::SC_GroupBoxCheckBox;
+ update(style()->subControlRect(QStyle::CC_GroupBox, &box, QStyle::SC_GroupBoxCheckBox, this));
+ return true;
+@@ -369,7 +374,10 @@ bool QGroupBox::event(QEvent *e)
+ }
+ case QEvent::KeyRelease: {
+ QKeyEvent *k = static_cast<QKeyEvent*>(e);
+- if (!k->isAutoRepeat() && (k->key() == Qt::Key_Select || k->key() == Qt::Key_Space)) {
++ const auto buttonPressKeys = QGuiApplicationPrivate::platformTheme()
++ ->themeHint(QPlatformTheme::ButtonPressKeys)
++ .value<QList<Qt::Key>>();
++ if (!k->isAutoRepeat() && buttonPressKeys.contains(static_cast<Qt::Key>(k->key()))) {
+ bool toggle = (d->pressedControl == QStyle::SC_GroupBoxLabel
+ || d->pressedControl == QStyle::SC_GroupBoxCheckBox);
+ d->pressedControl = QStyle::SC_None;
+diff --git a/qtbase/src/widgets/widgets/qlabel.cpp b/qtbase/src/widgets/widgets/qlabel.cpp
+index 30ff80cbb0..cf2605c17c 100644
+--- a/qtbase/src/widgets/widgets/qlabel.cpp
++++ b/qtbase/src/widgets/widgets/qlabel.cpp
+@@ -421,9 +421,6 @@ void QLabel::setPixmap(const QPixmap &pixmap)
+ d->pixmap = new QPixmap(pixmap);
+ }
+
+- if (d->pixmap->depth() == 1 && !d->pixmap->mask())
+- d->pixmap->setMask(*((QBitmap *)d->pixmap));
+-
+ d->updateLabel();
+ }
+
+diff --git a/qtbase/src/widgets/widgets/qtoolbararealayout.cpp b/qtbase/src/widgets/widgets/qtoolbararealayout.cpp
+index 493c094cc1..d5f4b59017 100644
+--- a/qtbase/src/widgets/widgets/qtoolbararealayout.cpp
++++ b/qtbase/src/widgets/widgets/qtoolbararealayout.cpp
+@@ -1367,7 +1367,7 @@ bool QToolBarAreaLayout::restoreState(QDataStream &stream, const QList<QToolBar*
+ item.widgetItem = new QWidgetItemV2(toolBar);
+ toolBar->setOrientation(floating ? ((shown & 2) ? Qt::Vertical : Qt::Horizontal) : dock.o);
+ toolBar->setVisible(shown & 1);
+- toolBar->d_func()->setWindowState(floating, true, rect);
++ toolBar->d_func()->setWindowState(floating, false, rect);
+
+ item.preferredSize = item.size;
+ line.toolBarItems.append(item);
+diff --git a/qtbase/tests/auto/concurrent/qtconcurrentiteratekernel/tst_qtconcurrentiteratekernel.cpp b/qtbase/tests/auto/concurrent/qtconcurrentiteratekernel/tst_qtconcurrentiteratekernel.cpp
+index 212c0a2e13..3c77b1ba0b 100644
+--- a/qtbase/tests/auto/concurrent/qtconcurrentiteratekernel/tst_qtconcurrentiteratekernel.cpp
++++ b/qtbase/tests/auto/concurrent/qtconcurrentiteratekernel/tst_qtconcurrentiteratekernel.cpp
+@@ -126,8 +126,7 @@ public:
+
+ void tst_QtConcurrentIterateKernel::instantiate()
+ {
+- auto future = startThreadEngine(new PrintFor(0, 40)).startAsynchronously();
+- future.waitForFinished();
++ startThreadEngine(new PrintFor(0, 40)).startBlocking();
+ QCOMPARE(iterations.loadRelaxed(), 40);
+ }
+
+@@ -166,10 +165,8 @@ void tst_QtConcurrentIterateKernel::stresstest()
+ const int times = 50;
+ for (int i = 0; i < times; ++i) {
+ counter.storeRelaxed(0);
+- // ThreadEngine will delete f when it finishes
+- auto f = new CountFor(0, iterations);
+- auto future = f->startAsynchronously();
+- future.waitForFinished();
++ CountFor f(0, iterations);
++ f.startBlocking();
+ QCOMPARE(counter.loadRelaxed(), iterations);
+ }
+ }
+@@ -177,11 +174,8 @@ void tst_QtConcurrentIterateKernel::stresstest()
+ void tst_QtConcurrentIterateKernel::noIterations()
+ {
+ const int times = 20000;
+- for (int i = 0; i < times; ++i) {
+- auto future = startThreadEngine(new IterateKernel<TestIterator, void>(0, 0))
+- .startAsynchronously();
+- future.waitForFinished();
+- }
++ for (int i = 0; i < times; ++i)
++ startThreadEngine(new IterateKernel<TestIterator, void>(0, 0)).startBlocking();
+ }
+
+ QMutex threadsMutex;
+@@ -236,10 +230,8 @@ void tst_QtConcurrentIterateKernel::throttling()
+
+ threads.clear();
+
+- // ThreadEngine will delete f when it finishes
+- auto f = new ThrottleFor(0, totalIterations);
+- auto future = f->startAsynchronously();
+- future.waitForFinished();
++ ThrottleFor f(0, totalIterations);
++ f.startBlocking();
+
+ QCOMPARE(iterations.loadRelaxed(), totalIterations);
+
+diff --git a/qtbase/tests/auto/concurrent/qtconcurrentthreadengine/tst_qtconcurrentthreadengine.cpp b/qtbase/tests/auto/concurrent/qtconcurrentthreadengine/tst_qtconcurrentthreadengine.cpp
+index ac7be7acdd..81bc64c8d9 100644
+--- a/qtbase/tests/auto/concurrent/qtconcurrentthreadengine/tst_qtconcurrentthreadengine.cpp
++++ b/qtbase/tests/auto/concurrent/qtconcurrentthreadengine/tst_qtconcurrentthreadengine.cpp
+@@ -65,9 +65,16 @@ public:
+
+ void tst_QtConcurrentThreadEngine::runDirectly()
+ {
+- PrintUser *engine = new PrintUser();
+- QFuture<void> f = engine->startAsynchronously();
+- f.waitForFinished();
++ {
++ PrintUser engine;
++ engine.startSingleThreaded();
++ engine.startBlocking();
++ }
++ {
++ PrintUser *engine = new PrintUser();
++ QFuture<void> f = engine->startAsynchronously();
++ f.waitForFinished();
++ }
+ }
+
+ class StringResultUser : public ThreadEngine<QString>
+@@ -99,10 +106,8 @@ public:
+
+ void tst_QtConcurrentThreadEngine::result()
+ {
+- // ThreadEngine will delete 'engine' when it finishes
+- auto engine = new StringResultUser();
+- auto future = engine->startAsynchronously();
+- QCOMPARE(future.result(), QString("Foo"));
++ StringResultUser engine;
++ QCOMPARE(*engine.startBlocking(), QString("Foo"));
+ }
+
+ class VoidResultUser : public ThreadEngine<void>
+@@ -128,9 +133,17 @@ public:
+
+ void tst_QtConcurrentThreadEngine::runThroughStarter()
+ {
+- ThreadEngineStarter<QString> starter = startThreadEngine(new StringResultUser());
+- QFuture<QString> f = starter.startAsynchronously();
+- QCOMPARE(f.result(), QString("Foo"));
++ {
++ ThreadEngineStarter<QString> starter = startThreadEngine(new StringResultUser());
++ QFuture<QString> f = starter.startAsynchronously();
++ QCOMPARE(f.result(), QString("Foo"));
++ }
++
++ {
++ ThreadEngineStarter<QString> starter = startThreadEngine(new StringResultUser());
++ QString str = starter.startBlocking();
++ QCOMPARE(str, QString("Foo"));
++ }
+ }
+
+ class CancelUser : public ThreadEngine<void>
+@@ -213,6 +226,12 @@ void tst_QtConcurrentThreadEngine::throttle()
+ f.waitForFinished();
+ QCOMPARE(count.loadRelaxed(), 0);
+ }
++
++ for (int i = 0; i < repeats; ++i) {
++ ThrottleAlwaysUser t;
++ t.startBlocking();
++ QCOMPARE(count.loadRelaxed(), 0);
++ }
+ }
+
+ QSet<QThread *> threads;
+@@ -249,17 +268,35 @@ void tst_QtConcurrentThreadEngine::threadCount()
+ {
+ const int repeats = 10;
+ for (int i = 0; i < repeats; ++i) {
++ ThreadCountUser t;
++ t.startBlocking();
++ int count = threads.count();
++ int count_expected = QThreadPool::globalInstance()->maxThreadCount() + 1; // +1 for the main thread.
++ if (count != count_expected)
++ QEXPECT_FAIL("", "QTBUG-23333", Abort);
++ QCOMPARE(count, count_expected);
++
+ (new ThreadCountUser())->startAsynchronously().waitForFinished();
+- const auto count = threads.count();
+- const auto maxThreadCount = QThreadPool::globalInstance()->maxThreadCount();
+- QVERIFY(count <= maxThreadCount);
+- QVERIFY(!threads.contains(QThread::currentThread()));
++ count = threads.count();
++ count_expected = QThreadPool::globalInstance()->maxThreadCount();
++ if (count != count_expected)
++ QEXPECT_FAIL("", "QTBUG-23333", Abort);
++ QCOMPARE(count, count_expected);
+ }
+
+ // Set the finish flag immediately, this should give us one thread only.
+ for (int i = 0; i < repeats; ++i) {
++ ThreadCountUser t(true /*finishImmediately*/);
++ t.startBlocking();
++ int count = threads.count();
++ if (count != 1)
++ QEXPECT_FAIL("", "QTBUG-23333", Abort);
++ QCOMPARE(count, 1);
++
+ (new ThreadCountUser(true /*finishImmediately*/))->startAsynchronously().waitForFinished();
+- const auto count = threads.count();
++ count = threads.count();
++ if (count != 1)
++ QEXPECT_FAIL("", "QTBUG-23333", Abort);
+ QCOMPARE(count, 1);
+ QVERIFY(!threads.contains(QThread::currentThread()));
+ }
+@@ -400,6 +437,7 @@ public:
+
+ void tst_QtConcurrentThreadEngine::exceptions()
+ {
++ // Asynchronous mode:
+ {
+ bool caught = false;
+ try {
+@@ -412,6 +450,32 @@ void tst_QtConcurrentThreadEngine::exceptions()
+ QVERIFY2(caught, "did not get exception");
+ }
+
++ // Blocking mode:
++ // test throwing the exception from a worker thread.
++ {
++ bool caught = false;
++ try {
++ QtConcurrentExceptionThrower e(QThread::currentThread());
++ e.startBlocking();
++ } catch (const QException &) {
++ caught = true;
++ }
++ QVERIFY2(caught, "did not get exception");
++ }
++
++ // test throwing the exception from the main thread (different code path)
++ {
++ bool caught = false;
++ try {
++ QtConcurrentExceptionThrower e(0);
++ e.startBlocking();
++ } catch (const QException &) {
++ caught = true;
++ }
++ QVERIFY2(caught, "did not get exception");
++ }
++
++ // Asynchronous mode:
+ {
+ bool caught = false;
+ try {
+@@ -423,6 +487,31 @@ void tst_QtConcurrentThreadEngine::exceptions()
+ }
+ QVERIFY2(caught, "did not get exception");
+ }
++
++ // Blocking mode:
++ // test throwing the exception from a worker thread.
++ {
++ bool caught = false;
++ try {
++ UnrelatedExceptionThrower e(QThread::currentThread());
++ e.startBlocking();
++ } catch (const QUnhandledException &) {
++ caught = true;
++ }
++ QVERIFY2(caught, "did not get exception");
++ }
++
++ // test throwing the exception from the main thread (different code path)
++ {
++ bool caught = false;
++ try {
++ UnrelatedExceptionThrower e(0);
++ e.startBlocking();
++ } catch (const QUnhandledException &) {
++ caught = true;
++ }
++ QVERIFY2(caught, "did not get exception");
++ }
+ }
+
+ #endif
+diff --git a/qtbase/tests/auto/corelib/io/qbuffer/tst_qbuffer.cpp b/qtbase/tests/auto/corelib/io/qbuffer/tst_qbuffer.cpp
+index 4968742110..f4c3fb711d 100644
+--- a/qtbase/tests/auto/corelib/io/qbuffer/tst_qbuffer.cpp
++++ b/qtbase/tests/auto/corelib/io/qbuffer/tst_qbuffer.cpp
+@@ -42,6 +42,7 @@ private slots:
+ void writeBlock_data();
+ void writeBlock();
+ void seek();
++ void invalidSeeks();
+ void seekTest_data();
+ void seekTest();
+ void read_rawdata();
+@@ -286,6 +287,29 @@ void tst_QBuffer::seek()
+ QCOMPARE(buffer.size(), pos);
+ }
+
++void tst_QBuffer::invalidSeeks()
++{
++ if constexpr (sizeof(qsizetype) == sizeof(qint64)) {
++ // sizeof(qsizetype) == sizeof(qint64), so +1 would overflow
++ QSKIP("This is a 32-bit-only test.");
++ } else {
++ QBuffer buffer;
++ buffer.open(QIODevice::WriteOnly);
++ QCOMPARE(buffer.buffer().size(), qsizetype(0));
++ QCOMPARE(buffer.pos(), qint64(0));
++ constexpr qint64 MaxQByteArrayCapacity = (std::numeric_limits<qsizetype>::max)();
++ // this should fail fast, not after trying to allocate nearly 2 GiB of data,
++ // potentially crashing in the process:
++ QVERIFY(!buffer.seek(2 * MaxQByteArrayCapacity - 1));
++ QCOMPARE(buffer.buffer().size(), qsizetype(0));
++ QCOMPARE(buffer.pos(), qint64(0));
++ // ditto:
++ QVERIFY(!buffer.seek(MaxQByteArrayCapacity + 1));
++ QCOMPARE(buffer.buffer().size(), qsizetype(0));
++ QCOMPARE(buffer.pos(), qint64(0));
++ }
++}
++
+ void tst_QBuffer::seekTest_data()
+ {
+ writeBlock_data();
+diff --git a/qtbase/tests/auto/corelib/io/qiodevice/tst_qiodevice.cpp b/qtbase/tests/auto/corelib/io/qiodevice/tst_qiodevice.cpp
+index da5327594c..4a04e0f7c6 100644
+--- a/qtbase/tests/auto/corelib/io/qiodevice/tst_qiodevice.cpp
++++ b/qtbase/tests/auto/corelib/io/qiodevice/tst_qiodevice.cpp
+@@ -561,7 +561,8 @@ protected:
+ qint64 readData(char *data, qint64 maxSize) override
+ {
+ maxSize = qMin(maxSize, qint64(buf->size() - offset));
+- memcpy(data, buf->constData() + offset, maxSize);
++ if (maxSize > 0)
++ memcpy(data, buf->constData() + offset, maxSize);
+ offset += maxSize;
+ return maxSize;
+ }
+@@ -604,13 +605,15 @@ protected:
+ qint64 readData(char *data, qint64 maxSize) override
+ {
+ maxSize = qMin(maxSize, qint64(buf.size() - pos()));
+- memcpy(data, buf.constData() + pos(), maxSize);
++ if (maxSize > 0)
++ memcpy(data, buf.constData() + pos(), maxSize);
+ return maxSize;
+ }
+ qint64 writeData(const char *data, qint64 maxSize) override
+ {
+ maxSize = qMin(maxSize, qint64(buf.size() - pos()));
+- memcpy(buf.data() + pos(), data, maxSize);
++ if (maxSize > 0)
++ memcpy(buf.data() + pos(), data, maxSize);
+ return maxSize;
+ }
+
+diff --git a/qtbase/tests/auto/corelib/io/qprocess/tst_qprocess.cpp b/qtbase/tests/auto/corelib/io/qprocess/tst_qprocess.cpp
+index db60bead64..f345a44414 100644
+--- a/qtbase/tests/auto/corelib/io/qprocess/tst_qprocess.cpp
++++ b/qtbase/tests/auto/corelib/io/qprocess/tst_qprocess.cpp
+@@ -1,7 +1,8 @@
+ /****************************************************************************
+ **
+ ** Copyright (C) 2021 The Qt Company Ltd.
+-** Copyright (C) 2020 Intel Corporation.
++** Copyright (C) 2020 The Qt Company Ltd.
++** Copyright (C) 2022 Intel Corporation.
+ ** Contact: https://www.qt.io/licensing/
+ **
+ ** This file is part of the test suite of the Qt Toolkit.
+@@ -150,6 +151,8 @@ private slots:
+ void startStopStartStopBuffers();
+ void processEventsInAReadyReadSlot_data();
+ void processEventsInAReadyReadSlot();
++ void startFromCurrentWorkingDir_data();
++ void startFromCurrentWorkingDir();
+
+ // keep these at the end, since they use lots of processes and sometimes
+ // caused obscure failures to occur in tests that followed them (esp. on the Mac)
+@@ -2731,5 +2734,94 @@ void tst_QProcess::finishProcessBeforeReadingDone_deprecated()
+
+ #endif
+
++enum class ChdirMode {
++ None = 0,
++ InParent,
++ InChild
++};
++Q_DECLARE_METATYPE(ChdirMode)
++
++void tst_QProcess::startFromCurrentWorkingDir_data()
++{
++ qRegisterMetaType<ChdirMode>();
++ QTest::addColumn<QString>("programPrefix");
++ QTest::addColumn<ChdirMode>("chdirMode");
++ QTest::addColumn<bool>("success");
++
++ constexpr bool IsWindows = true
++#ifdef Q_OS_UNIX
++ && false
++#endif
++ ;
++
++ // baseline: trying to execute the directory, this can't possibly succeed!
++ QTest::newRow("plain-same-cwd") << QString() << ChdirMode::None << false;
++
++ // cross-platform behavior: neither OS searches the setWorkingDirectory()
++ // dir without "./"
++ QTest::newRow("plain-child-chdir") << QString() << ChdirMode::InChild << false;
++
++ // cross-platform behavior: both OSes search the parent's CWD with "./"
++ QTest::newRow("prefixed-parent-chdir") << "./" << ChdirMode::InParent << true;
++
++ // opposite behaviors: Windows searches the parent's CWD and Unix searches
++ // the child's with "./"
++ QTest::newRow("prefixed-child-chdir") << "./" << ChdirMode::InChild << !IsWindows;
++
++ // Windows searches the parent's CWD without "./"
++ QTest::newRow("plain-parent-chdir") << QString() << ChdirMode::InParent << IsWindows;
++}
++
++void tst_QProcess::startFromCurrentWorkingDir()
++{
++ QFETCH(QString, programPrefix);
++ QFETCH(ChdirMode, chdirMode);
++ QFETCH(bool, success);
++
++ QProcess process;
++ qRegisterMetaType<QProcess::ProcessError>();
++ QSignalSpy errorSpy(&process, &QProcess::errorOccurred);
++ QVERIFY(errorSpy.isValid());
++
++ // both the dir name and the executable name
++ const QString target = QStringLiteral("testProcessNormal");
++ process.setProgram(programPrefix + target);
++
++#ifdef Q_OS_UNIX
++ // Reset PATH, to be sure it doesn't contain . or the empty path.
++ // We can't do this on Windows because DLLs are searched in PATH
++ // and Windows always searches "." anyway.
++ auto restoreEnv = qScopeGuard([old = qgetenv("PATH")] {
++ qputenv("PATH", old);
++ });
++ qputenv("PATH", "/");
++#endif
++
++ switch (chdirMode) {
++ case ChdirMode::InParent: {
++ auto restoreCwd = qScopeGuard([old = QDir::currentPath()] {
++ QDir::setCurrent(old);
++ });
++ QVERIFY(QDir::setCurrent(target));
++ process.start();
++ break;
++ }
++ case ChdirMode::InChild:
++ process.setWorkingDirectory(target);
++ Q_FALLTHROUGH();
++ case ChdirMode::None:
++ process.start();
++ break;
++ }
++
++ QCOMPARE(process.waitForStarted(), success);
++ QCOMPARE(errorSpy.count(), int(!success));
++ if (success) {
++ QVERIFY(process.waitForFinished());
++ } else {
++ QCOMPARE(process.error(), QProcess::FailedToStart);
++ }
++}
++
+ QTEST_MAIN(tst_QProcess)
+ #include "tst_qprocess.moc"
+diff --git a/qtbase/tests/auto/corelib/itemmodels/qconcatenatetablesproxymodel/tst_qconcatenatetablesproxymodel.cpp b/qtbase/tests/auto/corelib/itemmodels/qconcatenatetablesproxymodel/tst_qconcatenatetablesproxymodel.cpp
+index e1ea7a4552..90972caa57 100644
+--- a/qtbase/tests/auto/corelib/itemmodels/qconcatenatetablesproxymodel/tst_qconcatenatetablesproxymodel.cpp
++++ b/qtbase/tests/auto/corelib/itemmodels/qconcatenatetablesproxymodel/tst_qconcatenatetablesproxymodel.cpp
+@@ -117,6 +117,7 @@ private Q_SLOTS:
+ void shouldPropagateDropAfterLastRow_data();
+ void shouldPropagateDropAfterLastRow();
+ void qtbug91788();
++ void qtbug91878();
+
+ private:
+ QStandardItemModel mod;
+@@ -843,6 +844,22 @@ void tst_QConcatenateTablesProxyModel::qtbug91788()
+ QCOMPARE(proxyConcat.columnCount(), 0);
+ }
+
++void tst_QConcatenateTablesProxyModel::qtbug91878()
++{
++ QStandardItemModel m;
++ m.setRowCount(4);
++ m.setColumnCount(4);
++
++ QConcatenateTablesProxyModel pm;
++ QSortFilterProxyModel proxyFilter;
++ proxyFilter.setSourceModel(&pm);
++ proxyFilter.setFilterFixedString("something");
++ pm.addSourceModel(&m); // This should not assert
++
++ QCOMPARE(pm.columnCount(), 4);
++ QCOMPARE(pm.rowCount(), 4);
++}
++
+ QTEST_GUILESS_MAIN(tst_QConcatenateTablesProxyModel)
+
+ #include "tst_qconcatenatetablesproxymodel.moc"
+diff --git a/qtbase/tests/auto/corelib/kernel/qobject/tst_qobject.cpp b/qtbase/tests/auto/corelib/kernel/qobject/tst_qobject.cpp
+index 9bd66c0835..ed4a0bae5d 100644
+--- a/qtbase/tests/auto/corelib/kernel/qobject/tst_qobject.cpp
++++ b/qtbase/tests/auto/corelib/kernel/qobject/tst_qobject.cpp
+@@ -158,6 +158,7 @@ private slots:
+ void nullReceiver();
+ void functorReferencesConnection();
+ void disconnectDisconnects();
++ void declarativeData();
+ };
+
+ struct QObjectCreatedOnShutdown
+@@ -7679,5 +7680,81 @@ void tst_QObject::disconnectDisconnects()
+ Q_STATIC_ASSERT(QtPrivate::HasQ_OBJECT_Macro<tst_QObject>::Value);
+ Q_STATIC_ASSERT(!QtPrivate::HasQ_OBJECT_Macro<SiblingDeleter>::Value);
+
++#ifdef QT_BUILD_INTERNAL
++/*
++ Since QObjectPrivate stores the declarativeData pointer in a union with the pointer
++ to the currently destroyed child, calls to the QtDeclarative handlers need to be
++ correctly guarded. QTBUG-105286
++*/
++namespace QtDeclarative {
++static QAbstractDeclarativeData *theData;
++
++static void destroyed(QAbstractDeclarativeData *data, QObject *)
++{
++ QCOMPARE(data, theData);
++}
++static void signalEmitted(QAbstractDeclarativeData *data, QObject *, int, void **)
++{
++ QCOMPARE(data, theData);
++}
++// we can't use QCOMPARE in the next two functions, as they don't return void
++static int receivers(QAbstractDeclarativeData *data, const QObject *, int)
++{
++ QTest::qCompare(data, theData, "data", "theData", __FILE__, __LINE__);
++ return 0;
++}
++static bool isSignalConnected(QAbstractDeclarativeData *data, const QObject *, int)
++{
++ QTest::qCompare(data, theData, "data", "theData", __FILE__, __LINE__);
++ return true;
++}
++
++class Object : public QObject
++{
++ Q_OBJECT
++public:
++ using QObject::QObject;
++ ~Object()
++ {
++ if (Object *p = static_cast<Object *>(parent()))
++ p->emitSignal();
++ }
++
++ void emitSignal()
++ {
++ emit theSignal();
++ }
++
++signals:
++ void theSignal();
++};
++
++}
++#endif
++
++void tst_QObject::declarativeData()
++{
++#ifdef QT_BUILD_INTERNAL
++ QScopedValueRollback destroyed(QAbstractDeclarativeData::destroyed,
++ QtDeclarative::destroyed);
++ QScopedValueRollback signalEmitted(QAbstractDeclarativeData::signalEmitted,
++ QtDeclarative::signalEmitted);
++ QScopedValueRollback receivers(QAbstractDeclarativeData::receivers,
++ QtDeclarative::receivers);
++ QScopedValueRollback isSignalConnected(QAbstractDeclarativeData::isSignalConnected,
++ QtDeclarative::isSignalConnected);
++
++ QtDeclarative::Object p;
++ QObjectPrivate *priv = QObjectPrivate::get(&p);
++ priv->declarativeData = QtDeclarative::theData = new QAbstractDeclarativeData;
++
++ connect(&p, &QtDeclarative::Object::theSignal, &p, []{
++ });
++
++ QtDeclarative::Object *child = new QtDeclarative::Object;
++ child->setParent(&p);
++#endif
++}
++
+ QTEST_MAIN(tst_QObject)
+ #include "tst_qobject.moc"
+diff --git a/qtbase/tests/auto/corelib/mimetypes/qmimedatabase/tst_qmimedatabase.cpp b/qtbase/tests/auto/corelib/mimetypes/qmimedatabase/tst_qmimedatabase.cpp
+index 0ea422ecbc..1a3256534b 100644
+--- a/qtbase/tests/auto/corelib/mimetypes/qmimedatabase/tst_qmimedatabase.cpp
++++ b/qtbase/tests/auto/corelib/mimetypes/qmimedatabase/tst_qmimedatabase.cpp
+@@ -70,15 +70,15 @@ static inline QString testSuiteWarning()
+
+ QString result;
+ QTextStream str(&result);
+- str << "\nCannot find the shared-mime-info test suite\nstarting from: "
++ str << "\nCannot find the shared-mime-info test suite\nin the parent of: "
+ << QDir::toNativeSeparators(QDir::currentPath()) << "\n"
+ "cd " << QDir::toNativeSeparators(QStringLiteral("tests/auto/corelib/mimetypes/qmimedatabase")) << "\n"
+- "wget http://cgit.freedesktop.org/xdg/shared-mime-info/snapshot/Release-1-10.zip\n"
+- "unzip Release-1-10.zip\n";
++ "wget https://gitlab.freedesktop.org/xdg/shared-mime-info/-/archive/2.1/shared-mime-info-2.1.zip\n"
++ "unzip shared-mime-info-2.1.zip\n";
+ #ifdef Q_OS_WIN
+- str << "mkdir testfiles\nxcopy /s Release-1-10 s-m-i\n";
++ str << "mkdir testfiles\nxcopy /s shared-mime-info-2.1 s-m-i\n";
+ #else
+- str << "ln -s Release-1-10 s-m-i\n";
++ str << "ln -s shared-mime-info-2.1 s-m-i\n";
+ #endif
+ return result;
+ }
+@@ -154,7 +154,7 @@ void tst_QMimeDatabase::initTestCase()
+ QVERIFY2(copyResourceFile(xmlFileName, xmlTargetFileName, &errorMessage), qPrintable(errorMessage));
+ #endif
+
+- m_testSuite = QFINDTESTDATA("s-m-i/tests");
++ m_testSuite = QFINDTESTDATA("s-m-i/tests/mime-detection");
+ if (m_testSuite.isEmpty())
+ qWarning("%s", qPrintable(testSuiteWarning()));
+
+@@ -611,7 +611,7 @@ void tst_QMimeDatabase::allMimeTypes()
+ QVERIFY(!lst.isEmpty());
+
+ // Hardcoding this is the only way to check both providers find the same number of mimetypes.
+- QCOMPARE(lst.count(), 779);
++ QCOMPARE(lst.count(), 811);
+
+ foreach (const QMimeType &mime, lst) {
+ const QString name = mime.name();
+@@ -631,10 +631,9 @@ void tst_QMimeDatabase::suffixes_data()
+
+ QTest::newRow("mimetype with a single pattern") << "application/pdf" << "*.pdf" << "pdf";
+ QTest::newRow("mimetype with multiple patterns") << "application/x-kpresenter" << "*.kpr;*.kpt" << "kpr";
+- QTest::newRow("jpeg") << "image/jpeg" << "*.jpe;*.jpg;*.jpeg" << "jpeg";
+- //if (KMimeType::sharedMimeInfoVersion() > KDE_MAKE_VERSION(0, 60, 0)) {
+- QTest::newRow("mimetype with many patterns") << "application/vnd.wordperfect" << "*.wp;*.wp4;*.wp5;*.wp6;*.wpd;*.wpp" << "wp";
+- //}
++ // The preferred suffix for image/jpeg is *.jpg, as per https://bugs.kde.org/show_bug.cgi?id=176737
++ QTest::newRow("jpeg") << "image/jpeg" << "*.jpe;*.jpg;*.jpeg" << "jpg";
++ QTest::newRow("mimetype with many patterns") << "application/vnd.wordperfect" << "*.wp;*.wp4;*.wp5;*.wp6;*.wpd;*.wpp" << "wp";
+ QTest::newRow("oasis text mimetype") << "application/vnd.oasis.opendocument.text" << "*.odt" << "odt";
+ QTest::newRow("oasis presentation mimetype") << "application/vnd.oasis.opendocument.presentation" << "*.odp" << "odp";
+ QTest::newRow("mimetype with multiple patterns") << "text/plain" << "*.asc;*.txt;*,v" << "txt";
+diff --git a/qtbase/tests/auto/corelib/serialization/json/tst_qtjson.cpp b/qtbase/tests/auto/corelib/serialization/json/tst_qtjson.cpp
+index 3e58dd03cc..c8f82ef5d5 100644
+--- a/qtbase/tests/auto/corelib/serialization/json/tst_qtjson.cpp
++++ b/qtbase/tests/auto/corelib/serialization/json/tst_qtjson.cpp
+@@ -176,6 +176,8 @@ private Q_SLOTS:
+ void fromToVariantConversions_data();
+ void fromToVariantConversions();
+
++ void noLeakOnNameClash();
++
+ private:
+ QString testDataDir;
+ };
+@@ -3685,5 +3687,23 @@ void tst_QtJson::fromToVariantConversions()
+ }
+ }
+
++void tst_QtJson::noLeakOnNameClash()
++{
++ QJsonDocument doc = QJsonDocument::fromJson("{\"\":{\"\":0},\"\":0}");
++ QVERIFY(!doc.isNull());
++ const QJsonObject obj = doc.object();
++
++ // Removed the duplicate key.
++ QCOMPARE(obj.length(), 1);
++
++ // Retained the last of the duplicates.
++ const QJsonValue val = obj.begin().value();
++ QVERIFY(val.isDouble());
++ QCOMPARE(val.toDouble(), 0.0);
++
++ // It should not leak.
++ // In particular it should not forget to deref the container for the inner object.
++}
++
+ QTEST_MAIN(tst_QtJson)
+ #include "tst_qtjson.moc"
+diff --git a/qtbase/tests/auto/corelib/time/qtimezone/tst_qtimezone.cpp b/qtbase/tests/auto/corelib/time/qtimezone/tst_qtimezone.cpp
+index a59b58d57f..241c3e84ac 100644
+--- a/qtbase/tests/auto/corelib/time/qtimezone/tst_qtimezone.cpp
++++ b/qtbase/tests/auto/corelib/time/qtimezone/tst_qtimezone.cpp
+@@ -63,6 +63,7 @@ private slots:
+ void isValidId_data();
+ void isValidId();
+ void malformed();
++ void serialize();
+ // Backend tests
+ void utcTest();
+ void icuTest();
+@@ -947,6 +948,33 @@ void tst_QTimeZone::malformed()
+ barf.offsetFromUtc(now);
+ }
+
++void tst_QTimeZone::serialize()
++{
++ int parts = 0;
++#ifndef QT_NO_DEBUG_STREAM
++ qDebug() << QTimeZone(); // to verify no crash
++ parts++;
++#endif
++#ifndef QT_NO_DATASTREAM
++ QByteArray blob;
++ {
++ QDataStream stream(&blob, QIODevice::WriteOnly);
++ stream << QTimeZone("Europe/Oslo") << QTimeZone(420) << QTimeZone() << qint64(-1);
++ }
++ QDataStream stream(&blob, QIODevice::ReadOnly);
++ QTimeZone invalid, offset, oslo;
++ qint64 minusone;
++ stream >> oslo >> offset >> invalid >> minusone;
++ QCOMPARE(oslo, QTimeZone("Europe/Oslo"));
++ QCOMPARE(offset, QTimeZone(420));
++ QVERIFY(!invalid.isValid());
++ QCOMPARE(minusone, qint64(-1));
++ parts++;
++#endif
++ if (!parts)
++ QSKIP("No serialization enabled");
++}
++
+ void tst_QTimeZone::utcTest()
+ {
+ #ifdef QT_BUILD_INTERNAL
+diff --git a/qtbase/tests/auto/dbus/qdbusinterface/tst_qdbusinterface.cpp b/qtbase/tests/auto/dbus/qdbusinterface/tst_qdbusinterface.cpp
+index 05480c6dd2..70f4c75756 100644
+--- a/qtbase/tests/auto/dbus/qdbusinterface/tst_qdbusinterface.cpp
++++ b/qtbase/tests/auto/dbus/qdbusinterface/tst_qdbusinterface.cpp
+@@ -324,6 +324,13 @@ void tst_QDBusInterface::notValid()
+
+ QVERIFY(!interface.isValid());
+ QVERIFY(!QMetaObject::invokeMethod(&interface, "ListNames", Qt::DirectConnection));
++
++ // With a connection, but empty/null service and path specified
++ QDBusConnection con = QDBusConnection::sessionBus();
++ QVERIFY(con.isConnected());
++ QDBusInterface iface({}, {}, {}, con);
++ QVERIFY(!iface.isValid());
++ QVERIFY(!QMetaObject::invokeMethod(&interface, "ListNames", Qt::DirectConnection));
+ }
+
+ void tst_QDBusInterface::notValidDerived()
+diff --git a/qtbase/tests/auto/gui/kernel/qkeysequence/tst_qkeysequence.cpp b/qtbase/tests/auto/gui/kernel/qkeysequence/tst_qkeysequence.cpp
+index 874468c954..04ceb4ab65 100644
+--- a/qtbase/tests/auto/gui/kernel/qkeysequence/tst_qkeysequence.cpp
++++ b/qtbase/tests/auto/gui/kernel/qkeysequence/tst_qkeysequence.cpp
+@@ -507,6 +507,10 @@ void tst_QKeySequence::toStringFromKeycode_data()
+ QTest::newRow("Ctrl+Alt+Num+Del") << QKeySequence(Qt::ControlModifier | Qt::AltModifier | Qt::KeypadModifier | Qt::Key_Delete) << "Ctrl+Alt+Num+Del";
+ QTest::newRow("Ctrl+Ins") << QKeySequence(Qt::ControlModifier | Qt::Key_Insert) << "Ctrl+Ins";
+ QTest::newRow("Ctrl+Num+Ins(1)") << QKeySequence(Qt::Key_Insert | Qt::KeypadModifier | Qt::ControlModifier) << "Ctrl+Num+Ins";
++ QTest::newRow("Ctrl") << QKeySequence(Qt::Key_Control) << "Control";
++ QTest::newRow("Alt") << QKeySequence(Qt::Key_Alt) << "Alt";
++ QTest::newRow("Shift") << QKeySequence(Qt::Key_Shift) << "Shift";
++ QTest::newRow("Meta") << QKeySequence(Qt::Key_Meta) << "Meta";
+ }
+
+ void tst_QKeySequence::toStringFromKeycode()
+diff --git a/qtbase/tests/auto/gui/text/qfontdatabase/tst_qfontdatabase.cpp b/qtbase/tests/auto/gui/text/qfontdatabase/tst_qfontdatabase.cpp
+index 15e0ecadaa..b4eca74283 100644
+--- a/qtbase/tests/auto/gui/text/qfontdatabase/tst_qfontdatabase.cpp
++++ b/qtbase/tests/auto/gui/text/qfontdatabase/tst_qfontdatabase.cpp
+@@ -81,6 +81,8 @@ private slots:
+ void registerOpenTypePreferredNamesSystem();
+ void registerOpenTypePreferredNamesApplication();
+
++ void stretchRespected();
++
+ private:
+ QString m_ledFont;
+ QString m_testFont;
+@@ -355,6 +357,28 @@ static QString testString()
+ return QStringLiteral("foo bar");
+ }
+
++void tst_QFontDatabase::stretchRespected()
++{
++ int italicId = QFontDatabase::addApplicationFont(m_testFontItalic);
++ QVERIFY(italicId != -1);
++
++ QVERIFY(!QFontDatabase::applicationFontFamilies(italicId).isEmpty());
++
++ QString italicFontName = QFontDatabase::applicationFontFamilies(italicId).first();
++
++ QFont italicFont = QFontDatabase().font(italicFontName,
++ QString::fromLatin1("Italic"), 14);
++ QVERIFY(italicFont.italic());
++
++ QFont italicStretchedFont = italicFont;
++ italicStretchedFont.setStretch( 400 );
++
++ QVERIFY(QFontMetricsF(italicFont).horizontalAdvance(QStringLiteral("foobar")) <
++ QFontMetricsF(italicStretchedFont).horizontalAdvance(QStringLiteral("foobar")));
++
++ QFontDatabase::removeApplicationFont(italicId);
++}
++
+ void tst_QFontDatabase::condensedFontWidthNoFontMerging()
+ {
+ int regularFontId = QFontDatabase::addApplicationFont(m_testFont);
+diff --git a/qtbase/tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp b/qtbase/tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp
+index 3d4a094c43..b423e11a99 100644
+--- a/qtbase/tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp
++++ b/qtbase/tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp
+@@ -281,6 +281,7 @@ private Q_SLOTS:
+ void ioGetFromFileSpecial();
+ void ioGetFromFile_data();
+ void ioGetFromFile();
++ void ioGetFromFileUrl();
+ void ioGetFromFtp_data();
+ void ioGetFromFtp();
+ void ioGetFromFtpWithReuse();
+@@ -3300,6 +3301,18 @@ void tst_QNetworkReply::ioGetFromFile()
+ QCOMPARE(reader.data, data);
+ }
+
++void tst_QNetworkReply::ioGetFromFileUrl()
++{
++ // This immediately fails on non-windows platforms:
++ QNetworkRequest request(QUrl("file://unc-server/some/path"));
++ QNetworkReplyPtr reply(manager.get(request));
++ QSignalSpy finishedSpy(reply.get(), &QNetworkReply::finished);
++ // QTBUG-105618: This would, on non-Windows platforms, never happen because the signal
++ // was emitted before the constructor finished, leaving no chance at all to connect to the
++ // signal
++ QVERIFY(finishedSpy.wait());
++}
++
+ void tst_QNetworkReply::ioGetFromFtp_data()
+ {
+ QTest::addColumn<QString>("fileName");
+diff --git a/qtbase/tests/auto/network/ssl/qsslsocket/certs/fluke.cert b/qtbase/tests/auto/network/ssl/qsslsocket/certs/fluke.cert
+index 069fa6b341..4cc4d9a5ea 100644
+--- a/qtbase/tests/auto/network/ssl/qsslsocket/certs/fluke.cert
++++ b/qtbase/tests/auto/network/ssl/qsslsocket/certs/fluke.cert
+@@ -1,75 +1,34 @@
+-Certificate:
+- Data:
+- Version: 3 (0x2)
+- Serial Number: 0 (0x0)
+- Signature Algorithm: sha1WithRSAEncryption
+- Issuer: C=NO, ST=Oslo, L=Nydalen, O=Nokia Corporation and/or its subsidiary(-ies), OU=Development, CN=fluke.troll.no/emailAddress=ahanssen@trolltech.com
+- Validity
+- Not Before: Dec 4 01:10:32 2007 GMT
+- Not After : Apr 21 01:10:32 2035 GMT
+- Subject: C=NO, ST=Oslo, O=Nokia Corporation and/or its subsidiary(-ies), OU=Development, CN=fluke.troll.no
+- Subject Public Key Info:
+- Public Key Algorithm: rsaEncryption
+- RSA Public Key: (1024 bit)
+- Modulus (1024 bit):
+- 00:a7:c8:a0:4a:c4:19:05:1b:66:ba:32:e2:d2:f1:
+- 1c:6f:17:82:e4:39:2e:01:51:90:db:04:34:32:11:
+- 21:c2:0d:6f:59:d8:53:90:54:3f:83:8f:a9:d3:b3:
+- d5:ee:1a:9b:80:ae:c3:25:c9:5e:a5:af:4b:60:05:
+- aa:a0:d1:91:01:1f:ca:04:83:e3:58:1c:99:32:45:
+- 84:70:72:58:03:98:4a:63:8b:41:f5:08:49:d2:91:
+- 02:60:6b:e4:64:fe:dd:a0:aa:74:08:e9:34:4c:91:
+- 5f:12:3d:37:4d:54:2c:ad:7f:5b:98:60:36:02:8c:
+- 3b:f6:45:f3:27:6a:9b:94:9d
+- Exponent: 65537 (0x10001)
+- X509v3 extensions:
+- X509v3 Basic Constraints:
+- CA:FALSE
+- Netscape Comment:
+- OpenSSL Generated Certificate
+- X509v3 Subject Key Identifier:
+- 21:85:04:3D:23:01:66:E5:F7:9F:1A:84:24:8A:AF:0A:79:F4:E5:AC
+- X509v3 Authority Key Identifier:
+- DirName:/C=NO/ST=Oslo/L=Nydalen/O=Nokia Corporation and/or its subsidiary(-ies)/OU=Development/CN=fluke.troll.no/emailAddress=ahanssen@trolltech.com
+- serial:8E:A8:B4:E8:91:B7:54:2E
+-
+- Signature Algorithm: sha1WithRSAEncryption
+- 6d:57:5f:d1:05:43:f0:62:05:ec:2a:71:a5:dc:19:08:f2:c4:
+- a6:bd:bb:25:d9:ca:89:01:0e:e4:cf:1f:c1:8c:c8:24:18:35:
+- 53:59:7b:c0:43:b4:32:e6:98:b2:a6:ef:15:05:0b:48:5f:e1:
+- a0:0c:97:a9:a1:77:d8:35:18:30:bc:a9:8f:d3:b7:54:c7:f1:
+- a9:9e:5d:e6:19:bf:f6:3c:5b:2b:d8:e4:3e:62:18:88:8b:d3:
+- 24:e1:40:9b:0c:e6:29:16:62:ab:ea:05:24:70:36:aa:55:93:
+- ef:02:81:1b:23:10:a2:04:eb:56:95:75:fc:f8:94:b1:5d:42:
+- c5:3f:36:44:85:5d:3a:2e:90:46:8a:a2:b9:6f:87:ae:0c:15:
+- 40:19:31:90:fc:3b:25:bb:ae:f1:66:13:0d:85:90:d9:49:34:
+- 8f:f2:5d:f9:7a:db:4d:5d:27:f6:76:9d:35:8c:06:a6:4c:a3:
+- b1:b2:b6:6f:1d:d7:a3:00:fd:72:eb:9e:ea:44:a1:af:21:34:
+- 7d:c7:42:e2:49:91:19:8b:c0:ad:ba:82:80:a8:71:70:f4:35:
+- 31:91:63:84:20:95:e9:60:af:64:8b:cc:ff:3d:8a:76:74:3d:
+- c8:55:6d:e4:8e:c3:2b:1c:e8:42:18:ae:9f:e6:6b:9c:34:06:
+- ec:6a:f2:c3
+ -----BEGIN CERTIFICATE-----
+-MIIEEzCCAvugAwIBAgIBADANBgkqhkiG9w0BAQUFADCBnDELMAkGA1UEBhMCTk8x
+-DTALBgNVBAgTBE9zbG8xEDAOBgNVBAcTB055ZGFsZW4xFjAUBgNVBAoTDVRyb2xs
+-dGVjaCBBU0ExFDASBgNVBAsTC0RldmVsb3BtZW50MRcwFQYDVQQDEw5mbHVrZS50
+-cm9sbC5ubzElMCMGCSqGSIb3DQEJARYWYWhhbnNzZW5AdHJvbGx0ZWNoLmNvbTAe
+-Fw0wNzEyMDQwMTEwMzJaFw0zNTA0MjEwMTEwMzJaMGMxCzAJBgNVBAYTAk5PMQ0w
+-CwYDVQQIEwRPc2xvMRYwFAYDVQQKEw1Ucm9sbHRlY2ggQVNBMRQwEgYDVQQLEwtE
+-ZXZlbG9wbWVudDEXMBUGA1UEAxMOZmx1a2UudHJvbGwubm8wgZ8wDQYJKoZIhvcN
+-AQEBBQADgY0AMIGJAoGBAKfIoErEGQUbZroy4tLxHG8XguQ5LgFRkNsENDIRIcIN
+-b1nYU5BUP4OPqdOz1e4am4CuwyXJXqWvS2AFqqDRkQEfygSD41gcmTJFhHByWAOY
+-SmOLQfUISdKRAmBr5GT+3aCqdAjpNEyRXxI9N01ULK1/W5hgNgKMO/ZF8ydqm5Sd
+-AgMBAAGjggEaMIIBFjAJBgNVHRMEAjAAMCwGCWCGSAGG+EIBDQQfFh1PcGVuU1NM
+-IEdlbmVyYXRlZCBDZXJ0aWZpY2F0ZTAdBgNVHQ4EFgQUIYUEPSMBZuX3nxqEJIqv
+-Cnn05awwgbsGA1UdIwSBszCBsKGBoqSBnzCBnDELMAkGA1UEBhMCTk8xDTALBgNV
+-BAgTBE9zbG8xEDAOBgNVBAcTB055ZGFsZW4xFjAUBgNVBAoTDVRyb2xsdGVjaCBB
+-U0ExFDASBgNVBAsTC0RldmVsb3BtZW50MRcwFQYDVQQDEw5mbHVrZS50cm9sbC5u
+-bzElMCMGCSqGSIb3DQEJARYWYWhhbnNzZW5AdHJvbGx0ZWNoLmNvbYIJAI6otOiR
+-t1QuMA0GCSqGSIb3DQEBBQUAA4IBAQBtV1/RBUPwYgXsKnGl3BkI8sSmvbsl2cqJ
+-AQ7kzx/BjMgkGDVTWXvAQ7Qy5piypu8VBQtIX+GgDJepoXfYNRgwvKmP07dUx/Gp
+-nl3mGb/2PFsr2OQ+YhiIi9Mk4UCbDOYpFmKr6gUkcDaqVZPvAoEbIxCiBOtWlXX8
+-+JSxXULFPzZEhV06LpBGiqK5b4euDBVAGTGQ/Dslu67xZhMNhZDZSTSP8l35ettN
+-XSf2dp01jAamTKOxsrZvHdejAP1y657qRKGvITR9x0LiSZEZi8CtuoKAqHFw9DUx
+-kWOEIJXpYK9ki8z/PYp2dD3IVW3kjsMrHOhCGK6f5mucNAbsavLD
++MIIF6zCCA9OgAwIBAgIUfo9amJtJGWqWE6f+SkAO85zkGr4wDQYJKoZIhvcNAQEL
++BQAwgYMxCzAJBgNVBAYTAk5PMQ0wCwYDVQQIDARPc2xvMQ0wCwYDVQQHDARPc2xv
++MRcwFQYDVQQKDA5UaGUgUXQgQ29tcGFueTEMMAoGA1UECwwDUiZEMRIwEAYDVQQD
++DAlIMiBUZXN0ZXIxGzAZBgkqhkiG9w0BCQEWDG1pbmltaUBxdC5pbzAgFw0yMDEw
++MjYxMjAxMzFaGA8yMTIwMTAwMjEyMDEzMVowgYMxCzAJBgNVBAYTAk5PMQ0wCwYD
++VQQIDARPc2xvMQ0wCwYDVQQHDARPc2xvMRcwFQYDVQQKDA5UaGUgUXQgQ29tcGFu
++eTEMMAoGA1UECwwDUiZEMRIwEAYDVQQDDAlIMiBUZXN0ZXIxGzAZBgkqhkiG9w0B
++CQEWDG1pbmltaUBxdC5pbzCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIB
++AOiUp5+E4blouKH7q+rVNR8NoYX2XkBW+q+rpy1zu5ssRSzbqxAjDx9dkht7Qlnf
++VlDT00JvpOWdeuPon5915edQRsY4Unl6mKH29ra3OtUa1/yCJXsGVJTKCj7k4Bxb
++5mZzb/fTlZntMLdTIBMfUbw62FKir1WjKIcJ9fCoG8JaGeKVO4Rh5p0ezd4UUUId
++r1BXl5Nqdqy2vTMsEDnjOsD3egkv8I2SKN4O6n/C3wWYpMOWYZkGoZiKz7rJs/i/
++ez7bsV7JlwdzTlhpJzkcOSVFBP6JlEOxTNNxZ1wtKy7PtZGmsSSATq2e6+bw38Ae
++Op0XnzzqcGjtDDofBmT7OFzZWjS9VZS6+DOOe2QHWle1nCHcHyH4ku6IRlsr9xkR
++NAIlOfnvHHxqJUenoeaZ4oQDjCBKS1KXygJO/tL7BLTQVn/xK1EmPvKNnjzWk4tR
++PnibUhhs5635qpOU/YPqFBh1JjVruZbsWcDAhRcew0uxONXOa9E+4lttQ9ySYa1A
++LvWqJuAX7gu2BsBMLyqfm811YnA7CIFMyO+HlqmkLFfv5L/xIRAXR7l26YGO0VwX
++CGjMfz4NVPMMke4nB7qa9NkpXQBQKMms3Qzd5JW0Hy9Ruj5O8GPcFZmV0twjd1uJ
++PD/cAjkWLaXjdNsJ16QWc2nghQRS6HYqKRX6j+CXOxupAgMBAAGjUzBRMB0GA1Ud
++DgQWBBRSCOU58j9NJZkMamt623qyCrhN3TAfBgNVHSMEGDAWgBRSCOU58j9NJZkM
++amt623qyCrhN3TAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEBCwUAA4ICAQCq
++q4jxsWeNDv5Nq14hJtF9HB+ZL64zcZtRjJP1YgNs0QppKICmjPOL2nIMGmI/jKrs
++0eGAL/9XXNVHPxm1OPOncvimMMmU6emZfpMdEtTfKP43+Pg9HgKRjLoQp406vGeQ
++8ki/mbBhrItVPgEm3tu2AFA02XTYi+YxCI9kRZLGkM3FbgtOuTLPl0Z9y+kiPc9F
++uCSC03anBEqv+vDSI8+wODymQ/IJ3Jyz1lxIRDfp4qAekmy0jU2c91VOHHEmOmqq
++kqygGFRdwbe99m9yP63r6q0b5K3X2UnJ6bns0hmTwThYwpVPXLU8jdaTddbMukN2
++/Ef96Tsw8nWOEOPMySHOTIPgwyZRp26b0kA9EmhLwOP401SxXVQCmSRmtwNagmtg
++jJKmZoYBN+//D45ibK8z6Q0oOm9P+Whf/uUXehcRxBxyV3xz7k0wKGQbHj/ddwcy
++IUoIN4lrAlib+lK170kTKN352PDmrpo2gmIzPEsfurKAIMSelDl6H+kih16BtZ8y
++Nz6fh9Soqrg3OSAware8pxV7k51crBMoPLN78KoRV8MFCK4K7Fddq4rRISq6hiXq
++r1nsjoEPuKM9huprmZVZe9t5YcDa2I+wb3IiE3uwpZbAdaLDyQ5n6F/qpsiIkZXn
++gtcF7oqpG5oYrwCcZ53y/ezUgUg7PlSz2XwAGvQtgg==
+ -----END CERTIFICATE-----
+diff --git a/qtbase/tests/auto/network/ssl/qsslsocket/certs/fluke.key b/qtbase/tests/auto/network/ssl/qsslsocket/certs/fluke.key
+index 9d1664d609..337ce541a6 100644
+--- a/qtbase/tests/auto/network/ssl/qsslsocket/certs/fluke.key
++++ b/qtbase/tests/auto/network/ssl/qsslsocket/certs/fluke.key
+@@ -1,15 +1,52 @@
+------BEGIN RSA PRIVATE KEY-----
+-MIICXAIBAAKBgQCnyKBKxBkFG2a6MuLS8RxvF4LkOS4BUZDbBDQyESHCDW9Z2FOQ
+-VD+Dj6nTs9XuGpuArsMlyV6lr0tgBaqg0ZEBH8oEg+NYHJkyRYRwclgDmEpji0H1
+-CEnSkQJga+Rk/t2gqnQI6TRMkV8SPTdNVCytf1uYYDYCjDv2RfMnapuUnQIDAQAB
+-AoGANFzLkanTeSGNFM0uttBipFT9F4a00dqHz6JnO7zXAT26I5r8sU1pqQBb6uLz
+-/+Qz5Zwk8RUAQcsMRgJetuPQUb0JZjF6Duv24hNazqXBCu7AZzUenjafwmKC/8ri
+-KpX3fTwqzfzi//FKGgbXQ80yykSSliDL3kn/drATxsLCgQECQQDXhEFWLJ0vVZ1s
+-1Ekf+3NITE+DR16X+LQ4W6vyEHAjTbaNWtcTKdAWLA2l6N4WAAPYSi6awm+zMxx4
+-VomVTsjdAkEAx0z+e7natLeFcrrq8pbU+wa6SAP1VfhQWKitxL1e7u/QO90NCpxE
+-oQYKzMkmmpOOFjQwEMAy1dvFMbm4LHlewQJAC/ksDBaUcQHHqjktCtrUb8rVjAyW
+-A8lscckeB2fEYyG5J6dJVaY4ClNOOs5yMDS2Afk1F6H/xKvtQ/5CzInA/QJATDub
+-K+BPU8jO9q+gpuIi3VIZdupssVGmCgObVCHLakG4uO04y9IyPhV9lA9tALtoIf4c
+-VIvv5fWGXBrZ48kZAQJBAJmVCdzQxd9LZI5vxijUCj5EI4e+x5DRqVUvyP8KCZrC
+-AiNyoDP85T+hBZaSXK3aYGpVwelyj3bvo1GrTNwNWLw=
+------END RSA PRIVATE KEY-----
++-----BEGIN PRIVATE KEY-----
++MIIJQgIBADANBgkqhkiG9w0BAQEFAASCCSwwggkoAgEAAoICAQDolKefhOG5aLih
+++6vq1TUfDaGF9l5AVvqvq6ctc7ubLEUs26sQIw8fXZIbe0JZ31ZQ09NCb6TlnXrj
++6J+fdeXnUEbGOFJ5epih9va2tzrVGtf8giV7BlSUygo+5OAcW+Zmc2/305WZ7TC3
++UyATH1G8OthSoq9VoyiHCfXwqBvCWhnilTuEYeadHs3eFFFCHa9QV5eTanastr0z
++LBA54zrA93oJL/CNkijeDup/wt8FmKTDlmGZBqGYis+6ybP4v3s+27FeyZcHc05Y
++aSc5HDklRQT+iZRDsUzTcWdcLSsuz7WRprEkgE6tnuvm8N/AHjqdF5886nBo7Qw6
++HwZk+zhc2Vo0vVWUuvgzjntkB1pXtZwh3B8h+JLuiEZbK/cZETQCJTn57xx8aiVH
++p6HmmeKEA4wgSktSl8oCTv7S+wS00FZ/8StRJj7yjZ481pOLUT54m1IYbOet+aqT
++lP2D6hQYdSY1a7mW7FnAwIUXHsNLsTjVzmvRPuJbbUPckmGtQC71qibgF+4LtgbA
++TC8qn5vNdWJwOwiBTMjvh5appCxX7+S/8SEQF0e5dumBjtFcFwhozH8+DVTzDJHu
++Jwe6mvTZKV0AUCjJrN0M3eSVtB8vUbo+TvBj3BWZldLcI3dbiTw/3AI5Fi2l43Tb
++CdekFnNp4IUEUuh2KikV+o/glzsbqQIDAQABAoICAFw1q6tr5I48vY7DF+rXsuLn
++5ZUWE1IQ6fzB4lr72nJv/9EEGnMgYzt9PpMUsD6vdCpBgS2C0+6RHArFzJtNA+RM
++iHLIG7K7702veyr/xBx/MwiSlMeMv/XpkFxVI6E6skMGG2s3AMXxKvJTy5CpRx+I
++eQFyLG+Ya1X2lgJes/q+/CpAHkOjCOpcLySQC5NZ74q734V7nSdmn+Zs3tYEh+O/
++eiuwTP/j5b38Te5vVTqDxTciJPmljmXLCwa0N100lWlbcpvw8qbqiTI2Jm3XCbUE
++AzHjW9vmrF3cRS1fXxKFGShw3SRqlkbxjfeWoi8qDPUBS4m8LOr8qG9Wo5Nfon0z
++zLP4bci3zHDvVcaaZrrsUBs/yZbg+Dgka1DmX7ekmeccr2yTdKDFgPupYUyxVbTl
++a9ZLJysjFD7rgBv1ZclHonLp6Vbm+ZoTqvteo4ikAy6L9RtBWJ23XEK34PkP/+c5
++2vWZaOrnjSeBHbFce8cdJSxqWpP+eSCI5I9XbDrYFIsQ/gqKgtzDKy2ihJ2Y8STL
++yO4hyFPFjxc+Gg4/P2PpmT5CY2ty44M0BWs+JGW96CJPrrplf2lmQUQJj5LZY66X
++Z/4C9L7ZYtKZ+bs5SvU46yWugAvQZX22Xm9xLXWyVXRdx3bj+3M3fDnF9di/zdbh
++CgLx7oWPNrXc7FCajnn9AoIBAQD5FMYwRpw9NWT9WDxQwx+cSI4Icbd88ByTW63S
++LzeRwZA0J9/SfwO+aBRupzc9GkGXCiZcGMw3AGsCtig8yFlw8E5KnzN7KlftDMnM
++9NUxxzlR8VwKyLnZfG7sDTl057ZlUujnqhmt/F8F7dIy7FVO1dE/8nngA+FYTCOG
++UZdGjwyBDlDM0JJdUWGY3xslutcpCDN5mzSTKjy9drMvImAshRawxRF6WBpn7vr2
++nC6vciqfx1Mzx1vyk0Jm0ilaydDdLMADjt/iL4Nkr0BEs4k+UzQiKDwp8gu7abQ1
++eBfxd9Iar4htQa2I1Ewl6P01G/q+ZYwgHhJ9RVn4AxQXefILAoIBAQDvCouORdQX
++C8wsyp7MwXlF/3NQeNN5/+B2mhbxrBOf7PmMCXLnkRWcjwJtzypWFqJ0sqai/2+0
++bqbMcjX5maT8stT2shl3zXe/Ejt2e3TBYpc1tyuses8Kb5BMU8hu6tTd3G2CMXpD
++dT6DVemJZCTtwj9aBNIxSizvlgMolJnCpzhPnlfHSI6E+g3m/LTTo3HwbjMSw/Uq
++irgjOpI2wSBB6LZPSgjvfcYPRyWUk16L4A5uSX0cADnovDFLa5/h0wJvN/OoCSQg
++rLCXG5E18EyL5Wc58BCY1ZvxmjG3lQtgPxYu2Jwc36R/y/JKlxW5suER5ZNpbbD4
++uOyTt2VxMQ2bAoIBAQC5+MzRFqdo/AjfL5Y5JrbfVTzXCTDa09xCGd16ZU60QTWN
+++4ed/r+o1sUKqUcRFB2MzEM/2DQBjQpZB/CbEWvWa1XJWXxypXbowveZU+QqOnmN
++uQvj8WLyA3o+PNF9e9QvauwCrHpn8VpxbtPWuaYoKnUFreFZZQxHhPGxRBIS2JOZ
++eDrT8ZaWnkCkh1AZp5smQ71LOprSlmKrg4jd1GjCVMxQR5N5KXbtyv0OTCZ/UFqK
++2aRBsMPyJgkaBChkZPLRcKwc+/wlQRx1fHQb14DNTApMxoXFO7eOwqmOkpAt9iyl
++SBIwoS0UUI5ab88+bBmXNvKcuFdNuQ4nowTJUn9pAoIBADMNkILBXSvS5DeIyuO2
++Sp1tkoZUV+5NfPY3sMDK3KIibaW/+t+EOBZo4L7tKQCb8vRzl21mmsfxfgRaPDbj
++3r3tv9g0b4YLxxBy52pFscj/soXRai17SS7UZwA2QK+XzgDYbDcLNC6mIsTQG4Gx
++dsWk3/zs3KuUSQaehmwrWK+fIUK38c1pLK8v7LoxrLkqxlHwZ04RthHw8KTthH7X
++Pnl1J0LF8CSeOyfWLSuPUfkT0GEzptnNHpEbaHfQM6R6eaGhVJPF6AZme4y6YYgg
++m2ihhSt1n0XVEWpHYWjxFy3mK2mz75unFC4LM+NEY2p2zuUQoCw7NjnY3QYrfCnx
++rRMCggEAXeXsMSLFjjyuoL7iKbAxo52HD/P0fBoy58LyRcwfNVr0lvYan4pYEx+o
++KijIh9K16PqXZXKMA9v003B+ulmF8bJ7SddCZ5NGvnFhUTDe4DdTKgp2RuwQ3Bsc
++3skPIDbhVETyOLCtys34USHrq8U/0DlGY3eLRfxw9GnbKxSBGa/KEu/qQLPNUo50
++7xHZDg7GKeC3kqNJeqKM9rkp0VzIGkEnaD9127LeNDmERDfftxJzFoC/THvUBLfU
++6Sus2ZYwRE8VFvKC30Q45t/c54X3IuhYvAuiCuTmyfE4ruyzyOwKzhUkeeLq1APX
++g0veFbyfzlJ0q8qzD/iffqqIa2ZSmQ==
++-----END PRIVATE KEY-----
+diff --git a/qtbase/tests/auto/other/qaccessibilitylinux/tst_qaccessibilitylinux.cpp b/qtbase/tests/auto/other/qaccessibilitylinux/tst_qaccessibilitylinux.cpp
+index 7ba3715e13..752aa122f6 100644
+--- a/qtbase/tests/auto/other/qaccessibilitylinux/tst_qaccessibilitylinux.cpp
++++ b/qtbase/tests/auto/other/qaccessibilitylinux/tst_qaccessibilitylinux.cpp
+@@ -179,6 +179,7 @@ void tst_QAccessibilityLinux::initTestCase()
+ QVERIFY(!address.isEmpty());
+
+ m_window = new AccessibleTestWindow();
++ m_window->setObjectName("mainWindow"_L1);
+ m_window->show();
+
+ QVERIFY(QTest::qWaitForWindowExposed(m_window));
+@@ -236,8 +237,11 @@ bool hasState(QDBusInterface *interface, AtspiStateType state)
+ void tst_QAccessibilityLinux::testLabel()
+ {
+ QLabel *l = new QLabel(m_window);
++ l->setObjectName("theObjectName"_L1);
+ l->setText("Hello A11y");
+ m_window->addWidget(l);
++ auto a11yEmpty = new QLabel(m_window);
++ m_window->addWidget(l);
+
+ // Application
+ QCOMPARE(getParent(mainWindow), QLatin1String(ATSPI_DBUS_PATH_ROOT));
+@@ -249,6 +253,8 @@ void tst_QAccessibilityLinux::testLabel()
+ QCOMPARE(getChildren(labelInterface).count(), 0);
+ QCOMPARE(labelInterface->call(QDBus::Block, "GetRoleName").arguments().first().toString(), QLatin1String("label"));
+ QCOMPARE(labelInterface->call(QDBus::Block, "GetRole").arguments().first().toUInt(), 29u);
++ QCOMPARE(labelInterface->call(QDBus::Block, "GetAccessibleId").arguments().first().toString(),
++ QLatin1String("mainWindow.theObjectName"));
+ QCOMPARE(getParent(labelInterface), mainWindow->path());
+ QVERIFY(!hasState(labelInterface, ATSPI_STATE_EDITABLE));
+ QVERIFY(hasState(labelInterface, ATSPI_STATE_READ_ONLY));
+@@ -256,7 +262,12 @@ void tst_QAccessibilityLinux::testLabel()
+ l->setText("New text");
+ QCOMPARE(labelInterface->property("Name").toString(), l->text());
+
++ auto *a11yEmptyInterface = getInterface(children.at(1), "org.a11y.atspi.Accessible");
++ QCOMPARE(a11yEmptyInterface->call(QDBus::Block, "GetAccessibleId").arguments().first().toString(),
++ QLatin1String("mainWindow.QLabel"));
++
+ m_window->clearChildren();
++ delete a11yEmptyInterface;
+ delete labelInterface;
+ }
+
+diff --git a/qtbase/tests/auto/sql/kernel/qsqlquery/tst_qsqlquery.cpp b/qtbase/tests/auto/sql/kernel/qsqlquery/tst_qsqlquery.cpp
+index 76df61c892..6d6d65b791 100644
+--- a/qtbase/tests/auto/sql/kernel/qsqlquery/tst_qsqlquery.cpp
++++ b/qtbase/tests/auto/sql/kernel/qsqlquery/tst_qsqlquery.cpp
+@@ -1,6 +1,6 @@
+ /****************************************************************************
+ **
+-** Copyright (C) 2016 The Qt Company Ltd.
++** Copyright (C) 2022 The Qt Company Ltd.
+ ** Contact: https://www.qt.io/licensing/
+ **
+ ** This file is part of the test suite of the Qt Toolkit.
+@@ -68,6 +68,8 @@ private slots:
+ void query_exec();
+ void execErrorRecovery_data() { generic_data(); }
+ void execErrorRecovery();
++ void prematureExec_data() { generic_data(); }
++ void prematureExec();
+ void first_data() { generic_data(); }
+ void first();
+ void next_data() { generic_data(); }
+@@ -2770,6 +2772,35 @@ void tst_QSqlQuery::execErrorRecovery()
+ QVERIFY_SQL( q, exec() );
+ }
+
++void tst_QSqlQuery::prematureExec()
++{
++ QFETCH(QString, dbName);
++ // We only want the engine name, for addDatabase():
++ int cut = dbName.indexOf(QChar('@'));
++ if (cut < 0)
++ QSKIP("Failed to parse database type out of name");
++ dbName.truncate(cut);
++ cut = dbName.indexOf(QChar('_'));
++ if (cut >= 0)
++ dbName = dbName.mid(cut + 1);
++
++ auto db = QSqlDatabase::addDatabase(dbName);
++ QSqlQuery q(db);
++
++ QTest::ignoreMessage(QtWarningMsg,
++ "QSqlDatabasePrivate::removeDatabase: connection "
++ "'qt_sql_default_connection' is still in use, all "
++ "queries will cease to work.");
++ QTest::ignoreMessage(QtWarningMsg,
++ "QSqlDatabasePrivate::addDatabase: duplicate connection name "
++ "'qt_sql_default_connection', old connection removed.");
++ auto otherDb = QSqlDatabase::addDatabase(dbName);
++
++ QTest::ignoreMessage(QtWarningMsg, "QSqlQuery::exec: called before driver has been set up");
++ // QTBUG-100037: shouldn't crash !
++ QVERIFY(!q.exec("select stuff from TheVoid"));
++}
++
+ void tst_QSqlQuery::lastInsertId()
+ {
+ QFETCH( QString, dbName );
+diff --git a/qtbase/tests/auto/testlib/qabstractitemmodeltester/tst_qabstractitemmodeltester.cpp b/qtbase/tests/auto/testlib/qabstractitemmodeltester/tst_qabstractitemmodeltester.cpp
+index 4aa3f8d60b..d2050a61aa 100644
+--- a/qtbase/tests/auto/testlib/qabstractitemmodeltester/tst_qabstractitemmodeltester.cpp
++++ b/qtbase/tests/auto/testlib/qabstractitemmodeltester/tst_qabstractitemmodeltester.cpp
+@@ -115,6 +115,10 @@ void tst_QAbstractItemModelTester::standardItemModelZeroColumns()
+ // QTBUG-92886
+ model.insertRows(0, 5);
+ model.removeRows(1, 2);
++
++ const QModelIndex parentIndex = model.index(0, 0);
++ model.insertRows(0, 5, parentIndex);
++ model.removeRows(1, 2, parentIndex);
+ }
+
+ void tst_QAbstractItemModelTester::testInsertThroughProxy()
+diff --git a/qtbase/tests/auto/tools/moc/allmocs_baseline_in.json b/qtbase/tests/auto/tools/moc/allmocs_baseline_in.json
+index 12a4a22a19..ce518e78fb 100644
+--- a/qtbase/tests/auto/tools/moc/allmocs_baseline_in.json
++++ b/qtbase/tests/auto/tools/moc/allmocs_baseline_in.json
+@@ -668,50 +668,6 @@
+ "inputFile": "task192552.h",
+ "outputRevision": 67
+ },
+- {
+- "classes": [
+- {
+- "className": "InlineSlotsWithThrowDeclaration",
+- "object": true,
+- "qualifiedClassName": "InlineSlotsWithThrowDeclaration",
+- "slots": [
+- {
+- "access": "public",
+- "name": "a",
+- "returnType": "void"
+- },
+- {
+- "access": "public",
+- "name": "b",
+- "returnType": "void"
+- },
+- {
+- "access": "public",
+- "name": "c",
+- "returnType": "void"
+- },
+- {
+- "access": "public",
+- "name": "d",
+- "returnType": "void"
+- },
+- {
+- "access": "public",
+- "name": "e",
+- "returnType": "void"
+- }
+- ],
+- "superClasses": [
+- {
+- "access": "public",
+- "name": "QObject"
+- }
+- ]
+- }
+- ],
+- "inputFile": "task189996.h",
+- "outputRevision": 67
+- },
+ {
+ "classes": [
+ {
+diff --git a/qtbase/tests/auto/tools/moc/moc.pro b/qtbase/tests/auto/tools/moc/moc.pro
+index c324b3a8cd..4aceb78dc0 100644
+--- a/qtbase/tests/auto/tools/moc/moc.pro
++++ b/qtbase/tests/auto/tools/moc/moc.pro
+@@ -15,7 +15,7 @@ cross_compile: DEFINES += MOC_CROSS_COMPILED
+ HEADERS += using-namespaces.h no-keywords.h task87883.h c-comments.h backslash-newlines.h oldstyle-casts.h \
+ slots-with-void-template.h qinvokable.h namespaced-flags.h trigraphs.h \
+ escapes-in-string-literals.h cstyle-enums.h qprivateslots.h gadgetwithnoenums.h \
+- dir-in-include-path.h single_function_keyword.h task192552.h task189996.h \
++ dir-in-include-path.h single_function_keyword.h task192552.h \
+ task234909.h task240368.h pure-virtual-signals.h cxx11-enums.h \
+ cxx11-final-classes.h \
+ cxx11-explicit-override-control.h \
+diff --git a/qtbase/tests/auto/tools/moc/task189996.h b/qtbase/tests/auto/tools/moc/task189996.h
+deleted file mode 100644
+index f94a051b3a..0000000000
+--- a/qtbase/tests/auto/tools/moc/task189996.h
++++ /dev/null
+@@ -1,47 +0,0 @@
+-/****************************************************************************
+-**
+-** Copyright (C) 2016 The Qt Company Ltd.
+-** Contact: https://www.qt.io/licensing/
+-**
+-** This file is part of the test suite of the Qt Toolkit.
+-**
+-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+-** Commercial License Usage
+-** Licensees holding valid commercial Qt licenses may use this file in
+-** accordance with the commercial license agreement provided with the
+-** Software or, alternatively, in accordance with the terms contained in
+-** a written agreement between you and The Qt Company. For licensing terms
+-** and conditions see https://www.qt.io/terms-conditions. For further
+-** information use the contact form at https://www.qt.io/contact-us.
+-**
+-** GNU General Public License Usage
+-** Alternatively, this file may be used under the terms of the GNU
+-** General Public License version 3 as published by the Free Software
+-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+-** included in the packaging of this file. Please review the following
+-** information to ensure the GNU General Public License requirements will
+-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+-**
+-** $QT_END_LICENSE$
+-**
+-****************************************************************************/
+-// inline functions can have throw declarations
+-
+-#ifndef TASK189996_H
+-#define TASK189996_H
+-
+-#include <QObject>
+-
+-class InlineSlotsWithThrowDeclaration : public QObject
+-{
+- Q_OBJECT
+-
+-public slots:
+- void a() throw() { }
+- void b() const throw() { }
+- void c() throw();
+- void d() throw(int) { }
+- void e() const throw(int,double) { }
+-};
+-
+-#endif
+diff --git a/qtbase/tests/auto/tools/moc/tst_moc.cpp b/qtbase/tests/auto/tools/moc/tst_moc.cpp
+index c716aead21..15dd9e41e5 100644
+--- a/qtbase/tests/auto/tools/moc/tst_moc.cpp
++++ b/qtbase/tests/auto/tools/moc/tst_moc.cpp
+@@ -631,7 +631,6 @@ public:
+ private slots:
+ void initTestCase();
+
+- void slotWithException() throw(MyStruct);
+ void dontStripNamespaces();
+ void oldStyleCasts();
+ void warnOnExtraSignalSlotQualifiaction();
+@@ -673,7 +672,6 @@ private slots:
+ void templateGtGt();
+ void qprivateslots();
+ void qprivateproperties();
+- void inlineSlotsWithThrowDeclaration();
+ void warnOnPropertyWithoutREAD();
+ void constructors();
+ void typenameWithUnsigned();
+@@ -784,12 +782,6 @@ void tst_Moc::initTestCase()
+ #endif
+ }
+
+-void tst_Moc::slotWithException() throw(MyStruct)
+-{
+- // be happy
+- QVERIFY(true);
+-}
+-
+ void tst_Moc::dontStripNamespaces()
+ {
+ Sender sender;
+@@ -824,7 +816,7 @@ void tst_Moc::oldStyleCasts()
+
+ QStringList args;
+ args << "-c" << "-x" << "c++" << "-Wold-style-cast" << "-I" << "."
+- << "-I" << qtIncludePath << "-o" << "/dev/null" << "-fPIC" << "-std=c++11" << "-";
++ << "-I" << qtIncludePath << "-o" << "/dev/null" << "-fPIC" << "-std=c++1z" << "-";
+ proc.start("gcc", args);
+ QVERIFY(proc.waitForStarted());
+ proc.write(mocOut);
+@@ -894,7 +886,7 @@ void tst_Moc::inputFileNameWithDotsButNoExtension()
+
+ QStringList args;
+ args << "-c" << "-x" << "c++" << "-I" << ".."
+- << "-I" << qtIncludePath << "-o" << "/dev/null" << "-fPIC" << "-std=c++11" << "-";
++ << "-I" << qtIncludePath << "-o" << "/dev/null" << "-fPIC" << "-std=c++1z" << "-";
+ proc.start("gcc", args);
+ QVERIFY(proc.waitForStarted());
+ proc.write(mocOut);
+@@ -1174,7 +1166,7 @@ void tst_Moc::ignoreOptionClashes()
+ QStringList gccArgs;
+ gccArgs << "-c" << "-x" << "c++" << "-I" << ".."
+ << "-I" << qtIncludePath << "-I" << includeDir << "-o" << "/dev/null"
+- << "-fPIC" << "-std=c++11" << "-";
++ << "-fPIC" << "-std=c++1z" << "-";
+ proc.start("gcc", gccArgs);
+ QVERIFY(proc.waitForStarted());
+ proc.write(mocOut);
+@@ -1593,21 +1585,6 @@ void tst_Moc::qprivateproperties()
+
+ }
+
+-#include "task189996.h"
+-
+-void InlineSlotsWithThrowDeclaration::c() throw() {}
+-
+-void tst_Moc::inlineSlotsWithThrowDeclaration()
+-{
+- InlineSlotsWithThrowDeclaration tst;
+- const QMetaObject *mobj = tst.metaObject();
+- QVERIFY(mobj->indexOfSlot("a()") != -1);
+- QVERIFY(mobj->indexOfSlot("b()") != -1);
+- QVERIFY(mobj->indexOfSlot("c()") != -1);
+- QVERIFY(mobj->indexOfSlot("d()") != -1);
+- QVERIFY(mobj->indexOfSlot("e()") != -1);
+-}
+-
+ void tst_Moc::warnOnPropertyWithoutREAD()
+ {
+ #ifdef MOC_CROSS_COMPILED
+@@ -1869,7 +1846,7 @@ void tst_Moc::notifyError()
+
+ QStringList args;
+ args << "-c" << "-x" << "c++" << "-I" << "."
+- << "-I" << qtIncludePath << "-o" << "/dev/null" << "-fPIC" << "-std=c++11" << "-";
++ << "-I" << qtIncludePath << "-o" << "/dev/null" << "-fPIC" << "-std=c++1z" << "-";
+ proc.start("gcc", args);
+ QVERIFY(proc.waitForStarted());
+ proc.write(mocOut);
+diff --git a/qtbase/tests/auto/widgets/itemviews/qheaderview/tst_qheaderview.cpp b/qtbase/tests/auto/widgets/itemviews/qheaderview/tst_qheaderview.cpp
+index c355ee9665..88c09de8e0 100644
+--- a/qtbase/tests/auto/widgets/itemviews/qheaderview/tst_qheaderview.cpp
++++ b/qtbase/tests/auto/widgets/itemviews/qheaderview/tst_qheaderview.cpp
+@@ -251,6 +251,7 @@ private slots:
+ void testResetCachedSizeHint();
+ void statusTips();
+ void testRemovingColumnsViaLayoutChanged();
++ void testModelMovingColumns();
+
+ protected:
+ void setupTestData(bool use_reset_model = false);
+@@ -360,6 +361,12 @@ public:
+ endRemoveColumns();
+ }
+
++ void moveColumn(int from, int to)
++ {
++ beginMoveColumns(QModelIndex(), from, from, QModelIndex(), to);
++ endMoveColumns();
++ }
++
+ void cleanup()
+ {
+ emit layoutAboutToBeChanged();
+@@ -3627,5 +3634,18 @@ void tst_QHeaderView::testRemovingColumnsViaLayoutChanged()
+ // The main point of this test is that the section-size restoring code didn't go out of bounds.
+ }
+
++void tst_QHeaderView::testModelMovingColumns()
++{
++ QtTestModel model(10, 10);
++ QHeaderView hv(Qt::Horizontal);
++ hv.setModel(&model);
++ hv.resizeSections(QHeaderView::ResizeToContents);
++ hv.show();
++
++ QPersistentModelIndex index3 = model.index(0, 3);
++ model.moveColumn(3, 1);
++ QCOMPARE(index3.column(), 1);
++}
++
+ QTEST_MAIN(tst_QHeaderView)
+ #include "tst_qheaderview.moc"
+diff --git a/qtbase/tests/auto/widgets/itemviews/qtableview/tst_qtableview.cpp b/qtbase/tests/auto/widgets/itemviews/qtableview/tst_qtableview.cpp
+index 761357b252..06bb706074 100644
+--- a/qtbase/tests/auto/widgets/itemviews/qtableview/tst_qtableview.cpp
++++ b/qtbase/tests/auto/widgets/itemviews/qtableview/tst_qtableview.cpp
+@@ -397,6 +397,7 @@ private slots:
+ void checkHeaderMinSize();
+
+ void resizeToContents();
++ void resizeToContentsSpans();
+
+ void tabFocus();
+ void bigModel();
+@@ -3721,6 +3722,70 @@ void tst_QTableView::resizeToContents()
+
+ }
+
++
++class SpanModel : public QAbstractTableModel
++{
++public:
++ SpanModel(bool sectionsMoved)
++ : _sectionsMoved(sectionsMoved)
++ {}
++ int columnCount(const QModelIndex & = {}) const override { return 2; }
++ int rowCount(const QModelIndex & = {}) const override { return 1; }
++ QVariant data(const QModelIndex &idx, int role = Qt::DisplayRole) const override
++ {
++ if (role != Qt::DisplayRole)
++ return QVariant();
++ const int col = _sectionsMoved ? 1 - idx.column() : idx.column();
++ if (col == 0)
++ return "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.";
++ return QVariant();
++ }
++private:
++ bool _sectionsMoved;
++};
++
++
++void tst_QTableView::resizeToContentsSpans()
++{
++ SpanModel model1(false);
++ SpanModel model2(true);
++ QTableView view1, view2, view3;
++ view1.setModel(&model1);
++ view2.setModel(&model2);
++ view2.horizontalHeader()->moveSection(0, 1);
++ view3.setModel(&model1);
++
++ view1.setSpan(0, 0, 1, 2);
++ view2.setSpan(0, 1, 1, 2);
++ view1.show();
++ view2.show();
++ view3.show();
++ QVERIFY(QTest::qWaitForWindowExposed(&view1));
++ QVERIFY(QTest::qWaitForWindowExposed(&view2));
++ QVERIFY(QTest::qWaitForWindowExposed(&view3));
++ view1.setColumnWidth(0, 100);
++ view1.setColumnWidth(1, 100);
++ view2.setColumnWidth(0, 100);
++ view2.setColumnWidth(1, 100);
++ view3.setColumnWidth(0, 200);
++
++ view1.resizeRowToContents(0);
++ view2.resizeRowToContents(0);
++ view3.resizeRowToContents(0);
++ QCOMPARE(view1.rowHeight(0), view3.rowHeight(0));
++ QCOMPARE(view2.rowHeight(0), view3.rowHeight(0));
++
++ view3.resizeColumnToContents(0);
++ view3.resizeRowToContents(0);
++ // height should be only 1 text line for easy testing
++ view1.setRowHeight(0, view3.verticalHeader()->sectionSize(0));
++ view2.setRowHeight(0, view3.verticalHeader()->sectionSize(0));
++ view1.resizeColumnToContents(0);
++ view2.resizeColumnToContents(1);
++ QCOMPARE(view1.columnWidth(0), view3.columnWidth(0) - view1.columnWidth(1));
++ QCOMPARE(view2.columnWidth(0), view3.columnWidth(0) - view2.columnWidth(1));
++}
++
+ QT_BEGIN_NAMESPACE
+ extern bool Q_WIDGETS_EXPORT qt_tab_all_widgets(); // qapplication.cpp
+ QT_END_NAMESPACE
+diff --git a/qtbase/tests/auto/widgets/kernel/qapplication/tst_qapplication.cpp b/qtbase/tests/auto/widgets/kernel/qapplication/tst_qapplication.cpp
+index a3b8ef78d8..4955cebd5d 100644
+--- a/qtbase/tests/auto/widgets/kernel/qapplication/tst_qapplication.cpp
++++ b/qtbase/tests/auto/widgets/kernel/qapplication/tst_qapplication.cpp
+@@ -1498,7 +1498,7 @@ void tst_QApplication::desktopSettingsAware()
+ environment += QLatin1String("QT_MAC_DISABLE_FOREGROUND_APPLICATION_TRANSFORM=1");
+ testProcess.setEnvironment(environment);
+ #endif
+- testProcess.start("desktopsettingsaware_helper");
++ testProcess.start("./desktopsettingsaware_helper");
+ QVERIFY2(testProcess.waitForStarted(),
+ qPrintable(QString::fromLatin1("Cannot start 'desktopsettingsaware_helper': %1").arg(testProcess.errorString())));
+ QVERIFY(testProcess.waitForFinished(10000));
+@@ -2452,7 +2452,7 @@ void tst_QApplication::qtbug_12673()
+ #if QT_CONFIG(process)
+ QProcess testProcess;
+ QStringList arguments;
+- testProcess.start("modal_helper", arguments);
++ testProcess.start("./modal_helper", arguments);
+ QVERIFY2(testProcess.waitForStarted(),
+ qPrintable(QString::fromLatin1("Cannot start 'modal_helper': %1").arg(testProcess.errorString())));
+ QVERIFY(testProcess.waitForFinished(20000));
+diff --git a/qtbase/tests/auto/widgets/widgets/qabstractbutton/tst_qabstractbutton.cpp b/qtbase/tests/auto/widgets/widgets/qabstractbutton/tst_qabstractbutton.cpp
+index eb108a40de..dca5528c1b 100644
+--- a/qtbase/tests/auto/widgets/widgets/qabstractbutton/tst_qabstractbutton.cpp
++++ b/qtbase/tests/auto/widgets/widgets/qabstractbutton/tst_qabstractbutton.cpp
+@@ -41,6 +41,7 @@
+
+ #include <private/qguiapplication_p.h>
+ #include <qpa/qplatformintegration.h>
++#include <qpa/qplatformtheme.h>
+
+ class tst_QAbstractButton : public QObject
+ {
+@@ -76,6 +77,8 @@ private slots:
+ void keyNavigation();
+ #endif
+
++ void buttonPressKeys();
++
+ protected slots:
+ void onClicked();
+ void onToggled( bool on );
+@@ -269,7 +272,13 @@ void tst_QAbstractButton::setAutoRepeat()
+ QCOMPARE(press_count, click_count);
+ QVERIFY(click_count > 1);
+ break;
+- case 4:
++ case 4: {
++ const auto buttonPressKeys = QGuiApplicationPrivate::platformTheme()
++ ->themeHint(QPlatformTheme::ButtonPressKeys)
++ .value<QList<Qt::Key>>();
++ if (buttonPressKeys.contains(Qt::Key_Enter)) {
++ QSKIP("platform theme has Key_Enter in ButtonPressKeys");
++ }
+ // check that pressing ENTER has no effect when autorepeat is false
+ testWidget->setDown( false );
+ testWidget->setAutoRepeat( false );
+@@ -286,7 +295,14 @@ void tst_QAbstractButton::setAutoRepeat()
+
+ QVERIFY( click_count == 0 );
+ break;
+- case 5:
++ }
++ case 5: {
++ const auto buttonPressKeys = QGuiApplicationPrivate::platformTheme()
++ ->themeHint(QPlatformTheme::ButtonPressKeys)
++ .value<QList<Qt::Key>>();
++ if (buttonPressKeys.contains(Qt::Key_Enter)) {
++ QSKIP("platform theme has Key_Enter in ButtonPressKeys");
++ }
+ // check that pressing ENTER has no effect when autorepeat is true
+ testWidget->setDown( false );
+ testWidget->setAutoRepeat( true );
+@@ -304,6 +320,7 @@ void tst_QAbstractButton::setAutoRepeat()
+
+ QVERIFY( click_count == 0 );
+ break;
++ }
+ case 6:
+ // verify autorepeat is off by default.
+ MyButton tmp( 0);
+@@ -651,5 +668,16 @@ void tst_QAbstractButton::keyNavigation()
+ }
+ #endif
+
++void tst_QAbstractButton::buttonPressKeys()
++{
++ const auto buttonPressKeys = QGuiApplicationPrivate::platformTheme()
++ ->themeHint(QPlatformTheme::ButtonPressKeys)
++ .value<QList<Qt::Key>>();
++ for (int i = 0; i < buttonPressKeys.length(); ++i) {
++ QTest::keyClick(testWidget, buttonPressKeys[i]);
++ QCOMPARE(click_count, i + 1);
++ }
++}
++
+ QTEST_MAIN(tst_QAbstractButton)
+ #include "tst_qabstractbutton.moc"
+diff --git a/qtbase/tests/auto/widgets/widgets/qcombobox/tst_qcombobox.cpp b/qtbase/tests/auto/widgets/widgets/qcombobox/tst_qcombobox.cpp
+index 32437050f5..46b5af6d63 100644
+--- a/qtbase/tests/auto/widgets/widgets/qcombobox/tst_qcombobox.cpp
++++ b/qtbase/tests/auto/widgets/widgets/qcombobox/tst_qcombobox.cpp
+@@ -168,6 +168,7 @@ private slots:
+ void checkMenuItemPosWhenStyleSheetIsSet();
+ void checkEmbeddedLineEditWhenStyleSheetIsSet();
+ void propagateStyleChanges();
++ void buttonPressKeys();
+
+ private:
+ PlatformInputContext m_platformInputContext;
+@@ -1682,6 +1683,16 @@ void tst_QComboBox::setModel()
+ QCOMPARE(box.rootModelIndex(), rootModelIndex);
+ box.setModel(box.model());
+ QCOMPARE(box.rootModelIndex(), rootModelIndex);
++
++ // check that setting the same model as the completer's doesn't crash
++ QCompleter *completer = new QCompleter(&box);
++ box.setEditable(true);
++ box.setCompleter(completer);
++ auto *listModel = new QStringListModel({ "one", "two" }, completer);
++ completer->setModel(listModel);
++ QCOMPARE(listModel->rowCount(), 2); // make sure it wasn't deleted
++ box.setModel(listModel);
++ QCOMPARE(listModel->rowCount(), 2); // make sure it wasn't deleted
+ }
+
+ void tst_QComboBox::setCustomModelAndView()
+@@ -3632,5 +3643,24 @@ void tst_QComboBox::propagateStyleChanges()
+ QVERIFY(frameStyle.inquired);
+ }
+
++void tst_QComboBox::buttonPressKeys()
++{
++ QComboBox comboBox;
++ comboBox.setEditable(false);
++ comboBox.addItem(QString::number(1));
++ comboBox.addItem(QString::number(2));
++ const auto buttonPressKeys = QGuiApplicationPrivate::platformTheme()
++ ->themeHint(QPlatformTheme::ButtonPressKeys)
++ .value<QList<Qt::Key>>();
++ for (int i = 0; i < buttonPressKeys.length(); ++i) {
++ QTest::keyClick(&comboBox, buttonPressKeys[i]);
++ // On some platforms, a window will not be immediately visible,
++ // but take some event-loop iterations to complete.
++ // Using QTRY_VERIFY to deal with that.
++ QTRY_VERIFY(comboBox.view()->isVisible());
++ comboBox.hidePopup();
++ }
++}
++
+ QTEST_MAIN(tst_QComboBox)
+ #include "tst_qcombobox.moc"
+diff --git a/qtbase/tests/auto/widgets/widgets/qcommandlinkbutton/qcommandlinkbutton.pro b/qtbase/tests/auto/widgets/widgets/qcommandlinkbutton/qcommandlinkbutton.pro
+index be3cfcd104..c228fdfcca 100644
+--- a/qtbase/tests/auto/widgets/widgets/qcommandlinkbutton/qcommandlinkbutton.pro
++++ b/qtbase/tests/auto/widgets/widgets/qcommandlinkbutton/qcommandlinkbutton.pro
+@@ -1,6 +1,6 @@
+ CONFIG += testcase
+ TARGET = tst_qcommandlinkbutton
+-QT += widgets testlib
++QT += widgets testlib gui-private
+ SOURCES += tst_qcommandlinkbutton.cpp
+
+
+diff --git a/qtbase/tests/auto/widgets/widgets/qcommandlinkbutton/tst_qcommandlinkbutton.cpp b/qtbase/tests/auto/widgets/widgets/qcommandlinkbutton/tst_qcommandlinkbutton.cpp
+index 0044d33c66..4cf06296e4 100644
+--- a/qtbase/tests/auto/widgets/widgets/qcommandlinkbutton/tst_qcommandlinkbutton.cpp
++++ b/qtbase/tests/auto/widgets/widgets/qcommandlinkbutton/tst_qcommandlinkbutton.cpp
+@@ -40,6 +40,9 @@
+ #include <QGridLayout>
+ #include <QPainter>
+
++#include <private/qguiapplication_p.h>
++#include <qpa/qplatformtheme.h>
++
+ class tst_QCommandLinkButton : public QObject
+ {
+ Q_OBJECT
+@@ -223,6 +226,13 @@ void tst_QCommandLinkButton::setAutoRepeat()
+ // check that pressing ENTER has no effect
+ resetCounters();
+ testWidget->setDown( false );
++ // Skip after reset if ButtonPressKeys has Key_Enter
++ const auto buttonPressKeys = QGuiApplicationPrivate::platformTheme()
++ ->themeHint(QPlatformTheme::ButtonPressKeys)
++ .value<QList<Qt::Key>>();
++ if (buttonPressKeys.contains(Qt::Key_Enter)) {
++ return;
++ }
+ testWidget->setAutoRepeat( false );
+ QTest::keyPress( testWidget, Qt::Key_Enter );
+
+@@ -255,6 +265,14 @@ void tst_QCommandLinkButton::pressed()
+ QCOMPARE( press_count, (uint)1 );
+ QCOMPARE( release_count, (uint)1 );
+
++ // Skip if ButtonPressKeys has Key_Enter
++ const auto buttonPressKeys = QGuiApplicationPrivate::platformTheme()
++ ->themeHint(QPlatformTheme::ButtonPressKeys)
++ .value<QList<Qt::Key>>();
++ if (buttonPressKeys.contains(Qt::Key_Enter)) {
++ return;
++ }
++
+ QTest::keyPress( testWidget,Qt::Key_Enter );
+ QCOMPARE( press_count, (uint)1 );
+ QCOMPARE( release_count, (uint)1 );
+diff --git a/qtbase/tests/auto/widgets/widgets/qgroupbox/qgroupbox.pro b/qtbase/tests/auto/widgets/widgets/qgroupbox/qgroupbox.pro
+index 4a5e76ff65..a235fa1fac 100644
+--- a/qtbase/tests/auto/widgets/widgets/qgroupbox/qgroupbox.pro
++++ b/qtbase/tests/auto/widgets/widgets/qgroupbox/qgroupbox.pro
+@@ -1,6 +1,6 @@
+ CONFIG += testcase
+ TARGET = tst_qgroupbox
+-QT += widgets testlib
++QT += widgets testlib gui-private
+ SOURCES += tst_qgroupbox.cpp
+
+
+diff --git a/qtbase/tests/auto/widgets/widgets/qgroupbox/tst_qgroupbox.cpp b/qtbase/tests/auto/widgets/widgets/qgroupbox/tst_qgroupbox.cpp
+index 4fb5d262ca..d8d7562b73 100644
+--- a/qtbase/tests/auto/widgets/widgets/qgroupbox/tst_qgroupbox.cpp
++++ b/qtbase/tests/auto/widgets/widgets/qgroupbox/tst_qgroupbox.cpp
+@@ -35,6 +35,9 @@
+ #include <QRadioButton>
+ #include <QDialog>
+
++#include <private/qguiapplication_p.h>
++#include <qpa/qplatformtheme.h>
++
+ #include "qgroupbox.h"
+
+ class tst_QGroupBox : public QObject
+@@ -69,6 +72,7 @@ private slots:
+ void propagateFocus();
+ void task_QTBUG_19170_ignoreMouseReleaseEvent();
+ void task_QTBUG_15519_propagateMouseEvents();
++ void buttonPressKeys();
+
+ private:
+ bool checked;
+@@ -610,6 +614,20 @@ void tst_QGroupBox::task_QTBUG_15519_propagateMouseEvents()
+ QCOMPARE(parent.mouseMoved, true);
+ }
+
++void tst_QGroupBox::buttonPressKeys()
++{
++ QGroupBox groupBox;
++ groupBox.setCheckable(true);
++ QSignalSpy clickedSpy(&groupBox, &QGroupBox::clicked);
++ const auto buttonPressKeys = QGuiApplicationPrivate::platformTheme()
++ ->themeHint(QPlatformTheme::ButtonPressKeys)
++ .value<QList<Qt::Key>>();
++ for (int i = 0; i < buttonPressKeys.length(); ++i) {
++ QTest::keyClick(&groupBox, buttonPressKeys[i]);
++ QCOMPARE(clickedSpy.length(), i + 1);
++ }
++}
++
+ void tst_QGroupBox::sendMouseMoveEvent(QWidget *widget, const QPoint &localPos)
+ {
+ // Send a MouseMove event without actually moving the pointer
+diff --git a/qtbase/tests/auto/widgets/widgets/qpushbutton/qpushbutton.pro b/qtbase/tests/auto/widgets/widgets/qpushbutton/qpushbutton.pro
+index 353ad06ca2..e55f6148f2 100644
+--- a/qtbase/tests/auto/widgets/widgets/qpushbutton/qpushbutton.pro
++++ b/qtbase/tests/auto/widgets/widgets/qpushbutton/qpushbutton.pro
+@@ -1,6 +1,6 @@
+ CONFIG += testcase
+ TARGET = tst_qpushbutton
+-QT += widgets testlib
++QT += widgets testlib gui-private
+ SOURCES += tst_qpushbutton.cpp
+
+
+diff --git a/qtbase/tests/auto/widgets/widgets/qpushbutton/tst_qpushbutton.cpp b/qtbase/tests/auto/widgets/widgets/qpushbutton/tst_qpushbutton.cpp
+index e818514a79..4043e9326a 100644
+--- a/qtbase/tests/auto/widgets/widgets/qpushbutton/tst_qpushbutton.cpp
++++ b/qtbase/tests/auto/widgets/widgets/qpushbutton/tst_qpushbutton.cpp
+@@ -41,6 +41,9 @@
+ #include <QStyleFactory>
+ #include <QTabWidget>
+
++#include <private/qguiapplication_p.h>
++#include <qpa/qplatformtheme.h>
++
+ class tst_QPushButton : public QObject
+ {
+ Q_OBJECT
+@@ -212,6 +215,13 @@ void tst_QPushButton::autoRepeat()
+ // check that pressing ENTER has no effect
+ resetCounters();
+ testWidget->setDown( false );
++ // Skip after reset if ButtonPressKeys has Key_Enter
++ const auto buttonPressKeys = QGuiApplicationPrivate::platformTheme()
++ ->themeHint(QPlatformTheme::ButtonPressKeys)
++ .value<QList<Qt::Key>>();
++ if (buttonPressKeys.contains(Qt::Key_Enter)) {
++ return;
++ }
+ testWidget->setAutoRepeat( false );
+ QTest::keyPress( testWidget, Qt::Key_Enter );
+
+@@ -247,6 +257,14 @@ void tst_QPushButton::pressed()
+ QCOMPARE( press_count, (uint)1 );
+ QCOMPARE( release_count, (uint)1 );
+
++ // Skip if ButtonPressKeys has Key_Enter
++ const auto buttonPressKeys = QGuiApplicationPrivate::platformTheme()
++ ->themeHint(QPlatformTheme::ButtonPressKeys)
++ .value<QList<Qt::Key>>();
++ if (buttonPressKeys.contains(Qt::Key_Enter)) {
++ return;
++ }
++
+ QTest::keyPress( testWidget,Qt::Key_Enter );
+ QCOMPARE( press_count, (uint)1 );
+ QCOMPARE( release_count, (uint)1 );
+diff --git a/qtbase/tests/manual/rhi/cubemap_render/buildshader.bat b/qtbase/tests/manual/rhi/cubemap_render/buildshader.bat
+old mode 100755
+new mode 100644
+Submodule qtconnectivity e957d481..056294c0:
+diff --git a/qtconnectivity/src/bluetooth/bluez/hcimanager.cpp b/qtconnectivity/src/bluetooth/bluez/hcimanager.cpp
+index e2635fae..a8b8e3b9 100644
+--- a/qtconnectivity/src/bluetooth/bluez/hcimanager.cpp
++++ b/qtconnectivity/src/bluetooth/bluez/hcimanager.cpp
+@@ -563,9 +563,11 @@ void HciManager::handleHciAclPacket(const quint8 *data, int size)
+
+ void HciManager::handleLeMetaEvent(const quint8 *data)
+ {
+- // Spec v4.2, Vol 2, part E, 7.7.65ff
++ // Spec v5.3, Vol 4, part E, 7.7.65.*
+ switch (*data) {
+- case 0x1: {
++ case 0x1: // HCI_LE_Connection_Complete
++ case 0xA: // HCI_LE_Enhanced_Connection_Complete
++ {
+ const quint16 handle = bt_get_le16(data + 2);
+ emit connectionComplete(handle);
+ break;
+diff --git a/qtconnectivity/src/bluetooth/qbluetoothservicediscoveryagent_bluez.cpp b/qtconnectivity/src/bluetooth/qbluetoothservicediscoveryagent_bluez.cpp
+index 6a93143b..4a18cfc7 100644
+--- a/qtconnectivity/src/bluetooth/qbluetoothservicediscoveryagent_bluez.cpp
++++ b/qtconnectivity/src/bluetooth/qbluetoothservicediscoveryagent_bluez.cpp
+@@ -320,7 +320,10 @@ void QBluetoothServiceDiscoveryAgentPrivate::_q_finishSdpScan(QBluetoothServiceD
+ for (const QBluetoothUuid &id : serviceClassUuids) {
+ if (id.minimumSize() == 16) {
+ serviceInfo.setServiceUuid(id);
+- serviceInfo.setServiceName(QBluetoothServiceDiscoveryAgent::tr("Custom Service"));
++ if (serviceInfo.serviceName().isEmpty()) {
++ serviceInfo.setServiceName(
++ QBluetoothServiceDiscoveryAgent::tr("Custom Service"));
++ }
+ QBluetoothServiceInfo::Sequence modSeq =
+ serviceInfo.attribute(QBluetoothServiceInfo::ServiceClassIds).value<QBluetoothServiceInfo::Sequence>();
+ modSeq.removeOne(QVariant::fromValue(id));
+@@ -334,8 +337,10 @@ void QBluetoothServiceDiscoveryAgentPrivate::_q_finishSdpScan(QBluetoothServiceD
+ qCDebug(QT_BT_BLUEZ) << "Discovered services" << discoveredDevices.at(0).address().toString()
+ << serviceInfo.serviceName() << serviceInfo.serviceUuid()
+ << ">>>" << serviceInfo.serviceClassUuids();
+-
+- emit q->serviceDiscovered(serviceInfo);
++ // Use queued connection to allow us finish the service looping; the application
++ // might call stop() when it has detected the service-of-interest.
++ QMetaObject::invokeMethod(q, "serviceDiscovered", Qt::QueuedConnection,
++ Q_ARG(QBluetoothServiceInfo, serviceInfo));
+ }
+ }
+ }
+diff --git a/qtconnectivity/src/bluetooth/qbluetoothsocket.cpp b/qtconnectivity/src/bluetooth/qbluetoothsocket.cpp
+index e4d85447..aadd4755 100644
+--- a/qtconnectivity/src/bluetooth/qbluetoothsocket.cpp
++++ b/qtconnectivity/src/bluetooth/qbluetoothsocket.cpp
+@@ -593,7 +593,7 @@ void QBluetoothSocket::setSocketState(QBluetoothSocket::SocketState state)
+ bool QBluetoothSocket::canReadLine() const
+ {
+ Q_D(const QBluetoothSocketBase);
+- return d->canReadLine();
++ return d->canReadLine() || QIODevice::canReadLine();
+ }
+
+ /*!
+diff --git a/qtconnectivity/src/bluetooth/qbluetoothsocket_bluezdbus.cpp b/qtconnectivity/src/bluetooth/qbluetoothsocket_bluezdbus.cpp
+index 084aa958..d6aa17a7 100644
+--- a/qtconnectivity/src/bluetooth/qbluetoothsocket_bluezdbus.cpp
++++ b/qtconnectivity/src/bluetooth/qbluetoothsocket_bluezdbus.cpp
+@@ -284,6 +284,10 @@ void QBluetoothSocketPrivateBluezDBus::connectToService(
+ return;
+ }
+
++ if (service.socketProtocol() != QBluetoothServiceInfo::Protocol::UnknownProtocol)
++ socketType = service.socketProtocol();
++ qCDebug(QT_BT_BLUEZ) << "Socket protocol used:" << socketType;
++
+ connectToService(service.device().address(), targetService, openMode);
+ }
+
+diff --git a/qtconnectivity/tests/auto/qbluetoothsocket/tst_qbluetoothsocket.cpp b/qtconnectivity/tests/auto/qbluetoothsocket/tst_qbluetoothsocket.cpp
+index 05bc1a0f..a7b5ef1f 100644
+--- a/qtconnectivity/tests/auto/qbluetoothsocket/tst_qbluetoothsocket.cpp
++++ b/qtconnectivity/tests/auto/qbluetoothsocket/tst_qbluetoothsocket.cpp
+@@ -142,7 +142,7 @@ void tst_QBluetoothSocket::initTestCase()
+ qDebug() << "Starting discovery";
+
+ sda->setUuidFilter(QBluetoothUuid(QString(TEST_SERVICE_UUID)));
+- sda->start(QBluetoothServiceDiscoveryAgent::MinimalDiscovery);
++ sda->start(QBluetoothServiceDiscoveryAgent::FullDiscovery);
+
+ for (int connectTime = MaxConnectTime; !done_discovery && connectTime > 0; connectTime -= 1000)
+ QTest::qWait(1000);
+Submodule qtdeclarative f5701f0d..8defe7bf:
+diff --git a/qtdeclarative/src/qml/common/qqmljsfixedpoolarray_p.h b/qtdeclarative/src/qml/common/qqmljsfixedpoolarray_p.h
+index b65b994d6c..15a8cd6878 100644
+--- a/qtdeclarative/src/qml/common/qqmljsfixedpoolarray_p.h
++++ b/qtdeclarative/src/qml/common/qqmljsfixedpoolarray_p.h
+@@ -86,7 +86,7 @@ public:
+ if (QTypeInfo<T>::isComplex) {
+ for (int i = 0; i < count; ++i)
+ new (data + i) T(vector.at(i));
+- } else {
++ } else if (count) {
+ memcpy(data, static_cast<const void*>(vector.constData()), count * sizeof(T));
+ }
+ }
+diff --git a/qtdeclarative/src/qml/jsruntime/qv4qobjectwrapper.cpp b/qtdeclarative/src/qml/jsruntime/qv4qobjectwrapper.cpp
+index e57cdd8278..94613598af 100644
+--- a/qtdeclarative/src/qml/jsruntime/qv4qobjectwrapper.cpp
++++ b/qtdeclarative/src/qml/jsruntime/qv4qobjectwrapper.cpp
+@@ -1145,8 +1145,7 @@ void Heap::QObjectWrapper::markObjects(Heap::Base *that, QV4::MarkStack *markSta
+ void QObjectWrapper::destroyObject(bool lastCall)
+ {
+ Heap::QObjectWrapper *h = d();
+- if (!h->internalClass)
+- return; // destroyObject already got called
++ Q_ASSERT(h->internalClass);
+
+ if (h->object()) {
+ QQmlData *ddata = QQmlData::get(h->object(), false);
+@@ -1176,7 +1175,7 @@ void QObjectWrapper::destroyObject(bool lastCall)
+ }
+ }
+
+- h->~Data();
++ h->destroy();
+ }
+
+
+diff --git a/qtdeclarative/src/qml/memory/qv4mm.cpp b/qtdeclarative/src/qml/memory/qv4mm.cpp
+index 06caf04e5a..da149a67c4 100644
+--- a/qtdeclarative/src/qml/memory/qv4mm.cpp
++++ b/qtdeclarative/src/qml/memory/qv4mm.cpp
+@@ -981,7 +981,7 @@ void MemoryManager::sweep(bool lastSweep, ClassDestroyStatsCallback classCountPt
+
+ if (MultiplyWrappedQObjectMap *multiplyWrappedQObjects = engine->m_multiplyWrappedQObjects) {
+ for (MultiplyWrappedQObjectMap::Iterator it = multiplyWrappedQObjects->begin(); it != multiplyWrappedQObjects->end();) {
+- if (!it.value().isNullOrUndefined())
++ if (it.value().isNullOrUndefined())
+ it = multiplyWrappedQObjects->erase(it);
+ else
+ ++it;
+diff --git a/qtdeclarative/src/qmlmodels/qqmldelegatemodel.cpp b/qtdeclarative/src/qmlmodels/qqmldelegatemodel.cpp
+index 2079a8ed04..a577cb2351 100644
+--- a/qtdeclarative/src/qmlmodels/qqmldelegatemodel.cpp
++++ b/qtdeclarative/src/qmlmodels/qqmldelegatemodel.cpp
+@@ -389,6 +389,12 @@ void QQmlDelegateModelPrivate::connectToAbstractItemModel()
+ q, QQmlDelegateModel, SLOT(_q_rowsRemoved(QModelIndex,int,int)));
+ qmlobject_connect(aim, QAbstractItemModel, SIGNAL(rowsAboutToBeRemoved(QModelIndex,int,int)),
+ q, QQmlDelegateModel, SLOT(_q_rowsAboutToBeRemoved(QModelIndex,int,int)));
++ qmlobject_connect(aim, QAbstractItemModel, SIGNAL(columnsInserted(QModelIndex,int,int)),
++ q, QQmlDelegateModel, SLOT(_q_columnsInserted(QModelIndex,int,int)));
++ qmlobject_connect(aim, QAbstractItemModel, SIGNAL(columnsRemoved(QModelIndex,int,int)),
++ q, QQmlDelegateModel, SLOT(_q_columnsRemoved(QModelIndex,int,int)));
++ qmlobject_connect(aim, QAbstractItemModel, SIGNAL(columnsMoved(QModelIndex,int,int,QModelIndex,int)),
++ q, QQmlDelegateModel, SLOT(_q_columnsMoved(QModelIndex,int,int,QModelIndex,int)));
+ qmlobject_connect(aim, QAbstractItemModel, SIGNAL(dataChanged(QModelIndex,QModelIndex,QVector<int>)),
+ q, QQmlDelegateModel, SLOT(_q_dataChanged(QModelIndex,QModelIndex,QVector<int>)));
+ qmlobject_connect(aim, QAbstractItemModel, SIGNAL(rowsMoved(QModelIndex,int,int,QModelIndex,int)),
+@@ -413,6 +419,12 @@ void QQmlDelegateModelPrivate::disconnectFromAbstractItemModel()
+ q, SLOT(_q_rowsAboutToBeRemoved(QModelIndex,int,int)));
+ QObject::disconnect(aim, SIGNAL(rowsRemoved(QModelIndex,int,int)),
+ q, SLOT(_q_rowsRemoved(QModelIndex,int,int)));
++ QObject::disconnect(aim, SIGNAL(columnsInserted(QModelIndex,int,int)), q,
++ SLOT(_q_columnsInserted(QModelIndex,int,int)));
++ QObject::disconnect(aim, SIGNAL(columnsRemoved(QModelIndex,int,int)), q,
++ SLOT(_q_columnsRemoved(QModelIndex,int,int)));
++ QObject::disconnect(aim, SIGNAL(columnsMoved(QModelIndex,int,int,QModelIndex,int)), q,
++ SLOT(_q_columnsMoved(QModelIndex,int,int,QModelIndex,int)));
+ QObject::disconnect(aim, SIGNAL(dataChanged(QModelIndex,QModelIndex,QVector<int>)),
+ q, SLOT(_q_dataChanged(QModelIndex,QModelIndex,QVector<int>)));
+ QObject::disconnect(aim, SIGNAL(rowsMoved(QModelIndex,int,int,QModelIndex,int)),
+@@ -1973,6 +1985,38 @@ void QQmlDelegateModel::_q_rowsMoved(
+ }
+ }
+
++void QQmlDelegateModel::_q_columnsInserted(const QModelIndex &parent, int begin, int end)
++{
++ Q_D(QQmlDelegateModel);
++ Q_UNUSED(end);
++ if (parent == d->m_adaptorModel.rootIndex && begin == 0) {
++ // mark all items as changed
++ _q_itemsChanged(0, d->m_count, QVector<int>());
++ }
++}
++
++void QQmlDelegateModel::_q_columnsRemoved(const QModelIndex &parent, int begin, int end)
++{
++ Q_D(QQmlDelegateModel);
++ Q_UNUSED(end);
++ if (parent == d->m_adaptorModel.rootIndex && begin == 0) {
++ // mark all items as changed
++ _q_itemsChanged(0, d->m_count, QVector<int>());
++ }
++}
++
++void QQmlDelegateModel::_q_columnsMoved(const QModelIndex &parent, int start, int end,
++ const QModelIndex &destination, int column)
++{
++ Q_D(QQmlDelegateModel);
++ Q_UNUSED(end);
++ if ((parent == d->m_adaptorModel.rootIndex && start == 0)
++ || (destination == d->m_adaptorModel.rootIndex && column == 0)) {
++ // mark all items as changed
++ _q_itemsChanged(0, d->m_count, QVector<int>());
++ }
++}
++
+ void QQmlDelegateModel::_q_dataChanged(const QModelIndex &begin, const QModelIndex &end, const QVector<int> &roles)
+ {
+ Q_D(QQmlDelegateModel);
+diff --git a/qtdeclarative/src/qmlmodels/qqmldelegatemodel_p.h b/qtdeclarative/src/qmlmodels/qqmldelegatemodel_p.h
+index 8aab4badca..d140bfbaaf 100644
+--- a/qtdeclarative/src/qmlmodels/qqmldelegatemodel_p.h
++++ b/qtdeclarative/src/qmlmodels/qqmldelegatemodel_p.h
+@@ -152,6 +152,9 @@ private Q_SLOTS:
+ void _q_itemsMoved(int from, int to, int count);
+ void _q_modelReset();
+ void _q_rowsInserted(const QModelIndex &,int,int);
++ void _q_columnsInserted(const QModelIndex &, int, int);
++ void _q_columnsRemoved(const QModelIndex &, int, int);
++ void _q_columnsMoved(const QModelIndex &, int, int, const QModelIndex &, int);
+ void _q_rowsAboutToBeRemoved(const QModelIndex &parent, int begin, int end);
+ void _q_rowsRemoved(const QModelIndex &,int,int);
+ void _q_rowsMoved(const QModelIndex &, int, int, const QModelIndex &, int);
+diff --git a/qtdeclarative/src/quick/accessible/qaccessiblequickitem.cpp b/qtdeclarative/src/quick/accessible/qaccessiblequickitem.cpp
+index 85719fdc80..78e2ab302c 100644
+--- a/qtdeclarative/src/quick/accessible/qaccessiblequickitem.cpp
++++ b/qtdeclarative/src/quick/accessible/qaccessiblequickitem.cpp
+@@ -46,6 +46,7 @@
+ #include "QtQuick/private/qquicktextinput_p.h"
+ #include "QtQuick/private/qquickaccessibleattached_p.h"
+ #include "QtQuick/qquicktextdocument.h"
++#include "QtQuick/qquickrendercontrol.h"
+ QT_BEGIN_NAMESPACE
+
+ #if QT_CONFIG(accessibility)
+@@ -57,7 +58,19 @@ QAccessibleQuickItem::QAccessibleQuickItem(QQuickItem *item)
+
+ QWindow *QAccessibleQuickItem::window() const
+ {
+- return item()->window();
++ QQuickWindow *window = item()->window();
++
++ // For QQuickWidget the above window will be the offscreen QQuickWindow,
++ // which is not a part of the accessibility tree. Detect this case and
++ // return the window for the QQuickWidget instead.
++ if (window && !window->handle()) {
++ if (QQuickRenderControl *renderControl = QQuickWindowPrivate::get(window)->renderControl) {
++ if (QWindow *renderWindow = renderControl->renderWindow(nullptr))
++ return renderWindow;
++ }
++ }
++
++ return window;
+ }
+
+ int QAccessibleQuickItem::childCount() const
+@@ -113,19 +126,15 @@ QAccessibleInterface *QAccessibleQuickItem::childAt(int x, int y) const
+ QAccessibleInterface *QAccessibleQuickItem::parent() const
+ {
+ QQuickItem *parent = item()->parentItem();
+- QQuickWindow *window = item()->window();
+- QQuickItem *ci = window ? window->contentItem() : nullptr;
++ QQuickWindow *itemWindow = item()->window();
++ QQuickItem *ci = itemWindow ? itemWindow->contentItem() : nullptr;
+ while (parent && !QQuickItemPrivate::get(parent)->isAccessible && parent != ci)
+ parent = parent->parentItem();
+
+ if (parent) {
+ if (parent == ci) {
+- // Jump out to the scene widget if the parent is the root item.
+- // There are two root items, QQuickWindow::rootItem and
+- // QQuickView::declarativeRoot. The former is the true root item,
+- // but is not a part of the accessibility tree. Check if we hit
+- // it here and return an interface for the scene instead.
+- return QAccessible::queryAccessibleInterface(window);
++ // Jump out to the window if the parent is the root item
++ return QAccessible::queryAccessibleInterface(window());
+ } else {
+ while (parent && !parent->d_func()->isAccessible)
+ parent = parent->parentItem();
+@@ -188,7 +197,7 @@ QAccessible::State QAccessibleQuickItem::state() const
+ QRect viewRect_ = viewRect();
+ QRect itemRect = rect();
+
+- if (viewRect_.isNull() || itemRect.isNull() || !item()->window() || !item()->window()->isVisible() ||!item()->isVisible() || qFuzzyIsNull(item()->opacity()))
++ if (viewRect_.isNull() || itemRect.isNull() || !window() || !window()->isVisible() ||!item()->isVisible() || qFuzzyIsNull(item()->opacity()))
+ state.invisible = true;
+ if (!viewRect_.intersects(itemRect))
+ state.offscreen = true;
+@@ -201,6 +210,10 @@ QAccessible::State QAccessibleQuickItem::state() const
+ if (role() == QAccessible::EditableText)
+ if (auto ti = qobject_cast<QQuickTextInput *>(item()))
+ state.passwordEdit = ti->echoMode() != QQuickTextInput::Normal;
++ if (!item()->isEnabled()) {
++ state.focusable = false;
++ state.disabled = true;
++ }
+ return state;
+ }
+
+diff --git a/qtdeclarative/src/quick/accessible/qaccessiblequickview_p.h b/qtdeclarative/src/quick/accessible/qaccessiblequickview_p.h
+index 39ffcaf39c..8baa01330c 100644
+--- a/qtdeclarative/src/quick/accessible/qaccessiblequickview_p.h
++++ b/qtdeclarative/src/quick/accessible/qaccessiblequickview_p.h
+@@ -58,7 +58,7 @@ QT_BEGIN_NAMESPACE
+
+ #if QT_CONFIG(accessibility)
+
+-class QAccessibleQuickWindow : public QAccessibleObject
++class Q_QUICK_EXPORT QAccessibleQuickWindow : public QAccessibleObject
+ {
+ public:
+ QAccessibleQuickWindow(QQuickWindow *object);
+diff --git a/qtdeclarative/src/quick/items/qquickdrag.cpp b/qtdeclarative/src/quick/items/qquickdrag.cpp
+index 8321fcfeed..383078b3b9 100644
+--- a/qtdeclarative/src/quick/items/qquickdrag.cpp
++++ b/qtdeclarative/src/quick/items/qquickdrag.cpp
+@@ -481,7 +481,9 @@ void QQuickDragAttached::setKeys(const QStringList &keys)
+ \qmlattachedproperty stringlist QtQuick::Drag::mimeData
+ \since 5.2
+
+- This property holds a map of mimeData that is used during startDrag.
++ This property holds a map from mime type to data that is used during startDrag.
++ The mime data needs to be a \c string, or an \c ArrayBuffer with the data encoded
++ according to the mime type.
+ */
+
+ QVariantMap QQuickDragAttached::mimeData() const
+@@ -766,8 +768,12 @@ Qt::DropAction QQuickDragAttachedPrivate::startDrag(Qt::DropActions supportedAct
+ QDrag *drag = new QDrag(source ? source : q);
+ QMimeData *mimeData = new QMimeData();
+
+- for (auto it = externalMimeData.cbegin(), end = externalMimeData.cend(); it != end; ++it)
+- mimeData->setData(it.key(), it.value().toString().toUtf8());
++ for (auto it = externalMimeData.cbegin(), end = externalMimeData.cend(); it != end; ++it) {
++ if (static_cast<QMetaType::Type>(it.value().type()) == QMetaType::QByteArray)
++ mimeData->setData(it.key(), it.value().toByteArray());
++ else
++ mimeData->setData(it.key(), it.value().toString().toUtf8());
++ }
+
+ drag->setMimeData(mimeData);
+ if (pixmapLoader.isReady()) {
+diff --git a/qtdeclarative/src/quick/items/qquickitem.cpp b/qtdeclarative/src/quick/items/qquickitem.cpp
+index 75f1457816..dec0ae19ae 100644
+--- a/qtdeclarative/src/quick/items/qquickitem.cpp
++++ b/qtdeclarative/src/quick/items/qquickitem.cpp
+@@ -59,6 +59,7 @@
+ #include <QtCore/private/qnumeric_p.h>
+ #include <QtGui/qpa/qplatformtheme.h>
+ #include <QtCore/qloggingcategory.h>
++#include <QtCore/private/qduplicatetracker_p.h>
+
+ #include <private/qqmlglobal_p.h>
+ #include <private/qqmlengine_p.h>
+@@ -2326,6 +2327,7 @@ QQuickItem::QQuickItem(QQuickItemPrivate &dd, QQuickItem *parent)
+ QQuickItem::~QQuickItem()
+ {
+ Q_D(QQuickItem);
++ d->inDestructor = true;
+
+ if (d->windowRefCount > 1)
+ d->windowRefCount = 1; // Make sure window is set to null in next call to derefWindow().
+@@ -2526,6 +2528,7 @@ QQuickItem* QQuickItemPrivate::nextPrevItemInTabFocusChain(QQuickItem *item, boo
+ QQuickItem *current = item;
+ qCDebug(DBG_FOCUS) << "QQuickItemPrivate::nextPrevItemInTabFocusChain: startItem:" << startItem;
+ qCDebug(DBG_FOCUS) << "QQuickItemPrivate::nextPrevItemInTabFocusChain: firstFromItem:" << firstFromItem;
++ QDuplicateTracker<QQuickItem *> cycleDetector;
+ do {
+ qCDebug(DBG_FOCUS) << "QQuickItemPrivate::nextPrevItemInTabFocusChain: current:" << current;
+ qCDebug(DBG_FOCUS) << "QQuickItemPrivate::nextPrevItemInTabFocusChain: from:" << from;
+@@ -2592,7 +2595,10 @@ QQuickItem* QQuickItemPrivate::nextPrevItemInTabFocusChain(QQuickItem *item, boo
+ // traversed all of the chain (by compare the [current] item with [startItem])
+ // Since the [startItem] might be promoted to its parent if it is invisible,
+ // we still have to check [current] item with original start item
+- if ((current == startItem || current == originalStartItem) && from == firstFromItem) {
++ // We might also run into a cycle before we reach firstFromItem again
++ // but note that we have to ignore current if we are meant to skip it
++ if (((current == startItem || current == originalStartItem) && from == firstFromItem) ||
++ (!skip && cycleDetector.hasSeen(current))) {
+ // wrapped around, avoid endless loops
+ if (item == contentItem) {
+ qCDebug(DBG_FOCUS) << "QQuickItemPrivate::nextPrevItemInTabFocusChain: looped, return contentItem";
+@@ -2689,9 +2695,8 @@ void QQuickItem::setParentItem(QQuickItem *parentItem)
+
+ const bool wasVisible = isVisible();
+ op->removeChild(this);
+- if (wasVisible) {
++ if (wasVisible && !op->inDestructor)
+ emit oldParentItem->visibleChildrenChanged();
+- }
+ } else if (d->window) {
+ QQuickWindowPrivate::get(d->window)->parentlessItems.remove(this);
+ }
+@@ -2768,8 +2773,9 @@ void QQuickItem::setParentItem(QQuickItem *parentItem)
+
+ d->itemChange(ItemParentHasChanged, d->parentItem);
+
+- emit parentChanged(d->parentItem);
+- if (isVisible() && d->parentItem)
++ if (!d->inDestructor)
++ emit parentChanged(d->parentItem);
++ if (isVisible() && d->parentItem && !QQuickItemPrivate::get(d->parentItem)->inDestructor)
+ emit d->parentItem->visibleChildrenChanged();
+ }
+
+@@ -2965,7 +2971,8 @@ void QQuickItemPrivate::removeChild(QQuickItem *child)
+
+ itemChange(QQuickItem::ItemChildRemovedChange, child);
+
+- emit q->childrenChanged();
++ if (!inDestructor)
++ emit q->childrenChanged();
+ }
+
+ void QQuickItemPrivate::refWindow(QQuickWindow *c)
+@@ -3194,6 +3201,7 @@ QQuickItemPrivate::QQuickItemPrivate()
+ , touchEnabled(false)
+ #endif
+ , hasCursorHandler(false)
++ , inDestructor(false)
+ , dirtyAttributes(0)
+ , nextDirtyItem(nullptr)
+ , prevDirtyItem(nullptr)
+@@ -5120,6 +5128,13 @@ void QQuickItem::componentComplete()
+ d->addToDirtyList();
+ QQuickWindowPrivate::get(d->window)->dirtyItem(this);
+ }
++
++#if QT_CONFIG(accessibility)
++ if (d->isAccessible && d->effectiveVisible) {
++ QAccessibleEvent ev(this, QAccessible::ObjectShow);
++ QAccessible::updateAccessibility(&ev);
++ }
++#endif
+ }
+
+ QQuickStateGroup *QQuickItemPrivate::_states()
+@@ -6106,9 +6121,11 @@ bool QQuickItemPrivate::setEffectiveVisibleRecur(bool newEffectiveVisible)
+ QAccessible::updateAccessibility(&ev);
+ }
+ #endif
+- emit q->visibleChanged();
+- if (childVisibilityChanged)
+- emit q->visibleChildrenChanged();
++ if (!inDestructor) {
++ emit q->visibleChanged();
++ if (childVisibilityChanged)
++ emit q->visibleChildrenChanged();
++ }
+
+ return true; // effective visibility DID change
+ }
+@@ -6157,6 +6174,15 @@ void QQuickItemPrivate::setEffectiveEnableRecur(QQuickItem *scope, bool newEffec
+ }
+
+ itemChange(QQuickItem::ItemEnabledHasChanged, effectiveEnable);
++#if QT_CONFIG(accessibility)
++ if (isAccessible) {
++ QAccessible::State changedState;
++ changedState.disabled = true;
++ changedState.focusable = true;
++ QAccessibleStateChangeEvent ev(q, changedState);
++ QAccessible::updateAccessibility(&ev);
++ }
++#endif
+ emit q->enabledChanged();
+ }
+
+diff --git a/qtdeclarative/src/quick/items/qquickitem_p.h b/qtdeclarative/src/quick/items/qquickitem_p.h
+index 841d91bb40..ade8fb61f2 100644
+--- a/qtdeclarative/src/quick/items/qquickitem_p.h
++++ b/qtdeclarative/src/quick/items/qquickitem_p.h
+@@ -472,6 +472,7 @@ public:
+ bool replayingPressEvent:1;
+ bool touchEnabled:1;
+ bool hasCursorHandler:1;
++ quint32 inDestructor:1; // has entered ~QQuickItem
+
+ enum DirtyType {
+ TransformOrigin = 0x00000001,
+diff --git a/qtdeclarative/src/quick/items/qquickitemview.cpp b/qtdeclarative/src/quick/items/qquickitemview.cpp
+index 010a0152e1..f8ad168a17 100644
+--- a/qtdeclarative/src/quick/items/qquickitemview.cpp
++++ b/qtdeclarative/src/quick/items/qquickitemview.cpp
+@@ -1785,7 +1785,7 @@ void QQuickItemViewPrivate::refill(qreal from, qreal to)
+
+ do {
+ bufferPause.stop();
+- if (currentChanges.hasPendingChanges() || bufferedChanges.hasPendingChanges()) {
++ if (currentChanges.hasPendingChanges() || bufferedChanges.hasPendingChanges() || currentChanges.active) {
+ currentChanges.reset();
+ bufferedChanges.reset();
+ releaseVisibleItems(reusableFlag);
+diff --git a/qtdeclarative/src/quick/items/qquickmousearea_p_p.h b/qtdeclarative/src/quick/items/qquickmousearea_p_p.h
+index fba383e268..0d63618622 100644
+--- a/qtdeclarative/src/quick/items/qquickmousearea_p_p.h
++++ b/qtdeclarative/src/quick/items/qquickmousearea_p_p.h
+@@ -61,7 +61,6 @@ QT_BEGIN_NAMESPACE
+
+ class QQuickMouseEvent;
+ class QQuickMouseArea;
+-class QQuickPointerMask;
+ class QQuickMouseAreaPrivate : public QQuickItemPrivate
+ {
+ Q_DECLARE_PUBLIC(QQuickMouseArea)
+@@ -100,7 +99,6 @@ public:
+ #if QT_CONFIG(quick_draganddrop)
+ QQuickDrag *drag;
+ #endif
+- QPointer<QQuickPointerMask> mask;
+ QPointF startScene;
+ QPointF targetStartPos;
+ QPointF lastPos;
+diff --git a/qtdeclarative/src/quick/items/qquicktext.cpp b/qtdeclarative/src/quick/items/qquicktext.cpp
+index 6230186933..e823ca1095 100644
+--- a/qtdeclarative/src/quick/items/qquicktext.cpp
++++ b/qtdeclarative/src/quick/items/qquicktext.cpp
+@@ -2168,7 +2168,7 @@ void QQuickText::resetMaximumLineCount()
+ <img src="" align="top,middle,bottom" width="" height=""> - inline images
+ <ol type="">, <ul type=""> and <li> - ordered and unordered lists
+ <pre></pre> - preformatted
+- > < &
++ > < & " '
+ \endcode
+
+ \c Text.StyledText parser is strict, requiring tags to be correctly nested.
+diff --git a/qtdeclarative/src/quick/scenegraph/qsgrhidistancefieldglyphcache.cpp b/qtdeclarative/src/quick/scenegraph/qsgrhidistancefieldglyphcache.cpp
+index eb4db0f85e..2325a2665b 100644
+--- a/qtdeclarative/src/quick/scenegraph/qsgrhidistancefieldglyphcache.cpp
++++ b/qtdeclarative/src/quick/scenegraph/qsgrhidistancefieldglyphcache.cpp
+@@ -446,7 +446,7 @@ bool QSGRhiDistanceFieldGlyphCache::loadPregeneratedCache(const QRawFont &font)
+
+ const char *textureRecord = allocatorData;
+ for (int i = 0; i < textureCount; ++i, textureRecord += Qtdf::TextureRecordSize) {
+- if (textureRecord + Qtdf::TextureRecordSize > qtdfTableEnd) {
++ if (qtdfTableEnd - textureRecord < Qtdf::TextureRecordSize) {
+ qWarning("qtdf table too small in font '%s'.",
+ qPrintable(font.familyName()));
+ return false;
+@@ -462,7 +462,7 @@ bool QSGRhiDistanceFieldGlyphCache::loadPregeneratedCache(const QRawFont &font)
+
+ const char *glyphRecord = textureRecord;
+ for (quint32 i = 0; i < glyphCount; ++i, glyphRecord += Qtdf::GlyphRecordSize) {
+- if (glyphRecord + Qtdf::GlyphRecordSize > qtdfTableEnd) {
++ if (qtdfTableEnd - glyphRecord < Qtdf:: GlyphRecordSize) {
+ qWarning("qtdf table too small in font '%s'.",
+ qPrintable(font.familyName()));
+ return false;
+@@ -512,8 +512,8 @@ bool QSGRhiDistanceFieldGlyphCache::loadPregeneratedCache(const QRawFont &font)
+
+ int width = texInfo->allocatedArea.width();
+ int height = texInfo->allocatedArea.height();
+- qint64 size = width * height;
+- if (reinterpret_cast<const char *>(textureData + size) > qtdfTableEnd) {
++ qint64 size = qint64(width) * height;
++ if (qtdfTableEnd - reinterpret_cast<const char *>(textureData) < size) {
+ qWarning("qtdf table too small in font '%s'.",
+ qPrintable(font.familyName()));
+ return false;
+diff --git a/qtdeclarative/src/quick/util/qquickstyledtext.cpp b/qtdeclarative/src/quick/util/qquickstyledtext.cpp
+index d531fc9205..a25af90414 100644
+--- a/qtdeclarative/src/quick/util/qquickstyledtext.cpp
++++ b/qtdeclarative/src/quick/util/qquickstyledtext.cpp
+@@ -564,6 +564,8 @@ void QQuickStyledTextPrivate::parseEntity(const QChar *&ch, const QString &textI
+ textOut += QChar(60);
+ else if (entity == QLatin1String("amp"))
+ textOut += QChar(38);
++ else if (entity == QLatin1String("apos"))
++ textOut += QChar(39);
+ else if (entity == QLatin1String("quot"))
+ textOut += QChar(34);
+ else if (entity == QLatin1String("nbsp"))
+diff --git a/qtdeclarative/src/quickwidgets/qaccessiblequickwidget.cpp b/qtdeclarative/src/quickwidgets/qaccessiblequickwidget.cpp
+new file mode 100644
+index 0000000000..8a1c901880
+--- /dev/null
++++ b/qtdeclarative/src/quickwidgets/qaccessiblequickwidget.cpp
+@@ -0,0 +1,110 @@
++/****************************************************************************
++**
++** Copyright (C) 2021 The Qt Company Ltd.
++** Contact: https://www.qt.io/licensing/
++**
++** This file is part of the QtQuick module of the Qt Toolkit.
++**
++** $QT_BEGIN_LICENSE:LGPL$
++** Commercial License Usage
++** Licensees holding valid commercial Qt licenses may use this file in
++** accordance with the commercial license agreement provided with the
++** Software or, alternatively, in accordance with the terms contained in
++** a written agreement between you and The Qt Company. For licensing terms
++** and conditions see https://www.qt.io/terms-conditions. For further
++** information use the contact form at https://www.qt.io/contact-us.
++**
++** GNU Lesser General Public License Usage
++** Alternatively, this file may be used under the terms of the GNU Lesser
++** General Public License version 3 as published by the Free Software
++** Foundation and appearing in the file LICENSE.LGPL3 included in the
++** packaging of this file. Please review the following information to
++** ensure the GNU Lesser General Public License version 3 requirements
++** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
++**
++** GNU General Public License Usage
++** Alternatively, this file may be used under the terms of the GNU
++** General Public License version 2.0 or (at your option) the GNU General
++** Public license version 3 or any later version approved by the KDE Free
++** Qt Foundation. The licenses are as published by the Free Software
++** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
++** included in the packaging of this file. Please review the following
++** information to ensure the GNU General Public License requirements will
++** be met: https://www.gnu.org/licenses/gpl-2.0.html and
++** https://www.gnu.org/licenses/gpl-3.0.html.
++**
++** $QT_END_LICENSE$
++**
++****************************************************************************/
++
++#include "qaccessiblequickwidget_p.h"
++
++#include "qquickwidget_p.h"
++
++QT_BEGIN_NAMESPACE
++
++#if QT_CONFIG(accessibility)
++
++QAccessibleQuickWidget::QAccessibleQuickWidget(QQuickWidget* widget)
++: QAccessibleWidget(widget)
++, m_accessibleWindow(QQuickWidgetPrivate::get(widget)->offscreenWindow)
++{
++ // NOTE: m_accessibleWindow is a QAccessibleQuickWindow, and not a
++ // QAccessibleQuickWidgetOffscreenWindow (defined below). This means
++ // it will return the Quick item child interfaces, which is what's needed here
++ // (unlike QAccessibleQuickWidgetOffscreenWindow, which will report 0 children).
++}
++
++QAccessibleInterface *QAccessibleQuickWidget::child(int index) const
++{
++ return m_accessibleWindow.child(index);
++}
++
++int QAccessibleQuickWidget::childCount() const
++{
++ return m_accessibleWindow.childCount();
++}
++
++int QAccessibleQuickWidget::indexOfChild(const QAccessibleInterface *iface) const
++{
++ return m_accessibleWindow.indexOfChild(iface);
++}
++
++QAccessibleInterface *QAccessibleQuickWidget::childAt(int x, int y) const
++{
++ return m_accessibleWindow.childAt(x, y);
++}
++
++QAccessibleQuickWidgetOffscreenWindow::QAccessibleQuickWidgetOffscreenWindow(QQuickWindow *window)
++:QAccessibleQuickWindow(window)
++{
++
++}
++
++QAccessibleInterface *QAccessibleQuickWidgetOffscreenWindow::child(int index) const
++{
++ Q_UNUSED(index);
++ return nullptr;
++}
++
++int QAccessibleQuickWidgetOffscreenWindow::childCount() const
++{
++ return 0;
++}
++
++int QAccessibleQuickWidgetOffscreenWindow::indexOfChild(const QAccessibleInterface *iface) const
++{
++ Q_UNUSED(iface);
++ return -1;
++}
++
++QAccessibleInterface *QAccessibleQuickWidgetOffscreenWindow::QAccessibleQuickWidgetOffscreenWindow::childAt(int x, int y) const
++{
++ Q_UNUSED(x);
++ Q_UNUSED(y);
++ return nullptr;
++}
++
++#endif // accessibility
++
++QT_END_NAMESPACE
+diff --git a/qtdeclarative/src/quickwidgets/qaccessiblequickwidget_p.h b/qtdeclarative/src/quickwidgets/qaccessiblequickwidget_p.h
+new file mode 100644
+index 0000000000..7c2ab930e0
+--- /dev/null
++++ b/qtdeclarative/src/quickwidgets/qaccessiblequickwidget_p.h
+@@ -0,0 +1,95 @@
++/****************************************************************************
++**
++** Copyright (C) 2021 The Qt Company Ltd.
++** Contact: https://www.qt.io/licensing/
++**
++** This file is part of the QtQuick module of the Qt Toolkit.
++**
++** $QT_BEGIN_LICENSE:LGPL$
++** Commercial License Usage
++** Licensees holding valid commercial Qt licenses may use this file in
++** accordance with the commercial license agreement provided with the
++** Software or, alternatively, in accordance with the terms contained in
++** a written agreement between you and The Qt Company. For licensing terms
++** and conditions see https://www.qt.io/terms-conditions. For further
++** information use the contact form at https://www.qt.io/contact-us.
++**
++** GNU Lesser General Public License Usage
++** Alternatively, this file may be used under the terms of the GNU Lesser
++** General Public License version 3 as published by the Free Software
++** Foundation and appearing in the file LICENSE.LGPL3 included in the
++** packaging of this file. Please review the following information to
++** ensure the GNU Lesser General Public License version 3 requirements
++** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
++**
++** GNU General Public License Usage
++** Alternatively, this file may be used under the terms of the GNU
++** General Public License version 2.0 or (at your option) the GNU General
++** Public license version 3 or any later version approved by the KDE Free
++** Qt Foundation. The licenses are as published by the Free Software
++** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
++** included in the packaging of this file. Please review the following
++** information to ensure the GNU General Public License requirements will
++** be met: https://www.gnu.org/licenses/gpl-2.0.html and
++** https://www.gnu.org/licenses/gpl-3.0.html.
++**
++** $QT_END_LICENSE$
++**
++****************************************************************************/
++
++#ifndef QACCESSIBLEQUICKWIDGET_H
++#define QACCESSIBLEQUICKWIDGET_H
++
++//
++// W A R N I N G
++// -------------
++//
++// This file is not part of the Qt API. It exists purely as an
++// implementation detail. This header file may change from version to
++// version without notice, or even be removed.
++//
++// We mean it.
++//
++
++#include "qquickwidget.h"
++#include <QtWidgets/qaccessiblewidget.h>
++
++#include <private/qaccessiblequickview_p.h>
++
++QT_BEGIN_NAMESPACE
++
++#if QT_CONFIG(accessibility)
++
++// These classes implement the QQuickWiget accessibility switcharoo,
++// where the child items of the QQuickWidgetOffscreenWindow are reported
++// as child accessible interfaces of the QAccessibleQuickWidget.
++class QAccessibleQuickWidget: public QAccessibleWidget
++{
++public:
++ QAccessibleQuickWidget(QQuickWidget* widget);
++
++ QAccessibleInterface *child(int index) const override;
++ int childCount() const override;
++ int indexOfChild(const QAccessibleInterface *iface) const override;
++ QAccessibleInterface *childAt(int x, int y) const override;
++
++private:
++ QAccessibleQuickWindow m_accessibleWindow;
++ Q_DISABLE_COPY(QAccessibleQuickWidget)
++};
++
++class QAccessibleQuickWidgetOffscreenWindow: public QAccessibleQuickWindow
++{
++public:
++ QAccessibleQuickWidgetOffscreenWindow(QQuickWindow *window);
++ QAccessibleInterface *child(int index) const override;
++ int childCount() const override;
++ int indexOfChild(const QAccessibleInterface *iface) const override;
++ QAccessibleInterface *childAt(int x, int y) const override;
++};
++
++#endif // accessibility
++
++QT_END_NAMESPACE
++
++#endif
+diff --git a/qtdeclarative/src/quickwidgets/qaccessiblequickwidgetfactory.cpp b/qtdeclarative/src/quickwidgets/qaccessiblequickwidgetfactory.cpp
+new file mode 100644
+index 0000000000..7ba88a1769
+--- /dev/null
++++ b/qtdeclarative/src/quickwidgets/qaccessiblequickwidgetfactory.cpp
+@@ -0,0 +1,60 @@
++/****************************************************************************
++**
++** Copyright (C) 2021 The Qt Company Ltd.
++** Contact: https://www.qt.io/licensing/
++**
++** This file is part of the QtQuick module of the Qt Toolkit.
++**
++** $QT_BEGIN_LICENSE:LGPL$
++** Commercial License Usage
++** Licensees holding valid commercial Qt licenses may use this file in
++** accordance with the commercial license agreement provided with the
++** Software or, alternatively, in accordance with the terms contained in
++** a written agreement between you and The Qt Company. For licensing terms
++** and conditions see https://www.qt.io/terms-conditions. For further
++** information use the contact form at https://www.qt.io/contact-us.
++**
++** GNU Lesser General Public License Usage
++** Alternatively, this file may be used under the terms of the GNU Lesser
++** General Public License version 3 as published by the Free Software
++** Foundation and appearing in the file LICENSE.LGPL3 included in the
++** packaging of this file. Please review the following information to
++** ensure the GNU Lesser General Public License version 3 requirements
++** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
++**
++** GNU General Public License Usage
++** Alternatively, this file may be used under the terms of the GNU
++** General Public License version 2.0 or (at your option) the GNU General
++** Public license version 3 or any later version approved by the KDE Free
++** Qt Foundation. The licenses are as published by the Free Software
++** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
++** included in the packaging of this file. Please review the following
++** information to ensure the GNU General Public License requirements will
++** be met: https://www.gnu.org/licenses/gpl-2.0.html and
++** https://www.gnu.org/licenses/gpl-3.0.html.
++**
++** $QT_END_LICENSE$
++**
++****************************************************************************/
++
++#include "qaccessiblequickwidgetfactory_p.h"
++#include "qaccessiblequickwidget_p.h"
++
++QT_BEGIN_NAMESPACE
++
++#if QT_CONFIG(accessibility)
++
++QAccessibleInterface *qAccessibleQuickWidgetFactory(const QString &classname, QObject *object)
++{
++ if (classname == QLatin1String("QQuickWidget")) {
++ return new QAccessibleQuickWidget(qobject_cast<QQuickWidget *>(object));
++ } else if (classname == QLatin1String("QQuickWidgetOffscreenWindow")) {
++ return new QAccessibleQuickWidgetOffscreenWindow(qobject_cast<QQuickWindow *>(object));
++ }
++ return 0;
++}
++
++#endif // accessibility
++
++QT_END_NAMESPACE
++
+diff --git a/qtdeclarative/src/quickwidgets/qaccessiblequickwidgetfactory_p.h b/qtdeclarative/src/quickwidgets/qaccessiblequickwidgetfactory_p.h
+new file mode 100644
+index 0000000000..8c63b09f81
+--- /dev/null
++++ b/qtdeclarative/src/quickwidgets/qaccessiblequickwidgetfactory_p.h
+@@ -0,0 +1,66 @@
++/****************************************************************************
++**
++** Copyright (C) 2021 The Qt Company Ltd.
++** Contact: https://www.qt.io/licensing/
++**
++** This file is part of the QtQuick module of the Qt Toolkit.
++**
++** $QT_BEGIN_LICENSE:LGPL$
++** Commercial License Usage
++** Licensees holding valid commercial Qt licenses may use this file in
++** accordance with the commercial license agreement provided with the
++** Software or, alternatively, in accordance with the terms contained in
++** a written agreement between you and The Qt Company. For licensing terms
++** and conditions see https://www.qt.io/terms-conditions. For further
++** information use the contact form at https://www.qt.io/contact-us.
++**
++** GNU Lesser General Public License Usage
++** Alternatively, this file may be used under the terms of the GNU Lesser
++** General Public License version 3 as published by the Free Software
++** Foundation and appearing in the file LICENSE.LGPL3 included in the
++** packaging of this file. Please review the following information to
++** ensure the GNU Lesser General Public License version 3 requirements
++** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
++**
++** GNU General Public License Usage
++** Alternatively, this file may be used under the terms of the GNU
++** General Public License version 2.0 or (at your option) the GNU General
++** Public license version 3 or any later version approved by the KDE Free
++** Qt Foundation. The licenses are as published by the Free Software
++** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
++** included in the packaging of this file. Please review the following
++** information to ensure the GNU General Public License requirements will
++** be met: https://www.gnu.org/licenses/gpl-2.0.html and
++** https://www.gnu.org/licenses/gpl-3.0.html.
++**
++** $QT_END_LICENSE$
++**
++****************************************************************************/
++
++#include <QtGui/qaccessible.h>
++
++#ifndef QACCESSIBLEQUICKWIDGETFACTORY_H
++#define QACCESSIBLEQUICKWIDGETFACTORY_H
++
++//
++// W A R N I N G
++// -------------
++//
++// This file is not part of the Qt API. It exists purely as an
++// implementation detail. This header file may change from version to
++// version without notice, or even be removed.
++//
++// We mean it.
++//
++
++QT_BEGIN_NAMESPACE
++
++#if QT_CONFIG(accessibility)
++
++QAccessibleInterface *qAccessibleQuickWidgetFactory(const QString &classname, QObject *object);
++
++#endif
++
++QT_END_NAMESPACE
++
++#endif
+diff --git a/qtdeclarative/src/quickwidgets/qquickwidget.cpp b/qtdeclarative/src/quickwidgets/qquickwidget.cpp
+index 39780f8de3..9c97b43518 100644
+--- a/qtdeclarative/src/quickwidgets/qquickwidget.cpp
++++ b/qtdeclarative/src/quickwidgets/qquickwidget.cpp
+@@ -39,6 +39,7 @@
+
+ #include "qquickwidget.h"
+ #include "qquickwidget_p.h"
++#include "qaccessiblequickwidgetfactory_p.h"
+
+ #include "private/qquickwindow_p.h"
+ #include "private/qquickitem_p.h"
+@@ -75,9 +76,16 @@
+
+ QT_BEGIN_NAMESPACE
+
++QQuickWidgetOffscreenWindow::QQuickWidgetOffscreenWindow(QQuickWindowPrivate &dd, QQuickRenderControl *control)
++:QQuickWindow(dd, control)
++{
++ setTitle(QString::fromLatin1("Offscreen"));
++ setObjectName(QString::fromLatin1("QQuickOffScreenWindow"));
++}
++
+ // override setVisble to prevent accidental offscreen window being created
+ // by base class.
+-class QQuickOffcreenWindowPrivate: public QQuickWindowPrivate {
++class QQuickWidgetOffscreenWindowPrivate: public QQuickWindowPrivate {
+ public:
+ void setVisible(bool visible) override {
+ Q_Q(QWindow);
+@@ -105,9 +113,8 @@ void QQuickWidgetPrivate::init(QQmlEngine* e)
+ Q_Q(QQuickWidget);
+
+ renderControl = new QQuickWidgetRenderControl(q);
+- offscreenWindow = new QQuickWindow(*new QQuickOffcreenWindowPrivate(),renderControl);
+- offscreenWindow->setTitle(QString::fromLatin1("Offscreen"));
+- offscreenWindow->setObjectName(QString::fromLatin1("QQuickOffScreenWindow"));
++ offscreenWindow = new QQuickWidgetOffscreenWindow(*new QQuickWidgetOffscreenWindowPrivate(), renderControl);
++ offscreenWindow->setScreen(q->screen());
+ // Do not call create() on offscreenWindow.
+
+ // Check if the Software Adaptation is being used
+@@ -138,6 +145,10 @@ void QQuickWidgetPrivate::init(QQmlEngine* e)
+ QWidget::connect(offscreenWindow, &QQuickWindow::focusObjectChanged, q, &QQuickWidget::propagateFocusObjectChanged);
+ QObject::connect(renderControl, SIGNAL(renderRequested()), q, SLOT(triggerUpdate()));
+ QObject::connect(renderControl, SIGNAL(sceneChanged()), q, SLOT(triggerUpdate()));
++
++#if QT_CONFIG(accessibility)
++ QAccessible::installFactory(&qAccessibleQuickWidgetFactory);
++#endif
+ }
+
+ void QQuickWidgetPrivate::ensureEngine() const
+@@ -901,9 +912,7 @@ void QQuickWidgetPrivate::createContext()
+
+ context = new QOpenGLContext;
+ context->setFormat(offscreenWindow->requestedFormat());
+- const QWindow *win = q->window()->windowHandle();
+- if (win && win->screen())
+- context->setScreen(win->screen());
++ context->setScreen(q->screen());
+ QOpenGLContext *shareContext = qt_gl_global_share_context();
+ if (!shareContext)
+ shareContext = QWidgetPrivate::get(q->window())->shareContext();
+@@ -1520,19 +1529,16 @@ bool QQuickWidget::event(QEvent *e)
+ d->handleWindowChange();
+ break;
+
+- case QEvent::ScreenChangeInternal:
+- if (QWindow *window = this->window()->windowHandle()) {
+- QScreen *newScreen = window->screen();
+-
+- if (d->offscreenWindow)
+- d->offscreenWindow->setScreen(newScreen);
+- if (d->offscreenSurface)
+- d->offscreenSurface->setScreen(newScreen);
++ case QEvent::ScreenChangeInternal: {
++ QScreen *newScreen = screen();
++ if (d->offscreenWindow)
++ d->offscreenWindow->setScreen(newScreen);
++ if (d->offscreenSurface)
++ d->offscreenSurface->setScreen(newScreen);
+ #if QT_CONFIG(opengl)
+- if (d->context)
+- d->context->setScreen(newScreen);
++ if (d->context)
++ d->context->setScreen(newScreen);
+ #endif
+- }
+
+ if (d->useSoftwareRenderer
+ #if QT_CONFIG(opengl)
+@@ -1545,7 +1551,7 @@ bool QQuickWidget::event(QEvent *e)
+ d->render(true);
+ }
+ break;
+-
++ }
+ case QEvent::Show:
+ case QEvent::Move:
+ d->updatePosition();
+diff --git a/qtdeclarative/src/quickwidgets/qquickwidget_p.h b/qtdeclarative/src/quickwidgets/qquickwidget_p.h
+index 881f7f9220..1a946bcc71 100644
+--- a/qtdeclarative/src/quickwidgets/qquickwidget_p.h
++++ b/qtdeclarative/src/quickwidgets/qquickwidget_p.h
+@@ -148,6 +148,14 @@ public:
+ bool forceFullUpdate;
+ };
+
++class QQuickWidgetOffscreenWindow: public QQuickWindow
++{
++ Q_OBJECT
++
++public:
++ QQuickWidgetOffscreenWindow(QQuickWindowPrivate &dd, QQuickRenderControl *control);
++};
++
+ QT_END_NAMESPACE
+
+ #endif // QQuickWidget_P_H
+diff --git a/qtdeclarative/src/quickwidgets/quickwidgets.pro b/qtdeclarative/src/quickwidgets/quickwidgets.pro
+index 2438e577ae..85d156b8a3 100644
+--- a/qtdeclarative/src/quickwidgets/quickwidgets.pro
++++ b/qtdeclarative/src/quickwidgets/quickwidgets.pro
+@@ -7,9 +7,13 @@ DEFINES += QT_NO_URL_CAST_FROM_STRING QT_NO_INTEGER_EVENT_COORDINATES QT_NO_FO
+ HEADERS += \
+ qquickwidget.h \
+ qquickwidget_p.h \
+- qtquickwidgetsglobal.h
++ qtquickwidgetsglobal.h \
++ qaccessiblequickwidget_p.h \
++ qaccessiblequickwidgetfactory_p.h
+
+ SOURCES += \
+- qquickwidget.cpp
++ qquickwidget.cpp \
++ qaccessiblequickwidget.cpp \
++ qaccessiblequickwidgetfactory.cpp
+
+ load(qt_module)
+diff --git a/qtdeclarative/tests/auto/qml/qjsengine/tst_qjsengine.cpp b/qtdeclarative/tests/auto/qml/qjsengine/tst_qjsengine.cpp
+index 3b7d74df63..b75bf820d5 100644
+--- a/qtdeclarative/tests/auto/qml/qjsengine/tst_qjsengine.cpp
++++ b/qtdeclarative/tests/auto/qml/qjsengine/tst_qjsengine.cpp
+@@ -102,6 +102,7 @@ private slots:
+ void valueConversion_RegularExpression();
+ void castWithMultipleInheritance();
+ void collectGarbage();
++ void collectGarbageNestedWrappersTwoEngines();
+ void gcWithNestedDataStructure();
+ void stacktrace();
+ void numberParsing_data();
+@@ -1809,6 +1810,44 @@ void tst_QJSEngine::collectGarbage()
+ QVERIFY(ptr.isNull());
+ }
+
++class TestObjectContainer : public QObject
++{
++ Q_OBJECT
++ Q_PROPERTY(QObject *dummy MEMBER m_dummy CONSTANT)
++
++public:
++ TestObjectContainer() : m_dummy(new QObject(this)) {}
++
++private:
++ QObject *m_dummy;
++};
++
++void tst_QJSEngine::collectGarbageNestedWrappersTwoEngines()
++{
++ QJSEngine engine1;
++ QJSEngine engine2;
++
++ TestObjectContainer container;
++ QQmlEngine::setObjectOwnership(&container, QQmlEngine::CppOwnership);
++
++ engine1.globalObject().setProperty("foobar", engine1.newQObject(&container));
++ engine2.globalObject().setProperty("foobar", engine2.newQObject(&container));
++
++ engine1.evaluate("foobar.dummy.baz = 42");
++ engine2.evaluate("foobar.dummy.baz = 43");
++
++ QCOMPARE(engine1.evaluate("foobar.dummy.baz").toInt(), 42);
++ QCOMPARE(engine2.evaluate("foobar.dummy.baz").toInt(), 43);
++
++ engine1.collectGarbage();
++ engine2.collectGarbage();
++
++ // The GC should not collect dummy object wrappers neither in engine1 nor engine2, we
++ // verify that by checking whether the baz property still has its previous value.
++ QCOMPARE(engine1.evaluate("foobar.dummy.baz").toInt(), 42);
++ QCOMPARE(engine2.evaluate("foobar.dummy.baz").toInt(), 43);
++}
++
+ void tst_QJSEngine::gcWithNestedDataStructure()
+ {
+ // The GC must be able to traverse deeply nested objects, otherwise this
+diff --git a/qtdeclarative/tests/auto/qml/qqmldelegatemodel/data/redrawUponColumnChange.qml b/qtdeclarative/tests/auto/qml/qqmldelegatemodel/data/redrawUponColumnChange.qml
+new file mode 100644
+index 0000000000..206133bb39
+--- /dev/null
++++ b/qtdeclarative/tests/auto/qml/qqmldelegatemodel/data/redrawUponColumnChange.qml
+@@ -0,0 +1,11 @@
++import QtQuick 2.8
++
++ListView {
++ id: root
++ width: 200
++ height: 200
++
++ delegate: Text {
++ text: display
++ }
++}
+diff --git a/qtdeclarative/tests/auto/qml/qqmldelegatemodel/tst_qqmldelegatemodel.cpp b/qtdeclarative/tests/auto/qml/qqmldelegatemodel/tst_qqmldelegatemodel.cpp
+index 35f1e2c94d..1722447830 100644
+--- a/qtdeclarative/tests/auto/qml/qqmldelegatemodel/tst_qqmldelegatemodel.cpp
++++ b/qtdeclarative/tests/auto/qml/qqmldelegatemodel/tst_qqmldelegatemodel.cpp
+@@ -27,6 +27,8 @@
+ ****************************************************************************/
+
+ #include <QtTest/qtest.h>
++#include <QtCore/QConcatenateTablesProxyModel>
++#include <QtGui/QStandardItemModel>
+ #include <QtQml/qqmlcomponent.h>
+ #include <QtQmlModels/private/qqmldelegatemodel_p.h>
+ #include <QtQuick/qquickview.h>
+@@ -47,6 +49,7 @@ private slots:
+ void filterOnGroup_removeWhenCompleted();
+ void qtbug_86017();
+ void contextAccessedByHandler();
++ void redrawUponColumnChange();
+ };
+
+ class AbstractItemModel : public QAbstractItemModel
+@@ -186,6 +189,30 @@ void tst_QQmlDelegateModel::contextAccessedByHandler()
+ QVERIFY(root->property("works").toBool());
+ }
+
++void tst_QQmlDelegateModel::redrawUponColumnChange()
++{
++ QStandardItemModel m1;
++ m1.appendRow({
++ new QStandardItem("Banana"),
++ new QStandardItem("Coconut"),
++ });
++
++ QQuickView view(testFileUrl("redrawUponColumnChange.qml"));
++ QCOMPARE(view.status(), QQuickView::Ready);
++ view.show();
++ QQuickItem *root = view.rootObject();
++ root->setProperty("model", QVariant::fromValue<QObject *>(&m1));
++
++ QObject *item = root->property("currentItem").value<QObject *>();
++ QVERIFY(item);
++ QCOMPARE(item->property("text").toString(), "Banana");
++
++ QVERIFY(root);
++ m1.removeColumn(0);
++
++ QCOMPARE(item->property("text").toString(), "Coconut");
++}
++
+ QTEST_MAIN(tst_QQmlDelegateModel)
+
+ #include "tst_qqmldelegatemodel.moc"
+diff --git a/qtdeclarative/tests/auto/qml/qv4mm/tst_qv4mm.cpp b/qtdeclarative/tests/auto/qml/qv4mm/tst_qv4mm.cpp
+index 5d635aa63b..824fd89e5b 100644
+--- a/qtdeclarative/tests/auto/qml/qv4mm/tst_qv4mm.cpp
++++ b/qtdeclarative/tests/auto/qml/qv4mm/tst_qv4mm.cpp
+@@ -76,10 +76,10 @@ void tst_qv4mm::multiWrappedQObjects()
+ QCOMPARE(engine1.memoryManager->m_pendingFreedObjectWrapperValue.size(), 1);
+ QCOMPARE(engine2.memoryManager->m_pendingFreedObjectWrapperValue.size(), 0);
+
+- // Moves the additional WeakValue from m_multiplyWrappedQObjects to
+- // m_pendingFreedObjectWrapperValue. It's still alive after all.
++ // The additional WeakValue from m_multiplyWrappedQObjects hasn't been moved
++ // to m_pendingFreedObjectWrapperValue yet. It's still alive after all.
+ engine1.memoryManager->runGC();
+- QCOMPARE(engine1.memoryManager->m_pendingFreedObjectWrapperValue.size(), 2);
++ QCOMPARE(engine1.memoryManager->m_pendingFreedObjectWrapperValue.size(), 1);
+
+ // engine2 doesn't own the object as engine1 was the first to wrap it above.
+ // Therefore, no effect here.
+diff --git a/qtdeclarative/tests/auto/quick/qquickitem2/data/activeFocusOnTab_infiniteLoop3.qml b/qtdeclarative/tests/auto/quick/qquickitem2/data/activeFocusOnTab_infiniteLoop3.qml
+new file mode 100644
+index 0000000000..889e480f3b
+--- /dev/null
++++ b/qtdeclarative/tests/auto/quick/qquickitem2/data/activeFocusOnTab_infiniteLoop3.qml
+@@ -0,0 +1,13 @@
++import QtQuick 2.6
++
++Item {
++ visible: true
++ Item {
++ visible: false
++ Item {
++ objectName: "hiddenChild"
++ activeFocusOnTab: true
++ focus: true
++ }
++ }
++}
+diff --git a/qtdeclarative/tests/auto/quick/qquickitem2/tst_qquickitem.cpp b/qtdeclarative/tests/auto/quick/qquickitem2/tst_qquickitem.cpp
+index c8f251dbe1..c8ef36ee68 100644
+--- a/qtdeclarative/tests/auto/quick/qquickitem2/tst_qquickitem.cpp
++++ b/qtdeclarative/tests/auto/quick/qquickitem2/tst_qquickitem.cpp
+@@ -67,6 +67,7 @@ private slots:
+ void activeFocusOnTab10();
+ void activeFocusOnTab_infiniteLoop_data();
+ void activeFocusOnTab_infiniteLoop();
++ void activeFocusOnTab_infiniteLoopControls();
+
+ void nextItemInFocusChain();
+ void nextItemInFocusChain2();
+@@ -1057,6 +1058,17 @@ void tst_QQuickItem::activeFocusOnTab_infiniteLoop()
+ QCOMPARE(item, window->rootObject());
+ }
+
++
++void tst_QQuickItem::activeFocusOnTab_infiniteLoopControls()
++{
++ auto source = testFileUrl("activeFocusOnTab_infiniteLoop3.qml");
++ QScopedPointer<QQuickView>window(new QQuickView());
++ window->setSource(source);
++ window->show();
++ QVERIFY(window->errors().isEmpty());
++ QTest::keyClick(window.get(), Qt::Key_Tab); // should not hang
++}
++
+ void tst_QQuickItem::nextItemInFocusChain()
+ {
+ if (!qt_tab_all_widgets())
+Submodule qtdoc c0c7bf07...79d6ef69:
+Submodule qtimageformats 2dcf2899..abe44c0f:
+diff --git a/qtimageformats/src/plugins/imageformats/icns/qicnshandler.cpp b/qtimageformats/src/plugins/imageformats/icns/qicnshandler.cpp
+index dde783c..1bf9074 100644
+--- a/qtimageformats/src/plugins/imageformats/icns/qicnshandler.cpp
++++ b/qtimageformats/src/plugins/imageformats/icns/qicnshandler.cpp
+@@ -462,8 +462,12 @@ static bool parseIconEntryInfo(ICNSEntry &icon)
+ if (isIconCompressed(icon))
+ return true;
+ // Icon depth:
+- if (!depth.isEmpty())
+- icon.depth = ICNSEntry::Depth(depth.toUInt());
++ if (!depth.isEmpty()) {
++ const uint depthUInt = depth.toUInt();
++ if (depthUInt > 32)
++ return false;
++ icon.depth = ICNSEntry::Depth(depthUInt);
++ }
+ // Try mono if depth not found
+ if (icon.depth == ICNSEntry::DepthUnknown)
+ icon.depth = ICNSEntry::DepthMono;
+@@ -515,6 +519,9 @@ static bool parseIconEntryInfo(ICNSEntry &icon)
+ }
+ icon.height = icon.width;
+ }
++ // Sanity check
++ if (icon.width == 0 || icon.width > 4096)
++ return false;
+ return true;
+ }
+
+@@ -685,7 +692,7 @@ bool QICNSHandler::canRead() const
+ bool QICNSHandler::read(QImage *outImage)
+ {
+ QImage img;
+- if (!ensureScanned()) {
++ if (!ensureScanned() || m_currentIconIndex >= m_icons.size()) {
+ qWarning("QICNSHandler::read(): The device wasn't parsed properly!");
+ return false;
+ }
+@@ -892,7 +899,7 @@ bool QICNSHandler::scanDevice()
+ return false;
+
+ const qint64 blockDataOffset = device()->pos();
+- if (!isBlockHeaderValid(blockHeader)) {
++ if (!isBlockHeaderValid(blockHeader, ICNSBlockHeaderSize + filelength - blockDataOffset)) {
+ qWarning("QICNSHandler::scanDevice(): Failed, bad header at pos %s. OSType \"%s\", length %u",
+ QByteArray::number(blockDataOffset).constData(),
+ nameFromOSType(blockHeader.ostype).constData(), blockHeader.length);
+@@ -927,11 +934,14 @@ bool QICNSHandler::scanDevice()
+ case ICNSBlockHeader::TypeOdrp:
+ // Icns container seems to have an embedded icon variant container
+ // Let's start a scan for entries
+- while (device()->pos() < nextBlockOffset) {
++ while (!stream.atEnd() && device()->pos() < nextBlockOffset) {
+ ICNSBlockHeader icon;
+ stream >> icon;
++ if (stream.status() != QDataStream::Ok)
++ return false;
+ // Check for incorrect variant entry header and stop scan
+- if (!isBlockHeaderValid(icon, blockDataLength))
++ quint64 remaining = blockDataLength - (device()->pos() - blockDataOffset);
++ if (!isBlockHeaderValid(icon, ICNSBlockHeaderSize + remaining))
+ break;
+ if (!addEntry(icon, device()->pos(), blockHeader.ostype))
+ return false;
+@@ -1003,7 +1013,7 @@ bool QICNSHandler::scanDevice()
+ break;
+ }
+ }
+- return true;
++ return (m_icons.size() > 0);
+ }
+
+ const ICNSEntry &QICNSHandler::getIconMask(const ICNSEntry &icon) const
+diff --git a/qtimageformats/src/plugins/imageformats/jp2/qjp2handler.cpp b/qtimageformats/src/plugins/imageformats/jp2/qjp2handler.cpp
+index 5082023..cb34374 100644
+--- a/qtimageformats/src/plugins/imageformats/jp2/qjp2handler.cpp
++++ b/qtimageformats/src/plugins/imageformats/jp2/qjp2handler.cpp
+@@ -43,6 +43,7 @@
+ #include "qimage.h"
+ #include "qvariant.h"
+ #include "qcolor.h"
++#include "qimagereader.h"
+
+ #include <jasper/jasper.h>
+ #include <math.h> // for pow
+@@ -333,16 +334,46 @@ private:
+ Jpeg2000JasperReader::Jpeg2000JasperReader(QIODevice *iod, SubFormat format)
+ : jasperOk(true), ioDevice(iod), format(format), hasAlpha(false)
+ {
++#if JAS_VERSION_MAJOR < 3
+ if (jas_init()) {
+ jasperOk = false;
+ qDebug("Jasper Library initialization failed");
+ }
++#else
++ jas_conf_clear();
++#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
++ jas_conf_set_max_mem_usage(QImageReader::allocationLimit() * 1024 * 1024);
++#else
++ // 128MB seems to be enough.
++ jas_conf_set_max_mem_usage(128 * 1024 * 1024);
++#endif
++ if (jas_init_library()) {
++ jasperOk = false;
++ qDebug("Jasper library initialization failed");
++ }
++ if (jas_init_thread()) {
++ jas_cleanup_library();
++ jasperOk = false;
++ qDebug("Jasper thread initialization failed");
++ }
++#endif
+ }
+
+ Jpeg2000JasperReader::~Jpeg2000JasperReader()
+ {
++#if JAS_VERSION_MAJOR < 3
+ if (jasperOk)
+ jas_cleanup();
++#else
++ if (jasperOk) {
++ if (jas_cleanup_thread()) {
++ qDebug("Jasper thread cleanup failed");
++ }
++ if (jas_cleanup_library()) {
++ qDebug("Jasper library cleanup failed");
++ }
++ }
++#endif
+ }
+
+ /*! \internal
+@@ -857,7 +888,7 @@ bool Jpeg2000JasperReader::write(const QImage &image, int quality)
+ }
+
+ // Open an empty jasper stream that grows automatically
+- jas_stream_t * memory_stream = jas_stream_memopen(0, -1);
++ jas_stream_t * memory_stream = jas_stream_memopen(0, 0);
+
+ // Jasper wants a non-const string.
+ char *str = qstrdup(jasperFormatString.toLatin1().constData());
+diff --git a/qtimageformats/src/plugins/imageformats/tiff/qtiffhandler.cpp b/qtimageformats/src/plugins/imageformats/tiff/qtiffhandler.cpp
+index 1386750..ac8956c 100644
+--- a/qtimageformats/src/plugins/imageformats/tiff/qtiffhandler.cpp
++++ b/qtimageformats/src/plugins/imageformats/tiff/qtiffhandler.cpp
+@@ -361,6 +361,8 @@ bool QTiffHandler::read(QImage *image)
+ }
+
+ TIFF *const tiff = d->tiff;
++ if (TIFFIsTiled(tiff) && TIFFTileSize64(tiff) > uint64_t(image->sizeInBytes())) // Corrupt image
++ return false;
+ const quint32 width = d->size.width();
+ const quint32 height = d->size.height();
+
+diff --git a/qtimageformats/src/plugins/imageformats/webp/qwebphandler.cpp b/qtimageformats/src/plugins/imageformats/webp/qwebphandler.cpp
+index 82d38cb..d02eb05 100644
+--- a/qtimageformats/src/plugins/imageformats/webp/qwebphandler.cpp
++++ b/qtimageformats/src/plugins/imageformats/webp/qwebphandler.cpp
+@@ -45,6 +45,7 @@
+ #include <qdebug.h>
+ #include <qpainter.h>
+ #include <qvariant.h>
++#include <QtEndian>
+
+ static const int riffHeaderSize = 12; // RIFF_HEADER_SIZE from webp/format_constants.h
+
+@@ -102,21 +103,23 @@ bool QWebpHandler::ensureScanned() const
+
+ m_scanState = ScanError;
+
+- if (device()->isSequential()) {
+- qWarning() << "Sequential devices are not supported";
++ QWebpHandler *that = const_cast<QWebpHandler *>(this);
++ const int headerBytesNeeded = sizeof(WebPBitstreamFeatures);
++ QByteArray header = device()->peek(headerBytesNeeded);
++ if (header.size() < headerBytesNeeded)
+ return false;
+- }
+
+- qint64 oldPos = device()->pos();
+- device()->seek(0);
+-
+- QWebpHandler *that = const_cast<QWebpHandler *>(this);
+- QByteArray header = device()->peek(sizeof(WebPBitstreamFeatures));
++ // We do no random access during decoding, just a readAll() of the whole image file. So if
++ // if it is all available already, we can accept a sequential device. The riff header contains
++ // the file size minus 8 bytes header
++ qint64 byteSize = qFromLittleEndian<quint32>(header.constData() + 4);
++ if (device()->isSequential() && device()->bytesAvailable() < byteSize + 8) {
++ qWarning() << "QWebpHandler: Insufficient data available in sequential device";
++ return false;
++ }
+ if (WebPGetFeatures((const uint8_t*)header.constData(), header.size(), &(that->m_features)) == VP8_STATUS_OK) {
+ if (m_features.has_animation) {
+ // For animation, we have to read and scan whole file to determine loop count and images count
+- device()->seek(oldPos);
+-
+ if (that->ensureDemuxer()) {
+ that->m_loop = WebPDemuxGetI(m_demuxer, WEBP_FF_LOOP_COUNT);
+ that->m_frameCount = WebPDemuxGetI(m_demuxer, WEBP_FF_FRAME_COUNT);
+@@ -126,17 +129,13 @@ bool QWebpHandler::ensureScanned() const
+ if (that->m_features.has_alpha)
+ that->m_composited->fill(Qt::transparent);
+
+- // We do not reset device position since we have read in all data
+ m_scanState = ScanSuccess;
+- return true;
+ }
+ } else {
+ m_scanState = ScanSuccess;
+ }
+ }
+
+- device()->seek(oldPos);
+-
+ return m_scanState == ScanSuccess;
+ }
+
+@@ -159,7 +158,7 @@ bool QWebpHandler::ensureDemuxer()
+
+ bool QWebpHandler::read(QImage *image)
+ {
+- if (!ensureScanned() || device()->isSequential() || !ensureDemuxer())
++ if (!ensureScanned() || !ensureDemuxer())
+ return false;
+
+ QRect prevFrameRect;
+Submodule qtlocation 98a5c511..f991e28c:
+diff --git a/qtlocation/src/location/configure.json b/qtlocation/src/location/configure.json
+index 6d01a9a3..d1e623a1 100644
+--- a/qtlocation/src/location/configure.json
++++ b/qtlocation/src/location/configure.json
+@@ -9,7 +9,7 @@
+ "label": "Qt.labs.location experimental QML plugin",
+ "purpose": "Provides experimental QtLocation QML types",
+ "section": "Location",
+- "condition": "config.opengl",
++ "condition": "features.opengl",
+ "output": [ "privateFeature" ]
+ },
+ "geoservices_osm": {
+diff --git a/qtlocation/src/location/labs/qsg/qgeomapobjectqsgsupport.cpp b/qtlocation/src/location/labs/qsg/qgeomapobjectqsgsupport.cpp
+index a978573d..11e1466f 100644
+--- a/qtlocation/src/location/labs/qsg/qgeomapobjectqsgsupport.cpp
++++ b/qtlocation/src/location/labs/qsg/qgeomapobjectqsgsupport.cpp
+@@ -158,7 +158,7 @@ void QGeoMapObjectQSGSupport::updateMapObjects(QSGNode *root, QQuickWindow *wind
+ if (!root)
+ return;
+
+- if (m_mapObjectsRootNode && m_mapObjectsRootNode->parent())
++ if (m_mapObjectsRootNode && !m_mapObjectsRootNode->parent())
+ root->appendChildNode(m_mapObjectsRootNode.get());
+
+ if (!m_mapObjectsRootNode) {
+diff --git a/qtlocation/src/plugins/geoservices/esri/geocodingmanagerengine_esri.cpp b/qtlocation/src/plugins/geoservices/esri/geocodingmanagerengine_esri.cpp
+index 5a40467e..d123c6a8 100644
+--- a/qtlocation/src/plugins/geoservices/esri/geocodingmanagerengine_esri.cpp
++++ b/qtlocation/src/plugins/geoservices/esri/geocodingmanagerengine_esri.cpp
+@@ -59,8 +59,10 @@ QT_BEGIN_NAMESPACE
+ static const QString kPrefixEsri(QStringLiteral("esri."));
+ static const QString kParamUserAgent(kPrefixEsri + QStringLiteral("useragent"));
+
+-static const QString kUrlGeocode(QStringLiteral("http://geocode.arcgis.com/arcgis/rest/services/World/GeocodeServer/findAddressCandidates"));
+-static const QString kUrlReverseGeocode(QStringLiteral("http://geocode.arcgis.com/arcgis/rest/services/World/GeocodeServer/reverseGeocode"));
++static const QString kUrlGeocode(QStringLiteral("https://geocode.arcgis.com/arcgis/rest/services/"
++ "World/GeocodeServer/findAddressCandidates"));
++static const QString kUrlReverseGeocode(QStringLiteral(
++ "https://geocode.arcgis.com/arcgis/rest/services/World/GeocodeServer/reverseGeocode"));
+
+ static QString addressToQuery(const QGeoAddress &address)
+ {
+diff --git a/qtlocation/src/plugins/geoservices/esri/georoutejsonparser_esri.cpp b/qtlocation/src/plugins/geoservices/esri/georoutejsonparser_esri.cpp
+index 17492d94..96c12b1b 100644
+--- a/qtlocation/src/plugins/geoservices/esri/georoutejsonparser_esri.cpp
++++ b/qtlocation/src/plugins/geoservices/esri/georoutejsonparser_esri.cpp
+@@ -46,7 +46,8 @@
+
+ QT_BEGIN_NAMESPACE
+
+-// JSON reference: http://resources.arcgis.com/en/help/arcgis-rest-api/#/Route_service_with_synchronous_execution/02r300000036000000/
++// JSON reference:
++// https://resources.arcgis.com/en/help/arcgis-rest-api/#/Route_service_with_synchronous_execution/02r300000036000000/
+
+ static const QString kErrorMessage(QStringLiteral("Error %1: %2."));
+ static const QString kErrorJson(QStringLiteral("Error: invalide JSON document."));
+diff --git a/qtlocation/src/plugins/geoservices/esri/georoutereply_esri.cpp b/qtlocation/src/plugins/geoservices/esri/georoutereply_esri.cpp
+index 8cadfb29..92b6bb13 100644
+--- a/qtlocation/src/plugins/geoservices/esri/georoutereply_esri.cpp
++++ b/qtlocation/src/plugins/geoservices/esri/georoutereply_esri.cpp
+@@ -44,7 +44,8 @@
+
+ QT_BEGIN_NAMESPACE
+
+-// JSON reference: http://resources.arcgis.com/en/help/arcgis-rest-api/#/Route_service_with_synchronous_execution/02r300000036000000/
++// JSON reference:
++// https://resources.arcgis.com/en/help/arcgis-rest-api/#/Route_service_with_synchronous_execution/02r300000036000000/
+
+ GeoRouteReplyEsri::GeoRouteReplyEsri(QNetworkReply *reply, const QGeoRouteRequest &request,
+ QObject *parent) :
+diff --git a/qtlocation/src/plugins/geoservices/esri/georoutingmanagerengine_esri.cpp b/qtlocation/src/plugins/geoservices/esri/georoutingmanagerengine_esri.cpp
+index 0e6bc2c7..ed613f4b 100644
+--- a/qtlocation/src/plugins/geoservices/esri/georoutingmanagerengine_esri.cpp
++++ b/qtlocation/src/plugins/geoservices/esri/georoutingmanagerengine_esri.cpp
+@@ -48,7 +48,8 @@ static const QString kPrefixEsri(QStringLiteral("esri."));
+ static const QString kParamUserAgent(kPrefixEsri + QStringLiteral("useragent"));
+ static const QString kParamToken(kPrefixEsri + QStringLiteral("token"));
+
+-static const QString kUrlRouting(QStringLiteral("http://route.arcgis.com/arcgis/rest/services/World/Route/NAServer/Route_World/solve"));
++static const QString kUrlRouting(QStringLiteral(
++ "https://route.arcgis.com/arcgis/rest/services/World/Route/NAServer/Route_World/solve"));
+
+ GeoRoutingManagerEngineEsri::GeoRoutingManagerEngineEsri(const QVariantMap ¶meters,
+ QGeoServiceProvider::Error *error,
+@@ -70,7 +71,8 @@ GeoRoutingManagerEngineEsri::~GeoRoutingManagerEngineEsri()
+ {
+ }
+
+-// REST reference: http://resources.arcgis.com/en/help/arcgis-rest-api/index.html#//02r300000036000000
++// REST reference:
++// https://resources.arcgis.com/en/help/arcgis-rest-api/index.html#//02r300000036000000
+
+ QGeoRouteReply *GeoRoutingManagerEngineEsri::calculateRoute(const QGeoRouteRequest &request)
+ {
+@@ -125,7 +127,7 @@ void GeoRoutingManagerEngineEsri::replyError(QGeoRouteReply::Error errorCode, co
+ QString GeoRoutingManagerEngineEsri::preferedDirectionLangage()
+ {
+ // list of supported langages is defined in:
+- // http://resources.arcgis.com/en/help/arcgis-rest-api/index.html#//02r300000036000000
++ // https://resources.arcgis.com/en/help/arcgis-rest-api/index.html#//02r300000036000000
+ const QStringList supportedLanguages = {
+ "ar", // Generate directions in Arabic
+ "cs", // Generate directions in Czech
+diff --git a/qtlocation/src/plugins/geoservices/esri/geotiledmappingmanagerengine_esri.cpp b/qtlocation/src/plugins/geoservices/esri/geotiledmappingmanagerengine_esri.cpp
+index 5d15835d..24148f95 100644
+--- a/qtlocation/src/plugins/geoservices/esri/geotiledmappingmanagerengine_esri.cpp
++++ b/qtlocation/src/plugins/geoservices/esri/geotiledmappingmanagerengine_esri.cpp
+@@ -230,7 +230,8 @@ QGeoMap *GeoTiledMappingManagerEngineEsri::createMap()
+ // ${y} = Y
+ // ${token} = Token
+
+-// template = 'http://services.arcgisonline.com/ArcGIS/rest/services/World_Topo_Map/MapServer/tile/{{z}}/{{y}}/{{x}}.png'
++// template =
++// 'https://services.arcgisonline.com/ArcGIS/rest/services/World_Topo_Map/MapServer/tile/{{z}}/{{y}}/{{x}}.png'
+
+ bool GeoTiledMappingManagerEngineEsri::initializeMapSources(QGeoServiceProvider::Error *error,
+ QString *errorString,
+diff --git a/qtlocation/src/plugins/geoservices/esri/maps.json b/qtlocation/src/plugins/geoservices/esri/maps.json
+index 8167ae7d..862e087d 100644
+--- a/qtlocation/src/plugins/geoservices/esri/maps.json
++++ b/qtlocation/src/plugins/geoservices/esri/maps.json
+@@ -6,8 +6,8 @@
+ "description": "ArcGIS Online World Street Map",
+ "mobile": true,
+ "night": false,
+- "url": "http://services.arcgisonline.com/ArcGIS/rest/services/World_Street_Map/MapServer",
+- "copyrightText": "© <a href='http://www.arcgis.com/home/item.html?id=3b93337983e9436f8db950e38a8629af'>Esri</a> contributors"
++ "url": "https://services.arcgisonline.com/ArcGIS/rest/services/World_Street_Map/MapServer",
++ "copyrightText": "© <a href='https://www.arcgis.com/home/item.html?id=3b93337983e9436f8db950e38a8629af'>Esri</a> contributors"
+ },
+
+ {
+@@ -16,8 +16,8 @@
+ "": "ArcGIS Online World Imagery",
+ "mobile": true,
+ "night": false,
+- "url": "http://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer",
+- "copyrightText": "© <a href='http://www.arcgis.com/home/item.html?id=10df2279f9684e4a9f6a7f08febac2a9'>Esri</a> contributors"
++ "url": "https://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer",
++ "copyrightText": "© <a href='https://www.arcgis.com/home/item.html?id=10df2279f9684e4a9f6a7f08febac2a9'>Esri</a> contributors"
+ },
+
+ {
+@@ -26,8 +26,8 @@
+ "description": "ArcGIS Online World Terrain Base",
+ "mobile": false,
+ "night": false,
+- "url": "http://server.arcgisonline.com/ArcGIS/rest/services/World_Terrain_Base/MapServer",
+- "copyrightText": "© <a href='http://www.arcgis.com/home/item.html?id=c61ad8ab017d49e1a82f580ee1298931'>Esri</a> contributors"
++ "url": "https://server.arcgisonline.com/ArcGIS/rest/services/World_Terrain_Base/MapServer",
++ "copyrightText": "© <a href='https://www.arcgis.com/home/item.html?id=c61ad8ab017d49e1a82f580ee1298931'>Esri</a> contributors"
+ },
+
+ {
+@@ -36,8 +36,8 @@
+ "description": "ArcGIS Online World Topography",
+ "mobile": true,
+ "night": false,
+- "url": "http://server.arcgisonline.com/ArcGIS/rest/services/World_Topo_Map/MapServer",
+- "copyrightText": "© <a href='http://www.arcgis.com/home/item.html?id=30e5fe3149c34df1ba922e6f5bbf808f'>Esri</a> contributors"
++ "url": "https://server.arcgisonline.com/ArcGIS/rest/services/World_Topo_Map/MapServer",
++ "copyrightText": "© <a href='https://www.arcgis.com/home/item.html?id=30e5fe3149c34df1ba922e6f5bbf808f'>Esri</a> contributors"
+ },
+
+ {
+@@ -46,8 +46,8 @@
+ "description": "This map presents land cover and detailed topographic maps for the United States.",
+ "mobile": true,
+ "night": false,
+- "url": "http://services.arcgisonline.com/ArcGIS/rest/services/USA_Topo_Maps/MapServer",
+- "copyrightText": "© <a href='http://www.arcgis.com/home/item.html?id=99cd5fbd98934028802b4f797c4b1732'>Esri</a> contributors"
++ "url": "https://services.arcgisonline.com/ArcGIS/rest/services/USA_Topo_Maps/MapServer",
++ "copyrightText": "© <a href='https://www.arcgis.com/home/item.html?id=99cd5fbd98934028802b4f797c4b1732'>Esri</a> contributors"
+ },
+
+ {
+@@ -56,8 +56,8 @@
+ "description": "National Geographic World Map",
+ "mobile": false,
+ "night": false,
+- "url": "http://services.arcgisonline.com/ArcGIS/rest/services/NatGeo_World_Map/MapServer",
+- "copyrightText": "© <a href='http://www.arcgis.com/home/item.html?id=b9b1b422198944fbbd5250b3241691b6'>Esri</a> contributors"
++ "url": "https://services.arcgisonline.com/ArcGIS/rest/services/NatGeo_World_Map/MapServer",
++ "copyrightText": "© <a href='https://www.arcgis.com/home/item.html?id=b9b1b422198944fbbd5250b3241691b6'>Esri</a> contributors"
+ },
+
+ {
+@@ -66,8 +66,8 @@
+ "description": "Thematic content providing a neutral background with minimal colors",
+ "mobile": true,
+ "night": false,
+- "url": "http://services.arcgisonline.com/ArcGIS/rest/services/Canvas/World_Light_Gray_Base/MapServer",
+- "copyrightText": "© <a href='http://www.arcgis.com/home/item.html?id=ed712cb1db3e4bae9e85329040fb9a49'>Esri</a> contributors"
++ "url": "https://services.arcgisonline.com/ArcGIS/rest/services/Canvas/World_Light_Gray_Base/MapServer",
++ "copyrightText": "© <a href='https://www.arcgis.com/home/item.html?id=ed712cb1db3e4bae9e85329040fb9a49'>Esri</a> contributors"
+ },
+
+ {
+@@ -76,8 +76,8 @@
+ "description": "Natural Earth physical map for the world",
+ "mobile": false,
+ "night": false,
+- "url": "http://server.arcgisonline.com/ArcGIS/rest/services/World_Physical_Map/MapServer",
+- "copyrightText": "© <a href='http://www.arcgis.com/home/item.html?id=c4ec722a1cd34cf0a23904aadf8923a0'>Esri</a> contributors"
++ "url": "https://server.arcgisonline.com/ArcGIS/rest/services/World_Physical_Map/MapServer",
++ "copyrightText": "© <a href='https://www.arcgis.com/home/item.html?id=c4ec722a1cd34cf0a23904aadf8923a0'>Esri</a> contributors"
+ },
+
+ {
+@@ -86,8 +86,8 @@
+ "description": "Portrays surface elevation as shaded relief",
+ "mobile": false,
+ "night": false,
+- "url": "http://server.arcgisonline.com/ArcGIS/rest/services/World_Shaded_Relief/MapServer",
+- "copyrightText": "© <a href='http://www.arcgis.com/home/item.html?id=9c5370d0b54f4de1b48a3792d7377ff2'>Esri</a> contributors"
++ "url": "https://server.arcgisonline.com/ArcGIS/rest/services/World_Shaded_Relief/MapServer",
++ "copyrightText": "© <a href='https://www.arcgis.com/home/item.html?id=9c5370d0b54f4de1b48a3792d7377ff2'>Esri</a> contributors"
+ },
+
+ {
+@@ -96,8 +96,8 @@
+ "description": "This map is designed to be used as a basemap by marine GIS professionals and as a reference map by anyone interested in ocean data",
+ "mobile": false,
+ "night": false,
+- "url": "http://server.arcgisonline.com/arcgis/rest/services/Ocean/World_Ocean_Base/MapServer",
+- "copyrightText": "© <a href='http://www.arcgis.com/home/item.html?id=1e126e7520f9466c9ca28b8f28b5e500'>Esri</a> contributors"
++ "url": "https://server.arcgisonline.com/arcgis/rest/services/Ocean/World_Ocean_Base/MapServer",
++ "copyrightText": "© <a href='https://www.arcgis.com/home/item.html?id=1e126e7520f9466c9ca28b8f28b5e500'>Esri</a> contributors"
+ },
+
+ {
+@@ -106,8 +106,8 @@
+ "description": "Thematic content providing a neutral background with minimal colors",
+ "mobile": false,
+ "night": true,
+- "url": "http://services.arcgisonline.com/ArcGIS/rest/services/Canvas/World_Dark_Gray_Base/MapServer",
+- "copyrightText": "© <a href='http://www.arcgis.com/home/item.html?id=a284a9b99b3446a3910d4144a50990f6'>Esri</a> contributors"
++ "url": "https://services.arcgisonline.com/ArcGIS/rest/services/Canvas/World_Dark_Gray_Base/MapServer",
++ "copyrightText": "© <a href='https://www.arcgis.com/home/item.html?id=a284a9b99b3446a3910d4144a50990f6'>Esri</a> contributors"
+ },
+
+ {
+@@ -116,8 +116,8 @@
+ "description": "DeLorme’s topographic basemap is a seamless global data set that portrays transportation, hydrography, jurisdiction boundaries, and major geographic features",
+ "mobile": false,
+ "night": false,
+- "url": "http://server.arcgisonline.com/ArcGIS/rest/services/Specialty/DeLorme_World_Base_Map/MapServer",
+- "copyrightText": "© <a href='http://www.arcgis.com/home/item.html?id=b165c3df453e4be6b5ac4fdb241effbe'>Esri</a> contributors"
++ "url": "https://server.arcgisonline.com/ArcGIS/rest/services/Specialty/DeLorme_World_Base_Map/MapServer",
++ "copyrightText": "© <a href='https://www.arcgis.com/home/item.html?id=b165c3df453e4be6b5ac4fdb241effbe'>Esri</a> contributors"
+ }
+ ]
+ }
+diff --git a/qtlocation/src/plugins/geoservices/esri/placemanagerengine_esri.cpp b/qtlocation/src/plugins/geoservices/esri/placemanagerengine_esri.cpp
+index 3858ddf5..af66f28e 100644
+--- a/qtlocation/src/plugins/geoservices/esri/placemanagerengine_esri.cpp
++++ b/qtlocation/src/plugins/geoservices/esri/placemanagerengine_esri.cpp
+@@ -63,8 +63,10 @@ static const QString kCountriesKey(QStringLiteral("detailedCountries"));
+ static const QString kLocalizedNamesKey(QStringLiteral("localizedNames"));
+ static const QString kMaxLocationsKey(QStringLiteral("maxLocations"));
+
+-static const QUrl kUrlGeocodeServer("http://geocode.arcgis.com/arcgis/rest/services/World/GeocodeServer?f=pjson");
+-static const QUrl kUrlFindAddressCandidates("http://geocode.arcgis.com/arcgis/rest/services/World/GeocodeServer/findAddressCandidates");
++static const QUrl kUrlGeocodeServer(
++ "https://geocode.arcgis.com/arcgis/rest/services/World/GeocodeServer?f=pjson");
++static const QUrl kUrlFindAddressCandidates("https://geocode.arcgis.com/arcgis/rest/services/World/"
++ "GeocodeServer/findAddressCandidates");
+
+ PlaceManagerEngineEsri::PlaceManagerEngineEsri(const QVariantMap ¶meters, QGeoServiceProvider::Error *error,
+ QString *errorString) :
+Submodule qtmultimedia f0344079..0d7cc33a:
+diff --git a/qtmultimedia/src/plugins/pulseaudio/qaudioinput_pulse.cpp b/qtmultimedia/src/plugins/pulseaudio/qaudioinput_pulse.cpp
+index 2b5325132..b68b4af1b 100644
+--- a/qtmultimedia/src/plugins/pulseaudio/qaudioinput_pulse.cpp
++++ b/qtmultimedia/src/plugins/pulseaudio/qaudioinput_pulse.cpp
+@@ -402,6 +402,8 @@ int QPulseAudioInput::bytesReady() const
+
+ qint64 QPulseAudioInput::read(char *data, qint64 len)
+ {
++ Q_ASSERT(data != nullptr || len == 0);
++
+ m_bytesAvailable = checkBytesReady();
+
+ setError(QAudio::NoError);
+@@ -411,7 +413,8 @@ qint64 QPulseAudioInput::read(char *data, qint64 len)
+
+ if (!m_pullMode && !m_tempBuffer.isEmpty()) {
+ readBytes = qMin(static_cast<int>(len), m_tempBuffer.size());
+- memcpy(data, m_tempBuffer.constData(), readBytes);
++ if (readBytes)
++ memcpy(data, m_tempBuffer.constData(), readBytes);
+ m_totalTimeValue += readBytes;
+
+ if (readBytes < m_tempBuffer.size()) {
+@@ -502,9 +505,10 @@ qint64 QPulseAudioInput::read(char *data, qint64 len)
+
+ void QPulseAudioInput::applyVolume(const void *src, void *dest, int len)
+ {
++ Q_ASSERT((src && dest) || len == 0);
+ if (m_volume < 1.f)
+ QAudioHelperInternal::qMultiplySamples(m_volume, m_format, src, dest, len);
+- else
++ else if (len)
+ memcpy(dest, src, len);
+ }
+
+Submodule qtpim 02efef5e...f9a8f0fc (commits not present)
+Submodule qtquick3d b85cf622..47defc8b:
+diff --git a/qtquick3d/src/plugins/assetimporters/assimp/assimp.pro b/qtquick3d/src/plugins/assetimporters/assimp/assimp.pro
+index ca5c499e..174a075b 100644
+--- a/qtquick3d/src/plugins/assetimporters/assimp/assimp.pro
++++ b/qtquick3d/src/plugins/assetimporters/assimp/assimp.pro
+@@ -10,7 +10,7 @@ QT_FOR_CONFIG += assetimporters-private
+ include($$OUT_PWD/../qtassetimporters-config.pri)
+
+ qtConfig(system-assimp):!if(cross_compile:host_build) {
+- QMAKE_USE_PRIVATE += assimp
++ QMAKE_USE_PRIVATE += quick3d-assimp
+ } else {
+ include(../../../3rdparty/assimp/assimp.pri)
+ }
+Submodule qtquickcontrols2 3a657dc0..56ce8233:
+diff --git a/qtquickcontrols2/src/imports/platform/widgets/qwidgetplatformmenu.cpp b/qtquickcontrols2/src/imports/platform/widgets/qwidgetplatformmenu.cpp
+index e5fe734f7..e36922775 100644
+--- a/qtquickcontrols2/src/imports/platform/widgets/qwidgetplatformmenu.cpp
++++ b/qtquickcontrols2/src/imports/platform/widgets/qwidgetplatformmenu.cpp
+@@ -38,6 +38,7 @@
+ #include "qwidgetplatformmenuitem_p.h"
+
+ #include <QtGui/qwindow.h>
++#include <QtGui/private/qhighdpiscaling_p.h>
+ #include <QtWidgets/qmenu.h>
+ #include <QtWidgets/qaction.h>
+
+@@ -145,7 +146,7 @@ void QWidgetPlatformMenu::showPopup(const QWindow *window, const QRect &targetRe
+
+ QPoint targetPos = targetRect.bottomLeft();
+ if (window)
+- targetPos = window->mapToGlobal(targetPos);
++ targetPos = window->mapToGlobal(QHighDpi::fromNativeLocalPosition(targetPos, window));
+
+ const QWidgetPlatformMenuItem *widgetItem = qobject_cast<const QWidgetPlatformMenuItem *>(item);
+ m_menu->popup(targetPos, widgetItem ? widgetItem->action() : nullptr);
+diff --git a/qtquickcontrols2/src/quicktemplates2/qquickabstractbutton.cpp b/qtquickcontrols2/src/quicktemplates2/qquickabstractbutton.cpp
+index 950e4e099..b81fbea0b 100644
+--- a/qtquickcontrols2/src/quicktemplates2/qquickabstractbutton.cpp
++++ b/qtquickcontrols2/src/quicktemplates2/qquickabstractbutton.cpp
+@@ -387,6 +387,17 @@ void QQuickAbstractButtonPrivate::itemImplicitHeightChanged(QQuickItem *item)
+ emit q->implicitIndicatorHeightChanged();
+ }
+
++void QQuickAbstractButtonPrivate::itemDestroyed(QQuickItem *item)
++{
++ Q_Q(QQuickAbstractButton);
++ QQuickControlPrivate::itemDestroyed(item);
++ if (item == indicator) {
++ indicator = nullptr;
++ emit q->implicitIndicatorWidthChanged();
++ emit q->implicitIndicatorHeightChanged();
++ }
++}
++
+ QQuickAbstractButton *QQuickAbstractButtonPrivate::findCheckedButton() const
+ {
+ Q_Q(const QQuickAbstractButton);
+@@ -1176,6 +1187,12 @@ QAccessible::Role QQuickAbstractButton::accessibleRole() const
+ }
+ return QAccessible::Button;
+ }
++
++void QQuickAbstractButton::accessiblePressAction()
++{
++ Q_D(QQuickAbstractButton);
++ d->trigger();
++}
+ #endif
+
+ QT_END_NAMESPACE
+diff --git a/qtquickcontrols2/src/quicktemplates2/qquickabstractbutton_p.h b/qtquickcontrols2/src/quicktemplates2/qquickabstractbutton_p.h
+index 0fa48980e..ab66220d0 100644
+--- a/qtquickcontrols2/src/quicktemplates2/qquickabstractbutton_p.h
++++ b/qtquickcontrols2/src/quicktemplates2/qquickabstractbutton_p.h
+@@ -209,6 +209,7 @@ protected:
+ #if QT_CONFIG(accessibility)
+ void accessibilityActiveChanged(bool active) override;
+ QAccessible::Role accessibleRole() const override;
++ Q_INVOKABLE void accessiblePressAction();
+ #endif
+
+ private:
+diff --git a/qtquickcontrols2/src/quicktemplates2/qquickabstractbutton_p_p.h b/qtquickcontrols2/src/quicktemplates2/qquickabstractbutton_p_p.h
+index 9291c1a87..b729720f2 100644
+--- a/qtquickcontrols2/src/quicktemplates2/qquickabstractbutton_p_p.h
++++ b/qtquickcontrols2/src/quicktemplates2/qquickabstractbutton_p_p.h
+@@ -109,6 +109,7 @@ public:
+
+ void itemImplicitWidthChanged(QQuickItem *item) override;
+ void itemImplicitHeightChanged(QQuickItem *item) override;
++ void itemDestroyed(QQuickItem *item) override;
+
+ // copied from qabstractbutton.cpp
+ static const int AUTO_REPEAT_DELAY = 300;
+diff --git a/qtquickcontrols2/src/quicktemplates2/qquickaction.cpp b/qtquickcontrols2/src/quicktemplates2/qquickaction.cpp
+index 2041e7741..8610cdfae 100644
+--- a/qtquickcontrols2/src/quicktemplates2/qquickaction.cpp
++++ b/qtquickcontrols2/src/quicktemplates2/qquickaction.cpp
+@@ -145,7 +145,7 @@ int QQuickActionPrivate::ShortcutEntry::shortcutId() const
+
+ void QQuickActionPrivate::ShortcutEntry::grab(const QKeySequence &shortcut, bool enabled)
+ {
+- if (shortcut.isEmpty())
++ if (shortcut.isEmpty() || m_shortcutId)
+ return;
+
+ Qt::ShortcutContext context = Qt::WindowShortcut; // TODO
+diff --git a/qtquickcontrols2/src/quicktemplates2/qquickcontainer.cpp b/qtquickcontrols2/src/quicktemplates2/qquickcontainer.cpp
+index f38c2b09c..6eed2a024 100644
+--- a/qtquickcontrols2/src/quicktemplates2/qquickcontainer.cpp
++++ b/qtquickcontrols2/src/quicktemplates2/qquickcontainer.cpp
+@@ -225,6 +225,7 @@ void QQuickContainerPrivate::cleanup()
+ QObject::disconnect(contentModel, &QQmlObjectModel::countChanged, q, &QQuickContainer::countChanged);
+ QObject::disconnect(contentModel, &QQmlObjectModel::childrenChanged, q, &QQuickContainer::contentChildrenChanged);
+ delete contentModel;
++ contentModel = nullptr;
+ }
+
+ QQuickItem *QQuickContainerPrivate::itemAt(int index) const
+@@ -436,7 +437,7 @@ void QQuickContainerPrivate::contentChildren_clear(QQmlListProperty<QQuickItem>
+ void QQuickContainerPrivate::updateContentWidth()
+ {
+ Q_Q(QQuickContainer);
+- if (hasContentWidth || qFuzzyCompare(contentWidth, implicitContentWidth))
++ if (hasContentWidth || qFuzzyCompare(contentWidth, implicitContentWidth) || !contentModel)
+ return;
+
+ contentWidth = implicitContentWidth;
+@@ -446,7 +447,7 @@ void QQuickContainerPrivate::updateContentWidth()
+ void QQuickContainerPrivate::updateContentHeight()
+ {
+ Q_Q(QQuickContainer);
+- if (hasContentHeight || qFuzzyCompare(contentHeight, implicitContentHeight))
++ if (hasContentHeight || qFuzzyCompare(contentHeight, implicitContentHeight) || !contentModel)
+ return;
+
+ contentHeight = implicitContentHeight;
+diff --git a/qtquickcontrols2/src/quicktemplates2/qquickcontrol.cpp b/qtquickcontrols2/src/quicktemplates2/qquickcontrol.cpp
+index bbbd0e622..1f4b47343 100644
+--- a/qtquickcontrols2/src/quicktemplates2/qquickcontrol.cpp
++++ b/qtquickcontrols2/src/quicktemplates2/qquickcontrol.cpp
+@@ -845,6 +845,13 @@ void QQuickControlPrivate::executeBackground(bool complete)
+ quickCompleteDeferred(q, backgroundName(), background);
+ }
+
++/*
++ \internal
++
++ Hides an item that was replaced by a newer one, rather than
++ deleting it, as the item is typically created in QML and hence
++ we don't own it.
++*/
+ void QQuickControlPrivate::hideOldItem(QQuickItem *item)
+ {
+ if (!item)
+@@ -863,6 +870,29 @@ void QQuickControlPrivate::hideOldItem(QQuickItem *item)
+ #endif
+ }
+
++/*
++ \internal
++
++ Named "unhide" because it's used for cases where an item
++ that was previously hidden by \l hideOldItem() wants to be
++ shown by a control again, such as a ScrollBar in ScrollView.
++*/
++void QQuickControlPrivate::unhideOldItem(QQuickControl *control, QQuickItem *item)
++{
++ Q_ASSERT(item);
++ qCDebug(lcItemManagement) << "unhiding old item" << item;
++
++ item->setVisible(true);
++ item->setParentItem(control);
++
++#if QT_CONFIG(accessibility)
++ // Add the item back in to the accessibility tree.
++ QQuickAccessibleAttached *accessible = accessibleAttached(item);
++ if (accessible)
++ accessible->setIgnored(false);
++#endif
++}
++
+ void QQuickControlPrivate::updateBaselineOffset()
+ {
+ Q_Q(QQuickControl);
+diff --git a/qtquickcontrols2/src/quicktemplates2/qquickcontrol_p_p.h b/qtquickcontrols2/src/quicktemplates2/qquickcontrol_p_p.h
+index 8e979079e..a6e624c91 100644
+--- a/qtquickcontrols2/src/quicktemplates2/qquickcontrol_p_p.h
++++ b/qtquickcontrols2/src/quicktemplates2/qquickcontrol_p_p.h
+@@ -173,6 +173,7 @@ public:
+ virtual void executeBackground(bool complete = false);
+
+ static void hideOldItem(QQuickItem *item);
++ static void unhideOldItem(QQuickControl *control, QQuickItem *item);
+
+ void updateBaselineOffset();
+
+diff --git a/qtquickcontrols2/src/quicktemplates2/qquickdialogbuttonbox.cpp b/qtquickcontrols2/src/quicktemplates2/qquickdialogbuttonbox.cpp
+index e6db14eb5..6197d1547 100644
+--- a/qtquickcontrols2/src/quicktemplates2/qquickdialogbuttonbox.cpp
++++ b/qtquickcontrols2/src/quicktemplates2/qquickdialogbuttonbox.cpp
+@@ -237,7 +237,7 @@ static QRectF alignedRect(Qt::LayoutDirection direction, Qt::Alignment alignment
+ void QQuickDialogButtonBoxPrivate::resizeContent()
+ {
+ Q_Q(QQuickDialogButtonBox);
+- if (!contentItem)
++ if (!contentItem || !contentModel)
+ return;
+
+ QRectF geometry = q->boundingRect().adjusted(q->leftPadding(), q->topPadding(), -q->rightPadding(), -q->bottomPadding());
+@@ -322,6 +322,9 @@ void QQuickDialogButtonBoxPrivate::updateLayout()
+ qreal QQuickDialogButtonBoxPrivate::getContentWidth() const
+ {
+ Q_Q(const QQuickDialogButtonBox);
++ if (!contentModel)
++ return 0;
++
+ const int count = contentModel->count();
+ const qreal totalSpacing = qMax(0, count - 1) * spacing;
+ qreal totalWidth = totalSpacing;
+@@ -341,6 +344,9 @@ qreal QQuickDialogButtonBoxPrivate::getContentWidth() const
+ qreal QQuickDialogButtonBoxPrivate::getContentHeight() const
+ {
+ Q_Q(const QQuickDialogButtonBox);
++ if (!contentModel)
++ return 0;
++
+ const int count = contentModel->count();
+ qreal maxHeight = 0;
+ for (int i = 0; i < count; ++i) {
+diff --git a/qtquickcontrols2/src/quicktemplates2/qquickoverlay.cpp b/qtquickcontrols2/src/quicktemplates2/qquickoverlay.cpp
+index 91bd59184..0ce518f84 100644
+--- a/qtquickcontrols2/src/quicktemplates2/qquickoverlay.cpp
++++ b/qtquickcontrols2/src/quicktemplates2/qquickoverlay.cpp
+@@ -399,8 +399,11 @@ void QQuickOverlay::itemChange(ItemChange change, const ItemChangeData &data)
+ Q_D(QQuickOverlay);
+ QQuickItem::itemChange(change, data);
+
+- if (change == ItemChildAddedChange || change == ItemChildRemovedChange)
++ if (change == ItemChildAddedChange || change == ItemChildRemovedChange) {
+ setVisible(!d->allDrawers.isEmpty() || !childItems().isEmpty());
++ if (data.item->parent() == d->mouseGrabberPopup)
++ d->setMouseGrabberPopup(nullptr);
++ }
+ }
+
+ void QQuickOverlay::geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry)
+diff --git a/qtquickcontrols2/src/quicktemplates2/qquickscrollbar.cpp b/qtquickcontrols2/src/quicktemplates2/qquickscrollbar.cpp
+index 4e2f509db..1c4b308cd 100644
+--- a/qtquickcontrols2/src/quicktemplates2/qquickscrollbar.cpp
++++ b/qtquickcontrols2/src/quicktemplates2/qquickscrollbar.cpp
+@@ -797,6 +797,14 @@ void QQuickScrollBarAttachedPrivate::initHorizontal()
+ if (parent && parent == flickable->parentItem())
+ horizontal->stackAfter(flickable);
+
++ // If a scroll bar was previously hidden (due to e.g. setting a new contentItem
++ // on a ScrollView), we need to make sure that we un-hide it.
++ // We don't bother checking if the item is actually the old one, because
++ // if it's not, all of the things the function does (setting parent, visibility, etc.)
++ // should be no-ops anyway.
++ if (auto control = qobject_cast<QQuickControl*>(q_ptr->parent()))
++ QQuickControlPrivate::unhideOldItem(control, horizontal);
++
+ layoutHorizontal();
+ horizontal->setSize(area->property("widthRatio").toReal());
+ horizontal->setPosition(area->property("xPosition").toReal());
+@@ -818,6 +826,9 @@ void QQuickScrollBarAttachedPrivate::initVertical()
+ if (parent && parent == flickable->parentItem())
+ vertical->stackAfter(flickable);
+
++ if (auto control = qobject_cast<QQuickControl*>(q_ptr->parent()))
++ QQuickControlPrivate::unhideOldItem(control, vertical);
++
+ layoutVertical();
+ vertical->setSize(area->property("heightRatio").toReal());
+ vertical->setPosition(area->property("yPosition").toReal());
+diff --git a/qtquickcontrols2/tests/auto/controls/data/tst_scrollview.qml b/qtquickcontrols2/tests/auto/controls/data/tst_scrollview.qml
+index 0e8b08352..cd4931184 100644
+--- a/qtquickcontrols2/tests/auto/controls/data/tst_scrollview.qml
++++ b/qtquickcontrols2/tests/auto/controls/data/tst_scrollview.qml
+@@ -576,4 +576,51 @@ TestCase {
+ verify(newHorizontalScrollBar.visible)
+ verify(!oldHorizontalScrollBar.visible)
+ }
++
++ Component {
++ id: bindingToContentItemAndStandaloneFlickable
++
++ Item {
++ width: 200
++ height: 200
++
++ property alias scrollView: scrollView
++
++ ScrollView {
++ id: scrollView
++ anchors.fill: parent
++ contentItem: listView
++
++ property Item someBinding: contentItem
++ }
++ ListView {
++ id: listView
++ model: 10
++ delegate: ItemDelegate {
++ text: modelData
++ width: listView.width
++ }
++ }
++ }
++ }
++
++ // Tests that scroll bars show up for a ScrollView where
++ // - its contentItem is declared as a standalone, separate item
++ // - there is a binding to contentItem (which causes a default Flickable to be created)
++ function test_bindingToContentItemAndStandaloneFlickable() {
++ let root = createTemporaryObject(bindingToContentItemAndStandaloneFlickable, testCase)
++ verify(root)
++
++ let control = root.scrollView
++ let verticalScrollBar = control.ScrollBar.vertical
++ let horizontalScrollBar = control.ScrollBar.horizontal
++ compare(verticalScrollBar.parent, control)
++ compare(horizontalScrollBar.parent, control)
++ verify(verticalScrollBar.visible)
++ verify(horizontalScrollBar.visible)
++
++ mouseDrag(verticalScrollBar, verticalScrollBar.width / 2, verticalScrollBar.height / 2, 0, 50)
++ verify(verticalScrollBar.active)
++ verify(horizontalScrollBar.active)
++ }
+ }
+diff --git a/qtquickcontrols2/tests/auto/controls/data/tst_switch.qml b/qtquickcontrols2/tests/auto/controls/data/tst_switch.qml
+index b3fab41ca..10b6baa02 100644
+--- a/qtquickcontrols2/tests/auto/controls/data/tst_switch.qml
++++ b/qtquickcontrols2/tests/auto/controls/data/tst_switch.qml
+@@ -608,4 +608,27 @@ TestCase {
+ mouseClick(control.indicator)
+ verify(control.activeFocus)
+ }
++
++ Component {
++ id: deletionOrder1
++ Item {
++ Image { id: innerImage }
++ Switch { indicator: innerImage }
++ }
++ }
++
++ Component {
++ id: deletionOrder2
++ Item {
++ Switch { indicator: innerImage }
++ Image { id: innerImage }
++ }
++ }
++
++ function test_deletionOrder() {
++ var control1 = createTemporaryObject(deletionOrder1, testCase)
++ verify(control1)
++ var control2 = createTemporaryObject(deletionOrder2, testCase)
++ verify(control2)
++ }
+ }
+diff --git a/qtquickcontrols2/tests/auto/qquickpopup/data/releaseAfterExitTransition.qml b/qtquickcontrols2/tests/auto/qquickpopup/data/releaseAfterExitTransition.qml
+new file mode 100644
+index 000000000..9e4598b9f
+--- /dev/null
++++ b/qtquickcontrols2/tests/auto/qquickpopup/data/releaseAfterExitTransition.qml
+@@ -0,0 +1,78 @@
++/****************************************************************************
++**
++** Copyright (C) 2021 The Qt Company Ltd.
++** Contact: https://www.qt.io/licensing/
++**
++** This file is part of the test suite of the Qt Toolkit.
++**
++** $QT_BEGIN_LICENSE:BSD$
++** Commercial License Usage
++** Licensees holding valid commercial Qt licenses may use this file in
++** accordance with the commercial license agreement provided with the
++** Software or, alternatively, in accordance with the terms contained in
++** a written agreement between you and The Qt Company. For licensing terms
++** and conditions see https://www.qt.io/terms-conditions. For further
++** information use the contact form at https://www.qt.io/contact-us.
++**
++** BSD License Usage
++** Alternatively, you may use this file under the terms of the BSD license
++** as follows:
++**
++** "Redistribution and use in source and binary forms, with or without
++** modification, are permitted provided that the following conditions are
++** met:
++** * Redistributions of source code must retain the above copyright
++** notice, this list of conditions and the following disclaimer.
++** * Redistributions in binary form must reproduce the above copyright
++** notice, this list of conditions and the following disclaimer in
++** the documentation and/or other materials provided with the
++** distribution.
++** * Neither the name of The Qt Company Ltd nor the names of its
++** contributors may be used to endorse or promote products derived
++** from this software without specific prior written permission.
++**
++**
++** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
++** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
++** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
++** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
++** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
++** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
++** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
++** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
++** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
++** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
++** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
++**
++** $QT_END_LICENSE$
++**
++****************************************************************************/
++
++import QtQuick 2.15
++import QtQuick.Controls 2.15
++
++ApplicationWindow {
++ id: window
++ width: 400
++ height: 400
++ title: "releaseAfterExitTransition"
++
++ property alias popup: popup
++ property alias modalPopup: modalPopup
++
++ Popup {
++ id: popup
++ y: parent.height - height
++ width: 50
++ height: 50
++ }
++
++ Popup {
++ id: modalPopup
++ modal: true
++ y: parent.height - height
++ width: 50
++ height: 50
++ exit: Transition { PauseAnimation { duration: 100 } }
++ }
++}
+diff --git a/qtquickcontrols2/tests/auto/qquickpopup/tst_qquickpopup.cpp b/qtquickcontrols2/tests/auto/qquickpopup/tst_qquickpopup.cpp
+index 54952d128..3d50e2dd4 100644
+--- a/qtquickcontrols2/tests/auto/qquickpopup/tst_qquickpopup.cpp
++++ b/qtquickcontrols2/tests/auto/qquickpopup/tst_qquickpopup.cpp
+@@ -100,6 +100,7 @@ private slots:
+ void invisibleToolTipOpen();
+ void centerInOverlayWithinStackViewItem();
+ void destroyDuringExitTransition();
++ void releaseAfterExitTransition();
+ };
+
+ void tst_QQuickPopup::initTestCase()
+@@ -1575,6 +1576,34 @@ void tst_QQuickPopup::destroyDuringExitTransition()
+ QVERIFY(!button->isDown());
+ }
+
++void tst_QQuickPopup::releaseAfterExitTransition()
++{
++ QQuickApplicationHelper helper(this, "releaseAfterExitTransition.qml");
++ QVERIFY2(helper.ready, helper.failureMessage());
++
++ QQuickWindow *window = helper.window;
++ window->show();
++ QVERIFY(QTest::qWaitForWindowActive(window));
++
++ QQuickOverlay *overlay = QQuickOverlay::overlay(window);
++ QQuickPopup *modalPopup = window->property("modalPopup").value<QQuickPopup *>();
++ QQuickPopup *popup = window->property("popup").value<QQuickPopup *>();
++
++ modalPopup->open();
++ QTRY_VERIFY(modalPopup->isOpened());
++
++ QTest::mousePress(window, Qt::LeftButton, Qt::NoModifier, QPoint(1, 1));
++ // wait until the transition is finished and the overlay hides itself
++ QTRY_VERIFY(!overlay->isVisible());
++ QTest::mouseRelease(window, Qt::LeftButton, Qt::NoModifier, QPoint(1, 1));
++
++ popup->open();
++ QTRY_VERIFY(popup->isOpened());
++ QTest::mouseClick(window, Qt::LeftButton, Qt::NoModifier, QPoint(1, 1));
++ QTRY_VERIFY(!popup->isOpened());
++}
++
++
+ QTEST_QUICKCONTROLS_MAIN(tst_QQuickPopup)
+
+ #include "tst_qquickpopup.moc"
+Submodule qtscript 5be95f96...4d8e4bd2 (commits not present)
+Submodule qtspeech 17fc9fde..255845e2:
+diff --git a/qtspeech/src/plugins/tts/speechdispatcher/qtexttospeech_speechd.cpp b/qtspeech/src/plugins/tts/speechdispatcher/qtexttospeech_speechd.cpp
+index 6eb74b8..bcc7dd1 100644
+--- a/qtspeech/src/plugins/tts/speechdispatcher/qtexttospeech_speechd.cpp
++++ b/qtspeech/src/plugins/tts/speechdispatcher/qtexttospeech_speechd.cpp
+@@ -357,7 +357,9 @@ QVector<QLocale> QTextToSpeechEngineSpeechd::availableLocales() const
+
+ QVector<QVoice> QTextToSpeechEngineSpeechd::availableVoices() const
+ {
+- return m_voices.values(m_currentLocale.name()).toVector();
++ QList<QVoice> resultList = m_voices.values(m_currentLocale.name());
++ std::reverse(resultList.begin(), resultList.end());
++ return resultList.toVector();
+ }
+
+ // We have no way of knowing our own client_id since speech-dispatcher seems to be incomplete
+Submodule qtsvg 0c05780e..a7a0f249:
+diff --git a/qtsvg/src/plugins/imageformats/svg/qsvgiohandler.cpp b/qtsvg/src/plugins/imageformats/svg/qsvgiohandler.cpp
+index 561e77e..12e0574 100644
+--- a/qtsvg/src/plugins/imageformats/svg/qsvgiohandler.cpp
++++ b/qtsvg/src/plugins/imageformats/svg/qsvgiohandler.cpp
+@@ -191,6 +191,8 @@ bool QSvgIOHandler::read(QImage *image)
+ }
+ }
+ if (!finalSize.isEmpty()) {
++ if (qMax(finalSize.width(), finalSize.height()) > 0xffff)
++ return false; // Assume corrupted file
+ image->fill(d->backColor.rgba());
+ QPainter p(image);
+ d->r.render(&p, bounds);
+diff --git a/qtsvg/src/svg/qsvghandler.cpp b/qtsvg/src/svg/qsvghandler.cpp
+index a5f877f..8dda563 100644
+--- a/qtsvg/src/svg/qsvghandler.cpp
++++ b/qtsvg/src/svg/qsvghandler.cpp
+@@ -1393,9 +1393,10 @@ static void parseFont(QSvgNode *node,
+ case FontSizeNone:
+ break;
+ case FontSizeValue: {
+- QSvgHandler::LengthType dummy; // should always be pixel size
+- fontStyle->setSize(qMin(parseLength(attributes.fontSize, dummy, handler),
+- qreal(0xffff)));
++ QSvgHandler::LengthType type;
++ qreal fs = parseLength(attributes.fontSize, type, handler);
++ fs = convertToPixels(fs, true, type);
++ fontStyle->setSize(qMin(fs, qreal(0xffff)));
+ }
+ break;
+ default:
+@@ -2513,6 +2514,8 @@ static bool parseAnimateTransformNode(QSvgNode *parent,
+ ++s;
+ }
+ }
++ if (vals.count() % 3 != 0)
++ return false;
+
+ bool ok = true;
+ int begin = parseClockValue(beginStr, &ok);
+@@ -2576,6 +2579,8 @@ static QSvgNode *createCircleNode(QSvgNode *parent,
+ qreal ncx = toDouble(cx);
+ qreal ncy = toDouble(cy);
+ qreal nr = toDouble(r);
++ if (nr < 0.0)
++ return nullptr;
+
+ QRectF rect(ncx-nr, ncy-nr, nr*2, nr*2);
+ QSvgNode *circle = new QSvgCircle(parent, rect);
+@@ -3046,15 +3051,16 @@ static QSvgStyleProperty *createRadialGradientNode(QSvgNode *node,
+
+ qreal ncx = 0.5;
+ qreal ncy = 0.5;
+- qreal nr = 0.5;
+ if (!cx.isEmpty())
+ ncx = toDouble(cx);
+ if (!cy.isEmpty())
+ ncy = toDouble(cy);
++
++ qreal nr = 0.0;
+ if (!r.isEmpty())
+ nr = toDouble(r);
+- if (nr < 0.5)
+- nr = 0.5;
++ if (nr <= 0.0)
++ return nullptr;
+
+ qreal nfx = ncx;
+ if (!fx.isEmpty())
+@@ -3350,7 +3356,9 @@ static QSvgNode *createTextNode(QSvgNode *parent,
+ //### editable and rotate not handled
+ QSvgHandler::LengthType type;
+ qreal nx = parseLength(x, type, handler);
++ nx = convertToPixels(nx, true, type);
+ qreal ny = parseLength(y, type, handler);
++ ny = convertToPixels(ny, true, type);
+
+ QSvgNode *text = new QSvgText(parent, QPointF(nx, ny));
+ return text;
+@@ -3691,9 +3699,7 @@ void QSvgHandler::parse()
+ case QXmlStreamReader::EndElement:
+ endElement(xml->name());
+ ++remainingUnfinishedElements;
+- // if we are using somebody else's qxmlstreamreader
+- // we should not read until the end of the stream
+- done = !m_ownsReader && (xml->name() == QLatin1String("svg"));
++ done = (xml->name() == QLatin1String("svg"));
+ break;
+ case QXmlStreamReader::Characters:
+ characters(xml->text());
+diff --git a/qtsvg/src/svg/qsvgstructure.cpp b/qtsvg/src/svg/qsvgstructure.cpp
+index b89608b..89c9e4e 100644
+--- a/qtsvg/src/svg/qsvgstructure.cpp
++++ b/qtsvg/src/svg/qsvgstructure.cpp
+@@ -255,9 +255,13 @@ inline static bool isSupportedSvgFeature(const QString &str)
+ };
+
+ if (str.length() <= MAX_WORD_LENGTH && str.length() >= MIN_WORD_LENGTH) {
++ const char16_t unicode44 = str.at(44).unicode();
++ const char16_t unicode45 = str.at(45).unicode();
++ if (unicode44 >= sizeof(asso_values) || unicode45 >= sizeof(asso_values))
++ return false;
+ const int key = str.length()
+- + asso_values[str.at(45).unicode()]
+- + asso_values[str.at(44).unicode()];
++ + asso_values[unicode45]
++ + asso_values[unicode44];
+ if (key <= MAX_HASH_VALUE && key >= 0)
+ return str == QLatin1String(wordlist[key]);
+ }
+diff --git a/qtsvg/src/svg/qsvgtinydocument.cpp b/qtsvg/src/svg/qsvgtinydocument.cpp
+index 63d0797..19e7154 100644
+--- a/qtsvg/src/svg/qsvgtinydocument.cpp
++++ b/qtsvg/src/svg/qsvgtinydocument.cpp
+@@ -433,8 +433,16 @@ void QSvgTinyDocument::draw(QPainter *p, QSvgExtraStates &)
+ draw(p);
+ }
+
++static bool isValidMatrix(const QTransform &transform)
++{
++ qreal determinant = transform.determinant();
++ return qIsFinite(determinant);
++}
++
+ void QSvgTinyDocument::mapSourceToTarget(QPainter *p, const QRectF &targetRect, const QRectF &sourceRect)
+ {
++ QTransform oldTransform = p->worldTransform();
++
+ QRectF target = targetRect;
+ if (target.isEmpty()) {
+ QPaintDevice *dev = p->device();
+@@ -487,6 +495,9 @@ void QSvgTinyDocument::mapSourceToTarget(QPainter *p, const QRectF &targetRect,
+ }
+ #endif
+ }
++
++ if (!isValidMatrix(p->worldTransform()))
++ p->setWorldTransform(oldTransform);
+ }
+
+ QRectF QSvgTinyDocument::boundsOnElement(const QString &id) const
+diff --git a/qtsvg/tests/auto/qsvgrenderer/tst_qsvgrenderer.cpp b/qtsvg/tests/auto/qsvgrenderer/tst_qsvgrenderer.cpp
+index 36c76ec..db71e02 100644
+--- a/qtsvg/tests/auto/qsvgrenderer/tst_qsvgrenderer.cpp
++++ b/qtsvg/tests/auto/qsvgrenderer/tst_qsvgrenderer.cpp
+@@ -86,6 +86,8 @@ private slots:
+ void oss_fuzz_23731();
+ void oss_fuzz_24131();
+ void oss_fuzz_24738();
++ void illegalAnimateTransform_data();
++ void illegalAnimateTransform();
+
+ #ifndef QT_NO_COMPRESS
+ void testGzLoading();
+@@ -1646,5 +1648,22 @@ void tst_QSvgRenderer::oss_fuzz_24738()
+ QSvgRenderer().load(QByteArray("<svg><path d=\"a 2 1e-212.....\">"));
+ }
+
++void tst_QSvgRenderer::illegalAnimateTransform_data()
++{
++ QTest::addColumn<QByteArray>("svg");
++
++ QTest::newRow("case1") << QByteArray("<svg><animateTransform type=\"rotate\" begin=\"1\" dur=\"2\" values=\"8,0,5,0\">");
++ QTest::newRow("case2") << QByteArray("<svg><animateTransform type=\"rotate\" begin=\"1\" dur=\"2\" values=\"1,2\">");
++ QTest::newRow("case3") << QByteArray("<svg><animateTransform type=\"rotate\" begin=\"1\" dur=\"2\" from=\".. 5 2\" to=\"f\">");
++ QTest::newRow("case4") << QByteArray("<svg><animateTransform type=\"scale\" begin=\"1\" dur=\"2\" by=\"--,..\">");
++}
++
++void tst_QSvgRenderer::illegalAnimateTransform()
++{
++ QFETCH(QByteArray, svg);
++ QSvgRenderer renderer;
++ QVERIFY(!renderer.load(svg)); // also shouldn't assert
++}
++
+ QTEST_MAIN(tst_QSvgRenderer)
+ #include "tst_qsvgrenderer.moc"
+Submodule qttools 6914f7c8..090e526e:
+diff --git a/qttools/src/assistant/qhelpgenerator/helpgenerator.cpp b/qttools/src/assistant/qhelpgenerator/helpgenerator.cpp
+index feab1e2d5..cbfb82507 100644
+--- a/qttools/src/assistant/qhelpgenerator/helpgenerator.cpp
++++ b/qttools/src/assistant/qhelpgenerator/helpgenerator.cpp
+@@ -445,7 +445,9 @@ bool HelpGeneratorPrivate::insertFiles(const QStringList &files, const QString &
+ if (filterSetId < 0)
+ return false;
+ ++filterSetId;
+- for (int attId : qAsConst(filterAtts)) {
++ QList<int> attValues = filterAtts.values();
++ std::sort(attValues.begin(), attValues.end());
++ for (int attId : qAsConst(attValues)) {
+ m_query->prepare(QLatin1String("INSERT INTO FileAttributeSetTable "
+ "VALUES(?, ?)"));
+ m_query->bindValue(0, filterSetId);
+Submodule qtwayland dfb0129c..2904e1b3:
+diff --git a/qtwayland/src/client/configure.json b/qtwayland/src/client/configure.json
+index 2f424580..29222357 100644
+--- a/qtwayland/src/client/configure.json
++++ b/qtwayland/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/qtwayland/src/client/global/qwaylandclientextension.cpp b/qtwayland/src/client/global/qwaylandclientextension.cpp
+index 125b1e19..edccfe63 100644
+--- a/qtwayland/src/client/global/qwaylandclientextension.cpp
++++ b/qtwayland/src/client/global/qwaylandclientextension.cpp
+@@ -74,7 +74,10 @@ void QWaylandClientExtensionPrivate::handleRegistryGlobal(void *data, ::wl_regis
+ void QWaylandClientExtension::addRegistryListener()
+ {
+ Q_D(QWaylandClientExtension);
+- d->waylandIntegration->display()->addRegistryListener(&QWaylandClientExtensionPrivate::handleRegistryGlobal, this);
++ if (!d->registered) {
++ d->waylandIntegration->display()->addRegistryListener(&QWaylandClientExtensionPrivate::handleRegistryGlobal, this);
++ d->registered = true;
++ }
+ }
+
+ QWaylandClientExtension::QWaylandClientExtension(const int ver)
+@@ -88,6 +91,13 @@ QWaylandClientExtension::QWaylandClientExtension(const int ver)
+ QMetaObject::invokeMethod(this, "addRegistryListener", Qt::QueuedConnection);
+ }
+
++QWaylandClientExtension::~QWaylandClientExtension()
++{
++ Q_D(QWaylandClientExtension);
++ if (d->registered && !QCoreApplication::closingDown())
++ d->waylandIntegration->display()->removeListener(&QWaylandClientExtensionPrivate::handleRegistryGlobal, this);
++}
++
+ QtWaylandClient::QWaylandIntegration *QWaylandClientExtension::integration() const
+ {
+ Q_D(const QWaylandClientExtension);
+diff --git a/qtwayland/src/client/global/qwaylandclientextension.h b/qtwayland/src/client/global/qwaylandclientextension.h
+index 98272e57..5bd28398 100644
+--- a/qtwayland/src/client/global/qwaylandclientextension.h
++++ b/qtwayland/src/client/global/qwaylandclientextension.h
+@@ -63,6 +63,7 @@ class Q_WAYLAND_CLIENT_EXPORT QWaylandClientExtension : public QObject
+ Q_PROPERTY(bool active READ isActive NOTIFY activeChanged)
+ public:
+ QWaylandClientExtension(const int version);
++ ~QWaylandClientExtension();
+
+ QtWaylandClient::QWaylandIntegration *integration() const;
+ int version() const;
+diff --git a/qtwayland/src/client/global/qwaylandclientextension_p.h b/qtwayland/src/client/global/qwaylandclientextension_p.h
+index 69cc46a0..9091efbe 100644
+--- a/qtwayland/src/client/global/qwaylandclientextension_p.h
++++ b/qtwayland/src/client/global/qwaylandclientextension_p.h
+@@ -68,6 +68,7 @@ public:
+ QtWaylandClient::QWaylandIntegration *waylandIntegration = nullptr;
+ int version = -1;
+ bool active = false;
++ bool registered = false;
+ };
+
+ class Q_WAYLAND_CLIENT_EXPORT QWaylandClientExtensionTemplatePrivate : public QWaylandClientExtensionPrivate
+diff --git a/qtwayland/src/client/qwaylanddatadevice.cpp b/qtwayland/src/client/qwaylanddatadevice.cpp
+index 7e2e3308..e3e60ed5 100644
+--- a/qtwayland/src/client/qwaylanddatadevice.cpp
++++ b/qtwayland/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,7 +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::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;
+@@ -152,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;
+ }
+@@ -162,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();
+ }
+ }
+
+@@ -186,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,
+@@ -197,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()
+@@ -235,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());
+
+@@ -246,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)
+
+@@ -277,14 +296,10 @@ void QWaylandDataDevice::selectionSourceCancelled()
+ #if QT_CONFIG(draganddrop)
+ void QWaylandDataDevice::dragSourceCancelled()
+ {
++ static_cast<QWaylandDrag *>(QGuiApplicationPrivate::platformIntegration()->drag())->finishDrag();
+ 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));
+@@ -297,6 +312,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/qtwayland/src/client/qwaylanddatadevice_p.h b/qtwayland/src/client/qwaylanddatadevice_p.h
+index 16c3ad28..801dcc2c 100644
+--- a/qtwayland/src/client/qwaylanddatadevice_p.h
++++ b/qtwayland/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/qtwayland/src/client/qwaylanddatadevicemanager.cpp b/qtwayland/src/client/qwaylanddatadevicemanager.cpp
+index 35d67307..6dc4f77f 100644
+--- a/qtwayland/src/client/qwaylanddatadevicemanager.cpp
++++ b/qtwayland/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/qtwayland/src/client/qwaylanddatadevicemanager_p.h b/qtwayland/src/client/qwaylanddatadevicemanager_p.h
+index bd05c0fb..510d9be4 100644
+--- a/qtwayland/src/client/qwaylanddatadevicemanager_p.h
++++ b/qtwayland/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/qtwayland/src/client/qwaylanddataoffer.cpp b/qtwayland/src/client/qwaylanddataoffer.cpp
+index 2297e8a1..fe0ea8c9 100644
+--- a/qtwayland/src/client/qwaylanddataoffer.cpp
++++ b/qtwayland/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)
+ {
+@@ -163,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");
+diff --git a/qtwayland/src/client/qwaylanddataoffer_p.h b/qtwayland/src/client/qwaylanddataoffer_p.h
+index 9cf1483c..6f667398 100644
+--- a/qtwayland/src/client/qwaylanddataoffer_p.h
++++ b/qtwayland/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/qtwayland/src/client/qwaylanddatasource.cpp b/qtwayland/src/client/qwaylanddatasource.cpp
+index f45122fb..5599cbd4 100644
+--- a/qtwayland/src/client/qwaylanddatasource.cpp
++++ b/qtwayland/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/qtwayland/src/client/qwaylanddatasource_p.h b/qtwayland/src/client/qwaylanddatasource_p.h
+index 25afff79..96f07bc3 100644
+--- a/qtwayland/src/client/qwaylanddatasource_p.h
++++ b/qtwayland/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/qtwayland/src/client/qwaylanddisplay.cpp b/qtwayland/src/client/qwaylanddisplay.cpp
+index f10c1f79..c01e238b 100644
+--- a/qtwayland/src/client/qwaylanddisplay.cpp
++++ b/qtwayland/src/client/qwaylanddisplay.cpp
+@@ -85,10 +85,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)
+@@ -158,17 +351,16 @@ 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)
+ {
++ if (m_eventThread)
++ m_eventThread->stop();
++
++ if (m_frameEventQueueThread)
++ m_frameEventQueueThread->stop();
++
+ if (mSyncCallback)
+ wl_callback_destroy(mSyncCallback);
+
+@@ -187,6 +379,21 @@ 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
++// 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()
+@@ -203,98 +410,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
+@@ -345,7 +491,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));
+@@ -354,7 +500,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));
+@@ -369,6 +515,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));
+@@ -427,6 +575,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;
+ }
+@@ -452,9 +607,10 @@ void QWaylandDisplay::addRegistryListener(RegistryListener listener, void *data)
+
+ void QWaylandDisplay::removeListener(RegistryListener listener, void *data)
+ {
+- std::remove_if(mRegistryListeners.begin(), mRegistryListeners.end(), [=](Listener l){
++ auto iter = std::remove_if(mRegistryListeners.begin(), mRegistryListeners.end(), [=](Listener l){
+ return (l.listener == listener && l.data == data);
+ });
++ mRegistryListeners.erase(iter, mRegistryListeners.end());
+ }
+
+ uint32_t QWaylandDisplay::currentTimeMillisec()
+@@ -467,50 +623,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
+@@ -574,14 +689,10 @@ void QWaylandDisplay::handleKeyboardFocusChanged(QWaylandInputDevice *inputDevic
+ if (mLastKeyboardFocus == keyboardFocus)
+ return;
+
+- if (mWaylandIntegration->mShellIntegration) {
+- mWaylandIntegration->mShellIntegration->handleKeyboardFocusChanged(keyboardFocus, mLastKeyboardFocus);
+- } else {
+- if (keyboardFocus)
+- handleWindowActivated(keyboardFocus);
+- if (mLastKeyboardFocus)
+- handleWindowDeactivated(mLastKeyboardFocus);
+- }
++ if (keyboardFocus)
++ handleWindowActivated(keyboardFocus);
++ if (mLastKeyboardFocus)
++ handleWindowDeactivated(mLastKeyboardFocus);
+
+ mLastKeyboardFocus = keyboardFocus;
+ }
+@@ -600,6 +711,19 @@ void QWaylandDisplay::handleWaylandSync()
+ QWindow *activeWindow = mActiveWindows.empty() ? nullptr : mActiveWindows.last()->window();
+ if (activeWindow != QGuiApplication::focusWindow())
+ QWindowSystemInterface::handleWindowActivated(activeWindow);
++
++ if (!activeWindow) {
++ if (lastInputDevice()) {
++#if QT_CONFIG(clipboard)
++ if (auto *dataDevice = lastInputDevice()->dataDevice())
++ dataDevice->invalidateSelectionOffer();
++#endif
++#if QT_CONFIG(wayland_client_primary_selection)
++ if (auto *device = lastInputDevice()->primarySelectionDevice())
++ device->invalidateSelectionOffer();
++#endif
++ }
++ }
+ }
+
+ const wl_callback_listener QWaylandDisplay::syncCallbackListener = {
+@@ -626,6 +750,13 @@ QWaylandInputDevice *QWaylandDisplay::defaultInputDevice() const
+ return mInputDevices.isEmpty() ? 0 : mInputDevices.first();
+ }
+
++bool QWaylandDisplay::isKeyboardAvailable() const
++{
++ return std::any_of(
++ mInputDevices.constBegin(), mInputDevices.constEnd(),
++ [this](const QWaylandInputDevice *device) { return device->keyboard() != nullptr; });
++}
++
+ #if QT_CONFIG(cursor)
+
+ QWaylandCursor *QWaylandDisplay::waylandCursor()
+@@ -652,4 +783,6 @@ QWaylandCursorTheme *QWaylandDisplay::loadCursorTheme(const QString &name, int p
+
+ } // namespace QtWaylandClient
+
++#include "qwaylanddisplay.moc"
++
+ QT_END_NAMESPACE
+diff --git a/qtwayland/src/client/qwaylanddisplay_p.h b/qtwayland/src/client/qwaylanddisplay_p.h
+index 3b092bc8..42bc661d 100644
+--- a/qtwayland/src/client/qwaylanddisplay_p.h
++++ b/qtwayland/src/client/qwaylanddisplay_p.h
+@@ -109,6 +109,7 @@ class QWaylandSurface;
+ class QWaylandShellIntegration;
+ class QWaylandCursor;
+ class QWaylandCursorTheme;
++class EventThread;
+
+ typedef void (*RegistryListener)(void *data,
+ struct wl_registry *registry,
+@@ -120,15 +121,11 @@ 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;
+
++ void initialize();
++
+ #if QT_CONFIG(xkbcommon)
+ struct xkb_context *xkbContext() const { return mXkbContext.get(); }
+ #endif
+@@ -210,11 +207,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();
+@@ -237,6 +234,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;
+@@ -273,11 +273,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/qtwayland/src/client/qwaylanddnd.cpp b/qtwayland/src/client/qwaylanddnd.cpp
+index 6535aa16..7c53f5fa 100644
+--- a/qtwayland/src/client/qwaylanddnd.cpp
++++ b/qtwayland/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
+@@ -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)
+@@ -103,33 +106,41 @@ 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);
++
++ if (drag())
++ drag()->deleteLater();
++}
++
++bool QWaylandDrag::ownsDragObject() const
++{
++ return true;
+ }
+
+ }
+diff --git a/qtwayland/src/client/qwaylanddnd_p.h b/qtwayland/src/client/qwaylanddnd_p.h
+index 474fe2ab..46f629ac 100644
+--- a/qtwayland/src/client/qwaylanddnd_p.h
++++ b/qtwayland/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;
+@@ -82,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;
+diff --git a/qtwayland/src/client/qwaylandinputdevice.cpp b/qtwayland/src/client/qwaylandinputdevice.cpp
+index 613fe862..4b90de84 100644
+--- a/qtwayland/src/client/qwaylandinputdevice.cpp
++++ b/qtwayland/src/client/qwaylandinputdevice.cpp
+@@ -685,6 +685,11 @@ public:
+
+ void QWaylandInputDevice::Pointer::pointer_leave(uint32_t time, struct wl_surface *surface)
+ {
++ invalidateFocus();
++ mButtons = Qt::NoButton;
++
++ mParent->mTime = time;
++
+ // The event may arrive after destroying the window, indicated by
+ // a null surface.
+ if (!surface)
+@@ -696,11 +701,6 @@ void QWaylandInputDevice::Pointer::pointer_leave(uint32_t time, struct wl_surfac
+
+ if (!QWaylandWindow::mouseGrab())
+ setFrameEvent(new LeaveEvent(window, mSurfacePos, mGlobalPos));
+-
+- invalidateFocus();
+- mButtons = Qt::NoButton;
+-
+- mParent->mTime = time;
+ }
+
+ class MotionEvent : public QWaylandPointerEvent
+@@ -1300,14 +1300,6 @@ void QWaylandInputDevice::Keyboard::handleFocusDestroyed()
+ void QWaylandInputDevice::Keyboard::handleFocusLost()
+ {
+ mFocus = nullptr;
+-#if QT_CONFIG(clipboard)
+- if (auto *dataDevice = mParent->dataDevice())
+- dataDevice->invalidateSelectionOffer();
+-#endif
+-#if QT_CONFIG(wayland_client_primary_selection)
+- if (auto *device = mParent->primarySelectionDevice())
+- device->invalidateSelectionOffer();
+-#endif
+ mParent->mQDisplay->handleKeyboardFocusChanged(mParent);
+ mRepeatTimer.stop();
+ }
+@@ -1396,6 +1388,7 @@ void QWaylandInputDevice::Touch::touch_cancel()
+ if (touchExt)
+ touchExt->touchCanceled();
+
++ mFocus = nullptr;
+ QWindowSystemInterface::handleTouchCancelEvent(nullptr, mParent->mTouchDevice);
+ }
+
+diff --git a/qtwayland/src/client/qwaylandintegration.cpp b/qtwayland/src/client/qwaylandintegration.cpp
+index c53ccb78..54861600 100644
+--- a/qtwayland/src/client/qwaylandintegration.cpp
++++ b/qtwayland/src/client/qwaylandintegration.cpp
+@@ -125,6 +125,9 @@ QWaylandIntegration::QWaylandIntegration()
+ #endif
+
+ reconfigureInputContext();
++
++ QWaylandWindow::fixedToplevelPositions =
++ !qEnvironmentVariableIsSet("QT_WAYLAND_DISABLE_FIXED_POSITIONS");
+ }
+
+ QWaylandIntegration::~QWaylandIntegration()
+@@ -192,14 +195,18 @@ QAbstractEventDispatcher *QWaylandIntegration::createEventDispatcher() const
+
+ void QWaylandIntegration::initialize()
+ {
++ mDisplay->initEventThread();
++
++ // 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()));
+
+- 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()));
+-
+ // Qt does not support running with no screens
+ mDisplay->ensureScreen();
+ }
+@@ -262,6 +269,14 @@ QWaylandDisplay *QWaylandIntegration::display() const
+ return mDisplay.data();
+ }
+
++Qt::KeyboardModifiers QWaylandIntegration::queryKeyboardModifiers() const
++{
++ if (auto *seat = mDisplay->currentInputDevice()) {
++ return seat->modifiers();
++ }
++ return Qt::NoModifier;
++}
++
+ QList<int> QWaylandIntegration::possibleKeys(const QKeyEvent *event) const
+ {
+ if (auto *seat = mDisplay->currentInputDevice())
+@@ -479,7 +494,7 @@ void QWaylandIntegration::reconfigureInputContext()
+ }
+ #endif
+
+- qCDebug(lcQpaWayland) << "using input method:" << inputContext()->metaObject()->className();
++ qCDebug(lcQpaWayland) << "using input method:" << (inputContext() ? inputContext()->metaObject()->className() : "<none>");
+ }
+
+ QWaylandShellIntegration *QWaylandIntegration::createShellIntegration(const QString &integrationName)
+diff --git a/qtwayland/src/client/qwaylandintegration_p.h b/qtwayland/src/client/qwaylandintegration_p.h
+index ff70ae25..73b80658 100644
+--- a/qtwayland/src/client/qwaylandintegration_p.h
++++ b/qtwayland/src/client/qwaylandintegration_p.h
+@@ -107,6 +107,8 @@ public:
+
+ QWaylandDisplay *display() const;
+
++ Qt::KeyboardModifiers queryKeyboardModifiers() const override;
++
+ QList<int> possibleKeys(const QKeyEvent *event) const override;
+
+ QStringList themeNames() const override;
+diff --git a/qtwayland/src/client/qwaylandprimaryselectionv1.cpp b/qtwayland/src/client/qwaylandprimaryselectionv1.cpp
+index 832f9678..ea508771 100644
+--- a/qtwayland/src/client/qwaylandprimaryselectionv1.cpp
++++ b/qtwayland/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)
+diff --git a/qtwayland/src/client/qwaylandscreen.cpp b/qtwayland/src/client/qwaylandscreen.cpp
+index 6cb337de..5537dafd 100644
+--- a/qtwayland/src/client/qwaylandscreen.cpp
++++ b/qtwayland/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))
+@@ -72,7 +72,7 @@ QWaylandScreen::QWaylandScreen(QWaylandDisplay *waylandDisplay, int version, uin
+ qCWarning(lcQpaWayland) << "wl_output done event not supported by compositor,"
+ << "QScreen may not work correctly";
+ mWaylandDisplay->forceRoundTrip(); // Give the compositor a chance to send geometry etc.
+- mOutputDone = true; // Fake the done event
++ mProcessedEvents |= OutputDoneEvent; // Fake the done event
+ maybeInitialize();
+ }
+ }
+@@ -81,16 +81,29 @@ 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
++{
++ uint ret = OutputDoneEvent;
++
++ if (mWaylandDisplay->xdgOutputManager()) {
++ ret |= XdgOutputNameEvent;
++
++ if (mWaylandDisplay->xdgOutputManager()->version() < 3)
++ ret |= XdgOutputDoneEvent;
++ }
++ return ret;
+ }
+
+ void QWaylandScreen::maybeInitialize()
+ {
+ Q_ASSERT(!mInitialized);
+
+- if (!mOutputDone)
+- return;
+-
+- if (mWaylandDisplay->xdgOutputManager() && !mXdgOutputDone)
++ const uint requiredEvents = this->requiredEvents();
++ if ((mProcessedEvents & requiredEvents) != requiredEvents)
+ return;
+
+ mInitialized = true;
+@@ -276,9 +289,8 @@ void QWaylandScreen::output_scale(int32_t factor)
+
+ void QWaylandScreen::output_done()
+ {
+- mOutputDone = true;
+- if (zxdg_output_v1::isInitialized() && mWaylandDisplay->xdgOutputManager()->version() >= 3)
+- mXdgOutputDone = true;
++ mProcessedEvents |= OutputDoneEvent;
++
+ if (mInitialized) {
+ updateOutputProperties();
+ if (zxdg_output_v1::isInitialized())
+@@ -339,7 +351,7 @@ void QWaylandScreen::zxdg_output_v1_done()
+ if (Q_UNLIKELY(mWaylandDisplay->xdgOutputManager()->version() >= 3))
+ qWarning(lcQpaWayland) << "zxdg_output_v1.done received on version 3 or newer, this is most likely a bug in the compositor";
+
+- mXdgOutputDone = true;
++ mProcessedEvents |= XdgOutputDoneEvent;
+ if (mInitialized)
+ updateXdgOutputProperties();
+ else
+@@ -348,7 +360,11 @@ void QWaylandScreen::zxdg_output_v1_done()
+
+ void QWaylandScreen::zxdg_output_v1_name(const QString &name)
+ {
++ if (Q_UNLIKELY(mInitialized))
++ qWarning(lcQpaWayland) << "zxdg_output_v1.name received after output has been initialized, this is most likely a bug in the compositor";
++
+ mOutputName = name;
++ mProcessedEvents |= XdgOutputNameEvent;
+ }
+
+ void QWaylandScreen::updateXdgOutputProperties()
+diff --git a/qtwayland/src/client/qwaylandscreen_p.h b/qtwayland/src/client/qwaylandscreen_p.h
+index df1c94f2..050cfdc0 100644
+--- a/qtwayland/src/client/qwaylandscreen_p.h
++++ b/qtwayland/src/client/qwaylandscreen_p.h
+@@ -116,6 +116,13 @@ public:
+ static QWaylandScreen *fromWlOutput(::wl_output *output);
+
+ private:
++ enum Event : uint {
++ XdgOutputDoneEvent = 0x1,
++ OutputDoneEvent = 0x2,
++ XdgOutputNameEvent = 0x4,
++ };
++ uint requiredEvents() const;
++
+ void output_mode(uint32_t flags, int width, int height, int refresh) override;
+ void output_geometry(int32_t x, int32_t y,
+ int32_t width, int32_t height,
+@@ -148,8 +155,7 @@ private:
+ QSize mPhysicalSize;
+ QString mOutputName;
+ Qt::ScreenOrientation m_orientation = Qt::PrimaryOrientation;
+- bool mOutputDone = false;
+- bool mXdgOutputDone = false;
++ uint mProcessedEvents = 0;
+ bool mInitialized = false;
+
+ #if QT_CONFIG(cursor)
+diff --git a/qtwayland/src/client/qwaylandshmbackingstore.cpp b/qtwayland/src/client/qwaylandshmbackingstore.cpp
+index dc7ff670..41cffdf7 100644
+--- a/qtwayland/src/client/qwaylandshmbackingstore.cpp
++++ b/qtwayland/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
+@@ -74,8 +78,10 @@ QWaylandShmBuffer::QWaylandShmBuffer(QWaylandDisplay *display,
+ int alloc = stride * size.height();
+ int fd = -1;
+
+-#ifdef SYS_memfd_create
+- fd = syscall(SYS_memfd_create, "wayland-shm", MFD_CLOEXEC);
++#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);
+ #endif
+
+ QScopedPointer<QFile> filePointer;
+diff --git a/qtwayland/src/client/qwaylandwindow.cpp b/qtwayland/src/client/qwaylandwindow.cpp
+index cb82857a..fb2c59dc 100644
+--- a/qtwayland/src/client/qwaylandwindow.cpp
++++ b/qtwayland/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,9 +94,6 @@ QWaylandWindow::QWaylandWindow(QWindow *window, QWaylandDisplay *display)
+
+ QWaylandWindow::~QWaylandWindow()
+ {
+- mDisplay->destroyFrameQueue(mFrameQueue);
+- mDisplay->handleWindowDestroyed(this);
+-
+ delete mWindowDecoration;
+
+ if (mSurface)
+@@ -243,6 +239,7 @@ bool QWaylandWindow::shouldCreateSubSurface() const
+
+ void QWaylandWindow::reset()
+ {
++ closeChildPopups();
+ delete mShellSurface;
+ mShellSurface = nullptr;
+ delete mSubSurfaceWindow;
+@@ -255,17 +252,22 @@ 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();
+ mQueuedBuffer = nullptr;
++
++ mDisplay->handleWindowDestroyed(this);
+ }
+
+ QWaylandWindow *QWaylandWindow::fromWlSurface(::wl_surface *surface)
+@@ -351,19 +353,25 @@ 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()) {
+ 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());
+@@ -374,7 +382,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)
+@@ -399,21 +407,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);
+@@ -433,10 +426,7 @@ void QWaylandWindow::setVisible(bool visible)
+ lastVisible = visible;
+
+ if (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
+@@ -444,7 +434,6 @@ void QWaylandWindow::setVisible(bool visible)
+ // QWaylandShmBackingStore::beginPaint().
+ } else {
+ sendExposeEvent(QRect());
+- closePopups(this);
+ reset();
+ }
+ }
+@@ -556,12 +545,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();
+
+@@ -583,7 +572,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)
+@@ -619,8 +612,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();
+@@ -635,42 +634,53 @@ 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);
+- 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();
+
+ // 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;
+- };
++ 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();
++ };
+
++ 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();
+ }
+
+ 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";
+@@ -868,6 +878,17 @@ bool QWaylandWindow::createDecoration()
+ subsurf->set_position(pos.x() + m.left(), pos.y() + m.top());
+ }
+ sendExposeEvent(QRect(QPoint(), geometry().size()));
++
++ // This is a special case where the buffer is recreated, but since
++ // the content rect remains the same, the widgets remain the same
++ // size and are not redrawn, leaving the new buffer empty. As a simple
++ // work-around, we trigger a full extra update whenever the client-side
++ // window decorations are toggled while the window is showing.
++ // Note: createDecoration() is sometimes called from the render thread
++ // of Qt Quick. This is essentially wrong and could potentially cause problems,
++ // but until the underlying issue has been fixed, we have to use invokeMethod()
++ // here to avoid asserts.
++ QMetaObject::invokeMethod(window(), &QWindow::requestUpdate);
+ }
+
+ return mWindowDecoration;
+@@ -1023,6 +1044,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) {
+@@ -1094,10 +1122,18 @@ bool QWaylandWindow::setMouseGrabEnabled(bool grab)
+ return true;
+ }
+
++Qt::WindowStates QWaylandWindow::windowStates() const
++{
++ return mLastReportedWindowStates;
++}
++
+ void QWaylandWindow::handleWindowStatesChanged(Qt::WindowStates states)
+ {
+ createDecoration();
+- QWindowSystemInterface::handleWindowStateChanged(window(), states, mLastReportedWindowStates);
++ Qt::WindowStates statesWithoutActive = states & ~Qt::WindowActive;
++ Qt::WindowStates lastStatesWithoutActive = mLastReportedWindowStates & ~Qt::WindowActive;
++ QWindowSystemInterface::handleWindowStateChanged(window(), statesWithoutActive,
++ lastStatesWithoutActive);
+ mLastReportedWindowStates = states;
+ }
+
+@@ -1139,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()
+@@ -1160,8 +1201,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
+@@ -1174,7 +1218,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);
+ }
+@@ -1185,19 +1234,18 @@ void QWaylandWindow::requestUpdate()
+ void QWaylandWindow::handleUpdate()
+ {
+ qCDebug(lcWaylandBackingstore) << "handleUpdate" << QThread::currentThread();
++
+ // TODO: Should sync subsurfaces avoid requesting frame callbacks?
+ QReadLocker lock(&mSurfaceLock);
+ if (!mSurface)
+ return;
+
+- if (mFrameCallback) {
+- wl_callback_destroy(mFrameCallback);
+- mFrameCallback = nullptr;
+- }
++ QMutexLocker locker(&mFrameSyncMutex);
++ if (mWaitingForFrameCallback)
++ return;
+
+- 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);
++ 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);
+@@ -1207,6 +1255,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);
+@@ -1267,6 +1317,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/qtwayland/src/client/qwaylandwindow_p.h b/qtwayland/src/client/qwaylandwindow_p.h
+index 01337cff..2f219d8c 100644
+--- a/qtwayland/src/client/qwaylandwindow_p.h
++++ b/qtwayland/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;
+@@ -148,6 +151,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;
+@@ -206,6 +210,10 @@ public:
+ void handleUpdate();
+ void deliverUpdateRequest() override;
+
++ void addChildPopup(QWaylandWindow* child);
++ void removeChildPopup(QWaylandWindow* child);
++ void closeChildPopups();
++
+ public slots:
+ void applyConfigure();
+
+@@ -215,7 +223,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;
+@@ -225,13 +237,14 @@ protected:
+ Qt::MouseButtons mMousePressedInContentArea = Qt::NoButton;
+
+ 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;
+- QWaylandDisplay::FrameQueue mFrameQueue;
++ 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;
+
+ // True when we have called deliverRequestUpdate, but the client has not yet attached a new buffer
+@@ -261,6 +274,8 @@ protected:
+ QWaylandBuffer *mQueuedBuffer = nullptr;
+ QRegion mQueuedBufferDamage;
+
++ QList<QPointer<QWaylandWindow>> mChildPopups;
++
+ private:
+ void setGeometry_helper(const QRect &rect);
+ void initWindow();
+@@ -283,12 +298,10 @@ private:
+ QRect mLastExposeGeometry;
+
+ static const wl_callback_listener callbackListener;
+- void handleFrameCallback();
++ void handleFrameCallback(struct ::wl_callback* callback);
+
+ static QWaylandWindow *mMouseGrab;
+
+- mutable QReadWriteLock mSurfaceLock;
+-
+ friend class QWaylandSubSurface;
+ };
+
+diff --git a/qtwayland/src/client/shellintegration/qwaylandshellintegration_p.h b/qtwayland/src/client/shellintegration/qwaylandshellintegration_p.h
+index ccad0048..4cc9b3b8 100644
+--- a/qtwayland/src/client/shellintegration/qwaylandshellintegration_p.h
++++ b/qtwayland/src/client/shellintegration/qwaylandshellintegration_p.h
+@@ -73,11 +73,10 @@ public:
+ return true;
+ }
+ virtual QWaylandShellSurface *createShellSurface(QWaylandWindow *window) = 0;
++ // kept for binary compat with layer-shell-qt
+ virtual void handleKeyboardFocusChanged(QWaylandWindow *newFocus, QWaylandWindow *oldFocus) {
+- if (newFocus)
+- m_display->handleWindowActivated(newFocus);
+- if (oldFocus)
+- m_display->handleWindowDeactivated(oldFocus);
++ Q_UNUSED(newFocus);
++ Q_UNUSED(oldFocus);
+ }
+ virtual void *nativeResourceForWindow(const QByteArray &resource, QWindow *window) {
+ Q_UNUSED(resource);
+diff --git a/qtwayland/src/compositor/configure.json b/qtwayland/src/compositor/configure.json
+index bcfd5215..da95d07b 100644
+--- a/qtwayland/src/compositor/configure.json
++++ b/qtwayland/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"
+ }
+ },
+
+diff --git a/qtwayland/src/hardwareintegration/client/wayland-egl/qwaylandeglwindow.cpp b/qtwayland/src/hardwareintegration/client/wayland-egl/qwaylandeglwindow.cpp
+index 7889f575..64140672 100644
+--- a/qtwayland/src/hardwareintegration/client/wayland-egl/qwaylandeglwindow.cpp
++++ b/qtwayland/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>
+@@ -124,6 +125,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();
+@@ -131,14 +133,16 @@ void QWaylandEglWindow::updateSurface(bool create)
+ if (!disableResizeCheck) {
+ wl_egl_window_get_attached_size(m_waylandEglWindow, ¤t_width, ¤t_height);
+ }
+- if (disableResizeCheck || (current_width != sizeWithMargins.width() || current_height != sizeWithMargins.height())) {
++ if (disableResizeCheck || (current_width != sizeWithMargins.width() || current_height != sizeWithMargins.height()) || m_requestedSize != sizeWithMargins) {
+ wl_egl_window_resize(m_waylandEglWindow, sizeWithMargins.width(), sizeWithMargins.height(), mOffset.x(), mOffset.y());
++ m_requestedSize = sizeWithMargins;
+ mOffset = QPoint();
+
+ 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;
+ }
+
+ if (!m_eglSurface && m_waylandEglWindow && create) {
+diff --git a/qtwayland/src/hardwareintegration/client/wayland-egl/qwaylandeglwindow.h b/qtwayland/src/hardwareintegration/client/wayland-egl/qwaylandeglwindow.h
+index 5b1f4d56..0079dfef 100644
+--- a/qtwayland/src/hardwareintegration/client/wayland-egl/qwaylandeglwindow.h
++++ b/qtwayland/src/hardwareintegration/client/wayland-egl/qwaylandeglwindow.h
+@@ -88,6 +88,7 @@ private:
+ mutable QOpenGLFramebufferObject *m_contentFBO = nullptr;
+
+ QSurfaceFormat m_format;
++ QSize m_requestedSize;
+ };
+
+ }
+diff --git a/qtwayland/src/hardwareintegration/compositor/linux-dmabuf-unstable-v1/linuxdmabuf.h b/qtwayland/src/hardwareintegration/compositor/linux-dmabuf-unstable-v1/linuxdmabuf.h
+index 56a710c3..c6a8b6c6 100644
+--- a/qtwayland/src/hardwareintegration/compositor/linux-dmabuf-unstable-v1/linuxdmabuf.h
++++ b/qtwayland/src/hardwareintegration/compositor/linux-dmabuf-unstable-v1/linuxdmabuf.h
+@@ -41,6 +41,8 @@
+ #include <QtCore/QTextStream>
+ #include <QtGui/QOpenGLTexture>
+
++#include <array>
++
+ #include <EGL/egl.h>
+ #include <EGL/eglext.h>
+
+diff --git a/qtwayland/src/plugins/decorations/bradient/main.cpp b/qtwayland/src/plugins/decorations/bradient/main.cpp
+index e75fda3c..fa885143 100644
+--- a/qtwayland/src/plugins/decorations/bradient/main.cpp
++++ b/qtwayland/src/plugins/decorations/bradient/main.cpp
+@@ -164,13 +164,10 @@ void QWaylandBradientDecoration::paint(QPaintDevice *device)
+ // Window icon
+ QIcon icon = waylandWindow()->windowIcon();
+ if (!icon.isNull()) {
+- QPixmap pixmap = icon.pixmap(QSize(128, 128));
+- QPixmap scaled = pixmap.scaled(22, 22, Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
+-
+ QRectF iconRect(0, 0, 22, 22);
+- p.drawPixmap(iconRect.adjusted(margins().left() + BUTTON_SPACING, 4,
+- margins().left() + BUTTON_SPACING, 4),
+- scaled, iconRect);
++ iconRect.adjust(margins().left() + BUTTON_SPACING, 4,
++ margins().left() + BUTTON_SPACING, 4),
++ icon.paint(&p, iconRect.toRect());
+ }
+
+ // Window title
+diff --git a/qtwayland/src/plugins/shellintegration/xdg-shell-v5/qwaylandxdgpopupv5.cpp b/qtwayland/src/plugins/shellintegration/xdg-shell-v5/qwaylandxdgpopupv5.cpp
+index 85d25e3c..60bdd491 100644
+--- a/qtwayland/src/plugins/shellintegration/xdg-shell-v5/qwaylandxdgpopupv5.cpp
++++ b/qtwayland/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/qtwayland/src/plugins/shellintegration/xdg-shell-v5/qwaylandxdgpopupv5_p.h b/qtwayland/src/plugins/shellintegration/xdg-shell-v5/qwaylandxdgpopupv5_p.h
+index 7494f6a6..d85f130b 100644
+--- a/qtwayland/src/plugins/shellintegration/xdg-shell-v5/qwaylandxdgpopupv5_p.h
++++ b/qtwayland/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/qtwayland/src/plugins/shellintegration/xdg-shell-v5/qwaylandxdgshellv5.cpp b/qtwayland/src/plugins/shellintegration/xdg-shell-v5/qwaylandxdgshellv5.cpp
+index 7e242c4a..def8452a 100644
+--- a/qtwayland/src/plugins/shellintegration/xdg-shell-v5/qwaylandxdgshellv5.cpp
++++ b/qtwayland/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/qtwayland/src/plugins/shellintegration/xdg-shell-v5/qwaylandxdgshellv5integration.cpp b/qtwayland/src/plugins/shellintegration/xdg-shell-v5/qwaylandxdgshellv5integration.cpp
+index 4e25949f..cfc60939 100644
+--- a/qtwayland/src/plugins/shellintegration/xdg-shell-v5/qwaylandxdgshellv5integration.cpp
++++ b/qtwayland/src/plugins/shellintegration/xdg-shell-v5/qwaylandxdgshellv5integration.cpp
+@@ -85,13 +85,6 @@ QWaylandShellSurface *QWaylandXdgShellV5Integration::createShellSurface(QWayland
+ return m_xdgShell->createXdgSurface(window);
+ }
+
+-void QWaylandXdgShellV5Integration::handleKeyboardFocusChanged(QWaylandWindow *newFocus, QWaylandWindow *oldFocus) {
+- if (newFocus && qobject_cast<QWaylandXdgPopupV5 *>(newFocus->shellSurface()))
+- m_display->handleWindowActivated(newFocus);
+- if (oldFocus && qobject_cast<QWaylandXdgPopupV5 *>(oldFocus->shellSurface()))
+- m_display->handleWindowDeactivated(oldFocus);
+-}
+-
+ }
+
+ QT_END_NAMESPACE
+diff --git a/qtwayland/src/plugins/shellintegration/xdg-shell-v5/qwaylandxdgshellv5integration_p.h b/qtwayland/src/plugins/shellintegration/xdg-shell-v5/qwaylandxdgshellv5integration_p.h
+index ce6bdb9e..aed88670 100644
+--- a/qtwayland/src/plugins/shellintegration/xdg-shell-v5/qwaylandxdgshellv5integration_p.h
++++ b/qtwayland/src/plugins/shellintegration/xdg-shell-v5/qwaylandxdgshellv5integration_p.h
+@@ -67,7 +67,6 @@ public:
+ QWaylandXdgShellV5Integration() {}
+ bool initialize(QWaylandDisplay *display) override;
+ QWaylandShellSurface *createShellSurface(QWaylandWindow *window) override;
+- void handleKeyboardFocusChanged(QWaylandWindow *newFocus, QWaylandWindow *oldFocus) override;
+
+ private:
+ QScopedPointer<QWaylandXdgShellV5> m_xdgShell;
+diff --git a/qtwayland/src/plugins/shellintegration/xdg-shell-v6/qwaylandxdgshellv6.cpp b/qtwayland/src/plugins/shellintegration/xdg-shell-v6/qwaylandxdgshellv6.cpp
+index 8c371661..151c78e3 100644
+--- a/qtwayland/src/plugins/shellintegration/xdg-shell-v6/qwaylandxdgshellv6.cpp
++++ b/qtwayland/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/qtwayland/src/plugins/shellintegration/xdg-shell-v6/qwaylandxdgshellv6integration.cpp b/qtwayland/src/plugins/shellintegration/xdg-shell-v6/qwaylandxdgshellv6integration.cpp
+index 03164316..e8da8ba1 100644
+--- a/qtwayland/src/plugins/shellintegration/xdg-shell-v6/qwaylandxdgshellv6integration.cpp
++++ b/qtwayland/src/plugins/shellintegration/xdg-shell-v6/qwaylandxdgshellv6integration.cpp
+@@ -68,20 +68,6 @@ QWaylandShellSurface *QWaylandXdgShellV6Integration::createShellSurface(QWayland
+ return m_xdgShell->getXdgSurface(window);
+ }
+
+-void QWaylandXdgShellV6Integration::handleKeyboardFocusChanged(QWaylandWindow *newFocus, QWaylandWindow *oldFocus)
+-{
+- if (newFocus) {
+- auto *xdgSurface = qobject_cast<QWaylandXdgSurfaceV6 *>(newFocus->shellSurface());
+- if (xdgSurface && !xdgSurface->handlesActiveState())
+- m_display->handleWindowActivated(newFocus);
+- }
+- if (oldFocus && qobject_cast<QWaylandXdgSurfaceV6 *>(oldFocus->shellSurface())) {
+- auto *xdgSurface = qobject_cast<QWaylandXdgSurfaceV6 *>(oldFocus->shellSurface());
+- if (xdgSurface && !xdgSurface->handlesActiveState())
+- m_display->handleWindowDeactivated(oldFocus);
+- }
+-}
+-
+ }
+
+ QT_END_NAMESPACE
+diff --git a/qtwayland/src/plugins/shellintegration/xdg-shell-v6/qwaylandxdgshellv6integration_p.h b/qtwayland/src/plugins/shellintegration/xdg-shell-v6/qwaylandxdgshellv6integration_p.h
+index 261f8cbb..c1bcd5c6 100644
+--- a/qtwayland/src/plugins/shellintegration/xdg-shell-v6/qwaylandxdgshellv6integration_p.h
++++ b/qtwayland/src/plugins/shellintegration/xdg-shell-v6/qwaylandxdgshellv6integration_p.h
+@@ -65,7 +65,6 @@ public:
+ QWaylandXdgShellV6Integration() {}
+ bool initialize(QWaylandDisplay *display) override;
+ QWaylandShellSurface *createShellSurface(QWaylandWindow *window) override;
+- void handleKeyboardFocusChanged(QWaylandWindow *newFocus, QWaylandWindow *oldFocus) override;
+
+ private:
+ QScopedPointer<QWaylandXdgShellV6> m_xdgShell;
+diff --git a/qtwayland/src/plugins/shellintegration/xdg-shell/qwaylandxdgshell.cpp b/qtwayland/src/plugins/shellintegration/xdg-shell/qwaylandxdgshell.cpp
+index f3e3c330..fa6d5808 100644
+--- a/qtwayland/src/plugins/shellintegration/xdg-shell/qwaylandxdgshell.cpp
++++ b/qtwayland/src/plugins/shellintegration/xdg-shell/qwaylandxdgshell.cpp
+@@ -67,11 +67,6 @@ QWaylandXdgSurface::Toplevel::Toplevel(QWaylandXdgSurface *xdgSurface)
+
+ QWaylandXdgSurface::Toplevel::~Toplevel()
+ {
+- if (m_applied.states & Qt::WindowActive) {
+- QWaylandWindow *window = m_xdgSurface->window();
+- window->display()->handleWindowDeactivated(window);
+- }
+-
+ // The protocol spec requires that the decoration object is deleted before xdg_toplevel.
+ delete m_decoration;
+ m_decoration = nullptr;
+@@ -85,16 +80,15 @@ void QWaylandXdgSurface::Toplevel::applyConfigure()
+ if (!(m_applied.states & (Qt::WindowMaximized|Qt::WindowFullScreen)))
+ 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)
++ && !m_xdgSurface->m_window->display()->isKeyboardAvailable())
+ 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)
++ && !m_xdgSurface->m_window->display()->isKeyboardAvailable())
+ m_xdgSurface->m_window->display()->handleWindowDeactivated(m_xdgSurface->m_window);
+
+- // TODO: none of the other plugins send WindowActive either, but is it on purpose?
+- Qt::WindowStates statesWithoutActive = m_pending.states & ~Qt::WindowActive;
+-
+- m_xdgSurface->m_window->handleWindowStatesChanged(statesWithoutActive);
++ m_xdgSurface->m_window->handleWindowStatesChanged(m_pending.states);
+
+ if (m_pending.size.isEmpty()) {
+ // An empty size in the configure means it's up to the client to choose the size
+@@ -105,8 +99,6 @@ void QWaylandXdgSurface::Toplevel::applyConfigure()
+ m_xdgSurface->m_window->resizeFromApplyConfigure(m_pending.size);
+ }
+
+- m_xdgSurface->setSizeHints();
+-
+ m_applied = m_pending;
+ qCDebug(lcQpaWayland) << "Applied pending xdg_toplevel configure event:" << m_applied.size << m_applied.states;
+ }
+@@ -203,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()
+@@ -216,10 +213,24 @@ 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
++ QWindow *leave = nullptr;
++ if (m_xdgSurface && m_xdgSurface->window())
++ leave = m_xdgSurface->window()->window();
++ QWindowSystemInterface::handleLeaveEvent(leave);
++
++ if (QWindow *enter = QGuiApplication::topLevelAt(QCursor::pos()))
++ QWindowSystemInterface::handleEnterEvent(enter, enter->mapFromGlobal(QCursor::pos()), QCursor::pos());
+ }
+ }
+
+@@ -257,6 +268,7 @@ QWaylandXdgSurface::QWaylandXdgSurface(QWaylandXdgShell *shell, ::xdg_surface *s
+ m_toplevel->set_parent(parentXdgSurface->m_toplevel->object());
+ }
+ }
++ setSizeHints();
+ }
+
+ QWaylandXdgSurface::~QWaylandXdgSurface()
+@@ -400,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
+@@ -414,8 +424,9 @@ void QWaylandXdgSurface::setPopup(QWaylandWindow *parent)
+ positioner->set_anchor(QtWayland::xdg_positioner::anchor_top_left);
+ positioner->set_gravity(QtWayland::xdg_positioner::gravity_bottom_right);
+ positioner->set_size(m_window->geometry().width(), m_window->geometry().height());
+- m_popup = new Popup(this, parentXdgSurface, positioner);
++ m_popup = new Popup(this, parent, positioner);
+ positioner->destroy();
++
+ delete positioner;
+ }
+
+@@ -437,6 +448,23 @@ void QWaylandXdgSurface::setGrabPopup(QWaylandWindow *parent, QWaylandInputDevic
+ }
+ setPopup(parent);
+ m_popup->grab(device, serial);
++
++ // Synthesize Qt enter/leave events for popup
++ if (!parent)
++ return;
++ QWindow *current = QGuiApplication::topLevelAt(QCursor::pos());
++ QWindow *leave = parent->window();
++ if (current != leave)
++ return;
++
++ QWindowSystemInterface::handleLeaveEvent(leave);
++
++ QWindow *enter = nullptr;
++ if (m_popup && m_popup->m_xdgSurface && m_popup->m_xdgSurface->window())
++ enter = m_popup->m_xdgSurface->window()->window();
++
++ if (enter)
++ QWindowSystemInterface::handleEnterEvent(enter, enter->mapFromGlobal(QCursor::pos()), QCursor::pos());
+ }
+
+ void QWaylandXdgSurface::xdg_surface_configure(uint32_t serial)
+diff --git a/qtwayland/src/plugins/shellintegration/xdg-shell/qwaylandxdgshell_p.h b/qtwayland/src/plugins/shellintegration/xdg-shell/qwaylandxdgshell_p.h
+index 96785205..4b518f0a 100644
+--- a/qtwayland/src/plugins/shellintegration/xdg-shell/qwaylandxdgshell_p.h
++++ b/qtwayland/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/qtwayland/src/plugins/shellintegration/xdg-shell/qwaylandxdgshellintegration.cpp b/qtwayland/src/plugins/shellintegration/xdg-shell/qwaylandxdgshellintegration.cpp
+index 8769d971..da0dd6a7 100644
+--- a/qtwayland/src/plugins/shellintegration/xdg-shell/qwaylandxdgshellintegration.cpp
++++ b/qtwayland/src/plugins/shellintegration/xdg-shell/qwaylandxdgshellintegration.cpp
+@@ -69,20 +69,6 @@ QWaylandShellSurface *QWaylandXdgShellIntegration::createShellSurface(QWaylandWi
+ return m_xdgShell->getXdgSurface(window);
+ }
+
+-void QWaylandXdgShellIntegration::handleKeyboardFocusChanged(QWaylandWindow *newFocus, QWaylandWindow *oldFocus)
+-{
+- if (newFocus) {
+- auto *xdgSurface = qobject_cast<QWaylandXdgSurface *>(newFocus->shellSurface());
+- if (xdgSurface && !xdgSurface->handlesActiveState())
+- m_display->handleWindowActivated(newFocus);
+- }
+- if (oldFocus && qobject_cast<QWaylandXdgSurface *>(oldFocus->shellSurface())) {
+- auto *xdgSurface = qobject_cast<QWaylandXdgSurface *>(oldFocus->shellSurface());
+- if (xdgSurface && !xdgSurface->handlesActiveState())
+- m_display->handleWindowDeactivated(oldFocus);
+- }
+-}
+-
+ }
+
+ QT_END_NAMESPACE
+diff --git a/qtwayland/src/plugins/shellintegration/xdg-shell/qwaylandxdgshellintegration_p.h b/qtwayland/src/plugins/shellintegration/xdg-shell/qwaylandxdgshellintegration_p.h
+index b6caa6c9..2f929f98 100644
+--- a/qtwayland/src/plugins/shellintegration/xdg-shell/qwaylandxdgshellintegration_p.h
++++ b/qtwayland/src/plugins/shellintegration/xdg-shell/qwaylandxdgshellintegration_p.h
+@@ -65,7 +65,6 @@ public:
+ QWaylandXdgShellIntegration() {}
+ bool initialize(QWaylandDisplay *display) override;
+ QWaylandShellSurface *createShellSurface(QWaylandWindow *window) override;
+- void handleKeyboardFocusChanged(QWaylandWindow *newFocus, QWaylandWindow *oldFocus) override;
+
+ private:
+ QScopedPointer<QWaylandXdgShell> m_xdgShell;
+diff --git a/qtwayland/src/shared/qwaylandinputmethodeventbuilder.cpp b/qtwayland/src/shared/qwaylandinputmethodeventbuilder.cpp
+index 526d0ef4..f50ccf30 100644
+--- a/qtwayland/src/shared/qwaylandinputmethodeventbuilder.cpp
++++ b/qtwayland/src/shared/qwaylandinputmethodeventbuilder.cpp
+@@ -39,7 +39,10 @@
+
+ #include "qwaylandinputmethodeventbuilder_p.h"
+
++#include <QBrush>
++#include <QGuiApplication>
+ #include <QInputMethod>
++#include <QPalette>
+ #include <QTextCharFormat>
+
+ #ifdef QT_BUILD_WAYLANDCOMPOSITOR_LIB
+@@ -81,32 +84,38 @@ void QWaylandInputMethodEventBuilder::addPreeditStyling(uint32_t index, uint32_t
+ QTextCharFormat format;
+
+ switch (style) {
+- case 0:
+- case 1:
++ case ZWP_TEXT_INPUT_V2_PREEDIT_STYLE_NONE:
++ break;
++ case ZWP_TEXT_INPUT_V2_PREEDIT_STYLE_DEFAULT:
++ case ZWP_TEXT_INPUT_V2_PREEDIT_STYLE_UNDERLINE:
+ format.setFontUnderline(true);
+ format.setUnderlineStyle(QTextCharFormat::SingleUnderline);
+ m_preeditStyles.append(QInputMethodEvent::Attribute(QInputMethodEvent::TextFormat, index, length, format));
+ break;
+- case 2:
+- case 3:
++ case ZWP_TEXT_INPUT_V2_PREEDIT_STYLE_ACTIVE:
++ case ZWP_TEXT_INPUT_V2_PREEDIT_STYLE_INACTIVE:
+ format.setFontWeight(QFont::Bold);
+ format.setFontUnderline(true);
+ format.setUnderlineStyle(QTextCharFormat::SingleUnderline);
+ m_preeditStyles.append(QInputMethodEvent::Attribute(QInputMethodEvent::TextFormat, index, length, format));
+ break;
+- case 4:
+- format.setFontUnderline(true);
+- format.setUnderlineStyle(QTextCharFormat::SingleUnderline);
+- m_preeditStyles.append(QInputMethodEvent::Attribute(QInputMethodEvent::TextFormat, index, length, format));
++ case ZWP_TEXT_INPUT_V2_PREEDIT_STYLE_HIGHLIGHT:
++ case ZWP_TEXT_INPUT_V2_PREEDIT_STYLE_SELECTION:
++ {
++ format.setFontUnderline(true);
++ format.setUnderlineStyle(QTextCharFormat::SingleUnderline);
++ QPalette palette = qApp->palette();
++ format.setBackground(QBrush(palette.color(QPalette::Active, QPalette::Highlight)));
++ format.setForeground(QBrush(palette.color(QPalette::Active, QPalette::HighlightedText)));
++ m_preeditStyles.append(QInputMethodEvent::Attribute(QInputMethodEvent::TextFormat, index, length, format));
++ }
+ break;
+- case 5:
++ case ZWP_TEXT_INPUT_V2_PREEDIT_STYLE_INCORRECT:
+ format.setFontUnderline(true);
+ format.setUnderlineStyle(QTextCharFormat::WaveUnderline);
+ format.setUnderlineColor(QColor(Qt::red));
+ m_preeditStyles.append(QInputMethodEvent::Attribute(QInputMethodEvent::TextFormat, index, length, format));
+ break;
+-// case QtWayland::wl_text_input::preedit_style_selection:
+-// case QtWayland::wl_text_input::preedit_style_none:
+ default:
+ break;
+ }
+@@ -153,7 +162,7 @@ QInputMethodEvent QWaylandInputMethodEventBuilder::buildPreedit(const QString &t
+
+ if (m_preeditCursor < 0) {
+ attributes.append(QInputMethodEvent::Attribute(QInputMethodEvent::Cursor, 0, 0, QVariant()));
+- } else if (m_preeditCursor > 0) {
++ } else {
+ attributes.append(QInputMethodEvent::Attribute(QInputMethodEvent::Cursor, indexFromWayland(text, m_preeditCursor), 1, QVariant()));
+ }
+
+diff --git a/qtwayland/src/shared/qwaylandmimehelper.cpp b/qtwayland/src/shared/qwaylandmimehelper.cpp
+index a5fdd34d..e2fe1928 100644
+--- a/qtwayland/src/shared/qwaylandmimehelper.cpp
++++ b/qtwayland/src/shared/qwaylandmimehelper.cpp
+@@ -60,7 +60,7 @@ QByteArray QWaylandMimeHelper::getByteArray(QMimeData *mimeData, const QString &
+ buf.open(QIODevice::ReadWrite);
+ QByteArray fmt = "BMP";
+ if (mimeType.startsWith(QLatin1String("image/"))) {
+- QByteArray imgFmt = mimeType.mid(6).toUpper().toLatin1();
++ QByteArray imgFmt = mimeType.mid(6).toLower().toLatin1();
+ if (QImageWriter::supportedImageFormats().contains(imgFmt))
+ fmt = imgFmt;
+ }
+@@ -74,7 +74,7 @@ QByteArray QWaylandMimeHelper::getByteArray(QMimeData *mimeData, const QString &
+ QList<QUrl> urls = mimeData->urls();
+ for (int i = 0; i < urls.count(); ++i) {
+ content.append(urls.at(i).toEncoded());
+- content.append('\n');
++ content.append("\r\n");
+ }
+ } else {
+ content = mimeData->data(mimeType);
+diff --git a/qtwayland/tests/auto/client/datadevicev1/tst_datadevicev1.cpp b/qtwayland/tests/auto/client/datadevicev1/tst_datadevicev1.cpp
+index 1568b3b9..067410d0 100644
+--- a/qtwayland/tests/auto/client/datadevicev1/tst_datadevicev1.cpp
++++ b/qtwayland/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:
+diff --git a/qtwayland/tests/auto/client/seatv5/tst_seatv5.cpp b/qtwayland/tests/auto/client/seatv5/tst_seatv5.cpp
+index 9312c2e5..2ea382f1 100644
+--- a/qtwayland/tests/auto/client/seatv5/tst_seatv5.cpp
++++ b/qtwayland/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, Qt::TouchPointPressed);
++ QCOMPARE(e.touchPoints.length(), 1);
++ QCOMPARE(e.touchPoints.first().pos(), 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/qtwayland/tests/auto/client/shared/corecompositor.cpp b/qtwayland/tests/auto/client/shared/corecompositor.cpp
+index 5c6c83ba..fa9b7662 100644
+--- a/qtwayland/tests/auto/client/shared/corecompositor.cpp
++++ b/qtwayland/tests/auto/client/shared/corecompositor.cpp
+@@ -27,6 +27,7 @@
+ ****************************************************************************/
+
+ #include "corecompositor.h"
++#include <thread>
+
+ namespace MockCompositor {
+
+diff --git a/qtwayland/tests/auto/client/shared/coreprotocol.cpp b/qtwayland/tests/auto/client/shared/coreprotocol.cpp
+index 0d988521..d1a2e7cb 100644
+--- a/qtwayland/tests/auto/client/shared/coreprotocol.cpp
++++ b/qtwayland/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/qtwayland/tests/auto/client/shared/coreprotocol.h b/qtwayland/tests/auto/client/shared/coreprotocol.h
+index a1af137a..210d8ddb 100644
+--- a/qtwayland/tests/auto/client/shared/coreprotocol.h
++++ b/qtwayland/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)
+ {}
+@@ -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;
+ };
+diff --git a/qtwayland/tests/auto/client/shared_old/mockcompositor.cpp b/qtwayland/tests/auto/client/shared_old/mockcompositor.cpp
+index a415cbf5..b1d3d07d 100644
+--- a/qtwayland/tests/auto/client/shared_old/mockcompositor.cpp
++++ b/qtwayland/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/qtwayland/tests/auto/client/shared_old/mocksurface.cpp b/qtwayland/tests/auto/client/shared_old/mocksurface.cpp
+index e9df5f90..c3246e4a 100644
+--- a/qtwayland/tests/auto/client/shared_old/mocksurface.cpp
++++ b/qtwayland/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/qtwayland/tests/auto/client/shared_old/mocksurface.h b/qtwayland/tests/auto/client/shared_old/mocksurface.h
+index 949dc23d..d176837e 100644
+--- a/qtwayland/tests/auto/client/shared_old/mocksurface.h
++++ b/qtwayland/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;
+diff --git a/qtwayland/tests/auto/client/surface/tst_surface.cpp b/qtwayland/tests/auto/client/surface/tst_surface.cpp
+index 95e4e609..60c672ce 100644
+--- a/qtwayland/tests/auto/client/surface/tst_surface.cpp
++++ b/qtwayland/tests/auto/client/surface/tst_surface.cpp
+@@ -129,6 +129,10 @@ void tst_surface::waitForFrameCallbackGl()
+ // Make sure we follow frame callbacks for some frames
+ for (int i = 0; i < 5; ++i) {
+ xdgPingAndWaitForPong(); // Make sure things have happened on the client
++ if (!qEnvironmentVariableIntValue("QT_WAYLAND_DISABLE_WINDOWDECORATION") && i == 0) {
++ QCOMPARE(bufferSpy.count(), 1);
++ bufferSpy.removeFirst();
++ }
+ exec([&] {
+ QVERIFY(bufferSpy.empty()); // Make sure no extra buffers have arrived
+ QVERIFY(!xdgToplevel()->surface()->m_waitingFrameCallbacks.empty());
+diff --git a/qtwayland/tests/auto/client/xdgshell/tst_xdgshell.cpp b/qtwayland/tests/auto/client/xdgshell/tst_xdgshell.cpp
+index 2277bbb8..747875b4 100644
+--- a/qtwayland/tests/auto/client/xdgshell/tst_xdgshell.cpp
++++ b/qtwayland/tests/auto/client/xdgshell/tst_xdgshell.cpp
+@@ -31,6 +31,7 @@
+ #include <QtGui/QOpenGLWindow>
+ #include <QtGui/qpa/qplatformnativeinterface.h>
+ #include <QtWaylandClient/private/wayland-wayland-client-protocol.h>
++#include <QtWaylandClient/private/qwaylandwindow_p.h>
+
+ using namespace MockCompositor;
+
+@@ -45,6 +46,7 @@ private slots:
+ void configureStates();
+ void popup();
+ void tooltipOnPopup();
++ void tooltipAndSiblingPopup();
+ void switchPopups();
+ void hidePopupParent();
+ void pongs();
+@@ -138,6 +140,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();
+@@ -154,9 +157,12 @@ void tst_xdgshell::configureStates()
+ // 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
+
+-// QEXPECT_FAIL("", "configure has already been acked, we shouldn't have to wait for isActive", Continue);
+-// QVERIFY(window.isActive());
+- QTRY_VERIFY(window.isActive()); // Just make sure it eventually get's set correctly
++ // window.windowstate() is driven by keyboard focus, however for decorations we want to follow
++ // XDGShell this is internal to QtWayland so it is queried directly
++ auto waylandWindow = static_cast<QtWaylandClient::QWaylandWindow *>(window.handle());
++ Q_ASSERT(waylandWindow);
++ QTRY_VERIFY(waylandWindow->windowStates().testFlag(
++ Qt::WindowActive)); // Just make sure it eventually get's set correctly
+
+ const QSize screenSize(640, 480);
+ const uint maximizedSerial = exec([=] {
+@@ -186,6 +192,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()
+@@ -340,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()
+ {
+@@ -505,7 +598,7 @@ void tst_xdgshell::minMaxSize()
+ window.show();
+ QCOMPOSITOR_TRY_VERIFY(xdgToplevel());
+
+- exec([=] { xdgToplevel()->sendCompleteConfigure(); });
++ // we don't roundtrip with our configuration the initial commit should be correct
+
+ QCOMPOSITOR_TRY_COMPARE(xdgToplevel()->m_committed.minSize, QSize(100, 100));
+ QCOMPOSITOR_TRY_COMPARE(xdgToplevel()->m_committed.maxSize, QSize(1000, 1000));
+Submodule qtwebchannel 618422ee..f8949655:
+diff --git a/qtwebchannel/src/webchannel/qmetaobjectpublisher.cpp b/qtwebchannel/src/webchannel/qmetaobjectpublisher.cpp
+index 536eb5c..898d769 100644
+--- a/qtwebchannel/src/webchannel/qmetaobjectpublisher.cpp
++++ b/qtwebchannel/src/webchannel/qmetaobjectpublisher.cpp
+@@ -186,8 +186,6 @@ Q_DECLARE_TYPEINFO(OverloadResolutionCandidate, Q_MOVABLE_TYPE);
+ QMetaObjectPublisher::QMetaObjectPublisher(QWebChannel *webChannel)
+ : QObject(webChannel)
+ , webChannel(webChannel)
+- , signalHandler(this)
+- , clientIsIdle(false)
+ , blockUpdates(false)
+ , propertyUpdatesInitialized(false)
+ {
+@@ -301,17 +299,17 @@ QJsonObject QMetaObjectPublisher::classInfoForObject(const QObject *object, QWeb
+ return data;
+ }
+
+-void QMetaObjectPublisher::setClientIsIdle(bool isIdle)
++void QMetaObjectPublisher::setClientIsIdle(bool isIdle, QWebChannelAbstractTransport *transport)
+ {
+- if (clientIsIdle == isIdle) {
+- return;
+- }
+- clientIsIdle = isIdle;
+- if (!isIdle && timer.isActive()) {
+- timer.stop();
+- } else if (isIdle && !timer.isActive()) {
+- timer.start(PROPERTY_UPDATE_INTERVAL, this);
+- }
++ transportState[transport].clientIsIdle = isIdle;
++ if (isIdle)
++ sendEnqueuedPropertyUpdates(transport);
++}
++
++bool QMetaObjectPublisher::isClientIdle(QWebChannelAbstractTransport *transport)
++{
++ auto found = transportState.find(transport);
++ return found != transportState.end() && found.value().clientIsIdle;
+ }
+
+ QJsonObject QMetaObjectPublisher::initializeClient(QWebChannelAbstractTransport *transport)
+@@ -333,6 +331,7 @@ QJsonObject QMetaObjectPublisher::initializeClient(QWebChannelAbstractTransport
+
+ void QMetaObjectPublisher::initializePropertyUpdates(const QObject *const object, const QJsonObject &objectInfo)
+ {
++ auto *signalHandler = signalHandlerFor(object);
+ foreach (const QJsonValue &propertyInfoVar, objectInfo[KEY_PROPERTIES].toArray()) {
+ const QJsonArray &propertyInfo = propertyInfoVar.toArray();
+ if (propertyInfo.size() < 2) {
+@@ -353,19 +352,19 @@ void QMetaObjectPublisher::initializePropertyUpdates(const QObject *const object
+
+ // Only connect for a property update once
+ if (connectedProperties.isEmpty()) {
+- signalHandler.connectTo(object, signalIndex);
++ signalHandler->connectTo(object, signalIndex);
+ }
+
+ connectedProperties.insert(propertyIndex);
+ }
+
+ // also always connect to destroyed signal
+- signalHandler.connectTo(object, s_destroyedSignalIndex);
++ signalHandler->connectTo(object, s_destroyedSignalIndex);
+ }
+
+ void QMetaObjectPublisher::sendPendingPropertyUpdates()
+ {
+- if (blockUpdates || !clientIsIdle || pendingPropertyUpdates.isEmpty()) {
++ if (blockUpdates) {
+ return;
+ }
+
+@@ -415,18 +414,19 @@ void QMetaObjectPublisher::sendPendingPropertyUpdates()
+
+ // data does not contain specific updates
+ if (!data.isEmpty()) {
+- setClientIsIdle(false);
+-
+ message[KEY_DATA] = data;
+- broadcastMessage(message);
++ enqueueBroadcastMessage(message);
+ }
+
+ // send every property update which is not supposed to be broadcasted
+ const QHash<QWebChannelAbstractTransport*, QJsonArray>::const_iterator suend = specificUpdates.constEnd();
+ for (QHash<QWebChannelAbstractTransport*, QJsonArray>::const_iterator it = specificUpdates.constBegin(); it != suend; ++it) {
+ message[KEY_DATA] = it.value();
+- it.key()->sendMessage(message);
++ enqueueMessage(message, it.key());
+ }
++
++ for (auto state = transportState.begin(); state != transportState.end(); ++state)
++ sendEnqueuedPropertyUpdates(state.key());
+ }
+
+ QVariant QMetaObjectPublisher::invokeMethod(QObject *const object, const QMetaMethod &method,
+@@ -572,7 +572,7 @@ void QMetaObjectPublisher::signalEmitted(const QObject *object, const int signal
+ }
+ } else {
+ pendingPropertyUpdates[object][signalIndex] = arguments;
+- if (clientIsIdle && !blockUpdates && !timer.isActive()) {
++ if (!blockUpdates && !timer.isActive()) {
+ timer.start(PROPERTY_UPDATE_INTERVAL, this);
+ }
+ }
+@@ -590,7 +590,7 @@ void QMetaObjectPublisher::objectDestroyed(const QObject *object)
+ // only remove from handler when we initialized the property updates
+ // cf: https://bugreports.qt.io/browse/QTBUG-60250
+ if (propertyUpdatesInitialized) {
+- signalHandler.remove(object);
++ signalHandlerFor(object)->remove(object);
+ signalToPropertyMap.remove(object);
+ }
+ pendingPropertyUpdates.remove(object);
+@@ -852,6 +852,52 @@ void QMetaObjectPublisher::broadcastMessage(const QJsonObject &message) const
+ }
+ }
+
++void QMetaObjectPublisher::enqueueBroadcastMessage(const QJsonObject &message)
++{
++ if (webChannel->d_func()->transports.isEmpty()) {
++ qWarning("QWebChannel is not connected to any transports, cannot send message: %s",
++ QJsonDocument(message).toJson().constData());
++ return;
++ }
++
++ for (auto *transport : webChannel->d_func()->transports) {
++ auto &state = transportState[transport];
++ state.queuedMessages.append(message);
++ }
++}
++
++void QMetaObjectPublisher::enqueueMessage(const QJsonObject &message,
++ QWebChannelAbstractTransport *transport)
++{
++ auto &state = transportState[transport];
++ state.queuedMessages.append(message);
++}
++
++void QMetaObjectPublisher::sendEnqueuedPropertyUpdates(QWebChannelAbstractTransport *transport)
++{
++ auto found = transportState.find(transport);
++ if (found != transportState.end() && found.value().clientIsIdle
++ && !found.value().queuedMessages.isEmpty()) {
++
++ // If the client is connected with an in-process transport, it can
++ // happen that a message triggers a subsequent property change. In
++ // that case, we need to ensure that the queued messages have already
++ // been cleared; otherwise the recursive call will send everythig again.
++ // Case in point: The qmlwebchannel tests fail if we don't clear the
++ // queued messages before sending them out.
++ // For that same reason set the client to "busy" (aka non-idle) just
++ // right before sending out the messages; otherwise a potential
++ // "Idle" type message will not correctly restore the Idle state.
++ const auto messages = std::move(found.value().queuedMessages);
++ Q_ASSERT(found.value().queuedMessages.isEmpty());
++ found.value().clientIsIdle = false;
++
++ for (const auto &message : messages) {
++ transport->sendMessage(message);
++ }
++ }
++}
++
+ void QMetaObjectPublisher::handleMessage(const QJsonObject &message, QWebChannelAbstractTransport *transport)
+ {
+ if (!webChannel->d_func()->transports.contains(transport)) {
+@@ -866,7 +912,7 @@ void QMetaObjectPublisher::handleMessage(const QJsonObject &message, QWebChannel
+
+ const MessageType type = toType(message.value(KEY_TYPE));
+ if (type == TypeIdle) {
+- setClientIsIdle(true);
++ setClientIsIdle(true, transport);
+ } else if (type == TypeInit) {
+ if (!message.contains(KEY_ID)) {
+ qWarning("JSON message object is missing the id property: %s",
+@@ -913,9 +959,9 @@ void QMetaObjectPublisher::handleMessage(const QJsonObject &message, QWebChannel
+ return;
+ transport->sendMessage(createResponse(message.value(KEY_ID), wrapResult(result, transport)));
+ } else if (type == TypeConnectToSignal) {
+- signalHandler.connectTo(object, message.value(KEY_SIGNAL).toInt(-1));
++ signalHandlerFor(object)->connectTo(object, message.value(KEY_SIGNAL).toInt(-1));
+ } else if (type == TypeDisconnectFromSignal) {
+- signalHandler.disconnectFrom(object, message.value(KEY_SIGNAL).toInt(-1));
++ signalHandlerFor(object)->disconnectFrom(object, message.value(KEY_SIGNAL).toInt(-1));
+ } else if (type == TypeSetProperty) {
+ setProperty(object, message.value(KEY_PROPERTY).toInt(-1),
+ message.value(KEY_VALUE));
+@@ -931,6 +977,7 @@ void QMetaObjectPublisher::setBlockUpdates(bool block)
+ blockUpdates = block;
+
+ if (!blockUpdates) {
++ timer.start(PROPERTY_UPDATE_INTERVAL, this);
+ sendPendingPropertyUpdates();
+ } else if (timer.isActive()) {
+ timer.stop();
+@@ -948,4 +995,15 @@ void QMetaObjectPublisher::timerEvent(QTimerEvent *event)
+ }
+ }
+
++SignalHandler<QMetaObjectPublisher> *QMetaObjectPublisher::signalHandlerFor(const QObject *object)
++{
++ auto thread = object->thread();
++ auto it = signalHandlers.find(thread);
++ if (it == signalHandlers.end()) {
++ it = signalHandlers.emplace(thread, this).first;
++ it->second.moveToThread(thread);
++ }
++ return &it->second;
++}
++
+ QT_END_NAMESPACE
+diff --git a/qtwebchannel/src/webchannel/qmetaobjectpublisher_p.h b/qtwebchannel/src/webchannel/qmetaobjectpublisher_p.h
+index bbd9875..4713ef1 100644
+--- a/qtwebchannel/src/webchannel/qmetaobjectpublisher_p.h
++++ b/qtwebchannel/src/webchannel/qmetaobjectpublisher_p.h
+@@ -59,6 +59,9 @@
+ #include <QBasicTimer>
+ #include <QPointer>
+ #include <QJsonObject>
++#include <QQueue>
++
++#include <unordered_map>
+
+ #include "qwebchannelglobal.h"
+
+@@ -109,17 +112,36 @@ public:
+ */
+ void broadcastMessage(const QJsonObject &message) const;
+
++ /**
++ * Enqueue the given @p message to all known transports.
++ */
++ void enqueueBroadcastMessage(const QJsonObject &message);
++
++ /**
++ * Enqueue the given @p message to @p transport.
++ */
++ void enqueueMessage(const QJsonObject &message, QWebChannelAbstractTransport *transport);
++
++ /**
++ * If client for given @p transport is idle, send queued messaged to @p transport and then mark
++ * the client as not idle.
++ */
++ void sendEnqueuedPropertyUpdates(QWebChannelAbstractTransport *transport);
++
+ /**
+ * Serialize the QMetaObject of @p object and return it in JSON form.
+ */
+ QJsonObject classInfoForObject(const QObject *object, QWebChannelAbstractTransport *transport);
+
+ /**
+- * Set the client to idle or busy, based on the value of @p isIdle.
+- *
+- * When the value changed, start/stop the property update timer accordingly.
++ * Set the client to idle or busy for a single @p transport, based on the value of @p isIdle.
++ */
++ void setClientIsIdle(bool isIdle, QWebChannelAbstractTransport *transport);
++
++ /**
++ * Check that client is idle for @p transport.
+ */
+- void setClientIsIdle(bool isIdle);
++ bool isClientIdle(QWebChannelAbstractTransport *transport);
+
+ /**
+ * Initialize clients by sending them the class information of the registered objects.
+@@ -272,10 +294,18 @@ private:
+ friend class TestWebChannel;
+
+ QWebChannel *webChannel;
+- SignalHandler<QMetaObjectPublisher> signalHandler;
++ std::unordered_map<const QThread*, SignalHandler<QMetaObjectPublisher>> signalHandlers;
++ SignalHandler<QMetaObjectPublisher> *signalHandlerFor(const QObject *object);
+
+- // true when the client is idle, false otherwise
+- bool clientIsIdle;
++ struct TransportState
++ {
++ TransportState() : clientIsIdle(false) { }
++ // true when the client is idle, false otherwise
++ bool clientIsIdle;
++ // messages to send
++ QQueue<QJsonObject> queuedMessages;
++ };
++ QHash<QWebChannelAbstractTransport *, TransportState> transportState;
+
+ // true when no property updates should be sent, false otherwise
+ bool blockUpdates;
+diff --git a/qtwebchannel/src/webchannel/signalhandler_p.h b/qtwebchannel/src/webchannel/signalhandler_p.h
+index 27afadb..d77373c 100644
+--- a/qtwebchannel/src/webchannel/signalhandler_p.h
++++ b/qtwebchannel/src/webchannel/signalhandler_p.h
+@@ -56,6 +56,7 @@
+ #include <QVector>
+ #include <QMetaMethod>
+ #include <QDebug>
++#include <QThread>
+
+ QT_BEGIN_NAMESPACE
+
+@@ -71,6 +72,7 @@ static const int s_destroyedSignalIndex = QObject::staticMetaObject.indexOfMetho
+ template<class Receiver>
+ class SignalHandler : public QObject
+ {
++ Q_DISABLE_COPY(SignalHandler)
+ public:
+ SignalHandler(Receiver *receiver, QObject *parent = 0);
+
+@@ -268,6 +270,7 @@ int SignalHandler<Receiver>::qt_metacall(QMetaObject::Call call, int methodId, v
+ if (call == QMetaObject::InvokeMetaMethod) {
+ const QObject *object = sender();
+ Q_ASSERT(object);
++ Q_ASSERT(QThread::currentThread() == object->thread());
+ Q_ASSERT(senderSignalIndex() == methodId);
+ Q_ASSERT(m_connectionsCounter.contains(object));
+ Q_ASSERT(m_connectionsCounter.value(object).contains(methodId));
+diff --git a/qtwebchannel/tests/auto/qml/testwebchannel.cpp b/qtwebchannel/tests/auto/qml/testwebchannel.cpp
+index 9891687..3ca81c2 100644
+--- a/qtwebchannel/tests/auto/qml/testwebchannel.cpp
++++ b/qtwebchannel/tests/auto/qml/testwebchannel.cpp
+@@ -46,7 +46,11 @@ TestWebChannel::~TestWebChannel()
+
+ bool TestWebChannel::clientIsIdle() const
+ {
+- return QWebChannel::d_func()->publisher->clientIsIdle;
++ for (auto *transport : QWebChannel::d_func()->transports) {
++ if (QWebChannel::d_func()->publisher->isClientIdle(transport))
++ return true;
++ }
++ return false;
+ }
+
+ QT_END_NAMESPACE
+diff --git a/qtwebchannel/tests/auto/webchannel/tst_webchannel.cpp b/qtwebchannel/tests/auto/webchannel/tst_webchannel.cpp
+index 181da9e..37f989a 100644
+--- a/qtwebchannel/tests/auto/webchannel/tst_webchannel.cpp
++++ b/qtwebchannel/tests/auto/webchannel/tst_webchannel.cpp
+@@ -785,7 +785,7 @@ void TestWebChannel::testTransportWrapObjectProperties()
+ DummyTransport *dummyTransport = new DummyTransport(this);
+ channel.connectTo(dummyTransport);
+ channel.d_func()->publisher->initializeClient(dummyTransport);
+- channel.d_func()->publisher->setClientIsIdle(true);
++ channel.d_func()->publisher->setClientIsIdle(true, dummyTransport);
+
+ QCOMPARE(channel.d_func()->publisher->transportedWrappedObjects.size(), 0);
+
+@@ -943,8 +943,6 @@ void TestWebChannel::testInfiniteRecursion()
+
+ void TestWebChannel::testAsyncObject()
+ {
+- QSKIP("This test is broken. See QTBUG-80729");
+-
+ QWebChannel channel;
+ channel.connectTo(m_dummyTransport);
+
+@@ -990,6 +988,50 @@ void TestWebChannel::testAsyncObject()
+ thread.wait();
+ }
+
++void TestWebChannel::testPropertyMultipleTransports()
++{
++ DummyTransport transport1;
++ DummyTransport transport2;
++
++ QWebChannel channel;
++ QMetaObjectPublisher *publisher = channel.d_func()->publisher;
++
++ TestObject testObj;
++ testObj.setObjectName("testObject");
++ channel.registerObject(testObj.objectName(), &testObj);
++ channel.connectTo(&transport1);
++ channel.connectTo(&transport2);
++
++ testObj.setProp("Hello");
++
++ publisher->initializeClient(&transport1);
++ publisher->initializeClient(&transport2);
++ publisher->setClientIsIdle(true, &transport1);
++ QCOMPARE(publisher->isClientIdle(&transport1), true);
++ QCOMPARE(publisher->isClientIdle(&transport2), false);
++ QVERIFY(transport1.messagesSent().isEmpty());
++ QVERIFY(transport2.messagesSent().isEmpty());
++
++ testObj.setProp("World");
++ QTRY_COMPARE_WITH_TIMEOUT(transport1.messagesSent().size(), 1u, 2000);
++ QCOMPARE(transport2.messagesSent().size(), 0u);
++ publisher->setClientIsIdle(true, &transport2);
++ QTRY_COMPARE_WITH_TIMEOUT(transport2.messagesSent().size(), 1u, 2000);
++ QCOMPARE(publisher->isClientIdle(&transport1), false);
++ QCOMPARE(publisher->isClientIdle(&transport2), false);
++
++ testObj.setProp("!!!");
++ publisher->setClientIsIdle(true, &transport2);
++ QCOMPARE(publisher->isClientIdle(&transport2), true);
++ QCOMPARE(publisher->isClientIdle(&transport1), false);
++ QTRY_COMPARE_WITH_TIMEOUT(transport2.messagesSent().size(), 2u, 2000);
++ QCOMPARE(transport1.messagesSent().size(), 1u);
++ publisher->setClientIsIdle(true, &transport1);
++ QTRY_COMPARE_WITH_TIMEOUT(transport1.messagesSent().size(), 2u, 2000);
++ QCOMPARE(publisher->isClientIdle(&transport1), false);
++ QCOMPARE(publisher->isClientIdle(&transport2), false);
++}
++
+ class FunctionWrapper : public QObject
+ {
+ Q_OBJECT
+@@ -1082,7 +1124,7 @@ void TestWebChannel::benchInitializeClients()
+
+ publisher->propertyUpdatesInitialized = false;
+ publisher->signalToPropertyMap.clear();
+- publisher->signalHandler.clear();
++ publisher->signalHandlers.clear();
+ }
+ }
+
+@@ -1107,7 +1149,7 @@ void TestWebChannel::benchPropertyUpdates()
+ obj->change();
+ }
+
+- channel.d_func()->publisher->clientIsIdle = true;
++ channel.d_func()->publisher->setClientIsIdle(true, m_dummyTransport);
+ channel.d_func()->publisher->sendPendingPropertyUpdates();
+ }
+ }
+diff --git a/qtwebchannel/tests/auto/webchannel/tst_webchannel.h b/qtwebchannel/tests/auto/webchannel/tst_webchannel.h
+index eae21f4..dd4e690 100644
+--- a/qtwebchannel/tests/auto/webchannel/tst_webchannel.h
++++ b/qtwebchannel/tests/auto/webchannel/tst_webchannel.h
+@@ -348,6 +348,7 @@ private slots:
+ void testJsonToVariant();
+ void testInfiniteRecursion();
+ void testAsyncObject();
++ void testPropertyMultipleTransports();
+ void testDeletionDuringMethodInvocation_data();
+ void testDeletionDuringMethodInvocation();
+
+Submodule qtwebengine f328054d...38e0df6c (commits not present)
+Submodule qtwebsockets 65850954..63fb8da1:
+diff --git a/qtwebsockets/src/websockets/qwebsocketdataprocessor.cpp b/qtwebsockets/src/websockets/qwebsocketdataprocessor.cpp
+index 2affdd5..95f1194 100644
+--- a/qtwebsockets/src/websockets/qwebsocketdataprocessor.cpp
++++ b/qtwebsockets/src/websockets/qwebsocketdataprocessor.cpp
+@@ -273,6 +273,7 @@ void QWebSocketDataProcessor::clear()
+ if (!m_pConverterState)
+ m_pConverterState = new QTextCodec::ConverterState(QTextCodec::ConvertInvalidToNull |
+ QTextCodec::IgnoreHeader);
++ frame.clear();
+ }
+
+ /*!
+diff --git a/qtwebsockets/src/websockets/qwebsocketprotocol.cpp b/qtwebsockets/src/websockets/qwebsocketprotocol.cpp
+index df87a93..d0465f1 100644
+--- a/qtwebsockets/src/websockets/qwebsocketprotocol.cpp
++++ b/qtwebsockets/src/websockets/qwebsocketprotocol.cpp
+@@ -210,7 +210,7 @@ void QWebSocketProtocol::mask(char *payload, quint64 size, quint32 maskingKey)
+ quint8((maskingKey & 0x0000FF00u) >> 8),
+ quint8((maskingKey & 0x000000FFu))
+ };
+- int i = 0;
++ quint64 i = 0;
+ while (size-- > 0)
+ *payload++ ^= mask[i++ % 4];
+ }
diff --git a/srcpkgs/qt5/template b/srcpkgs/qt5/template
index e0463e1c9198..ca1800ce9dc2 100644
--- a/srcpkgs/qt5/template
+++ b/srcpkgs/qt5/template
@@ -2,11 +2,11 @@
#
# revbump libqtxdg after bumping patch version
pkgname=qt5
-version=5.15.7+20221119
+version=5.15.8
+revision=1
+build_style=meta
# commit f8c9fb304bc3e53b3aa07f962cd74e9160decccc
# base repo: https://invent.kde.org/qt/qt/qt5
-revision=4
-build_style=meta
hostmakedepends="cmake clang flex perl glib-devel pkg-config
python re2c ruby which"
makedepends="SDL2-devel Vulkan-Headers alsa-lib-devel double-conversion-devel
@@ -29,8 +29,9 @@ homepage="https://qt.io/"
# tarball is generated with `git archive-all qt5-$version.tar.gz`
# to keep the size smaller qtwebengine, qtwebview, qtdocgallery, qtactiveqt and qtpim
# can be marked with the export-ignore attribute
-distfiles="https://void.johnnynator.dev/distfiles/qt5-${version}.tar.gz"
-checksum=9d57af471c78029a362276b7c99108ea009f511bb9ba6ff6cb884f6ddd255e9f
+#distfiles="https://void.johnnynator.dev/distfiles/qt5-${version}.tar.gz"
+distfiles="https://download.qt.io/archive/qt/5.15/${version}/single/qt-everywhere-opensource-src-${version}.tar.xz"
+checksum=776a9302c336671f9406a53bd30b8e36f825742b2ec44a57c08217bff0fa86b9
python_version=2 #unverified
replaces="qt5-doc<5.6.0 qt5-quick1<5.6.0 qt5-quick1-devel<5.6.0 qt5-webkit<5.6.0 qt5-webkit-devel<5.6.0
qt5-enginio<5.7.1 qt5-enginio-devel<5.7.1 qt5-plugin-gtk<5.7.1 qt5-canvas3d<5.13.0"
@@ -248,7 +249,6 @@ do_configure() {
# opts+=" -v"
opts+=" -skip qtwebengine"
opts+=" -skip qtwebview"
- opts+=" -skip qtdocgallery"
opts+=" -skip qtpim"
opts+=" -skip qtsystems"
opts+=" -skip qtspeech"
From f8d4814ab768e63224b06d2ac05dd5ff0d2356a9 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:51 -0400
Subject: [PATCH 078/130] qt6-multimedia: revbump for ffmpeg-6.0
---
srcpkgs/qt6-multimedia/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/qt6-multimedia/template b/srcpkgs/qt6-multimedia/template
index d89e7d54eb5a..aae15e57ca7b 100644
--- a/srcpkgs/qt6-multimedia/template
+++ b/srcpkgs/qt6-multimedia/template
@@ -1,7 +1,7 @@
# Template file for 'qt6-multimedia'
pkgname=qt6-multimedia
version=6.4.2
-revision=1
+revision=2
build_style=cmake
configure_args="-DQT_FEATURE_gstreamer=ON"
hostmakedepends="perl qt6-declarative-host-tools pkg-config qt6-shadertools"
From a7475a8958e163f53fdcde791caf5d15958f149c Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:51 -0400
Subject: [PATCH 079/130] qtav: revbump for ffmpeg4-4.4.3
---
srcpkgs/qtav/template | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/srcpkgs/qtav/template b/srcpkgs/qtav/template
index 34c30b2c0c78..2d00ad104355 100644
--- a/srcpkgs/qtav/template
+++ b/srcpkgs/qtav/template
@@ -1,10 +1,10 @@
# Template file for 'qtav'
pkgname=qtav
version=1.13.0
-revision=1
+revision=2
build_style=qmake
hostmakedepends="qt5-qmake qt5-host-tools"
-makedepends="ffmpeg-devel libass-devel libopenal-devel
+makedepends="ffmpeg4-devel libass-devel libopenal-devel
libva-glx-devel libXv-devel pulseaudio-devel
qt5-declarative-devel qt5-svg-devel
qt5-quickcontrols"
From 1b5bb912204ce6efb71ea01843717b1698a88705 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:51 -0400
Subject: [PATCH 080/130] qtox: revbump for ffmpeg-6.0
---
srcpkgs/qtox/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/qtox/template b/srcpkgs/qtox/template
index 16019d7eaec9..5cea0b11b697 100644
--- a/srcpkgs/qtox/template
+++ b/srcpkgs/qtox/template
@@ -1,7 +1,7 @@
# Template file for 'qtox'
pkgname=qtox
version=1.17.6
-revision=2
+revision=3
build_style=cmake
configure_args="-DUPDATE_CHECK=OFF
-DGIT_DESCRIBE=${version}
From 89e5d436d14ed04676574302a6694b82393b5386 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:51 -0400
Subject: [PATCH 081/130] retroarch: revbump for ffmpeg-6.0
---
srcpkgs/retroarch/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/retroarch/template b/srcpkgs/retroarch/template
index 240d3df9db00..6d0b16ae2598 100644
--- a/srcpkgs/retroarch/template
+++ b/srcpkgs/retroarch/template
@@ -1,7 +1,7 @@
# Template file for 'retroarch'
pkgname=retroarch
version=1.14.0
-revision=1
+revision=2
build_style=configure
configure_args="--prefix=/usr --sysconfdir=/etc --enable-networking
--enable-udev --disable-builtinflac --disable-builtinglslang
From 192d0aaa5e505e89f0c6c3c8b299dc610e767309 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:51 -0400
Subject: [PATCH 082/130] scrcpy: revbump for ffmpeg-6.0
---
srcpkgs/scrcpy/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/scrcpy/template b/srcpkgs/scrcpy/template
index ee6e698e387f..8ada5ca4323f 100644
--- a/srcpkgs/scrcpy/template
+++ b/srcpkgs/scrcpy/template
@@ -1,7 +1,7 @@
# Template file for 'scrcpy'
pkgname=scrcpy
version=2.0
-revision=1
+revision=2
build_style=meson
configure_args="-Dcompile_server=false
-Dprebuilt_server=/usr/share/scrcpy/scrcpy-server-v${version}"
From e343ec6226ae1f5bfbcb09f6c3a4b14dee0b8c10 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:51 -0400
Subject: [PATCH 083/130] spek-alternative: revbump for ffmpeg4-4.4.3
---
srcpkgs/spek-alternative/template | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/srcpkgs/spek-alternative/template b/srcpkgs/spek-alternative/template
index d65086b8f008..05246f1b8d0c 100644
--- a/srcpkgs/spek-alternative/template
+++ b/srcpkgs/spek-alternative/template
@@ -1,11 +1,11 @@
# Template file for 'spek-alternative'
pkgname=spek-alternative
version=0.8.2.3
-revision=1
+revision=2
build_style=gnu-configure
hostmakedepends="automake gettext-devel intltool libtool pkg-config wxWidgets-common"
-makedepends="ffmpeg-devel wxWidgets-gtk3-devel"
-depends="ffmpeg"
+makedepends="ffmpeg4-devel wxWidgets-gtk3-devel"
+depends="ffmpeg4"
short_desc="Acoustic spectrum analyser"
maintainer="Kartik Singh <kartik.ynwa@gmail.com>"
license="GPL-3.0-or-later"
From 3f97f97606cddc28f1af588bdefc2fd2426a98fd Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:51 -0400
Subject: [PATCH 084/130] ssr: revbump for ffmpeg4-4.4.3
---
srcpkgs/ssr/template | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/srcpkgs/ssr/template b/srcpkgs/ssr/template
index b055b9ec0774..3448ca110eb0 100644
--- a/srcpkgs/ssr/template
+++ b/srcpkgs/ssr/template
@@ -1,11 +1,11 @@
# Template file for 'ssr'
pkgname=ssr
version=0.4.4
-revision=1
+revision=2
build_style=cmake
configure_args="-DWITH_QT5=ON"
hostmakedepends="pkg-config"
-makedepends="alsa-lib-devel ffmpeg-devel glu-devel jack-devel pulseaudio-devel
+makedepends="alsa-lib-devel ffmpeg4-devel glu-devel jack-devel pulseaudio-devel
qt5-tools-devel qt5-x11extras-devel libXinerama-devel v4l-utils-devel"
depends="desktop-file-utils hicolor-icon-theme"
short_desc="Simple Screen Recorder for programs and games"
From f20fa071b18ed2cc44a2e7302e7662cd081ea4a7 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:51 -0400
Subject: [PATCH 085/130] sumo: revbump for ffmpeg-6.0
---
srcpkgs/sumo/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/sumo/template b/srcpkgs/sumo/template
index 0f9b9ec815f5..a3fe134aa5ac 100644
--- a/srcpkgs/sumo/template
+++ b/srcpkgs/sumo/template
@@ -1,7 +1,7 @@
# Template file for 'sumo'
pkgname=sumo
version=1.12.0
-revision=5
+revision=6
build_style=cmake
hostmakedepends="libgdal-tools pkg-config swig python3-setuptools"
makedepends="python3-devel ffmpeg-devel fox-devel gl2ps-devel libgdal-devel
From 141ddd9358317c3d4847ea07b78484010055e60e Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:52 -0400
Subject: [PATCH 086/130] synfig: revbump for ffmpeg-6.0 and mlt7
---
srcpkgs/synfig/patches/ffmpeg6.patch | 46 ++++++++++++++++++++++++++++
srcpkgs/synfig/template | 4 +--
2 files changed, 48 insertions(+), 2 deletions(-)
create mode 100644 srcpkgs/synfig/patches/ffmpeg6.patch
diff --git a/srcpkgs/synfig/patches/ffmpeg6.patch b/srcpkgs/synfig/patches/ffmpeg6.patch
new file mode 100644
index 000000000000..a70204a9d23e
--- /dev/null
+++ b/srcpkgs/synfig/patches/ffmpeg6.patch
@@ -0,0 +1,46 @@
+--- a/src/modules/mod_libavcodec/trgt_av.cpp 2022-10-25 09:14:12.000000000 -0400
++++ b/src/modules/mod_libavcodec/trgt_av.cpp 2023-05-05 12:04:04.897219775 -0400
+@@ -49,6 +49,8 @@
+ # endif
+ #endif
+
++#include <libavcodec/avcodec.h>
++
+ #ifdef HAVE_LIBSWSCALE_SWSCALE_H
+ # include <libswscale/swscale.h>
+ #elif defined(HAVE_SWSCALE_H)
+--- a/src/modules/mod_libavcodec/trgt_av.cpp 2023-05-05 12:07:26.579860833 -0400
++++ b/src/modules/mod_libavcodec/trgt_av.cpp 2023-05-05 12:14:11.122033763 -0400
+@@ -236,12 +236,11 @@
+ close();
+
+ if (!av_registered) {
+- av_register_all();
+ av_registered = true;
+ }
+
+ // guess format
+- AVOutputFormat *format = av_guess_format(NULL, filename.c_str(), NULL);
++ const AVOutputFormat *format = av_guess_format(NULL, filename.c_str(), NULL);
+ if (!format) {
+ synfig::warning("Target_LibAVCodec: unable to guess the output format, defaulting to MPEG");
+ format = av_guess_format("mpeg", NULL, NULL);
+@@ -256,15 +255,15 @@
+ context = avformat_alloc_context();
+ assert(context);
+ context->oformat = format;
+- if (filename.size() + 1 > sizeof(context->filename)) {
++ if (filename.size() + 1 > sizeof(context->url)) {
+ synfig::error(
+ "Target_LibAVCodec: filename too long, max length is %d, filename is '%s'",
+- sizeof(context->filename) - 1,
++ sizeof(context->url) - 1,
+ filename.c_str() );
+ close();
+ return false;
+ }
+- memcpy(context->filename, filename.c_str(), filename.size() + 1);
++ memcpy(context->url, filename.c_str(), filename.size() + 1);
+
+ packet = av_packet_alloc();
+ assert(packet);
diff --git a/srcpkgs/synfig/template b/srcpkgs/synfig/template
index 5f5f5bb3f4b2..6e0d713150ae 100644
--- a/srcpkgs/synfig/template
+++ b/srcpkgs/synfig/template
@@ -6,7 +6,7 @@ revision=2
build_style=gnu-configure
configure_args="--with-boost-libdir=${XBPS_CROSS_BASE}/usr/lib"
hostmakedepends="boost-build ImageMagick pkg-config intltool"
-makedepends="ETL gettext-devel libxml++-devel mlt-devel libmagick-devel
+makedepends="ETL gettext-devel libxml++-devel mlt7-devel libmagick-devel
libmng-devel boost-build boost-devel libopenexr-devel ffmpeg-devel"
depends="ImageMagick"
short_desc="CLI 2D vector and timeline-based animation software"
@@ -20,7 +20,7 @@ CXXFLAGS="-std=c++11 -DHAVE_LOCALE_H=1"
synfig-devel_package() {
depends="${sourcepkg}>=${version}_${revision}
- libopenexr-devel libxml++-devel mlt-devel"
+ libopenexr-devel libxml++-devel mlt7-devel"
short_desc+=" - development files"
pkg_install() {
vmove usr/bin/synfig-config
From 08c40ae13f36544c386999284a7e9cc9ccd37ab0 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Fri, 5 May 2023 12:57:57 -0400
Subject: [PATCH 087/130] synfigstudio: revbump for synfig mlt7
---
srcpkgs/synfigstudio/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/synfigstudio/template b/srcpkgs/synfigstudio/template
index 91349169ed2b..af1c5a296ef0 100644
--- a/srcpkgs/synfigstudio/template
+++ b/srcpkgs/synfigstudio/template
@@ -2,7 +2,7 @@
# Should be kept in sync with 'synfig' and 'ETL'
pkgname=synfigstudio
version=1.4.4
-revision=2
+revision=3
build_style=gnu-configure
configure_args="--disable-update-mimedb"
hostmakedepends="pkg-config intltool gettext synfig"
From f1c3cd289dee8bf9147e557c775113ce11035213 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:52 -0400
Subject: [PATCH 088/130] telegram-desktop: revbump for ffmpeg-6.0
---
srcpkgs/telegram-desktop/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/telegram-desktop/template b/srcpkgs/telegram-desktop/template
index aae9f3135100..7943b36f0b8a 100644
--- a/srcpkgs/telegram-desktop/template
+++ b/srcpkgs/telegram-desktop/template
@@ -1,7 +1,7 @@
# Template file for 'telegram-desktop'
pkgname=telegram-desktop
version=4.6.5
-revision=1
+revision=2
build_style=cmake
build_helper="qemu"
configure_args="-DTDESKTOP_API_ID=209235
From 9f410af0f16cc1de7ee78849701aa810624f9cc1 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:52 -0400
Subject: [PATCH 089/130] tg_owt: revbump for ffmpeg-6.0
---
srcpkgs/tg_owt/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/tg_owt/template b/srcpkgs/tg_owt/template
index 97d195ddb34a..551614b24956 100644
--- a/srcpkgs/tg_owt/template
+++ b/srcpkgs/tg_owt/template
@@ -1,7 +1,7 @@
# Template file for 'tg_owt'
pkgname=tg_owt
version=0.0.0.20230107
-revision=1
+revision=2
_commit=5098730b9eb6173f0b52068fe2555b7c1015123a
_libyuv_commit=00950840d1c9bcbb3eb6ebc5aac5793e71166c8b
_abseil_commit=8c0b94e793a66495e0b1f34a5eb26bd7dc672db0
From 33554050489c681efc31187fd02b1648e11c8fd3 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:52 -0400
Subject: [PATCH 090/130] timg: revbump for ffmpeg-6.0
---
srcpkgs/timg/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/timg/template b/srcpkgs/timg/template
index 91f1516b2597..334443d3f9bb 100644
--- a/srcpkgs/timg/template
+++ b/srcpkgs/timg/template
@@ -1,7 +1,7 @@
# Template file for 'timg'
pkgname=timg
version=1.4.4
-revision=1
+revision=2
build_style=cmake
configure_args="-DWITH_OPENSLIDE_SUPPORT=off -Wno-dev"
hostmakedepends="pkg-config git"
From 9f6b096156cc99bbdd829b6a713f36c89ee67439 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:52 -0400
Subject: [PATCH 091/130] tvheadend: revbump for ffmpeg4-4.4.3
---
srcpkgs/tvheadend/template | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/srcpkgs/tvheadend/template b/srcpkgs/tvheadend/template
index e6b16d7ccf3b..46b52b6fb7f9 100644
--- a/srcpkgs/tvheadend/template
+++ b/srcpkgs/tvheadend/template
@@ -1,14 +1,14 @@
# Template file for 'tvheadend'
pkgname=tvheadend
version=4.2.8
-revision=6
+revision=7
build_style=gnu-configure
configure_args="--enable-dvbscan --disable-ffmpeg_static
--disable-hdhomerun_static --disable-bintray_cache --disable-libx264_static
--disable-libx265_static --disable-libvpx_static --disable-libtheora_static
--disable-libvorbis_static --disable-libfdkaac_static"
hostmakedepends="gettext pkg-config python git which"
-makedepends="avahi-libs-devel openssl-devel zlib-devel libcurl-devel ffmpeg-devel"
+makedepends="avahi-libs-devel openssl-devel zlib-devel libcurl-devel ffmpeg4-devel"
short_desc="TV streaming server"
maintainer="lemmi <lemmi@nerd2nerd.org>"
license="GPL-3.0-only"
From a0d740bdc08ec4461cbdf1a953b154c827de849c Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:52 -0400
Subject: [PATCH 092/130] unpaper: update to 7.0.0.
---
srcpkgs/unpaper/template | 16 ++++++++--------
1 file changed, 8 insertions(+), 8 deletions(-)
diff --git a/srcpkgs/unpaper/template b/srcpkgs/unpaper/template
index 38ed47a58401..1ff910e722af 100644
--- a/srcpkgs/unpaper/template
+++ b/srcpkgs/unpaper/template
@@ -1,13 +1,13 @@
# Template file for 'unpaper'
pkgname=unpaper
-version=6.1
-revision=3
-build_style=gnu-configure
+version=7.0.0
+revision=1
+build_style=meson
+hostmakedepends="pkg-config meson libxslt"
+makedepends="ffmpeg-devel python3-Sphinx"
+short_desc="Post-processing tool for scanned sheets of paper"
maintainer="Orphaned <orphan@voidlinux.org>"
-hostmakedepends="pkg-config libxslt"
-makedepends="ffmpeg-devel"
-license="GPL-2"
+license="GPL-2.0-or-later"
homepage="https://www.flameeyes.eu/projects/unpaper"
-short_desc="A post-processing tool for scanned sheets of paper"
distfiles="https://www.flameeyes.eu/files/${pkgname}-${version}.tar.xz"
-checksum=237c84f5da544b3f7709827f9f12c37c346cdf029b1128fb4633f9bafa5cb930
+checksum=2575fbbf26c22719d1cb882b59602c9900c7f747118ac130883f63419be46a80
From 8e0375be46171fcd7dd9468bc28b4d7ced3fe295 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:52 -0400
Subject: [PATCH 093/130] vba-m: revbump for ffmpeg-6.0
---
srcpkgs/vba-m/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/vba-m/template b/srcpkgs/vba-m/template
index ba153e0b58ca..aa6093645e97 100644
--- a/srcpkgs/vba-m/template
+++ b/srcpkgs/vba-m/template
@@ -2,7 +2,7 @@
pkgname=vba-m
reverts=1292_2
version=2.1.5
-revision=1
+revision=2
build_style=cmake
configure_args="-DENABLE_GTK=TRUE -DENABLE_FFMPEG=TRUE -DENABLE_LINK=TRUE -DCMAKE_BUILD_TYPE=Release"
hostmakedepends="gettext pkg-config unzip zip yasm wxWidgets-gtk3-devel"
From 197baa2fecfcdbdce2e721ccf69d153218b89283 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:52 -0400
Subject: [PATCH 094/130] vice: revbump for ffmpeg4-4.4.3
---
srcpkgs/vice/template | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/srcpkgs/vice/template b/srcpkgs/vice/template
index 0924767cfcfb..5981e45149d0 100644
--- a/srcpkgs/vice/template
+++ b/srcpkgs/vice/template
@@ -1,7 +1,7 @@
# Template file for 'vice'
pkgname=vice
version=3.5
-revision=1
+revision=2
build_style=gnu-configure
configure_args="
$(vopt_enable sdl2 sdlui2)
@@ -28,7 +28,7 @@ makedepends="
$(vopt_if gtk3 gtk+3-devel)
$(vopt_if gtk3 pulseaudio-devel)
$(vopt_if gtk3 pango-devel)
- $(vopt_if ffmpeg ffmpeg-devel)"
+ $(vopt_if ffmpeg ffmpeg4-devel)"
short_desc="Emulator for C64, C128, CBM-II, PET, VIC20, Plus4 and C16"
maintainer="Orphaned <orphan@voidlinux.org>"
license="GPL-2.0-or-later"
From 555c583938b20ce29c6da8890e2ff435b5d577d8 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:52 -0400
Subject: [PATCH 095/130] waypipe: revbump for ffmpeg-6.0
---
srcpkgs/waypipe/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/waypipe/template b/srcpkgs/waypipe/template
index 5c4161900060..1a46fe27f7d8 100644
--- a/srcpkgs/waypipe/template
+++ b/srcpkgs/waypipe/template
@@ -1,7 +1,7 @@
# Template file for 'waypipe'
pkgname=waypipe
version=0.8.4
-revision=1
+revision=2
build_style=meson
# lto is off because it causes linking errors in armv6l and armv7l (due to NEON)
configure_args="-Dwerror=false -Dwith_dmabuf=enabled -Dwith_lz4=enabled
From 9f7d61d3840076cb3a2402774f2a0dc7568806ac Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:52 -0400
Subject: [PATCH 096/130] wf-recorder: revbump for ffmpeg-6.0
---
srcpkgs/wf-recorder/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/wf-recorder/template b/srcpkgs/wf-recorder/template
index e278eb001600..5d014a5f28af 100644
--- a/srcpkgs/wf-recorder/template
+++ b/srcpkgs/wf-recorder/template
@@ -1,7 +1,7 @@
# Template file for 'wf-recorder'
pkgname=wf-recorder
version=0.3.0
-revision=1
+revision=2
build_style=meson
hostmakedepends="pkg-config scdoc wayland-devel"
makedepends="wayland-protocols wayland-devel ffmpeg-devel x264-devel
From 63f9107c64d75b09b2d8bd7f243439e67dec7d15 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:52 -0400
Subject: [PATCH 097/130] xpra: revbump for ffmpeg-6.0
---
srcpkgs/xpra/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/xpra/template b/srcpkgs/xpra/template
index 38f83283b1e5..b6e01ff0a813 100644
--- a/srcpkgs/xpra/template
+++ b/srcpkgs/xpra/template
@@ -1,7 +1,7 @@
# Template file for 'xpra'
pkgname=xpra
version=4.4.4
-revision=1
+revision=2
build_style=python3-module
make_build_args="--without-cuda_kernels --without-cuda_rebuild"
make_install_args="$(vopt_with docs) ${make_build_args}"
From 662734cb1c7fc58526257d3e33acb1b4d92f024a Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Fri, 31 Mar 2023 09:07:40 -0400
Subject: [PATCH 098/130] nv-codec-headers: update to 12.0.16.0
---
srcpkgs/nv-codec-headers/template | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/srcpkgs/nv-codec-headers/template b/srcpkgs/nv-codec-headers/template
index 3d422a61e489..251e057f826f 100644
--- a/srcpkgs/nv-codec-headers/template
+++ b/srcpkgs/nv-codec-headers/template
@@ -1,6 +1,6 @@
# Template file for 'nv-codec-headers'
pkgname=nv-codec-headers
-version=11.1.5.1
+version=12.0.16.0
revision=1
build_style=gnu-makefile
short_desc="FFmpeg version of headers required to interface with Nvidias codec APIs"
@@ -8,7 +8,7 @@ maintainer="Orphaned <orphan@voidlinux.org>"
license="MIT"
homepage="http://git.videolan.org/?p=ffmpeg/nv-codec-headers.git"
distfiles="https://github.com/FFmpeg/nv-codec-headers/archive/n${version}.tar.gz"
-checksum=d095fbd56aa93772471a323be0ebe65504a0f43f06c76a30b6d25da77b06ae9c
+checksum=2a1533b65f55f9da52956faf0627ed3b74868ac0c7f269990edd21369113b48f
post_install() {
sed -n '4,25p' include/ffnvcodec/nvEncodeAPI.h > LICENSE
From b2acede94aa1b2de553fab049039500efad9f79f Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Fri, 31 Mar 2023 09:08:40 -0400
Subject: [PATCH 099/130] openimagedenoise: revbump for ffmpeg-6.0
---
srcpkgs/openimagedenoise/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/openimagedenoise/template b/srcpkgs/openimagedenoise/template
index db5ccdb055cc..cb90045afb63 100644
--- a/srcpkgs/openimagedenoise/template
+++ b/srcpkgs/openimagedenoise/template
@@ -1,7 +1,7 @@
# Template file for 'openimagedenoise'
pkgname=openimagedenoise
version=1.4.3
-revision=1
+revision=2
archs="x86_64*"
build_style=cmake
hostmakedepends="ispc python3"
From 039e9516e5ec8c20f0df654f49993751ae1e4fb9 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Fri, 16 Dec 2022 09:25:22 -0500
Subject: [PATCH 100/130] intel-gmmlib: update to 22.3.3
---
srcpkgs/intel-gmmlib/template | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/srcpkgs/intel-gmmlib/template b/srcpkgs/intel-gmmlib/template
index 8ed6ed3cf56c..2605226152e5 100644
--- a/srcpkgs/intel-gmmlib/template
+++ b/srcpkgs/intel-gmmlib/template
@@ -1,6 +1,6 @@
# Template file for 'intel-gmmlib'
pkgname=intel-gmmlib
-version=22.2.0
+version=22.3.3
revision=1
archs="i686* x86_64*"
build_style=cmake
@@ -18,7 +18,7 @@ maintainer="Stefano Ragni <st3r4g@protonmail.com>"
license="MIT"
homepage="https://github.com/intel/gmmlib"
distfiles="https://github.com/intel/gmmlib/archive/intel-gmmlib-${version}.tar.gz"
-checksum=0b2253894c6fc8455b6d7c5e87e6504a76d6f60ea192e1445c2f93164bf529c0
+checksum=86651bd2803c9f0afd82471bec784e65d2b418dee315a053d22215eb2a679be7
lib32disabled=yes
From 04f823cf014314ef50326aa5808b3c245e62b9ef Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Fri, 16 Dec 2022 09:25:47 -0500
Subject: [PATCH 101/130] intel-media-driver: update to 22.6.4
---
...mmon-Enable-MMC-in-free-kernel-build.patch | 125 ++++++++++++++++++
.../intel-media-driver/patches/execinfo.patch | 58 --------
srcpkgs/intel-media-driver/template | 4 +-
3 files changed, 127 insertions(+), 60 deletions(-)
create mode 100644 srcpkgs/intel-media-driver/patches/0001-Media-Common-Enable-MMC-in-free-kernel-build.patch
delete mode 100644 srcpkgs/intel-media-driver/patches/execinfo.patch
diff --git a/srcpkgs/intel-media-driver/patches/0001-Media-Common-Enable-MMC-in-free-kernel-build.patch b/srcpkgs/intel-media-driver/patches/0001-Media-Common-Enable-MMC-in-free-kernel-build.patch
new file mode 100644
index 000000000000..525fb688722c
--- /dev/null
+++ b/srcpkgs/intel-media-driver/patches/0001-Media-Common-Enable-MMC-in-free-kernel-build.patch
@@ -0,0 +1,125 @@
+From e68feab7db036838d9521ba3b9f00717c37c024c Mon Sep 17 00:00:00 2001
+From: JayYang <jay.yang@intel.com>
+Date: Tue, 21 Mar 2023 17:17:55 +0800
+Subject: [PATCH] [Media Common] Enable MMC in free kernel build
+
+Add mmc build definition in free kernel build
+---
+ media_driver/agnostic/gen9/codec/hal/media_srcs.cmake | 2 +-
+ media_driver/cmake/linux/media_feature_flags_linux.cmake | 3 +--
+ .../media_interfaces_m9_bxt/media_interfaces_g9_bxt.cpp | 2 +-
+ .../media_interfaces_m9_cfl/media_interfaces_g9_cfl.cpp | 2 +-
+ .../media_interfaces_m9_glk/media_interfaces_g9_glk.cpp | 2 +-
+ .../media_interfaces_m9_kbl/media_interfaces_g9_kbl.cpp | 2 +-
+ .../media_interfaces_m9_skl/media_interfaces_g9_skl.cpp | 2 +-
+ 7 files changed, 7 insertions(+), 8 deletions(-)
+
+diff --git a/media_driver/agnostic/gen9/codec/hal/media_srcs.cmake b/media_driver/agnostic/gen9/codec/hal/media_srcs.cmake
+index 8bb36bafe..78902a22d 100644
+--- a/media_driver/agnostic/gen9/codec/hal/media_srcs.cmake
++++ b/media_driver/agnostic/gen9/codec/hal/media_srcs.cmake
+@@ -27,7 +27,7 @@ set(TMP_1_HEADERS_
+ ${CMAKE_CURRENT_LIST_DIR}/codechal_hw_g9_X.h
+ )
+
+-if(${MMC_Supported} STREQUAL "yes")
++if(${MMC_Supported} STREQUAL "yes" AND ENABLE_NONFREE_KERNELS AND ENABLE_KERNELS)
+ set(TMP_1_SOURCES_
+ ${TMP_1_SOURCES_}
+ ${CMAKE_CURRENT_LIST_DIR}/codechal_memdecomp_g9.cpp
+diff --git a/media_driver/cmake/linux/media_feature_flags_linux.cmake b/media_driver/cmake/linux/media_feature_flags_linux.cmake
+index de0ca853f..8121ea60c 100644
+--- a/media_driver/cmake/linux/media_feature_flags_linux.cmake
++++ b/media_driver/cmake/linux/media_feature_flags_linux.cmake
+@@ -35,7 +35,6 @@ if(NOT ENABLE_KERNELS OR NOT ENABLE_NONFREE_KERNELS)
+ bs_set_if_undefined(HEVC_Encode_VME_Supported "no")
+ bs_set_if_undefined(MPEG2_Encode_VME_Supported "no")
+ bs_set_if_undefined(CMRT_HEVC_ENC_FEI_Supported "no")
+- bs_set_if_undefined(MMC_Supported "no")
+ bs_set_if_undefined(VC1_Decode_Supported "no")
+ bs_set_if_undefined(Decode_Processing_Supported "no")
+ bs_set_if_undefined(Kernel_Auto_Denoise_Supported "no")
+@@ -46,7 +45,6 @@ else()
+ bs_set_if_undefined(HEVC_Encode_VME_Supported "${Encode_VME_Supported}")
+ bs_set_if_undefined(MPEG2_Encode_VME_Supported "${Encode_VME_Supported}")
+ bs_set_if_undefined(CMRT_HEVC_ENC_FEI_Supported "yes")
+- bs_set_if_undefined(MMC_Supported "yes")
+ bs_set_if_undefined(VC1_Decode_Supported "yes")
+ bs_set_if_undefined(Decode_Processing_Supported "yes")
+ bs_set_if_undefined(Kernel_Auto_Denoise_Supported "yes")
+@@ -64,6 +62,7 @@ bs_set_if_undefined(VP9_Decode_Supported "yes")
+ bs_set_if_undefined(VP_SFC_Supported "yes")
+ bs_set_if_undefined(Common_Encode_Supported "yes")
+ bs_set_if_undefined(Media_Scalability_Supported "yes")
++bs_set_if_undefined(MMC_Supported "yes")
+
+ # features controlled by global flag Encode_VDEnc_Supported
+ bs_set_if_undefined(AVC_Encode_VDEnc_Supported "${Encode_VDEnc_Supported}")
+diff --git a/media_driver/media_interface/media_interfaces_m9_bxt/media_interfaces_g9_bxt.cpp b/media_driver/media_interface/media_interfaces_m9_bxt/media_interfaces_g9_bxt.cpp
+index 3f306ee2a..8e4c0f532 100644
+--- a/media_driver/media_interface/media_interfaces_m9_bxt/media_interfaces_g9_bxt.cpp
++++ b/media_driver/media_interface/media_interfaces_m9_bxt/media_interfaces_g9_bxt.cpp
+@@ -135,7 +135,7 @@ MOS_STATUS MhwInterfacesG9Bxt::Initialize(
+
+ return MOS_STATUS_SUCCESS;
+ }
+-#ifdef _MMC_SUPPORTED
++#if defined(_MMC_SUPPORTED) && defined(ENABLE_KERNELS) && !defined(_FULL_OPEN_SOURCE)
+ static bool bxtRegisteredMmd =
+ MediaFactory<uint32_t, MmdDevice>::
+ Register<MmdDeviceG9Bxt>((uint32_t)IGFX_BROXTON);
+diff --git a/media_driver/media_interface/media_interfaces_m9_cfl/media_interfaces_g9_cfl.cpp b/media_driver/media_interface/media_interfaces_m9_cfl/media_interfaces_g9_cfl.cpp
+index b8fa1eec0..84e0fad1d 100644
+--- a/media_driver/media_interface/media_interfaces_m9_cfl/media_interfaces_g9_cfl.cpp
++++ b/media_driver/media_interface/media_interfaces_m9_cfl/media_interfaces_g9_cfl.cpp
+@@ -44,7 +44,7 @@ static bool cflRegisteredMhw =
+ MediaFactory<uint32_t, MhwInterfaces>::
+ Register<MhwInterfacesG9Kbl>((uint32_t)IGFX_COFFEELAKE);
+
+-#ifdef _MMC_SUPPORTED
++#if defined(_MMC_SUPPORTED) && defined(ENABLE_KERNELS) && !defined(_FULL_OPEN_SOURCE)
+ static bool cflRegisteredMmd =
+ MediaFactory<uint32_t, MmdDevice>::
+ Register<MmdDeviceG9Kbl>((uint32_t)IGFX_COFFEELAKE);
+diff --git a/media_driver/media_interface/media_interfaces_m9_glk/media_interfaces_g9_glk.cpp b/media_driver/media_interface/media_interfaces_m9_glk/media_interfaces_g9_glk.cpp
+index de81e6091..2638cb3a6 100644
+--- a/media_driver/media_interface/media_interfaces_m9_glk/media_interfaces_g9_glk.cpp
++++ b/media_driver/media_interface/media_interfaces_m9_glk/media_interfaces_g9_glk.cpp
+@@ -65,7 +65,7 @@ static bool glkRegisteredMhw =
+ MediaFactory<uint32_t, MhwInterfaces>::
+ Register<MhwInterfacesG9Kbl>((uint32_t)IGFX_GEMINILAKE);
+
+-#ifdef _MMC_SUPPORTED
++#if defined(_MMC_SUPPORTED) && defined(ENABLE_KERNELS) && !defined(_FULL_OPEN_SOURCE)
+ static bool glkRegisteredMmd =
+ MediaFactory<uint32_t, MmdDevice>::
+ Register<MmdDeviceG9Kbl>((uint32_t)IGFX_GEMINILAKE);
+diff --git a/media_driver/media_interface/media_interfaces_m9_kbl/media_interfaces_g9_kbl.cpp b/media_driver/media_interface/media_interfaces_m9_kbl/media_interfaces_g9_kbl.cpp
+index 99d786185..4e9c6e7f1 100644
+--- a/media_driver/media_interface/media_interfaces_m9_kbl/media_interfaces_g9_kbl.cpp
++++ b/media_driver/media_interface/media_interfaces_m9_kbl/media_interfaces_g9_kbl.cpp
+@@ -131,7 +131,7 @@ MOS_STATUS MhwInterfacesG9Kbl::Initialize(
+
+ return MOS_STATUS_SUCCESS;
+ }
+-#ifdef _MMC_SUPPORTED
++#if defined(_MMC_SUPPORTED) && defined(ENABLE_KERNELS) && !defined(_FULL_OPEN_SOURCE)
+ static bool kblRegisteredMmd =
+ MediaFactory<uint32_t, MmdDevice>::
+ Register<MmdDeviceG9Kbl>((uint32_t)IGFX_KABYLAKE);
+diff --git a/media_driver/media_interface/media_interfaces_m9_skl/media_interfaces_g9_skl.cpp b/media_driver/media_interface/media_interfaces_m9_skl/media_interfaces_g9_skl.cpp
+index e2520edf7..4b0012c64 100644
+--- a/media_driver/media_interface/media_interfaces_m9_skl/media_interfaces_g9_skl.cpp
++++ b/media_driver/media_interface/media_interfaces_m9_skl/media_interfaces_g9_skl.cpp
+@@ -139,7 +139,7 @@ MOS_STATUS MhwInterfacesG9Skl::Initialize(
+
+ return MOS_STATUS_SUCCESS;
+ }
+-#ifdef _MMC_SUPPORTED
++#if defined(_MMC_SUPPORTED) && defined(ENABLE_KERNELS) && !defined(_FULL_OPEN_SOURCE)
+ static bool sklRegisteredMmd =
+ MediaFactory<uint32_t, MmdDevice>::
+ Register<MmdDeviceG9Skl>((uint32_t)IGFX_SKYLAKE);
+--
+2.40.0
+
diff --git a/srcpkgs/intel-media-driver/patches/execinfo.patch b/srcpkgs/intel-media-driver/patches/execinfo.patch
deleted file mode 100644
index 25d21192d5a1..000000000000
--- a/srcpkgs/intel-media-driver/patches/execinfo.patch
+++ /dev/null
@@ -1,58 +0,0 @@
-From b17354142563b45e0ebf427485591426481368fd Mon Sep 17 00:00:00 2001
-From: Bernd Kuhls <bernd.kuhls@t-online.de>
-Date: Fri, 29 Jul 2022 19:51:39 +0200
-Subject: [PATCH] Fix uClibc build
-
-uClibc does not provide execinfo.h
----
- CMakeLists.txt | 6 ++++++
- .../linux/common/os/osservice/mos_utilities_specific.cpp | 4 ++++
- 2 files changed, 10 insertions(+)
-
-diff --git a/CMakeLists.txt b/CMakeLists.txt
-index 053904748..4a3f0869e 100755
---- a/CMakeLists.txt
-+++ b/CMakeLists.txt
-@@ -53,6 +53,12 @@ option (BUILD_CMRTLIB "Build and Install cmrtlib together with media driver" ON)
-
- option (ENABLE_PRODUCTION_KMD "Enable Production KMD header files" OFF)
-
-+include(CheckIncludeFileCXX)
-+check_include_file_cxx("execinfo.h" HAVE_EXECINFO)
-+if (HAVE_EXECINFO)
-+ add_definitions(-DHAVE_EXECINFO)
-+endif()
-+
- include(GNUInstallDirs)
-
- if (BUILD_CMRTLIB AND NOT CMAKE_WDDM_LINUX)
-diff --git a/media_softlet/linux/common/os/osservice/mos_utilities_specific.cpp b/media_softlet/linux/common/os/osservice/mos_utilities_specific.cpp
-index bde216b83..120b02d55 100644
---- a/media_softlet/linux/common/os/osservice/mos_utilities_specific.cpp
-+++ b/media_softlet/linux/common/os/osservice/mos_utilities_specific.cpp
-@@ -34,7 +34,9 @@
- #include <signal.h>
- #include <unistd.h> // fork
- #include <algorithm>
-+#ifdef HAVE_EXECINFO
- #include <execinfo.h> // backtrace
-+#endif
- #include <sys/types.h>
- #include <sys/stat.h> // fstat
- #include <sys/ipc.h> // System V IPC
-@@ -2473,6 +2475,7 @@ void MosUtilities::MosTraceEvent(
- MOS_FreeMemory(pTraceBuf);
- }
- }
-+#ifdef HAVE_EXECINFO
- if (m_mosTraceFilter & (1ULL << TR_KEY_CALL_STACK))
- {
- // reserve space for header and stack size field.
-@@ -2492,6 +2495,7 @@ void MosUtilities::MosTraceEvent(
- size_t ret = write(MosUtilitiesSpecificNext::m_mosTraceFd, traceBuf, nLen);
- }
- }
-+#endif
- }
- return;
- }
diff --git a/srcpkgs/intel-media-driver/template b/srcpkgs/intel-media-driver/template
index 1ca94569e117..1735b90c65ce 100644
--- a/srcpkgs/intel-media-driver/template
+++ b/srcpkgs/intel-media-driver/template
@@ -1,6 +1,6 @@
# Template file for 'intel-media-driver'
pkgname=intel-media-driver
-version=22.5.3
+version=22.6.4
revision=1
archs="x86_64*"
build_style=cmake
@@ -12,7 +12,7 @@ maintainer="Stefano Ragni <st3r4g@protonmail.com>"
license="MIT, BSD-3-Clause"
homepage="https://github.com/intel/media-driver"
distfiles="https://github.com/intel/media-driver/archive/intel-media-${version}.tar.gz"
-checksum=65652b365d48be3c9f0b3c561502952b92ee5fcc587520b88d0d752cf2a6a3b5
+checksum=0c04b9d74b92de41fd409b62913ce4afd799236c0b6bc1983a496990764e5d90
build_options="nonfree"
desc_option_nonfree="Enable nonfree kernels"
From e60eeb3d157ebea5c44bf585326c14705ff25fa3 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Fri, 16 Dec 2022 09:31:43 -0500
Subject: [PATCH 102/130] New package: onevpl-2023.1.2
---
common/shlibs | 1 +
srcpkgs/onevpl-devel | 1 +
srcpkgs/onevpl/template | 34 ++++++++++++++++++++++++++++++++++
3 files changed, 36 insertions(+)
create mode 120000 srcpkgs/onevpl-devel
create mode 100644 srcpkgs/onevpl/template
diff --git a/common/shlibs b/common/shlibs
index d0d328b09ef9..dbc2dbf25d3d 100644
--- a/common/shlibs
+++ b/common/shlibs
@@ -879,6 +879,7 @@ libwebp.so.7 libwebp-0.6.0_1
libwebpmux.so.3 libwebp-0.6.0_1
libwebpdemux.so.2 libwebp-0.5.0_1
libwebpdecoder.so.3 libwebp-0.6.0_1
+libvpl.so.2 onevpl-2023.1.2_1
libva-x11.so.2 libva-2.13.0_1
libva.so.2 libva-2.13.0_1
libva-glx.so.2 libva-glx-2.13.0_1
diff --git a/srcpkgs/onevpl-devel b/srcpkgs/onevpl-devel
new file mode 120000
index 000000000000..e2306500b487
--- /dev/null
+++ b/srcpkgs/onevpl-devel
@@ -0,0 +1 @@
+onevpl
\ No newline at end of file
diff --git a/srcpkgs/onevpl/template b/srcpkgs/onevpl/template
new file mode 100644
index 000000000000..85c7c2da85ce
--- /dev/null
+++ b/srcpkgs/onevpl/template
@@ -0,0 +1,34 @@
+# Template file for 'onevpl'
+pkgname=onevpl
+version=2023.1.2
+revision=1
+archs="x86_64*"
+build_style=cmake
+configure_args="
+ -DCMAKE_BUILD_TYPE=Release -Wno-dev
+ -DBUILD_PYTHON_BINDING:BOOL='OFF'
+ -DBUILD_EXAMPLES:BOOL='OFF'
+ -DBUILD_TESTS:BOOL='ON'
+ -DINSTALL_EXAMPLE_CODE:BOOL='OFF'"
+hostmakedepends="cmake libX11 python wayland-protocols pkg-config"
+makedepends="libva-devel libX11-devel wayland-devel"
+short_desc="Intel oneAPI Video Processing library"
+maintainer="zlice <zlice555@gmail.com>"
+license="MIT"
+homepage="https://www.intel.com/content/www/us/en/developer/tools/oneapi/onevpl.html"
+distfiles="https://github.com/oneapi-src/oneVPL/archive/v${version}/${pkgname}-${version}.tar.gz"
+checksum=b2261cca174ce1815f3d47c647921ab17f68267c69c1e2444ff27aab7d199cbb
+
+post_install() {
+ vlicense LICENSE
+}
+
+onevpl-devel_package() {
+ depends="${makedepends} ${sourcepkg}-${version}_${revision}"
+ short_desc+=" - development files"
+ pkg_install() {
+ vmove usr/include
+ vmove usr/lib/pkgconfig
+ vmove "usr/lib/*.so"
+ }
+}
From 38c14e84fc61a229d7f2bafd4bf58d8ed8fa0ecd Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Fri, 16 Dec 2022 15:27:04 -0500
Subject: [PATCH 103/130] New package: onevpl-intel-gpu-22.6.4
---
srcpkgs/onevpl-intel-gpu-devel | 1 +
srcpkgs/onevpl-intel-gpu/template | 27 +++++++++++++++++++++++++++
2 files changed, 28 insertions(+)
create mode 120000 srcpkgs/onevpl-intel-gpu-devel
create mode 100644 srcpkgs/onevpl-intel-gpu/template
diff --git a/srcpkgs/onevpl-intel-gpu-devel b/srcpkgs/onevpl-intel-gpu-devel
new file mode 120000
index 000000000000..47920ceecf91
--- /dev/null
+++ b/srcpkgs/onevpl-intel-gpu-devel
@@ -0,0 +1 @@
+onevpl-intel-gpu
\ No newline at end of file
diff --git a/srcpkgs/onevpl-intel-gpu/template b/srcpkgs/onevpl-intel-gpu/template
new file mode 100644
index 000000000000..f14acb728a54
--- /dev/null
+++ b/srcpkgs/onevpl-intel-gpu/template
@@ -0,0 +1,27 @@
+# Template file for 'onevpl-intel-gpu'
+pkgname=onevpl-intel-gpu
+version=22.6.4
+revision=1
+archs="x86_64*"
+build_style=cmake
+configure_args="-Wno-dev -DCMAKE_BUILD_TYPE=Release"
+hostmakedepends="cmake pkg-config"
+makedepends="libdrm-devel libva-devel onevpl-devel"
+short_desc="Runtime implementation of oneVPL API for Intel Gen GPUs"
+maintainer="zlice <zlice555@gmail.com>"
+license="MIT"
+homepage="https://github.com/oneapi-src/oneVPL-intel-gpu"
+changelog="https://github.com/oneapi-src/oneVPL-intel-gpu/blob/main/CHANGELOG.md"
+distfiles="https://github.com/oneapi-src/oneVPL-intel-gpu/archive/refs/tags/intel-onevpl-${version}.tar.gz"
+checksum=74b0979dcb2af1b7c68edb8cbcb02d539de511090b12fac50652cbacd707c4e6
+
+post_install() {
+ vlicense LICENSE
+}
+
+onevpl-intel-gpu-devel_package() {
+ short_desc+=" - development files"
+ pkg_install() {
+ vmove usr/lib/pkgconfig
+ }
+}
From f218310407f98c5ec3d5e042d7da05c80e604456 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Sun, 18 Dec 2022 01:40:15 -0500
Subject: [PATCH 104/130] igt-gpu-tools: update to version 1.27 revbump idk
remove
---
...-loading-failure-in-resolve-function.patch | 63 -------------------
srcpkgs/igt-gpu-tools/patches/musl.patch | 20 ++++++
srcpkgs/igt-gpu-tools/template | 4 +-
3 files changed, 22 insertions(+), 65 deletions(-)
delete mode 100644 srcpkgs/igt-gpu-tools/patches/i-g-t-Fix-global-symbol-loading-failure-in-resolve-function.patch
diff --git a/srcpkgs/igt-gpu-tools/patches/i-g-t-Fix-global-symbol-loading-failure-in-resolve-function.patch b/srcpkgs/igt-gpu-tools/patches/i-g-t-Fix-global-symbol-loading-failure-in-resolve-function.patch
deleted file mode 100644
index 0c3b554d9949..000000000000
--- a/srcpkgs/igt-gpu-tools/patches/i-g-t-Fix-global-symbol-loading-failure-in-resolve-function.patch
+++ /dev/null
@@ -1,63 +0,0 @@
-diff --git lib/igt_halffloat.c lib/igt_halffloat.c
-index 08ab05fc..e5e8a5bd 100644
---- a/lib/igt_halffloat.c
-+++ b/lib/igt_halffloat.c
-@@ -24,6 +24,19 @@
-
- #include <assert.h>
- #include <math.h>
-+#include <stdbool.h>
-+
-+#ifdef HAVE_CPUID_H
-+#include <cpuid.h>
-+#else
-+#define __get_cpuid_max(x, y) 0
-+#define __cpuid(level, a, b, c, d) a = b = c = d = 0
-+#define __cpuid_count(level, count, a, b, c, d) a = b = c = d = 0
-+#endif
-+
-+#ifndef bit_F16C
-+#define bit_F16C (1 << 29)
-+#endif
-
- #include "igt_halffloat.h"
- #include "igt_x86.h"
-@@ -182,6 +195,20 @@ static void half_to_float_f16c(const uint16_t *h, float *f, unsigned int num)
-
- #pragma GCC pop_options
-
-+static bool f16c_is_supported(void)
-+{
-+ unsigned max = __get_cpuid_max(0, NULL);
-+ unsigned eax, ebx, ecx, edx;
-+
-+ if (max >= 1) {
-+ __cpuid(1, eax, ebx, ecx, edx);
-+
-+ if (ecx & bit_F16C)
-+ return true;
-+ }
-+ return false;
-+}
-+
- static void float_to_half(const float *f, uint16_t *h, unsigned int num)
- {
- for (int i = 0; i < num; i++)
-@@ -196,7 +223,7 @@ static void half_to_float(const uint16_t *h, float *f, unsigned int num)
-
- static void (*resolve_float_to_half(void))(const float *f, uint16_t *h, unsigned int num)
- {
-- if (igt_x86_features() & F16C)
-+ if (f16c_is_supported())
- return float_to_half_f16c;
-
- return float_to_half;
-@@ -207,7 +234,7 @@ void igt_float_to_half(const float *f, uint16_t *h, unsigned int num)
-
- static void (*resolve_half_to_float(void))(const uint16_t *h, float *f, unsigned int num)
- {
-- if (igt_x86_features() & F16C)
-+ if (f16c_is_supported())
- return half_to_float_f16c;
-
- return half_to_float;
diff --git a/srcpkgs/igt-gpu-tools/patches/musl.patch b/srcpkgs/igt-gpu-tools/patches/musl.patch
index 615afdb8f8ea..4de6e0cfd898 100644
--- a/srcpkgs/igt-gpu-tools/patches/musl.patch
+++ b/srcpkgs/igt-gpu-tools/patches/musl.patch
@@ -191,6 +191,7 @@ index 74935430..0dc87d8c 100644
+++ b/tests/i915/i915_pm_rpm.c
@@ -27,6 +27,7 @@
+<<<<<<< HEAD
#include "config.h"
+#include <limits.h> // PATH_MAX
@@ -293,3 +294,22 @@ index 0faf3fc8..f6bd970e 100644
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
+=======
+ fbo = bo->map;
+lib/ioctl_wrappers.c.new
+--- a/benchmarks/gem_exec_tracer.c 2022-12-18 10:32:15.742341964 -0500
++++ b/benchmarks/gem_exec_tracer.c 2022-12-18 10:32:09.862211372 -0500
+@@ -275,7 +275,11 @@
+ DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_GEM_EXECBUFFER2, struct drm_i915_gem_execbuffer2)
+
+ int
++#if defined(__GLIBC__) || defined(__FreeBSD__)
+ ioctl(int fd, unsigned long request, ...)
++#else
++ioctl(int fd, int request, ...)
++#endif
+ {
+ struct trace *t, **p;
+ va_list args;
+
+>>>>>>> 60301ae02f (igt-gpu-tools: update to version 1.26)
diff --git a/srcpkgs/igt-gpu-tools/template b/srcpkgs/igt-gpu-tools/template
index 225e2c79118a..1376c39d5d5b 100644
--- a/srcpkgs/igt-gpu-tools/template
+++ b/srcpkgs/igt-gpu-tools/template
@@ -1,7 +1,7 @@
# Template file for 'igt-gpu-tools'
pkgname=igt-gpu-tools
version=1.27.1
-revision=1
+revision=2
build_style=meson
configure_args="-Db_ndebug=false -Ddocs=disabled"
hostmakedepends="pkg-config flex peg python3-docutils"
@@ -13,7 +13,7 @@ maintainer="Orphaned <orphan@voidlinux.org>"
license="MIT"
homepage="https://gitlab.freedesktop.org/drm/igt-gpu-tools"
changelog="https://gitlab.freedesktop.org/drm/igt-gpu-tools/-/raw/master/NEWS"
-distfiles="${XORG_SITE}/app/igt-gpu-tools-${version}.tar.xz"
+distfiles="${XORG_SITE}/app/${pkgname}-${version}.tar.xz"
checksum=93b9a4816ed22b5145bb61024314c8a65caeea991ce93027643f1d40723bf417
# tests don't behave in containers
make_check=ci-skip
From 64a751bebba7c8c754eef8f948ac206201824568 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Mon, 3 Apr 2023 23:30:28 -0400
Subject: [PATCH 105/130] freecad: revbump for qt5-webengine-5.15.13
---
srcpkgs/freecad/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/freecad/template b/srcpkgs/freecad/template
index f62023ee8ce4..e301f32d3540 100644
--- a/srcpkgs/freecad/template
+++ b/srcpkgs/freecad/template
@@ -1,7 +1,7 @@
# Template file for 'freecad'
pkgname=freecad
version=0.20.2
-revision=3
+revision=4
build_style=cmake
_inst_prefix=/usr/lib/${pkgname}
From c7e2185c1e7d843ee603999520df932bf20fc40f Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Mon, 3 Apr 2023 23:31:45 -0400
Subject: [PATCH 106/130] shotcut: revbump for mlt7-7.14.0
---
srcpkgs/shotcut/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/shotcut/template b/srcpkgs/shotcut/template
index 32583277dab2..8d8a7a0ebdeb 100644
--- a/srcpkgs/shotcut/template
+++ b/srcpkgs/shotcut/template
@@ -1,7 +1,7 @@
# Template file for 'shotcut'
pkgname=shotcut
version=22.12.21
-revision=1
+revision=2
build_style=cmake
configure_args="-DSHOTCUT_VERSION=${version}"
hostmakedepends="pkg-config qt5-tools-devel"
From 4c468ed479dc7e94954999e599aa2c34cdc09b4b Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Mon, 3 Apr 2023 23:33:30 -0400
Subject: [PATCH 107/130] shiboken2: revbump for qt5-5.15.8
---
srcpkgs/shiboken2/patches/importlib-machinery-bypass.patch | 1 +
srcpkgs/shiboken2/template | 2 +-
2 files changed, 2 insertions(+), 1 deletion(-)
create mode 120000 srcpkgs/shiboken2/patches/importlib-machinery-bypass.patch
diff --git a/srcpkgs/shiboken2/patches/importlib-machinery-bypass.patch b/srcpkgs/shiboken2/patches/importlib-machinery-bypass.patch
new file mode 120000
index 000000000000..efcf3249bd88
--- /dev/null
+++ b/srcpkgs/shiboken2/patches/importlib-machinery-bypass.patch
@@ -0,0 +1 @@
+../../python3-pyside2/patches/importlib-machinery-bypass.patch
\ No newline at end of file
diff --git a/srcpkgs/shiboken2/template b/srcpkgs/shiboken2/template
index 084ecc3ba1e1..2a21998997eb 100644
--- a/srcpkgs/shiboken2/template
+++ b/srcpkgs/shiboken2/template
@@ -1,7 +1,7 @@
# Template file for 'shiboken2'
pkgname=shiboken2
version=5.15.7
-revision=1
+revision=2
_pkgname="pyside-setup-opensource-src-${version}"
build_wrksrc="sources/shiboken2"
build_style=cmake
From 3585f2154e8e876e2db0c98ed2b5d95ea3951e5b Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Mon, 3 Apr 2023 23:33:53 -0400
Subject: [PATCH 108/130] python3-pyside2: update to 5.15.8
---
.../patches/importlib-machinery-bypass.patch | 15 +++++++++++++++
srcpkgs/python3-pyside2/template | 9 +++++----
2 files changed, 20 insertions(+), 4 deletions(-)
create mode 100644 srcpkgs/python3-pyside2/patches/importlib-machinery-bypass.patch
diff --git a/srcpkgs/python3-pyside2/patches/importlib-machinery-bypass.patch b/srcpkgs/python3-pyside2/patches/importlib-machinery-bypass.patch
new file mode 100644
index 000000000000..64c429584776
--- /dev/null
+++ b/srcpkgs/python3-pyside2/patches/importlib-machinery-bypass.patch
@@ -0,0 +1,15 @@
+Using this prevents an error around line 220 below it.
+"AttributeError: module 'importlib' has no attribute 'machinery'"
+The old backup logic is in place and compiles without issues.
+--- a/sources/shiboken2/libshiboken/embed/signature_bootstrap.py 2023-04-02 23:09:34.688912402 -0400
++++ b/sources/shiboken2/libshiboken/embed/signature_bootstrap.py 2023-04-02 23:10:03.395529582 -0400
+@@ -170,9 +170,6 @@
+
+ # 'zipstring_sequence' comes from signature.cpp
+ zipbytes = base64.b64decode(''.join(zipstring_sequence))
+- if sys.version_info[0] >= 3:
+- vzip = zipfile.ZipFile(io.BytesIO(zipbytes))
+- return sys.meta_path, EmbeddableZipImporter(vzip)
+
+ # Old version for Python 2.7, only.
+ import os
diff --git a/srcpkgs/python3-pyside2/template b/srcpkgs/python3-pyside2/template
index 50e6ff260d3b..b50e62bd215d 100644
--- a/srcpkgs/python3-pyside2/template
+++ b/srcpkgs/python3-pyside2/template
@@ -1,11 +1,12 @@
# Template file for 'python3-pyside2'
pkgname=python3-pyside2
-version=5.15.5
-revision=2
+version=5.15.8
+revision=1
_pkgname="pyside-setup-opensource-src-${version}"
build_wrksrc="sources/pyside2"
build_style=cmake
-configure_args="-DPYTHON_EXECUTABLE=/usr/bin/python"
+configure_args="-DPYTHON_EXECUTABLE=/usr/bin/python -DCMAKE_BUILD_TYPE=None
+ -DBUILD_TESTS=OFF"
hostmakedepends="cmake python3 shiboken2"
makedepends="python3-devel libshiboken2-devel qt5-devel
qt5-multimedia-devel qt5-tools-devel qt5-plugin-mysql qt5-plugin-odbc
@@ -23,7 +24,7 @@ maintainer="yopito <pierre.bourgin@free.fr>"
license="LGPL-3.0-or-later"
homepage="https://wiki.qt.io/Qt_for_Python"
distfiles="https://download.qt.io/official_releases/QtForPython/pyside2/PySide2-${version}-src/${_pkgname}.tar.xz"
-checksum=3920a4fb353300260c9bc46ff70f1fb975c5e7efa22e9d51222588928ce19b33
+checksum=23436302c8deb5b4cbc769b205d09604e38ba83b40708efccb7bd8c9af6f6b5d
build_options="webengine"
desc_option_webengine="Build Qt5 WebEngine bindings"
From 3a79eb02c109a17527e193a8630944742f29edc0 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Tue, 4 Apr 2023 11:14:35 -0400
Subject: [PATCH 109/130] konqueror: revbump for ffmpeg-6.0
---
srcpkgs/konqueror/template | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/srcpkgs/konqueror/template b/srcpkgs/konqueror/template
index d8d0e73a78ab..c5bdba601d3c 100644
--- a/srcpkgs/konqueror/template
+++ b/srcpkgs/konqueror/template
@@ -1,11 +1,11 @@
# Template file for 'konqueror'
pkgname=konqueror
version=23.04.0
-revision=1
+revision=2
build_style=cmake
configure_args="-DDESKTOPTOJSON_EXECUTABLE=/usr/bin/desktoptojson"
hostmakedepends="extra-cmake-modules python3 qt5-host-tools qt5-qmake kdoctools
-kcoreaddons kconfig gettext"
+ kcoreaddons kconfig gettext"
makedepends="qt5-devel qt5-webengine-devel qt5-declarative-devel
qt5-webchannel-devel qt5-location-devel kcmutils-devel kdelibs4support-devel
karchive-devel khtml-devel kdesu-devel kactivities5-devel"
From 8b656d724bd174600d8e40a6a720c978141b768d Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Tue, 4 Apr 2023 11:14:58 -0400
Subject: [PATCH 110/130] qt5-speech: revbump for qt5-5.15.8
---
srcpkgs/qt5-speech/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/qt5-speech/template b/srcpkgs/qt5-speech/template
index 3ecd10d50650..2d7d4d4d2453 100644
--- a/srcpkgs/qt5-speech/template
+++ b/srcpkgs/qt5-speech/template
@@ -1,7 +1,7 @@
# Template file for 'qt5-speech'
pkgname=qt5-speech
version=5.15.7
-revision=2
+revision=3
_commit=d32f4a479d38a11f547598004b975f4356424a16
build_style=qmake
configure_args="-- -flite -flite-alsa -speechd"
From 1841dd928690d5da2e23b16a51c013952317837a Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Tue, 4 Apr 2023 18:38:50 -0400
Subject: [PATCH 111/130] qt5-styleplugins: revbump for qt5-5.15.8
---
srcpkgs/qt5-styleplugins/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/qt5-styleplugins/template b/srcpkgs/qt5-styleplugins/template
index 96ed97d12cd2..30d93660a2a4 100644
--- a/srcpkgs/qt5-styleplugins/template
+++ b/srcpkgs/qt5-styleplugins/template
@@ -1,7 +1,7 @@
# Template file for 'qt5-styleplugins'
pkgname=qt5-styleplugins
version=5.0.0
-revision=20
+revision=21
_gitrev=335dbece103e2cbf6c7cf819ab6672c2956b17b3
build_style=qmake
hostmakedepends="pkg-config qt5-host-tools qt5-qmake"
From 2c2f0f3b4ea2798279708acb71ad12fa865fcf2b Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Thu, 27 Apr 2023 21:58:35 -0400
Subject: [PATCH 112/130] blender: update to 3.5.1
---
srcpkgs/blender/patches/numpy-2.24.patch | 22 ----------------------
srcpkgs/blender/template | 13 +++++++------
2 files changed, 7 insertions(+), 28 deletions(-)
delete mode 100644 srcpkgs/blender/patches/numpy-2.24.patch
diff --git a/srcpkgs/blender/patches/numpy-2.24.patch b/srcpkgs/blender/patches/numpy-2.24.patch
deleted file mode 100644
index 716315b74be7..000000000000
--- a/srcpkgs/blender/patches/numpy-2.24.patch
+++ /dev/null
@@ -1,22 +0,0 @@
-From 74e6e07cf7c67b55d384db72f5aa3892db8a3da6 Mon Sep 17 00:00:00 2001
-From: oreo639 <oreo6391@gmail.com>
-Date: Tue, 17 Jan 2023 14:36:54 -0800
-Subject: [PATCH] Remove usage of deprecated np.bool alias
-
----
- addons/io_scene_gltf2/blender/imp/gltf2_blender_mesh.py | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-diff --git a/addons/io_scene_gltf2/blender/imp/gltf2_blender_mesh.py b/addons/io_scene_gltf2/blender/imp/gltf2_blender_mesh.py
-index 6366434a6..8160c9e99 100644
---- a/release/scripts/addons/io_scene_gltf2/blender/imp/gltf2_blender_mesh.py
-+++ b/release/scripts/addons/io_scene_gltf2/blender/imp/gltf2_blender_mesh.py
-@@ -620,7 +620,7 @@ def set_poly_smoothing(gltf, pymesh, mesh, vert_normals, loop_vidxs):
- # Try to guess which polys should be flat based on the fact that all the
- # loop normals for a flat poly are = the poly's normal.
-
-- poly_smooths = np.empty(num_polys, dtype=np.bool)
-+ poly_smooths = np.empty(num_polys, dtype=bool)
-
- poly_normals = np.empty(num_polys * 3, dtype=np.float32)
- mesh.polygons.foreach_get('normal', poly_normals)
diff --git a/srcpkgs/blender/template b/srcpkgs/blender/template
index d18bc88838ff..900bc17937c3 100644
--- a/srcpkgs/blender/template
+++ b/srcpkgs/blender/template
@@ -1,7 +1,7 @@
# Template file for 'blender'
pkgname=blender
-version=3.4.1
-revision=4
+version=3.5.1
+revision=1
archs="x86_64* ppc64*"
build_style="cmake"
pycompile_dirs="/usr/share/blender/${version%.*}/scripts"
@@ -9,8 +9,8 @@ configure_args="-DWITH_INSTALL_PORTABLE=OFF -DWITH_PYTHON_INSTALL=OFF
-DWITH_JACK=ON -DWITH_CODEC_FFMPEG=ON -DWITH_CODEC_SNDFILE=ON -DWITH_OPENMP=ON
-DWITH_FFTW3=ON -DWITH_MOD_OCEANSIM=ON -DWITH_CYCLES_EMBREE=OFF -DWITH_OPENCOLORIO=ON
-DWITH_IMAGE_OPENEXR=ON -DWITH_IMAGE_OPENJPEG=ON -DWITH_OPENSUBDIV=ON
- -DWITH_OPENCOLLADA=ON -DWITH_SYSTEM_GLEW=ON -DWITH_OPENVDB=ON -DWITH_ALEMBIC=ON
- -DWITH_GHOST_X11=ON -DWITH_GHOST_WAYLAND=ON -DWITH_GHOST_LIBDECOR=ON
+ -DWITH_OPENCOLLADA=ON -DWITH_OPENVDB=ON -DWITH_ALEMBIC=ON
+ -DWITH_GHOST_X11=ON -DWITH_GHOST_WAYLAND=ON -DWITH_GHOST_WAYLAND_LIBDECOR=ON
-DWITH_BUILDINFO=OFF -DPYTHON_VERSION=${py3_ver} -DPYTHON_LIBPATH=/usr/lib
-DPYTHON_LIBRARY='python${py3_ver}${py3_abiver}'
-DPYTHON_INCLUDE_DIRS=/${py3_inc}"
@@ -22,14 +22,15 @@ makedepends="libgomp-devel libpng-devel tiff-devel python3-devel glu-devel
opencolorio-devel opencollada-devel python3-numpy libXrender-devel
OpenSubdiv-devel tbb-devel libxml2-devel openvdb-devel alembic-devel
pugixml-devel libXxf86vm-devel libepoxy-devel gmp-devel gmpxx-devel
- wayland-protocols wayland-devel libxkbcommon-devel libdecor-devel"
+ wayland-protocols wayland-devel libxkbcommon-devel libdecor-devel
+ level-zero-devel"
depends="desktop-file-utils hicolor-icon-theme"
short_desc="3D graphics creation suite"
maintainer="Enno Boland <gottox@voidlinux.org>"
license="GPL-3.0-or-later"
homepage="https://www.blender.org"
distfiles="https://download.blender.org/source/blender-${version}.tar.xz"
-checksum=247c4c1228270c9010f4721c985cb5b628ab50abcf9f2678630737142eeb91c3
+checksum=bd7428c7e6cba5a900216269c32111dffaabaf1bdb5472f231965e615174a809
python_version=3
LDFLAGS="-Wl,-z,stack-size=2097152"
# Blender tests are executed against a system installation of blender. This
From c1f1116388b47a4027b03bbd1946c5988e5140c9 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Thu, 27 Apr 2023 20:41:10 -0400
Subject: [PATCH 113/130] New package: level-zero-1.10.0
---
srcpkgs/level-zero-devel | 1 +
srcpkgs/level-zero/template | 28 ++++++++++++++++++++++++++++
2 files changed, 29 insertions(+)
create mode 120000 srcpkgs/level-zero-devel
create mode 100644 srcpkgs/level-zero/template
diff --git a/srcpkgs/level-zero-devel b/srcpkgs/level-zero-devel
new file mode 120000
index 000000000000..96ee8adf7303
--- /dev/null
+++ b/srcpkgs/level-zero-devel
@@ -0,0 +1 @@
+level-zero
\ No newline at end of file
diff --git a/srcpkgs/level-zero/template b/srcpkgs/level-zero/template
new file mode 100644
index 000000000000..2338482a0fda
--- /dev/null
+++ b/srcpkgs/level-zero/template
@@ -0,0 +1,28 @@
+# Template file for 'level-zero'
+pkgname=level-zero
+version=1.10.0
+revision=1
+archs="x86_64*"
+build_style=cmake
+hostmakedepends="cmake"
+makedepends="llvm clang clang-tools-extra SPIRV-LLVM-Translator-devel"
+short_desc="OneAPI Level Zero Specification"
+maintainer="Zlice <zlice555@gmail.com>"
+license="NCSA"
+homepage="https://github.com/oneapi-src/level-zero"
+distfiles="${homepage}/archive/refs/tags/v${version}.tar.gz"
+checksum=2811e4128ff6114020d0a147c2769b9b2e782e68ad49827685c33b9e716bf6ab
+
+post_install() {
+ vlicense LICENSE
+}
+
+level-zero-devel_package() {
+ depends="${makedepends} ${sourcepkg}-${version}_${revision}"
+ short_desc+=" - development files"
+ pkg_install() {
+ vmove usr/include
+ vmove usr/lib/pkgconfig
+ vmove "usr/lib/*.so"
+ }
+}
From 5a265894b90f7abdf1403f2d4729c92329711968 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Tue, 28 Mar 2023 19:54:49 -0400
Subject: [PATCH 114/130] New package: intel-metrics-library 1.0.133
---
srcpkgs/intel-metrics-library/template | 19 +++++++++++++++++++
1 file changed, 19 insertions(+)
create mode 100644 srcpkgs/intel-metrics-library/template
diff --git a/srcpkgs/intel-metrics-library/template b/srcpkgs/intel-metrics-library/template
new file mode 100644
index 000000000000..50f1a6079d7b
--- /dev/null
+++ b/srcpkgs/intel-metrics-library/template
@@ -0,0 +1,19 @@
+# Template file for 'intel-metrics-library'
+pkgname=intel-metrics-library
+version=1.0.133
+revision=1
+archs="x86_64*"
+build_style=cmake
+configure_args="-Wdev-no -DCMAKE_BUILD_TYPE=Release"
+hostmakedepends="cmake"
+makedepends="libdrm-devel"
+short_desc="Helper library that provides access to GPU performance counters"
+maintainer="Zlice <zlice555@gmail.com>"
+license="MIT"
+homepage="https://github.com/intel/metrics-library"
+distfiles="${homepage}/archive/refs/tags/metrics-library-${version}.tar.gz"
+checksum=83f7b2de3af5ffd2f1b487df8836e6d212e11668bd958bebae622a483fb1231f
+
+post_install() {
+ vlicense LICENSE.md
+}
From a75c70f5248f33133ce0519bcedbf74f5b6555ca Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Tue, 28 Mar 2023 19:54:18 -0400
Subject: [PATCH 115/130] New package: intel-metrics-discovery 1.12.163
---
srcpkgs/intel-metrics-discovery/template | 19 +++++++++++++++++++
1 file changed, 19 insertions(+)
create mode 100644 srcpkgs/intel-metrics-discovery/template
diff --git a/srcpkgs/intel-metrics-discovery/template b/srcpkgs/intel-metrics-discovery/template
new file mode 100644
index 000000000000..6083595e273c
--- /dev/null
+++ b/srcpkgs/intel-metrics-discovery/template
@@ -0,0 +1,19 @@
+# Template file for 'intel-metrics-discovery'
+pkgname=intel-metrics-discovery
+version=1.12.163
+revision=1
+archs="x86_64*"
+build_style=cmake
+configure_args="-Wdev-no -DCMAKE_BUILD_TYPE=Release"
+hostmakedepends="cmake"
+makedepends="libdrm-devel"
+short_desc="Helper library that provides access to GPU performance data"
+maintainer="Zlice <zlice555@gmail.com>"
+license="MIT"
+homepage="https://github.com/intel/metrics-discovery"
+distfiles="${homepage}/archive/refs/tags/metrics-discovery-${version}.tar.gz"
+checksum=6dfe8d11c58625bf3ebf656ec2a95dc96bbb05705ec71c6c3c3dd0ef5cd2319c
+
+post_install() {
+ vlicense LICENSE.md
+}
From cdac747ace175f7779c2d08aa375900dccabd100 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Sun, 26 Mar 2023 10:48:34 -0400
Subject: [PATCH 116/130] New package: intel-graphics-compiler-1.0.13463.18
---
srcpkgs/intel-graphics-compiler/template | 22 ++++++++++++++++++++++
1 file changed, 22 insertions(+)
create mode 100644 srcpkgs/intel-graphics-compiler/template
diff --git a/srcpkgs/intel-graphics-compiler/template b/srcpkgs/intel-graphics-compiler/template
new file mode 100644
index 000000000000..44d38214f929
--- /dev/null
+++ b/srcpkgs/intel-graphics-compiler/template
@@ -0,0 +1,22 @@
+# Template file for 'intel-graphics-compiler'
+pkgname=intel-graphics-compiler
+version=1.0.13463.18
+revision=1
+archs="x86_64*"
+build_style=cmake
+configure_args="-Wno-dev -DIGC_OPTION__LLVM_PREFERRED_VERSION=15.0.7 -DCCLANG_FROM_SYSTEM=ON
+ -DIGC_OPTION__SPIRV_TOOLS_MODE=Prebuilds -DIGC_OPTION__USE_PREINSTALLED_SPRIV_HEADERS=ON
+ -DIGC_OPTION__VC_INTRINSICS_MODE=Prebuilds"
+hostmakedepends="flex bison zlib-devel libzstd-devel cmake"
+makedepends="llvm clang clang-tools-extra intel-opencl-clang intel-vc-intrinsics
+ lld lld-devel SPIRV-Headers SPIRV-LLVM-Translator-devel SPIRV-Tools-devel"
+short_desc="LLVM based compiler for OpenCL targeting Intel"
+maintainer="Zlice <zlice555@gmail.com>"
+license="MIT"
+homepage="https://github.com/intel/intel-graphics-compiler"
+distfiles="${homepage}/archive/refs/tags/igc-${version}.tar.gz"
+checksum=0b960878a5feffd6aa10197c48bf73a0a3a19d0105428d48163e91db0444070a
+
+post_install() {
+ vlicense LICENSE.md
+}
From a1bade807be1b6b27e431804062822ef3e3168ff Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Sun, 26 Mar 2023 10:48:05 -0400
Subject: [PATCH 117/130] New package: intel-compute-runtime-23.09.25812.14
---
srcpkgs/intel-compute-runtime/template | 22 ++++++++++++++++++++++
1 file changed, 22 insertions(+)
create mode 100644 srcpkgs/intel-compute-runtime/template
diff --git a/srcpkgs/intel-compute-runtime/template b/srcpkgs/intel-compute-runtime/template
new file mode 100644
index 000000000000..1132b830d348
--- /dev/null
+++ b/srcpkgs/intel-compute-runtime/template
@@ -0,0 +1,22 @@
+# Template file for 'intel-compute-runtime'
+pkgname=intel-compute-runtime
+version=23.09.25812.14
+revision=1
+archs="x86_64"
+build_style=cmake
+configure_args="-Wno-dev -DNEO_SKIP_UNIT_TESTS=1 -DSUPPORT_DG1=ON -DSUPPORT_DG2=ON"
+hostmakedepends="cmake pkg-config"
+makedepends="gcc intel-gmmlib-devel libva-devel ocl-icd-devel
+ intel-opencl-clang intel-graphics-compiler level-zero-devel
+ intel-metrics-library intel-metrics-discovery"
+depends="intel-graphics-compiler"
+short_desc="Intel Graphics Compute Runtime for oneAPI Level Zero and OpenCL"
+maintainer="Zlice <zlice555@gmail.com>"
+license="MIT"
+homepage="https://github.com/intel/compute-runtime"
+distfiles="${homepage}/archive/refs/tags/${version}.tar.gz"
+checksum=abe2e6d9d2ac771d5f42ee2357ce897ca3b00dc6185c06f3f62772f729c7f8e1
+
+post_install() {
+ vlicense LICENSE.md
+}
From a531615f5b0e1e3a5c8f44d000645aa667d34bd9 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Sun, 26 Mar 2023 10:46:58 -0400
Subject: [PATCH 118/130] New package: intel-vc-intrinsics-0.12.3
---
srcpkgs/intel-vc-intrinsics/template | 21 +++++++++++++++++++++
1 file changed, 21 insertions(+)
create mode 100644 srcpkgs/intel-vc-intrinsics/template
diff --git a/srcpkgs/intel-vc-intrinsics/template b/srcpkgs/intel-vc-intrinsics/template
new file mode 100644
index 000000000000..129482bdf985
--- /dev/null
+++ b/srcpkgs/intel-vc-intrinsics/template
@@ -0,0 +1,21 @@
+# Template file for 'intel-vc-intrinsics'
+pkgname=intel-vc-intrinsics
+version=0.12.3
+revision=1
+archs="x86_64*"
+build_style=cmake
+configure_args="-Wno-dev -DLLVM_DIR=/usr/lib/cmake/llvm -DCMAKE_BUILD_TYPE=Release"
+hostmakedepends="cmake python"
+makedepends="llvm clang clang-tools-extra"
+short_desc="Set of intrinsics on top of core LLVM IR"
+maintainer="Zlice <zlice555@gmail.com>"
+license="MIT"
+homepage="https://github.com/intel/vc-intrinsics"
+distfiles="${homepage}/archive/refs/tags/v${version}.tar.gz"
+checksum=ed1c0d968cb2f8ee7b2840a14c3261639f1700e844fb7d2a89856babffd5e1d1
+
+# TODO: license isn't bundled in tar?
+# just added 2 days ago... mar 24th 2023
+#post_install() {
+# vlicense LICENSE.md
+#}
From 39d5bc2fdb575fe21933f5c57c1da7de488f0a34 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Sun, 26 Mar 2023 10:46:11 -0400
Subject: [PATCH 119/130] New package: intel-opencl-clang-15.0.0
---
common/shlibs | 1 +
srcpkgs/intel-opencl-clang/template | 18 ++++++++++++++++++
2 files changed, 19 insertions(+)
create mode 100644 srcpkgs/intel-opencl-clang/template
diff --git a/common/shlibs b/common/shlibs
index dbc2dbf25d3d..25178211b8ec 100644
--- a/common/shlibs
+++ b/common/shlibs
@@ -1008,6 +1008,7 @@ libLLVM-15.so libllvm15-15.0.7_1
libLLVMSPIRVLib.so.15 SPIRV-LLVM-Translator-15.0.0_1
libomp.so.5 libomp-15.0.7_1
libomptarget.so.15 libomp-15.0.7_1
+libopencl-clang.so.15 intel-opencl-clang-15.0.0_1
libisofs.so.6 libisofs-0.6.24_1
libmpack.so.0 libmpack-1.0.5_1
libGeoIP.so.1 libgeoip-1.4.8_1
diff --git a/srcpkgs/intel-opencl-clang/template b/srcpkgs/intel-opencl-clang/template
new file mode 100644
index 000000000000..e6f09f6ad724
--- /dev/null
+++ b/srcpkgs/intel-opencl-clang/template
@@ -0,0 +1,18 @@
+# Template file for 'intel-opencl-clang'
+pkgname=intel-opencl-clang
+version=15.0.0
+revision=1
+archs="x86_64*"
+build_style=cmake
+hostmakedepends="cmake"
+makedepends="llvm clang clang-tools-extra SPIRV-LLVM-Translator-devel"
+short_desc="LLVM linked opencl-clang"
+maintainer="Zlice <zlice555@gmail.com>"
+license="NCSA"
+homepage="https://github.com/intel/opencl-clang"
+distfiles="${homepage}/archive/refs/tags/v${version}.tar.gz"
+checksum=ea179674e52bc8c658e2655f76be467f7052f7d2c37ebcfdb102dce645ad1411
+
+post_install() {
+ vlicense LICENSE
+}
From 7968cad60609a8267424f51ee70bb0a6f1de3644 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Sun, 30 Apr 2023 20:22:25 -0400
Subject: [PATCH 120/130] gstreamer1: update to 1.22.2
---
srcpkgs/gstreamer1/template | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/srcpkgs/gstreamer1/template b/srcpkgs/gstreamer1/template
index ae8a49cb20e8..571148f2ff33 100644
--- a/srcpkgs/gstreamer1/template
+++ b/srcpkgs/gstreamer1/template
@@ -1,6 +1,6 @@
# Template file for 'gstreamer1'
pkgname=gstreamer1
-version=1.20.3
+version=1.22.2
revision=1
build_style=meson
build_helper="gir"
@@ -16,7 +16,7 @@ maintainer="Orphaned <orphan@voidlinux.org>"
license="LGPL-2.0-or-later"
homepage="https://gstreamer.freedesktop.org"
distfiles="${homepage}/src/gstreamer/gstreamer-${version}.tar.xz"
-checksum=607daf64bbbd5fb18af9d17e21c0d22c4d702fffe83b23cb22d1b1af2ca23a2a
+checksum=b2afe73603921c608ba48969dbb7d743776744bfe5d8059ece241137b7f88e21
pre_check() {
# gst_gstdatetime is known to fail according to LFS
From 88382cc213c964a2528d396725e72365bf755119 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Sun, 30 Apr 2023 20:22:26 -0400
Subject: [PATCH 121/130] gst-plugins-base1: update to 1.22.2
---
srcpkgs/gst-plugins-base1/template | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/srcpkgs/gst-plugins-base1/template b/srcpkgs/gst-plugins-base1/template
index 29e8f76bd1fe..2f20ea819849 100644
--- a/srcpkgs/gst-plugins-base1/template
+++ b/srcpkgs/gst-plugins-base1/template
@@ -1,6 +1,6 @@
# Template file for 'gst-plugins-base1'
pkgname=gst-plugins-base1
-version=1.20.3
+version=1.22.2
revision=1
build_style=meson
build_helper="gir"
@@ -22,7 +22,7 @@ maintainer="Orphaned <orphan@voidlinux.org>"
license="GPL-2.0-or-later, LGPL-2.0-or-later"
homepage="https://gstreamer.freedesktop.org"
distfiles="${homepage}/src/${pkgname/1/}/${pkgname/1/}-${version}.tar.xz"
-checksum=7e30b3dd81a70380ff7554f998471d6996ff76bbe6fc5447096f851e24473c9f
+checksum=eb65120c4ee79b7a153c3c1972d5c0158c2151877cc51ec7725bba5749679d49
build_options="cdparanoia gir sndio wayland"
build_options_default="cdparanoia gir wayland"
From edaff2bb50e19481b0e3f68bfcc664a4736e3cc7 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Sun, 30 Apr 2023 20:22:26 -0400
Subject: [PATCH 122/130] gst-plugins-good1: update to 1.22.2
---
srcpkgs/gst-plugins-good1/template | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/srcpkgs/gst-plugins-good1/template b/srcpkgs/gst-plugins-good1/template
index 1f5e620ce1fd..5d0fe1bfe284 100644
--- a/srcpkgs/gst-plugins-good1/template
+++ b/srcpkgs/gst-plugins-good1/template
@@ -1,6 +1,6 @@
# Template file for 'gst-plugins-good1'
pkgname=gst-plugins-good1
-version=1.20.3
+version=1.22.2
revision=1
build_style=meson
configure_args="-Ddv=disabled -Ddv1394=disabled -Dshout2=disabled -Dqt5=enabled
@@ -22,7 +22,7 @@ maintainer="Orphaned <orphan@voidlinux.org>"
license="LGPL-2.1-or-later"
homepage="https://gstreamer.freedesktop.org"
distfiles="${homepage}/src/${pkgname/1/}/${pkgname/1/}-${version}.tar.xz"
-checksum=f8f3c206bf5cdabc00953920b47b3575af0ef15e9f871c0b6966f6d0aa5868b7
+checksum=7c8cc59425f2b232f60ca7d13e56edd615da4f711e73dd01a7cffa46e6bc0cdd
build_options="gtk3 wayland"
build_options_default="gtk3 wayland"
From a7505e721ef76ffc7fb94f5cfb1ecfa86157e72d Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Sun, 30 Apr 2023 20:22:26 -0400
Subject: [PATCH 123/130] gst-plugins-bad1: update to 1.22.2
---
srcpkgs/gst-plugins-bad1/template | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/srcpkgs/gst-plugins-bad1/template b/srcpkgs/gst-plugins-bad1/template
index 5a9d5387e0d4..77bf79981c20 100644
--- a/srcpkgs/gst-plugins-bad1/template
+++ b/srcpkgs/gst-plugins-bad1/template
@@ -1,7 +1,7 @@
# Template file for 'gst-plugins-bad1'
pkgname=gst-plugins-bad1
-version=1.22.1
-revision=2
+version=1.22.2
+revision=1
build_helper="gir"
build_style=meson
configure_args="-Dpackage-origin=https://voidlinux.org -Ddoc=disabled
@@ -36,7 +36,7 @@ maintainer="Orphaned <orphan@voidlinux.org>"
license="GPL-2.0-or-later, LGPL-2.1-or-later"
homepage="https://gstreamer.freedesktop.org"
distfiles="${homepage}/src/${pkgname/1/}/${pkgname/1/}-${version}.tar.xz"
-checksum=7a11c13b55dd1d2386dd902219e41cbfcdda8e1e0aa3e738186c95074b35da4f
+checksum=3d8faf1ce3402c8535ce3a8c4e1a6c960e4b5655dbda6b55943db9ac79022d0f
build_options="gir gme wayland"
build_options_default="gir wayland"
From 227f948225b2825167de946408680c5f06eec7e4 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Sun, 30 Apr 2023 20:22:26 -0400
Subject: [PATCH 124/130] gst-plugins-ugly1: update to 1.22.2
---
srcpkgs/gst-plugins-ugly1/template | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/srcpkgs/gst-plugins-ugly1/template b/srcpkgs/gst-plugins-ugly1/template
index e254fd40f869..85ae64bc7a0a 100644
--- a/srcpkgs/gst-plugins-ugly1/template
+++ b/srcpkgs/gst-plugins-ugly1/template
@@ -1,6 +1,6 @@
# Template file for 'gst-plugins-ugly1'
pkgname=gst-plugins-ugly1
-version=1.20.3
+version=1.22.2
revision=1
build_style=meson
configure_args="-Damrnb=disabled -Damrwbdec=disabled -Dsidplay=disabled"
@@ -15,4 +15,4 @@ maintainer="Orphaned <orphan@voidlinux.org>"
license="LGPL-2.1-or-later"
homepage="https://gstreamer.freedesktop.org"
distfiles="${homepage}/src/${pkgname/1/}/${pkgname/1/}-${version}.tar.xz"
-checksum=8caa20789a09c304b49cf563d33cca9421b1875b84fcc187e4a385fa01d6aefd
+checksum=8f30f44db0bd063709bf6fbe55138e3a98af0abcb61c360f35582bbe10e80691
From e44f19cfc4d127520d2455c3bde0d3222703a0f1 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Sun, 30 Apr 2023 20:22:26 -0400
Subject: [PATCH 125/130] gst-omx: update to 1.22.2
---
srcpkgs/gst-omx/template | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/srcpkgs/gst-omx/template b/srcpkgs/gst-omx/template
index 893535c463da..5ad54cc7b9d8 100644
--- a/srcpkgs/gst-omx/template
+++ b/srcpkgs/gst-omx/template
@@ -1,6 +1,6 @@
# Template file for 'gst-omx'
pkgname=gst-omx
-version=1.20.3
+version=1.22.2
revision=1
build_style=meson
configure_args="-Dexamples=disabled -Dtarget=generic"
@@ -11,4 +11,4 @@ maintainer="Orphaned <orphan@voidlinux.org>"
license="LGPL-2.1-only"
homepage="https://gstreamer.freedesktop.org"
distfiles="${homepage}/src/${pkgname}/${pkgname}-${version}.tar.xz"
-checksum=8db48040bb41f09edf8d17ff6d16c54888d7777ba4501c2c69f0083350ea9a15
+checksum=1b0c57f2cc4ddeec5e7f0c436e502f06665c4e93c73261855b94e04fc94337b2
From d031d9801a56a82faffbf0eddcf13f59801bfb59 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Sun, 30 Apr 2023 20:22:26 -0400
Subject: [PATCH 126/130] gst-rtsp-server: update to 1.22.2
---
srcpkgs/gst-rtsp-server/template | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/srcpkgs/gst-rtsp-server/template b/srcpkgs/gst-rtsp-server/template
index 8ceea8d34b4b..2f0c0c45ff82 100644
--- a/srcpkgs/gst-rtsp-server/template
+++ b/srcpkgs/gst-rtsp-server/template
@@ -1,7 +1,7 @@
# Template file for 'gst-rtsp-server'
pkgname=gst-rtsp-server
-version=1.20.3
-revision=3
+version=1.22.2
+revision=1
build_style=meson
hostmakedepends="pkg-config python3"
makedepends="glib-devel gst-plugins-bad1-devel gobject-introspection
@@ -10,5 +10,5 @@ short_desc="GStreamer multimedia graph framework - rtsp server"
maintainer="1is7ac3 <isaac.qa13@gmail.com>"
license="LGPL-2.1-or-later"
homepage="https://gstreamer.freedesktop.org"
-distfiles="https://gstreamer.freedesktop.org/src/gst-rtsp-server/gst-rtsp-server-${version}.tar.xz"
-checksum=ee402718be9b127f0e5e66ca4c1b4f42e4926ec93ba307b7ccca5dc6cc9794ca
+distfiles="${homepage}/src/${pkgname}/${pkgname}-${version}.tar.xz"
+checksum=2be4aecfb88710100ea7115ed0216403e8094344ebf146094271b8d4d73828bf
From 0e8395724127b1012d4b0a24ba44c742bd8c4efc Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Sun, 30 Apr 2023 20:22:26 -0400
Subject: [PATCH 127/130] gst1-editing-services: update to 1.22.2
---
srcpkgs/gst1-editing-services/template | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/srcpkgs/gst1-editing-services/template b/srcpkgs/gst1-editing-services/template
index 673b46970f24..102440f7f253 100644
--- a/srcpkgs/gst1-editing-services/template
+++ b/srcpkgs/gst1-editing-services/template
@@ -1,6 +1,6 @@
# Template file for 'gst1-editing-services'
pkgname=gst1-editing-services
-version=1.20.3
+version=1.22.2
revision=1
build_style=meson
build_helper="gir"
@@ -12,7 +12,7 @@ maintainer="Toyam Cox <Vaelatern@gmail.com>"
license="LGPL-2.0-or-later"
homepage="https://gstreamer.freedesktop.org"
distfiles="${homepage}/src/${pkgname/gst1/gst}/${pkgname/gst1/gst}-${version}.tar.xz"
-checksum=5fd896de69fbe24421eb6b0ff8d2f8b4c3cba3f3025ceacd302172f39a8abaa2
+checksum=453b1464fc3857de269a7cb0ebd966afe02171d97bef672a0b8a0a6d43e0cebf
do_check() {
: # Tests fail in older versions as well
From 7ad7458371b0140d5c2071ff962d4f44c8e450bb Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Sun, 30 Apr 2023 20:22:26 -0400
Subject: [PATCH 128/130] gst1-python3: update to 1.22.2
---
srcpkgs/gst1-python3/template | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/srcpkgs/gst1-python3/template b/srcpkgs/gst1-python3/template
index 3f564ac64b93..789e40f036ea 100644
--- a/srcpkgs/gst1-python3/template
+++ b/srcpkgs/gst1-python3/template
@@ -1,7 +1,7 @@
# Template file for 'gst1-python3'
pkgname=gst1-python3
-version=1.20.3
-revision=2
+version=1.22.2
+revision=1
build_style=meson
hostmakedepends="pkg-config python3"
makedepends="libglib-devel python3-devel python3-gobject-devel gst-plugins-base1-devel"
@@ -11,4 +11,4 @@ maintainer="Orphaned <orphan@voidlinux.org>"
license="LGPL-2.1-or-later"
homepage="https://gstreamer.freedesktop.org"
distfiles="${homepage}/src/gst-python/gst-python-${version}.tar.xz"
-checksum=db348120eae955b8cc4de3560a7ea06e36d6e1ddbaa99a7ad96b59846601cfdc
+checksum=bef2b3d82ce4be46b775b1bb56305c1003ee01b535a53a82f9fe8924972153ad
From e0f2b814656bfbd166208bab9a1a3dc4711ec4fd Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Sun, 30 Apr 2023 20:22:26 -0400
Subject: [PATCH 129/130] gstreamer-vaapi: update to 1.22.2
---
srcpkgs/gstreamer-vaapi/template | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/srcpkgs/gstreamer-vaapi/template b/srcpkgs/gstreamer-vaapi/template
index 3cc4e057559a..0a5ee8b1ca3f 100644
--- a/srcpkgs/gstreamer-vaapi/template
+++ b/srcpkgs/gstreamer-vaapi/template
@@ -1,6 +1,6 @@
# Template file for 'gstreamer-vaapi'
pkgname=gstreamer-vaapi
-version=1.20.3
+version=1.22.2
revision=1
build_style=meson
hostmakedepends="pkg-config"
@@ -11,7 +11,7 @@ license="LGPL-2.1-or-later"
homepage="https://gstreamer.freedesktop.org"
changelog="https://raw.githubusercontent.com/GStreamer/gstreamer-vaapi/master/ChangeLog"
distfiles="${homepage}/src/gstreamer-vaapi/gstreamer-vaapi-${version}.tar.xz"
-checksum=6ee99eb316abdde9ad37002915bd8c3867918f6fdc74b7cf2ac4c1ae0d690b45
+checksum=d2e642f9745f97d9f73a7f5085e7659a9a31fe209b774e6e45dae041b435df06
pre_check() {
# Seems to need certain hardware to pass
From 93e0afe90dd5a2ae3fcdb143c62a3192681a6530 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Sun, 30 Apr 2023 20:22:26 -0400
Subject: [PATCH 130/130] gst-libav: update to 1.22.2
---
srcpkgs/gst-libav/template | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/srcpkgs/gst-libav/template b/srcpkgs/gst-libav/template
index f082bd211c65..8c72fc3e97ee 100644
--- a/srcpkgs/gst-libav/template
+++ b/srcpkgs/gst-libav/template
@@ -1,7 +1,7 @@
# Template file for 'gst-libav'
pkgname=gst-libav
-version=1.20.3
-revision=2
+version=1.22.2
+revision=1
build_style=meson
hostmakedepends="pkg-config yasm"
makedepends="orc-devel gst-plugins-base1-devel ffmpeg-devel"
@@ -11,7 +11,7 @@ maintainer="Orphaned <orphan@voidlinux.org>"
license="LGPL-2.0-or-later"
homepage="https://gstreamer.freedesktop.org"
distfiles="${homepage}/src/${pkgname}/${pkgname}-${version}.tar.xz"
-checksum=3fedd10560fcdfaa1b6462cbf79a38c4e7b57d7f390359393fc0cef6dbf27dfe
+checksum=fcaaf9878fe8f3bc82317ef13a1558824cb68df1f8968c6797f556c5e33bcffd
case "$XBPS_TARGET_MACHINE" in
*-musl) # Required by musl for M_SQRT1_2
^ permalink raw reply [flat|nested] 175+ messages in thread
* Re: ffmpeg6 split
2023-05-05 13:20 [PR PATCH] ffmpeg6 split zlice
` (2 preceding siblings ...)
2023-05-05 18:04 ` [PR PATCH] [Updated] " zlice
@ 2023-05-07 19:26 ` paper42
2023-05-07 22:00 ` zlice
` (169 subsequent siblings)
173 siblings, 0 replies; 175+ messages in thread
From: paper42 @ 2023-05-07 19:26 UTC (permalink / raw)
To: ml
[-- Attachment #1: Type: text/plain, Size: 437 bytes --]
New comment by paper42 on void-packages repository
https://github.com/void-linux/void-packages/pull/43761#issuecomment-1537522552
Comment:
are the commits for a blender update, gstreamer and new intel packages really necessary for this PR? If not, please drop them. If yes and they could be merged before merging this PR, please split them to a separate PR and mention that it should be merged before this PR in this PR's description.
^ permalink raw reply [flat|nested] 175+ messages in thread
* Re: ffmpeg6 split
2023-05-05 13:20 [PR PATCH] ffmpeg6 split zlice
` (3 preceding siblings ...)
2023-05-07 19:26 ` paper42
@ 2023-05-07 22:00 ` zlice
2023-05-07 22:00 ` [PR PATCH] [Updated] " zlice
` (168 subsequent siblings)
173 siblings, 0 replies; 175+ messages in thread
From: zlice @ 2023-05-07 22:00 UTC (permalink / raw)
To: ml
[-- Attachment #1: Type: text/plain, Size: 374 bytes --]
New comment by zlice on void-packages repository
https://github.com/void-linux/void-packages/pull/43761#issuecomment-1537549840
Comment:
**Intel OpenCL** commits removed
**blender** - uses ffmpeg-devel, added to update list
**gstreamer** - added to 'Requirements' section and only revbumped the appropriate packages
**Intel Packages** - added to 'Requirements'
^ permalink raw reply [flat|nested] 175+ messages in thread
* Re: [PR PATCH] [Updated] ffmpeg6 split
2023-05-05 13:20 [PR PATCH] ffmpeg6 split zlice
` (4 preceding siblings ...)
2023-05-07 22:00 ` zlice
@ 2023-05-07 22:00 ` zlice
2023-05-08 0:23 ` zlice
` (167 subsequent siblings)
173 siblings, 0 replies; 175+ messages in thread
From: zlice @ 2023-05-07 22:00 UTC (permalink / raw)
To: ml
[-- Attachment #1: Type: text/plain, Size: 3256 bytes --]
There is an updated pull request by zlice against master on the void-packages repository
https://github.com/zlice/void-packages ffmpeg6-split
https://github.com/void-linux/void-packages/pull/43761
ffmpeg6 split
[ci skip]
#### Testing the changes
- I tested the changes in this PR: **YES**
main testing has been vaapi in Firefox Nightly and enc/dec in Shotcut on Intel A770
#### New package
- This new package conforms to the [package requirements](https://github.com/void-linux/void-packages/blob/master/CONTRIBUTING.md#package-requirements): **YES**
#### Local build testing
- I built this PR locally for my native architecture, **x86_64**
#### Discussion
Continuation of https://github.com/void-linux/void-packages/pull/36315
`libavresample` is deprecated, but marked as a dependency when trying to build other packages and install `ffmpeg`(6). I think the right way to handle this is make a meta package and the add to removals?
##### Commit naming / misc
~~Commits are 'dirty' right now, running with [gstreamer 1.22.1 updates](https://github.com/void-linux/void-packages/pull/42861) and [Intel OpenCL](https://github.com/void-linux/void-packages/pull/43084). This will also make [intel packages pr](https://github.com/void-linux/void-packages/pull/41132) obsolete.~~ (see Requirements below)
Maintainer for previous ffmpeg(4) was orphaned, I can put my name in there if that matters, though I don't exactly see myself keeping up on ffmpeg.
This updates QT5 which looks like it is usually hosted by Johnny. Not sure if there's any reason to stay there or these sources are fine.
##### STILL FFMPEG4
These are a mix of emulators, games and/or older packages.
- attract (multiple patches in master)
- audacity (3.2.x+ should work but requires wxWidgets dev 3.1.x)
- ccextractor (master patches? no release)
- vice
- kodi
- mlt (only dep left is flowblade)
- ~~synfig (mlt)~~ (work with mlt7, bump synfigstudio)
- tvheadend
- ssr
- spek-alternative
- ppsspp
- olive
- moc
- mediastreamer
- libextractor
- idjc
- hedgewars
- ~~ffmpegthumbnailer~~ (patches for moviedecoder.xxx files)
- ~~ffmpegthumbs~~ (latest compiles)
- deadbeef
- omxplayer
- qtav (fork has ffmpeg 5 patch - https://github.com/cmguo/QtAV)
- `vlc` (vlc4 will support ffmpeg5, there's a patch to build 3.x with ffmpeg5 but it will lack vaapi)
- `osg` (OpenSceneGraph plus `xine-lib`)
##### HAVE NOT BUILT YET
- omxplayer (rpi only? ffmpeg4)
- kodi (big, but ffmpeg4)
##### UPDATED (for ffmpeg6)
- blender: update to 3.5.1
- unpaper: update to 7.0.0.
- guvcview: update to 2.0.8.
- qt5: update to 5.15.8
- qt5-webengine: update to 5.18.13
- shiboken2: revbump for qt5.15.8 (patch)
- python3-pyside2: update to 5.15.8 (patch)
##### Requirements
- [gstreamer 1.22.2](https://github.com/void-linux/void-packages/pull/42861) - a few packages use ffmpeg-devel and require a revbump
- [Intel Packages](https://github.com/void-linux/void-packages/pull/41132) - ffmpeg4 uses different libraries than 6 (libmfx / Intel-MediaSDK vs only oneVPL that Intel is moving to), both are included here
A patch file from https://github.com/void-linux/void-packages/pull/43761.patch is attached
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: github-pr-ffmpeg6-split-43761.patch --]
[-- Type: text/x-diff, Size: 781111 bytes --]
From f278ff8326ee28cf7c3a18299ef6f519bd747330 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 19:55:46 -0400
Subject: [PATCH 001/110] ffmpeg: update to 6.0.
---
common/shlibs | 26 +++++---
srcpkgs/ffmpeg/files/altivec.patch | 60 -------------------
.../patches/armv5tel-floating-point.patch | 18 ------
.../workaround-mesa-readeon-vaapi-bug.patch | 28 ---------
srcpkgs/ffmpeg/template | 31 +++++-----
5 files changed, 33 insertions(+), 130 deletions(-)
delete mode 100644 srcpkgs/ffmpeg/files/altivec.patch
delete mode 100644 srcpkgs/ffmpeg/patches/armv5tel-floating-point.patch
delete mode 100644 srcpkgs/ffmpeg/patches/workaround-mesa-readeon-vaapi-bug.patch
diff --git a/common/shlibs b/common/shlibs
index 89f7e53081f8..9497f6499aa2 100644
--- a/common/shlibs
+++ b/common/shlibs
@@ -390,15 +390,23 @@ libid3tag.so.0 libid3tag-0.15.1b_1
libgif.so.7 giflib-5.1.0_1
libImlib2.so.1 imlib2-1.4.2_1
libmp3lame.so.0 lame-3.98.2_1
-libavdevice.so.58 libavdevice-4.0_1
-libavformat.so.58 libavformat-4.0_1
-libswscale.so.5 libswscale-4.0_1
-libswresample.so.3 libswresample-4.0_1
-libavresample.so.4 libavresample-4.0_1
-libpostproc.so.55 libpostproc-4.0_1
-libavcodec.so.58 libavcodec-4.0_1
-libavutil.so.56 libavutil-4.0_1
-libavfilter.so.7 libavfilter-4.0_1
+libavdevice.so.60 libavdevice-6.0_1
+libavformat.so.60 libavformat-6.0_1
+libswscale.so.7 libswscale-6.0_1
+libswresample.so.4 libswresample-6.0_1
+libpostproc.so.57 libpostproc-6.0_1
+libavcodec.so.60 libavcodec-6.0_1
+libavutil.so.58 libavutil-6.0_1
+libavfilter.so.9 libavfilter-6.0_1
+libavdevice.so.58 libavdevice4-4.0_1
+libavformat.so.58 libavformat4-4.0_1
+libswscale.so.5 libswscale4-4.0_1
+libswresample.so.3 libswresample4-4.0_1
+libavresample.so.4 libavresample4-4.0_1
+libpostproc.so.55 libpostproc4-4.0_1
+libavcodec.so.58 libavcodec4-4.0_1
+libavutil.so.56 libavutil4-4.0_1
+libavfilter.so.7 libavfilter4-4.0_1
libSDL-1.2.so.0 SDL-1.2.14_1
libSDL_image-1.2.so.0 SDL_image-1.2.10_1
libx264.so.157 x264-20190507.2245_1
diff --git a/srcpkgs/ffmpeg/files/altivec.patch b/srcpkgs/ffmpeg/files/altivec.patch
deleted file mode 100644
index 9c5720046332..000000000000
--- a/srcpkgs/ffmpeg/files/altivec.patch
+++ /dev/null
@@ -1,60 +0,0 @@
-revert some altivec specific change on all ppc* except ppc64le*
-
-q66: "We should also throw in a revert of FFmpeg/FFmpeg@3a557c5 but only
-conditionally, for ppc* but not ppc64le* (the new code is valid for
-POWER8 VSX which LE targets as a baseline but not BE)"
-
-
-This reverts commit 3a557c5d88b7b15b5954ba2743febb055549b536.
----
- libswscale/ppc/yuv2rgb_altivec.c | 24 ++++++++++++++++++++----
- 1 file changed, 20 insertions(+), 4 deletions(-)
-
-diff --git a/libswscale/ppc/yuv2rgb_altivec.c b/libswscale/ppc/yuv2rgb_altivec.c
-index 536545293d..c1e2852adb 100644
---- a/libswscale/ppc/yuv2rgb_altivec.c
-+++ b/libswscale/ppc/yuv2rgb_altivec.c
-@@ -305,6 +305,9 @@ static int altivec_ ## name(SwsContext *c, const unsigned char **in, \
- vector signed short R1, G1, B1; \
- vector unsigned char R, G, B; \
- \
-+ const vector unsigned char *y1ivP, *y2ivP, *uivP, *vivP; \
-+ vector unsigned char align_perm; \
-+ \
- vector signed short lCY = c->CY; \
- vector signed short lOY = c->OY; \
- vector signed short lCRV = c->CRV; \
-@@ -335,13 +338,26 @@ static int altivec_ ## name(SwsContext *c, const unsigned char **in, \
- vec_dstst(oute, (0x02000002 | (((w * 3 + 32) / 32) << 16)), 1); \
- \
- for (j = 0; j < w / 16; j++) { \
-- y0 = vec_xl(0, y1i); \
-+ y1ivP = (const vector unsigned char *) y1i; \
-+ y2ivP = (const vector unsigned char *) y2i; \
-+ uivP = (const vector unsigned char *) ui; \
-+ vivP = (const vector unsigned char *) vi; \
-+ \
-+ align_perm = vec_lvsl(0, y1i); \
-+ y0 = (vector unsigned char) \
-+ vec_perm(y1ivP[0], y1ivP[1], align_perm); \
- \
-- y1 = vec_xl(0, y2i); \
-+ align_perm = vec_lvsl(0, y2i); \
-+ y1 = (vector unsigned char) \
-+ vec_perm(y2ivP[0], y2ivP[1], align_perm); \
- \
-- u = (vector signed char) vec_xl(0, ui); \
-+ align_perm = vec_lvsl(0, ui); \
-+ u = (vector signed char) \
-+ vec_perm(uivP[0], uivP[1], align_perm); \
- \
-- v = (vector signed char) vec_xl(0, vi); \
-+ align_perm = vec_lvsl(0, vi); \
-+ v = (vector signed char) \
-+ vec_perm(vivP[0], vivP[1], align_perm); \
- \
- u = (vector signed char) \
- vec_sub(u, \
---
-2.27.0
-
diff --git a/srcpkgs/ffmpeg/patches/armv5tel-floating-point.patch b/srcpkgs/ffmpeg/patches/armv5tel-floating-point.patch
deleted file mode 100644
index 9a55178c74f0..000000000000
--- a/srcpkgs/ffmpeg/patches/armv5tel-floating-point.patch
+++ /dev/null
@@ -1,18 +0,0 @@
---- a/libavfilter/vf_drawtext.c 2017-10-26 21:03:03.000000000 +0200
-+++ b/libavfilter/vf_drawtext.c 2017-11-21 11:06:49.602284422 +0100
-@@ -39,6 +39,15 @@
- #endif
- #include <fenv.h>
-
-+#if (FE_ALL_EXCEPT == 0)
-+/* E.g. ARM soft float does not define these */
-+#define FE_INVALID 0
-+#define FE_DIVBYZERO 0
-+#define FE_OVERFLOW 0
-+#define FE_UNDERFLOW 0
-+#define FE_INEXACT 0
-+#endif
-+
- #if CONFIG_LIBFONTCONFIG
- #include <fontconfig/fontconfig.h>
- #endif
diff --git a/srcpkgs/ffmpeg/patches/workaround-mesa-readeon-vaapi-bug.patch b/srcpkgs/ffmpeg/patches/workaround-mesa-readeon-vaapi-bug.patch
deleted file mode 100644
index 00e3f68a415b..000000000000
--- a/srcpkgs/ffmpeg/patches/workaround-mesa-readeon-vaapi-bug.patch
+++ /dev/null
@@ -1,28 +0,0 @@
-From 811d290844206fc73dc39c3e5b67d5d895baedf8 Mon Sep 17 00:00:00 2001
-From: Rainer Hochecker <fernetmenta@online.de>
-Date: Sat, 26 Jan 2019 19:48:35 +0100
-Subject: [PATCH] avcodec/vaapi_h264: skip decode if pic has no slices
-
-This fixes / workarounds https://bugs.freedesktop.org/show_bug.cgi?id=105368.
-It was hit frequently when watching h264 channels received via DVB-X.
-Corresponding kodi bug: https://github.com/xbmc/xbmc/issues/15704
----
- libavcodec/vaapi_h264.c | 5 +++++
- 1 file changed, 5 insertions(+)
-
-diff --git a/libavcodec/vaapi_h264.c b/libavcodec/vaapi_h264.c
-index 5854587a255..f12fdc457a4 100644
---- a/libavcodec/vaapi_h264.c
-+++ b/libavcodec/vaapi_h264.c
-@@ -317,6 +317,11 @@ static int vaapi_h264_end_frame(AVCodecContext *avctx)
- H264SliceContext *sl = &h->slice_ctx[0];
- int ret;
-
-+ if (pic->nb_slices == 0) {
-+ ret = AVERROR_INVALIDDATA;
-+ goto finish;
-+ }
-+
- ret = ff_vaapi_decode_issue(avctx, pic);
- if (ret < 0)
- goto finish;
diff --git a/srcpkgs/ffmpeg/template b/srcpkgs/ffmpeg/template
index 23a3d5c9967b..3d99e5173697 100644
--- a/srcpkgs/ffmpeg/template
+++ b/srcpkgs/ffmpeg/template
@@ -1,15 +1,15 @@
# Template file for 'ffmpeg'
# audacity also needs to be bumped when a new ffmpeg version bumps libavformat's soname!
pkgname=ffmpeg
-version=4.4.3
-revision=2
+version=6.0
+revision=1
short_desc="Decoding, encoding and streaming software"
maintainer="Orphaned <orphan@voidlinux.org>"
license="GPL-3.0-or-later"
homepage="https://www.ffmpeg.org"
changelog="https://raw.githubusercontent.com/FFmpeg/FFmpeg/master/Changelog"
distfiles="https://www.ffmpeg.org/releases/ffmpeg-${version}.tar.xz"
-checksum=6c5b6c195e61534766a0b5fe16acc919170c883362612816d0a1c7f4f947006e
+checksum=57be87c22d9b49c112b6d24bc67d42508660e6b718b3db89c44e47e289137082
hostmakedepends="pkg-config perl yasm"
makedepends="zlib-devel bzip2-devel freetype-devel alsa-lib-devel libXfixes-devel
@@ -26,12 +26,13 @@ makedepends="zlib-devel bzip2-devel freetype-devel alsa-lib-devel libXfixes-deve
$(vopt_if webp libwebp-devel) $(vopt_if sofa libmysofa-devel)
$(vopt_if drm libdrm-devel) $(vopt_if svtav1 libsvt-av1-devel)
$(vopt_if srt srt-devel) $(vopt_if rist librist-devel)
- $(vopt_if vulkan 'vulkan-loader Vulkan-Headers')
+ $(vopt_if vulkan 'vulkan-loader Vulkan-Headers Vulkan-Tools Vulkan-ValidationLayers')
+ $(vopt_if onevpl 'onevpl onevpl-devel')
$(vopt_if nvenc nv-codec-headers) $(vopt_if nvdec nv-codec-headers)"
depends="ffplay>=${version}_${revision}"
build_options="x265 v4l2 vaapi vdpau vpx fdk_aac aom nvenc sndio pulseaudio
- dav1d zimg webp sofa vulkan drm svtav1 srt rist nvdec"
+ dav1d zimg webp sofa vulkan drm svtav1 srt rist nvdec onevpl"
build_options_default="x265 v4l2 vpx aom sndio pulseaudio dav1d webp vulkan drm srt rist"
desc_option_srt="Enable support for SRT (Secure, Reliable, Transport)"
desc_option_rist="Enable support for RIST (Reliable Internet Stream Transport)"
@@ -39,7 +40,8 @@ desc_option_sofa="Enable support for AES SOFA"
desc_option_webp="Enable support for WebP"
case "$XBPS_TARGET_MACHINE" in
- i686*|x86_64*) build_options_default+=" vaapi vdpau nvenc nvdec";;
+ i686*) build_options_default+=" vaapi vdpau nvenc nvdec";;
+ x86_64*) build_options_default+=" vaapi vdpau nvenc nvdec onevpl";;
ppc64*) build_options_default+=" vaapi vdpau";;
mips*) CFLAGS="-mnan=legacy";;
esac
@@ -114,18 +116,19 @@ do_configure() {
$(vopt_enable x265 libx265) \
$(vopt_enable v4l2 libv4l2) \
$(vopt_enable aom libaom) $(vopt_enable vaapi) $(vopt_enable vdpau) \
- --enable-libbs2b --enable-avresample --enable-libvidstab \
+ --enable-libbs2b --enable-libvidstab \
$(vopt_enable dav1d libdav1d) \
$(vopt_enable zimg libzimg) \
$(vopt_enable webp libwebp) \
$(vopt_enable sofa libmysofa) \
$(vopt_enable vulkan) \
+ $(vopt_enable onevpl libvpl) \
$(vopt_enable drm libdrm) \
$(vopt_enable svtav1 libsvtav1) \
$(vopt_enable srt libsrt) \
$(vopt_enable rist librist) \
- $(vopt_if nvenc '--enable-nvenc') \
- $(vopt_if nvdec '--enable-nvdec')
+ $(vopt_enable nvenc nvenc) \
+ $(vopt_enable nvdec nvdec)
}
do_build() {
make ${makejobs}
@@ -148,10 +151,8 @@ libavdevice_package() {
}
}
libavresample_package() {
- short_desc="FFmpeg audio resampling library"
- pkg_install() {
- vmove "usr/lib/libavresample.so.*"
- }
+ short_desc="Package deprecated, removal needed"
+ build_style=meta
}
libavformat_package() {
short_desc="FFmpeg file format library"
@@ -198,9 +199,9 @@ ffmpeg-devel_package() {
libavfilter>=${version}_${revision}
libpostproc>=${version}_${revision}
libswscale>=${version}_${revision}
- libswresample>=${version}_${revision}
- libavresample>=${version}_${revision}"
+ libswresample>=${version}_${revision}"
short_desc+=" - development files"
+ conflicts="ffmpeg4-devel"
pkg_install() {
vmove usr/include
vmove usr/lib/pkgconfig
From ac6cf0bdb93725409f9bb2bb8043c0572efe1fde Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 19:56:22 -0400
Subject: [PATCH 002/110] New package: ffmpeg4-4.4.3.
---
srcpkgs/ffmpeg4-devel | 1 +
srcpkgs/ffmpeg4/files/altivec.patch | 60 +++++
.../patches/armv5tel-floating-point.patch | 18 ++
.../workaround-mesa-readeon-vaapi-bug.patch | 28 +++
srcpkgs/ffmpeg4/template | 217 ++++++++++++++++++
srcpkgs/libavcodec4 | 1 +
srcpkgs/libavdevice4 | 1 +
srcpkgs/libavfilter4 | 1 +
srcpkgs/libavformat4 | 1 +
srcpkgs/libavresample4 | 1 +
srcpkgs/libavutil4 | 1 +
srcpkgs/libpostproc4 | 1 +
srcpkgs/libswresample4 | 1 +
srcpkgs/libswscale4 | 1 +
14 files changed, 333 insertions(+)
create mode 120000 srcpkgs/ffmpeg4-devel
create mode 100644 srcpkgs/ffmpeg4/files/altivec.patch
create mode 100644 srcpkgs/ffmpeg4/patches/armv5tel-floating-point.patch
create mode 100644 srcpkgs/ffmpeg4/patches/workaround-mesa-readeon-vaapi-bug.patch
create mode 100644 srcpkgs/ffmpeg4/template
create mode 120000 srcpkgs/libavcodec4
create mode 120000 srcpkgs/libavdevice4
create mode 120000 srcpkgs/libavfilter4
create mode 120000 srcpkgs/libavformat4
create mode 120000 srcpkgs/libavresample4
create mode 120000 srcpkgs/libavutil4
create mode 120000 srcpkgs/libpostproc4
create mode 120000 srcpkgs/libswresample4
create mode 120000 srcpkgs/libswscale4
diff --git a/srcpkgs/ffmpeg4-devel b/srcpkgs/ffmpeg4-devel
new file mode 120000
index 000000000000..887f354e7c6b
--- /dev/null
+++ b/srcpkgs/ffmpeg4-devel
@@ -0,0 +1 @@
+ffmpeg4
\ No newline at end of file
diff --git a/srcpkgs/ffmpeg4/files/altivec.patch b/srcpkgs/ffmpeg4/files/altivec.patch
new file mode 100644
index 000000000000..9c5720046332
--- /dev/null
+++ b/srcpkgs/ffmpeg4/files/altivec.patch
@@ -0,0 +1,60 @@
+revert some altivec specific change on all ppc* except ppc64le*
+
+q66: "We should also throw in a revert of FFmpeg/FFmpeg@3a557c5 but only
+conditionally, for ppc* but not ppc64le* (the new code is valid for
+POWER8 VSX which LE targets as a baseline but not BE)"
+
+
+This reverts commit 3a557c5d88b7b15b5954ba2743febb055549b536.
+---
+ libswscale/ppc/yuv2rgb_altivec.c | 24 ++++++++++++++++++++----
+ 1 file changed, 20 insertions(+), 4 deletions(-)
+
+diff --git a/libswscale/ppc/yuv2rgb_altivec.c b/libswscale/ppc/yuv2rgb_altivec.c
+index 536545293d..c1e2852adb 100644
+--- a/libswscale/ppc/yuv2rgb_altivec.c
++++ b/libswscale/ppc/yuv2rgb_altivec.c
+@@ -305,6 +305,9 @@ static int altivec_ ## name(SwsContext *c, const unsigned char **in, \
+ vector signed short R1, G1, B1; \
+ vector unsigned char R, G, B; \
+ \
++ const vector unsigned char *y1ivP, *y2ivP, *uivP, *vivP; \
++ vector unsigned char align_perm; \
++ \
+ vector signed short lCY = c->CY; \
+ vector signed short lOY = c->OY; \
+ vector signed short lCRV = c->CRV; \
+@@ -335,13 +338,26 @@ static int altivec_ ## name(SwsContext *c, const unsigned char **in, \
+ vec_dstst(oute, (0x02000002 | (((w * 3 + 32) / 32) << 16)), 1); \
+ \
+ for (j = 0; j < w / 16; j++) { \
+- y0 = vec_xl(0, y1i); \
++ y1ivP = (const vector unsigned char *) y1i; \
++ y2ivP = (const vector unsigned char *) y2i; \
++ uivP = (const vector unsigned char *) ui; \
++ vivP = (const vector unsigned char *) vi; \
++ \
++ align_perm = vec_lvsl(0, y1i); \
++ y0 = (vector unsigned char) \
++ vec_perm(y1ivP[0], y1ivP[1], align_perm); \
+ \
+- y1 = vec_xl(0, y2i); \
++ align_perm = vec_lvsl(0, y2i); \
++ y1 = (vector unsigned char) \
++ vec_perm(y2ivP[0], y2ivP[1], align_perm); \
+ \
+- u = (vector signed char) vec_xl(0, ui); \
++ align_perm = vec_lvsl(0, ui); \
++ u = (vector signed char) \
++ vec_perm(uivP[0], uivP[1], align_perm); \
+ \
+- v = (vector signed char) vec_xl(0, vi); \
++ align_perm = vec_lvsl(0, vi); \
++ v = (vector signed char) \
++ vec_perm(vivP[0], vivP[1], align_perm); \
+ \
+ u = (vector signed char) \
+ vec_sub(u, \
+--
+2.27.0
+
diff --git a/srcpkgs/ffmpeg4/patches/armv5tel-floating-point.patch b/srcpkgs/ffmpeg4/patches/armv5tel-floating-point.patch
new file mode 100644
index 000000000000..9a55178c74f0
--- /dev/null
+++ b/srcpkgs/ffmpeg4/patches/armv5tel-floating-point.patch
@@ -0,0 +1,18 @@
+--- a/libavfilter/vf_drawtext.c 2017-10-26 21:03:03.000000000 +0200
++++ b/libavfilter/vf_drawtext.c 2017-11-21 11:06:49.602284422 +0100
+@@ -39,6 +39,15 @@
+ #endif
+ #include <fenv.h>
+
++#if (FE_ALL_EXCEPT == 0)
++/* E.g. ARM soft float does not define these */
++#define FE_INVALID 0
++#define FE_DIVBYZERO 0
++#define FE_OVERFLOW 0
++#define FE_UNDERFLOW 0
++#define FE_INEXACT 0
++#endif
++
+ #if CONFIG_LIBFONTCONFIG
+ #include <fontconfig/fontconfig.h>
+ #endif
diff --git a/srcpkgs/ffmpeg4/patches/workaround-mesa-readeon-vaapi-bug.patch b/srcpkgs/ffmpeg4/patches/workaround-mesa-readeon-vaapi-bug.patch
new file mode 100644
index 000000000000..00e3f68a415b
--- /dev/null
+++ b/srcpkgs/ffmpeg4/patches/workaround-mesa-readeon-vaapi-bug.patch
@@ -0,0 +1,28 @@
+From 811d290844206fc73dc39c3e5b67d5d895baedf8 Mon Sep 17 00:00:00 2001
+From: Rainer Hochecker <fernetmenta@online.de>
+Date: Sat, 26 Jan 2019 19:48:35 +0100
+Subject: [PATCH] avcodec/vaapi_h264: skip decode if pic has no slices
+
+This fixes / workarounds https://bugs.freedesktop.org/show_bug.cgi?id=105368.
+It was hit frequently when watching h264 channels received via DVB-X.
+Corresponding kodi bug: https://github.com/xbmc/xbmc/issues/15704
+---
+ libavcodec/vaapi_h264.c | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+diff --git a/libavcodec/vaapi_h264.c b/libavcodec/vaapi_h264.c
+index 5854587a255..f12fdc457a4 100644
+--- a/libavcodec/vaapi_h264.c
++++ b/libavcodec/vaapi_h264.c
+@@ -317,6 +317,11 @@ static int vaapi_h264_end_frame(AVCodecContext *avctx)
+ H264SliceContext *sl = &h->slice_ctx[0];
+ int ret;
+
++ if (pic->nb_slices == 0) {
++ ret = AVERROR_INVALIDDATA;
++ goto finish;
++ }
++
+ ret = ff_vaapi_decode_issue(avctx, pic);
+ if (ret < 0)
+ goto finish;
diff --git a/srcpkgs/ffmpeg4/template b/srcpkgs/ffmpeg4/template
new file mode 100644
index 000000000000..e736c205371d
--- /dev/null
+++ b/srcpkgs/ffmpeg4/template
@@ -0,0 +1,217 @@
+# Template file for 'ffmpeg4'
+# audacity also needs to be bumped when a new ffmpeg version bumps libavformat's soname!
+pkgname=ffmpeg4
+version=4.4.3
+revision=1
+short_desc="Decoding, encoding and streaming software - ffmpeg4 libraries only"
+maintainer="Orphaned <orphan@voidlinux.org>"
+license="GPL-3.0-or-later"
+homepage="https://www.ffmpeg.org"
+changelog="https://raw.githubusercontent.com/FFmpeg/FFmpeg/master/Changelog"
+distfiles="https://www.ffmpeg.org/releases/ffmpeg-${version}.tar.xz"
+checksum=6c5b6c195e61534766a0b5fe16acc919170c883362612816d0a1c7f4f947006e
+
+hostmakedepends="pkg-config perl yasm"
+makedepends="zlib-devel bzip2-devel freetype-devel alsa-lib-devel libXfixes-devel
+ libXext-devel libXvMC-devel libxcb-devel lame-devel libtheora-devel
+ libvorbis-devel x264-devel xvidcore-devel jack-devel SDL2-devel
+ libcdio-paranoia-devel librtmp-devel libmodplug-devel gnutls-devel
+ speex-devel celt-devel harfbuzz-devel libass-devel opus-devel ocl-icd-devel
+ libbs2b-devel libvidstab-devel $(vopt_if pulseaudio pulseaudio-devel)
+ $(vopt_if vaapi libva-devel) $(vopt_if vdpau libvdpau-devel)
+ $(vopt_if x265 x265-devel) $(vopt_if v4l2 v4l-utils-devel)
+ $(vopt_if fdk_aac fdk-aac-devel) $(vopt_if vpx libvpx-devel)
+ $(vopt_if aom libaom-devel) $(vopt_if sndio sndio-devel)
+ $(vopt_if dav1d libdav1d-devel) $(vopt_if zimg zimg-devel)
+ $(vopt_if webp libwebp-devel) $(vopt_if sofa libmysofa-devel)
+ $(vopt_if drm libdrm-devel) $(vopt_if svtav1 libsvt-av1-devel)
+ $(vopt_if srt srt-devel) $(vopt_if rist librist-devel)
+ $(vopt_if vulkan 'vulkan-loader Vulkan-Headers')
+ $(vopt_if mfx 'libmfx libmfx-devel')
+ $(vopt_if nvenc nv-codec-headers) $(vopt_if nvdec nv-codec-headers)"
+
+build_options="x265 v4l2 vaapi vdpau vpx fdk_aac aom nvenc sndio pulseaudio
+ dav1d zimg webp sofa vulkan drm svtav1 srt rist nvdec mfx"
+build_options_default="x265 v4l2 vpx aom sndio pulseaudio dav1d webp vulkan drm srt rist"
+
+desc_option_srt="Enable support for SRT (Secure, Reliable, Transport)"
+desc_option_rist="Enable support for RIST (Reliable Internet Stream Transport)"
+desc_option_sofa="Enable support for AES SOFA"
+desc_option_webp="Enable support for WebP"
+
+case "$XBPS_TARGET_MACHINE" in
+ i686*) build_options_default+=" vaapi vdpau nvenc nvdec";;
+ x86_64*) build_options_default+=" vaapi vdpau mfx nvenc nvdec";;
+ ppc64*) build_options_default+=" vaapi vdpau";;
+ mips*) CFLAGS="-mnan=legacy";;
+esac
+
+if [ "$XBPS_TARGET_WORDSIZE" != "32" ]; then
+ build_options_default+=" svtav1"
+fi
+
+if [ "$XBPS_TARGET_NO_ATOMIC8" ]; then
+ makedepends+=" libatomic-devel"
+fi
+
+_apply_patch() {
+ local args="$1" pname="$(basename $2)"
+
+ if [ ! -f ".${pname}_done" ]; then
+ patch -N $args -i $2
+ touch .${pname}_done
+ fi
+}
+
+post_patch() {
+ case "$XBPS_TARGET_MACHINE" in
+ ppc64le*) ;;
+ ppc*) _apply_patch -p1 ${FILESDIR}/altivec.patch ;;
+ esac
+}
+
+do_configure() {
+ # Fix gcc on x86_64-musl only
+ if [ "$XBPS_TARGET_MACHINE" = "x86_64-musl" ]; then
+ sed -i configure -e "s;_cflags_speed='-O3';_cflags_speed='-O2';"
+ fi
+
+ if [ "$CROSS_BUILD" ]; then
+ case "$XBPS_TARGET_MACHINE" in
+ arm*) _arch="arm";;
+ aarch64*) _arch="aarch64";;
+ mips*) _arch="mips";;
+ ppc64*) _arch="ppc64";;
+ ppc*) _arch="ppc";;
+ *) _arch="${XBPS_TARGET_MACHINE%%-musl}";;
+ esac
+
+ _args+=" --enable-cross-compile
+ --sysroot=$XBPS_CROSS_BASE
+ --cross-prefix=${XBPS_CROSS_TRIPLET}-
+ --target-os=linux --arch=${_arch}"
+ fi
+
+ case "$XBPS_TARGET_MACHINE" in
+ ppc|ppc-musl) _args+=" --disable-altivec";;
+ esac
+
+ if [ "$XBPS_TARGET_NO_ATOMIC8" ]; then
+ _args+=" --extra-libs=-latomic"
+ fi
+
+ ./configure --prefix=/usr --disable-debug --enable-gpl --enable-gnutls \
+ --disable-stripping \
+ --enable-libcdio --enable-version3 --enable-runtime-cpudetect \
+ --enable-libmp3lame --enable-libvorbis --enable-libxvid \
+ --enable-libx264 $(vopt_enable vpx libvpx) --enable-libtheora \
+ --enable-shared --enable-static --enable-libxcb \
+ $(vopt_enable pulseaudio libpulse) --enable-libfreetype --enable-libmodplug \
+ --enable-libspeex --enable-libcelt --enable-libass \
+ --enable-libopus --enable-librtmp --enable-libjack \
+ $(vopt_if fdk_aac '--enable-nonfree --enable-libfdk-aac') \
+ --disable-libopencore_amrnb --disable-libopencore_amrwb \
+ --disable-libopenjpeg \
+ --enable-postproc --enable-opencl ${_args} \
+ $(vopt_enable x265 libx265) \
+ $(vopt_enable v4l2 libv4l2) \
+ $(vopt_enable aom libaom) $(vopt_enable vaapi) $(vopt_enable vdpau) \
+ --enable-libbs2b --enable-avresample --enable-libvidstab \
+ $(vopt_enable dav1d libdav1d) \
+ $(vopt_enable zimg libzimg) \
+ $(vopt_enable webp libwebp) \
+ $(vopt_enable sofa libmysofa) \
+ $(vopt_enable vulkan) \
+ $(vopt_enable drm libdrm) \
+ $(vopt_enable svtav1 libsvtav1) \
+ $(vopt_enable srt libsrt) \
+ $(vopt_enable rist librist) \
+ $(vopt_enable mfx libmfx) \
+ $(vopt_if nvenc '--enable-nvenc') \
+ $(vopt_if nvdec '--enable-nvdec')
+}
+do_build() {
+ make ${makejobs}
+ make doc/ff{mpeg,play}.1
+}
+do_install() {
+ make DESTDIR=${DESTDIR} install install-man
+ rm -rf ${DESTDIR}/usr/bin
+}
+
+libavcodec4_package() {
+ short_desc="FFmpeg codec library"
+ pkg_install() {
+ vmove "usr/lib/libavcodec.so.*"
+ }
+}
+libavdevice4_package() {
+ short_desc="FFmpeg device handling library"
+ pkg_install() {
+ vmove "usr/lib/libavdevice.so.*"
+ }
+}
+libavresample4_package() {
+ short_desc="FFmpeg audio resampling library"
+ pkg_install() {
+ vmove "usr/lib/libavresample.so.*"
+ }
+}
+libavformat4_package() {
+ short_desc="FFmpeg file format library"
+ pkg_install() {
+ vmove "usr/lib/libavformat.so.*"
+ }
+}
+libavutil4_package() {
+ short_desc="FFmpeg utility library"
+ pkg_install() {
+ vmove "usr/lib/libavutil.so.*"
+ }
+}
+libavfilter4_package() {
+ short_desc="FFmpeg audio/video filter library"
+ pkg_install() {
+ vmove "usr/lib/libavfilter.so.*"
+ }
+}
+libpostproc4_package() {
+ short_desc="FFmpeg video postprocessing library"
+ pkg_install() {
+ vmove "usr/lib/libpostproc.so.*"
+ }
+}
+libswscale4_package() {
+ short_desc="FFmpeg video scaling library"
+ pkg_install() {
+ vmove "usr/lib/libswscale.so.*"
+ }
+}
+libswresample4_package() {
+ short_desc="FFmpeg video resampling library"
+ pkg_install() {
+ vmove "usr/lib/libswresample.so.*"
+ }
+}
+ffmpeg4-devel_package() {
+ depends="
+ libavcodec4>=${version}_${revision}
+ libavdevice4>=${version}_${revision}
+ libavformat4>=${version}_${revision}
+ libavutil4>=${version}_${revision}
+ libavfilter4>=${version}_${revision}
+ libpostproc4>=${version}_${revision}
+ libswscale4>=${version}_${revision}
+ libswresample4>=${version}_${revision}
+ libavresample4>=${version}_${revision}"
+ short_desc+=" - development files"
+ conflicts="ffmpeg-devel"
+ pkg_install() {
+ vmove usr/include
+ vmove usr/lib/pkgconfig
+ vmove usr/lib/*.a
+ vmove usr/lib/*.so
+ vmove usr/share/ffmpeg/examples
+ vmove usr/share/man/man3
+ }
+}
diff --git a/srcpkgs/libavcodec4 b/srcpkgs/libavcodec4
new file mode 120000
index 000000000000..887f354e7c6b
--- /dev/null
+++ b/srcpkgs/libavcodec4
@@ -0,0 +1 @@
+ffmpeg4
\ No newline at end of file
diff --git a/srcpkgs/libavdevice4 b/srcpkgs/libavdevice4
new file mode 120000
index 000000000000..887f354e7c6b
--- /dev/null
+++ b/srcpkgs/libavdevice4
@@ -0,0 +1 @@
+ffmpeg4
\ No newline at end of file
diff --git a/srcpkgs/libavfilter4 b/srcpkgs/libavfilter4
new file mode 120000
index 000000000000..887f354e7c6b
--- /dev/null
+++ b/srcpkgs/libavfilter4
@@ -0,0 +1 @@
+ffmpeg4
\ No newline at end of file
diff --git a/srcpkgs/libavformat4 b/srcpkgs/libavformat4
new file mode 120000
index 000000000000..887f354e7c6b
--- /dev/null
+++ b/srcpkgs/libavformat4
@@ -0,0 +1 @@
+ffmpeg4
\ No newline at end of file
diff --git a/srcpkgs/libavresample4 b/srcpkgs/libavresample4
new file mode 120000
index 000000000000..887f354e7c6b
--- /dev/null
+++ b/srcpkgs/libavresample4
@@ -0,0 +1 @@
+ffmpeg4
\ No newline at end of file
diff --git a/srcpkgs/libavutil4 b/srcpkgs/libavutil4
new file mode 120000
index 000000000000..887f354e7c6b
--- /dev/null
+++ b/srcpkgs/libavutil4
@@ -0,0 +1 @@
+ffmpeg4
\ No newline at end of file
diff --git a/srcpkgs/libpostproc4 b/srcpkgs/libpostproc4
new file mode 120000
index 000000000000..887f354e7c6b
--- /dev/null
+++ b/srcpkgs/libpostproc4
@@ -0,0 +1 @@
+ffmpeg4
\ No newline at end of file
diff --git a/srcpkgs/libswresample4 b/srcpkgs/libswresample4
new file mode 120000
index 000000000000..887f354e7c6b
--- /dev/null
+++ b/srcpkgs/libswresample4
@@ -0,0 +1 @@
+ffmpeg4
\ No newline at end of file
diff --git a/srcpkgs/libswscale4 b/srcpkgs/libswscale4
new file mode 120000
index 000000000000..887f354e7c6b
--- /dev/null
+++ b/srcpkgs/libswscale4
@@ -0,0 +1 @@
+ffmpeg4
\ No newline at end of file
From 76e6a1ba626611e69f2530f2f949b8b00d9e9ca2 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 19:59:04 -0400
Subject: [PATCH 003/110] opencv: update to 4.7.0.
---
common/shlibs | 104 ++++++++++++++++++++--------------------
srcpkgs/opencv/template | 8 ++--
2 files changed, 56 insertions(+), 56 deletions(-)
diff --git a/common/shlibs b/common/shlibs
index 9497f6499aa2..fcc7401be626 100644
--- a/common/shlibs
+++ b/common/shlibs
@@ -2137,58 +2137,58 @@ libcapstone.so.4 capstone-4.0_1
libhavege.so.2 libhaveged-1.9.11_1
libnih.so.1 libnih-1.0.3_1
libnih-dbus.so.1 libnih-1.0.3_1
-libopencv_quality.so.406 libopencv-4.6.0_1
-libopencv_reg.so.406 libopencv-4.6.0_1
-libopencv_surface_matching.so.406 libopencv-4.6.0_1
-libopencv_xphoto.so.406 libopencv-4.6.0_1
-libopencv_freetype.so.406 libopencv-4.6.0_1
-libopencv_fuzzy.so.406 libopencv-4.6.0_1
-libopencv_hfs.so.406 libopencv-4.6.0_1
-libopencv_img_hash.so.406 libopencv-4.6.0_1
-libopencv_line_descriptor.so.406 libopencv-4.6.0_1
-libopencv_saliency.so.406 libopencv-4.6.0_1
-libopencv_structured_light.so.406 libopencv-4.6.0_1
-libopencv_aruco.so.406 libopencv-4.6.0_1
-libopencv_bgsegm.so.406 libopencv-4.6.0_1
-libopencv_bioinspired.so.406 libopencv-4.6.0_1
-libopencv_ccalib.so.406 libopencv-4.6.0_1
-libopencv_face.so.406 libopencv-4.6.0_1
-libopencv_tracking.so.406 libopencv-4.6.0_1
-libopencv_xfeatures2d.so.406 libopencv-4.6.0_1
-libopencv_optflow.so.406 libopencv-4.6.0_1
-libopencv_ximgproc.so.406 libopencv-4.6.0_1
-libopencv_plot.so.406 libopencv-4.6.0_1
-libopencv_text.so.406 libopencv-4.6.0_1
-libopencv_ml.so.406 libopencv-4.6.0_1
-libopencv_objdetect.so.406 libopencv-4.6.0_1
-libopencv_dnn.so.406 libopencv-4.6.0_1
-libopencv_shape.so.406 libopencv-4.6.0_1
-libopencv_stitching.so.406 libopencv-4.6.0_1
-libopencv_photo.so.406 libopencv-4.6.0_1
-libopencv_video.so.406 libopencv-4.6.0_1
-libopencv_calib3d.so.406 libopencv-4.6.0_1
-libopencv_features2d.so.406 libopencv-4.6.0_1
-libopencv_flann.so.406 libopencv-4.6.0_1
-libopencv_highgui.so.406 libopencv-4.6.0_1
-libopencv_videoio.so.406 libopencv-4.6.0_1
-libopencv_imgcodecs.so.406 libopencv-4.6.0_1
-libopencv_imgproc.so.406 libopencv-4.6.0_1
-libopencv_core.so.406 libopencv-4.6.0_1
-libopencv_superres.so.406 libopencv-4.6.0_1
-libopencv_videostab.so.406 libopencv-4.6.0_1
-libopencv_gapi.so.406 libopencv-4.6.0_1
-libopencv_xobjdetect.so.406 libopencv-4.6.0_1
-libopencv_datasets.so.406 libopencv-4.6.0_1
-libopencv_dnn_objdetect.so.406 libopencv-4.6.0_1
-libopencv_dnn_superres.so.406 libopencv-4.6.0_1
-libopencv_dpm.so.406 libopencv-4.6.0_1
-libopencv_phase_unwrapping.so.406 libopencv-4.6.0_1
-libopencv_stereo.so.406 libopencv-4.6.0_1
-libopencv_rapid.so.406 libopencv-4.6.0_1
-libopencv_intensity_transform.so.406 libopencv-4.6.0_1
-libopencv_alphamat.so.406 libopencv-4.6.0_1
-libopencv_barcode.so.406 libopencv-4.6.0_1
-libopencv_mcc.so.406 libopencv-4.6.0_1
+libopencv_quality.so.407 libopencv-4.7.0_1
+libopencv_reg.so.407 libopencv-4.7.0_1
+libopencv_surface_matching.so.407 libopencv-4.7.0_1
+libopencv_xphoto.so.407 libopencv-4.7.0_1
+libopencv_freetype.so.407 libopencv-4.7.0_1
+libopencv_fuzzy.so.407 libopencv-4.7.0_1
+libopencv_hfs.so.407 libopencv-4.7.0_1
+libopencv_img_hash.so.407 libopencv-4.7.0_1
+libopencv_line_descriptor.so.407 libopencv-4.7.0_1
+libopencv_saliency.so.407 libopencv-4.7.0_1
+libopencv_structured_light.so.407 libopencv-4.7.0_1
+libopencv_aruco.so.407 libopencv-4.7.0_1
+libopencv_bgsegm.so.407 libopencv-4.7.0_1
+libopencv_bioinspired.so.407 libopencv-4.7.0_1
+libopencv_ccalib.so.407 libopencv-4.7.0_1
+libopencv_face.so.407 libopencv-4.7.0_1
+libopencv_tracking.so.407 libopencv-4.7.0_1
+libopencv_xfeatures2d.so.407 libopencv-4.7.0_1
+libopencv_optflow.so.407 libopencv-4.7.0_1
+libopencv_ximgproc.so.407 libopencv-4.7.0_1
+libopencv_plot.so.407 libopencv-4.7.0_1
+libopencv_text.so.407 libopencv-4.7.0_1
+libopencv_ml.so.407 libopencv-4.7.0_1
+libopencv_objdetect.so.407 libopencv-4.7.0_1
+libopencv_dnn.so.407 libopencv-4.7.0_1
+libopencv_shape.so.407 libopencv-4.7.0_1
+libopencv_stitching.so.407 libopencv-4.7.0_1
+libopencv_photo.so.407 libopencv-4.7.0_1
+libopencv_video.so.407 libopencv-4.7.0_1
+libopencv_calib3d.so.407 libopencv-4.7.0_1
+libopencv_features2d.so.407 libopencv-4.7.0_1
+libopencv_flann.so.407 libopencv-4.7.0_1
+libopencv_highgui.so.407 libopencv-4.7.0_1
+libopencv_videoio.so.407 libopencv-4.7.0_1
+libopencv_imgcodecs.so.407 libopencv-4.7.0_1
+libopencv_imgproc.so.407 libopencv-4.7.0_1
+libopencv_core.so.407 libopencv-4.7.0_1
+libopencv_superres.so.407 libopencv-4.7.0_1
+libopencv_videostab.so.407 libopencv-4.7.0_1
+libopencv_gapi.so.407 libopencv-4.7.0_1
+libopencv_xobjdetect.so.407 libopencv-4.7.0_1
+libopencv_datasets.so.407 libopencv-4.7.0_1
+libopencv_dnn_objdetect.so.407 libopencv-4.7.0_1
+libopencv_dnn_superres.so.407 libopencv-4.7.0_1
+libopencv_dpm.so.407 libopencv-4.7.0_1
+libopencv_phase_unwrapping.so.407 libopencv-4.7.0_1
+libopencv_stereo.so.407 libopencv-4.7.0_1
+libopencv_rapid.so.407 libopencv-4.7.0_1
+libopencv_intensity_transform.so.407 libopencv-4.7.0_1
+libopencv_alphamat.so.407 libopencv-4.7.0_1
+libopencv_barcode.so.407 libopencv-4.7.0_1
+libopencv_mcc.so.407 libopencv-4.7.0_1
libuniconf.so.4.6 wvstreams-4.6.1_20
libwvbase.so.4.6 wvstreams-4.6.1_20
libwvutils.so.4.6 wvstreams-4.6.1_20
diff --git a/srcpkgs/opencv/template b/srcpkgs/opencv/template
index 69c635b1ad2b..41f3183f1582 100644
--- a/srcpkgs/opencv/template
+++ b/srcpkgs/opencv/template
@@ -1,7 +1,7 @@
# Template file for 'opencv'
pkgname=opencv
-version=4.6.0
-revision=4
+version=4.7.0
+revision=1
create_wrksrc=yes
build_wrksrc=${pkgname}-${version}
build_style=cmake
@@ -24,8 +24,8 @@ homepage="https://opencv.org"
changelog="https://github.com/opencv/opencv/wiki/ChangeLog"
distfiles="https://github.com/opencv/opencv/archive/${version}.tar.gz
https://github.com/opencv/opencv_contrib/archive/${version}.tar.gz>contrib.tar.gz"
-checksum="1ec1cba65f9f20fe5a41fda1586e01c70ea0c9a6d7b67c9e13edf0cfe2239277
- 1777d5fd2b59029cf537e5fd6f8aa68d707075822f90bde683fcde086f85f7a7"
+checksum="8df0079cdbe179748a18d44731af62a245a45ebf5085223dc03133954c662973
+ 42df840cf9055e59d0e22c249cfb19f04743e1bdad113d31b1573d3934d62584"
patch_args="-Np1 -d ${build_wrksrc}"
# tests hang indenfinitely, even with test data included
make_check=no
From a509c1b5be006ed1b2f1ff94bc7be74ad8e92594 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 19:59:45 -0400
Subject: [PATCH 004/110] actiona: revbump for opencv-4.7.0
---
srcpkgs/actiona/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/actiona/template b/srcpkgs/actiona/template
index cf5f0b7a2ae6..0d899311e6df 100644
--- a/srcpkgs/actiona/template
+++ b/srcpkgs/actiona/template
@@ -1,7 +1,7 @@
# Template file for 'actiona'
pkgname=actiona
version=3.10.1
-revision=2
+revision=3
build_style=qmake
configure_args="PKGCONFIG_OPENCV=opencv4"
hostmakedepends="pkg-config qt5-plugin-mysql qt5-qmake qt5-host-tools"
From 190023a92a4b726734883507c8721a38a9bf2642 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 19:59:45 -0400
Subject: [PATCH 005/110] gmic: revbump for opencv-4.7.0
---
srcpkgs/gmic/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/gmic/template b/srcpkgs/gmic/template
index 24a9c7218fdf..0bb4034d5cc8 100644
--- a/srcpkgs/gmic/template
+++ b/srcpkgs/gmic/template
@@ -1,7 +1,7 @@
# Template file for 'gmic'
pkgname=gmic
version=3.1.6
-revision=3
+revision=4
_zart_hash=34ebf6cce0bafb98abe57cec83c4a02cd1abeca0
create_wrksrc=yes
build_wrksrc="src"
From 9b1d36b0e1e4c7a9465960f003785edfc048fc6e Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 19:59:46 -0400
Subject: [PATCH 006/110] qimgv: revbump for opencv-4.7.0
---
srcpkgs/qimgv/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/qimgv/template b/srcpkgs/qimgv/template
index 7eb30db33992..dd341dfe1bfc 100644
--- a/srcpkgs/qimgv/template
+++ b/srcpkgs/qimgv/template
@@ -1,7 +1,7 @@
# Template file for 'qimgv'
pkgname=qimgv
version=1.0.2
-revision=2
+revision=3
build_style=cmake
configure_args="$(vopt_if video -DVIDEO_SUPPORT=ON -DVIDEO_SUPPORT=OFF)
$(vopt_if scale -DOPENCV_SUPPORT=ON -DOPENCV_SUPPORT=OFF)
From e346a9f402d63ffb70b7180928a879d641eee6ec Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 19:59:46 -0400
Subject: [PATCH 007/110] retroshare: revbump for opencv-4.7.0
---
srcpkgs/retroshare/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/retroshare/template b/srcpkgs/retroshare/template
index 8a0786c21a08..72023fa98b75 100644
--- a/srcpkgs/retroshare/template
+++ b/srcpkgs/retroshare/template
@@ -1,7 +1,7 @@
# Template file for 'retroshare'
pkgname=retroshare
version=0.6.6
-revision=2
+revision=4
build_style=qmake
#XXX broadcast feature requires an ancient udp-discovery-cpp which either needs
# to be fetched+patched (FTBFS) here or packaged :/
From 9785459d7311f68d0339b13fac30db2fecfaa877 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 19:59:46 -0400
Subject: [PATCH 008/110] siril: revbump for opencv-4.7.0
---
srcpkgs/siril/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/siril/template b/srcpkgs/siril/template
index e88f30fb6178..84332f79d060 100644
--- a/srcpkgs/siril/template
+++ b/srcpkgs/siril/template
@@ -1,7 +1,7 @@
# Template file for 'siril'
pkgname=siril
version=0.9.12
-revision=9
+revision=10
build_style=gnu-configure
hostmakedepends="pkg-config intltool autoconf automake gettext-devel"
makedepends="fftw-devel libconfig-devel libopencv-devel libffms2-devel
From b00da3a5eb14e386b5fe8aaf72950c12d60991b0 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 19:59:46 -0400
Subject: [PATCH 009/110] waifu2x-converter-cpp: revbump for opencv-4.7.0
---
srcpkgs/waifu2x-converter-cpp/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/waifu2x-converter-cpp/template b/srcpkgs/waifu2x-converter-cpp/template
index 8c095d0d7bab..aa52d8c981a8 100644
--- a/srcpkgs/waifu2x-converter-cpp/template
+++ b/srcpkgs/waifu2x-converter-cpp/template
@@ -1,7 +1,7 @@
# Template file for 'waifu2x-converter-cpp'
pkgname=waifu2x-converter-cpp
version=5.2.4
-revision=2
+revision=3
build_style=cmake
configure_args="-DINSTALL_MODELS=ON"
hostmakedepends="pkg-config"
From 3455096e71cf50ea1a0920ba62c067cbbbdaa9ba Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:00:38 -0400
Subject: [PATCH 010/110] vlc: revbump for ffmpeg4-4.4.3
---
srcpkgs/vlc/template | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/srcpkgs/vlc/template b/srcpkgs/vlc/template
index 210762b0a7e2..855ca5238662 100644
--- a/srcpkgs/vlc/template
+++ b/srcpkgs/vlc/template
@@ -1,7 +1,7 @@
# Template file for 'vlc'
pkgname=vlc
version=3.0.18
-revision=3
+revision=4
build_style=gnu-configure
configure_args="--disable-gme --disable-libtar --enable-jack
--enable-live555 --disable-fluidsynth --enable-dvdread
@@ -25,7 +25,7 @@ lib32disabled=yes
hostmakedepends="automake libtool pkg-config flex gettext libgcrypt-devel
live555-devel gettext-devel $(vopt_if lua lua52) $(vopt_if chromecast protobuf)"
makedepends="
- avahi-libs-devel dbus-glib-devel faad2-devel ffmpeg-devel freefont-ttf
+ avahi-libs-devel dbus-glib-devel faad2-devel ffmpeg4-devel freefont-ttf
gnutls-devel jack-devel liba52-devel libass-devel libbluray-devel
libcdio-devel libdca-devel libdvbpsi-devel libdvdnav-devel libmad-devel
libmatroska-devel libmodplug-devel libmpcdec-devel libmpeg2-devel
From 406094108d480e8c65e8b6d9b2974243bd797347 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:00:55 -0400
Subject: [PATCH 011/110] osg: revbump for ffmpeg4-4.4.3
---
srcpkgs/osg/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/osg/template b/srcpkgs/osg/template
index a9ebbd287933..755793f7e11b 100644
--- a/srcpkgs/osg/template
+++ b/srcpkgs/osg/template
@@ -8,7 +8,7 @@ build_helper="qemu"
configure_args="-DLIB_POSTFIX="
hostmakedepends="pkg-config xrandr"
makedepends="MesaLib-devel gtkglext-devel libcurl-devel giflib-devel librsvg-devel
- jasper-devel tiff-devel libgdal-devel libgta-devel ffmpeg-devel xine-lib-devel
+ jasper-devel tiff-devel libgdal-devel libgta-devel ffmpeg4-devel xine-lib-devel
SDL2-devel gst-plugins-base1-devel
$(vopt_if openexr libopenexr-devel)
$(vopt_if poppler poppler-glib-devel)
From 119d0efa7794b3eac98f14cf2cca68dbe5bf84af Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:13 -0400
Subject: [PATCH 012/110] xine-lib: revbump for ffmpeg4-4.4.3
---
srcpkgs/xine-lib/template | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/srcpkgs/xine-lib/template b/srcpkgs/xine-lib/template
index f713eff49b07..ed6194c17d11 100644
--- a/srcpkgs/xine-lib/template
+++ b/srcpkgs/xine-lib/template
@@ -1,6 +1,6 @@
# Template file for 'xine-lib'
pkgname=xine-lib
-version=1.2.12
+version=1.2.13
revision=1
build_style=gnu-configure
configure_args="--disable-vcd --disable-gnomevfs --without-esound --disable-dxr3
@@ -8,7 +8,7 @@ configure_args="--disable-vcd --disable-gnomevfs --without-esound --disable-dxr3
hostmakedepends="automake gettext-devel libtool pkg-config perl"
makedepends="
zlib-devel alsa-lib-devel libxcb-devel libSM-devel libXext-devel libXv-devel
- libXvMC-devel liba52-devel libmad-devel ffmpeg-devel pulseaudio-devel
+ libXvMC-devel liba52-devel libmad-devel ffmpeg4-devel pulseaudio-devel
jack-devel samba-devel libflac-devel libmodplug-devel libmpcdec-devel
speex-devel libtheora-devel libvorbis-devel libdca-devel faad2-devel
libcdio-devel libbluray-devel aalib-devel libcaca-devel libXinerama-devel
@@ -19,7 +19,7 @@ license="GPL-2.0-or-later, LGPL-2.0-or-later"
homepage="http://www.xine-project.org"
changelog="https://sourceforge.net/projects/xine/files/xine-lib/${version}/README.txt/view"
distfiles="${SOURCEFORGE_SITE}/xine/${pkgname}-${version}.tar.xz"
-checksum=d606270468e1540c2a89c0d7f5fdf11e17ecc0c2698cc0bcb1065ff26abee098
+checksum=5f10d6d718a4a51c17ed1b32b031d4f9b80b061e8276535b2be31e5ac4b75e6f
case "$XBPS_TARGET_MACHINE" in
i686-musl)
From 29b9b402f89b90493d5647b9d13714b19d3f3708 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:45 -0400
Subject: [PATCH 013/110] QMPlay2: revbump for ffmpeg-6.0
---
srcpkgs/QMPlay2/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/QMPlay2/template b/srcpkgs/QMPlay2/template
index ad73cbb01bae..55284c051161 100644
--- a/srcpkgs/QMPlay2/template
+++ b/srcpkgs/QMPlay2/template
@@ -1,7 +1,7 @@
# Template file for 'QMPlay2'
pkgname=QMPlay2
version=23.02.05
-revision=1
+revision=2
build_style=cmake
hostmakedepends="pkg-config qt5-qmake qt5-host-tools"
makedepends="alsa-lib-devel ffmpeg-devel libass-devel libcdio-devel libgme-devel
From 18eefc5a66bc8cbff261cd6c775148ed3fd26d52 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:45 -0400
Subject: [PATCH 014/110] alsa-plugins: revbump for ffmpeg-6.0
---
srcpkgs/alsa-plugins/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/alsa-plugins/template b/srcpkgs/alsa-plugins/template
index 0bfa6d9fd264..a5708a7d82a8 100644
--- a/srcpkgs/alsa-plugins/template
+++ b/srcpkgs/alsa-plugins/template
@@ -1,7 +1,7 @@
# Template file for 'alsa-plugins'
pkgname=alsa-plugins
version=1.2.7.1
-revision=1
+revision=2
build_style=gnu-configure
configure_args="--disable-maemo-plugin"
hostmakedepends="pkg-config"
From 0a3360b77f9a48aecca6322db8909b875405ddef Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:45 -0400
Subject: [PATCH 015/110] arcan: revbump for ffmpeg-6.0
---
srcpkgs/arcan/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/arcan/template b/srcpkgs/arcan/template
index 7be9652eccf3..ccc7df11ceac 100644
--- a/srcpkgs/arcan/template
+++ b/srcpkgs/arcan/template
@@ -2,7 +2,7 @@
# !! keep synced with: acfgfs aclip aloadimage
pkgname=arcan
version=0.6.2.1
-revision=1
+revision=2
create_wrksrc=yes
build_wrksrc=arcan/src
build_style=cmake
From 5ef415dbca0848cad76a128f45eb98cf4b5ea7e0 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:45 -0400
Subject: [PATCH 016/110] attract: revbump for ffmpeg4-4.4.3
---
srcpkgs/attract/template | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/srcpkgs/attract/template b/srcpkgs/attract/template
index 26144e931a3c..e760bf0d18ae 100644
--- a/srcpkgs/attract/template
+++ b/srcpkgs/attract/template
@@ -1,12 +1,12 @@
# Template file for 'attract'
pkgname=attract
version=2.6.2
-revision=1
+revision=2
build_style=gnu-makefile
make_build_args="VERBOSE=1"
make_use_env=yes
hostmakedepends="pkg-config"
-makedepends="SFML-devel ffmpeg-devel fontconfig-devel glu-devel libarchive-devel
+makedepends="SFML-devel ffmpeg4-devel fontconfig-devel glu-devel libarchive-devel
libcurl-devel libjpeg-turbo-devel xine-lib rapidjson libXrandr-devel"
depends="git"
short_desc="Attract-Mode is a graphical frontend for emulators"
From d8e13c06eacf1e520e7ef537dbb449a3ffbe1412 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:45 -0400
Subject: [PATCH 017/110] aubio: revbump for ffmpeg-6.0
---
srcpkgs/aubio/patches/ffmpeg5.patch | 25 +++++++++++++++++++++++++
srcpkgs/aubio/template | 2 +-
2 files changed, 26 insertions(+), 1 deletion(-)
create mode 100644 srcpkgs/aubio/patches/ffmpeg5.patch
diff --git a/srcpkgs/aubio/patches/ffmpeg5.patch b/srcpkgs/aubio/patches/ffmpeg5.patch
new file mode 100644
index 000000000000..aace41a6e6d9
--- /dev/null
+++ b/srcpkgs/aubio/patches/ffmpeg5.patch
@@ -0,0 +1,25 @@
+From 8a05420e5dd8c7b8b2447f82dc919765876511b3 Mon Sep 17 00:00:00 2001
+From: Paul Brossier <piem@piem.org>
+Date: Tue, 25 Jan 2022 18:30:27 +0100
+Subject: [PATCH] [source_avcodec] define FF_API_LAVF_AVCTX for libavcodec >
+ 59, thx @berolinux (closes gh-353)
+
+---
+ src/io/source_avcodec.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/src/io/source_avcodec.c b/src/io/source_avcodec.c
+index e0ae93b5..1421bd9a 100644
+--- a/src/io/source_avcodec.c
++++ b/src/io/source_avcodec.c
+@@ -68,6 +68,10 @@
+ #define AUBIO_AVCODEC_MAX_BUFFER_SIZE AV_INPUT_BUFFER_MIN_SIZE
+ #endif
+
++#if LIBAVCODEC_VERSION_MAJOR >= 59
++#define FF_API_LAVF_AVCTX 1
++#endif
++
+ struct _aubio_source_avcodec_t {
+ uint_t hop_size;
+ uint_t samplerate;
diff --git a/srcpkgs/aubio/template b/srcpkgs/aubio/template
index ad1c4b256991..7d875cc02541 100644
--- a/srcpkgs/aubio/template
+++ b/srcpkgs/aubio/template
@@ -1,7 +1,7 @@
# Template file for 'aubio'
pkgname=aubio
version=0.4.9
-revision=1
+revision=2
build_style=waf3
# XXX lash, pure and swig support.
hostmakedepends="pkg-config txt2man"
From 24e5231c5ed6e3a9c30548e6eb2a441c3f490d3b Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:45 -0400
Subject: [PATCH 018/110] audacious-plugins: revbump for ffmpeg-6.0
---
.../audacious-plugins/patches/ffmpeg5.patch | 43 +++++++++++++++++++
srcpkgs/audacious-plugins/template | 2 +-
2 files changed, 44 insertions(+), 1 deletion(-)
create mode 100644 srcpkgs/audacious-plugins/patches/ffmpeg5.patch
diff --git a/srcpkgs/audacious-plugins/patches/ffmpeg5.patch b/srcpkgs/audacious-plugins/patches/ffmpeg5.patch
new file mode 100644
index 000000000000..4e5e34099d71
--- /dev/null
+++ b/srcpkgs/audacious-plugins/patches/ffmpeg5.patch
@@ -0,0 +1,43 @@
+commit 298aa371c56c2f52c25a33d9bdec4918b11cebdc
+Author: tibequadorian <tibequadorian@posteo.de>
+Date: Sat Mar 19 18:40:12 2022 +0100
+
+ audacious-plugins: rebuild against ffmpeg-5.0
+
+diff --git a/srcpkgs/audacious-plugins/patches/ffmpeg-5.0.patch b/srcpkgs/audacious-plugins/patches/ffmpeg-5.0.patch
+new file mode 100644
+index 0000000000..617c11215b
+--- /dev/null
++++ b/srcpkgs/audacious-plugins/patches/ffmpeg-5.0.patch
+@@ -0,0 +1,31 @@
++From f60beb400eeb1e4778bbfd738bc4a4ccef3de539 Mon Sep 17 00:00:00 2001
++From: John Lindgren <john@jlindgren.net>
++Date: Sat, 5 Mar 2022 12:05:34 -0500
++Subject: [PATCH] Fix build with FFmpeg 5.0
++
++---
++ src/ffaudio/ffaudio-core.cc | 4 ++--
++ 1 file changed, 2 insertions(+), 2 deletions(-)
++
++diff --git a/src/ffaudio/ffaudio-core.cc b/src/ffaudio/ffaudio-core.cc
++index 16dc63e3a..a2b95fd6c 100644
++--- a/src/ffaudio/ffaudio-core.cc
+++++ b/src/ffaudio/ffaudio-core.cc
++@@ -274,7 +274,7 @@ static AVInputFormat * get_format_by_content (const char * name, VFSFile & file)
++ AVProbeData d = {name, buf, filled};
++ score = target;
++
++- f = av_probe_input_format2 (& d, true, & score);
+++ f = (AVInputFormat *) av_probe_input_format2 (& d, true, & score);
++ if (f)
++ break;
++
++@@ -347,7 +347,7 @@ static bool find_codec (AVFormatContext * c, CodecInfo * cinfo)
++ #endif
++ if (stream && stream->codecpar && stream->codecpar->codec_type == AVMEDIA_TYPE_AUDIO)
++ {
++- AVCodec * codec = avcodec_find_decoder (stream->codecpar->codec_id);
+++ AVCodec * codec = (AVCodec *) avcodec_find_decoder (stream->codecpar->codec_id);
++
++ if (codec)
++ {
diff --git a/srcpkgs/audacious-plugins/template b/srcpkgs/audacious-plugins/template
index 88cbc1671fc6..beebfae59ed4 100644
--- a/srcpkgs/audacious-plugins/template
+++ b/srcpkgs/audacious-plugins/template
@@ -2,7 +2,7 @@
#Keep in sync with audacious!
pkgname=audacious-plugins
version=4.3.1
-revision=1
+revision=2
build_style=meson
configure_args="$(vopt_bool gtk3 gtk) $(vopt_bool gtk3)
$(vopt_bool qt) $(vopt_bool qt qt6)"
From 2de41f17ef3610d78b034c06ef41d5eb499f065b Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:45 -0400
Subject: [PATCH 019/110] audacity: revbump for ffmpeg4-4.4.3
---
srcpkgs/audacity/template | 5 ++---
1 file changed, 2 insertions(+), 3 deletions(-)
diff --git a/srcpkgs/audacity/template b/srcpkgs/audacity/template
index d509c0a89407..11e20255685b 100644
--- a/srcpkgs/audacity/template
+++ b/srcpkgs/audacity/template
@@ -1,7 +1,7 @@
# Template file for 'audacity'
pkgname=audacity
version=2.4.1
-revision=2
+revision=3
build_style=gnu-configure
configure_args="--with-ffmpeg=system --with-libsndfile=system --with-expat=system
--with-libsoxr=system --with-lame=system --with-lv2=system ac_cv_path_WX_CONFIG=wx-config-gtk3"
@@ -9,7 +9,7 @@ hostmakedepends="pkg-config cmake gettext libtool m4 which"
makedepends="jack-devel wxWidgets-gtk3-devel gtk+3-devel
libmad-devel soundtouch-devel libsoxr-devel
vamp-plugin-sdk-devel lame-devel libid3tag-devel libflac-devel
- ffmpeg-devel twolame-devel serd-devel lv2 lilv-devel suil-devel"
+ ffmpeg4-devel twolame-devel serd-devel lv2 lilv-devel suil-devel"
depends="desktop-file-utils hicolor-icon-theme"
short_desc="Graphical cross-platform audio editor"
maintainer="Orphaned <orphan@voidlinux.org>"
@@ -33,5 +33,4 @@ post_install() {
vcopy plug-ins /usr/share/audacity
rm ${DESTDIR}/usr/share/doc/audacity/LICENSE.txt
- vlicense LICENSE.txt LICENSE
}
From 4c70d1505c1fab3721d7aef479112117de0bb98a Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:45 -0400
Subject: [PATCH 020/110] avidemux: revbump for ffmpeg-6.0
---
srcpkgs/avidemux/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/avidemux/template b/srcpkgs/avidemux/template
index 253a0243e225..557285982d2b 100644
--- a/srcpkgs/avidemux/template
+++ b/srcpkgs/avidemux/template
@@ -1,7 +1,7 @@
# Template file for 'avidemux'
pkgname=avidemux
version=2.8.0
-revision=2
+revision=3
# Can't be compiled for aarch64, arm* or mips*
archs="x86_64* i686*"
hostmakedepends="cmake pkg-config qt5-host-tools qt5-devel tar yasm"
From f722a1bc1a3b9d0dc76fa458d339903524bbfdd7 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:45 -0400
Subject: [PATCH 021/110] baresip: revbump for ffmpeg-6.0
---
srcpkgs/baresip/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/baresip/template b/srcpkgs/baresip/template
index f1bd1817048b..b21e22334316 100644
--- a/srcpkgs/baresip/template
+++ b/srcpkgs/baresip/template
@@ -1,7 +1,7 @@
# Template file for 'baresip'
pkgname=baresip
version=2.10.0
-revision=1
+revision=2
build_style=cmake
hostmakedepends="pkg-config glib-devel"
makedepends="libgsm-devel libpng-devel openssl-devel libsndfile-devel
From 4d4905c17768c254e1b6f47455f873b93e2c286d Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:46 -0400
Subject: [PATCH 022/110] blender: revbump for ffmpeg-6.0
---
.../patches/ffmpeg6-compat-blender.patch | 42 +++++++++++++++++++
srcpkgs/blender/template | 2 +-
2 files changed, 43 insertions(+), 1 deletion(-)
create mode 100644 srcpkgs/blender/patches/ffmpeg6-compat-blender.patch
diff --git a/srcpkgs/blender/patches/ffmpeg6-compat-blender.patch b/srcpkgs/blender/patches/ffmpeg6-compat-blender.patch
new file mode 100644
index 000000000000..d51a9c7710cc
--- /dev/null
+++ b/srcpkgs/blender/patches/ffmpeg6-compat-blender.patch
@@ -0,0 +1,42 @@
+--- a/source/blender/blenkernel/intern/writeffmpeg.c 2022-11-08 13:50:16 UTC
++++ b/source/blender/blenkernel/intern/writeffmpeg.c
+@@ -855,7 +855,7 @@ static AVStream *alloc_video_stream(FFMpegContext *con
+ 255);
+ st->avg_frame_rate = av_inv_q(c->time_base);
+
+- if (codec->capabilities & AV_CODEC_CAP_AUTO_THREADS) {
++ if (codec->capabilities & AV_CODEC_CAP_OTHER_THREADS) {
+ c->thread_count = 0;
+ }
+ else {
+--- a/source/blender/imbuf/intern/anim_movie.c 2022-11-04 00:33:07 UTC
++++ b/source/blender/imbuf/intern/anim_movie.c
+@@ -554,7 +554,7 @@ static int startffmpeg(struct anim *anim)
+ avcodec_parameters_to_context(pCodecCtx, video_stream->codecpar);
+ pCodecCtx->workaround_bugs = FF_BUG_AUTODETECT;
+
+- if (pCodec->capabilities & AV_CODEC_CAP_AUTO_THREADS) {
++ if (pCodec->capabilities & AV_CODEC_CAP_OTHER_THREADS) {
+ pCodecCtx->thread_count = 0;
+ }
+ else {
+--- a/source/blender/imbuf/intern/indexer.c 2022-11-04 00:33:07 UTC
++++ b/source/blender/imbuf/intern/indexer.c
+@@ -559,7 +559,7 @@ static struct proxy_output_ctx *alloc_proxy_output_ffm
+ av_dict_set(&codec_opts, "preset", "veryfast", 0);
+ av_dict_set(&codec_opts, "tune", "fastdecode", 0);
+
+- if (rv->codec->capabilities & AV_CODEC_CAP_AUTO_THREADS) {
++ if (rv->codec->capabilities & AV_CODEC_CAP_OTHER_THREADS) {
+ rv->c->thread_count = 0;
+ }
+ else {
+@@ -872,7 +872,7 @@ static IndexBuildContext *index_ffmpeg_create_context(
+ avcodec_parameters_to_context(context->iCodecCtx, context->iStream->codecpar);
+ context->iCodecCtx->workaround_bugs = FF_BUG_AUTODETECT;
+
+- if (context->iCodec->capabilities & AV_CODEC_CAP_AUTO_THREADS) {
++ if (context->iCodec->capabilities & AV_CODEC_CAP_OTHER_THREADS) {
+ context->iCodecCtx->thread_count = 0;
+ }
+ else {
diff --git a/srcpkgs/blender/template b/srcpkgs/blender/template
index 61b42eb2e51e..d18bc88838ff 100644
--- a/srcpkgs/blender/template
+++ b/srcpkgs/blender/template
@@ -1,7 +1,7 @@
# Template file for 'blender'
pkgname=blender
version=3.4.1
-revision=3
+revision=4
archs="x86_64* ppc64*"
build_style="cmake"
pycompile_dirs="/usr/share/blender/${version%.*}/scripts"
From 80efbfaa9c09e0ab8ce50d09f60bec27539acf5f Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:46 -0400
Subject: [PATCH 023/110] cantata: revbump for ffmpeg-6.0
---
srcpkgs/cantata/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/cantata/template b/srcpkgs/cantata/template
index 4b417d80d5c2..8a90aaa4c07a 100644
--- a/srcpkgs/cantata/template
+++ b/srcpkgs/cantata/template
@@ -1,7 +1,7 @@
# Template file for 'cantata'
pkgname=cantata
version=2.5.0
-revision=1
+revision=2
build_style=cmake
hostmakedepends="pkg-config qt5-qmake qt5-host-tools qt5-tools"
makedepends="qt5-devel qt5-tools-devel qt5-svg-devel qt5-xmlpatterns-devel
From d52d2a9e99aa813b4a8865c9aeb501ce769bde7f Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:46 -0400
Subject: [PATCH 024/110] ccextractor: revbump for ffmpeg4-4.4.3
---
srcpkgs/ccextractor/template | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/srcpkgs/ccextractor/template b/srcpkgs/ccextractor/template
index 9abcd82852b2..6eccad5885af 100644
--- a/srcpkgs/ccextractor/template
+++ b/srcpkgs/ccextractor/template
@@ -1,12 +1,12 @@
# Template file for 'ccextractor'
pkgname=ccextractor
version=0.93
-revision=1
+revision=2
build_wrksrc="linux"
build_style=gnu-configure
configure_args="--enable-ocr --enable-hardsubx"
hostmakedepends="automake pkg-config"
-makedepends="leptonica-devel tesseract-ocr-devel ffmpeg-devel"
+makedepends="leptonica-devel tesseract-ocr-devel ffmpeg4-devel"
short_desc="Extract subtitles from video streams"
maintainer="newbluemoon <blaumolch@mailbox.org>"
license="GPL-2.0-or-later"
From c854753841086ce7b6dbc25e59c9d25c88300800 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:46 -0400
Subject: [PATCH 025/110] chromaprint: revbump for ffmpeg-6.0
---
srcpkgs/chromaprint/patches/ffmpeg5.patch | 569 ++++++++++++++++++++++
srcpkgs/chromaprint/template | 2 +-
2 files changed, 570 insertions(+), 1 deletion(-)
create mode 100644 srcpkgs/chromaprint/patches/ffmpeg5.patch
diff --git a/srcpkgs/chromaprint/patches/ffmpeg5.patch b/srcpkgs/chromaprint/patches/ffmpeg5.patch
new file mode 100644
index 000000000000..a9fd307a23c8
--- /dev/null
+++ b/srcpkgs/chromaprint/patches/ffmpeg5.patch
@@ -0,0 +1,569 @@
+From 8ccad6937177b1b92e40ab8f4447ea27bac009a7 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Luk=C3=A1=C5=A1=20Lalinsk=C3=BD?= <lalinsky@gmail.com>
+Date: Fri, 4 Nov 2022 21:47:38 +0100
+Subject: [PATCH] Use FFmpeg 5.x (#120)
+
+* Use FFmpeg 5.1.2 for CI builds
+
+* Build on Ubuntu 20.04
+
+* Upgrade code to FFmpeg 5.x APIs
+
+* Only set FFmpeg include dirs if building tools
+
+* No longer needed
+
+* Use ubuntu 20.04
+---
+ .github/workflows/build.yml | 6 +-
+ CMakeLists.txt | 16 --
+ package/build.sh | 4 +-
+ src/audio/ffmpeg_audio_processor.h | 2 -
+ src/audio/ffmpeg_audio_processor_avresample.h | 72 -------
+ src/audio/ffmpeg_audio_processor_swresample.h | 18 +-
+ src/audio/ffmpeg_audio_reader.h | 197 +++++++++---------
+ tests/CMakeLists.txt | 6 +
+ 8 files changed, 122 insertions(+), 199 deletions(-)
+ delete mode 100644 src/audio/ffmpeg_audio_processor_avresample.h
+
+diff --git a/CMakeLists.txt b/CMakeLists.txt
+index f8d6a32..4da2405 100644
+--- a/CMakeLists.txt
++++ b/CMakeLists.txt
+@@ -84,9 +84,6 @@ find_package(FFmpeg)
+ if(FFMPEG_LIBRARIES)
+ cmake_push_check_state(RESET)
+ set(CMAKE_REQUIRED_LIBRARIES ${FFMPEG_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT} -lm)
+- check_function_exists(av_packet_unref HAVE_AV_PACKET_UNREF)
+- check_function_exists(av_frame_alloc HAVE_AV_FRAME_ALLOC)
+- check_function_exists(av_frame_free HAVE_AV_FRAME_FREE)
+ cmake_pop_check_state()
+ endif()
+
+@@ -163,14 +160,11 @@ message(STATUS "Using ${FFT_LIB} for FFT calculations")
+ if(NOT AUDIO_PROCESSOR_LIB)
+ if(FFMPEG_LIBSWRESAMPLE_FOUND)
+ set(AUDIO_PROCESSOR_LIB "swresample")
+- elseif(FFMPEG_LIBAVRESAMPLE_FOUND)
+- set(AUDIO_PROCESSOR_LIB "avresample")
+ endif()
+ endif()
+
+ if(AUDIO_PROCESSOR_LIB STREQUAL "swresample")
+ if(FFMPEG_LIBSWRESAMPLE_FOUND)
+- set(USE_AVRESAMPLE OFF)
+ set(USE_SWRESAMPLE ON)
+ set(AUDIO_PROCESSOR_LIBRARIES ${FFMPEG_LIBSWRESAMPLE_LIBRARIES})
+ set(AUDIO_PROCESSOR_INCLUDE_DIRS ${FFMPEG_LIBSWRESAMPLE_INCLUDE_DIRS})
+@@ -178,16 +172,6 @@ if(AUDIO_PROCESSOR_LIB STREQUAL "swresample")
+ message(FATAL_ERROR "Selected ${AUDIO_PROCESSOR_LIB} for audio processing, but the library is not found")
+ endif()
+ message(STATUS "Using ${AUDIO_PROCESSOR_LIB} for audio conversion")
+-elseif(AUDIO_PROCESSOR_LIB STREQUAL "avresample")
+- if(FFMPEG_LIBAVRESAMPLE_FOUND)
+- set(USE_AVRESAMPLE ON)
+- set(USE_SWRESAMPLE OFF)
+- set(AUDIO_PROCESSOR_LIBRARIES ${FFMPEG_LIBAVRESAMPLE_LIBRARIES})
+- set(AUDIO_PROCESSOR_INCLUDE_DIRS ${FFMPEG_LIBAVRESAMPLE_INCLUDE_DIRS})
+- else()
+- message(FATAL_ERROR "Selected ${AUDIO_PROCESSOR_LIB} for audio processing, but the library is not found")
+- endif()
+- message(STATUS "Using ${AUDIO_PROCESSOR_LIB} for audio conversion")
+ else()
+ message(STATUS "Building without audio conversion support, please install FFmpeg with libswresample")
+ endif()
+diff --git a/package/build.sh b/package/build.sh
+index da631ae..b41d36e 100755
+--- a/package/build.sh
++++ b/package/build.sh
+@@ -7,8 +7,8 @@ set -eux
+
+ BASE_DIR=$(cd $(dirname $0)/.. && pwd)
+
+-FFMPEG_VERSION=4.4.1
+-FFMPEG_BUILD_TAG=v4.4.1-1
++FFMPEG_VERSION=5.1.2
++FFMPEG_BUILD_TAG=v${FFMPEG_VERSION}-1
+
+ TMP_BUILD_DIR=$BASE_DIR/$(mktemp -d build.XXXXXXXX)
+ trap 'rm -rf $TMP_BUILD_DIR' EXIT
+diff --git a/src/audio/ffmpeg_audio_processor.h b/src/audio/ffmpeg_audio_processor.h
+index 7628fc7..39f4f6d 100644
+--- a/src/audio/ffmpeg_audio_processor.h
++++ b/src/audio/ffmpeg_audio_processor.h
+@@ -10,8 +10,6 @@
+
+ #if defined(USE_SWRESAMPLE)
+ #include "audio/ffmpeg_audio_processor_swresample.h"
+-#elif defined(USE_AVRESAMPLE)
+-#include "audio/ffmpeg_audio_processor_avresample.h"
+ #else
+ #error "no audio processing library"
+ #endif
+diff --git a/src/audio/ffmpeg_audio_processor_avresample.h b/src/audio/ffmpeg_audio_processor_avresample.h
+deleted file mode 100644
+index bd85f92..0000000
+--- a/src/audio/ffmpeg_audio_processor_avresample.h
++++ /dev/null
+@@ -1,72 +0,0 @@
+-// Copyright (C) 2016 Lukas Lalinsky
+-// Distributed under the MIT license, see the LICENSE file for details.
+-
+-#ifndef CHROMAPRINT_AUDIO_FFMPEG_AUDIO_PROCESSOR_AVRESAMPLE_H_
+-#define CHROMAPRINT_AUDIO_FFMPEG_AUDIO_PROCESSOR_AVRESAMPLE_H_
+-
+-extern "C" {
+-#include <libavresample/avresample.h>
+-}
+-
+-namespace chromaprint {
+-
+-class FFmpegAudioProcessor {
+-public:
+- FFmpegAudioProcessor() {
+- m_resample_ctx = avresample_alloc_context();
+- }
+-
+- ~FFmpegAudioProcessor() {
+- avresample_free(&m_resample_ctx);
+- }
+-
+- void SetCompatibleMode() {
+- av_opt_set_int(m_resample_ctx, "filter_size", 16, 0);
+- av_opt_set_int(m_resample_ctx, "phase_shift", 8, 0);
+- av_opt_set_int(m_resample_ctx, "linear_interp", 1, 0);
+- av_opt_set_double(m_resample_ctx, "cutoff", 0.8, 0);
+- }
+-
+- void SetInputChannelLayout(int64_t channel_layout) {
+- av_opt_set_int(m_resample_ctx, "in_channel_layout", channel_layout, 0);
+- }
+-
+- void SetInputSampleFormat(AVSampleFormat sample_format) {
+- av_opt_set_int(m_resample_ctx, "in_sample_fmt", sample_format, 0);
+- }
+-
+- void SetInputSampleRate(int sample_rate) {
+- av_opt_set_int(m_resample_ctx, "in_sample_rate", sample_rate, 0);
+- }
+-
+- void SetOutputChannelLayout(int64_t channel_layout) {
+- av_opt_set_int(m_resample_ctx, "out_channel_layout", channel_layout, 0);
+- }
+-
+- void SetOutputSampleFormat(AVSampleFormat sample_format) {
+- av_opt_set_int(m_resample_ctx, "out_sample_fmt", sample_format, 0);
+- }
+-
+- void SetOutputSampleRate(int sample_rate) {
+- av_opt_set_int(m_resample_ctx, "out_sample_fmt", sample_rate, 0);
+- }
+-
+- int Init() {
+- return avresample_open(m_resample_ctx);
+- }
+-
+- int Convert(uint8_t **out, int out_count, const uint8_t **in, int in_count) {
+- return avresample_convert(m_resample_ctx, out, 0, out_count, (uint8_t **) in, 0, in_count);
+- }
+-
+- int Flush(uint8_t **out, int out_count) {
+- return avresample_read(m_resample_ctx, out, out_count);
+- }
+-
+-private:
+- AVAudioResampleContext *m_resample_ctx = nullptr;
+-};
+-
+-}; // namespace chromaprint
+-
+-#endif
+diff --git a/src/audio/ffmpeg_audio_processor_swresample.h b/src/audio/ffmpeg_audio_processor_swresample.h
+index b86266b..b1d4bea 100644
+--- a/src/audio/ffmpeg_audio_processor_swresample.h
++++ b/src/audio/ffmpeg_audio_processor_swresample.h
+@@ -28,30 +28,28 @@ public:
+ av_opt_set_double(m_swr_ctx, "cutoff", 0.8, 0);
+ }
+
+- void SetInputChannelLayout(int64_t channel_layout) {
+- av_opt_set_int(m_swr_ctx, "icl", channel_layout, 0);
+- av_opt_set_int(m_swr_ctx, "ich", av_get_channel_layout_nb_channels(channel_layout), 0);
++ void SetInputChannelLayout(AVChannelLayout *channel_layout) {
++ av_opt_set_int(m_swr_ctx, "in_channel_layout", channel_layout->u.mask, 0);
+ }
+
+ void SetInputSampleFormat(AVSampleFormat sample_format) {
+- av_opt_set_int(m_swr_ctx, "isf", sample_format, 0);
++ av_opt_set_sample_fmt(m_swr_ctx, "in_sample_fmt", sample_format, 0);
+ }
+
+ void SetInputSampleRate(int sample_rate) {
+- av_opt_set_int(m_swr_ctx, "isr", sample_rate, 0);
++ av_opt_set_int(m_swr_ctx, "in_sample_rate", sample_rate, 0);
+ }
+
+- void SetOutputChannelLayout(int64_t channel_layout) {
+- av_opt_set_int(m_swr_ctx, "ocl", channel_layout, 0);
+- av_opt_set_int(m_swr_ctx, "och", av_get_channel_layout_nb_channels(channel_layout), 0);
++ void SetOutputChannelLayout(AVChannelLayout *channel_layout) {
++ av_opt_set_int(m_swr_ctx, "out_channel_layout", channel_layout->u.mask, 0);
+ }
+
+ void SetOutputSampleFormat(AVSampleFormat sample_format) {
+- av_opt_set_int(m_swr_ctx, "osf", sample_format, 0);
++ av_opt_set_sample_fmt(m_swr_ctx, "out_sample_fmt", sample_format, 0);
+ }
+
+ void SetOutputSampleRate(int sample_rate) {
+- av_opt_set_int(m_swr_ctx, "osr", sample_rate, 0);
++ av_opt_set_int(m_swr_ctx, "out_sample_rate", sample_rate, 0);
+ }
+
+ int Init() {
+diff --git a/src/audio/ffmpeg_audio_reader.h b/src/audio/ffmpeg_audio_reader.h
+index 5550164..1c6b346 100644
+--- a/src/audio/ffmpeg_audio_reader.h
++++ b/src/audio/ffmpeg_audio_reader.h
+@@ -62,7 +62,7 @@ public:
+ bool Read(const int16_t **data, size_t *size);
+
+ bool IsOpen() const { return m_opened; }
+- bool IsFinished() const { return m_finished && !m_got_frame; }
++ bool IsFinished() const { return !m_has_more_packets && !m_has_more_frames; }
+
+ std::string GetError() const { return m_error; }
+ int GetErrorCode() const { return m_error_code; }
+@@ -74,20 +74,19 @@ private:
+ uint8_t *m_convert_buffer[1] = { nullptr };
+ int m_convert_buffer_nb_samples = 0;
+
+- AVInputFormat *m_input_fmt = nullptr;
++ const AVInputFormat *m_input_fmt = nullptr;
+ AVDictionary *m_input_opts = nullptr;
+
+ AVFormatContext *m_format_ctx = nullptr;
+ AVCodecContext *m_codec_ctx = nullptr;
+- AVFrame *m_frame = nullptr;
+ int m_stream_index = -1;
+ std::string m_error;
+ int m_error_code = 0;
+- bool m_finished = false;
+ bool m_opened = false;
+- int m_got_frame = 0;
+- AVPacket m_packet;
+- AVPacket m_packet0;
++ bool m_has_more_packets = true;
++ bool m_has_more_frames = true;
++ AVPacket *m_packet = nullptr;
++ AVFrame *m_frame = nullptr;
+
+ int m_output_sample_rate = 0;
+ int m_output_channels = 0;
+@@ -98,19 +97,12 @@ private:
+
+ inline FFmpegAudioReader::FFmpegAudioReader() {
+ av_log_set_level(AV_LOG_QUIET);
+-
+- av_init_packet(&m_packet);
+- m_packet.data = nullptr;
+- m_packet.size = 0;
+-
+- m_packet0 = m_packet;
+ }
+
+ inline FFmpegAudioReader::~FFmpegAudioReader() {
+ Close();
+ av_dict_free(&m_input_opts);
+ av_freep(&m_convert_buffer[0]);
+- av_packet_unref(&m_packet0);
+ }
+
+ inline bool FFmpegAudioReader::SetInputFormat(const char *name) {
+@@ -135,11 +127,10 @@ inline bool FFmpegAudioReader::Open(const std::string &file_name) {
+
+ Close();
+
+- av_init_packet(&m_packet);
+- m_packet.data = nullptr;
+- m_packet.size = 0;
+-
+- m_packet0 = m_packet;
++ m_packet = av_packet_alloc();
++ if (!m_packet) {
++ return false;
++ }
+
+ ret = avformat_open_input(&m_format_ctx, file_name.c_str(), m_input_fmt, &m_input_opts);
+ if (ret < 0) {
+@@ -153,26 +144,31 @@ inline bool FFmpegAudioReader::Open(const std::string &file_name) {
+ return false;
+ }
+
+- AVCodec *codec;
++ const AVCodec *codec;
+ ret = av_find_best_stream(m_format_ctx, AVMEDIA_TYPE_AUDIO, -1, -1, &codec, 0);
+ if (ret < 0) {
+ SetError("Could not find any audio stream in the file", ret);
+ return false;
+ }
+ m_stream_index = ret;
++ auto stream = m_format_ctx->streams[m_stream_index];
+
+- m_codec_ctx = m_format_ctx->streams[m_stream_index]->codec;
++ m_codec_ctx = avcodec_alloc_context3(codec);
+ m_codec_ctx->request_sample_fmt = AV_SAMPLE_FMT_S16;
+
++ ret = avcodec_parameters_to_context(m_codec_ctx, stream->codecpar);
++ if (ret < 0) {
++ SetError("Could not copy the stream parameters", ret);
++ return false;
++ }
++
+ ret = avcodec_open2(m_codec_ctx, codec, nullptr);
+ if (ret < 0) {
+ SetError("Could not open the codec", ret);
+ return false;
+ }
+
+- if (!m_codec_ctx->channel_layout) {
+- m_codec_ctx->channel_layout = av_get_default_channel_layout(m_codec_ctx->channels);
+- }
++ av_dump_format(m_format_ctx, 0, "foo", 0);
+
+ m_frame = av_frame_alloc();
+ if (!m_frame) {
+@@ -183,19 +179,23 @@ inline bool FFmpegAudioReader::Open(const std::string &file_name) {
+ m_output_sample_rate = m_codec_ctx->sample_rate;
+ }
+
+- if (!m_output_channels) {
+- m_output_channels = m_codec_ctx->channels;
++ AVChannelLayout output_channel_layout;
++ if (m_output_channels) {
++ av_channel_layout_default(&output_channel_layout, m_output_channels);
++ } else {
++ m_output_channels = m_codec_ctx->ch_layout.nb_channels;
++ av_channel_layout_default(&output_channel_layout, m_output_channels);
+ }
+
+- if (m_codec_ctx->sample_fmt != AV_SAMPLE_FMT_S16 || m_codec_ctx->channels != m_output_channels || m_codec_ctx->sample_rate != m_output_sample_rate) {
++ if (m_codec_ctx->sample_fmt != AV_SAMPLE_FMT_S16 || m_codec_ctx->ch_layout.nb_channels != m_output_channels || m_codec_ctx->sample_rate != m_output_sample_rate) {
+ m_converter.reset(new FFmpegAudioProcessor());
+ m_converter->SetCompatibleMode();
+ m_converter->SetInputSampleFormat(m_codec_ctx->sample_fmt);
+ m_converter->SetInputSampleRate(m_codec_ctx->sample_rate);
+- m_converter->SetInputChannelLayout(m_codec_ctx->channel_layout);
++ m_converter->SetInputChannelLayout(&(m_codec_ctx->ch_layout));
+ m_converter->SetOutputSampleFormat(AV_SAMPLE_FMT_S16);
+ m_converter->SetOutputSampleRate(m_output_sample_rate);
+- m_converter->SetOutputChannelLayout(av_get_default_channel_layout(m_output_channels));
++ m_converter->SetOutputChannelLayout(&output_channel_layout);
+ auto ret = m_converter->Init();
+ if (ret != 0) {
+ SetError("Could not create an audio converter instance", ret);
+@@ -203,10 +203,11 @@ inline bool FFmpegAudioReader::Open(const std::string &file_name) {
+ }
+ }
+
++ av_channel_layout_uninit(&output_channel_layout);
++
+ m_opened = true;
+- m_finished = false;
+- m_got_frame = 0;
+- m_nb_packets = 0;
++ m_has_more_packets = true;
++ m_has_more_frames = true;
+ m_decode_error = 0;
+
+ return true;
+@@ -214,6 +215,7 @@ inline bool FFmpegAudioReader::Open(const std::string &file_name) {
+
+ inline void FFmpegAudioReader::Close() {
+ av_frame_free(&m_frame);
++ av_packet_free(&m_packet);
+
+ m_stream_index = -1;
+
+@@ -252,91 +254,98 @@ inline bool FFmpegAudioReader::Read(const int16_t **data, size_t *size) {
+ return false;
+ }
+
++ *data = nullptr;
++ *size = 0;
++
+ int ret;
++ bool needs_packet = false;
+ while (true) {
+- while (m_packet.size <= 0) {
+- av_packet_unref(&m_packet0);
+- av_init_packet(&m_packet);
+- m_packet.data = nullptr;
+- m_packet.size = 0;
+- ret = av_read_frame(m_format_ctx, &m_packet);
++ while (needs_packet && m_packet->size == 0) {
++ ret = av_read_frame(m_format_ctx, m_packet);
+ if (ret < 0) {
+ if (ret == AVERROR_EOF) {
+- m_finished = true;
++ needs_packet = false;
++ m_has_more_packets = false;
+ break;
+- } else {
++ }
++ SetError("Error reading from the audio source", ret);
++ return false;
++ }
++ if (m_packet->stream_index == m_stream_index) {
++ needs_packet = false;
++ } else {
++ av_packet_unref(m_packet);
++ }
++ }
++
++ if (m_packet->size != 0) {
++ ret = avcodec_send_packet(m_codec_ctx, m_packet);
++ if (ret < 0) {
++ if (ret != AVERROR(EAGAIN)) {
+ SetError("Error reading from the audio source", ret);
+ return false;
+ }
+- }
+- m_packet0 = m_packet;
+- if (m_packet.stream_index != m_stream_index) {
+- m_packet.data = nullptr;
+- m_packet.size = 0;
+ } else {
+- m_nb_packets++;
++ av_packet_unref(m_packet);
+ }
+ }
+
+- ret = avcodec_decode_audio4(m_codec_ctx, m_frame, &m_got_frame, &m_packet);
++ ret = avcodec_receive_frame(m_codec_ctx, m_frame);
+ if (ret < 0) {
+- if (m_decode_error) {
+- SetError("Error decoding audio frame", m_decode_error);
+- return false;
++ if (ret == AVERROR_EOF) {
++ m_has_more_frames = false;
++ } else if (ret == AVERROR(EAGAIN)) {
++ if (m_has_more_packets) {
++ needs_packet = true;
++ continue;
++ } else {
++ m_has_more_frames = false;
++ }
+ }
+- m_decode_error = ret;
+- m_packet.data = nullptr;
+- m_packet.size = 0;
+- continue;
++ SetError("Error decoding the audio source", ret);
++ return false;
+ }
+
+- break;
+- }
+-
+- m_decode_error = 0;
+-
+- const int decoded = std::min(ret, m_packet.size);
+- m_packet.data += decoded;
+- m_packet.size -= decoded;
+-
+- if (m_got_frame) {
+- if (m_converter) {
+- if (m_frame->nb_samples > m_convert_buffer_nb_samples) {
+- int linsize;
+- av_freep(&m_convert_buffer[0]);
+- m_convert_buffer_nb_samples = std::max(1024 * 8, m_frame->nb_samples);
+- ret = av_samples_alloc(m_convert_buffer, &linsize, m_codec_ctx->channels, m_convert_buffer_nb_samples, AV_SAMPLE_FMT_S16, 1);
+- if (ret < 0) {
+- SetError("Couldn't allocate audio converter buffer", ret);
++ if (m_frame->nb_samples > 0) {
++ if (m_converter) {
++ if (m_frame->nb_samples > m_convert_buffer_nb_samples) {
++ int linsize;
++ av_freep(&m_convert_buffer[0]);
++ m_convert_buffer_nb_samples = std::max(1024 * 8, m_frame->nb_samples);
++ ret = av_samples_alloc(m_convert_buffer, &linsize, m_codec_ctx->ch_layout.nb_channels, m_convert_buffer_nb_samples, AV_SAMPLE_FMT_S16, 1);
++ if (ret < 0) {
++ SetError("Couldn't allocate audio converter buffer", ret);
++ return false;
++ }
++ }
++ auto nb_samples = m_converter->Convert(m_convert_buffer, m_convert_buffer_nb_samples, (const uint8_t **) m_frame->data, m_frame->nb_samples);
++ if (nb_samples < 0) {
++ SetError("Couldn't convert audio", ret);
+ return false;
+ }
+- }
+- auto nb_samples = m_converter->Convert(m_convert_buffer, m_convert_buffer_nb_samples, (const uint8_t **) m_frame->data, m_frame->nb_samples);
+- if (nb_samples < 0) {
+- SetError("Couldn't convert audio", ret);
+- return false;
+- }
+- *data = (const int16_t *) m_convert_buffer[0];
+- *size = nb_samples;
+- } else {
+- *data = (const int16_t *) m_frame->data[0];
+- *size = m_frame->nb_samples;
+- }
+- } else {
+- if (m_finished && m_converter) {
+- auto nb_samples = m_converter->Flush(m_convert_buffer, m_convert_buffer_nb_samples);
+- if (nb_samples < 0) {
+- SetError("Couldn't convert audio", ret);
+- return false;
+- } else if (nb_samples > 0) {
+- m_got_frame = 1;
+ *data = (const int16_t *) m_convert_buffer[0];
+ *size = nb_samples;
++ } else {
++ *data = (const int16_t *) m_frame->data[0];
++ *size = m_frame->nb_samples;
++ }
++ } else {
++ if (m_converter) {
++ if (IsFinished()) {
++ auto nb_samples = m_converter->Flush(m_convert_buffer, m_convert_buffer_nb_samples);
++ if (nb_samples < 0) {
++ SetError("Couldn't convert audio", ret);
++ return false;
++ } else if (nb_samples > 0) {
++ *data = (const int16_t *) m_convert_buffer[0];
++ *size = nb_samples;
++ }
++ }
+ }
+ }
+- }
+
+- return true;
++ return true;
++ }
+ }
+
+ inline void FFmpegAudioReader::SetError(const char *message, int errnum) {
+diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt
+index a2b517b..123e643 100644
+--- a/tests/CMakeLists.txt
++++ b/tests/CMakeLists.txt
+@@ -38,6 +38,12 @@ set(SRCS
+
+ if(BUILD_TOOLS)
+ set(SRCS ${SRCS} ../src/audio/ffmpeg_audio_reader_test.cpp)
++ include_directories(
++ ${FFMPEG_LIBAVFORMAT_INCLUDE_DIRS}
++ ${FFMPEG_LIBAVCODEC_INCLUDE_DIRS}
++ ${FFMPEG_LIBAVUTIL_INCLUDE_DIRS}
++ ${AUDIO_PROCESSOR_INCLUDE_DIRS}
++ )
+ link_libraries(fpcalc_libs)
+ endif()
+
+--
+2.38.1
+
+
diff --git a/srcpkgs/chromaprint/template b/srcpkgs/chromaprint/template
index 7ef7838949f3..1f7bbc70a22c 100644
--- a/srcpkgs/chromaprint/template
+++ b/srcpkgs/chromaprint/template
@@ -1,7 +1,7 @@
# Template file for 'chromaprint'
pkgname=chromaprint
version=1.5.1
-revision=1
+revision=2
build_style=cmake
configure_args="-DBUILD_TOOLS=ON"
make_check_target="check"
From 4eff70ebc68cdc5f320b0f69c6ab405e658fd543 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:46 -0400
Subject: [PATCH 026/110] chromium: revbump for ffmpeg-6.0
---
.../patches/chromium-93-ffmpeg-4.4.patch | 36 --------------
srcpkgs/chromium/patches/ffmpeg5.patch | 47 +++++++++++++++++++
srcpkgs/chromium/template | 2 +-
3 files changed, 48 insertions(+), 37 deletions(-)
delete mode 100644 srcpkgs/chromium/patches/chromium-93-ffmpeg-4.4.patch
create mode 100644 srcpkgs/chromium/patches/ffmpeg5.patch
diff --git a/srcpkgs/chromium/patches/chromium-93-ffmpeg-4.4.patch b/srcpkgs/chromium/patches/chromium-93-ffmpeg-4.4.patch
deleted file mode 100644
index f0ec736f98bc..000000000000
--- a/srcpkgs/chromium/patches/chromium-93-ffmpeg-4.4.patch
+++ /dev/null
@@ -1,36 +0,0 @@
-diff --git a/media/filters/ffmpeg_demuxer.cc b/media/filters/ffmpeg_demuxer.cc
-index ac4713b07268..492a9a37d096 100644
---- a/media/filters/ffmpeg_demuxer.cc
-+++ b/media/filters/ffmpeg_demuxer.cc
-@@ -427,11 +427,11 @@ void FFmpegDemuxerStream::EnqueuePacket(ScopedAVPacket packet) {
- scoped_refptr<DecoderBuffer> buffer;
-
- if (type() == DemuxerStream::TEXT) {
-- size_t id_size = 0;
-+ int id_size = 0;
- uint8_t* id_data = av_packet_get_side_data(
- packet.get(), AV_PKT_DATA_WEBVTT_IDENTIFIER, &id_size);
-
-- size_t settings_size = 0;
-+ int settings_size = 0;
- uint8_t* settings_data = av_packet_get_side_data(
- packet.get(), AV_PKT_DATA_WEBVTT_SETTINGS, &settings_size);
-
-@@ -443,7 +443,7 @@ void FFmpegDemuxerStream::EnqueuePacket(ScopedAVPacket packet) {
- buffer = DecoderBuffer::CopyFrom(packet->data, packet->size,
- side_data.data(), side_data.size());
- } else {
-- size_t side_data_size = 0;
-+ int side_data_size = 0;
- uint8_t* side_data = av_packet_get_side_data(
- packet.get(), AV_PKT_DATA_MATROSKA_BLOCKADDITIONAL, &side_data_size);
-
-@@ -504,7 +504,7 @@ void FFmpegDemuxerStream::EnqueuePacket(ScopedAVPacket packet) {
- packet->size - data_offset);
- }
-
-- size_t skip_samples_size = 0;
-+ int skip_samples_size = 0;
- const uint32_t* skip_samples_ptr =
- reinterpret_cast<const uint32_t*>(av_packet_get_side_data(
- packet.get(), AV_PKT_DATA_SKIP_SAMPLES, &skip_samples_size));
diff --git a/srcpkgs/chromium/patches/ffmpeg5.patch b/srcpkgs/chromium/patches/ffmpeg5.patch
new file mode 100644
index 000000000000..24e2da38e34c
--- /dev/null
+++ b/srcpkgs/chromium/patches/ffmpeg5.patch
@@ -0,0 +1,47 @@
+--- a/media/filters/ffmpeg_demuxer.cc 2023-01-23 17:33:57.366213805 +0200
++++ b/media/filters/ffmpeg_demuxer.cc 2023-01-23 17:43:09.283436983 +0200
+@@ -92,24 +92,12 @@
+
+ static base::TimeDelta ExtractStartTime(AVStream* stream) {
+ // The default start time is zero.
+- base::TimeDelta start_time;
++ base::TimeDelta start_time = kNoTimestamp;
+
+ // First try to use the |start_time| value as is.
+- if (stream->start_time != kNoFFmpegTimestamp)
++ if (stream->start_time != kNoFFmpegTimestamp) // AV_NOPTS_VALUE
+ start_time = ConvertFromTimeBase(stream->time_base, stream->start_time);
+
+- // Next try to use the first DTS value, for codecs where we know PTS == DTS
+- // (excludes all H26x codecs). The start time must be returned in PTS.
+- if (av_stream_get_first_dts(stream) != kNoFFmpegTimestamp &&
+- stream->codecpar->codec_id != AV_CODEC_ID_HEVC &&
+- stream->codecpar->codec_id != AV_CODEC_ID_H264 &&
+- stream->codecpar->codec_id != AV_CODEC_ID_MPEG4) {
+- const base::TimeDelta first_pts =
+- ConvertFromTimeBase(stream->time_base, av_stream_get_first_dts(stream));
+- if (first_pts < start_time)
+- start_time = first_pts;
+- }
+-
+ return start_time;
+ }
+
+@@ -1597,7 +1585,7 @@
+ for (const auto& stream : streams_) {
+ if (!stream || stream->IsEnabled() != enabled)
+ continue;
+- if (av_stream_get_first_dts(stream->av_stream()) == kInvalidPTSMarker)
++ if (stream->av_stream()->start_time == AV_NOPTS_VALUE)
+ continue;
+ if (!lowest_start_time_stream ||
+ stream->start_time() < lowest_start_time_stream->start_time()) {
+@@ -1618,7 +1606,7 @@
+ if (stream->type() != DemuxerStream::VIDEO)
+ continue;
+
+- if (av_stream_get_first_dts(stream->av_stream()) == kInvalidPTSMarker)
++ if (stream->av_stream()->start_time == AV_NOPTS_VALUE)
+ continue;
+
+ if (!stream->IsEnabled())
diff --git a/srcpkgs/chromium/template b/srcpkgs/chromium/template
index e50c739d3ee7..8705f2ef973f 100644
--- a/srcpkgs/chromium/template
+++ b/srcpkgs/chromium/template
@@ -2,7 +2,7 @@
pkgname=chromium
# See https://chromiumdash.appspot.com/releases?platform=Linux for the latest version
version=112.0.5615.49
-revision=1
+revision=2
archs="i686* x86_64* aarch64* armv7l*"
hostmakedepends="
$(vopt_if clang "clang lld llvm15")
From b98c175524d808211385f5673fe92684bc829839 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:46 -0400
Subject: [PATCH 027/110] cmus: revbump for ffmpeg-6.0
---
srcpkgs/cmus/patches/ffmpeg6.patch | 12 ++++++++++++
srcpkgs/cmus/template | 2 +-
2 files changed, 13 insertions(+), 1 deletion(-)
create mode 100644 srcpkgs/cmus/patches/ffmpeg6.patch
diff --git a/srcpkgs/cmus/patches/ffmpeg6.patch b/srcpkgs/cmus/patches/ffmpeg6.patch
new file mode 100644
index 000000000000..ffa95ab81110
--- /dev/null
+++ b/srcpkgs/cmus/patches/ffmpeg6.patch
@@ -0,0 +1,12 @@
+--- a/ip/ffmpeg.c
++++ b/ip/ffmpeg.c
+@@ -202,9 +202,6 @@ static int ffmpeg_open(struct input_plugin_data *ip_data)
+ break;
+ }
+
+- if (codec->capabilities & AV_CODEC_CAP_TRUNCATED)
+- cc->flags |= AV_CODEC_FLAG_TRUNCATED;
+-
+ if (avcodec_open2(cc, codec, NULL) < 0) {
+ d_print("could not open codec: %d, %s\n", cc->codec_id, avcodec_get_name(cc->codec_id));
+ err = -IP_ERROR_UNSUPPORTED_FILE_TYPE;
diff --git a/srcpkgs/cmus/template b/srcpkgs/cmus/template
index 0fcb424ce336..05b77d0fecae 100644
--- a/srcpkgs/cmus/template
+++ b/srcpkgs/cmus/template
@@ -1,7 +1,7 @@
# Template file for 'cmus'
pkgname=cmus
version=2.10.0
-revision=1
+revision=2
build_style=configure
configure_args="prefix=/usr LD=$CC"
hostmakedepends="pkg-config"
From 30b63fff37a439263e89febd8d653aa4246a4e7e Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:46 -0400
Subject: [PATCH 028/110] cyanrip: revbump for ffmpeg-6.0
---
srcpkgs/cyanrip/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/cyanrip/template b/srcpkgs/cyanrip/template
index 9796e3461601..5db30e020d17 100644
--- a/srcpkgs/cyanrip/template
+++ b/srcpkgs/cyanrip/template
@@ -1,7 +1,7 @@
# Template file for 'cyanrip'
pkgname=cyanrip
version=0.9.0
-revision=1
+revision=2
build_style=meson
hostmakedepends="pkg-config"
makedepends="ffmpeg-devel libcdio-devel libcdio-paranoia-devel libcurl-devel libmusicbrainz5-devel"
From 902fd691e1a36042aac84f60ff26c3d54d3e7f97 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:46 -0400
Subject: [PATCH 029/110] deadbeef: revbump for ffmpeg4-4.4.3
---
srcpkgs/deadbeef/template | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/srcpkgs/deadbeef/template b/srcpkgs/deadbeef/template
index b664bb1b9bd9..165b3c7b9cad 100644
--- a/srcpkgs/deadbeef/template
+++ b/srcpkgs/deadbeef/template
@@ -1,14 +1,14 @@
# Template file for 'deadbeef'
pkgname=deadbeef
version=1.8.8
-revision=1
+revision=2
create_wrksrc=yes
build_style=gnu-configure
configure_args="--disable-oss --disable-lfm --disable-notify --disable-gtk2"
hostmakedepends="automake libtool gettext gettext-devel intltool pkg-config
yasm clang glib-devel"
makedepends="
- alsa-lib-devel dbus-devel faad2-devel ffmpeg-devel gtk+3-devel imlib2-devel
+ alsa-lib-devel dbus-devel faad2-devel ffmpeg4-devel gtk+3-devel imlib2-devel
jansson-devel libcddb-devel libcdio-devel libcurl-devel libflac-devel
libmad-devel libpng-devel libsamplerate-devel libsndfile-devel libvorbis-devel
libzip-devel mpg123-devel opusfile-devel pulseaudio-devel wavpack-devel"
From 2456a8f4bbce810d6519144f291fd01db94b1d83 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:46 -0400
Subject: [PATCH 030/110] dolphin-emu: revbump for ffmpeg-6.0
---
srcpkgs/dolphin-emu/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/dolphin-emu/template b/srcpkgs/dolphin-emu/template
index 7ea197ceb2a8..7aeb0a5b645e 100644
--- a/srcpkgs/dolphin-emu/template
+++ b/srcpkgs/dolphin-emu/template
@@ -1,7 +1,7 @@
# Template file for 'dolphin-emu'
pkgname=dolphin-emu
version=5.0.16101
-revision=1
+revision=2
_dolphin_commit=8ecfa537a242de74d2e372e30d9d79b14584b2fb
_mgba_commit=40d4c430fc36caeb7ea32fd39624947ed487d2f2
#Version/hash pair can be found at https://dolphin-emu.org/download/
From e68ee8f569ec5211863bcc95fe81d4b3ced82d4c Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:46 -0400
Subject: [PATCH 031/110] droidcam-obs-plugin: revbump for ffmpeg-6.0
---
srcpkgs/droidcam-obs-plugin/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/droidcam-obs-plugin/template b/srcpkgs/droidcam-obs-plugin/template
index fc9c9bf6b9d5..fb0480754df4 100644
--- a/srcpkgs/droidcam-obs-plugin/template
+++ b/srcpkgs/droidcam-obs-plugin/template
@@ -1,7 +1,7 @@
# Template file for 'droidcam-obs-plugin'
pkgname=droidcam-obs-plugin
version=2.0.1
-revision=1
+revision=2
build_style=gnu-makefile
make_use_env=yes
make_build_args="ALLOW_STATIC=no"
From d96079ddd992bdd31dc09731bdb6f17811a9fcf0 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:46 -0400
Subject: [PATCH 032/110] droidcam: revbump for ffmpeg-6.0
---
srcpkgs/droidcam/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/droidcam/template b/srcpkgs/droidcam/template
index 1c3f1b8b1fc6..32a9220b79a4 100644
--- a/srcpkgs/droidcam/template
+++ b/srcpkgs/droidcam/template
@@ -1,7 +1,7 @@
# Template file for 'droidcam'
pkgname=droidcam
version=1.8.2
-revision=2
+revision=3
build_style=gnu-makefile
make_build_args="USBMUXD=-lusbmuxd-2.0 JPEG=-lturbojpeg"
hostmakedepends="pkg-config"
From 6386b9085759bc7afafb8a8a1e68491ed05882eb Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:46 -0400
Subject: [PATCH 033/110] electron19: revbump for ffmpeg-6.0
---
srcpkgs/electron19/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/electron19/template b/srcpkgs/electron19/template
index 068136be7623..32ce301e730c 100644
--- a/srcpkgs/electron19/template
+++ b/srcpkgs/electron19/template
@@ -1,7 +1,7 @@
# Template file for 'electron19'
pkgname=electron19
version=19.0.8
-revision=2
+revision=3
_nodever=16.14.2
_chromiumver=102.0.5005.125
archs="x86_64* aarch64* ppc64le*"
From 45c6aee838ecd1878339d8b45ce441b7cb544ba5 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:47 -0400
Subject: [PATCH 034/110] ffmpegthumbnailer: revbump for ffmpeg-6.0
---
.../ffmpegthumbnailer/patches/ffmpeg6.patch | 202 ++++++++++++++++++
srcpkgs/ffmpegthumbnailer/template | 6 +-
2 files changed, 205 insertions(+), 3 deletions(-)
create mode 100644 srcpkgs/ffmpegthumbnailer/patches/ffmpeg6.patch
diff --git a/srcpkgs/ffmpegthumbnailer/patches/ffmpeg6.patch b/srcpkgs/ffmpegthumbnailer/patches/ffmpeg6.patch
new file mode 100644
index 000000000000..363ff35a2841
--- /dev/null
+++ b/srcpkgs/ffmpegthumbnailer/patches/ffmpeg6.patch
@@ -0,0 +1,202 @@
+--- a/libffmpegthumbnailer/moviedecoder.cpp 2017-11-21 14:06:57.000000000 -0500
++++ b/libffmpegthumbnailer/moviedecoder.cpp 2023-05-05 13:14:47.946560668 -0400
+@@ -41,11 +41,6 @@
+ namespace ffmpegthumbnailer
+ {
+
+-struct SilenceLogLevel
+-{
+- SilenceLogLevel() { av_log_set_level(AV_LOG_QUIET); }
+-};
+-
+ MovieDecoder::MovieDecoder(AVFormatContext* pavContext)
+ : m_VideoStream(-1)
+ , m_pFormatContext(pavContext)
+@@ -70,8 +65,6 @@
+
+ void MovieDecoder::initialize(const string& filename, bool preferEmbeddedMetadata)
+ {
+- av_register_all();
+- avcodec_register_all();
+ avformat_network_init();
+
+ string inputFile = filename == "-" ? "pipe:" : filename;
+@@ -97,8 +90,7 @@
+ {
+ if (m_pVideoCodecContext)
+ {
+- avcodec_close(m_pVideoCodecContext);
+- m_pVideoCodecContext = nullptr;
++ avcodec_free_context(&m_pVideoCodecContext);
+ }
+
+ if ((!m_FormatContextWasGiven) && m_pFormatContext)
+@@ -152,10 +144,10 @@
+ for (unsigned int i = 0; i < m_pFormatContext->nb_streams; ++i)
+ {
+ AVStream *stream = m_pFormatContext->streams[i];
+- auto ctx = m_pFormatContext->streams[i]->codec;
+- if (ctx->codec_type == AVMEDIA_TYPE_VIDEO)
++ auto par = m_pFormatContext->streams[i]->codecpar;
++ if (par->codec_type == AVMEDIA_TYPE_VIDEO)
+ {
+- if (!preferEmbeddedMetadata || !isStillImageCodec(ctx->codec_id))
++ if (!preferEmbeddedMetadata || !isStillImageCodec(par->codec_id))
+ {
+ videoStreams.push_back(i);
+ continue;
+@@ -203,8 +195,7 @@
+ }
+
+ m_pVideoStream = m_pFormatContext->streams[m_VideoStream];
+- m_pVideoCodecContext = m_pVideoStream->codec;
+- m_pVideoCodec = avcodec_find_decoder(m_pVideoCodecContext->codec_id);
++ m_pVideoCodec = avcodec_find_decoder(m_pVideoStream->codecpar->codec_id);
+
+ if (m_pVideoCodec == nullptr)
+ {
+@@ -214,6 +205,20 @@
+ throw logic_error("Video Codec not found");
+ }
+
++ m_pVideoCodecContext = avcodec_alloc_context3(m_pVideoCodec);
++
++ if (m_pVideoCodecContext == nullptr)
++ {
++ destroy();
++ throw logic_error("Could not allocate video codec context");
++ }
++
++ if (avcodec_parameters_to_context(m_pVideoCodecContext, m_pVideoStream->codecpar) < 0)
++ {
++ destroy();
++ throw logic_error("Could not configure video codec context");
++ }
++
+ m_pVideoCodecContext->workaround_bugs = 1;
+
+ if (avcodec_open2(m_pVideoCodecContext, m_pVideoCodec, nullptr) < 0)
+@@ -386,13 +391,6 @@
+
+ void MovieDecoder::initializeFilterGraph(const AVRational& timeBase, const std::string& size, bool maintainAspectRatio)
+ {
+- static const AVPixelFormat pixelFormats[] = { AV_PIX_FMT_RGB24, AV_PIX_FMT_NONE };
+-
+- auto del = [] (AVBufferSinkParams* p) { av_freep(p); };
+- std::unique_ptr<AVBufferSinkParams, decltype(del)> buffersinkParams(av_buffersink_params_alloc(), del);
+-
+- avfilter_register_all();
+-
+ m_pFilterGraph = avfilter_graph_alloc();
+ assert(m_pFilterGraph);
+
+@@ -404,10 +402,8 @@
+
+ checkRc(avfilter_graph_create_filter(&m_pFilterSource, avfilter_get_by_name("buffer"), "thumb_buffer", ss.str().c_str(), nullptr, m_pFilterGraph),
+ "Failed to create filter source");
+- buffersinkParams->pixel_fmts = pixelFormats;
+- checkRc(avfilter_graph_create_filter(&m_pFilterSink, avfilter_get_by_name("buffersink"), "thumb_buffersink", nullptr, buffersinkParams.get(), m_pFilterGraph),
++ checkRc(avfilter_graph_create_filter(&m_pFilterSink, avfilter_get_by_name("buffersink"), "thumb_buffersink", nullptr, nullptr, m_pFilterGraph),
+ "Failed to create filter sink");
+- buffersinkParams.release();
+
+ AVFilterContext* yadifFilter = nullptr;
+ if (m_pFrame->interlaced_frame != 0)
+@@ -500,15 +496,15 @@
+ }
+
+ checkRc(av_seek_frame(m_pFormatContext, -1, timestamp, 0), "Seeking in video failed");
+- avcodec_flush_buffers(m_pFormatContext->streams[m_VideoStream]->codec);
++ avcodec_flush_buffers(m_pVideoCodecContext);
+
+ int keyFrameAttempts = 0;
+- bool gotFrame = 0;
++ bool gotFrame;
+
+ do
+ {
+ int count = 0;
+- gotFrame = 0;
++ gotFrame = false;
+
+ while (!gotFrame && count < 20)
+ {
+@@ -552,17 +548,33 @@
+ return false;
+ }
+
+- av_frame_unref(m_pFrame);
+-
+- int frameFinished;
++ int rc = avcodec_send_packet(m_pVideoCodecContext, m_pPacket);
++ if(rc == AVERROR(EAGAIN))
++ {
++ rc = 0;
++ }
+
+- int bytesDecoded = avcodec_decode_video2(m_pVideoCodecContext, m_pFrame, &frameFinished, m_pPacket);
+- if (bytesDecoded < 0)
++ if(rc == AVERROR_EOF)
++ {
++ return false;
++ }
++ else if(rc < 0)
+ {
+- throw logic_error("Failed to decode video frame: bytesDecoded < 0");
++ throw logic_error("Failed to decode video frame: avcodec_send_packet() < 0");
+ }
+
+- return frameFinished > 0;
++ rc = avcodec_receive_frame(m_pVideoCodecContext, m_pFrame);
++ switch(rc)
++ {
++ case 0:
++ return true;
++
++ case AVERROR(EAGAIN):
++ return false;
++
++ default:
++ throw logic_error("Failed to decode video frame: avcodec_receive_frame() < 0");
++ }
+ }
+
+ bool MovieDecoder::getVideoPacket()
+@@ -570,8 +582,6 @@
+ bool framesAvailable = true;
+ bool frameDecoded = false;
+
+- int attempts = 0;
+-
+ if (m_pPacket)
+ {
+ av_packet_unref(m_pPacket);
+@@ -580,6 +590,7 @@
+
+ m_pPacket = new AVPacket();
+
++
+ while (framesAvailable && !frameDecoded)
+ {
+ framesAvailable = av_read_frame(m_pFormatContext, m_pPacket) >= 0;
+@@ -644,7 +655,7 @@
+
+ int32_t MovieDecoder::getStreamRotation()
+ {
+- int32_t* matrix = reinterpret_cast<int32_t*>(av_stream_get_side_data(m_pVideoStream, AV_PKT_DATA_DISPLAYMATRIX, nullptr));
++ auto matrix = reinterpret_cast<int32_t*>(av_stream_get_side_data(m_pVideoStream, AV_PKT_DATA_DISPLAYMATRIX, nullptr));
+ if (matrix)
+ {
+ auto angle = lround(av_display_rotation_get(matrix));
+
+--- a/libffmpegthumbnailer/moviedecoder.h 2017-11-12 04:23:38.000000000 -0500
++++ b/libffmpegthumbnailer/moviedecoder.h 2023-05-05 13:26:07.095529911 -0400
+@@ -78,7 +78,7 @@
+ int m_VideoStream;
+ AVFormatContext* m_pFormatContext;
+ AVCodecContext* m_pVideoCodecContext;
+- AVCodec* m_pVideoCodec;
++ const AVCodec* m_pVideoCodec;
+ AVFilterGraph* m_pFilterGraph;
+ AVFilterContext* m_pFilterSource;
+ AVFilterContext* m_pFilterSink;
diff --git a/srcpkgs/ffmpegthumbnailer/template b/srcpkgs/ffmpegthumbnailer/template
index 039eea7622b3..35d546018d12 100644
--- a/srcpkgs/ffmpegthumbnailer/template
+++ b/srcpkgs/ffmpegthumbnailer/template
@@ -1,7 +1,7 @@
# Template file for 'ffmpegthumbnailer'
pkgname=ffmpegthumbnailer
version=2.2.2
-revision=1
+revision=2
build_style=cmake
hostmakedepends="pkg-config"
makedepends="libpng-devel libjpeg-turbo-devel ffmpeg-devel"
@@ -9,8 +9,8 @@ depends="ffmpeg"
short_desc="Lightweight video thumbnailer"
maintainer="Orphaned <orphan@voidlinux.org>"
license="GPL-2.0-or-later"
-homepage="https://github.com/dirkvdb/${pkgname}"
-distfiles="${homepage}/releases/download/${version}/${pkgname}-${version}.tar.bz2"
+homepage="https://github.com/dirkvdb"
+distfiles="${homepage}/${pkgname}/releases/download/${version}/${pkgname}-${version}.tar.bz2"
checksum=1cb24059c38223f657b300c84dd80491b7040d4b69471c4fea69be862bc99b5b
post_install() {
From 40e5ac9edaceee097397791f9d15ac0b69689a30 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:47 -0400
Subject: [PATCH 035/110] ffmpegthumbs: revbump for ffmpeg-6.0
---
srcpkgs/ffmpegthumbs/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/ffmpegthumbs/template b/srcpkgs/ffmpegthumbs/template
index 5f0b9414dada..11b88193528f 100644
--- a/srcpkgs/ffmpegthumbs/template
+++ b/srcpkgs/ffmpegthumbs/template
@@ -1,7 +1,7 @@
# Template file for 'ffmpegthumbs'
pkgname=ffmpegthumbs
version=22.12.1
-revision=1
+revision=2
build_style=cmake
hostmakedepends="extra-cmake-modules kcoreaddons kconfig-devel
pkg-config qt5-host-tools qt5-qmake gettext"
From 259d49a7dc220758b5c7f2248766953104edd88b Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:47 -0400
Subject: [PATCH 036/110] ffms2: revbump for ffmpeg-6.0
---
srcpkgs/ffms2/patches/ffmpeg5.patch | 424 ++++++++++++++++++++++++++++
srcpkgs/ffms2/template | 2 +-
2 files changed, 425 insertions(+), 1 deletion(-)
create mode 100644 srcpkgs/ffms2/patches/ffmpeg5.patch
diff --git a/srcpkgs/ffms2/patches/ffmpeg5.patch b/srcpkgs/ffms2/patches/ffmpeg5.patch
new file mode 100644
index 000000000000..1479fabcafcb
--- /dev/null
+++ b/srcpkgs/ffms2/patches/ffmpeg5.patch
@@ -0,0 +1,424 @@
+From 45673149e9a2f5586855ad472e3059084eaa36b1 Mon Sep 17 00:00:00 2001
+From: Derek Buitenhuis <derek.buitenhuis@gmail.com>
+Date: Tue, 4 May 2021 14:41:21 +0100
+Subject: [PATCH] Use auto for AVCodec
+
+The geniuses over at FFmpeg decided to constify this API, so old
+versions of the library will return AVCodec *, while new versions
+of the libary will return const AVCodec *, which, in C++, are not
+OK to convert between.
+
+Rather than use some macro hell in ffmscompat.h, we can work around
+this by using auto.
+
+Gross.
+
+Signed-off-by: Derek Buitenhuis <derek.buitenhuis@gmail.com>
+---
+ src/core/audiosource.cpp | 2 +-
+ src/core/indexing.cpp | 6 +++---
+ src/core/videosource.cpp | 2 +-
+ 3 files changed, 5 insertions(+), 5 deletions(-)
+
+diff --git a/src/core/audiosource.cpp b/src/core/audiosource.cpp
+index e4ce97c..ac09666 100644
+--- a/src/core/audiosource.cpp
++++ b/src/core/audiosource.cpp
+@@ -469,7 +469,7 @@ void FFMS_AudioSource::OpenFile() {
+
+ LAVFOpenFile(SourceFile.c_str(), FormatContext, TrackNumber);
+
+- AVCodec *Codec = avcodec_find_decoder(FormatContext->streams[TrackNumber]->codecpar->codec_id);
++ auto *Codec = avcodec_find_decoder(FormatContext->streams[TrackNumber]->codecpar->codec_id);
+ if (Codec == nullptr)
+ throw FFMS_Exception(FFMS_ERROR_DECODING, FFMS_ERROR_CODEC,
+ "Audio codec not found");
+diff --git a/src/core/indexing.cpp b/src/core/indexing.cpp
+index e547c5a..59fb4e8 100644
+--- a/src/core/indexing.cpp
++++ b/src/core/indexing.cpp
+@@ -384,7 +384,7 @@ FFMS_TrackType FFMS_Indexer::GetTrackType(int Track) {
+ }
+
+ const char *FFMS_Indexer::GetTrackCodec(int Track) {
+- AVCodec *codec = avcodec_find_decoder(FormatContext->streams[Track]->codecpar->codec_id);
++ auto *codec = avcodec_find_decoder(FormatContext->streams[Track]->codecpar->codec_id);
+ return codec ? codec->name : nullptr;
+ }
+
+@@ -402,7 +402,7 @@ FFMS_Index *FFMS_Indexer::DoIndexing() {
+ UseDTS);
+
+ if (IndexMask.count(i) && FormatContext->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
+- AVCodec *VideoCodec = avcodec_find_decoder(FormatContext->streams[i]->codecpar->codec_id);
++ auto *VideoCodec = avcodec_find_decoder(FormatContext->streams[i]->codecpar->codec_id);
+ if (!VideoCodec) {
+ FormatContext->streams[i]->discard = AVDISCARD_ALL;
+ IndexMask.erase(i);
+@@ -433,7 +433,7 @@ FFMS_Index *FFMS_Indexer::DoIndexing() {
+ IndexMask.insert(i);
+ }
+ } else if (IndexMask.count(i) && FormatContext->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) {
+- AVCodec *AudioCodec = avcodec_find_decoder(FormatContext->streams[i]->codecpar->codec_id);
++ auto *AudioCodec = avcodec_find_decoder(FormatContext->streams[i]->codecpar->codec_id);
+ if (AudioCodec == nullptr)
+ throw FFMS_Exception(FFMS_ERROR_CODEC, FFMS_ERROR_UNSUPPORTED,
+ "Audio codec not found");
+diff --git a/src/core/videosource.cpp b/src/core/videosource.cpp
+index b889970..8956c22 100644
+--- a/src/core/videosource.cpp
++++ b/src/core/videosource.cpp
+@@ -171,7 +171,7 @@ FFMS_VideoSource::FFMS_VideoSource(const char *SourceFile, FFMS_Index &Index, in
+
+ LAVFOpenFile(SourceFile, FormatContext, VideoTrack);
+
+- AVCodec *Codec = avcodec_find_decoder(FormatContext->streams[VideoTrack]->codecpar->codec_id);
++ auto *Codec = avcodec_find_decoder(FormatContext->streams[VideoTrack]->codecpar->codec_id);
+ if (Codec == nullptr)
+ throw FFMS_Exception(FFMS_ERROR_DECODING, FFMS_ERROR_CODEC,
+ "Video codec not found");
+--
+2.40.0
+
+From 96cbf38ea9381829a1314f432a2c60495dcefaad Mon Sep 17 00:00:00 2001
+From: Derek Buitenhuis <derek.buitenhuis@gmail.com>
+Date: Tue, 4 May 2021 14:12:41 +0100
+Subject: [PATCH] all: Update AVPacket API usage
+
+AVPackets must all be on the heap now, since it is no longer
+part of the libav* ABI.
+
+Signed-off-by: Derek Buitenhuis <derek.buitenhuis@gmail.com>
+---
+ src/core/audiosource.cpp | 16 ++++++----
+ src/core/indexing.cpp | 63 ++++++++++++++++++++++------------------
+ src/core/indexing.h | 4 +--
+ src/core/utils.cpp | 6 ----
+ src/core/utils.h | 1 -
+ src/core/videosource.cpp | 30 ++++++++++---------
+ 6 files changed, 64 insertions(+), 56 deletions(-)
+
+diff --git a/src/core/audiosource.cpp b/src/core/audiosource.cpp
+index 37cf9ae..e4ce97c 100644
+--- a/src/core/audiosource.cpp
++++ b/src/core/audiosource.cpp
+@@ -285,10 +285,15 @@ FFMS_AudioSource::AudioBlock *FFMS_AudioSource::CacheBlock(CacheIterator &pos) {
+ int FFMS_AudioSource::DecodeNextBlock(CacheIterator *pos) {
+ CurrentFrame = &Frames[PacketNumber];
+
+- AVPacket Packet;
+- if (!ReadPacket(&Packet))
++ AVPacket *Packet = av_packet_alloc();
++ if (!Packet)
++ throw FFMS_Exception(FFMS_ERROR_PARSER, FFMS_ERROR_ALLOCATION_FAILED,
++ "Could not allocate packet.");
++ if (!ReadPacket(Packet)) {
++ av_packet_free(&Packet);
+ throw FFMS_Exception(FFMS_ERROR_PARSER, FFMS_ERROR_UNKNOWN,
+ "ReadPacket unexpectedly failed to read a packet");
++ }
+
+ // ReadPacket may have changed the packet number
+ CurrentFrame = &Frames[PacketNumber];
+@@ -297,8 +302,9 @@ int FFMS_AudioSource::DecodeNextBlock(CacheIterator *pos) {
+ int NumberOfSamples = 0;
+ AudioBlock *CachedBlock = nullptr;
+
+- int Ret = avcodec_send_packet(CodecContext, &Packet);
+- av_packet_unref(&Packet);
++ int Ret = avcodec_send_packet(CodecContext, Packet);
++ av_packet_unref(Packet);
++ av_packet_free(&Packet);
+
+ av_frame_unref(DecodeFrame);
+ Ret = avcodec_receive_frame(CodecContext, DecodeFrame);
+@@ -513,8 +519,6 @@ void FFMS_AudioSource::Seek() {
+ }
+
+ bool FFMS_AudioSource::ReadPacket(AVPacket *Packet) {
+- InitNullPacket(*Packet);
+-
+ while (av_read_frame(FormatContext, Packet) >= 0) {
+ if (Packet->stream_index == TrackNumber) {
+ // Required because not all audio packets, especially in ogg, have a pts. Use the previous valid packet's pts instead.
+diff --git a/src/core/indexing.cpp b/src/core/indexing.cpp
+index 23fb95b..e547c5a 100644
+--- a/src/core/indexing.cpp
++++ b/src/core/indexing.cpp
+@@ -320,7 +320,7 @@ void FFMS_Indexer::CheckAudioProperties(int Track, AVCodecContext *Context) {
+ }
+ }
+
+-void FFMS_Indexer::ParseVideoPacket(SharedAVContext &VideoContext, AVPacket &pkt, int *RepeatPict,
++void FFMS_Indexer::ParseVideoPacket(SharedAVContext &VideoContext, AVPacket *pkt, int *RepeatPict,
+ int *FrameType, bool *Invisible, enum AVPictureStructure *LastPicStruct) {
+ if (VideoContext.Parser) {
+ uint8_t *OB;
+@@ -330,8 +330,8 @@ void FFMS_Indexer::ParseVideoPacket(SharedAVContext &VideoContext, AVPacket &pkt
+ av_parser_parse2(VideoContext.Parser,
+ VideoContext.CodecContext,
+ &OB, &OBSize,
+- pkt.data, pkt.size,
+- pkt.pts, pkt.dts, pkt.pos);
++ pkt->data, pkt->size,
++ pkt->pts, pkt->dts, pkt->pos);
+
+ // H.264 (PAFF) and HEVC may have one field per packet, so we need to track
+ // when we have a full or half frame available, and mark one of them as
+@@ -351,15 +351,15 @@ void FFMS_Indexer::ParseVideoPacket(SharedAVContext &VideoContext, AVPacket &pkt
+
+ *RepeatPict = VideoContext.Parser->repeat_pict;
+ *FrameType = VideoContext.Parser->pict_type;
+- *Invisible = (IncompleteFrame || VideoContext.Parser->repeat_pict < 0 || (pkt.flags & AV_PKT_FLAG_DISCARD));
++ *Invisible = (IncompleteFrame || VideoContext.Parser->repeat_pict < 0 || (pkt->flags & AV_PKT_FLAG_DISCARD));
+ } else {
+- *Invisible = !!(pkt.flags & AV_PKT_FLAG_DISCARD);
++ *Invisible = !!(pkt->flags & AV_PKT_FLAG_DISCARD);
+ }
+
+ if (VideoContext.CodecContext->codec_id == AV_CODEC_ID_VP8)
+- ParseVP8(pkt.data[0], Invisible, FrameType);
++ ParseVP8(pkt->data[0], Invisible, FrameType);
+ else if (VideoContext.CodecContext->codec_id == AV_CODEC_ID_VP9)
+- ParseVP9(pkt.data[0], Invisible, FrameType);
++ ParseVP9(pkt->data[0], Invisible, FrameType);
+ }
+
+ void FFMS_Indexer::Free() {
+@@ -458,32 +458,36 @@ FFMS_Index *FFMS_Indexer::DoIndexing() {
+ }
+ }
+
+- AVPacket Packet;
+- InitNullPacket(Packet);
++ AVPacket *Packet = av_packet_alloc();
++ if (!Packet)
++ throw FFMS_Exception(FFMS_ERROR_CODEC, FFMS_ERROR_ALLOCATION_FAILED,
++ "Could not allocate packet.");
+ std::vector<int64_t> LastValidTS(FormatContext->nb_streams, AV_NOPTS_VALUE);
+
+ int64_t filesize = avio_size(FormatContext->pb);
+ enum AVPictureStructure LastPicStruct = AV_PICTURE_STRUCTURE_UNKNOWN;
+- while (av_read_frame(FormatContext, &Packet) >= 0) {
++ while (av_read_frame(FormatContext, Packet) >= 0) {
+ // Update progress
+ // FormatContext->pb can apparently be NULL when opening images.
+ if (IC && FormatContext->pb) {
+- if ((*IC)(FormatContext->pb->pos, filesize, ICPrivate))
++ if ((*IC)(FormatContext->pb->pos, filesize, ICPrivate)) {
++ av_packet_free(&Packet);
+ throw FFMS_Exception(FFMS_ERROR_CANCELLED, FFMS_ERROR_USER,
+ "Cancelled by user");
++ }
+ }
+- if (!IndexMask.count(Packet.stream_index)) {
+- av_packet_unref(&Packet);
++ if (!IndexMask.count(Packet->stream_index)) {
++ av_packet_unref(Packet);
+ continue;
+ }
+
+- int Track = Packet.stream_index;
++ int Track = Packet->stream_index;
+ FFMS_Track &TrackInfo = (*TrackIndices)[Track];
+- bool KeyFrame = !!(Packet.flags & AV_PKT_FLAG_KEY);
++ bool KeyFrame = !!(Packet->flags & AV_PKT_FLAG_KEY);
+ ReadTS(Packet, LastValidTS[Track], (*TrackIndices)[Track].UseDTS);
+
+ if (FormatContext->streams[Track]->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
+- int64_t PTS = TrackInfo.UseDTS ? Packet.dts : Packet.pts;
++ int64_t PTS = TrackInfo.UseDTS ? Packet->dts : Packet->pts;
+ if (PTS == AV_NOPTS_VALUE) {
+ // VPx alt-refs are output as packets which lack timestmps or durations, since
+ // they are invisible. Currently, the timestamp mangling code in libavformat
+@@ -495,9 +499,11 @@ FFMS_Index *FFMS_Indexer::DoIndexing() {
+ // FFMS2 currently sorts packets by PTS, which will break decoding, otherwise.
+ bool HasAltRefs = (FormatContext->streams[Track]->codecpar->codec_id == AV_CODEC_ID_VP8 ||
+ FormatContext->streams[Track]->codecpar->codec_id == AV_CODEC_ID_VP9);
+- if (Packet.duration == 0 && !HasAltRefs)
++ if (Packet->duration == 0 && !HasAltRefs) {
++ av_packet_free(&Packet);
+ throw FFMS_Exception(FFMS_ERROR_INDEXING, FFMS_ERROR_PARSER,
+ "Invalid packet pts, dts, and duration");
++ }
+
+ if (TrackInfo.empty())
+ PTS = 0;
+@@ -513,7 +519,7 @@ FFMS_Index *FFMS_Indexer::DoIndexing() {
+ ParseVideoPacket(AVContexts[Track], Packet, &RepeatPict, &FrameType, &Invisible, &LastPicStruct);
+
+ TrackInfo.AddVideoFrame(PTS, RepeatPict, KeyFrame,
+- FrameType, Packet.pos, Invisible);
++ FrameType, Packet->pos, Invisible);
+ } else if (FormatContext->streams[Track]->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) {
+ // For video seeking timestamps are used only if all packets have
+ // timestamps, while for audio they're used if any have timestamps,
+@@ -522,28 +528,29 @@ FFMS_Index *FFMS_Indexer::DoIndexing() {
+ TrackInfo.HasTS = true;
+
+ int64_t StartSample = AVContexts[Track].CurrentSample;
+- uint32_t SampleCount = IndexAudioPacket(Track, &Packet, AVContexts[Track], *TrackIndices);
++ uint32_t SampleCount = IndexAudioPacket(Track, Packet, AVContexts[Track], *TrackIndices);
+ TrackInfo.SampleRate = AVContexts[Track].CodecContext->sample_rate;
+
+ TrackInfo.AddAudioFrame(LastValidTS[Track],
+- StartSample, SampleCount, KeyFrame, Packet.pos, Packet.flags & AV_PKT_FLAG_DISCARD);
++ StartSample, SampleCount, KeyFrame, Packet->pos, Packet->flags & AV_PKT_FLAG_DISCARD);
+ }
+
+- if (!(Packet.flags & AV_PKT_FLAG_DISCARD))
+- TrackInfo.LastDuration = Packet.duration;
++ if (!(Packet->flags & AV_PKT_FLAG_DISCARD))
++ TrackInfo.LastDuration = Packet->duration;
+
+- av_packet_unref(&Packet);
++ av_packet_unref(Packet);
+ }
++ av_packet_free(&Packet);
+
+ TrackIndices->Finalize(AVContexts, FormatContext->iformat->name);
+ return TrackIndices.release();
+ }
+
+-void FFMS_Indexer::ReadTS(const AVPacket &Packet, int64_t &TS, bool &UseDTS) {
+- if (!UseDTS && Packet.pts != AV_NOPTS_VALUE)
+- TS = Packet.pts;
++void FFMS_Indexer::ReadTS(const AVPacket *Packet, int64_t &TS, bool &UseDTS) {
++ if (!UseDTS && Packet->pts != AV_NOPTS_VALUE)
++ TS = Packet->pts;
+ if (TS == AV_NOPTS_VALUE)
+ UseDTS = true;
+- if (UseDTS && Packet.dts != AV_NOPTS_VALUE)
+- TS = Packet.dts;
++ if (UseDTS && Packet->dts != AV_NOPTS_VALUE)
++ TS = Packet->dts;
+ }
+diff --git a/src/core/indexing.h b/src/core/indexing.h
+index 3cfc3c3..5c06868 100644
+--- a/src/core/indexing.h
++++ b/src/core/indexing.h
+@@ -80,10 +80,10 @@ private:
+ int64_t Filesize;
+ uint8_t Digest[20];
+
+- void ReadTS(const AVPacket &Packet, int64_t &TS, bool &UseDTS);
++ void ReadTS(const AVPacket *Packet, int64_t &TS, bool &UseDTS);
+ void CheckAudioProperties(int Track, AVCodecContext *Context);
+ uint32_t IndexAudioPacket(int Track, AVPacket *Packet, SharedAVContext &Context, FFMS_Index &TrackIndices);
+- void ParseVideoPacket(SharedAVContext &VideoContext, AVPacket &pkt, int *RepeatPict, int *FrameType, bool *Invisible, enum AVPictureStructure *LastPicStruct);
++ void ParseVideoPacket(SharedAVContext &VideoContext, AVPacket *pkt, int *RepeatPict, int *FrameType, bool *Invisible, enum AVPictureStructure *LastPicStruct);
+ void Free();
+ public:
+ FFMS_Indexer(const char *Filename);
+diff --git a/src/core/utils.cpp b/src/core/utils.cpp
+index ce67533..8a2e997 100644
+--- a/src/core/utils.cpp
++++ b/src/core/utils.cpp
+@@ -62,12 +62,6 @@ void ClearErrorInfo(FFMS_ErrorInfo *ErrorInfo) {
+ }
+ }
+
+-void InitNullPacket(AVPacket &pkt) {
+- av_init_packet(&pkt);
+- pkt.data = nullptr;
+- pkt.size = 0;
+-}
+-
+ void FillAP(FFMS_AudioProperties &AP, AVCodecContext *CTX, FFMS_Track &Frames) {
+ AP.SampleFormat = static_cast<FFMS_SampleFormat>(av_get_packed_sample_fmt(CTX->sample_fmt));
+ AP.BitsPerSample = av_get_bytes_per_sample(CTX->sample_fmt) * 8;
+diff --git a/src/core/utils.h b/src/core/utils.h
+index 9819dc7..003ab79 100644
+--- a/src/core/utils.h
++++ b/src/core/utils.h
+@@ -58,7 +58,6 @@ std::unique_ptr<T> make_unique(Args&&... args) {
+ }
+
+ void ClearErrorInfo(FFMS_ErrorInfo *ErrorInfo);
+-void InitNullPacket(AVPacket &pkt);
+ void FillAP(FFMS_AudioProperties &AP, AVCodecContext *CTX, FFMS_Track &Frames);
+
+ void LAVFOpenFile(const char *SourceFile, AVFormatContext *&FormatContext, int Track);
+diff --git a/src/core/videosource.cpp b/src/core/videosource.cpp
+index 06bd161..b889970 100644
+--- a/src/core/videosource.cpp
++++ b/src/core/videosource.cpp
+@@ -673,30 +673,34 @@ void FFMS_VideoSource::DecodeNextFrame(int64_t &AStartTime, int64_t &Pos) {
+ if (HasPendingDelayedFrames())
+ return;
+
+- AVPacket Packet;
+- InitNullPacket(Packet);
+-
+- while (ReadFrame(&Packet) >= 0) {
+- if (Packet.stream_index != VideoTrack) {
+- av_packet_unref(&Packet);
++ AVPacket *Packet = av_packet_alloc();
++ if (!Packet)
++ throw FFMS_Exception(FFMS_ERROR_DECODING, FFMS_ERROR_ALLOCATION_FAILED,
++ "Could not allocate packet.");
++
++ while (ReadFrame(Packet) >= 0) {
++ if (Packet->stream_index != VideoTrack) {
++ av_packet_unref(Packet);
+ continue;
+ }
+
+ if (AStartTime < 0)
+- AStartTime = Frames.UseDTS ? Packet.dts : Packet.pts;
++ AStartTime = Frames.UseDTS ? Packet->dts : Packet->pts;
+
+ if (Pos < 0)
+- Pos = Packet.pos;
++ Pos = Packet->pos;
+
+- bool FrameFinished = DecodePacket(&Packet);
+- av_packet_unref(&Packet);
+- if (FrameFinished)
++ bool FrameFinished = DecodePacket(Packet);
++ av_packet_unref(Packet);
++ if (FrameFinished) {
++ av_packet_free(&Packet);
+ return;
++ }
+ }
+
+ // Flush final frames
+- InitNullPacket(Packet);
+- DecodePacket(&Packet);
++ DecodePacket(Packet);
++ av_packet_free(&Packet);
+ }
+
+ bool FFMS_VideoSource::SeekTo(int n, int SeekOffset) {
+--
+2.40.0
+
+From bf9e03e9e08534c024e5a744a6437c4aac160201 Mon Sep 17 00:00:00 2001
+From: Derek Buitenhuis <derek.buitenhuis@gmail.com>
+Date: Tue, 4 May 2021 14:20:47 +0100
+Subject: [PATCH 2/3] configure: Remove deprecated API use
+
+Signed-off-by: Derek Buitenhuis <derek.buitenhuis@gmail.com>
+---
+ configure.ac | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/configure.ac b/configure.ac
+index b35ef80bc..d19714d0f 100644
+--- a/configure.ac
++++ b/configure.ac
+@@ -102,10 +102,10 @@ CFLAGS="$_CFLAGS $FFMPEG_CFLAGS"
+
+ AC_DEFUN([TEST_FFMPEG],
+ [AC_LINK_IFELSE([AC_LANG_PROGRAM([[
+- #include <libavcodec/avcodec.h>
++ #include <libavformat/avformat.h>
+ #include <libswscale/swscale.h>
+ ]],[[
+- avcodec_register_all();
++ avformat_network_init();
+ swscale_version();
+ ]])], [eval $1=yes], [eval $1=no])
+ ])
+
diff --git a/srcpkgs/ffms2/template b/srcpkgs/ffms2/template
index 68e8a0c14bce..2acfadac44b3 100644
--- a/srcpkgs/ffms2/template
+++ b/srcpkgs/ffms2/template
@@ -1,7 +1,7 @@
# Template file for 'ffms2'
pkgname=ffms2
version=2.40
-revision=1
+revision=2
build_style=gnu-configure
configure_args="--enable-shared --disable-static"
hostmakedepends="pkg-config autoconf automake libtool"
From d126aef90bfaff4562679bb8478dc903a390c1b0 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:47 -0400
Subject: [PATCH 037/110] freerdp: revbump for ffmpeg-6.0
---
.../freerdp/patches/ffmpeg6_aa2cb9aa.patch | 42 +++++++++++++++++++
srcpkgs/freerdp/template | 2 +-
2 files changed, 43 insertions(+), 1 deletion(-)
create mode 100644 srcpkgs/freerdp/patches/ffmpeg6_aa2cb9aa.patch
diff --git a/srcpkgs/freerdp/patches/ffmpeg6_aa2cb9aa.patch b/srcpkgs/freerdp/patches/ffmpeg6_aa2cb9aa.patch
new file mode 100644
index 000000000000..a4324da3a882
--- /dev/null
+++ b/srcpkgs/freerdp/patches/ffmpeg6_aa2cb9aa.patch
@@ -0,0 +1,42 @@
+From aa2cb9aa5ff5562433598ba168a466e0752bca0e Mon Sep 17 00:00:00 2001
+From: akallabeth <akallabeth@posteo.net>
+Date: Tue, 14 Feb 2023 07:48:54 +0100
+Subject: [PATCH] Fixed #8686: Update h264 to use new FFMPEG API
+
+---
+ channels/tsmf/client/ffmpeg/tsmf_ffmpeg.c | 2 ++
+ libfreerdp/codec/h264_ffmpeg.c | 2 ++
+ 2 files changed, 4 insertions(+)
+
+diff --git a/channels/tsmf/client/ffmpeg/tsmf_ffmpeg.c b/channels/tsmf/client/ffmpeg/tsmf_ffmpeg.c
+index 339462d865f..beea80b7a1e 100644
+--- a/channels/tsmf/client/ffmpeg/tsmf_ffmpeg.c
++++ b/channels/tsmf/client/ffmpeg/tsmf_ffmpeg.c
+@@ -239,8 +239,10 @@ static BOOL tsmf_ffmpeg_init_stream(ITSMFDecoder* decoder, const TS_AM_MEDIA_TYP
+ }
+ }
+
++#if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(59, 18, 100)
+ if (mdecoder->codec->capabilities & AV_CODEC_CAP_TRUNCATED)
+ mdecoder->codec_context->flags |= AV_CODEC_FLAG_TRUNCATED;
++#endif
+
+ return TRUE;
+ }
+diff --git a/libfreerdp/codec/h264_ffmpeg.c b/libfreerdp/codec/h264_ffmpeg.c
+index 8a23db2473c..896a333019b 100644
+--- a/libfreerdp/codec/h264_ffmpeg.c
++++ b/libfreerdp/codec/h264_ffmpeg.c
+@@ -615,10 +615,12 @@ static BOOL libavcodec_init(H264_CONTEXT* h264)
+ goto EXCEPTION;
+ }
+
++#if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(59, 18, 100)
+ if (sys->codecDecoder->capabilities & AV_CODEC_CAP_TRUNCATED)
+ {
+ sys->codecDecoderContext->flags |= AV_CODEC_FLAG_TRUNCATED;
+ }
++#endif
+
+ #ifdef WITH_VAAPI
+
diff --git a/srcpkgs/freerdp/template b/srcpkgs/freerdp/template
index 25e8aa9677f0..4d51c8189902 100644
--- a/srcpkgs/freerdp/template
+++ b/srcpkgs/freerdp/template
@@ -1,7 +1,7 @@
# Template file for 'freerdp'
pkgname=freerdp
version=2.10.0
-revision=1
+revision=2
build_style=cmake
configure_args="-DWITH_ALSA=ON -DWITH_CUPS=OFF -DWITH_FFMPEG=ON
-DWITH_GSTREAMER_0_10=OFF -DWITH_GSTREAMER_1_0=OFF -DWITH_JPEG=ON
From 1f033aec29257dbf388e178cd4c00ee78591800d Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:47 -0400
Subject: [PATCH 038/110] gerbera: revbump for ffmpeg-6.0
---
srcpkgs/gerbera/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/gerbera/template b/srcpkgs/gerbera/template
index ae14f35c767c..2dc0ac0ce03b 100644
--- a/srcpkgs/gerbera/template
+++ b/srcpkgs/gerbera/template
@@ -1,7 +1,7 @@
# Template file for 'gerbera'
pkgname=gerbera
version=1.12.1
-revision=1
+revision=2
build_style=cmake
configure_args="-DWITH_SYSTEMD=0 -DWITH_AVCODEC=1"
hostmakedepends="pkg-config"
From 4ea188d64e5f4806ab1259a39d7a7aba46e59f6d Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:47 -0400
Subject: [PATCH 039/110] goldendict: revbump for ffmpeg-6.0
---
srcpkgs/goldendict/patches/ffmpeg4.patch | 21 --
srcpkgs/goldendict/patches/ffmpeg5.patch | 232 +++++++++++++++++++++++
srcpkgs/goldendict/template | 2 +-
3 files changed, 233 insertions(+), 22 deletions(-)
delete mode 100644 srcpkgs/goldendict/patches/ffmpeg4.patch
create mode 100644 srcpkgs/goldendict/patches/ffmpeg5.patch
diff --git a/srcpkgs/goldendict/patches/ffmpeg4.patch b/srcpkgs/goldendict/patches/ffmpeg4.patch
deleted file mode 100644
index f045fa27f54b..000000000000
--- a/srcpkgs/goldendict/patches/ffmpeg4.patch
+++ /dev/null
@@ -1,21 +0,0 @@
---- a/ffmpegaudio.cc.orig 2018-05-09 22:16:13.480659958 +0200
-+++ b/ffmpegaudio.cc 2018-05-09 22:16:50.748322790 +0200
-@@ -143,7 +143,7 @@
- return false;
- }
-
-- unsigned char * avioBuffer = ( unsigned char * )av_malloc( kBufferSize + FF_INPUT_BUFFER_PADDING_SIZE );
-+ unsigned char * avioBuffer = ( unsigned char * )av_malloc( kBufferSize + AV_INPUT_BUFFER_PADDING_SIZE );
- if ( !avioBuffer )
- {
- errorString = QObject::tr( "av_malloc() failed." );
-@@ -380,7 +380,7 @@
- }
-
- if ( !Qt4x5::AtomicInt::loadAcquire( isCancelled_ ) &&
-- codecContext_->codec->capabilities & CODEC_CAP_DELAY )
-+ codecContext_->codec->capabilities & AV_CODEC_CAP_DELAY )
- {
- av_init_packet( &packet );
- int gotFrame = 0;
-
diff --git a/srcpkgs/goldendict/patches/ffmpeg5.patch b/srcpkgs/goldendict/patches/ffmpeg5.patch
new file mode 100644
index 000000000000..7cfc98ada368
--- /dev/null
+++ b/srcpkgs/goldendict/patches/ffmpeg5.patch
@@ -0,0 +1,232 @@
+From 03bbe01b79a1f07a6780cb60f23a087104c5d77b Mon Sep 17 00:00:00 2001
+From: Abs62 <ottomann@yandex.ru>
+Date: Fri, 30 Mar 2018 22:53:24 +0300
+Subject: [PATCH] Fix warnings while compile with FFMpeg 3.4.2 (issue #978)
+
+---
+ ffmpegaudio.cc | 68 +++++++++++++++++++++++++++++++++++++++++++++-----
+ 1 file changed, 62 insertions(+), 6 deletions(-)
+
+diff --git a/ffmpegaudio.cc b/ffmpegaudio.cc
+index ed1172bdd..56e8f788e 100644
+--- a/ffmpegaudio.cc
++++ b/ffmpegaudio.cc
+@@ -91,6 +91,7 @@ struct DecoderContext
+ QByteArray audioData_;
+ QDataStream audioDataStream_;
+ AVFormatContext * formatContext_;
++ AVCodec * codec_;
+ AVCodecContext * codecContext_;
+ AVIOContext * avioContext_;
+ AVStream * audioStream_;
+@@ -114,6 +115,7 @@ DecoderContext::DecoderContext( QByteArray const & audioData, QAtomicInt & isCan
+ audioData_( audioData ),
+ audioDataStream_( audioData_ ),
+ formatContext_( NULL ),
++ codec_( NULL ),
+ codecContext_( NULL ),
+ avioContext_( NULL ),
+ audioStream_( NULL ),
+@@ -143,7 +145,11 @@ bool DecoderContext::openCodec( QString & errorString )
+ return false;
+ }
+
++#if LIBAVCODEC_VERSION_MAJOR < 56 || ( LIBAVCODEC_VERSION_MAJOR == 56 && LIBAVCODEC_VERSION_MINOR < 56 )
+ unsigned char * avioBuffer = ( unsigned char * )av_malloc( kBufferSize + FF_INPUT_BUFFER_PADDING_SIZE );
++#else
++ unsigned char * avioBuffer = ( unsigned char * )av_malloc( kBufferSize + AV_INPUT_BUFFER_PADDING_SIZE );
++#endif
+ if ( !avioBuffer )
+ {
+ errorString = QObject::tr( "av_malloc() failed." );
+@@ -186,7 +192,11 @@ bool DecoderContext::openCodec( QString & errorString )
+ // Find audio stream, use the first audio stream if available
+ for ( unsigned i = 0; i < formatContext_->nb_streams; i++ )
+ {
++#if LIBAVCODEC_VERSION_MAJOR < 57 || ( LIBAVCODEC_VERSION_MAJOR == 57 && LIBAVCODEC_VERSION_MINOR < 33 )
+ if ( formatContext_->streams[i]->codec->codec_type == AVMEDIA_TYPE_AUDIO )
++#else
++ if ( formatContext_->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_AUDIO )
++#endif
+ {
+ audioStream_ = formatContext_->streams[i];
+ break;
+@@ -198,22 +208,38 @@ bool DecoderContext::openCodec( QString & errorString )
+ return false;
+ }
+
++#if LIBAVCODEC_VERSION_MAJOR < 57 || ( LIBAVCODEC_VERSION_MAJOR == 57 && LIBAVCODEC_VERSION_MINOR < 33 )
+ codecContext_ = audioStream_->codec;
+- AVCodec * codec = avcodec_find_decoder( codecContext_->codec_id );
+- if ( !codec )
++ codec_ = avcodec_find_decoder( codecContext_->codec_id );
++ if ( !codec_ )
+ {
+ errorString = QObject::tr( "Codec [id: %1] not found." ).arg( codecContext_->codec_id );
+ return false;
+ }
++#else
++ codec_ = avcodec_find_decoder( audioStream_->codecpar->codec_id );
++ if ( !codec_ )
++ {
++ errorString = QObject::tr( "Codec [id: %1] not found." ).arg( audioStream_->codecpar->codec_id );
++ return false;
++ }
++ codecContext_ = avcodec_alloc_context3( codec_ );
++ if ( !codecContext_ )
++ {
++ errorString = QObject::tr( "avcodec_alloc_context3() failed." );
++ return false;
++ }
++ avcodec_parameters_to_context( codecContext_, audioStream_->codecpar );
++#endif
+
+- ret = avcodec_open2( codecContext_, codec, NULL );
++ ret = avcodec_open2( codecContext_, codec_, NULL );
+ if ( ret < 0 )
+ {
+ errorString = QObject::tr( "avcodec_open2() failed: %1." ).arg( avErrorString( ret ) );
+ return false;
+ }
+
+- av_log( NULL, AV_LOG_INFO, "Codec open: %s: channels: %d, rate: %d, format: %s\n", codec->long_name,
++ av_log( NULL, AV_LOG_INFO, "Codec open: %s: channels: %d, rate: %d, format: %s\n", codec_->long_name,
+ codecContext_->channels, codecContext_->sample_rate, av_get_sample_fmt_name( codecContext_->sample_fmt ) );
+ return true;
+ }
+@@ -252,10 +278,13 @@ void DecoderContext::closeCodec()
+
+ // Closing a codec context without prior avcodec_open2() will result in
+ // a crash in ffmpeg
+- if ( audioStream_ && audioStream_->codec && audioStream_->codec->codec )
++ if ( audioStream_ && codecContext_ && codec_ )
+ {
+ audioStream_->discard = AVDISCARD_ALL;
+- avcodec_close( audioStream_->codec );
++ avcodec_close( codecContext_ );
++#if LIBAVCODEC_VERSION_MAJOR > 57 || ( LIBAVCODEC_VERSION_MAJOR == 57 && LIBAVCODEC_VERSION_MINOR >= 33 )
++ avcodec_free_context( &codecContext_ );
++#endif
+ }
+
+ avformat_close_input( &formatContext_ );
+@@ -356,6 +385,7 @@ bool DecoderContext::play( QString & errorString )
+ if ( packet.stream_index == audioStream_->index )
+ {
+ AVPacket pack = packet;
++#if LIBAVCODEC_VERSION_MAJOR < 57 || ( LIBAVCODEC_VERSION_MAJOR == 57 && LIBAVCODEC_VERSION_MINOR < 37 )
+ int gotFrame = 0;
+ do
+ {
+@@ -370,6 +400,19 @@ bool DecoderContext::play( QString & errorString )
+ pack.data += len;
+ }
+ while( pack.size > 0 );
++#else
++ int ret = avcodec_send_packet( codecContext_, &pack );
++ /* read all the output frames (in general there may be any number of them) */
++ while( ret >= 0 )
++ {
++ ret = avcodec_receive_frame( codecContext_, frame);
++
++ if ( Qt4x5::AtomicInt::loadAcquire( isCancelled_ ) || ret < 0 )
++ break;
++
++ playFrame( frame );
++ }
++#endif
+ }
+ // av_free_packet() must be called after each call to av_read_frame()
+ #if LIBAVCODEC_VERSION_MAJOR < 57 || ( LIBAVCODEC_VERSION_MAJOR == 57 && LIBAVCODEC_VERSION_MINOR < 7 )
+@@ -379,6 +422,7 @@ bool DecoderContext::play( QString & errorString )
+ #endif
+ }
+
++#if LIBAVCODEC_VERSION_MAJOR < 57 || ( LIBAVCODEC_VERSION_MAJOR == 57 && LIBAVCODEC_VERSION_MINOR < 37 )
+ if ( !Qt4x5::AtomicInt::loadAcquire( isCancelled_ ) &&
+ codecContext_->codec->capabilities & CODEC_CAP_DELAY )
+ {
+@@ -391,6 +435,18 @@ bool DecoderContext::play( QString & errorString )
+ playFrame( frame );
+ }
+ }
++#else
++ /* flush the decoder */
++ av_init_packet( &packet );
++ int ret = avcodec_send_packet(codecContext_, &packet );
++ while( ret >= 0 )
++ {
++ ret = avcodec_receive_frame(codecContext_, frame);
++ if ( Qt4x5::AtomicInt::loadAcquire( isCancelled_ ) || ret < 0 )
++ break;
++ playFrame( frame );
++ }
++#endif
+
+ #if LIBAVCODEC_VERSION_MAJOR < 54
+ av_free( frame );
+32
+srcpkgs/goldendict/patches/ffmpeg5-2.patch
+Comment on this file
+@@ -0,0 +1,32 @@
+From 966f4a8b78e6324b930e5a50f2bb930bd87e565e Mon Sep 17 00:00:00 2001
+From: Abs62 <ottomann@yandex.ru>
+Date: Fri, 27 Sep 2019 17:00:52 +0300
+Subject: [PATCH] FFmpeg player: Fix some crashes on broken files
+
+---
+ ffmpegaudio.cc | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/ffmpegaudio.cc b/ffmpegaudio.cc
+index 56e8f788e..415fc79cb 100644
+--- a/ffmpegaudio.cc
++++ b/ffmpegaudio.cc
+@@ -51,7 +51,9 @@ AudioService & AudioService::instance()
+
+ AudioService::AudioService()
+ {
++#if LIBAVFORMAT_VERSION_MAJOR < 58 || ( LIBAVFORMAT_VERSION_MAJOR == 58 && LIBAVFORMAT_VERSION_MINOR < 9 )
+ av_register_all();
++#endif
+ ao_initialize();
+ }
+
+@@ -438,6 +440,8 @@ bool DecoderContext::play( QString & errorString )
+ #else
+ /* flush the decoder */
+ av_init_packet( &packet );
++ packet.data = NULL;
++ packet.size = 0;
+ int ret = avcodec_send_packet(codecContext_, &packet );
+ while( ret >= 0 )
+ {
+25
+srcpkgs/goldendict/patches/ffmpeg5-3.patch
+Comment on this file
+@@ -0,0 +1,25 @@
+From 8acb288c9e9bdb3c6bf2e803954dd3b6ac273c05 Mon Sep 17 00:00:00 2001
+From: Liao Junxuan <mikeljx@126.com>
+Date: Sun, 20 Feb 2022 12:28:05 +0800
+Subject: [PATCH] add support for ffmpeg 5.0
+
+---
+ ffmpegaudio.cc | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/ffmpegaudio.cc b/ffmpegaudio.cc
+index d550f4a77..7948d2187 100644
+--- a/ffmpegaudio.cc
++++ b/ffmpegaudio.cc
+@@ -94,7 +94,11 @@ struct DecoderContext
+ QByteArray audioData_;
+ QDataStream audioDataStream_;
+ AVFormatContext * formatContext_;
++#if LIBAVCODEC_VERSION_MAJOR < 59
+ AVCodec * codec_;
++#else
++ const AVCodec * codec_;
++#endif
+ AVCodecContext * codecContext_;
+ AVIOContext * avioContext_;
+ AVStream * audioStream_;
diff --git a/srcpkgs/goldendict/template b/srcpkgs/goldendict/template
index 4544ae710ee6..2ca4185e538a 100644
--- a/srcpkgs/goldendict/template
+++ b/srcpkgs/goldendict/template
@@ -9,7 +9,7 @@ makedepends="tiff-devel qt5-devel libvorbis-devel zlib-devel
libXtst-devel hunspell-devel qt5-tools-devel qt5-declarative-devel
qt5-webkit-devel lzo-devel bzip2-devel libao-devel qt5-svg-devel
libeb-devel qt5-x11extras-devel ffmpeg-devel liblzma-devel"
-short_desc="A feature-rich dictionary lookup program"
+short_desc="Feature-rich dictionary lookup program"
maintainer="John <me@johnnynator.dev>"
license="GPL-3.0-or-later"
homepage="http://goldendict.org/"
From e6ba92d79d1f211876e0373ce29adea4f1c6261c Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:47 -0400
Subject: [PATCH 040/110] gst-libav: revbump for ffmpeg-6.0
---
srcpkgs/gst-libav/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/gst-libav/template b/srcpkgs/gst-libav/template
index e9a79dc650a5..f082bd211c65 100644
--- a/srcpkgs/gst-libav/template
+++ b/srcpkgs/gst-libav/template
@@ -1,7 +1,7 @@
# Template file for 'gst-libav'
pkgname=gst-libav
version=1.20.3
-revision=1
+revision=2
build_style=meson
hostmakedepends="pkg-config yasm"
makedepends="orc-devel gst-plugins-base1-devel ffmpeg-devel"
From 0e27fb9528d61dd6b1f17ca00364da1ba4f9f342 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:47 -0400
Subject: [PATCH 041/110] gst-plugins-bad1: revbump for ffmpeg-6.0
---
srcpkgs/gst-plugins-bad1/template | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/srcpkgs/gst-plugins-bad1/template b/srcpkgs/gst-plugins-bad1/template
index f55f82fd4c77..5a9d5387e0d4 100644
--- a/srcpkgs/gst-plugins-bad1/template
+++ b/srcpkgs/gst-plugins-bad1/template
@@ -1,7 +1,7 @@
# Template file for 'gst-plugins-bad1'
pkgname=gst-plugins-bad1
-version=1.20.3
-revision=3
+version=1.22.1
+revision=2
build_helper="gir"
build_style=meson
configure_args="-Dpackage-origin=https://voidlinux.org -Ddoc=disabled
From 8b323b01849cb45238d6c451949c1bd4f60e4b99 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:47 -0400
Subject: [PATCH 042/110] gst-rtsp-server: revbump for ffmpeg-6.0
---
srcpkgs/gst-rtsp-server/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/gst-rtsp-server/template b/srcpkgs/gst-rtsp-server/template
index 33cd64ceb95e..8ceea8d34b4b 100644
--- a/srcpkgs/gst-rtsp-server/template
+++ b/srcpkgs/gst-rtsp-server/template
@@ -1,7 +1,7 @@
# Template file for 'gst-rtsp-server'
pkgname=gst-rtsp-server
version=1.20.3
-revision=2
+revision=3
build_style=meson
hostmakedepends="pkg-config python3"
makedepends="glib-devel gst-plugins-bad1-devel gobject-introspection
From 273c42c9bb65e2599b0569581487fa084c1c2a3e Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:47 -0400
Subject: [PATCH 043/110] guvcview: update to 2.0.8.
---
srcpkgs/guvcview/patches/fix-include.patch | 10 ++++++++++
srcpkgs/guvcview/template | 5 ++---
2 files changed, 12 insertions(+), 3 deletions(-)
create mode 100644 srcpkgs/guvcview/patches/fix-include.patch
diff --git a/srcpkgs/guvcview/patches/fix-include.patch b/srcpkgs/guvcview/patches/fix-include.patch
new file mode 100644
index 000000000000..503c2af3b78c
--- /dev/null
+++ b/srcpkgs/guvcview/patches/fix-include.patch
@@ -0,0 +1,10 @@
+--- a/guvcview/guvcview.c
++++ b/guvcview/guvcview.c
+@@ -28,6 +28,7 @@
+ #include <sys/stat.h>
+ #include <sys/resource.h>
+ #include <errno.h>
++#include <locale.h>
+
+ #include "gview.h"
+ #include "gviewv4l2core.h"
diff --git a/srcpkgs/guvcview/template b/srcpkgs/guvcview/template
index 345cf6006f24..86a7fd619612 100644
--- a/srcpkgs/guvcview/template
+++ b/srcpkgs/guvcview/template
@@ -1,8 +1,7 @@
# Template file for 'guvcview'
pkgname=guvcview
-version=2.0.7
+version=2.0.8
revision=1
-create_wrksrc=yes
build_style=gnu-configure
configure_args="--disable-static --disable-debian-menu"
hostmakedepends="pkg-config intltool autoconf automake libtool glib-devel"
@@ -14,7 +13,7 @@ maintainer="Orphaned <orphan@voidlinux.org>"
license="GPL-3.0-or-later"
homepage="http://guvcview.sourceforge.net/"
distfiles="${SOURCEFORGE_SITE}/${pkgname}/${pkgname}-src-${version}.tar.bz2"
-checksum=f47d51fbd06e44eeaa1a82f4a153c927527c90d94514197a70b2956028cc8ad4
+checksum=a21f4e448286666cf27bafef5290cc953a0a1796b752e5bbe521266dc1230c81
post_patch() {
sed '31a#include <locale.h>' -i guvcview/guvcview.c
From 76e4aa9c13a874d5409b7f5367bd6ede458316d8 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:48 -0400
Subject: [PATCH 044/110] handbrake: update to 1.6.1
---
.../patches/fix-missing-x265-link-flag.patch | 11 ++++++-----
.../handbrake/patches/libhb-vpl-include.patch | 15 +++++++++++++++
srcpkgs/handbrake/template | 17 ++++++++++-------
3 files changed, 31 insertions(+), 12 deletions(-)
create mode 100644 srcpkgs/handbrake/patches/libhb-vpl-include.patch
diff --git a/srcpkgs/handbrake/patches/fix-missing-x265-link-flag.patch b/srcpkgs/handbrake/patches/fix-missing-x265-link-flag.patch
index 26db03867a0c..d6bb2eda627a 100644
--- a/srcpkgs/handbrake/patches/fix-missing-x265-link-flag.patch
+++ b/srcpkgs/handbrake/patches/fix-missing-x265-link-flag.patch
@@ -1,14 +1,15 @@
--- a/gtk/configure.ac
+++ b/gtk/configure.ac
@@ -203,7 +203,7 @@
-
+
AM_CONDITIONAL([MINGW], [test "x$mingw_flag" = "xyes"])
-
--HB_LIBS="$HB_LIBS -lhandbrake -lavformat -lavfilter -lavcodec -lavutil -ldav1d -lswresample -lpostproc -ldvdnav -ldvdread -lmp3lame -lvorbis -lvorbisenc -logg -lswscale -ltheoraenc -ltheoradec -lvpx -lz -lbz2 -lbluray -lass -lfontconfig -lfreetype -lxml2 -ljansson -lopus -lspeex -lturbojpeg -llzma -lzimg"
-+HB_LIBS="$HB_LIBS -lhandbrake -lavformat -lavfilter -lavcodec -lavutil -ldav1d -lswresample -lpostproc -ldvdnav -ldvdread -lmp3lame -lvorbis -lvorbisenc -logg -lswscale -ltheoraenc -ltheoradec -lvpx -lz -lbz2 -lbluray -lass -lfontconfig -lfreetype -lxml2 -ljansson -lopus -lspeex -lturbojpeg -llzma -lzimg -ldl"
+
+-HB_LIBS="$HB_LIBS -lhandbrake -lavformat -lavfilter -lavcodec -lavutil -ldav1d -lswresample -lpostproc -ldvdnav -ldvdread -lmp3lame -lvorbis -lvorbisenc -logg -lswscale -ltheoraenc -ltheoradec -lvpx -lz -lbz2 -lbluray -lass -lfontconfig -lfreetype -lxml2 -ljansson -lopus -lspeex -lturbojpeg -llzma -lzimg -lSvtAv1Enc"
++HB_LIBS="$HB_LIBS -lhandbrake -lavformat -lavfilter -lavcodec -lavutil -ldav1d -lswresample -lpostproc -ldvdnav -ldvdread -lmp3lame -lvorbis -lvorbisenc -logg -lswscale -ltheoraenc -ltheoradec -lvpx -lz -lbz2 -lbluray -lass -lfontconfig -lfreetype -lxml2 -ljansson -lopus -lspeex -lturbojpeg -llzma -lzimg -lSvtAv1Enc -ldl"
HB_CPPFLAGS="$HB_CPPFLAGS $HBINC"
-
+
PKG_CHECK_MODULES([x264], [x264], sys_x264=yes, sys_x264=no)
+
--- a/test/module.defs
+++ b/test/module.defs
@@ -69,6 +69,9 @@
diff --git a/srcpkgs/handbrake/patches/libhb-vpl-include.patch b/srcpkgs/handbrake/patches/libhb-vpl-include.patch
new file mode 100644
index 000000000000..298f9f4ab28f
--- /dev/null
+++ b/srcpkgs/handbrake/patches/libhb-vpl-include.patch
@@ -0,0 +1,15 @@
+--- a/libhb/module.defs 2023-01-22 11:36:49.000000000 -0500
++++ b/libhb/module.defs 2023-04-03 22:37:52.395467010 -0400
+@@ -46,11 +46,7 @@
+ LIBHB.GCC.I += $(LIBHB.build/) $(CONTRIB.build/)include
+
+ ifeq (1,$(FEATURE.qsv))
+- ifeq ($(HOST.system),freebsd))
+- LIBHB.GCC.I += $(LOCALBASE)/include/vpl
+- else
+- LIBHB.GCC.I += $(CONTRIB.build/)include/vpl
+- endif
++ LIBHB.GCC.I += /usr/include/vpl
+ endif
+
+ ifneq (,$(filter $(HOST.system),freebsd netbsd openbsd))
diff --git a/srcpkgs/handbrake/template b/srcpkgs/handbrake/template
index ca5e4571e49c..c32cb1bfa31f 100644
--- a/srcpkgs/handbrake/template
+++ b/srcpkgs/handbrake/template
@@ -1,10 +1,10 @@
# Template file for 'handbrake'
pkgname=handbrake
-version=1.5.1
+version=1.6.1
revision=1
build_style=gnu-configure
configure_args="--force --disable-gtk-update-checks --disable-df-fetch --harden
- $(vopt_enable fdk_aac fdk-aac) $(vopt_enable nvenc)"
+ $(vopt_enable fdk_aac fdk-aac) $(vopt_enable nvenc) $(vopt_enable qsv)"
make_build_args="-C ${XBPS_TRIPLET}"
make_install_args="-C ${XBPS_TRIPLET}"
hostmakedepends="automake cmake gettext-devel glib-devel intltool libtool m4 meson nasm pkg-config python3"
@@ -12,8 +12,11 @@ makedepends="bzip2-devel ffmpeg-devel gst-plugins-base1-devel gtk+3-devel
jansson-devel lame-devel libass-devel libbluray-devel libdav1d-devel
libdvdnav-devel libdvdread-devel libgudev-devel libnuma-devel
libsamplerate-devel libtheora-devel libvorbis-devel libvpx-devel libxml2-devel
- opus-devel speex-devel x264-devel x265-devel zimg-devel
+ opus-devel speex-devel x264-devel x265-devel zimg-devel libsvt-av1-devel
$(vopt_if fdk_aac fdk-aac-devel)
+ $(vopt_if qsv libva-devel)
+ $(vopt_if qsv libdrm-devel)
+ $(vopt_if qsv onevpl-devel)
$(vopt_if nvenc nv-codec-headers)"
depends="desktop-file-utils gst-plugins-good1 hicolor-icon-theme"
short_desc="Multithreaded video transcoder"
@@ -21,15 +24,15 @@ maintainer="Enno Boland <gottox@voidlinux.org>"
license="GPL-2.0-only"
homepage="https://handbrake.fr/"
distfiles="https://github.com/HandBrake/HandBrake/releases/download/${version}/HandBrake-${version}-source.tar.bz2"
-checksum=3999fe06d5309c819799a73a968a8ec3840e7840c2b64af8f5cdb7fd8c9430f0
+checksum=94ccfe03db917a91650000c510f7fd53f844da19f19ad4b4be1b8f6bc31a8d4c
nocross=yes
-build_options="fdk_aac nvenc"
+build_options="fdk_aac nvenc qsv"
case "$XBPS_TARGET_MACHINE" in
x86_64*|i686*)
CFLAGS="-msse"
- build_options_default="nvenc"
+ build_options_default="nvenc qsv"
;;
esac
@@ -37,7 +40,7 @@ pre_configure() {
# use system libraries, don't download them
rm -rf contrib/
for module in fdk-aac ffmpeg libbluray libdav1d libdvdnav libdvdread nvenc \
- x265 zimg; do
+ x265 zimg svt-av1 libvpl; do
vsed -i "/MODULES += contrib\/${module}/d" make/include/main.defs
done
}
From 0cd7f8afb3be8335009fa2049e823565a02f5c7a Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:48 -0400
Subject: [PATCH 045/110] hedgewars: revbump for ffmpeg4-4.4.3
---
srcpkgs/hedgewars/template | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/srcpkgs/hedgewars/template b/srcpkgs/hedgewars/template
index 419f29b98b44..926fe4fe3e68 100644
--- a/srcpkgs/hedgewars/template
+++ b/srcpkgs/hedgewars/template
@@ -1,13 +1,13 @@
# Template file for 'hedgewars'
pkgname=hedgewars
version=1.0.2
-revision=1
+revision=2
build_style=cmake
configure_args="-DNOSERVER=1 -DDATA_INSTALL_DIR=/usr/share/${pkgname}
-DPHYSFS_SYSTEM=1 -DMINIMAL_FLAGS=1"
make_cmd=make
hostmakedepends="lua51 pkg-config qt5-qmake qt5-host-tools"
-makedepends="ffmpeg-devel lua51-devel physfs-devel qt5-tools-devel SDL2_image-devel
+makedepends="ffmpeg4-devel lua51-devel physfs-devel qt5-tools-devel SDL2_image-devel
SDL2_mixer-devel SDL2_net-devel SDL2_ttf-devel"
depends="libfreeglut"
short_desc="Funny turn-based artillery game, featuring fighting Hedgehogs!"
From 1cb72aa09e22c605bea0313f3faab6d86e7420ba Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:48 -0400
Subject: [PATCH 046/110] idjc: revbump for ffmpeg4-4.4.3
---
srcpkgs/idjc/template | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/srcpkgs/idjc/template b/srcpkgs/idjc/template
index df60318b3db9..36a75baf597c 100644
--- a/srcpkgs/idjc/template
+++ b/srcpkgs/idjc/template
@@ -1,11 +1,11 @@
# Template file for 'idjc'
pkgname=idjc
version=0.9.1
-revision=3
+revision=4
build_style=gnu-configure
hostmakedepends="pkg-config git python3 automake gettext-devel libtool"
makedepends="libvorbis-devel libogg-devel jack-devel libsamplerate-devel
- libflac-devel libsndfile-devel mpg123-devel ffmpeg-devel speex-devel
+ libflac-devel libsndfile-devel mpg123-devel ffmpeg4-devel speex-devel
glib-devel pixman-devel lame-devel python3-gobject-devel libshout-idjc-devel
opus-devel twolame-devel python3-mutagen python3-devel"
depends="python3-gobject python3-mutagen desktop-file-utils shared-mime-info python3-dbus jack"
From 05cb713f07c3a74543c2ec7418617cc7c331c0cc Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:48 -0400
Subject: [PATCH 047/110] kfilemetadata5: revbump for ffmpeg-6.0
---
srcpkgs/kfilemetadata5/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/kfilemetadata5/template b/srcpkgs/kfilemetadata5/template
index 8980121fbc69..f662a2043f93 100644
--- a/srcpkgs/kfilemetadata5/template
+++ b/srcpkgs/kfilemetadata5/template
@@ -1,7 +1,7 @@
# Template file for 'kfilemetadata5'
pkgname=kfilemetadata5
version=5.105.0
-revision=1
+revision=2
build_style=cmake
hostmakedepends="kcoreaddons extra-cmake-modules pkg-config qt5-host-tools qt5-qmake
gettext kcoreaddons python3"
From 09b41f29d8853380499d10349dbfc93e3af3e8a0 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:48 -0400
Subject: [PATCH 048/110] kid3: revbump for ffmpeg-6.0
---
srcpkgs/kid3/patches/ffmpeg5.patch | 17 +++++++++++++++++
srcpkgs/kid3/template | 2 +-
2 files changed, 18 insertions(+), 1 deletion(-)
create mode 100644 srcpkgs/kid3/patches/ffmpeg5.patch
diff --git a/srcpkgs/kid3/patches/ffmpeg5.patch b/srcpkgs/kid3/patches/ffmpeg5.patch
new file mode 100644
index 000000000000..135fc50e07c9
--- /dev/null
+++ b/srcpkgs/kid3/patches/ffmpeg5.patch
@@ -0,0 +1,17 @@
+# https://aur.archlinux.org/cgit/aur.git/diff/ffmpeg5.patch?h=kid3-cli&id=12410a74906612e7efc0ec8fbce739b4a0fef7e7
+diff --git a/src/plugins/acoustidimport/ffmpegfingerprintdecoder.cpp b/src/plugins/acoustidimport/ffmpegfingerprintdecoder.cpp
+index e156d424..e12b9abd 100644
+--- a/src/plugins/acoustidimport/ffmpegfingerprintdecoder.cpp
++++ b/src/plugins/acoustidimport/ffmpegfingerprintdecoder.cpp
+@@ -232,7 +232,11 @@ private:
+ friend class Format;
+ friend class Converter;
+ AVCodecContext* m_ptr;
++#if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(59, 0, 0)
+ AVCodec* m_impl;
++#else
++ const AVCodec* m_impl;
++#endif
+ AVFrame* m_frame;
+ bool m_opened;
+ };
diff --git a/srcpkgs/kid3/template b/srcpkgs/kid3/template
index 456206d90e16..f32f9decb0e7 100644
--- a/srcpkgs/kid3/template
+++ b/srcpkgs/kid3/template
@@ -1,7 +1,7 @@
# Template file for 'kid3'
pkgname=kid3
version=3.9.1
-revision=2
+revision=3
build_style=cmake
configure_args="-DWITH_APPS='CLI;$(vopt_if KDE KDE Qt)'
-DWITH_DOCBOOKDIR=/usr/share/xsl/docbook -DWITH_FLAC=$(vopt_if flac ON OFF)
From 3cb6a98588f710b94fe04729f6e2b95852bd8f0a Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:48 -0400
Subject: [PATCH 049/110] kodi: revbump for ffmpeg4-4.4.3
---
srcpkgs/kodi/template | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/srcpkgs/kodi/template b/srcpkgs/kodi/template
index 8057964d78a3..6cc1874be7ba 100644
--- a/srcpkgs/kodi/template
+++ b/srcpkgs/kodi/template
@@ -1,7 +1,7 @@
# Template file for 'kodi'
pkgname=kodi
version=19.4
-revision=6
+revision=7
_codename="Matrix"
build_style=cmake
configure_args="-DWITH_FFMPEG=/usr -DENABLE_LDGOLD=OFF
@@ -54,7 +54,7 @@ makedepends="
libmad-devel fontconfig-devel libXinerama-devel libsamplerate-devel libmms-devel
enca-devel boost-devel libcurl-devel libva-devel libvdpau-devel libass-devel
libbluetooth-devel yajl-devel libplist-devel librtmp-devel tinyxml-devel
- taglib-devel libcap-devel lame-devel libbluray-devel libnfs-devel ffmpeg-devel
+ taglib-devel libcap-devel lame-devel libbluray-devel libnfs-devel ffmpeg4-devel
giflib-devel libxslt-devel gnutls-devel libssh-devel libmicrohttpd-devel
libcec-devel dcadec-devel flatbuffers-devel fmt-devel lcms2-devel
libfstrcmp-devel rapidjson libcdio-paranoia spdlog libwaylandpp-devel
From 916a44b7203c62e94e6a1ee76249271b5085af56 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:48 -0400
Subject: [PATCH 050/110] kpipewire: revbump for ffmpeg-6.0
---
srcpkgs/kpipewire/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/kpipewire/template b/srcpkgs/kpipewire/template
index 467ab823a5e1..51827f24db9e 100644
--- a/srcpkgs/kpipewire/template
+++ b/srcpkgs/kpipewire/template
@@ -1,7 +1,7 @@
# Template file for 'kpipewire'
pkgname=kpipewire
version=5.27.4
-revision=1
+revision=2
build_style=cmake
hostmakedepends="extra-cmake-modules plasma-wayland-protocols gettext
qt5-qmake qt5-host-tools pkg-config wayland-devel kcoreaddons
From 45e732702da0292eef1bea8c3d169361d10013f6 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:48 -0400
Subject: [PATCH 051/110] libextractor: revbump for ffmpeg4-4.4.3
---
srcpkgs/libextractor/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/libextractor/template b/srcpkgs/libextractor/template
index ddd4790f93e8..1fb9ca56a96a 100644
--- a/srcpkgs/libextractor/template
+++ b/srcpkgs/libextractor/template
@@ -7,7 +7,7 @@ configure_args="--disable-static"
hostmakedepends="pkg-config"
makedepends="zlib-devel bzip2-devel exiv2-devel tiff-devel libpng-devel
libjpeg-turbo-devel libvorbis-devel libflac-devel giflib-devel libmpeg2-devel
- ffmpeg-devel gtk+3-devel libltdl-devel libarchive-devel file-devel libgsf-devel"
+ ffmpeg4-devel gtk+3-devel libltdl-devel libarchive-devel file-devel libgsf-devel"
short_desc="Library used to extract meta data from files"
maintainer="Martin Riese <grauehaare@gmx.de>"
license="GPL-3.0-or-later"
From 156a438afc5a01a65449435df2952c2853813c1f Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:48 -0400
Subject: [PATCH 052/110] libopenal: revbump for ffmpeg-6.0
---
srcpkgs/libopenal/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/libopenal/template b/srcpkgs/libopenal/template
index 77218f9e539d..3f49ed75a1fd 100644
--- a/srcpkgs/libopenal/template
+++ b/srcpkgs/libopenal/template
@@ -1,7 +1,7 @@
# Template file for 'libopenal'
pkgname=libopenal
version=1.22.2
-revision=1
+revision=2
build_style=cmake
configure_args="-DALSOFT_EXAMPLES=OFF"
hostmakedepends="pkg-config"
From 179dd5a54b3f154f718bb51730b0ad81c5048776 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:48 -0400
Subject: [PATCH 053/110] libopenshot: revbump for ffmpeg-6.0
---
srcpkgs/libopenshot/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/libopenshot/template b/srcpkgs/libopenshot/template
index db831f69b474..81aa0d7136d9 100644
--- a/srcpkgs/libopenshot/template
+++ b/srcpkgs/libopenshot/template
@@ -1,7 +1,7 @@
# Template file for 'libopenshot'
pkgname=libopenshot
version=0.3.0
-revision=1
+revision=2
build_style=cmake
# Builds fail with Ruby-2.4.1
configure_args="-DENABLE_RUBY=OFF -DUSE_SYSTEM_JSONCPP=ON"
From 5c6c1494d4261548b052f3b0bf6e22421280be3a Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:48 -0400
Subject: [PATCH 054/110] loudgain: revbump for ffmpeg-6.0
---
srcpkgs/loudgain/patches/ffmpeg5.patch | 11 +++++++++++
srcpkgs/loudgain/template | 2 +-
2 files changed, 12 insertions(+), 1 deletion(-)
create mode 100644 srcpkgs/loudgain/patches/ffmpeg5.patch
diff --git a/srcpkgs/loudgain/patches/ffmpeg5.patch b/srcpkgs/loudgain/patches/ffmpeg5.patch
new file mode 100644
index 000000000000..16d4510ee98f
--- /dev/null
+++ b/srcpkgs/loudgain/patches/ffmpeg5.patch
@@ -0,0 +1,11 @@
+--- a/src/scan.c 2019-09-06 11:31:19.000000000 -0400
++++ b/src/scan.c 2023-03-23 11:15:40.867968521 -0400
+@@ -69,8 +69,6 @@
+ * It is now useless
+ * https://github.com/FFmpeg/FFmpeg/blob/70d25268c21cbee5f08304da95be1f647c630c15/doc/APIchanges#L86
+ */
+- if (avformat_version() < AV_VERSION_INT(58,9,100))
+- av_register_all();
+
+ av_log_set_callback(scan_av_log);
+
diff --git a/srcpkgs/loudgain/template b/srcpkgs/loudgain/template
index da4f2d56e94c..4d6bf29efb4f 100644
--- a/srcpkgs/loudgain/template
+++ b/srcpkgs/loudgain/template
@@ -1,7 +1,7 @@
# Template file for 'loudgain'
pkgname=loudgain
version=0.6.8
-revision=2
+revision=3
build_style=cmake
hostmakedepends="pkg-config"
makedepends="libebur128-devel taglib-devel ffmpeg-devel"
From a494d51205779fa8a5457ffc8a009f5c5b2c7261 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:48 -0400
Subject: [PATCH 055/110] mediastreamer: revbump for ffmpeg4-4.4.3
---
srcpkgs/mediastreamer/template | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/srcpkgs/mediastreamer/template b/srcpkgs/mediastreamer/template
index d0e97e858e29..1bde031443a5 100644
--- a/srcpkgs/mediastreamer/template
+++ b/srcpkgs/mediastreamer/template
@@ -1,11 +1,11 @@
# Template file for 'mediastreamer'
pkgname=mediastreamer
version=5.2.6
-revision=1
+revision=2
build_style=cmake
configure_args="-DENABLE_STRICT=0 -DENABLE_UNIT_TESTS=0"
hostmakedepends="python3"
-makedepends="bzrtp-devel ffmpeg-devel glew-devel libXv-devel libsrtp-devel
+makedepends="bzrtp-devel ffmpeg4-devel glew-devel libXv-devel libsrtp-devel
libupnp-devel libvpx-devel mbedtls-devel opus-devel ortp-devel pulseaudio-devel
libtheora-devel speex-devel v4l-utils-devel bcg729-devel bcmatroska2-devel libgsm-devel"
# zxing-cpp-devel (1.2.0 probably not compatible, check again after updaing xzing)
From ea1f818456bac1f377aa26cfa095927b65f46183 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:48 -0400
Subject: [PATCH 056/110] mgba: revbump for ffmpeg-6.0
---
srcpkgs/mgba/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/mgba/template b/srcpkgs/mgba/template
index ae0504311eee..d31295a0cd3d 100644
--- a/srcpkgs/mgba/template
+++ b/srcpkgs/mgba/template
@@ -1,7 +1,7 @@
# Template file for 'mgba'
pkgname=mgba
version=0.10.2
-revision=1
+revision=2
build_style=cmake
hostmakedepends="pkg-config qt5-host-tools qt5-qmake desktop-file-utils"
makedepends="SDL2-devel ffmpeg-devel libedit-devel libepoxy-devel libmagick-devel
From 79b0075e25daf0be86eb91a2d23431f81b99b707 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:48 -0400
Subject: [PATCH 057/110] minidlna: revbump for ffmpeg-6.0
---
srcpkgs/minidlna/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/minidlna/template b/srcpkgs/minidlna/template
index e8081b1cbc67..9ee9714861fd 100644
--- a/srcpkgs/minidlna/template
+++ b/srcpkgs/minidlna/template
@@ -1,7 +1,7 @@
# Template file for 'minidlna'
pkgname=minidlna
version=1.3.2
-revision=1
+revision=2
build_style=gnu-configure
configure_args="
--sbindir=/usr/bin
From c01f7fd094f1da3369954331388193563742187e Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:49 -0400
Subject: [PATCH 058/110] mixxx: revbump for ffmpeg-6.0
---
srcpkgs/mixxx/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/mixxx/template b/srcpkgs/mixxx/template
index 619ddca0d332..4b9ea00d3fb3 100644
--- a/srcpkgs/mixxx/template
+++ b/srcpkgs/mixxx/template
@@ -1,7 +1,7 @@
# Template file for 'mixxx'
pkgname=mixxx
version=2.3.3
-revision=1
+revision=2
build_style=cmake
configure_args="-DCMAKE_BUILD_TYPE=Release"
hostmakedepends="extra-cmake-modules pkg-config protobuf qt5-host-tools qt5-devel"
From 3233fa3991eafa6bdee7fa943bae7cb8e8432423 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:49 -0400
Subject: [PATCH 059/110] mlt: revbump for ffmpeg4-4.4.3
---
srcpkgs/mlt/template | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/srcpkgs/mlt/template b/srcpkgs/mlt/template
index 8933eb4e7bb9..73353fedafb5 100644
--- a/srcpkgs/mlt/template
+++ b/srcpkgs/mlt/template
@@ -1,14 +1,14 @@
# Template file for 'mlt'
pkgname=mlt
version=6.26.1
-revision=1
+revision=2
build_style=configure
configure_args="--prefix=/usr --libdir=/usr/lib$XBPS_TARGET_WORDSIZE
--enable-gpl --enable-gpl3 --disable-swfdec --without-kde
--swig-languages=python"
hostmakedepends="doxygen pkg-config ladspa-sdk swig python3 which"
# XXX: movit vid.stab
-makedepends="alsa-lib-devel ffmpeg-devel gtk+-devel jack-devel ladspa-sdk
+makedepends="alsa-lib-devel ffmpeg4-devel gtk+-devel jack-devel ladspa-sdk
libexif-devel libsamplerate-devel libxml2-devel sox-devel SDL_image-devel
fftw-devel frei0r-plugins python3-devel pulseaudio-devel movit-devel
libvidstab-devel libatomic-devel"
From 872195cb60f49c12f166b9be201205088d8015cd Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:49 -0400
Subject: [PATCH 060/110] moc: revbump for ffmpeg4-4.4.3
---
srcpkgs/moc/template | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/srcpkgs/moc/template b/srcpkgs/moc/template
index c42be650a1d2..d4f0eefbad52 100644
--- a/srcpkgs/moc/template
+++ b/srcpkgs/moc/template
@@ -1,10 +1,10 @@
# Template file for 'moc'
pkgname=moc
version=2.5.2
-revision=6
+revision=7
build_style=gnu-configure
hostmakedepends="pkg-config"
-makedepends="db-devel ncurses-devel libcurl-devel popt-devel ffmpeg-devel
+makedepends="db-devel ncurses-devel libcurl-devel popt-devel ffmpeg4-devel
jack-devel alsa-lib-devel libltdl-devel libflac-devel libvorbis-devel
libmad-devel libmpcdec-devel libmodplug-devel libid3tag-devel faad2-devel
taglib-devel libsndfile-devel wavpack-devel speex-devel libsamplerate-devel
From 9befcbdbb9437163eac879e5a72780295d63b9e3 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:49 -0400
Subject: [PATCH 061/110] motion: revbump for ffmpeg-6.0
---
srcpkgs/motion/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/motion/template b/srcpkgs/motion/template
index 3cf3c3035c5b..7dca12d851e3 100644
--- a/srcpkgs/motion/template
+++ b/srcpkgs/motion/template
@@ -1,7 +1,7 @@
# Template file for 'motion'
pkgname=motion
version=4.5.1
-revision=1
+revision=2
build_style=gnu-configure
hostmakedepends="automake pkg-config gettext-devel tar"
makedepends="ffmpeg-devel libmicrohttpd-devel v4l-utils-devel gettext-devel"
From a2f9fbadbbbb11cbb3c744ef296fb1181752b813 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:49 -0400
Subject: [PATCH 062/110] mpv: revbump for ffmpeg-6.0
---
srcpkgs/mpv/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/mpv/template b/srcpkgs/mpv/template
index e163c496c6eb..d4fefbf5e3c7 100644
--- a/srcpkgs/mpv/template
+++ b/srcpkgs/mpv/template
@@ -1,7 +1,7 @@
# Template file for 'mpv'
pkgname=mpv
version=0.35.1
-revision=2
+revision=3
build_style=meson
configure_args="-Dcdda=enabled -Ddvbin=enabled -Ddvdnav=enabled
-Dlibmpv=true -Dcplugins=enabled
From 8f1f20999f83532f0e26c0236f62173c1bfdb356 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:49 -0400
Subject: [PATCH 063/110] musikcube: revbump for ffmpeg-6.0
---
srcpkgs/musikcube/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/musikcube/template b/srcpkgs/musikcube/template
index 4b7930041126..7cd65cf76b77 100644
--- a/srcpkgs/musikcube/template
+++ b/srcpkgs/musikcube/template
@@ -1,7 +1,7 @@
# Template file for 'musikcube'
pkgname=musikcube
version=0.99.4
-revision=1
+revision=2
build_style=cmake
make_cmd=make
configure_args="-DNO_NCURSESW=1"
From 62eb73128b9ad2415792972cb4ee7d963154b900 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:49 -0400
Subject: [PATCH 064/110] notcurses: revbump for ffmpeg-6.0
---
srcpkgs/notcurses/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/notcurses/template b/srcpkgs/notcurses/template
index 6dd8a091319f..3110c30c9aff 100644
--- a/srcpkgs/notcurses/template
+++ b/srcpkgs/notcurses/template
@@ -1,7 +1,7 @@
# Template file for 'notcurses'
pkgname=notcurses
version=3.0.9
-revision=1
+revision=2
build_style=cmake
configure_args="-DUSE_STATIC=ON $(vopt_bool man USE_PANDOC)"
hostmakedepends="pkg-config $(vopt_if man pandoc)"
From 7acde282bd77d6f56ecd04255eaa05ed64a392fa Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:49 -0400
Subject: [PATCH 065/110] obs: revbump for ffmpeg-6.0
---
srcpkgs/obs/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/obs/template b/srcpkgs/obs/template
index 89fd11297c3f..3cf49e414bf3 100644
--- a/srcpkgs/obs/template
+++ b/srcpkgs/obs/template
@@ -1,7 +1,7 @@
# Template file for 'obs'
pkgname=obs
version=29.1.0
-revision=1
+revision=2
archs="i686* x86_64* ppc64le* aarch64*"
build_style=cmake
configure_args="-DOBS_VERSION_OVERRIDE=${version} -DENABLE_JACK=ON
From c770da63d236cbc3d992f4910cb481f263a15fe3 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:49 -0400
Subject: [PATCH 066/110] olive: revbump for ffmpeg4-4.4.3
---
srcpkgs/olive/template | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/srcpkgs/olive/template b/srcpkgs/olive/template
index 12a46936c990..5c2917b9c512 100644
--- a/srcpkgs/olive/template
+++ b/srcpkgs/olive/template
@@ -1,10 +1,10 @@
# Template file for 'olive'
pkgname=olive
version=0.1.2
-revision=2
+revision=3
build_style=qmake
hostmakedepends="qt5-qmake qt5-host-tools pkg-config"
-makedepends="qt5-devel qt5-multimedia-devel qt5-svg-devel ffmpeg-devel frei0r-plugins"
+makedepends="qt5-devel qt5-multimedia-devel qt5-svg-devel ffmpeg4-devel frei0r-plugins"
short_desc="Non-linear video editor"
maintainer="Orphaned <orphan@voidlinux.org>"
license="GPL-3.0-or-later"
From b67130e6b1f97bdfdb04ebfb2112e3944f53ce72 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:49 -0400
Subject: [PATCH 067/110] omxplayer: revbump for ffmpeg4-4.4.3
---
srcpkgs/omxplayer/template | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/srcpkgs/omxplayer/template b/srcpkgs/omxplayer/template
index e70bf7873d4d..0e9bc70e7c8e 100644
--- a/srcpkgs/omxplayer/template
+++ b/srcpkgs/omxplayer/template
@@ -1,10 +1,10 @@
# Template file for 'omxplayer'
pkgname=omxplayer
version=20190102
-revision=1
+revision=2
short_desc="Commandline OMX player for the Raspberry Pi"
maintainer="Orphaned <orphan@voidlinux.org>"
-license="GPL-2"
+license="GPL-2.0-or-later"
homepage="https://github.com/popcornmix/omxplayer"
_commit="f06235cc9690a6d58187514452df8cf8fcdaacec"
@@ -15,7 +15,7 @@ checksum=af2d9450f8947842ea8c401fe9f71eec444013ebbdee29f2ac828c9c493c1329
archs="armv6l* armv7l*"
build_style=gnu-makefile
hostmakedepends="curl pkg-config"
-makedepends="alsa-lib-devel rpi-userland-devel pcre-devel boost-devel freetype-devel ffmpeg-devel dbus-devel"
+makedepends="alsa-lib-devel rpi-userland-devel pcre-devel boost-devel freetype-devel ffmpeg4-devel dbus-devel"
depends="freefont-ttf"
do_build() {
From ff414c79bff8df0b91f7a06b03279024bd3882b9 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:50 -0400
Subject: [PATCH 068/110] openimageio: revbump for ffmpeg-6.0
---
common/shlibs | 2 ++
srcpkgs/openimageio/template | 2 +-
2 files changed, 3 insertions(+), 1 deletion(-)
diff --git a/common/shlibs b/common/shlibs
index fcc7401be626..5f05896ba1d1 100644
--- a/common/shlibs
+++ b/common/shlibs
@@ -2262,6 +2262,8 @@ libxmp.so.4 libxmp-4.3.7_1
libKF5ThreadWeaver.so.5 threadweaver-5.26.0_1
libOpenImageIO_Util.so.2.4 openimageio-2.4.9.0_1
libOpenImageIO.so.2.4 openimageio-2.4.9.0_1
+libOpenImageIO_Util.so.2.4 openimageio-2.4.8.1_1
+libOpenImageIO.so.2.4 openimageio-2.4.8.1_1
libOpenColorIO.so.2.1 opencolorio-2.1.2_1
libpystring.so.1 pystring-1.1.3_1
libyaml-cpp.so.0.7 yaml-cpp-0.7.0_1
diff --git a/srcpkgs/openimageio/template b/srcpkgs/openimageio/template
index b661bbf7ba57..9b38ace50f7e 100644
--- a/srcpkgs/openimageio/template
+++ b/srcpkgs/openimageio/template
@@ -1,7 +1,7 @@
# Template file for 'openimageio'
pkgname=openimageio
version=2.4.9.0
-revision=2
+revision=3
build_style=cmake
build_helper=qemu
configure_args="-DUSE_QT=0 -DUSE_PYTHON=0 -DOIIO_BUILD_TESTS=0
From 3e9d7602aa4309b2ef35c23e1c6c25a6a973dac8 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:50 -0400
Subject: [PATCH 069/110] openmw: revbump for ffmpeg-6.0
---
srcpkgs/openmw/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/openmw/template b/srcpkgs/openmw/template
index 5251a0283dc1..e3771c7aaf1a 100644
--- a/srcpkgs/openmw/template
+++ b/srcpkgs/openmw/template
@@ -1,7 +1,7 @@
# Template file for 'openmw'
pkgname=openmw
version=0.47.0
-revision=4
+revision=5
build_style=cmake
_recast_commit=e75adf86f91eb3082220085e42dda62679f9a3ea
_bullet_tag=3.17
From 7c056ef462a1540048fe17ff39a07ef81b1e03ad Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:50 -0400
Subject: [PATCH 070/110] openshot: revbump for ffmpeg-6.0
---
srcpkgs/openshot/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/openshot/template b/srcpkgs/openshot/template
index 322717d40abc..c074e0338773 100644
--- a/srcpkgs/openshot/template
+++ b/srcpkgs/openshot/template
@@ -1,7 +1,7 @@
# Template file for 'openshot'
pkgname=openshot
version=3.0.0
-revision=1
+revision=2
build_style=python3-module
hostmakedepends="python3 python3-setuptools"
makedepends="ffmpeg-devel python3-PyQt5"
From 87dd339ffef41c2976be1b88c47655bfdf587fd9 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:50 -0400
Subject: [PATCH 071/110] opentoonz: revbump for ffmpeg-6.0
---
srcpkgs/opentoonz/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/opentoonz/template b/srcpkgs/opentoonz/template
index ee9f7603f55f..3e81834ca0ed 100644
--- a/srcpkgs/opentoonz/template
+++ b/srcpkgs/opentoonz/template
@@ -1,7 +1,7 @@
# Template file for 'opentoonz'
pkgname=opentoonz
version=1.6.0
-revision=2
+revision=3
build_wrksrc="toonz/sources"
build_style=cmake
make_cmd=make
From 94f318e08d5dab7240b54b297ead562ba5f7321a Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:50 -0400
Subject: [PATCH 072/110] pianobar: revbump for ffmpeg-6.0
---
srcpkgs/pianobar/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/pianobar/template b/srcpkgs/pianobar/template
index a9b29e91993f..81efcd122c4d 100644
--- a/srcpkgs/pianobar/template
+++ b/srcpkgs/pianobar/template
@@ -1,7 +1,7 @@
# Template file for 'pianobar'
pkgname=pianobar
version=2022.04.01
-revision=1
+revision=2
build_style=gnu-makefile
make_build_args="V=1"
hostmakedepends="pkg-config"
From ae8839ef9612cfa96ded9def765189499a051eb6 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:50 -0400
Subject: [PATCH 073/110] ppsspp: revbump for ffmpeg4-4.4.3
---
srcpkgs/ppsspp/template | 7 +++----
1 file changed, 3 insertions(+), 4 deletions(-)
diff --git a/srcpkgs/ppsspp/template b/srcpkgs/ppsspp/template
index 7984a733d4be..15a42fd2c993 100644
--- a/srcpkgs/ppsspp/template
+++ b/srcpkgs/ppsspp/template
@@ -1,7 +1,7 @@
# Template file for 'ppsspp'
pkgname=ppsspp
version=1.14.4
-revision=1
+revision=2
_glslang_commit=dc11adde23c455a24e13dd54de9b4ede8bdd7db8
_SPIRV_Cross_commit=9acb9ec31f5a8ef80ea6b994bb77be787b08d3d1
_armips_commit=6719edebaae03330ee5441d9b28280672edf00d5
@@ -13,7 +13,7 @@ configure_args="-DHEADLESS=1 -DUSE_SYSTEM_FFMPEG=1 -DUNITTEST=ON
-DUSING_QT_UI=$(vopt_if qt ON OFF) -DUSE_SYSTEM_ZSTD=ON
-DARMIPS_USE_STD_FILESYSTEM=ON"
hostmakedepends="pkg-config python3 $(vopt_if qt qt5-host-tools)"
-makedepends="zlib-devel glew-devel ffmpeg-devel libzip-devel
+makedepends="zlib-devel glew-devel ffmpeg4-devel libzip-devel
snappy-devel rapidjson libpng-devel libzstd-devel
$(vopt_if sdl2 SDL2-devel) $(vopt_if wayland wayland-devel)
$(vopt_if qt 'qt5-devel qt5-multimedia-devel')"
@@ -62,13 +62,12 @@ post_extract() {
mv ${wrksrc}/miniupnp-${_miniupnp_commit} ${wrksrc}/ext/miniupnp
}
-post_patch(){
+post_patch() {
# disable git versioning
vsed -e 's|find_package(Git)|# &|' -i git-version.cmake
}
do_install() {
- vlicense LICENSE.TXT
vinstall icons/icon.svg 644 usr/share/pixmaps ppsspp.svg
vinstall Qt/PPSSPP.desktop 644 usr/share/applications
vbin build/PPSSPPHeadless ppsspp-headless
From 7b8d07be011eadf5c96922ef118097fa99b038ce Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:50 -0400
Subject: [PATCH 074/110] pqiv: revbump for ffmpeg-6.0
---
srcpkgs/pqiv/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/pqiv/template b/srcpkgs/pqiv/template
index 542fc27a2d32..9308d949b6a1 100644
--- a/srcpkgs/pqiv/template
+++ b/srcpkgs/pqiv/template
@@ -1,7 +1,7 @@
# Template file for 'pqiv'
pkgname=pqiv
version=2.12
-revision=1
+revision=2
build_style=gnu-makefile
hostmakedepends="pkg-config"
makedepends="glib-devel gtk+3-devel $(vopt_if ffmpeg ffmpeg-devel)
From 5593dda726829d77cc471b7e9c7ae7caf33ed373 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:50 -0400
Subject: [PATCH 075/110] qmmp: revbump for ffmpeg-6.0
---
srcpkgs/qmmp/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/qmmp/template b/srcpkgs/qmmp/template
index 26c661ed16be..a150d7441c7a 100644
--- a/srcpkgs/qmmp/template
+++ b/srcpkgs/qmmp/template
@@ -1,7 +1,7 @@
# Template file for 'qmmp'
pkgname=qmmp
version=1.6.1
-revision=1
+revision=2
build_style=cmake
configure_args="-DUSE_HAL:BOOL=FALSE -DQMMP_DEFAULT_UI:STRING=simple"
hostmakedepends="pkg-config qt5-host-tools qt5-qmake"
From 234609804864d53a21f61ca2ef3f43cff8d43184 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:50 -0400
Subject: [PATCH 076/110] qt5-webengine: update to 5.15.13
---
.../chromium-media-filters-cpp14.patch | 11 ++
srcpkgs/qt5-webengine/patches/ffmpeg5.patch | 179 ++++++++++++++++++
srcpkgs/qt5-webengine/template | 10 +-
3 files changed, 195 insertions(+), 5 deletions(-)
create mode 100644 srcpkgs/qt5-webengine/patches/chromium-media-filters-cpp14.patch
create mode 100644 srcpkgs/qt5-webengine/patches/ffmpeg5.patch
diff --git a/srcpkgs/qt5-webengine/patches/chromium-media-filters-cpp14.patch b/srcpkgs/qt5-webengine/patches/chromium-media-filters-cpp14.patch
new file mode 100644
index 000000000000..04adc540f2cb
--- /dev/null
+++ b/srcpkgs/qt5-webengine/patches/chromium-media-filters-cpp14.patch
@@ -0,0 +1,11 @@
+--- a/src/3rdparty/chromium/media/filters/BUILD.gn 2023-02-27 13:32:59.000000000 -0500
++++ b/src/3rdparty/chromium/media/filters/BUILD.gn 2023-04-02 17:21:39.204066384 -0400
+@@ -96,6 +96,8 @@
+ "//ui/gfx/geometry:geometry",
+ ]
+
++ cflags_cc = [ "-std=c++14" ]
++
+ libs = []
+
+ if (proprietary_codecs) {
diff --git a/srcpkgs/qt5-webengine/patches/ffmpeg5.patch b/srcpkgs/qt5-webengine/patches/ffmpeg5.patch
new file mode 100644
index 000000000000..ac55e1634423
--- /dev/null
+++ b/srcpkgs/qt5-webengine/patches/ffmpeg5.patch
@@ -0,0 +1,179 @@
+--- a/src/3rdparty/chromium/media/filters/ffmpeg_demuxer.cc 2023-04-02 16:50:57.732547446 -0400
++++ b/src/3rdparty/chromium/media/filters/ffmpeg_demuxer.cc 2023-04-02 16:50:09.486478995 -0400
+@@ -57,6 +57,8 @@
+
+ namespace {
+
++constexpr int64_t kRelativeTsBase = static_cast<int64_t>(0x7ffeffffffffffff);
++
+ void SetAVStreamDiscard(AVStream* stream, AVDiscard discard) {
+ DCHECK(stream);
+ stream->discard = discard;
+@@ -90,24 +92,12 @@
+
+ static base::TimeDelta ExtractStartTime(AVStream* stream) {
+ // The default start time is zero.
+- base::TimeDelta start_time;
++ base::TimeDelta start_time = kNoTimestamp;
+
+ // First try to use the |start_time| value as is.
+ if (stream->start_time != kNoFFmpegTimestamp)
+ start_time = ConvertFromTimeBase(stream->time_base, stream->start_time);
+
+- // Next try to use the first DTS value, for codecs where we know PTS == DTS
+- // (excludes all H26x codecs). The start time must be returned in PTS.
+- if (stream->first_dts != kNoFFmpegTimestamp &&
+- stream->codecpar->codec_id != AV_CODEC_ID_HEVC &&
+- stream->codecpar->codec_id != AV_CODEC_ID_H264 &&
+- stream->codecpar->codec_id != AV_CODEC_ID_MPEG4) {
+- const base::TimeDelta first_pts =
+- ConvertFromTimeBase(stream->time_base, stream->first_dts);
+- if (first_pts < start_time)
+- start_time = first_pts;
+- }
+-
+ return start_time;
+ }
+
+@@ -408,11 +398,11 @@
+ scoped_refptr<DecoderBuffer> buffer;
+
+ if (type() == DemuxerStream::TEXT) {
+- int id_size = 0;
++ size_t id_size = 0;
+ uint8_t* id_data = av_packet_get_side_data(
+ packet.get(), AV_PKT_DATA_WEBVTT_IDENTIFIER, &id_size);
+
+- int settings_size = 0;
++ size_t settings_size = 0;
+ uint8_t* settings_data = av_packet_get_side_data(
+ packet.get(), AV_PKT_DATA_WEBVTT_SETTINGS, &settings_size);
+
+@@ -424,7 +414,7 @@
+ buffer = DecoderBuffer::CopyFrom(packet->data, packet->size,
+ side_data.data(), side_data.size());
+ } else {
+- int side_data_size = 0;
++ size_t side_data_size = 0;
+ uint8_t* side_data = av_packet_get_side_data(
+ packet.get(), AV_PKT_DATA_MATROSKA_BLOCKADDITIONAL, &side_data_size);
+
+@@ -485,7 +475,7 @@
+ packet->size - data_offset);
+ }
+
+- int skip_samples_size = 0;
++ size_t skip_samples_size = 0;
+ const uint32_t* skip_samples_ptr =
+ reinterpret_cast<const uint32_t*>(av_packet_get_side_data(
+ packet.get(), AV_PKT_DATA_SKIP_SAMPLES, &skip_samples_size));
+@@ -1587,6 +1577,8 @@
+ for (const auto& stream : streams_) {
+ if (!stream || stream->IsEnabled() != enabled)
+ continue;
++ if (stream->av_stream()->start_time == AV_NOPTS_VALUE)
++ continue;
+ if (!lowest_start_time_stream ||
+ stream->start_time() < lowest_start_time_stream->start_time()) {
+ lowest_start_time_stream = stream.get();
+@@ -1604,6 +1596,8 @@
+ if (stream && stream->type() == DemuxerStream::VIDEO &&
+ stream->IsEnabled()) {
+ video_stream = stream.get();
++ if (stream->av_stream()->start_time == AV_NOPTS_VALUE)
++ continue;
+ if (video_stream->start_time() <= seek_time) {
+ return video_stream;
+ }
+diff -Naurp qtwebengine-5.15.10.orig/src/3rdparty/chromium/media/ffmpeg/ffmpeg_common.h qtwebengine-5.15.10/src/3rdparty/chromium/media/ffmpeg/ffmpeg_common.h
+--- a/src/3rdparty/chromium/media/ffmpeg/ffmpeg_common.h 2022-05-23 06:38:40.000000000 -0500
++++ b/src/3rdparty/chromium/media/ffmpeg/ffmpeg_common.h 2022-07-11 22:12:47.917192788 -0500
+@@ -29,6 +29,7 @@ extern "C" {
+ #include <libavformat/avformat.h>
+ #include <libavformat/avio.h>
+ #include <libavutil/avutil.h>
++#include <libavutil/channel_layout.h>
+ #include <libavutil/imgutils.h>
+ #include <libavutil/log.h>
+ #include <libavutil/mastering_display_metadata.h>
+diff -Naurp qtwebengine-5.15.10.orig/src/3rdparty/chromium/media/filters/audio_file_reader.cc qtwebengine-5.15.10/src/3rdparty/chromium/media/filters/audio_file_reader.cc
+--- a/src/3rdparty/chromium/media/filters/audio_file_reader.cc 2022-05-23 06:38:40.000000000 -0500
++++ b/src/3rdparty/chromium/media/filters/audio_file_reader.cc 2022-07-11 22:12:47.917192788 -0500
+@@ -85,7 +85,7 @@ bool AudioFileReader::OpenDemuxer() {
+ }
+
+ bool AudioFileReader::OpenDecoder() {
+- AVCodec* codec = avcodec_find_decoder(codec_context_->codec_id);
++ const AVCodec* codec = avcodec_find_decoder(codec_context_->codec_id);
+ if (codec) {
+ // MP3 decodes to S16P which we don't support, tell it to use S16 instead.
+ if (codec_context_->sample_fmt == AV_SAMPLE_FMT_S16P)
+diff -Naurp qtwebengine-5.15.10.orig/src/3rdparty/chromium/media/filters/ffmpeg_audio_decoder.cc qtwebengine-5.15.10/src/3rdparty/chromium/media/filters/ffmpeg_audio_decoder.cc
+--- a/src/3rdparty/chromium/media/filters/ffmpeg_audio_decoder.cc 2022-05-23 06:38:40.000000000 -0500
++++ b/src/3rdparty/chromium/media/filters/ffmpeg_audio_decoder.cc 2022-07-11 22:12:47.917192788 -0500
+@@ -329,7 +329,7 @@ bool FFmpegAudioDecoder::ConfigureDecode
+ }
+ }
+
+- AVCodec* codec = avcodec_find_decoder(codec_context_->codec_id);
++ const AVCodec* codec = avcodec_find_decoder(codec_context_->codec_id);
+ if (!codec ||
+ avcodec_open2(codec_context_.get(), codec, &codec_options) < 0) {
+ DLOG(ERROR) << "Could not initialize audio decoder: "
+diff -Naurp qtwebengine-5.15.10.orig/src/3rdparty/chromium/media/filters/ffmpeg_glue.cc qtwebengine-5.15.10/src/3rdparty/chromium/media/filters/ffmpeg_glue.cc
+--- a/src/3rdparty/chromium/media/filters/ffmpeg_glue.cc 2022-05-23 06:38:40.000000000 -0500
++++ b/src/3rdparty/chromium/media/filters/ffmpeg_glue.cc 2022-07-11 22:12:47.918192779 -0500
+@@ -59,7 +59,6 @@ static int64_t AVIOSeekOperation(void* o
+ }
+
+ void FFmpegGlue::InitializeFFmpeg() {
+- av_register_all();
+ }
+
+ static void LogContainer(bool is_local_file,
+@@ -95,9 +94,6 @@ FFmpegGlue::FFmpegGlue(FFmpegURLProtocol
+ // Enable fast, but inaccurate seeks for MP3.
+ format_context_->flags |= AVFMT_FLAG_FAST_SEEK;
+
+- // Ensures we can read out various metadata bits like vp8 alpha.
+- format_context_->flags |= AVFMT_FLAG_KEEP_SIDE_DATA;
+-
+ // Ensures format parsing errors will bail out. From an audit on 11/2017, all
+ // instances were real failures. Solves bugs like http://crbug.com/710791.
+ format_context_->error_recognition |= AV_EF_EXPLODE;
+diff -Naurp qtwebengine-5.15.10.orig/src/3rdparty/chromium/media/filters/ffmpeg_video_decoder.cc qtwebengine-5.15.10/src/3rdparty/chromium/media/filters/ffmpeg_video_decoder.cc
+--- a/src/3rdparty/chromium/media/filters/ffmpeg_video_decoder.cc 2022-05-23 06:38:40.000000000 -0500
++++ b/src/3rdparty/chromium/media/filters/ffmpeg_video_decoder.cc 2022-07-11 22:12:47.918192779 -0500
+@@ -391,7 +391,7 @@ bool FFmpegVideoDecoder::ConfigureDecode
+ if (decode_nalus_)
+ codec_context_->flags2 |= AV_CODEC_FLAG2_CHUNKS;
+
+- AVCodec* codec = avcodec_find_decoder(codec_context_->codec_id);
++ const AVCodec* codec = avcodec_find_decoder(codec_context_->codec_id);
+ if (!codec || avcodec_open2(codec_context_.get(), codec, NULL) < 0) {
+ ReleaseFFmpegResources();
+ return false;
+diff -Naurp qtwebengine-5.15.10.orig/src/3rdparty/chromium/media/filters/media_file_checker.cc qtwebengine-5.15.10/src/3rdparty/chromium/media/filters/media_file_checker.cc
+--- a/src/3rdparty/chromium/media/filters/media_file_checker.cc 2022-05-23 06:38:40.000000000 -0500
++++ b/src/3rdparty/chromium/media/filters/media_file_checker.cc 2022-07-11 22:12:47.918192779 -0500
+@@ -68,7 +68,7 @@ bool MediaFileChecker::Start(base::TimeD
+ auto context = AVStreamToAVCodecContext(format_context->streams[i]);
+ if (!context)
+ continue;
+- AVCodec* codec = avcodec_find_decoder(cp->codec_id);
++ const AVCodec* codec = avcodec_find_decoder(cp->codec_id);
+ if (codec && avcodec_open2(context.get(), codec, nullptr) >= 0) {
+ auto loop = std::make_unique<FFmpegDecodingLoop>(context.get());
+ stream_contexts[i] = {std::move(context), std::move(loop)};
+diff -Naurp qtwebengine-5.15.10.orig/src/3rdparty/chromium/third_party/webrtc/modules/video_coding/codecs/h264/h264_decoder_impl.cc qtwebengine-5.15.10/src/3rdparty/chromium/third_party/webrtc/modules/video_coding/codecs/h264/h264_decoder_impl.cc
+--- a/src/3rdparty/chromium/third_party/webrtc/modules/video_coding/codecs/h264/h264_decoder_impl.cc 2022-05-23 06:38:40.000000000 -0500
++++ b/src/3rdparty/chromium/third_party/webrtc/modules/video_coding/codecs/h264/h264_decoder_impl.cc 2022-07-11 22:12:47.918192779 -0500
+@@ -203,7 +203,7 @@ int32_t H264DecoderImpl::InitDecode(cons
+ // a pointer |this|.
+ av_context_->opaque = this;
+
+- AVCodec* codec = avcodec_find_decoder(av_context_->codec_id);
++ const AVCodec* codec = avcodec_find_decoder(av_context_->codec_id);
+ if (!codec) {
+ // This is an indication that FFmpeg has not been initialized or it has not
+ // been compiled/initialized with the correct set of codecs.
diff --git a/srcpkgs/qt5-webengine/template b/srcpkgs/qt5-webengine/template
index 0a71484208bc..095ab67701e4 100644
--- a/srcpkgs/qt5-webengine/template
+++ b/srcpkgs/qt5-webengine/template
@@ -1,9 +1,9 @@
# Template file for 'qt5-webengine'
pkgname=qt5-webengine
-version=5.15.11
-revision=2
+version=5.15.13
+revision=1
_version="${version}-lts"
-_chromium_commit=be349eaf62e77955791d7bf29f893f1e8a37daf4
+_chromium_commit=e48df7803c7c98b0b2471c94057d32e44a301ad5
archs="x86_64* i686* armv[67]* ppc64* aarch64*"
create_wrksrc=yes
build_style=qmake
@@ -32,8 +32,8 @@ license="GPL-3.0-or-later, LGPL-3.0-or-later"
homepage="https://qt.io/"
distfiles="https://github.com/qt/qtwebengine/archive/v${_version}.tar.gz
https://github.com/qt/qtwebengine-chromium/archive/${_chromium_commit}.tar.gz"
-checksum="aa7466356c450c5f5870f979b93cd7e7e62da1165c328ffcab1a9928db18ad67
- 6f47ed8ab8cc062411f6f206da6353bc8263d6ed6d6290c689a05c01d91f646b"
+checksum="4b59838ed75ef788b59e1e412535a0e42dd9d311661fdeadb191b581ba815c63
+ a91686562b1d4e8b220e0bbcbab5feb64630e2de974b35ac034bf388af771a6c"
no_generic_pkgconfig_link=yes
build_options="sndio pipewire"
From 2dcc253c4a271a2b437c6a82fdbef7d98a8894f4 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:51 -0400
Subject: [PATCH 077/110] qt5: update to 5.15.8
---
...erywhere-opensource-src-5.15.8-kf5-1.patch | 12913 ++++++++++++++++
srcpkgs/qt5/template | 12 +-
2 files changed, 12919 insertions(+), 6 deletions(-)
create mode 100644 srcpkgs/qt5/patches/qt-everywhere-opensource-src-5.15.8-kf5-1.patch
diff --git a/srcpkgs/qt5/patches/qt-everywhere-opensource-src-5.15.8-kf5-1.patch b/srcpkgs/qt5/patches/qt-everywhere-opensource-src-5.15.8-kf5-1.patch
new file mode 100644
index 000000000000..966c98bcd3bb
--- /dev/null
+++ b/srcpkgs/qt5/patches/qt-everywhere-opensource-src-5.15.8-kf5-1.patch
@@ -0,0 +1,12913 @@
+Submitted By: Pierre Labastie <pierre_dot_labastie_at_neuf_dot_fr>
+Date: 2023-01-05
+Initial Package Version: 5.15.8
+Upstream Status: Applied (according to KDE)
+Origin: KDE patch set
+Description: Patch set maintained by the KDE folks
+see https://dot.kde.org/2021/04/06/announcing-kdes-qt-5-patch-collection
+Patch generated using the procedure in
+https://wiki.linuxfromscratch.org/blfs/ticket/17476#comment:3
+
+Submodule qtbase 4ee4fc18..9cf586d6:
+diff --git a/qtbase/mkspecs/common/android/qplatformdefs.h b/qtbase/mkspecs/common/android/qplatformdefs.h
+index f75bc4093b..2bd59410d4 100644
+--- a/qtbase/mkspecs/common/android/qplatformdefs.h
++++ b/qtbase/mkspecs/common/android/qplatformdefs.h
+@@ -144,11 +144,7 @@
+ #define QT_SIGNAL_ARGS int
+ #define QT_SIGNAL_IGNORE SIG_IGN
+
+-#if defined(__GLIBC__) && (__GLIBC__ >= 2)
+ #define QT_SOCKLEN_T socklen_t
+-#else
+-#define QT_SOCKLEN_T int
+-#endif
+
+ #if defined(_XOPEN_SOURCE) && (_XOPEN_SOURCE >= 500)
+ #define QT_SNPRINTF ::snprintf
+diff --git a/qtbase/mkspecs/features/mac/sdk.mk b/qtbase/mkspecs/features/mac/sdk.mk
+index f30b5830b4..a32ceacb6c 100644
+--- a/qtbase/mkspecs/features/mac/sdk.mk
++++ b/qtbase/mkspecs/features/mac/sdk.mk
+@@ -1,6 +1,6 @@
+
+ ifeq ($(QT_MAC_SDK_NO_VERSION_CHECK),)
+- CHECK_SDK_COMMAND = /usr/bin/xcrun --sdk $(EXPORT_QMAKE_MAC_SDK) -show-sdk-version 2>&1
++ CHECK_SDK_COMMAND = /usr/bin/xcrun --sdk $(EXPORT_QMAKE_MAC_SDK) -show-sdk-version 2>/dev/null
+ CURRENT_MAC_SDK_VERSION := $(shell DEVELOPER_DIR=$(EXPORT_QMAKE_XCODE_DEVELOPER_PATH) $(CHECK_SDK_COMMAND))
+ ifneq ($(CURRENT_MAC_SDK_VERSION),$(EXPORT_QMAKE_MAC_SDK_VERSION))
+ # We don't want to complain about out of date SDK unless the target needs to be remade.
+diff --git a/qtbase/mkspecs/linux-clang/qplatformdefs.h b/qtbase/mkspecs/linux-clang/qplatformdefs.h
+index a818d973f0..c1ab72fbc6 100644
+--- a/qtbase/mkspecs/linux-clang/qplatformdefs.h
++++ b/qtbase/mkspecs/linux-clang/qplatformdefs.h
+@@ -79,14 +79,6 @@
+ #define QT_USE_XOPEN_LFS_EXTENSIONS
+ #include "../common/posix/qplatformdefs.h"
+
+-#undef QT_SOCKLEN_T
+-
+-#if defined(__GLIBC__) && (__GLIBC__ >= 2)
+-#define QT_SOCKLEN_T socklen_t
+-#else
+-#define QT_SOCKLEN_T int
+-#endif
+-
+ #if defined(_XOPEN_SOURCE) && (_XOPEN_SOURCE >= 500)
+ #define QT_SNPRINTF ::snprintf
+ #define QT_VSNPRINTF ::vsnprintf
+diff --git a/qtbase/mkspecs/linux-g++/qplatformdefs.h b/qtbase/mkspecs/linux-g++/qplatformdefs.h
+index 13523f0702..4d2750d9ec 100644
+--- a/qtbase/mkspecs/linux-g++/qplatformdefs.h
++++ b/qtbase/mkspecs/linux-g++/qplatformdefs.h
+@@ -79,14 +79,6 @@
+ #define QT_USE_XOPEN_LFS_EXTENSIONS
+ #include "../common/posix/qplatformdefs.h"
+
+-#undef QT_SOCKLEN_T
+-
+-#if defined(__GLIBC__) && (__GLIBC__ < 2)
+-#define QT_SOCKLEN_T int
+-#else
+-#define QT_SOCKLEN_T socklen_t
+-#endif
+-
+ #if defined(_XOPEN_SOURCE) && (_XOPEN_SOURCE >= 500)
+ #define QT_SNPRINTF ::snprintf
+ #define QT_VSNPRINTF ::vsnprintf
+diff --git a/qtbase/mkspecs/linux-llvm/qplatformdefs.h b/qtbase/mkspecs/linux-llvm/qplatformdefs.h
+index dc750ab1ef..d3cc39b47f 100644
+--- a/qtbase/mkspecs/linux-llvm/qplatformdefs.h
++++ b/qtbase/mkspecs/linux-llvm/qplatformdefs.h
+@@ -80,14 +80,6 @@
+ #define QT_USE_XOPEN_LFS_EXTENSIONS
+ #include "../common/posix/qplatformdefs.h"
+
+-#undef QT_SOCKLEN_T
+-
+-#if defined(__GLIBC__) && (__GLIBC__ >= 2)
+-#define QT_SOCKLEN_T socklen_t
+-#else
+-#define QT_SOCKLEN_T int
+-#endif
+-
+ #if defined(_XOPEN_SOURCE) && (_XOPEN_SOURCE >= 500)
+ #define QT_SNPRINTF ::snprintf
+ #define QT_VSNPRINTF ::vsnprintf
+diff --git a/qtbase/mkspecs/linux-lsb-g++/qplatformdefs.h b/qtbase/mkspecs/linux-lsb-g++/qplatformdefs.h
+index 4c4e53da2a..83baffb3e3 100644
+--- a/qtbase/mkspecs/linux-lsb-g++/qplatformdefs.h
++++ b/qtbase/mkspecs/linux-lsb-g++/qplatformdefs.h
+@@ -85,16 +85,9 @@
+ #include "../common/posix/qplatformdefs.h"
+
+ #undef QT_OPEN_LARGEFILE
+-#undef QT_SOCKLEN_T
+
+ #define QT_OPEN_LARGEFILE 0
+
+-#if defined(__GLIBC__) && (__GLIBC__ >= 2)
+-#define QT_SOCKLEN_T socklen_t
+-#else
+-#define QT_SOCKLEN_T int
+-#endif
+-
+ #ifndef SIOCGIFBRDADDR
+ # define SIOCGIFBRDADDR 0x8919
+ #endif
+diff --git a/qtbase/mkspecs/lynxos-g++/qplatformdefs.h b/qtbase/mkspecs/lynxos-g++/qplatformdefs.h
+index 4339ea2b23..6007af0055 100644
+--- a/qtbase/mkspecs/lynxos-g++/qplatformdefs.h
++++ b/qtbase/mkspecs/lynxos-g++/qplatformdefs.h
+@@ -72,14 +72,6 @@
+
+ #include "../common/posix/qplatformdefs.h"
+
+-#undef QT_SOCKLEN_T
+-
+-#if defined(__GLIBC__) && (__GLIBC__ >= 2)
+-#define QT_SOCKLEN_T socklen_t
+-#else
+-#define QT_SOCKLEN_T int
+-#endif
+-
+ #if defined(_XOPEN_SOURCE) && (_XOPEN_SOURCE >= 500)
+ #define QT_SNPRINTF ::snprintf
+ #define QT_VSNPRINTF ::vsnprintf
+diff --git a/qtbase/src/3rdparty/angle/src/libANGLE/HandleAllocator.cpp b/qtbase/src/3rdparty/angle/src/libANGLE/HandleAllocator.cpp
+index c3c184258f..32af3f8f29 100644
+--- a/qtbase/src/3rdparty/angle/src/libANGLE/HandleAllocator.cpp
++++ b/qtbase/src/3rdparty/angle/src/libANGLE/HandleAllocator.cpp
+@@ -10,6 +10,7 @@
+ #include "libANGLE/HandleAllocator.h"
+
+ #include <algorithm>
++#include <limits>
+
+ #include "common/debug.h"
+
+diff --git a/qtbase/src/3rdparty/forkfd/forkfd_linux.c b/qtbase/src/3rdparty/forkfd/forkfd_linux.c
+index ffe0e9a5e2..b1f5408d11 100644
+--- a/qtbase/src/3rdparty/forkfd/forkfd_linux.c
++++ b/qtbase/src/3rdparty/forkfd/forkfd_linux.c
+@@ -82,7 +82,8 @@ static int sys_clone(unsigned long cloneflags, int *ptid)
+ return syscall(__NR_clone, cloneflags, child_stack, stack_size, ptid, newtls, ctid);
+ #elif defined(__arc__) || defined(__arm__) || defined(__aarch64__) || defined(__mips__) || \
+ defined(__nds32__) || defined(__hppa__) || defined(__powerpc__) || defined(__i386__) || \
+- defined(__x86_64__) || defined(__xtensa__) || defined(__alpha__) || defined(__riscv)
++ defined(__x86_64__) || defined(__xtensa__) || defined(__alpha__) || defined(__riscv) || \
++ defined(__loongarch__)
+ /* ctid and newtls are inverted on CONFIG_CLONE_BACKWARDS architectures,
+ * but since both values are 0, there's no harm. */
+ return syscall(__NR_clone, cloneflags, child_stack, ptid, ctid, newtls);
+diff --git a/qtbase/src/android/jar/src/org/qtproject/qt5/android/QtNative.java b/qtbase/src/android/jar/src/org/qtproject/qt5/android/QtNative.java
+index 5792b5b2f5..2f74750fcf 100644
+--- a/qtbase/src/android/jar/src/org/qtproject/qt5/android/QtNative.java
++++ b/qtbase/src/android/jar/src/org/qtproject/qt5/android/QtNative.java
+@@ -116,6 +116,7 @@ public class QtNative
+ public static QtThread m_qtThread = new QtThread();
+ private static HashMap<String, Uri> m_cachedUris = new HashMap<String, Uri>();
+ private static ArrayList<String> m_knownDirs = new ArrayList<String>();
++ private static final String NoPermissionErrorMessage = "No permissions to open Uri";
+
+ private static final Runnable runPendingCppRunnablesRunnable = new Runnable() {
+ @Override
+@@ -193,11 +194,10 @@ public class QtNative
+ return iterUri;
+ }
+
+- // Android 6 and earlier could still manage to open the file so we can return the
+- // parsed uri here
+- if (Build.VERSION.SDK_INT < 24)
+- return parsedUri;
+- return null;
++ // if we only have transient permissions on uri all the above will fail,
++ // but we will be able to read the file anyway, so continue with uri here anyway
++ // and check for SecurityExceptions later
++ return parsedUri;
+ } catch (SecurityException e) {
+ e.printStackTrace();
+ return null;
+@@ -244,7 +244,7 @@ public class QtNative
+ int error = -1;
+
+ if (uri == null) {
+- Log.e(QtTAG, "openFdForContentUrl(): No permissions to open Uri");
++ Log.e(QtTAG, "openFdForContentUrl(): " + NoPermissionErrorMessage);
+ return error;
+ }
+
+@@ -254,12 +254,13 @@ public class QtNative
+ return fdDesc.detachFd();
+ } catch (FileNotFoundException e) {
+ e.printStackTrace();
+- return error;
+ } catch (IllegalArgumentException e) {
+ Log.e(QtTAG, "openFdForContentUrl(): Invalid Uri");
+ e.printStackTrace();
+- return error;
++ } catch (SecurityException e) {
++ Log.e(QtTAG, NoPermissionErrorMessage);
+ }
++ return error;
+ }
+
+ public static long getSize(Context context, String contentUrl)
+@@ -270,7 +271,7 @@ public class QtNative
+ uri = getUriWithValidPermission(context, contentUrl, "r");
+
+ if (uri == null) {
+- Log.e(QtTAG, "getSize(): No permissions to open Uri");
++ Log.e(QtTAG, NoPermissionErrorMessage);
+ return size;
+ } else if (!m_cachedUris.containsKey(contentUrl)) {
+ m_cachedUris.put(contentUrl, uri);
+@@ -288,12 +289,13 @@ public class QtNative
+ } catch (IllegalArgumentException e) {
+ Log.e(QtTAG, "getSize(): Invalid Uri");
+ e.printStackTrace();
+- return size;
+ } catch (UnsupportedOperationException e) {
+ Log.e(QtTAG, "getSize(): Unsupported operation for given Uri");
+ e.printStackTrace();
+- return size;
++ } catch (SecurityException e) {
++ Log.e(QtTAG, NoPermissionErrorMessage);
+ }
++ return size;
+ }
+
+ public static boolean checkFileExists(Context context, String contentUrl)
+@@ -303,7 +305,7 @@ public class QtNative
+ if (uri == null)
+ uri = getUriWithValidPermission(context, contentUrl, "r");
+ if (uri == null) {
+- Log.e(QtTAG, "checkFileExists(): No permissions to open Uri");
++ Log.e(QtTAG, NoPermissionErrorMessage);
+ return exists;
+ } else {
+ if (!m_cachedUris.containsKey(contentUrl))
+@@ -321,12 +323,13 @@ public class QtNative
+ } catch (IllegalArgumentException e) {
+ Log.e(QtTAG, "checkFileExists(): Invalid Uri");
+ e.printStackTrace();
+- return exists;
+ } catch (UnsupportedOperationException e) {
+ Log.e(QtTAG, "checkFileExists(): Unsupported operation for given Uri");
+ e.printStackTrace();
+- return false;
++ } catch (SecurityException e) {
++ Log.e(QtTAG, NoPermissionErrorMessage);
+ }
++ return exists;
+ }
+
+ public static boolean checkIfWritable(Context context, String contentUrl)
+@@ -344,7 +347,7 @@ public class QtNative
+ uri = getUriWithValidPermission(context, contentUrl, "r");
+ }
+ if (uri == null) {
+- Log.e(QtTAG, "isDir(): No permissions to open Uri");
++ Log.e(QtTAG, NoPermissionErrorMessage);
+ return isDir;
+ } else {
+ if (!m_cachedUris.containsKey(contentUrl))
+@@ -374,12 +377,13 @@ public class QtNative
+ } catch (IllegalArgumentException e) {
+ Log.e(QtTAG, "checkIfDir(): Invalid Uri");
+ e.printStackTrace();
+- return false;
+ } catch (UnsupportedOperationException e) {
+ Log.e(QtTAG, "checkIfDir(): Unsupported operation for given Uri");
+ e.printStackTrace();
+- return false;
++ } catch (SecurityException e) {
++ Log.e(QtTAG, NoPermissionErrorMessage);
+ }
++ return false;
+ }
+ public static String[] listContentsFromTreeUri(Context context, String contentUrl)
+ {
+diff --git a/qtbase/src/concurrent/qtconcurrentreducekernel.h b/qtbase/src/concurrent/qtconcurrentreducekernel.h
+index 8f9a938952..a98dedef2e 100644
+--- a/qtbase/src/concurrent/qtconcurrentreducekernel.h
++++ b/qtbase/src/concurrent/qtconcurrentreducekernel.h
+@@ -212,11 +212,13 @@ public:
+
+ inline bool shouldThrottle()
+ {
++ std::lock_guard<QMutex> locker(mutex);
+ return (resultsMapSize > (ReduceQueueThrottleLimit * threadCount));
+ }
+
+ inline bool shouldStartThread()
+ {
++ std::lock_guard<QMutex> locker(mutex);
+ return (resultsMapSize <= (ReduceQueueStartLimit * threadCount));
+ }
+ };
+diff --git a/qtbase/src/concurrent/qtconcurrentthreadengine.cpp b/qtbase/src/concurrent/qtconcurrentthreadengine.cpp
+index ea6ce3ac42..7f91a2ba68 100644
+--- a/qtbase/src/concurrent/qtconcurrentthreadengine.cpp
++++ b/qtbase/src/concurrent/qtconcurrentthreadengine.cpp
+@@ -176,6 +176,39 @@ void ThreadEngineBase::startSingleThreaded()
+ finish();
+ }
+
++void ThreadEngineBase::startBlocking()
++{
++ start();
++ barrier.acquire();
++ startThreads();
++
++ bool throttled = false;
++#ifndef QT_NO_EXCEPTIONS
++ try {
++#endif
++ while (threadFunction() == ThrottleThread) {
++ if (threadThrottleExit()) {
++ throttled = true;
++ break;
++ }
++ }
++#ifndef QT_NO_EXCEPTIONS
++ } catch (QException &e) {
++ handleException(e);
++ } catch (...) {
++ handleException(QUnhandledException());
++ }
++#endif
++
++ if (throttled == false) {
++ barrier.release();
++ }
++
++ barrier.wait();
++ finish();
++ exceptionStore.throwPossibleException();
++}
++
+ void ThreadEngineBase::startThread()
+ {
+ startThreadInternal();
+diff --git a/qtbase/src/concurrent/qtconcurrentthreadengine.h b/qtbase/src/concurrent/qtconcurrentthreadengine.h
+index 7c30cebdbc..a4c8548cc4 100644
+--- a/qtbase/src/concurrent/qtconcurrentthreadengine.h
++++ b/qtbase/src/concurrent/qtconcurrentthreadengine.h
+@@ -91,6 +91,7 @@ public:
+ ThreadEngineBase();
+ virtual ~ThreadEngineBase();
+ void startSingleThreaded();
++ void startBlocking();
+ void startThread();
+ bool isCanceled();
+ void waitForResume();
+@@ -143,6 +144,15 @@ public:
+ return result();
+ }
+
++ // Runs the user algorithm using multiple threads.
++ // This function blocks until the algorithm is finished,
++ // and then returns the result.
++ T *startBlocking()
++ {
++ ThreadEngineBase::startBlocking();
++ return result();
++ }
++
+ // Runs the user algorithm using multiple threads.
+ // Does not block, returns a future.
+ QFuture<T> startAsynchronously()
+@@ -223,6 +233,13 @@ class ThreadEngineStarter : public ThreadEngineStarterBase<T>
+ public:
+ ThreadEngineStarter(TypedThreadEngine *eng)
+ : Base(eng) { }
++
++ T startBlocking()
++ {
++ T t = *this->threadEngine->startBlocking();
++ delete this->threadEngine;
++ return t;
++ }
+ };
+
+ // Full template specialization where T is void.
+@@ -232,6 +249,12 @@ class ThreadEngineStarter<void> : public ThreadEngineStarterBase<void>
+ public:
+ ThreadEngineStarter(ThreadEngine<void> *_threadEngine)
+ : ThreadEngineStarterBase<void>(_threadEngine) {}
++
++ void startBlocking()
++ {
++ this->threadEngine->startBlocking();
++ delete this->threadEngine;
++ }
+ };
+
+ //! [qtconcurrentthreadengine-1]
+diff --git a/qtbase/src/corelib/animation/qvariantanimation.cpp b/qtbase/src/corelib/animation/qvariantanimation.cpp
+index 98b02f0202..eac1524107 100644
+--- a/qtbase/src/corelib/animation/qvariantanimation.cpp
++++ b/qtbase/src/corelib/animation/qvariantanimation.cpp
+@@ -276,7 +276,9 @@ void QVariantAnimationPrivate::setCurrentValueForProgress(const qreal progress)
+
+ const qreal startProgress = currentInterval.start.first;
+ const qreal endProgress = currentInterval.end.first;
+- const qreal localProgress = (progress - startProgress) / (endProgress - startProgress);
++ const qreal localProgress =
++ qIsNull(progress - startProgress) ? 0.0 // avoid 0/0 below
++ /* else */ : (progress - startProgress) / (endProgress - startProgress);
+
+ QVariant ret = q->interpolated(currentInterval.start.second,
+ currentInterval.end.second,
+diff --git a/qtbase/src/corelib/global/qnamespace.h b/qtbase/src/corelib/global/qnamespace.h
+index ad4150b317..bf19b1627b 100644
+--- a/qtbase/src/corelib/global/qnamespace.h
++++ b/qtbase/src/corelib/global/qnamespace.h
+@@ -1864,7 +1864,7 @@ public:
+ QT_Q_ENUM(TimerType)
+ QT_Q_ENUM(ScrollPhase)
+ QT_Q_ENUM(MouseEventSource)
+- QT_Q_FLAG(MouseEventFlag)
++ QT_Q_FLAG(MouseEventFlags)
+ QT_Q_ENUM(ChecksumType)
+ QT_Q_ENUM(HighDpiScaleFactorRoundingPolicy)
+ QT_Q_ENUM(TabFocusBehavior)
+diff --git a/qtbase/src/corelib/global/qrandom.cpp b/qtbase/src/corelib/global/qrandom.cpp
+index 10672c1f92..25f87c7e6a 100644
+--- a/qtbase/src/corelib/global/qrandom.cpp
++++ b/qtbase/src/corelib/global/qrandom.cpp
+@@ -383,7 +383,6 @@ struct QRandomGenerator::SystemAndGlobalGenerators
+
+ constexpr SystemAndGlobalGenerators g = {};
+ Q_UNUSED(g);
+- Q_STATIC_ASSERT(std::is_literal_type<SystemAndGlobalGenerators>::value);
+ #endif
+ }
+
+diff --git a/qtbase/src/corelib/io/qbuffer.cpp b/qtbase/src/corelib/io/qbuffer.cpp
+index 595fcd2724..032c0ddd4b 100644
+--- a/qtbase/src/corelib/io/qbuffer.cpp
++++ b/qtbase/src/corelib/io/qbuffer.cpp
+@@ -41,6 +41,8 @@
+ #include <QtCore/qmetaobject.h>
+ #include "private/qiodevice_p.h"
+
++#include <limits>
++
+ QT_BEGIN_NAMESPACE
+
+ /** QBufferPrivate **/
+@@ -366,7 +368,9 @@ qint64 QBuffer::size() const
+ bool QBuffer::seek(qint64 pos)
+ {
+ Q_D(QBuffer);
+- if (pos > d->buf->size() && isWritable()) {
++ const auto oldBufSize = d->buf->size();
++ constexpr qint64 MaxSeekPos = (std::numeric_limits<decltype(oldBufSize)>::max)();
++ if (pos <= MaxSeekPos && pos > oldBufSize && isWritable()) {
+ if (seek(d->buf->size())) {
+ const qint64 gapSize = pos - d->buf->size();
+ if (write(QByteArray(gapSize, 0)) != gapSize) {
+@@ -377,7 +381,7 @@ bool QBuffer::seek(qint64 pos)
+ return false;
+ }
+ } else if (pos > d->buf->size() || pos < 0) {
+- qWarning("QBuffer::seek: Invalid pos: %d", int(pos));
++ qWarning("QBuffer::seek: Invalid pos: %lld", pos);
+ return false;
+ }
+ return QIODevice::seek(pos);
+diff --git a/qtbase/src/corelib/io/qfilesystemengine_win.cpp b/qtbase/src/corelib/io/qfilesystemengine_win.cpp
+index 81d3a71986..c86ed1f9b0 100644
+--- a/qtbase/src/corelib/io/qfilesystemengine_win.cpp
++++ b/qtbase/src/corelib/io/qfilesystemengine_win.cpp
+@@ -664,14 +664,14 @@ QFileSystemEntry QFileSystemEngine::absoluteName(const QFileSystemEntry &entry)
+ return QFileSystemEntry(ret, QFileSystemEntry::FromInternalPath());
+ }
+
+-#if defined(Q_CC_MINGW) && WINVER < 0x0602 // Windows 8 onwards
++#if defined(Q_CC_MINGW) && WINVER < 0x0602 && _WIN32_WINNT < _WIN32_WINNT_WIN8 // Windows 8 onwards
+
+ typedef struct _FILE_ID_INFO {
+ ULONGLONG VolumeSerialNumber;
+ FILE_ID_128 FileId;
+ } FILE_ID_INFO, *PFILE_ID_INFO;
+
+-#endif // if defined (Q_CC_MINGW) && WINVER < 0x0602
++#endif // if defined(Q_CC_MINGW) && WINVER < 0x0602 && _WIN32_WINNT < _WIN32_WINNT_WIN8
+
+ // File ID for Windows up to version 7 and FAT32 drives
+ static inline QByteArray fileId(HANDLE handle)
+diff --git a/qtbase/src/corelib/io/qfilesystemwatcher_inotify.cpp b/qtbase/src/corelib/io/qfilesystemwatcher_inotify.cpp
+index 94d9d06bcb..27e0b13b0b 100644
+--- a/qtbase/src/corelib/io/qfilesystemwatcher_inotify.cpp
++++ b/qtbase/src/corelib/io/qfilesystemwatcher_inotify.cpp
+@@ -366,7 +366,9 @@ void QInotifyFileSystemWatcherEngine::readFromInotify()
+ // qDebug("QInotifyFileSystemWatcherEngine::readFromInotify");
+
+ int buffSize = 0;
+- ioctl(inotifyFd, FIONREAD, (char *) &buffSize);
++ if (ioctl(inotifyFd, FIONREAD, (char *) &buffSize) == -1 || buffSize == 0)
++ return;
++
+ QVarLengthArray<char, 4096> buffer(buffSize);
+ buffSize = read(inotifyFd, buffer.data(), buffSize);
+ char *at = buffer.data();
+diff --git a/qtbase/src/corelib/io/qlockfile_win.cpp b/qtbase/src/corelib/io/qlockfile_win.cpp
+index 277f8d4230..38ecef5550 100644
+--- a/qtbase/src/corelib/io/qlockfile_win.cpp
++++ b/qtbase/src/corelib/io/qlockfile_win.cpp
+@@ -48,6 +48,8 @@
+ #include "QtCore/qdebug.h"
+ #include "QtCore/qthread.h"
+
++#include "private/qsystemlibrary_p.h"
++
+ QT_BEGIN_NAMESPACE
+
+ static inline bool fileExists(const wchar_t *fileName)
+@@ -150,7 +152,7 @@ QString QLockFilePrivate::processNameByPid(qint64 pid)
+ #if !defined(Q_OS_WINRT)
+ typedef DWORD (WINAPI *GetModuleFileNameExFunc)(HANDLE, HMODULE, LPTSTR, DWORD);
+
+- HMODULE hPsapi = LoadLibraryA("psapi");
++ HMODULE hPsapi = QSystemLibrary::load(L"psapi");
+ if (!hPsapi)
+ return QString();
+ GetModuleFileNameExFunc qGetModuleFileNameEx = reinterpret_cast<GetModuleFileNameExFunc>(
+diff --git a/qtbase/src/corelib/io/qprocess_unix.cpp b/qtbase/src/corelib/io/qprocess_unix.cpp
+index 50390e57f5..15c8f30745 100644
+--- a/qtbase/src/corelib/io/qprocess_unix.cpp
++++ b/qtbase/src/corelib/io/qprocess_unix.cpp
+@@ -1,7 +1,7 @@
+ /****************************************************************************
+ **
+ ** Copyright (C) 2016 The Qt Company Ltd.
+-** Copyright (C) 2016 Intel Corporation.
++** Copyright (C) 2022 Intel Corporation.
+ ** Contact: https://www.qt.io/licensing/
+ **
+ ** This file is part of the QtCore module of the Qt Toolkit.
+@@ -422,14 +422,15 @@ void QProcessPrivate::startProcess()
+ // Add the program name to the argument list.
+ argv[0] = nullptr;
+ if (!program.contains(QLatin1Char('/'))) {
++ // findExecutable() returns its argument if it's an absolute path,
++ // otherwise it searches $PATH; returns empty if not found (we handle
++ // that case much later)
+ const QString &exeFilePath = QStandardPaths::findExecutable(program);
+- if (!exeFilePath.isEmpty()) {
+- const QByteArray &tmp = QFile::encodeName(exeFilePath);
+- argv[0] = ::strdup(tmp.constData());
+- }
+- }
+- if (!argv[0])
++ const QByteArray &tmp = QFile::encodeName(exeFilePath);
++ argv[0] = ::strdup(tmp.constData());
++ } else {
+ argv[0] = ::strdup(encodedProgramName.constData());
++ }
+
+ // Add every argument to the list
+ for (int i = 0; i < arguments.count(); ++i)
+@@ -983,15 +984,16 @@ bool QProcessPrivate::startDetached(qint64 *pid)
+ envp = _q_dupEnvironment(environment.d.constData()->vars, &envc);
+ }
+
+- QByteArray tmp;
+ if (!program.contains(QLatin1Char('/'))) {
++ // findExecutable() returns its argument if it's an absolute path,
++ // otherwise it searches $PATH; returns empty if not found (we handle
++ // that case much later)
+ const QString &exeFilePath = QStandardPaths::findExecutable(program);
+- if (!exeFilePath.isEmpty())
+- tmp = QFile::encodeName(exeFilePath);
++ const QByteArray &tmp = QFile::encodeName(exeFilePath);
++ argv[0] = ::strdup(tmp.constData());
++ } else {
++ argv[0] = ::strdup(QFile::encodeName(program));
+ }
+- if (tmp.isEmpty())
+- tmp = QFile::encodeName(program);
+- argv[0] = tmp.data();
+
+ if (envp)
+ qt_safe_execve(argv[0], argv, envp);
+diff --git a/qtbase/src/corelib/itemmodels/qabstractitemmodel.cpp b/qtbase/src/corelib/itemmodels/qabstractitemmodel.cpp
+index 3a79c502af..997a634e76 100644
+--- a/qtbase/src/corelib/itemmodels/qabstractitemmodel.cpp
++++ b/qtbase/src/corelib/itemmodels/qabstractitemmodel.cpp
+@@ -3196,9 +3196,8 @@ bool QAbstractItemModel::beginMoveColumns(const QModelIndex &sourceParent, int s
+ destinationChange.needsAdjust = destinationParent.isValid() && destinationParent.row() >= sourceLast && destinationParent.parent() == sourceParent;
+ d->changes.push(destinationChange);
+
+- d->itemsAboutToBeMoved(sourceParent, sourceFirst, sourceLast, destinationParent, destinationChild, Qt::Horizontal);
+-
+ emit columnsAboutToBeMoved(sourceParent, sourceFirst, sourceLast, destinationParent, destinationChild, QPrivateSignal());
++ d->itemsAboutToBeMoved(sourceParent, sourceFirst, sourceLast, destinationParent, destinationChild, Qt::Horizontal);
+ return true;
+ }
+
+@@ -3231,7 +3230,6 @@ void QAbstractItemModel::endMoveColumns()
+ adjustedSource = createIndex(adjustedSource.row(), adjustedSource.column() + numMoved, adjustedSource.internalPointer());
+
+ d->itemsMoved(adjustedSource, removeChange.first, removeChange.last, adjustedDestination, insertChange.first, Qt::Horizontal);
+-
+ emit columnsMoved(adjustedSource, removeChange.first, removeChange.last, adjustedDestination, insertChange.first, QPrivateSignal());
+ }
+
+diff --git a/qtbase/src/corelib/itemmodels/qsortfilterproxymodel.cpp b/qtbase/src/corelib/itemmodels/qsortfilterproxymodel.cpp
+index dc6379d9fb..c5e287ee84 100644
+--- a/qtbase/src/corelib/itemmodels/qsortfilterproxymodel.cpp
++++ b/qtbase/src/corelib/itemmodels/qsortfilterproxymodel.cpp
+@@ -939,8 +939,9 @@ void QSortFilterProxyModelPrivate::insert_source_items(
+ q->beginInsertColumns(proxy_parent, proxy_start, proxy_end);
+ }
+
+- for (int i = 0; i < source_items.size(); ++i)
+- proxy_to_source.insert(proxy_start + i, source_items.at(i));
++ // TODO: use the range QList::insert() overload once it is implemented (QTBUG-58633).
++ proxy_to_source.insert(proxy_start, source_items.size(), 0);
++ std::copy(source_items.cbegin(), source_items.cend(), proxy_to_source.begin() + proxy_start);
+
+ build_source_to_proxy_mapping(proxy_to_source, source_to_proxy);
+
+@@ -3123,8 +3124,9 @@ bool QSortFilterProxyModel::filterAcceptsRow(int source_row, const QModelIndex &
+
+ if (d->filter_data.isEmpty())
+ return true;
++
++ int column_count = d->model->columnCount(source_parent);
+ if (d->filter_column == -1) {
+- int column_count = d->model->columnCount(source_parent);
+ for (int column = 0; column < column_count; ++column) {
+ QModelIndex source_index = d->model->index(source_row, column, source_parent);
+ QString key = d->model->data(source_index, d->filter_role).toString();
+@@ -3133,9 +3135,10 @@ bool QSortFilterProxyModel::filterAcceptsRow(int source_row, const QModelIndex &
+ }
+ return false;
+ }
+- QModelIndex source_index = d->model->index(source_row, d->filter_column, source_parent);
+- if (!source_index.isValid()) // the column may not exist
++
++ if (d->filter_column >= column_count) // the column may not exist
+ return true;
++ QModelIndex source_index = d->model->index(source_row, d->filter_column, source_parent);
+ QString key = d->model->data(source_index, d->filter_role).toString();
+ return d->filter_data.hasMatch(key);
+ }
+diff --git a/qtbase/src/corelib/kernel/qcoreapplication.cpp b/qtbase/src/corelib/kernel/qcoreapplication.cpp
+index ca2864df83..132b2eae52 100644
+--- a/qtbase/src/corelib/kernel/qcoreapplication.cpp
++++ b/qtbase/src/corelib/kernel/qcoreapplication.cpp
+@@ -1157,7 +1157,7 @@ static bool doNotify(QObject *receiver, QEvent *event)
+ bool QCoreApplicationPrivate::sendThroughApplicationEventFilters(QObject *receiver, QEvent *event)
+ {
+ // We can't access the application event filters outside of the main thread (race conditions)
+- Q_ASSERT(receiver->d_func()->threadData.loadRelaxed()->thread.loadAcquire() == mainThread());
++ Q_ASSERT(receiver->d_func()->threadData.loadAcquire()->thread.loadRelaxed() == mainThread());
+
+ if (extraData) {
+ // application event filters are only called for objects in the GUI thread
+diff --git a/qtbase/src/corelib/kernel/qobject.cpp b/qtbase/src/corelib/kernel/qobject.cpp
+index 1eb79138d9..36cd780ee1 100644
+--- a/qtbase/src/corelib/kernel/qobject.cpp
++++ b/qtbase/src/corelib/kernel/qobject.cpp
+@@ -1010,7 +1010,7 @@ QObject::~QObject()
+ emit destroyed(this);
+ }
+
+- if (d->declarativeData) {
++ if (!d->isDeletingChildren && d->declarativeData) {
+ if (static_cast<QAbstractDeclarativeDataImpl*>(d->declarativeData)->ownedByQml1) {
+ if (QAbstractDeclarativeData::destroyed_qml1)
+ QAbstractDeclarativeData::destroyed_qml1(d->declarativeData, this);
+@@ -1580,7 +1580,7 @@ void QObject::moveToThread(QThread *targetThread)
+
+ QThreadData *currentData = QThreadData::current();
+ QThreadData *targetData = targetThread ? QThreadData::get2(targetThread) : nullptr;
+- QThreadData *thisThreadData = d->threadData.loadRelaxed();
++ QThreadData *thisThreadData = d->threadData.loadAcquire();
+ if (!thisThreadData->thread.loadAcquire() && currentData == targetData) {
+ // one exception to the rule: we allow moving objects with no thread affinity to the current thread
+ currentData = d->threadData;
+@@ -2620,7 +2620,7 @@ int QObject::receivers(const char *signal) const
+ if (!d->isSignalConnected(signal_index))
+ return receivers;
+
+- if (d->declarativeData && QAbstractDeclarativeData::receivers) {
++ if (!d->isDeletingChildren && d->declarativeData && QAbstractDeclarativeData::receivers) {
+ receivers += QAbstractDeclarativeData::receivers(d->declarativeData, this,
+ signal_index);
+ }
+diff --git a/qtbase/src/corelib/kernel/qobject_p.h b/qtbase/src/corelib/kernel/qobject_p.h
+index 0b827a52ca..13ffb88999 100644
+--- a/qtbase/src/corelib/kernel/qobject_p.h
++++ b/qtbase/src/corelib/kernel/qobject_p.h
+@@ -444,7 +444,7 @@ inline void QObjectPrivate::checkForIncompatibleLibraryVersion(int version) cons
+
+ inline bool QObjectPrivate::isDeclarativeSignalConnected(uint signal_index) const
+ {
+- return declarativeData && QAbstractDeclarativeData::isSignalConnected
++ return !isDeletingChildren && declarativeData && QAbstractDeclarativeData::isSignalConnected
+ && QAbstractDeclarativeData::isSignalConnected(declarativeData, q_func(), signal_index);
+ }
+
+diff --git a/qtbase/src/corelib/kernel/qtranslator.cpp b/qtbase/src/corelib/kernel/qtranslator.cpp
+index 2812ffb7ea..bc0177c5ec 100644
+--- a/qtbase/src/corelib/kernel/qtranslator.cpp
++++ b/qtbase/src/corelib/kernel/qtranslator.cpp
+@@ -902,7 +902,7 @@ static QString getMessage(const uchar *m, const uchar *end, const char *context,
+ goto end;
+ case Tag_Translation: {
+ int len = read32(m);
+- if (len % 1)
++ if (len & 1)
+ return QString();
+ m += 4;
+ if (!numerus--) {
+diff --git a/qtbase/src/corelib/mimetypes/qmimedatabase.cpp b/qtbase/src/corelib/mimetypes/qmimedatabase.cpp
+index 9de22cef33..ff868a3268 100644
+--- a/qtbase/src/corelib/mimetypes/qmimedatabase.cpp
++++ b/qtbase/src/corelib/mimetypes/qmimedatabase.cpp
+@@ -389,20 +389,23 @@ QMimeType QMimeDatabasePrivate::mimeTypeForFileNameAndData(const QString &fileNa
+ // Disambiguate conflicting extensions (if magic matching found something)
+ if (candidateByData.isValid() && magicAccuracy > 0) {
+ const QString sniffedMime = candidateByData.name();
+- // If the sniffedMime matches a glob match, use it
++ // If the sniffedMime matches a highest-weight glob match, use it
+ if (candidatesByName.m_matchingMimeTypes.contains(sniffedMime)) {
+ *accuracyPtr = 100;
+ return candidateByData;
+ }
+- for (const QString &m : qAsConst(candidatesByName.m_matchingMimeTypes)) {
++ for (const QString &m : qAsConst(candidatesByName.m_allMatchingMimeTypes)) {
+ if (inherits(m, sniffedMime)) {
+ // We have magic + pattern pointing to this, so it's a pretty good match
+ *accuracyPtr = 100;
+ return mimeTypeForName(m);
+ }
+ }
+- *accuracyPtr = magicAccuracy;
+- return candidateByData;
++ if (candidatesByName.m_allMatchingMimeTypes.isEmpty()) {
++ // No glob, use magic
++ *accuracyPtr = magicAccuracy;
++ return candidateByData;
++ }
+ }
+ }
+
+diff --git a/qtbase/src/corelib/mimetypes/qmimeglobpattern.cpp b/qtbase/src/corelib/mimetypes/qmimeglobpattern.cpp
+index a81112d227..fa8f4c545d 100644
+--- a/qtbase/src/corelib/mimetypes/qmimeglobpattern.cpp
++++ b/qtbase/src/corelib/mimetypes/qmimeglobpattern.cpp
+@@ -83,7 +83,10 @@ void QMimeGlobMatchResult::addMatch(const QString &mimeType, int weight, const Q
+ }
+ if (!m_matchingMimeTypes.contains(mimeType)) {
+ m_matchingMimeTypes.append(mimeType);
+- m_allMatchingMimeTypes.append(mimeType);
++ if (replace)
++ m_allMatchingMimeTypes.prepend(mimeType); // highest-weight first
++ else
++ m_allMatchingMimeTypes.append(mimeType);
+ m_knownSuffixLength = knownSuffixLength;
+ }
+ }
+@@ -94,7 +97,7 @@ QMimeGlobPattern::PatternType QMimeGlobPattern::detectPatternType(const QString
+ if (!patternLength)
+ return OtherPattern;
+
+- const bool starCount = pattern.count(QLatin1Char('*')) == 1;
++ const int starCount = pattern.count(QLatin1Char('*'));
+ const bool hasSquareBracket = pattern.indexOf(QLatin1Char('[')) != -1;
+ const bool hasQuestionMark = pattern.indexOf(QLatin1Char('?')) != -1;
+
+@@ -106,10 +109,10 @@ QMimeGlobPattern::PatternType QMimeGlobPattern::detectPatternType(const QString
+ // Patterns like "README*" (well this is currently the only one like that...)
+ if (pattern.at(patternLength - 1) == QLatin1Char('*'))
+ return PrefixPattern;
+- }
+- // Names without any wildcards like "README"
+- if (starCount == 0)
++ } else if (starCount == 0) {
++ // Names without any wildcards like "README"
+ return LiteralPattern;
++ }
+ }
+
+ if (pattern == QLatin1String("[0-9][0-9][0-9].vdr"))
+diff --git a/qtbase/src/corelib/mimetypes/qmimeprovider.cpp b/qtbase/src/corelib/mimetypes/qmimeprovider.cpp
+index 258dddf8cb..4642d0f2d0 100644
+--- a/qtbase/src/corelib/mimetypes/qmimeprovider.cpp
++++ b/qtbase/src/corelib/mimetypes/qmimeprovider.cpp
+@@ -244,15 +244,18 @@ void QMimeBinaryProvider::addFileNameMatches(const QString &fileName, QMimeGlobM
+ const QString lowerFileName = fileName.toLower();
+ // Check literals (e.g. "Makefile")
+ matchGlobList(result, m_cacheFile, m_cacheFile->getUint32(PosLiteralListOffset), fileName);
+- // Check complex globs (e.g. "callgrind.out[0-9]*")
+- matchGlobList(result, m_cacheFile, m_cacheFile->getUint32(PosGlobListOffset), fileName);
+ // Check the very common *.txt cases with the suffix tree
+- const int reverseSuffixTreeOffset = m_cacheFile->getUint32(PosReverseSuffixTreeOffset);
+- const int numRoots = m_cacheFile->getUint32(reverseSuffixTreeOffset);
+- const int firstRootOffset = m_cacheFile->getUint32(reverseSuffixTreeOffset + 4);
+- matchSuffixTree(result, m_cacheFile, numRoots, firstRootOffset, lowerFileName, lowerFileName.length() - 1, false);
++ if (result.m_matchingMimeTypes.isEmpty()) {
++ const int reverseSuffixTreeOffset = m_cacheFile->getUint32(PosReverseSuffixTreeOffset);
++ const int numRoots = m_cacheFile->getUint32(reverseSuffixTreeOffset);
++ const int firstRootOffset = m_cacheFile->getUint32(reverseSuffixTreeOffset + 4);
++ matchSuffixTree(result, m_cacheFile, numRoots, firstRootOffset, lowerFileName, lowerFileName.length() - 1, false);
++ if (result.m_matchingMimeTypes.isEmpty())
++ matchSuffixTree(result, m_cacheFile, numRoots, firstRootOffset, fileName, fileName.length() - 1, true);
++ }
++ // Check complex globs (e.g. "callgrind.out[0-9]*" or "README*")
+ if (result.m_matchingMimeTypes.isEmpty())
+- matchSuffixTree(result, m_cacheFile, numRoots, firstRootOffset, fileName, fileName.length() - 1, true);
++ matchGlobList(result, m_cacheFile, m_cacheFile->getUint32(PosGlobListOffset), fileName);
+ }
+
+ void QMimeBinaryProvider::matchGlobList(QMimeGlobMatchResult &result, CacheFile *cacheFile, int off, const QString &fileName)
+diff --git a/qtbase/src/corelib/serialization/qjsonparser.cpp b/qtbase/src/corelib/serialization/qjsonparser.cpp
+index 17e6f111ab..2e40b6c8fb 100644
+--- a/qtbase/src/corelib/serialization/qjsonparser.cpp
++++ b/qtbase/src/corelib/serialization/qjsonparser.cpp
+@@ -379,10 +379,30 @@ error:
+ return QCborValue();
+ }
+
++// We need to retain the _last_ value for any duplicate keys and we need to deref containers.
++// Therefore the manual implementation of std::unique().
++template<typename Iterator, typename Compare, typename Assign>
++static Iterator customAssigningUniqueLast(Iterator first, Iterator last,
++ Compare compare, Assign assign)
++{
++ first = std::adjacent_find(first, last, compare);
++ if (first == last)
++ return last;
++
++ Iterator result = first;
++ while (++first != last) {
++ if (!compare(*result, *first))
++ ++result;
++ if (result != first)
++ assign(*result, *first);
++ }
++
++ return ++result;
++}
++
+ static void sortContainer(QCborContainerPrivate *container)
+ {
+ using Forward = QJsonPrivate::KeyIterator;
+- using Reverse = std::reverse_iterator<Forward>;
+ using Value = Forward::value_type;
+
+ auto compare = [container](const Value &a, const Value &b)
+@@ -420,17 +440,31 @@ static void sortContainer(QCborContainerPrivate *container)
+ }
+ };
+
+- std::sort(Forward(container->elements.begin()), Forward(container->elements.end()),
+- [&compare](const Value &a, const Value &b) { return compare(a, b) < 0; });
++ // The elements' containers are owned by the outer container, not by the elements themselves.
++ auto move = [](Forward::reference target, Forward::reference source)
++ {
++ QtCbor::Element &targetValue = target.value();
++
++ // If the target has a container, deref it before overwriting, so that we don't leak.
++ if (targetValue.flags & QtCbor::Element::IsContainer)
++ targetValue.container->deref();
++
++ // Do not move, so that we can clear the value afterwards.
++ target = source;
++
++ // Clear the source value, so that we don't store the same container twice.
++ source.value() = QtCbor::Element();
++ };
++
++ std::stable_sort(
++ Forward(container->elements.begin()), Forward(container->elements.end()),
++ [&compare](const Value &a, const Value &b) { return compare(a, b) < 0; });
+
+- // We need to retain the _last_ value for any duplicate keys. Therefore the reverse dance here.
+- auto it = std::unique(Reverse(container->elements.end()), Reverse(container->elements.begin()),
+- [&compare](const Value &a, const Value &b) {
+- return compare(a, b) == 0;
+- }).base().elementsIterator();
++ Forward result = customAssigningUniqueLast(
++ Forward(container->elements.begin()), Forward(container->elements.end()),
++ [&compare](const Value &a, const Value &b) { return compare(a, b) == 0; }, move);
+
+- // The erase from beginning is expensive but hopefully rare.
+- container->elements.erase(container->elements.begin(), it);
++ container->elements.erase(result.elementsIterator(), container->elements.end());
+ }
+
+
+diff --git a/qtbase/src/corelib/serialization/qxmlstream.cpp b/qtbase/src/corelib/serialization/qxmlstream.cpp
+index b2f846544d..7cd457ba3a 100644
+--- a/qtbase/src/corelib/serialization/qxmlstream.cpp
++++ b/qtbase/src/corelib/serialization/qxmlstream.cpp
+@@ -980,7 +980,7 @@ inline uint QXmlStreamReaderPrivate::peekChar()
+ bool QXmlStreamReaderPrivate::scanUntil(const char *str, short tokenToInject)
+ {
+ int pos = textBuffer.size();
+- int oldLineNumber = lineNumber;
++ const auto oldLineNumber = lineNumber;
+
+ uint c;
+ while ((c = getChar()) != StreamEOF) {
+diff --git a/qtbase/src/corelib/text/qstring.cpp b/qtbase/src/corelib/text/qstring.cpp
+index 3e88ab4859..8deeae47bb 100644
+--- a/qtbase/src/corelib/text/qstring.cpp
++++ b/qtbase/src/corelib/text/qstring.cpp
+@@ -12312,7 +12312,7 @@ static qsizetype qLastIndexOf(Haystack haystack0, qsizetype from,
+ const auto needle = needle0.data();
+ const auto *end = haystack;
+ haystack += from;
+- const std::size_t sl_minus_1 = sl - 1;
++ const std::size_t sl_minus_1 = sl ? sl - 1 : 0;
+ const auto *n = needle + sl_minus_1;
+ const auto *h = haystack + sl_minus_1;
+ std::size_t hashNeedle = 0, hashHaystack = 0;
+diff --git a/qtbase/src/corelib/text/qstringiterator_p.h b/qtbase/src/corelib/text/qstringiterator_p.h
+index 219589b6e4..1d0c66cc78 100644
+--- a/qtbase/src/corelib/text/qstringiterator_p.h
++++ b/qtbase/src/corelib/text/qstringiterator_p.h
+@@ -61,6 +61,8 @@ class QStringIterator
+ {
+ QString::const_iterator i, pos, e;
+ Q_STATIC_ASSERT((std::is_same<QString::const_iterator, const QChar *>::value));
++ static bool less(const QChar *lhs, const QChar *rhs) noexcept
++ { return std::less<QString::const_iterator>{}(lhs, rhs); }
+ public:
+ explicit QStringIterator(QStringView string, qsizetype idx = 0)
+ : i(string.begin()),
+@@ -95,7 +97,8 @@ public:
+
+ inline void setPosition(QString::const_iterator position)
+ {
+- Q_ASSERT_X(i <= position && position <= e, Q_FUNC_INFO, "position out of bounds");
++ Q_ASSERT_X(!less(position, i) && !less(e, position),
++ Q_FUNC_INFO, "position out of bounds");
+ pos = position;
+ }
+
+@@ -103,7 +106,7 @@ public:
+
+ inline bool hasNext() const
+ {
+- return pos < e;
++ return less(pos, e);
+ }
+
+ inline void advance()
+@@ -120,16 +123,20 @@ public:
+ {
+ Q_ASSERT_X(hasNext(), Q_FUNC_INFO, "iterator hasn't a next item");
+
+- if (Q_UNLIKELY((pos++)->isHighSurrogate()))
++ if (Q_UNLIKELY((pos++)->isHighSurrogate())) {
++ Q_ASSERT(hasNext() && pos->isLowSurrogate());
+ ++pos;
++ }
+ }
+
+ inline uint peekNextUnchecked() const
+ {
+ Q_ASSERT_X(hasNext(), Q_FUNC_INFO, "iterator hasn't a next item");
+
+- if (Q_UNLIKELY(pos->isHighSurrogate()))
++ if (Q_UNLIKELY(pos->isHighSurrogate())) {
++ Q_ASSERT(less(pos + 1, e) && pos[1].isLowSurrogate());
+ return QChar::surrogateToUcs4(pos[0], pos[1]);
++ }
+
+ return pos->unicode();
+ }
+@@ -155,8 +162,10 @@ public:
+ Q_ASSERT_X(hasNext(), Q_FUNC_INFO, "iterator hasn't a next item");
+
+ const QChar cur = *pos++;
+- if (Q_UNLIKELY(cur.isHighSurrogate()))
++ if (Q_UNLIKELY(cur.isHighSurrogate())) {
++ Q_ASSERT(hasNext() && pos->isLowSurrogate());
+ return QChar::surrogateToUcs4(cur, *pos++);
++ }
+ return cur.unicode();
+ }
+
+@@ -166,7 +175,7 @@ public:
+
+ const QChar uc = *pos++;
+ if (Q_UNLIKELY(uc.isSurrogate())) {
+- if (Q_LIKELY(uc.isHighSurrogate() && pos < e && pos->isLowSurrogate()))
++ if (Q_LIKELY(uc.isHighSurrogate() && hasNext() && pos->isLowSurrogate()))
+ return QChar::surrogateToUcs4(uc, *pos++);
+ return invalidAs;
+ }
+@@ -178,7 +187,7 @@ public:
+
+ inline bool hasPrevious() const
+ {
+- return pos > i;
++ return less(i, pos);
+ }
+
+ inline void recede()
+@@ -196,16 +205,20 @@ public:
+ {
+ Q_ASSERT_X(hasPrevious(), Q_FUNC_INFO, "iterator hasn't a previous item");
+
+- if (Q_UNLIKELY((--pos)->isLowSurrogate()))
++ if (Q_UNLIKELY((--pos)->isLowSurrogate())) {
++ Q_ASSERT(hasPrevious() && pos[-1].isHighSurrogate());
+ --pos;
++ }
+ }
+
+ inline uint peekPreviousUnchecked() const
+ {
+ Q_ASSERT_X(hasPrevious(), Q_FUNC_INFO, "iterator hasn't a previous item");
+
+- if (Q_UNLIKELY(pos[-1].isLowSurrogate()))
++ if (Q_UNLIKELY(pos[-1].isLowSurrogate())) {
++ Q_ASSERT(less(i + 1, pos) && pos[-2].isHighSurrogate());
+ return QChar::surrogateToUcs4(pos[-2], pos[-1]);
++ }
+ return pos[-1].unicode();
+ }
+
+@@ -230,8 +243,10 @@ public:
+ Q_ASSERT_X(hasPrevious(), Q_FUNC_INFO, "iterator hasn't a previous item");
+
+ const QChar cur = *--pos;
+- if (Q_UNLIKELY(cur.isLowSurrogate()))
++ if (Q_UNLIKELY(cur.isLowSurrogate())) {
++ Q_ASSERT(hasPrevious() && pos[-1].isHighSurrogate());
+ return QChar::surrogateToUcs4(*--pos, cur);
++ }
+ return cur.unicode();
+ }
+
+@@ -241,7 +256,7 @@ public:
+
+ const QChar uc = *--pos;
+ if (Q_UNLIKELY(uc.isSurrogate())) {
+- if (Q_LIKELY(uc.isLowSurrogate() && pos > i && pos[-1].isHighSurrogate()))
++ if (Q_LIKELY(uc.isLowSurrogate() && hasPrevious() && pos[-1].isHighSurrogate()))
+ return QChar::surrogateToUcs4(*--pos, uc);
+ return invalidAs;
+ }
+diff --git a/qtbase/src/corelib/thread/qfutex_p.h b/qtbase/src/corelib/thread/qfutex_p.h
+index f287b752d7..e294537787 100644
+--- a/qtbase/src/corelib/thread/qfutex_p.h
++++ b/qtbase/src/corelib/thread/qfutex_p.h
+@@ -52,6 +52,7 @@
+ //
+
+ #include <qglobal.h>
++#include <QtCore/qtsan_impl.h>
+
+ QT_BEGIN_NAMESPACE
+
+@@ -106,16 +107,13 @@ namespace QtLinuxFutex {
+ inline int _q_futex(int *addr, int op, int val, quintptr val2 = 0,
+ int *addr2 = nullptr, int val3 = 0) noexcept
+ {
+- // A futex call ensures total ordering on the futex words
+- // (in either success or failure of the call). Instruct TSAN accordingly,
+- // as TSAN does not understand the futex(2) syscall.
+- _q_tsan_release(addr, addr2);
++ QtTsan::futexRelease(addr, addr2);
+
+ // we use __NR_futex because some libcs (like Android's bionic) don't
+ // provide SYS_futex etc.
+ int result = syscall(__NR_futex, addr, op | FUTEX_PRIVATE_FLAG, val, val2, addr2, val3);
+
+- _q_tsan_acquire(addr, addr2);
++ QtTsan::futexAcquire(addr, addr2);
+
+ return result;
+ }
+diff --git a/qtbase/src/corelib/thread/qmutex.cpp b/qtbase/src/corelib/thread/qmutex.cpp
+index 310d1cb14f..7097122d8e 100644
+--- a/qtbase/src/corelib/thread/qmutex.cpp
++++ b/qtbase/src/corelib/thread/qmutex.cpp
+@@ -152,6 +152,7 @@ public:
+
+ /*!
+ \enum QMutex::RecursionMode
++ \obsolete Use QRecursiveMutex to create a recursive mutex.
+
+ \value Recursive In this mode, a thread can lock the same mutex
+ multiple times and the mutex won't be unlocked
+@@ -173,6 +174,7 @@ public:
+
+ /*!
+ Constructs a new mutex. The mutex is created in an unlocked state.
++ \obsolete Use QRecursiveMutex to create a recursive mutex.
+
+ If \a mode is QMutex::Recursive, a thread can lock the same mutex
+ multiple times and the mutex won't be unlocked until a
+@@ -197,7 +199,7 @@ QMutex::QMutex(RecursionMode mode)
+ QMutex::~QMutex()
+ {
+ QMutexData *d = d_ptr.loadRelaxed();
+- if (isRecursive()) {
++ if (QBasicMutex::isRecursive()) {
+ delete static_cast<QRecursiveMutexPrivate *>(d);
+ } else if (d) {
+ #ifndef QT_LINUX_FUTEX
+diff --git a/qtbase/src/corelib/thread/qmutex.h b/qtbase/src/corelib/thread/qmutex.h
+index 73c9e00663..1bae573a03 100644
+--- a/qtbase/src/corelib/thread/qmutex.h
++++ b/qtbase/src/corelib/thread/qmutex.h
+@@ -42,6 +42,7 @@
+
+ #include <QtCore/qglobal.h>
+ #include <QtCore/qatomic.h>
++#include <QtCore/qtsan_impl.h>
+ #include <new>
+
+ #if __has_include(<chrono>)
+@@ -77,19 +78,37 @@ public:
+
+ // BasicLockable concept
+ inline void lock() QT_MUTEX_LOCK_NOEXCEPT {
++ QtTsan::mutexPreLock(this, 0u);
++
+ if (!fastTryLock())
+ lockInternal();
++
++ QtTsan::mutexPostLock(this, 0u, 0);
+ }
+
+ // BasicLockable concept
+ inline void unlock() noexcept {
+ Q_ASSERT(d_ptr.loadRelaxed()); //mutex must be locked
++
++ QtTsan::mutexPreUnlock(this, 0u);
++
+ if (!fastTryUnlock())
+ unlockInternal();
++
++ QtTsan::mutexPostUnlock(this, 0u);
+ }
+
+ bool tryLock() noexcept {
+- return fastTryLock();
++ unsigned tsanFlags = QtTsan::TryLock;
++ QtTsan::mutexPreLock(this, tsanFlags);
++
++ const bool success = fastTryLock();
++
++ if (!success)
++ tsanFlags |= QtTsan::TryLockFailed;
++ QtTsan::mutexPostLock(this, tsanFlags, 0);
++
++ return success;
+ }
+
+ // Lockable concept
+@@ -134,8 +153,16 @@ public:
+ #else
+ QMutex() { d_ptr.storeRelaxed(nullptr); }
+ #endif
++#if QT_DEPRECATED_SINCE(5,15)
+ enum RecursionMode { NonRecursive, Recursive };
++ QT_DEPRECATED_VERSION_X(5, 15, "Use QRecursiveMutex instead of a recursive QMutex")
+ explicit QMutex(RecursionMode mode);
++
++ QT_DEPRECATED_VERSION_X(5, 15, "Use QRecursiveMutex instead of a recursive QMutex")
++ bool isRecursive() const noexcept
++ { return QBasicMutex::isRecursive(); }
++#endif
++
+ ~QMutex();
+
+ // BasicLockable concept
+@@ -166,9 +193,6 @@ public:
+ }
+ #endif
+
+- bool isRecursive() const noexcept
+- { return QBasicMutex::isRecursive(); }
+-
+ private:
+ Q_DISABLE_COPY(QMutex)
+ friend class QMutexLocker;
+diff --git a/qtbase/src/corelib/thread/qreadwritelock.cpp b/qtbase/src/corelib/thread/qreadwritelock.cpp
+index 8c28507d5a..9dd8503116 100644
+--- a/qtbase/src/corelib/thread/qreadwritelock.cpp
++++ b/qtbase/src/corelib/thread/qreadwritelock.cpp
+@@ -155,7 +155,7 @@ QReadWriteLock::QReadWriteLock(RecursionMode recursionMode)
+ */
+ QReadWriteLock::~QReadWriteLock()
+ {
+- auto d = d_ptr.loadRelaxed();
++ auto d = d_ptr.loadAcquire();
+ if (isUncontendedLocked(d)) {
+ qWarning("QReadWriteLock: destroying locked QReadWriteLock");
+ return;
+@@ -445,7 +445,7 @@ void QReadWriteLock::unlock()
+ /*! \internal Helper for QWaitCondition::wait */
+ QReadWriteLock::StateForWaitCondition QReadWriteLock::stateForWaitCondition() const
+ {
+- QReadWriteLockPrivate *d = d_ptr.loadRelaxed();
++ QReadWriteLockPrivate *d = d_ptr.loadAcquire();
+ switch (quintptr(d) & StateMask) {
+ case StateLockedForRead: return LockedForRead;
+ case StateLockedForWrite: return LockedForWrite;
+@@ -453,6 +453,7 @@ QReadWriteLock::StateForWaitCondition QReadWriteLock::stateForWaitCondition() co
+
+ if (!d)
+ return Unlocked;
++ const auto lock = qt_scoped_lock(d->mutex);
+ if (d->writerCount > 1)
+ return RecursivelyLocked;
+ else if (d->writerCount == 1)
+diff --git a/qtbase/src/corelib/thread/qsemaphore.cpp b/qtbase/src/corelib/thread/qsemaphore.cpp
+index 1d01fc1b28..3ecdee3747 100644
+--- a/qtbase/src/corelib/thread/qsemaphore.cpp
++++ b/qtbase/src/corelib/thread/qsemaphore.cpp
+@@ -354,7 +354,12 @@ void QSemaphore::release(int n)
+ quintptr nn = unsigned(n);
+ if (futexHasWaiterCount)
+ nn |= quint64(nn) << 32; // token count replicated in high word
+- quintptr prevValue = u.fetchAndAddRelease(nn);
++ quintptr prevValue = u.loadRelaxed();
++ quintptr newValue;
++ do { // loop just to ensure the operations are done atomically
++ newValue = prevValue + nn;
++ newValue &= (futexNeedsWakeAllBit - 1);
++ } while (!u.testAndSetRelease(prevValue, newValue, prevValue));
+ if (futexNeedsWake(prevValue)) {
+ #ifdef FUTEX_OP
+ if (futexHasWaiterCount) {
+@@ -376,7 +381,6 @@ void QSemaphore::release(int n)
+ quint32 oparg = 0;
+ quint32 cmp = FUTEX_OP_CMP_NE;
+ quint32 cmparg = 0;
+- u.fetchAndAndRelease(futexNeedsWakeAllBit - 1);
+ futexWakeOp(*futexLow32(&u), n, INT_MAX, *futexHigh32(&u), FUTEX_OP(op, oparg, cmp, cmparg));
+ return;
+ }
+@@ -388,7 +392,6 @@ void QSemaphore::release(int n)
+ // its acquisition anyway, so it has to wait;
+ // 2) it did not see the new counter value, in which case its
+ // futexWait will fail.
+- u.fetchAndAndRelease(futexNeedsWakeAllBit - 1);
+ if (futexHasWaiterCount) {
+ futexWakeAll(*futexLow32(&u));
+ futexWakeAll(*futexHigh32(&u));
+diff --git a/qtbase/src/corelib/thread/qthread_p.h b/qtbase/src/corelib/thread/qthread_p.h
+index b2d1628e6e..f32f6f0460 100644
+--- a/qtbase/src/corelib/thread/qthread_p.h
++++ b/qtbase/src/corelib/thread/qthread_p.h
+@@ -174,7 +174,7 @@ public:
+ int returnCode;
+
+ uint stackSize;
+- QThread::Priority priority;
++ std::underlying_type<QThread::Priority>::type priority;
+
+ static QThread *threadForId(int id);
+
+@@ -213,6 +213,13 @@ public:
+ QCoreApplication::instance()->postEvent(q_ptr, new QEvent(QEvent::Quit));
+ }
+ }
++
++#ifndef Q_OS_INTEGRITY
++private:
++ // Used in QThread(Private)::start to avoid racy access to QObject::objectName,
++ // unset afterwards. On INTEGRITY we set the thread name before starting it.
++ QString objectName;
++#endif
+ };
+
+ #else // QT_CONFIG(thread)
+diff --git a/qtbase/src/corelib/thread/qthread_unix.cpp b/qtbase/src/corelib/thread/qthread_unix.cpp
+index 56a8e0a038..610117a640 100644
+--- a/qtbase/src/corelib/thread/qthread_unix.cpp
++++ b/qtbase/src/corelib/thread/qthread_unix.cpp
+@@ -169,8 +169,7 @@ static void set_thread_data(QThreadData *data)
+
+ static void clear_thread_data()
+ {
+- currentThreadData = nullptr;
+- pthread_setspecific(current_thread_data_key, nullptr);
++ set_thread_data(nullptr);
+ }
+
+ template <typename T>
+@@ -296,7 +295,7 @@ void *QThreadPrivate::start(void *arg)
+ QMutexLocker locker(&thr->d_func()->mutex);
+
+ // do we need to reset the thread priority?
+- if (int(thr->d_func()->priority) & ThreadPriorityResetFlag) {
++ if (thr->d_func()->priority & ThreadPriorityResetFlag) {
+ thr->d_func()->setPriority(QThread::Priority(thr->d_func()->priority & ~ThreadPriorityResetFlag));
+ }
+
+@@ -316,10 +315,10 @@ void *QThreadPrivate::start(void *arg)
+ // Sets the name of the current thread. We can only do this
+ // when the thread is starting, as we don't have a cross
+ // platform way of setting the name of an arbitrary thread.
+- if (Q_LIKELY(thr->objectName().isEmpty()))
++ if (Q_LIKELY(thr->d_func()->objectName.isEmpty()))
+ setCurrentThreadName(thr->metaObject()->className());
+ else
+- setCurrentThreadName(thr->objectName().toLocal8Bit());
++ setCurrentThreadName(std::exchange(thr->d_func()->objectName, {}).toLocal8Bit());
+ }
+ #endif
+
+@@ -671,7 +670,7 @@ void QThread::start(Priority priority)
+ // could not set scheduling hints, fallback to inheriting them
+ // we'll try again from inside the thread
+ pthread_attr_setinheritsched(&attr, PTHREAD_INHERIT_SCHED);
+- d->priority = Priority(priority | ThreadPriorityResetFlag);
++ d->priority = static_cast<std::underlying_type<QThread::Priority>::type>(priority) | ThreadPriorityResetFlag;
+ }
+ break;
+ }
+@@ -702,7 +701,10 @@ void QThread::start(Priority priority)
+ pthread_attr_setthreadname(&attr, metaObject()->className());
+ else
+ pthread_attr_setthreadname(&attr, objectName().toLocal8Bit());
++#else
++ d->objectName = objectName();
+ #endif
++
+ pthread_t threadId;
+ int code = pthread_create(&threadId, &attr, QThreadPrivate::start, this);
+ if (code == EPERM) {
+diff --git a/qtbase/src/corelib/thread/qthread_win.cpp b/qtbase/src/corelib/thread/qthread_win.cpp
+index bc70e3178a..4e76972498 100644
+--- a/qtbase/src/corelib/thread/qthread_win.cpp
++++ b/qtbase/src/corelib/thread/qthread_win.cpp
+@@ -394,10 +394,9 @@ unsigned int __stdcall QT_ENSURE_STACK_ALIGNED_FOR_SSE QThreadPrivate::start(voi
+
+ #if !defined(QT_NO_DEBUG) && defined(Q_CC_MSVC) && !defined(Q_OS_WINRT)
+ // sets the name of the current thread.
+- QByteArray objectName = thr->objectName().toLocal8Bit();
+- qt_set_thread_name(HANDLE(-1),
+- objectName.isEmpty() ?
+- thr->metaObject()->className() : objectName.constData());
++ qt_set_thread_name(HANDLE(-1), thr->d_func()->objectName.isEmpty()
++ ? thr->metaObject()->className()
++ : std::exchange(thr->d_func()->objectName, {}).toLocal8Bit().constData());
+ #endif
+
+ emit thr->started(QThread::QPrivateSignal());
+@@ -503,6 +502,7 @@ void QThread::start(Priority priority)
+ if (d->running)
+ return;
+
++ d->objectName = objectName();
+ d->running = true;
+ d->finished = false;
+ d->exited = false;
+@@ -548,7 +548,7 @@ void QThread::start(Priority priority)
+
+ int prio;
+ d->priority = priority;
+- switch (d->priority) {
++ switch (priority) {
+ case IdlePriority:
+ prio = THREAD_PRIORITY_IDLE;
+ break;
+@@ -686,7 +686,7 @@ void QThreadPrivate::setPriority(QThread::Priority threadPriority)
+
+ int prio;
+ priority = threadPriority;
+- switch (priority) {
++ switch (threadPriority) {
+ case QThread::IdlePriority:
+ prio = THREAD_PRIORITY_IDLE;
+ break;
+diff --git a/qtbase/src/corelib/thread/qtsan_impl.h b/qtbase/src/corelib/thread/qtsan_impl.h
+new file mode 100644
+index 0000000000..580a738b91
+--- /dev/null
++++ b/qtbase/src/corelib/thread/qtsan_impl.h
+@@ -0,0 +1,115 @@
++/****************************************************************************
++**
++** Copyright (C) 2017 Intel Corporation.
++** Copyright (C) 2022 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Giuseppe D'Angelo <giuseppe.dangelo@kdab.com>
++** Contact: https://www.qt.io/licensing/
++**
++** This file is part of the QtCore module of the Qt Toolkit.
++**
++** $QT_BEGIN_LICENSE:LGPL$
++** Commercial License Usage
++** Licensees holding valid commercial Qt licenses may use this file in
++** accordance with the commercial license agreement provided with the
++** Software or, alternatively, in accordance with the terms contained in
++** a written agreement between you and The Qt Company. For licensing terms
++** and conditions see https://www.qt.io/terms-conditions. For further
++** information use the contact form at https://www.qt.io/contact-us.
++**
++** GNU Lesser General Public License Usage
++** Alternatively, this file may be used under the terms of the GNU Lesser
++** General Public License version 3 as published by the Free Software
++** Foundation and appearing in the file LICENSE.LGPL3 included in the
++** packaging of this file. Please review the following information to
++** ensure the GNU Lesser General Public License version 3 requirements
++** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
++**
++** GNU General Public License Usage
++** Alternatively, this file may be used under the terms of the GNU
++** General Public License version 2.0 or (at your option) the GNU General
++** Public license version 3 or any later version approved by the KDE Free
++** Qt Foundation. The licenses are as published by the Free Software
++** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
++** included in the packaging of this file. Please review the following
++** information to ensure the GNU General Public License requirements will
++** be met: https://www.gnu.org/licenses/gpl-2.0.html and
++** https://www.gnu.org/licenses/gpl-3.0.html.
++**
++** $QT_END_LICENSE$
++**
++****************************************************************************/
++
++#ifndef QTSAN_IMPL_H
++#define QTSAN_IMPL_H
++
++#include <QtCore/qglobal.h>
++
++#if (__has_feature(thread_sanitizer) || defined(__SANITIZE_THREAD__)) && __has_include(<sanitizer/tsan_interface.h>)
++# define QT_BUILDING_UNDER_TSAN
++# include <sanitizer/tsan_interface.h>
++#endif
++
++QT_BEGIN_NAMESPACE
++
++namespace QtTsan {
++#ifdef QT_BUILDING_UNDER_TSAN
++inline void futexAcquire(void *addr, void *addr2 = nullptr)
++{
++ // A futex call ensures total ordering on the futex words
++ // (in either success or failure of the call). Instruct TSAN accordingly,
++ // as TSAN does not understand the futex(2) syscall (or equivalent).
++ ::__tsan_acquire(addr);
++ if (addr2)
++ ::__tsan_acquire(addr2);
++}
++
++inline void futexRelease(void *addr, void *addr2 = nullptr)
++{
++ if (addr2)
++ ::__tsan_release(addr2);
++ ::__tsan_release(addr);
++}
++
++inline void mutexPreLock(void *addr, unsigned flags)
++{
++ ::__tsan_mutex_pre_lock(addr, flags);
++}
++
++inline void mutexPostLock(void *addr, unsigned flags, int recursion)
++{
++ ::__tsan_mutex_post_lock(addr, flags, recursion);
++}
++
++inline void mutexPreUnlock(void *addr, unsigned flags)
++{
++ ::__tsan_mutex_pre_unlock(addr, flags);
++}
++
++inline void mutexPostUnlock(void *addr, unsigned flags)
++{
++ ::__tsan_mutex_post_unlock(addr, flags);
++}
++
++enum : unsigned {
++ MutexWriteReentrant = ::__tsan_mutex_write_reentrant,
++ TryLock = ::__tsan_mutex_try_lock,
++ TryLockFailed = ::__tsan_mutex_try_lock_failed,
++};
++#else
++inline void futexAcquire(void *, void * = nullptr) {}
++inline void futexRelease(void *, void * = nullptr) {}
++
++enum : unsigned {
++ MutexWriteReentrant,
++ TryLock,
++ TryLockFailed,
++};
++inline void mutexPreLock(void *, unsigned) {}
++inline void mutexPostLock(void *, unsigned, int) {}
++inline void mutexPreUnlock(void *, unsigned) {}
++inline void mutexPostUnlock(void *, unsigned) {}
++#endif // QT_BUILDING_UNDER_TSAN
++} // namespace QtTsan
++
++QT_END_NAMESPACE
++
++#endif // QTSAN_IMPL_H
+diff --git a/qtbase/src/corelib/thread/qwaitcondition_unix.cpp b/qtbase/src/corelib/thread/qwaitcondition_unix.cpp
+index 88b058f410..0f1da4dc9b 100644
+--- a/qtbase/src/corelib/thread/qwaitcondition_unix.cpp
++++ b/qtbase/src/corelib/thread/qwaitcondition_unix.cpp
+@@ -213,7 +213,7 @@ bool QWaitCondition::wait(QMutex *mutex, QDeadlineTimer deadline)
+ {
+ if (! mutex)
+ return false;
+- if (mutex->isRecursive()) {
++ if (static_cast<QBasicMutex *>(mutex)->isRecursive()) {
+ qWarning("QWaitCondition: cannot wait on recursive mutexes");
+ return false;
+ }
+diff --git a/qtbase/src/corelib/time/qdatetime.cpp b/qtbase/src/corelib/time/qdatetime.cpp
+index ec12569e3f..2c0b098079 100644
+--- a/qtbase/src/corelib/time/qdatetime.cpp
++++ b/qtbase/src/corelib/time/qdatetime.cpp
+@@ -43,6 +43,7 @@
+ #if QT_CONFIG(datetimeparser)
+ #include "private/qdatetimeparser_p.h"
+ #endif
++#include <private/qnumeric_p.h>
+
+ #include "qdatastream.h"
+ #include "qset.h"
+@@ -1429,9 +1430,11 @@ QDate QDate::addDays(qint64 ndays) const
+ if (isNull())
+ return QDate();
+
+- // Due to limits on minJd() and maxJd() we know that any overflow
+- // will be invalid and caught by fromJulianDay().
+- return fromJulianDay(jd + ndays);
++ qint64 r;
++ if (Q_UNLIKELY(add_overflow(jd, ndays, &r)))
++ return QDate();
++ else
++ return fromJulianDay(r);
+ }
+
+ /*!
+diff --git a/qtbase/src/corelib/time/qtimezone.cpp b/qtbase/src/corelib/time/qtimezone.cpp
+index 0309e43e52..3d451696a1 100644
+--- a/qtbase/src/corelib/time/qtimezone.cpp
++++ b/qtbase/src/corelib/time/qtimezone.cpp
+@@ -1,6 +1,6 @@
+ /****************************************************************************
+ **
+-** Copyright (C) 2013 John Layt <jlayt@kde.org>
++** Copyright (C) 2020 John Layt <jlayt@kde.org>
+ ** Contact: https://www.qt.io/licensing/
+ **
+ ** This file is part of the QtCore module of the Qt Toolkit.
+@@ -975,9 +975,15 @@ QList<QByteArray> QTimeZone::windowsIdToIanaIds(const QByteArray &windowsId,
+ }
+
+ #ifndef QT_NO_DATASTREAM
++// Invalid, as an IANA ID: too long, starts with - and has other invalid characters in it
++static inline QString invalidId() { return QStringLiteral("-No Time Zone Specified!"); }
++
+ QDataStream &operator<<(QDataStream &ds, const QTimeZone &tz)
+ {
+- tz.d->serialize(ds);
++ if (tz.isValid())
++ tz.d->serialize(ds);
++ else
++ ds << invalidId();
+ return ds;
+ }
+
+@@ -985,7 +991,9 @@ QDataStream &operator>>(QDataStream &ds, QTimeZone &tz)
+ {
+ QString ianaId;
+ ds >> ianaId;
+- if (ianaId == QLatin1String("OffsetFromUtc")) {
++ if (ianaId == invalidId()) {
++ tz = QTimeZone();
++ } else if (ianaId == QLatin1String("OffsetFromUtc")) {
+ int utcOffset;
+ QString name;
+ QString abbreviation;
+diff --git a/qtbase/src/corelib/time/qtimezoneprivate_tz.cpp b/qtbase/src/corelib/time/qtimezoneprivate_tz.cpp
+index b1611d7ddb..a7a6a72ccf 100644
+--- a/qtbase/src/corelib/time/qtimezoneprivate_tz.cpp
++++ b/qtbase/src/corelib/time/qtimezoneprivate_tz.cpp
+@@ -42,6 +42,7 @@
+ #include "qtimezone.h"
+ #include "qtimezoneprivate_p.h"
+ #include "private/qlocale_tools_p.h"
++#include "private/qlocking_p.h"
+
+ #include <QtCore/QDataStream>
+ #include <QtCore/QDateTime>
+@@ -62,6 +63,10 @@
+
+ QT_BEGIN_NAMESPACE
+
++#if QT_CONFIG(icu)
++static QBasicMutex s_icu_mutex;
++#endif
++
+ /*
+ Private
+
+@@ -670,6 +675,9 @@ QTzTimeZonePrivate::~QTzTimeZonePrivate()
+
+ QTzTimeZonePrivate *QTzTimeZonePrivate::clone() const
+ {
++#if QT_CONFIG(icu)
++ const auto lock = qt_scoped_lock(s_icu_mutex);
++#endif
+ return new QTzTimeZonePrivate(*this);
+ }
+
+@@ -913,12 +921,14 @@ QString QTzTimeZonePrivate::displayName(qint64 atMSecsSinceEpoch,
+ const QLocale &locale) const
+ {
+ #if QT_CONFIG(icu)
++ auto lock = qt_unique_lock(s_icu_mutex);
+ if (!m_icu)
+ m_icu = new QIcuTimeZonePrivate(m_id);
+ // TODO small risk may not match if tran times differ due to outdated files
+ // TODO Some valid TZ names are not valid ICU names, use translation table?
+ if (m_icu->isValid())
+ return m_icu->displayName(atMSecsSinceEpoch, nameType, locale);
++ lock.unlock();
+ #else
+ Q_UNUSED(nameType)
+ Q_UNUSED(locale)
+@@ -932,12 +942,14 @@ QString QTzTimeZonePrivate::displayName(QTimeZone::TimeType timeType,
+ const QLocale &locale) const
+ {
+ #if QT_CONFIG(icu)
++ auto lock = qt_unique_lock(s_icu_mutex);
+ if (!m_icu)
+ m_icu = new QIcuTimeZonePrivate(m_id);
+ // TODO small risk may not match if tran times differ due to outdated files
+ // TODO Some valid TZ names are not valid ICU names, use translation table?
+ if (m_icu->isValid())
+ return m_icu->displayName(timeType, nameType, locale);
++ lock.unlock();
+ #else
+ Q_UNUSED(timeType)
+ Q_UNUSED(nameType)
+diff --git a/qtbase/src/corelib/tools/qarraydata.h b/qtbase/src/corelib/tools/qarraydata.h
+index dcd95924c1..d01739e7e6 100644
+--- a/qtbase/src/corelib/tools/qarraydata.h
++++ b/qtbase/src/corelib/tools/qarraydata.h
+@@ -42,6 +42,7 @@
+
+ #include <QtCore/qrefcount.h>
+ #include <string.h>
++#include <cstdint>
+
+ QT_BEGIN_NAMESPACE
+
+@@ -58,14 +59,14 @@ struct Q_CORE_EXPORT QArrayData
+ {
+ Q_ASSERT(size == 0
+ || offset < 0 || size_t(offset) >= sizeof(QArrayData));
+- return reinterpret_cast<char *>(this) + offset;
++ return reinterpret_cast<void *> (reinterpret_cast<uintptr_t>(this) + offset);
+ }
+
+ const void *data() const
+ {
+ Q_ASSERT(size == 0
+ || offset < 0 || size_t(offset) >= sizeof(QArrayData));
+- return reinterpret_cast<const char *>(this) + offset;
++ return reinterpret_cast<void *> (reinterpret_cast<uintptr_t>(this) + offset);
+ }
+
+ // This refers to array data mutability, not "header data" represented by
+diff --git a/qtbase/src/corelib/tools/qfreelist_p.h b/qtbase/src/corelib/tools/qfreelist_p.h
+index 5ba23b344b..9974102136 100644
+--- a/qtbase/src/corelib/tools/qfreelist_p.h
++++ b/qtbase/src/corelib/tools/qfreelist_p.h
+@@ -161,7 +161,7 @@ class QFreeList
+ return i;
+ x -= size;
+ }
+- Q_ASSERT(false);
++ Q_UNREACHABLE();
+ return -1;
+ }
+
+diff --git a/qtbase/src/corelib/tools/qversionnumber.h b/qtbase/src/corelib/tools/qversionnumber.h
+index d43b86ba51..2843f2b043 100644
+--- a/qtbase/src/corelib/tools/qversionnumber.h
++++ b/qtbase/src/corelib/tools/qversionnumber.h
+@@ -273,10 +273,10 @@ public:
+
+ Q_REQUIRED_RESULT Q_CORE_EXPORT QString toString() const;
+ #if QT_STRINGVIEW_LEVEL < 2
+- Q_REQUIRED_RESULT Q_CORE_EXPORT static Q_DECL_PURE_FUNCTION QVersionNumber fromString(const QString &string, int *suffixIndex = nullptr);
++ Q_REQUIRED_RESULT Q_CORE_EXPORT static QVersionNumber fromString(const QString &string, int *suffixIndex = nullptr);
+ #endif
+- Q_REQUIRED_RESULT Q_CORE_EXPORT static Q_DECL_PURE_FUNCTION QVersionNumber fromString(QLatin1String string, int *suffixIndex = nullptr);
+- Q_REQUIRED_RESULT Q_CORE_EXPORT static Q_DECL_PURE_FUNCTION QVersionNumber fromString(QStringView string, int *suffixIndex = nullptr);
++ Q_REQUIRED_RESULT Q_CORE_EXPORT static QVersionNumber fromString(QLatin1String string, int *suffixIndex = nullptr);
++ Q_REQUIRED_RESULT Q_CORE_EXPORT static QVersionNumber fromString(QStringView string, int *suffixIndex = nullptr);
+
+ private:
+ #ifndef QT_NO_DATASTREAM
+diff --git a/qtbase/src/dbus/qdbusintegrator.cpp b/qtbase/src/dbus/qdbusintegrator.cpp
+index 5b66ce971b..28a3b0ffea 100644
+--- a/qtbase/src/dbus/qdbusintegrator.cpp
++++ b/qtbase/src/dbus/qdbusintegrator.cpp
+@@ -1135,7 +1135,13 @@ void QDBusConnectionPrivate::closeConnection()
+ }
+ }
+
+- qDeleteAll(pendingCalls);
++ for (auto it = pendingCalls.begin(); it != pendingCalls.end(); ++it) {
++ auto call = *it;
++ if (!call->ref.deref()) {
++ delete call;
++ }
++ }
++ pendingCalls.clear();
+
+ // Disconnect all signals from signal hooks and from the object tree to
+ // avoid QObject::destroyed being sent to dbus daemon thread which has
+@@ -2584,6 +2590,11 @@ QDBusConnectionPrivate::findMetaObject(const QString &service, const QString &pa
+ if (mo)
+ return mo;
+ }
++ if (path.isEmpty()) {
++ error = QDBusError(QDBusError::InvalidObjectPath, QLatin1String("Object path cannot be empty"));
++ lastError = error;
++ return nullptr;
++ }
+
+ // introspect the target object
+ QDBusMessage msg = QDBusMessage::createMethodCall(service, path,
+diff --git a/qtbase/src/dbus/qdbusmetaobject.cpp b/qtbase/src/dbus/qdbusmetaobject.cpp
+index 5265568f42..7e9f0f1acc 100644
+--- a/qtbase/src/dbus/qdbusmetaobject.cpp
++++ b/qtbase/src/dbus/qdbusmetaobject.cpp
+@@ -210,6 +210,9 @@ QDBusMetaObjectGenerator::findType(const QByteArray &signature,
+ } else if (signature == "a{ss}") {
+ result.name = "QMap<QString,QString>";
+ type = qMetaTypeId<QMap<QString, QString> >();
++ } else if (signature == "aay") {
++ result.name = "QByteArrayList";
++ type = qMetaTypeId<QByteArrayList>();
+ } else {
+ result.name = "{D-Bus type \"" + signature + "\"}";
+ type = registerComplexDBusType(result.name);
+diff --git a/qtbase/src/gui/accessible/qaccessible.cpp b/qtbase/src/gui/accessible/qaccessible.cpp
+index d705bfccb5..0caf3c808c 100644
+--- a/qtbase/src/gui/accessible/qaccessible.cpp
++++ b/qtbase/src/gui/accessible/qaccessible.cpp
+@@ -54,6 +54,7 @@
+ #include <QtCore/qdebug.h>
+ #include <QtCore/qloggingcategory.h>
+ #include <QtCore/qmetaobject.h>
++#include <QtCore/private/qmetaobject_p.h>
+ #include <QtCore/qhash.h>
+ #include <private/qfactoryloader_p.h>
+
+@@ -681,6 +682,25 @@ QAccessibleInterface *QAccessible::queryAccessibleInterface(QObject *object)
+ // Create a QAccessibleInterface for the object class. Start by the most
+ // derived class and walk up the class hierarchy.
+ const QMetaObject *mo = object->metaObject();
++ const auto *objectPriv = QObjectPrivate::get(object);
++ /*
++ We do not want to cache each and every QML metaobject (Button_QMLTYPE_124,
++ Button_QMLTYPE_125, etc.). Those dynamic metaobjects shouldn't have an
++ accessible interface in any case. Instead, we start the whole checking
++ with the first non-dynamic meta-object. To avoid potential regressions
++ in other areas of Qt that also use dynamic metaobjects, we only do this
++ for objects that are QML-related (approximated by checking whether they
++ have ddata set).
++ */
++ const bool qmlRelated = !objectPriv->isDeletingChildren &&
++ objectPriv->declarativeData;
++ while (qmlRelated && mo) {
++ auto mop = QMetaObjectPrivate::get(mo);
++ if (!mop || !(mop->flags & DynamicMetaObject))
++ break;
++
++ mo = mo->superClass();
++ };
+ while (mo) {
+ const QString cn = QLatin1String(mo->className());
+
+@@ -696,14 +716,15 @@ QAccessibleInterface *QAccessible::queryAccessibleInterface(QObject *object)
+ // Find a QAccessiblePlugin (factory) for the class name. If there's
+ // no entry in the cache try to create it using the plugin loader.
+ if (!qAccessiblePlugins()->contains(cn)) {
++ QAccessiblePlugin *factory = nullptr; // 0 means "no plugin found". This is cached as well.
+ const int index = loader()->indexOf(cn);
+- if (index != -1) {
+- QAccessiblePlugin *factory = qobject_cast<QAccessiblePlugin *>(loader()->instance(index));
+- qAccessiblePlugins()->insert(cn, factory);
+- }
++ if (index != -1)
++ factory = qobject_cast<QAccessiblePlugin *>(loader()->instance(index));
++ qAccessiblePlugins()->insert(cn, factory);
+ }
+
+ // At this point the cache should contain a valid factory pointer or 0:
++ Q_ASSERT(qAccessiblePlugins()->contains(cn));
+ QAccessiblePlugin *factory = qAccessiblePlugins()->value(cn);
+ if (factory) {
+ QAccessibleInterface *result = factory->create(cn, object);
+diff --git a/qtbase/src/gui/configure.json b/qtbase/src/gui/configure.json
+index 1f08795c57..12c95742d2 100644
+--- a/qtbase/src/gui/configure.json
++++ b/qtbase/src/gui/configure.json
+@@ -834,7 +834,8 @@
+ "// embedded devices, are not intended to be used together with X. EGL support",
+ "// has to be disabled in plugins like xcb in this case since the native display,",
+ "// window and pixmap types will be different than what an X-based platform",
+- "// plugin would expect."
++ "// plugin would expect.",
++ "#define USE_X11"
+ ],
+ "include": [ "EGL/egl.h", "X11/Xlib.h" ],
+ "main": [
+diff --git a/qtbase/src/gui/image/qbmphandler.cpp b/qtbase/src/gui/image/qbmphandler.cpp
+index 96f1e8cb1d..0e73bbbdb0 100644
+--- a/qtbase/src/gui/image/qbmphandler.cpp
++++ b/qtbase/src/gui/image/qbmphandler.cpp
+@@ -150,16 +150,42 @@ static QDataStream &operator<<(QDataStream &s, const BMP_INFOHDR &bi)
+ return s;
+ }
+
+-static int calc_shift(uint mask)
++static uint calc_shift(uint mask)
+ {
+- int result = 0;
+- while (mask && !(mask & 1)) {
++ uint result = 0;
++ while ((mask >= 0x100) || (!(mask & 1) && mask)) {
+ result++;
+ mask >>= 1;
+ }
+ return result;
+ }
+
++static uint calc_scale(uint low_mask)
++{
++ uint result = 8;
++ while (low_mask && result) {
++ result--;
++ low_mask >>= 1;
++ }
++ return result;
++}
++
++static inline uint apply_scale(uint value, uint scale)
++{
++ if (!(scale & 0x07)) // return immediately if scale == 8 or 0
++ return value;
++
++ uint filled = 8 - scale;
++ uint result = value << scale;
++
++ do {
++ result |= result >> filled;
++ filled <<= 1;
++ } while (filled < 8);
++
++ return result;
++}
++
+ static bool read_dib_fileheader(QDataStream &s, BMP_FILEHDR &bf)
+ {
+ // read BMP file header
+@@ -222,14 +248,14 @@ static bool read_dib_body(QDataStream &s, const BMP_INFOHDR &bi, qint64 offset,
+ uint green_mask = 0;
+ uint blue_mask = 0;
+ uint alpha_mask = 0;
+- int red_shift = 0;
+- int green_shift = 0;
+- int blue_shift = 0;
+- int alpha_shift = 0;
+- int red_scale = 0;
+- int green_scale = 0;
+- int blue_scale = 0;
+- int alpha_scale = 0;
++ uint red_shift = 0;
++ uint green_shift = 0;
++ uint blue_shift = 0;
++ uint alpha_shift = 0;
++ uint red_scale = 0;
++ uint green_scale = 0;
++ uint blue_scale = 0;
++ uint alpha_scale = 0;
+
+ if (!d->isSequential())
+ d->seek(startpos + BMP_FILEHDR_SIZE + bi.biSize); // goto start of colormap or masks
+@@ -308,19 +334,19 @@ static bool read_dib_body(QDataStream &s, const BMP_INFOHDR &bi, qint64 offset,
+ red_shift = calc_shift(red_mask);
+ if (((red_mask >> red_shift) + 1) == 0)
+ return false;
+- red_scale = 256 / ((red_mask >> red_shift) + 1);
++ red_scale = calc_scale(red_mask >> red_shift);
+ green_shift = calc_shift(green_mask);
+ if (((green_mask >> green_shift) + 1) == 0)
+ return false;
+- green_scale = 256 / ((green_mask >> green_shift) + 1);
++ green_scale = calc_scale(green_mask >> green_shift);
+ blue_shift = calc_shift(blue_mask);
+ if (((blue_mask >> blue_shift) + 1) == 0)
+ return false;
+- blue_scale = 256 / ((blue_mask >> blue_shift) + 1);
++ blue_scale = calc_scale(blue_mask >> blue_shift);
+ alpha_shift = calc_shift(alpha_mask);
+ if (((alpha_mask >> alpha_shift) + 1) == 0)
+ return false;
+- alpha_scale = 256 / ((alpha_mask >> alpha_shift) + 1);
++ alpha_scale = calc_scale(alpha_mask >> alpha_shift);
+ } else if (comp == BMP_RGB && (nbits == 24 || nbits == 32)) {
+ blue_mask = 0x000000ff;
+ green_mask = 0x0000ff00;
+@@ -328,17 +354,15 @@ static bool read_dib_body(QDataStream &s, const BMP_INFOHDR &bi, qint64 offset,
+ blue_shift = 0;
+ green_shift = 8;
+ red_shift = 16;
+- blue_scale = green_scale = red_scale = 1;
++ blue_scale = green_scale = red_scale = 0;
+ } else if (comp == BMP_RGB && nbits == 16) {
+ blue_mask = 0x001f;
+ green_mask = 0x03e0;
+ red_mask = 0x7c00;
+ blue_shift = 0;
+- green_shift = 2;
+- red_shift = 7;
+- red_scale = 1;
+- green_scale = 1;
+- blue_scale = 8;
++ green_shift = 5;
++ red_shift = 10;
++ blue_scale = green_scale = red_scale = 3;
+ }
+
+ #if 0
+@@ -544,10 +568,10 @@ static bool read_dib_body(QDataStream &s, const BMP_INFOHDR &bi, qint64 offset,
+ c |= *(uchar*)(b+2)<<16;
+ if (nbits > 24)
+ c |= *(uchar*)(b+3)<<24;
+- *p++ = qRgba(((c & red_mask) >> red_shift) * red_scale,
+- ((c & green_mask) >> green_shift) * green_scale,
+- ((c & blue_mask) >> blue_shift) * blue_scale,
+- transp ? ((c & alpha_mask) >> alpha_shift) * alpha_scale : 0xff);
++ *p++ = qRgba(apply_scale((c & red_mask) >> red_shift, red_scale),
++ apply_scale((c & green_mask) >> green_shift, green_scale),
++ apply_scale((c & blue_mask) >> blue_shift, blue_scale),
++ transp ? apply_scale((c & alpha_mask) >> alpha_shift, alpha_scale) : 0xff);
+ b += nbits/8;
+ }
+ }
+diff --git a/qtbase/src/gui/image/qimage.cpp b/qtbase/src/gui/image/qimage.cpp
+index 7152ac1607..0df772564c 100644
+--- a/qtbase/src/gui/image/qimage.cpp
++++ b/qtbase/src/gui/image/qimage.cpp
+@@ -4694,6 +4694,8 @@ QImage QImage::smoothScaled(int w, int h) const {
+ static QImage rotated90(const QImage &image)
+ {
+ QImage out(image.height(), image.width(), image.format());
++ if (out.isNull())
++ return out;
+ copyMetadata(&out, image);
+ if (image.colorCount() > 0)
+ out.setColorTable(image.colorTable());
+@@ -4722,6 +4724,8 @@ static QImage rotated180(const QImage &image)
+ return image.mirrored(true, true);
+
+ QImage out(image.width(), image.height(), image.format());
++ if (out.isNull())
++ return out;
+ copyMetadata(&out, image);
+ if (image.colorCount() > 0)
+ out.setColorTable(image.colorTable());
+@@ -4734,6 +4738,8 @@ static QImage rotated180(const QImage &image)
+ static QImage rotated270(const QImage &image)
+ {
+ QImage out(image.height(), image.width(), image.format());
++ if (out.isNull())
++ return out;
+ copyMetadata(&out, image);
+ if (image.colorCount() > 0)
+ out.setColorTable(image.colorTable());
+diff --git a/qtbase/src/gui/kernel/qcursor.cpp b/qtbase/src/gui/kernel/qcursor.cpp
+index d6ccaff8ed..455088241c 100644
+--- a/qtbase/src/gui/kernel/qcursor.cpp
++++ b/qtbase/src/gui/kernel/qcursor.cpp
+@@ -251,7 +251,8 @@ void QCursor::setPos(QScreen *screen, int x, int y)
+ {
+ if (screen) {
+ if (QPlatformCursor *cursor = screen->handle()->cursor()) {
+- const QPoint devicePos = QHighDpi::toNativePixels(QPoint(x, y), screen);
++ const QPoint pos(x, y);
++ const QPoint devicePos = QHighDpi::toNativePixels(pos, screen->virtualSiblingAt(pos));
+ // Need to check, since some X servers generate null mouse move
+ // events, causing looping in applications which call setPos() on
+ // every mouse move event.
+diff --git a/qtbase/src/gui/kernel/qhighdpiscaling.cpp b/qtbase/src/gui/kernel/qhighdpiscaling.cpp
+index 9bbf2773a9..3ac4a4d8b6 100644
+--- a/qtbase/src/gui/kernel/qhighdpiscaling.cpp
++++ b/qtbase/src/gui/kernel/qhighdpiscaling.cpp
+@@ -580,9 +580,8 @@ void QHighDpiScaling::setScreenFactor(QScreen *screen, qreal factor)
+ else
+ qNamedScreenScaleFactors()->insert(name, factor);
+
+- // hack to force re-evaluation of screen geometry
+ if (screen->handle())
+- screen->d_func()->setPlatformScreen(screen->handle()); // updates geometries based on scale factor
++ screen->d_func()->updateLogicalDpi();
+ }
+
+ QPoint QHighDpiScaling::mapPositionToNative(const QPoint &pos, const QPlatformScreen *platformScreen)
+diff --git a/qtbase/src/gui/kernel/qkeysequence.cpp b/qtbase/src/gui/kernel/qkeysequence.cpp
+index a75b8ef920..4f2d294739 100644
+--- a/qtbase/src/gui/kernel/qkeysequence.cpp
++++ b/qtbase/src/gui/kernel/qkeysequence.cpp
+@@ -701,6 +701,10 @@ static const struct {
+ { Qt::Key_TouchpadToggle, QT_TRANSLATE_NOOP("QShortcut", "Touchpad Toggle") },
+ { Qt::Key_TouchpadOn, QT_TRANSLATE_NOOP("QShortcut", "Touchpad On") },
+ { Qt::Key_TouchpadOff, QT_TRANSLATE_NOOP("QShortcut", "Touchpad Off") },
++ { Qt::Key_Shift, QT_TRANSLATE_NOOP("QShortcut", "Shift") },
++ { Qt::Key_Control, QT_TRANSLATE_NOOP("QShortcut", "Control") },
++ { Qt::Key_Alt, QT_TRANSLATE_NOOP("QShortcut", "Alt") },
++ { Qt::Key_Meta, QT_TRANSLATE_NOOP("QShortcut", "Meta") },
+
+ };
+ static Q_CONSTEXPR int numKeyNames = sizeof keyname / sizeof *keyname;
+diff --git a/qtbase/src/gui/kernel/qplatformservices.cpp b/qtbase/src/gui/kernel/qplatformservices.cpp
+index fdc6a6c4aa..ac47f98c5d 100644
+--- a/qtbase/src/gui/kernel/qplatformservices.cpp
++++ b/qtbase/src/gui/kernel/qplatformservices.cpp
+@@ -55,6 +55,19 @@ QT_BEGIN_NAMESPACE
+ \brief The QPlatformServices provides the backend for desktop-related functionality.
+ */
+
++/*!
++ \enum QPlatformServices::Capability
++
++ Capabilities are used to determine a specific platform service's availability.
++
++ \value ColorPickingFromScreen The platform natively supports color picking from screen.
++ This capability indicates that the platform supports "opaque" color picking, where the
++ platform implements a complete user experience for color picking and outputs a color.
++ This is in contrast to the application implementing the color picking user experience
++ (taking care of showing a cross hair, instructing the platform integration to obtain
++ the color at a given pixel, etc.). The related service function is pickColor().
++ */
++
+ QPlatformServices::QPlatformServices()
+ { }
+
+@@ -85,5 +98,16 @@ QByteArray QPlatformServices::desktopEnvironment() const
+ return QByteArray("UNKNOWN");
+ }
+
++QPlatformServiceColorPicker *QPlatformServices::colorPicker(QWindow *parent)
++{
++ Q_UNUSED(parent);
++ return nullptr;
++}
++
++bool QPlatformServices::hasCapability(Capability capability) const
++{
++ Q_UNUSED(capability)
++ return false;
++}
+
+ QT_END_NAMESPACE
+diff --git a/qtbase/src/gui/kernel/qplatformservices.h b/qtbase/src/gui/kernel/qplatformservices.h
+index 5de96cfa7d..a8b2a4ce71 100644
+--- a/qtbase/src/gui/kernel/qplatformservices.h
++++ b/qtbase/src/gui/kernel/qplatformservices.h
+@@ -50,16 +50,32 @@
+ //
+
+ #include <QtGui/qtguiglobal.h>
++#include <QtCore/qobject.h>
+
+ QT_BEGIN_NAMESPACE
+
+ class QUrl;
++class QWindow;
++
++class Q_GUI_EXPORT QPlatformServiceColorPicker : public QObject
++{
++ Q_OBJECT
++public:
++ using QObject::QObject;
++ virtual void pickColor() = 0;
++Q_SIGNALS:
++ void colorPicked(const QColor &color);
++};
+
+ class Q_GUI_EXPORT QPlatformServices
+ {
+ public:
+ Q_DISABLE_COPY_MOVE(QPlatformServices)
+
++ enum Capability {
++ ColorPicking,
++ };
++
+ QPlatformServices();
+ virtual ~QPlatformServices() { }
+
+@@ -67,6 +83,10 @@ public:
+ virtual bool openDocument(const QUrl &url);
+
+ virtual QByteArray desktopEnvironment() const;
++
++ virtual bool hasCapability(Capability capability) const;
++
++ virtual QPlatformServiceColorPicker *colorPicker(QWindow *parent = nullptr);
+ };
+
+ QT_END_NAMESPACE
+diff --git a/qtbase/src/gui/kernel/qplatformtheme.cpp b/qtbase/src/gui/kernel/qplatformtheme.cpp
+index 71521c0339..2325873245 100644
+--- a/qtbase/src/gui/kernel/qplatformtheme.cpp
++++ b/qtbase/src/gui/kernel/qplatformtheme.cpp
+@@ -163,6 +163,8 @@ QT_BEGIN_NAMESPACE
+
+ \value ShowShortcutsInContextMenus (bool) Whether to display shortcut key sequences in context menus.
+
++ \value ButtonPressKeys (QList<Qt::Key>) A list of keys that can be used to press buttons via keyboard input.
++
+ \sa themeHint(), QStyle::pixelMetric()
+ */
+
+@@ -563,6 +565,8 @@ QVariant QPlatformTheme::defaultThemeHint(ThemeHint hint)
+ }
+ case MouseQuickSelectionThreshold:
+ return QVariant(10);
++ case ButtonPressKeys:
++ return QVariant::fromValue(QList<Qt::Key>({ Qt::Key_Space, Qt::Key_Select }));
+ }
+ return QVariant();
+ }
+diff --git a/qtbase/src/gui/kernel/qplatformtheme.h b/qtbase/src/gui/kernel/qplatformtheme.h
+index 3185fc4541..7e6c9d5740 100644
+--- a/qtbase/src/gui/kernel/qplatformtheme.h
++++ b/qtbase/src/gui/kernel/qplatformtheme.h
+@@ -120,7 +120,8 @@ public:
+ TouchDoubleTapDistance,
+ ShowShortcutsInContextMenus,
+ IconFallbackSearchPaths,
+- MouseQuickSelectionThreshold
++ MouseQuickSelectionThreshold,
++ ButtonPressKeys
+ };
+
+ enum DialogType {
+diff --git a/qtbase/src/gui/kernel/qscreen.cpp b/qtbase/src/gui/kernel/qscreen.cpp
+index 8e0eb35116..5d172a58dd 100644
+--- a/qtbase/src/gui/kernel/qscreen.cpp
++++ b/qtbase/src/gui/kernel/qscreen.cpp
+@@ -77,6 +77,12 @@ QScreen::QScreen(QPlatformScreen *screen)
+ d->setPlatformScreen(screen);
+ }
+
++void QScreenPrivate::updateLogicalDpi()
++{
++ logicalDpi = QPlatformScreen::overrideDpi(platformScreen->logicalDpi());
++ updateGeometriesWithSignals(); // updates geometries based on scale factor
++}
++
+ void QScreenPrivate::updateGeometriesWithSignals()
+ {
+ const QRect oldGeometry = geometry;
+diff --git a/qtbase/src/gui/kernel/qscreen_p.h b/qtbase/src/gui/kernel/qscreen_p.h
+index 7da542c25e..e50fc3190b 100644
+--- a/qtbase/src/gui/kernel/qscreen_p.h
++++ b/qtbase/src/gui/kernel/qscreen_p.h
+@@ -70,6 +70,7 @@ public:
+ geometry = platformScreen->deviceIndependentGeometry();
+ availableGeometry = QHighDpi::fromNative(platformScreen->availableGeometry(), QHighDpiScaling::factor(platformScreen), geometry.topLeft());
+ }
++ void updateLogicalDpi();
+
+ void updatePrimaryOrientation();
+ void updateGeometriesWithSignals();
+diff --git a/qtbase/src/gui/painting/qblendfunctions_p.h b/qtbase/src/gui/painting/qblendfunctions_p.h
+index 080da98ec4..6997d62b3c 100644
+--- a/qtbase/src/gui/painting/qblendfunctions_p.h
++++ b/qtbase/src/gui/painting/qblendfunctions_p.h
+@@ -246,25 +246,32 @@ void qt_transform_image_rasterize(DestT *destPixels, int dbpl,
+ int dudx, int dvdx, int dudy, int dvdy, int u0, int v0,
+ Blender blender)
+ {
+- int fromY = qMax(qRound(topY), clip.top());
+- int toY = qMin(qRound(bottomY), clip.top() + clip.height());
++ qint64 fromY = qMax(qRound(topY), clip.top());
++ qint64 toY = qMin(qRound(bottomY), clip.top() + clip.height());
+ if (fromY >= toY)
+ return;
+
+ qreal leftSlope = (bottomLeft.x - topLeft.x) / (bottomLeft.y - topLeft.y);
+ qreal rightSlope = (bottomRight.x - topRight.x) / (bottomRight.y - topRight.y);
+- int dx_l = int(leftSlope * 0x10000);
+- int dx_r = int(rightSlope * 0x10000);
+- int x_l = int((topLeft.x + (qreal(0.5) + fromY - topLeft.y) * leftSlope + qreal(0.5)) * 0x10000);
+- int x_r = int((topRight.x + (qreal(0.5) + fromY - topRight.y) * rightSlope + qreal(0.5)) * 0x10000);
+-
+- int fromX, toX, x1, x2, u, v, i, ii;
++ qint64 dx_l = qint64(leftSlope * 0x10000);
++ qint64 dx_r = qint64(rightSlope * 0x10000);
++ qint64 x_l = qint64((topLeft.x + (qreal(0.5) + fromY - topLeft.y) * leftSlope + qreal(0.5)) * 0x10000);
++ qint64 x_r = qint64((topRight.x + (qreal(0.5) + fromY - topRight.y) * rightSlope + qreal(0.5)) * 0x10000);
++
++ qint64 sourceRectTop = qint64(sourceRect.top());
++ qint64 sourceRectLeft = qint64(sourceRect.left());
++ qint64 sourceRectWidth = qint64(sourceRect.width());
++ qint64 sourceRectHeight = qint64(sourceRect.height());
++ qint64 clipLeft = qint64(clip.left());
++ qint64 clipWidth = qint64(clip.width());
++
++ qint64 fromX, toX, x1, x2, u, v, i, ii;
+ DestT *line;
+- for (int y = fromY; y < toY; ++y) {
++ for (qint64 y = fromY; y < toY; ++y) {
+ line = reinterpret_cast<DestT *>(reinterpret_cast<uchar *>(destPixels) + y * dbpl);
+
+- fromX = qMax(x_l >> 16, clip.left());
+- toX = qMin(x_r >> 16, clip.left() + clip.width());
++ fromX = qMax(x_l >> 16, clipLeft);
++ toX = qMin(x_r >> 16, clipLeft + clipWidth);
+ if (fromX < toX) {
+ // Because of rounding, we can get source coordinates outside the source image.
+ // Clamp these coordinates to the source rect to avoid segmentation fault and
+@@ -275,10 +282,10 @@ void qt_transform_image_rasterize(DestT *destPixels, int dbpl,
+ u = x1 * dudx + y * dudy + u0;
+ v = x1 * dvdx + y * dvdy + v0;
+ for (; x1 < toX; ++x1) {
+- int uu = u >> 16;
+- int vv = v >> 16;
+- if (uu >= sourceRect.left() && uu < sourceRect.left() + sourceRect.width()
+- && vv >= sourceRect.top() && vv < sourceRect.top() + sourceRect.height()) {
++ qint64 uu = u >> 16;
++ qint64 vv = v >> 16;
++ if (uu >= sourceRectLeft && uu < sourceRectLeft + sourceRectWidth
++ && vv >= sourceRectTop && vv < sourceRectTop + sourceRectHeight) {
+ break;
+ }
+ u += dudx;
+@@ -290,10 +297,10 @@ void qt_transform_image_rasterize(DestT *destPixels, int dbpl,
+ u = (x2 - 1) * dudx + y * dudy + u0;
+ v = (x2 - 1) * dvdx + y * dvdy + v0;
+ for (; x2 > x1; --x2) {
+- int uu = u >> 16;
+- int vv = v >> 16;
+- if (uu >= sourceRect.left() && uu < sourceRect.left() + sourceRect.width()
+- && vv >= sourceRect.top() && vv < sourceRect.top() + sourceRect.height()) {
++ qint64 uu = u >> 16;
++ qint64 vv = v >> 16;
++ if (uu >= sourceRectLeft && uu < sourceRectLeft + sourceRectWidth
++ && vv >= sourceRectTop && vv < sourceRectTop + sourceRectHeight) {
+ break;
+ }
+ u -= dudx;
+@@ -308,8 +315,8 @@ void qt_transform_image_rasterize(DestT *destPixels, int dbpl,
+ // Beginning of the scan line, with per-pixel checks.
+ i = x1 - fromX;
+ while (i) {
+- int uu = qBound(sourceRect.left(), u >> 16, sourceRect.left() + sourceRect.width() - 1);
+- int vv = qBound(sourceRect.top(), v >> 16, sourceRect.top() + sourceRect.height() - 1);
++ qint64 uu = qBound(sourceRectLeft, u >> 16, sourceRectLeft + sourceRectWidth - 1);
++ qint64 vv = qBound(sourceRectTop, v >> 16, sourceRectTop + sourceRectHeight - 1);
+ blender.write(line, reinterpret_cast<const SrcT *>(reinterpret_cast<const uchar *>(srcPixels) + vv * sbpl)[uu]);
+ u += dudx;
+ v += dvdx;
+@@ -348,8 +355,8 @@ void qt_transform_image_rasterize(DestT *destPixels, int dbpl,
+ // End of the scan line, with per-pixel checks.
+ i = toX - x2;
+ while (i) {
+- int uu = qBound(sourceRect.left(), u >> 16, sourceRect.left() + sourceRect.width() - 1);
+- int vv = qBound(sourceRect.top(), v >> 16, sourceRect.top() + sourceRect.height() - 1);
++ qint64 uu = qBound(sourceRectLeft, u >> 16, sourceRectLeft + sourceRectWidth - 1);
++ qint64 vv = qBound(sourceRectTop, v >> 16, sourceRectTop + sourceRectHeight - 1);
+ blender.write(line, reinterpret_cast<const SrcT *>(reinterpret_cast<const uchar *>(srcPixels) + vv * sbpl)[uu]);
+ u += dudx;
+ v += dvdx;
+diff --git a/qtbase/src/gui/painting/qcolortrclut_p.h b/qtbase/src/gui/painting/qcolortrclut_p.h
+index 76a6a60803..24fd522e6c 100644
+--- a/qtbase/src/gui/painting/qcolortrclut_p.h
++++ b/qtbase/src/gui/painting/qcolortrclut_p.h
+@@ -118,6 +118,7 @@ public:
+ return QRgba64::fromRgba64(r, g, b, qAlpha(rgb32) * 257);
+ #endif
+ }
++ QRgba64 toLinear64(QRgba64) const = delete;
+
+ QRgb toLinear(QRgb rgb32) const
+ {
+diff --git a/qtbase/src/gui/painting/qdrawhelper.cpp b/qtbase/src/gui/painting/qdrawhelper.cpp
+index a61793508a..5ba2d277b7 100644
+--- a/qtbase/src/gui/painting/qdrawhelper.cpp
++++ b/qtbase/src/gui/painting/qdrawhelper.cpp
+@@ -6091,7 +6091,7 @@ static inline void alphargbblend_argb32(quint32 *dst, uint coverage, const QRgba
+ static inline void rgbBlendPixel(QRgba64 &dst, int coverage, QRgba64 slinear, const QColorTrcLut *colorProfile)
+ {
+ // Do a gammacorrected RGB alphablend...
+- const QRgba64 dlinear = colorProfile ? colorProfile->toLinear64(dst) : dst;
++ const QRgba64 dlinear = colorProfile ? colorProfile->toLinear(dst) : dst;
+
+ QRgba64 blend = rgbBlend(dlinear, slinear, coverage);
+
+diff --git a/qtbase/src/gui/painting/qpaintengine_raster.cpp b/qtbase/src/gui/painting/qpaintengine_raster.cpp
+index 283923de52..f08eb9cbee 100644
+--- a/qtbase/src/gui/painting/qpaintengine_raster.cpp
++++ b/qtbase/src/gui/painting/qpaintengine_raster.cpp
+@@ -560,31 +560,6 @@ void QRasterPaintEngine::updateMatrix(const QTransform &matrix)
+ QRasterPaintEngineState *s = state();
+ // FALCON: get rid of this line, see drawImage call below.
+ s->matrix = matrix;
+- QTransform::TransformationType txop = s->matrix.type();
+-
+- switch (txop) {
+-
+- case QTransform::TxNone:
+- s->flags.int_xform = true;
+- break;
+-
+- case QTransform::TxTranslate:
+- s->flags.int_xform = qreal(int(s->matrix.dx())) == s->matrix.dx()
+- && qreal(int(s->matrix.dy())) == s->matrix.dy();
+- break;
+-
+- case QTransform::TxScale:
+- s->flags.int_xform = qreal(int(s->matrix.dx())) == s->matrix.dx()
+- && qreal(int(s->matrix.dy())) == s->matrix.dy()
+- && qreal(int(s->matrix.m11())) == s->matrix.m11()
+- && qreal(int(s->matrix.m22())) == s->matrix.m22();
+- break;
+-
+- default: // shear / perspective...
+- s->flags.int_xform = false;
+- break;
+- }
+-
+ s->flags.tx_noshear = qt_scaleForTransform(s->matrix, &s->txscale);
+
+ ensureOutlineMapper();
+@@ -617,7 +592,6 @@ QRasterPaintEngineState::QRasterPaintEngineState()
+ flags.bilinear = false;
+ flags.legacy_rounding = false;
+ flags.fast_text = true;
+- flags.int_xform = true;
+ flags.tx_noshear = true;
+ flags.fast_images = true;
+
+@@ -1793,7 +1767,7 @@ void QRasterPaintEngine::fill(const QVectorPath &path, const QBrush &brush)
+ QRectF cpRect = path.controlPointRect();
+ const QRectF pathDeviceRect = s->matrix.mapRect(cpRect);
+ // Skip paths that by conservative estimates are completely outside the paint device.
+- if (!pathDeviceRect.intersects(QRectF(d->deviceRect)))
++ if (!pathDeviceRect.intersects(QRectF(d->deviceRect)) || !pathDeviceRect.isValid())
+ return;
+
+ ProcessSpans blend = d->getBrushFunc(pathDeviceRect, &s->brushData);
+diff --git a/qtbase/src/gui/painting/qpaintengine_raster_p.h b/qtbase/src/gui/painting/qpaintengine_raster_p.h
+index 089aadc3f7..bf7363d5aa 100644
+--- a/qtbase/src/gui/painting/qpaintengine_raster_p.h
++++ b/qtbase/src/gui/painting/qpaintengine_raster_p.h
+@@ -111,7 +111,6 @@ public:
+ uint bilinear : 1;
+ uint legacy_rounding : 1;
+ uint fast_text : 1;
+- uint int_xform : 1;
+ uint tx_noshear : 1;
+ uint fast_images : 1;
+ };
+diff --git a/qtbase/src/gui/painting/qpainterpath.cpp b/qtbase/src/gui/painting/qpainterpath.cpp
+index f9544a3241..d80fafeaf1 100644
+--- a/qtbase/src/gui/painting/qpainterpath.cpp
++++ b/qtbase/src/gui/painting/qpainterpath.cpp
+@@ -1253,7 +1253,7 @@ void QPainterPath::addText(const QPointF &point, const QFont &f, const QString &
+
+ if (si.analysis.flags < QScriptAnalysis::TabOrObject) {
+ QGlyphLayout glyphs = eng->shapedGlyphs(&si);
+- QFontEngine *fe = f.d->engineForScript(si.analysis.script);
++ QFontEngine *fe = eng->fontEngine(si);
+ Q_ASSERT(fe);
+ fe->addOutlineToPath(x, y, glyphs, this,
+ si.analysis.bidiLevel % 2
+diff --git a/qtbase/src/gui/painting/qpathclipper_p.h b/qtbase/src/gui/painting/qpathclipper_p.h
+index 9444a87b71..18f64c5e8c 100644
+--- a/qtbase/src/gui/painting/qpathclipper_p.h
++++ b/qtbase/src/gui/painting/qpathclipper_p.h
+@@ -156,7 +156,7 @@ public:
+ int vertex(Direction direction) const;
+
+ private:
+- int m_next[2][2];
++ int m_next[2][2] = { { -1, -1 }, { -1, -1 } };
+ };
+
+ class QPathSegments
+@@ -296,10 +296,6 @@ inline QPathEdge::QPathEdge(int a, int b)
+ , angle(0)
+ , invAngle(0)
+ {
+- m_next[0][0] = -1;
+- m_next[1][0] = -1;
+- m_next[0][0] = -1;
+- m_next[1][0] = -1;
+ }
+
+ inline int QPathEdge::next(Traversal traversal, Direction direction) const
+diff --git a/qtbase/src/gui/painting/qpdf.cpp b/qtbase/src/gui/painting/qpdf.cpp
+index 3066744f1b..2c8d3c3b53 100644
+--- a/qtbase/src/gui/painting/qpdf.cpp
++++ b/qtbase/src/gui/painting/qpdf.cpp
+@@ -2760,6 +2760,8 @@ int QPdfEnginePrivate::addBrushPattern(const QTransform &m, bool *specifyColor,
+ return gradientBrush(brush, matrix, gStateObject);
+ }
+
++ matrix = brush.transform() * matrix;
++
+ if ((!brush.isOpaque() && brush.style() < Qt::LinearGradientPattern) || opacity != 1.0)
+ *gStateObject = addConstantAlphaObject(qRound(brush.color().alpha() * opacity),
+ qRound(pen.color().alpha() * opacity));
+diff --git a/qtbase/src/gui/painting/qstroker.cpp b/qtbase/src/gui/painting/qstroker.cpp
+index cb5d395e80..3b6357a893 100644
+--- a/qtbase/src/gui/painting/qstroker.cpp
++++ b/qtbase/src/gui/painting/qstroker.cpp
+@@ -1182,6 +1182,7 @@ void QDashStroker::processCurrentSubpath()
+ // Check if the entire line should be clipped away or simplified
+ bool clipIt = clipping && !lineIntersectsRect(prev, e, clip_tl, clip_br);
+ bool skipDashing = elen * invSumLength > repetitionLimit();
++ int maxDashes = dashCount;
+ if (skipDashing || clipIt) {
+ // Cut away full dash sequences.
+ elen -= std::floor(elen * invSumLength) * sumLength;
+@@ -1196,7 +1197,7 @@ void QDashStroker::processCurrentSubpath()
+ pos = estop; // move pos to next path element
+ done = true;
+ } else { // Dash is on this line
+- pos = dpos + estart;
++ pos = --maxDashes > 0 ? dpos + estart : estop;
+ done = pos >= estop;
+ if (++idash >= dashCount)
+ idash = 0;
+diff --git a/qtbase/src/gui/painting/qt_attribution.json b/qtbase/src/gui/painting/qt_attribution.json
+index 7b16e8c211..0e87d30aa2 100644
+--- a/qtbase/src/gui/painting/qt_attribution.json
++++ b/qtbase/src/gui/painting/qt_attribution.json
+@@ -10,7 +10,7 @@
+ "Homepage": "http://www.freetype.org",
+ "License": "Freetype Project License or GNU General Public License v2.0 only",
+ "LicenseId": "FTL or GPL-2.0",
+- "LicenseFile": "../../3rdparty/freetype/docs/LICENSE.TXT",
++ "LicenseFile": "../../3rdparty/freetype/LICENSE.TXT",
+ "Copyright": "Copyright 2000-2016 by David Turner, Robert Wilhelm, and Werner Lemberg."
+ },
+ {
+diff --git a/qtbase/src/gui/rhi/qshader_p_p.h b/qtbase/src/gui/rhi/qshader_p_p.h
+index ec9d25971f..4a5a7a6d51 100644
+--- a/qtbase/src/gui/rhi/qshader_p_p.h
++++ b/qtbase/src/gui/rhi/qshader_p_p.h
+@@ -68,13 +68,13 @@ struct Q_GUI_EXPORT QShaderPrivate
+ {
+ }
+
+- QShaderPrivate(const QShaderPrivate *other)
++ QShaderPrivate(const QShaderPrivate &other)
+ : ref(1),
+- qsbVersion(other->qsbVersion),
+- stage(other->stage),
+- desc(other->desc),
+- shaders(other->shaders),
+- bindings(other->bindings)
++ qsbVersion(other.qsbVersion),
++ stage(other.stage),
++ desc(other.desc),
++ shaders(other.shaders),
++ bindings(other.bindings)
+ {
+ }
+
+diff --git a/qtbase/src/gui/rhi/qshaderdescription_p_p.h b/qtbase/src/gui/rhi/qshaderdescription_p_p.h
+index ec2b0b6b4c..3da33a8a2b 100644
+--- a/qtbase/src/gui/rhi/qshaderdescription_p_p.h
++++ b/qtbase/src/gui/rhi/qshaderdescription_p_p.h
+@@ -63,16 +63,16 @@ struct Q_GUI_EXPORT QShaderDescriptionPrivate
+ localSize[0] = localSize[1] = localSize[2] = 0;
+ }
+
+- QShaderDescriptionPrivate(const QShaderDescriptionPrivate *other)
++ QShaderDescriptionPrivate(const QShaderDescriptionPrivate &other)
+ : ref(1),
+- inVars(other->inVars),
+- outVars(other->outVars),
+- uniformBlocks(other->uniformBlocks),
+- pushConstantBlocks(other->pushConstantBlocks),
+- storageBlocks(other->storageBlocks),
+- combinedImageSamplers(other->combinedImageSamplers),
+- storageImages(other->storageImages),
+- localSize(other->localSize)
++ inVars(other.inVars),
++ outVars(other.outVars),
++ uniformBlocks(other.uniformBlocks),
++ pushConstantBlocks(other.pushConstantBlocks),
++ storageBlocks(other.storageBlocks),
++ combinedImageSamplers(other.combinedImageSamplers),
++ storageImages(other.storageImages),
++ localSize(other.localSize)
+ {
+ }
+
+diff --git a/qtbase/src/gui/text/qfontdatabase.cpp b/qtbase/src/gui/text/qfontdatabase.cpp
+index a657a8c516..4fc0100958 100644
+--- a/qtbase/src/gui/text/qfontdatabase.cpp
++++ b/qtbase/src/gui/text/qfontdatabase.cpp
+@@ -983,7 +983,7 @@ QFontEngine *loadSingleEngine(int script,
+ if (style->key.stretch != 0 && request.stretch != 0
+ && (request.styleName.isEmpty() || request.styleName != style->styleName)) {
+ def.stretch = (request.stretch * 100 + style->key.stretch / 2) / style->key.stretch;
+- } else {
++ } else if (request.stretch == QFont::AnyStretch) {
+ def.stretch = 100;
+ }
+
+diff --git a/qtbase/src/gui/text/qtextdocumentlayout.cpp b/qtbase/src/gui/text/qtextdocumentlayout.cpp
+index f3e6ea2100..72267e9380 100644
+--- a/qtbase/src/gui/text/qtextdocumentlayout.cpp
++++ b/qtbase/src/gui/text/qtextdocumentlayout.cpp
+@@ -2123,7 +2123,7 @@ void QTextDocumentLayoutPrivate::drawListItem(const QPointF &offset, QPainter *p
+ {
+ Q_Q(const QTextDocumentLayout);
+ const QTextBlockFormat blockFormat = bl.blockFormat();
+- const QTextCharFormat charFormat = QTextCursor(bl).charFormat();
++ const QTextCharFormat charFormat = bl.charFormat();
+ QFont font(charFormat.font());
+ if (q->paintDevice())
+ font = QFont(font, q->paintDevice());
+diff --git a/qtbase/src/gui/text/qtextengine.cpp b/qtbase/src/gui/text/qtextengine.cpp
+index ce4abac472..a6c66e5d2d 100644
+--- a/qtbase/src/gui/text/qtextengine.cpp
++++ b/qtbase/src/gui/text/qtextengine.cpp
+@@ -1,6 +1,6 @@
+ /****************************************************************************
+ **
+-** Copyright (C) 2016 The Qt Company Ltd.
++** Copyright (C) 2021 The Qt Company Ltd.
+ ** Contact: https://www.qt.io/licensing/
+ **
+ ** This file is part of the QtGui module of the Qt Toolkit.
+@@ -1565,6 +1565,12 @@ void QTextEngine::shapeText(int item) const
+ // Overwrite with 0 token to indicate failure
+ QGlyphLayout g = availableGlyphs(&si);
+ g.glyphs[0] = 0;
++ g.attributes[0].clusterStart = true;
++
++ ushort *log_clusters = logClusters(&si);
++ for (int i = 0; i < itemLength; ++i)
++ log_clusters[i] = 0;
++
+ return;
+ }
+
+diff --git a/qtbase/src/gui/util/qdesktopservices.cpp b/qtbase/src/gui/util/qdesktopservices.cpp
+index fbb63a9408..4d5fafaaa7 100644
+--- a/qtbase/src/gui/util/qdesktopservices.cpp
++++ b/qtbase/src/gui/util/qdesktopservices.cpp
+@@ -54,6 +54,8 @@
+ #include <qpa/qplatformintegration.h>
+ #include <qdir.h>
+
++#include <QtCore/private/qlocking_p.h>
++
+ QT_BEGIN_NAMESPACE
+
+ class QOpenUrlHandlerRegistry : public QObject
+@@ -81,6 +83,7 @@ Q_GLOBAL_STATIC(QOpenUrlHandlerRegistry, handlerRegistry)
+
+ void QOpenUrlHandlerRegistry::handlerDestroyed(QObject *handler)
+ {
++ const auto lock = qt_scoped_lock(mutex);
+ HandlerHash::Iterator it = handlers.begin();
+ while (it != handlers.end()) {
+ if (it->receiver == handler) {
+@@ -294,7 +297,8 @@ void QDesktopServices::setUrlHandler(const QString &scheme, QObject *receiver, c
+ h.name = method;
+ registry->handlers.insert(scheme.toLower(), h);
+ QObject::connect(receiver, SIGNAL(destroyed(QObject*)),
+- registry, SLOT(handlerDestroyed(QObject*)));
++ registry, SLOT(handlerDestroyed(QObject*)),
++ Qt::DirectConnection);
+ }
+
+ /*!
+diff --git a/qtbase/src/gui/util/qpkmhandler.cpp b/qtbase/src/gui/util/qpkmhandler.cpp
+index e0c3b75efe..3414f9d8ba 100644
+--- a/qtbase/src/gui/util/qpkmhandler.cpp
++++ b/qtbase/src/gui/util/qpkmhandler.cpp
+@@ -57,7 +57,7 @@ struct PkmType
+ quint32 bytesPerBlock;
+ };
+
+-static PkmType typeMap[5] = {
++static constexpr PkmType typeMap[5] = {
+ { 0x8D64, 8 }, // GL_ETC1_RGB8_OES
+ { 0x9274, 8 }, // GL_COMPRESSED_RGB8_ETC2
+ { 0, 0 }, // unused (obsolete)
+diff --git a/qtbase/src/network/access/qnetworkreplyfileimpl.cpp b/qtbase/src/network/access/qnetworkreplyfileimpl.cpp
+index b6be93147a..6e69b4c4d3 100644
+--- a/qtbase/src/network/access/qnetworkreplyfileimpl.cpp
++++ b/qtbase/src/network/access/qnetworkreplyfileimpl.cpp
+@@ -89,9 +89,10 @@ QNetworkReplyFileImpl::QNetworkReplyFileImpl(QNetworkAccessManager *manager, con
+ // we handle only local files
+ QString msg = QCoreApplication::translate("QNetworkAccessFileBackend", "Request for opening non-local file %1").arg(url.toString());
+ setError(QNetworkReply::ProtocolInvalidOperationError, msg);
++ setFinished(true); // We're finished, will emit finished() after ctor is done.
+ QMetaObject::invokeMethod(this, "errorOccurred", Qt::QueuedConnection,
+ Q_ARG(QNetworkReply::NetworkError, QNetworkReply::ProtocolInvalidOperationError));
+- fileOpenFinished(false);
++ QMetaObject::invokeMethod(this, [this](){ fileOpenFinished(false); }, Qt::QueuedConnection);
+ return;
+ }
+ #endif
+diff --git a/qtbase/src/network/access/qnetworkreplyimpl.cpp b/qtbase/src/network/access/qnetworkreplyimpl.cpp
+index bcdf6ee2f1..3b6deb82bd 100644
+--- a/qtbase/src/network/access/qnetworkreplyimpl.cpp
++++ b/qtbase/src/network/access/qnetworkreplyimpl.cpp
+@@ -680,7 +680,7 @@ void QNetworkReplyImplPrivate::appendDownstreamData(QIODevice *data)
+ // read until EOF from data
+ if (Q_UNLIKELY(copyDevice)) {
+ qCritical("QNetworkReplyImpl: copy from QIODevice already in progress -- "
+- "backend probly needs to be fixed");
++ "backend probably needs to be fixed");
+ return;
+ }
+
+diff --git a/qtbase/src/network/kernel/qauthenticator.cpp b/qtbase/src/network/kernel/qauthenticator.cpp
+index d9fe7bc47b..ccd04b294a 100644
+--- a/qtbase/src/network/kernel/qauthenticator.cpp
++++ b/qtbase/src/network/kernel/qauthenticator.cpp
+@@ -50,6 +50,7 @@
+ #include <qstring.h>
+ #include <qdatetime.h>
+ #include <qrandom.h>
++#include "private/qsystemlibrary_p.h"
+
+ #ifdef Q_OS_WIN
+ #include <qmutex.h>
+@@ -1563,7 +1564,7 @@ static bool q_SSPI_library_load()
+
+ // Initialize security interface
+ if (pSecurityFunctionTable == nullptr) {
+- securityDLLHandle = LoadLibrary(L"secur32.dll");
++ securityDLLHandle = QSystemLibrary::load(L"secur32");
+ if (securityDLLHandle != nullptr) {
+ INIT_SECURITY_INTERFACE pInitSecurityInterface =
+ reinterpret_cast<INIT_SECURITY_INTERFACE>(
+diff --git a/qtbase/src/network/kernel/qhostinfo_unix.cpp b/qtbase/src/network/kernel/qhostinfo_unix.cpp
+index 9b0a2ee669..73679c9ef1 100644
+--- a/qtbase/src/network/kernel/qhostinfo_unix.cpp
++++ b/qtbase/src/network/kernel/qhostinfo_unix.cpp
+@@ -122,7 +122,6 @@ static QFunctionPointer resolveSymbol(QLibrary &lib, const char *sym)
+
+ LibResolv::LibResolv()
+ {
+- QLibrary lib;
+ #ifdef LIBRESOLV_SO
+ lib.setFileName(QStringLiteral(LIBRESOLV_SO));
+ if (!lib.load())
+diff --git a/qtbase/src/network/socket/qsocks5socketengine.cpp b/qtbase/src/network/socket/qsocks5socketengine.cpp
+index 3a046fd116..97fadca0b3 100644
+--- a/qtbase/src/network/socket/qsocks5socketengine.cpp
++++ b/qtbase/src/network/socket/qsocks5socketengine.cpp
+@@ -1296,7 +1296,7 @@ void QSocks5SocketEnginePrivate::_q_udpSocketReadNotification()
+ int pos = 0;
+ const char *buf = inBuf.constData();
+ if (inBuf.size() < 4) {
+- QSOCKS5_D_DEBUG << "bugus udp data, discarding";
++ QSOCKS5_D_DEBUG << "bogus udp data, discarding";
+ return;
+ }
+ QSocks5RevivedDatagram datagram;
+diff --git a/qtbase/src/network/ssl/qsslcontext_openssl.cpp b/qtbase/src/network/ssl/qsslcontext_openssl.cpp
+index c9f202f573..c992da9d8e 100644
+--- a/qtbase/src/network/ssl/qsslcontext_openssl.cpp
++++ b/qtbase/src/network/ssl/qsslcontext_openssl.cpp
+@@ -409,7 +409,7 @@ init_context:
+ break;
+ case QSsl::DtlsV1_0OrLater:
+ minVersion = DTLS1_VERSION;
+- maxVersion = DTLS_MAX_VERSION;
++ maxVersion = 0;
+ break;
+ case QSsl::DtlsV1_2:
+ minVersion = DTLS1_2_VERSION;
+@@ -417,7 +417,7 @@ init_context:
+ break;
+ case QSsl::DtlsV1_2OrLater:
+ minVersion = DTLS1_2_VERSION;
+- maxVersion = DTLS_MAX_VERSION;
++ maxVersion = 0;
+ break;
+ case QSsl::TlsV1_3OrLater:
+ #ifdef TLS1_3_VERSION
+@@ -455,7 +455,7 @@ init_context:
+ }
+
+ // Enable bug workarounds.
+- long options = QSslSocketBackendPrivate::setupOpenSslOptions(configuration.protocol(), configuration.d->sslOptions);
++ qssloptions options = QSslSocketBackendPrivate::setupOpenSslOptions(configuration.protocol(), configuration.d->sslOptions);
+ q_SSL_CTX_set_options(sslContext->ctx, options);
+
+ // Tell OpenSSL to release memory early
+diff --git a/qtbase/src/network/ssl/qssldiffiehellmanparameters_openssl.cpp b/qtbase/src/network/ssl/qssldiffiehellmanparameters_openssl.cpp
+index aaf8741130..b58935372c 100644
+--- a/qtbase/src/network/ssl/qssldiffiehellmanparameters_openssl.cpp
++++ b/qtbase/src/network/ssl/qssldiffiehellmanparameters_openssl.cpp
+@@ -59,57 +59,6 @@
+
+ QT_BEGIN_NAMESPACE
+
+-#ifdef OPENSSL_NO_DEPRECATED_3_0
+-
+-static int q_DH_check(DH *dh, int *status)
+-{
+- // DH_check was first deprecated in OpenSSL 3.0.0, as low-level
+- // API; the EVP_PKEY family of functions was advised as an alternative.
+- // As of now EVP_PKEY_params_check ends up calling ... DH_check,
+- // which is good enough.
+-
+- Q_ASSERT(dh);
+- Q_ASSERT(status);
+-
+- EVP_PKEY *key = q_EVP_PKEY_new();
+- if (!key) {
+- qCWarning(lcSsl, "EVP_PKEY_new failed");
+- QSslSocketBackendPrivate::logAndClearErrorQueue();
+- return 0;
+- }
+- const auto keyDeleter = qScopeGuard([key](){
+- q_EVP_PKEY_free(key);
+- });
+- if (!q_EVP_PKEY_set1_DH(key, dh)) {
+- qCWarning(lcSsl, "EVP_PKEY_set1_DH failed");
+- QSslSocketBackendPrivate::logAndClearErrorQueue();
+- return 0;
+- }
+-
+- EVP_PKEY_CTX *keyCtx = q_EVP_PKEY_CTX_new(key, nullptr);
+- if (!keyCtx) {
+- qCWarning(lcSsl, "EVP_PKEY_CTX_new failed");
+- QSslSocketBackendPrivate::logAndClearErrorQueue();
+- return 0;
+- }
+- const auto ctxDeleter = qScopeGuard([keyCtx]{
+- q_EVP_PKEY_CTX_free(keyCtx);
+- });
+-
+- const int result = q_EVP_PKEY_param_check(keyCtx);
+- QSslSocketBackendPrivate::logAndClearErrorQueue();
+- // Note: unlike DH_check, we cannot obtain the 'status',
+- // if the 'result' is 0 (actually the result is 1 only
+- // if this 'status' was 0). We could probably check the
+- // errors from the error queue, but it's not needed anyway
+- // - see the 'isSafeDH' below, how it returns immediately
+- // on 0.
+- Q_UNUSED(status)
+-
+- return result;
+-}
+-#endif // OPENSSL_NO_DEPRECATED_3_0
+-
+ static bool isSafeDH(DH *dh)
+ {
+ int status = 0;
+diff --git a/qtbase/src/network/ssl/qsslsocket_openssl.cpp b/qtbase/src/network/ssl/qsslsocket_openssl.cpp
+index 37fad2a68f..8f6858c867 100644
+--- a/qtbase/src/network/ssl/qsslsocket_openssl.cpp
++++ b/qtbase/src/network/ssl/qsslsocket_openssl.cpp
+@@ -550,9 +550,9 @@ static void q_loadCiphersForConnection(SSL *connection, QList<QSslCipher> &ciphe
+ // Defined in qsslsocket.cpp
+ void q_setDefaultDtlsCiphers(const QList<QSslCipher> &ciphers);
+
+-long QSslSocketBackendPrivate::setupOpenSslOptions(QSsl::SslProtocol protocol, QSsl::SslOptions sslOptions)
++qssloptions QSslSocketBackendPrivate::setupOpenSslOptions(QSsl::SslProtocol protocol, QSsl::SslOptions sslOptions)
+ {
+- long options;
++ qssloptions options;
+ if (protocol == QSsl::TlsV1SslV3)
+ options = SSL_OP_ALL|SSL_OP_NO_SSLv2|SSL_OP_NO_SSLv3;
+ else if (protocol == QSsl::SecureProtocols)
+diff --git a/qtbase/src/network/ssl/qsslsocket_openssl_p.h b/qtbase/src/network/ssl/qsslsocket_openssl_p.h
+index 4103de23e8..5547589256 100644
+--- a/qtbase/src/network/ssl/qsslsocket_openssl_p.h
++++ b/qtbase/src/network/ssl/qsslsocket_openssl_p.h
+@@ -107,6 +107,12 @@
+
+ QT_BEGIN_NAMESPACE
+
++#if defined(OPENSSL_VERSION_MAJOR) && OPENSSL_VERSION_MAJOR >= 3
++typedef uint64_t qssloptions;
++#else
++typedef unsigned long qssloptions;
++#endif
++
+ struct QSslErrorEntry {
+ int code;
+ int depth;
+@@ -171,7 +177,7 @@ public:
+ QVector<QSslError> ocspErrors;
+ QByteArray ocspResponseDer;
+
+- Q_AUTOTEST_EXPORT static long setupOpenSslOptions(QSsl::SslProtocol protocol, QSsl::SslOptions sslOptions);
++ Q_AUTOTEST_EXPORT static qssloptions setupOpenSslOptions(QSsl::SslProtocol protocol, QSsl::SslOptions sslOptions);
+ static QSslCipher QSslCipher_from_SSL_CIPHER(const SSL_CIPHER *cipher);
+ static QList<QSslCertificate> STACKOFX509_to_QSslCertificates(STACK_OF(X509) *x509);
+ static QList<QSslError> verify(const QList<QSslCertificate> &certificateChain, const QString &hostName);
+diff --git a/qtbase/src/network/ssl/qsslsocket_openssl_symbols.cpp b/qtbase/src/network/ssl/qsslsocket_openssl_symbols.cpp
+index e53fb279f0..459ccd0b19 100644
+--- a/qtbase/src/network/ssl/qsslsocket_openssl_symbols.cpp
++++ b/qtbase/src/network/ssl/qsslsocket_openssl_symbols.cpp
+@@ -148,7 +148,6 @@ DEFINEFUNC(int, EVP_PKEY_up_ref, EVP_PKEY *a, a, return 0, return)
+ DEFINEFUNC2(EVP_PKEY_CTX *, EVP_PKEY_CTX_new, EVP_PKEY *pkey, pkey, ENGINE *e, e, return nullptr, return)
+ DEFINEFUNC(int, EVP_PKEY_param_check, EVP_PKEY_CTX *ctx, ctx, return 0, return)
+ DEFINEFUNC(void, EVP_PKEY_CTX_free, EVP_PKEY_CTX *ctx, ctx, return, return)
+-DEFINEFUNC(int, EVP_PKEY_base_id, EVP_PKEY *a, a, return NID_undef, return)
+ DEFINEFUNC(int, RSA_bits, RSA *a, a, return 0, return)
+ DEFINEFUNC(int, DSA_bits, DSA *a, a, return 0, return)
+ DEFINEFUNC(int, OPENSSL_sk_num, OPENSSL_STACK *a, a, return -1, return)
+@@ -158,7 +157,7 @@ DEFINEFUNC2(void, OPENSSL_sk_push, OPENSSL_STACK *a, a, void *b, b, return, DUMM
+ DEFINEFUNC(void, OPENSSL_sk_free, OPENSSL_STACK *a, a, return, DUMMYARG)
+ DEFINEFUNC2(void *, OPENSSL_sk_value, OPENSSL_STACK *a, a, int b, b, return nullptr, return)
+ DEFINEFUNC(int, SSL_session_reused, SSL *a, a, return 0, return)
+-DEFINEFUNC2(unsigned long, SSL_CTX_set_options, SSL_CTX *ctx, ctx, unsigned long op, op, return 0, return)
++DEFINEFUNC2(qssloptions, SSL_CTX_set_options, SSL_CTX *ctx, ctx, qssloptions op, op, return 0, return)
+ DEFINEFUNC(int, SSL_CTX_get_security_level, const SSL_CTX *ctx, ctx, return -1, return)
+ DEFINEFUNC2(void, SSL_CTX_set_security_level, SSL_CTX *ctx, ctx, int level, level, return, return)
+ #ifdef TLS1_3_VERSION
+@@ -371,7 +370,15 @@ DEFINEFUNC(const SSL_CIPHER *, SSL_get_current_cipher, SSL *a, a, return nullptr
+ DEFINEFUNC(int, SSL_version, const SSL *a, a, return 0, return)
+ DEFINEFUNC2(int, SSL_get_error, SSL *a, a, int b, b, return -1, return)
+ DEFINEFUNC(STACK_OF(X509) *, SSL_get_peer_cert_chain, SSL *a, a, return nullptr, return)
++
++#if defined(OPENSSL_VERSION_MAJOR) && OPENSSL_VERSION_MAJOR >= 3
++DEFINEFUNC(X509 *, SSL_get1_peer_certificate, SSL *a, a, return nullptr, return)
++DEFINEFUNC(int, EVP_PKEY_get_base_id, const EVP_PKEY *pkey, pkey, return -1, return)
++#else
+ DEFINEFUNC(X509 *, SSL_get_peer_certificate, SSL *a, a, return nullptr, return)
++DEFINEFUNC(int, EVP_PKEY_base_id, EVP_PKEY *a, a, return NID_undef, return)
++#endif // OPENSSL_VERSION_MAJOR >= 3
++
+ DEFINEFUNC(long, SSL_get_verify_result, const SSL *a, a, return -1, return)
+ DEFINEFUNC(SSL *, SSL_new, SSL_CTX *a, a, return nullptr, return)
+ DEFINEFUNC(SSL_CTX *, SSL_get_SSL_CTX, SSL *a, a, return nullptr, return)
+@@ -492,9 +499,7 @@ DEFINEFUNC(DH *, DH_new, DUMMYARG, DUMMYARG, return nullptr, return)
+ DEFINEFUNC(void, DH_free, DH *dh, dh, return, DUMMYARG)
+ DEFINEFUNC3(DH *, d2i_DHparams, DH**a, a, const unsigned char **pp, pp, long length, length, return nullptr, return)
+ DEFINEFUNC2(int, i2d_DHparams, DH *a, a, unsigned char **p, p, return -1, return)
+-#ifndef OPENSSL_NO_DEPRECATED_3_0
+ DEFINEFUNC2(int, DH_check, DH *dh, dh, int *codes, codes, return 0, return)
+-#endif // OPENSSL_NO_DEPRECATED_3_0
+ DEFINEFUNC3(BIGNUM *, BN_bin2bn, const unsigned char *s, s, int len, len, BIGNUM *ret, ret, return nullptr, return)
+
+ #ifndef OPENSSL_NO_EC
+@@ -868,7 +873,6 @@ bool q_resolveOpenSslSymbols()
+ RESOLVEFUNC(EVP_PKEY_CTX_new)
+ RESOLVEFUNC(EVP_PKEY_param_check)
+ RESOLVEFUNC(EVP_PKEY_CTX_free)
+- RESOLVEFUNC(EVP_PKEY_base_id)
+ RESOLVEFUNC(RSA_bits)
+ RESOLVEFUNC(OPENSSL_sk_new_null)
+ RESOLVEFUNC(OPENSSL_sk_push)
+@@ -1107,7 +1111,15 @@ bool q_resolveOpenSslSymbols()
+ RESOLVEFUNC(SSL_version)
+ RESOLVEFUNC(SSL_get_error)
+ RESOLVEFUNC(SSL_get_peer_cert_chain)
++
++#if defined(OPENSSL_VERSION_MAJOR) && OPENSSL_VERSION_MAJOR >= 3
++ RESOLVEFUNC(SSL_get1_peer_certificate)
++ RESOLVEFUNC(EVP_PKEY_get_base_id)
++#else
+ RESOLVEFUNC(SSL_get_peer_certificate)
++ RESOLVEFUNC(EVP_PKEY_base_id)
++#endif // OPENSSL_VERSION_MAJOR >= 3
++
+ RESOLVEFUNC(SSL_get_verify_result)
+ RESOLVEFUNC(SSL_new)
+ RESOLVEFUNC(SSL_get_SSL_CTX)
+@@ -1206,9 +1218,7 @@ bool q_resolveOpenSslSymbols()
+ RESOLVEFUNC(DH_free)
+ RESOLVEFUNC(d2i_DHparams)
+ RESOLVEFUNC(i2d_DHparams)
+-#ifndef OPENSSL_NO_DEPRECATED_3_0
+ RESOLVEFUNC(DH_check)
+-#endif // OPENSSL_NO_DEPRECATED_3_0
+ RESOLVEFUNC(BN_bin2bn)
+
+ #ifndef OPENSSL_NO_EC
+diff --git a/qtbase/src/network/ssl/qsslsocket_openssl_symbols_p.h b/qtbase/src/network/ssl/qsslsocket_openssl_symbols_p.h
+index 95e8897a3b..27aeffa18a 100644
+--- a/qtbase/src/network/ssl/qsslsocket_openssl_symbols_p.h
++++ b/qtbase/src/network/ssl/qsslsocket_openssl_symbols_p.h
+@@ -237,7 +237,6 @@ Q_AUTOTEST_EXPORT int q_EVP_PKEY_up_ref(EVP_PKEY *a);
+ EVP_PKEY_CTX *q_EVP_PKEY_CTX_new(EVP_PKEY *pkey, ENGINE *e);
+ void q_EVP_PKEY_CTX_free(EVP_PKEY_CTX *ctx);
+ int q_EVP_PKEY_param_check(EVP_PKEY_CTX *ctx);
+-int q_EVP_PKEY_base_id(EVP_PKEY *a);
+ int q_RSA_bits(RSA *a);
+ Q_AUTOTEST_EXPORT int q_OPENSSL_sk_num(OPENSSL_STACK *a);
+ Q_AUTOTEST_EXPORT void q_OPENSSL_sk_pop_free(OPENSSL_STACK *a, void (*b)(void *));
+@@ -246,7 +245,7 @@ Q_AUTOTEST_EXPORT void q_OPENSSL_sk_push(OPENSSL_STACK *st, void *data);
+ Q_AUTOTEST_EXPORT void q_OPENSSL_sk_free(OPENSSL_STACK *a);
+ Q_AUTOTEST_EXPORT void * q_OPENSSL_sk_value(OPENSSL_STACK *a, int b);
+ int q_SSL_session_reused(SSL *a);
+-unsigned long q_SSL_CTX_set_options(SSL_CTX *ctx, unsigned long op);
++qssloptions q_SSL_CTX_set_options(SSL_CTX *ctx, qssloptions op);
+ int q_OPENSSL_init_ssl(uint64_t opts, const OPENSSL_INIT_SETTINGS *settings);
+ size_t q_SSL_get_client_random(SSL *a, unsigned char *out, size_t outlen);
+ size_t q_SSL_SESSION_get_master_key(const SSL_SESSION *session, unsigned char *out, size_t outlen);
+@@ -510,7 +509,6 @@ const SSL_CIPHER *q_SSL_get_current_cipher(SSL *a);
+ int q_SSL_version(const SSL *a);
+ int q_SSL_get_error(SSL *a, int b);
+ STACK_OF(X509) *q_SSL_get_peer_cert_chain(SSL *a);
+-X509 *q_SSL_get_peer_certificate(SSL *a);
+ long q_SSL_get_verify_result(const SSL *a);
+ SSL *q_SSL_new(SSL_CTX *a);
+ SSL_CTX *q_SSL_get_SSL_CTX(SSL *a);
+@@ -582,10 +580,7 @@ DH *q_DH_new();
+ void q_DH_free(DH *dh);
+ DH *q_d2i_DHparams(DH **a, const unsigned char **pp, long length);
+ int q_i2d_DHparams(DH *a, unsigned char **p);
+-
+-#ifndef OPENSSL_NO_DEPRECATED_3_0
+ int q_DH_check(DH *dh, int *codes);
+-#endif // OPENSSL_NO_DEPRECATED_3_0
+
+ BIGNUM *q_BN_bin2bn(const unsigned char *s, int len, BIGNUM *ret);
+ #define q_SSL_CTX_set_tmp_dh(ctx, dh) q_SSL_CTX_ctrl((ctx), SSL_CTRL_SET_TMP_DH, 0, (char *)dh)
+@@ -754,6 +749,17 @@ void q_CRYPTO_free(void *str, const char *file, int line);
+ int q_SSL_CTX_get_security_level(const SSL_CTX *ctx);
+ void q_SSL_CTX_set_security_level(SSL_CTX *ctx, int level);
+
++// Here we have the ones that make difference between OpenSSL pre/post v3:
++#if defined(OPENSSL_VERSION_MAJOR) && OPENSSL_VERSION_MAJOR >= 3
++X509 *q_SSL_get1_peer_certificate(SSL *a);
++#define q_SSL_get_peer_certificate q_SSL_get1_peer_certificate
++int q_EVP_PKEY_get_base_id(const EVP_PKEY *pkey);
++#define q_EVP_PKEY_base_id q_EVP_PKEY_get_base_id
++#else
++X509 *q_SSL_get_peer_certificate(SSL *a);
++int q_EVP_PKEY_base_id(EVP_PKEY *a);
++#endif // OPENSSL_VERSION_MAJOR >= 3
++
+ QT_END_NAMESPACE
+
+ #endif
+diff --git a/qtbase/src/platformsupport/eglconvenience/qt_egl_p.h b/qtbase/src/platformsupport/eglconvenience/qt_egl_p.h
+index bf37d07fd8..dbd42fb799 100644
+--- a/qtbase/src/platformsupport/eglconvenience/qt_egl_p.h
++++ b/qtbase/src/platformsupport/eglconvenience/qt_egl_p.h
+@@ -61,7 +61,11 @@
+ # if !defined(Q_OS_INTEGRITY)
+ # define WIN_INTERFACE_CUSTOM // NV
+ # endif // Q_OS_INTEGRITY
+-#endif // QT_EGL_NO_X11
++#else // QT_EGL_NO_X11
++// If one has an eglplatform.h with https://github.com/KhronosGroup/EGL-Registry/pull/130
++// that needs USE_X11 to be defined.
++# define USE_X11
++#endif
+
+ #ifdef QT_EGL_WAYLAND
+ # define WAYLAND // NV
+diff --git a/qtbase/src/platformsupport/fontdatabases/fontconfig/qfontconfigdatabase.cpp b/qtbase/src/platformsupport/fontdatabases/fontconfig/qfontconfigdatabase.cpp
+index 159b490ce0..00aa80cd58 100644
+--- a/qtbase/src/platformsupport/fontdatabases/fontconfig/qfontconfigdatabase.cpp
++++ b/qtbase/src/platformsupport/fontdatabases/fontconfig/qfontconfigdatabase.cpp
+@@ -567,6 +567,8 @@ void QFontconfigDatabase::populateFontDatabase()
+ fonts = FcFontList(nullptr, pattern, os);
+ FcObjectSetDestroy(os);
+ FcPatternDestroy(pattern);
++ if (!fonts)
++ return;
+ }
+
+ for (int i = 0; i < fonts->nfont; i++)
+diff --git a/qtbase/src/platformsupport/input/xkbcommon/qxkbcommon.cpp b/qtbase/src/platformsupport/input/xkbcommon/qxkbcommon.cpp
+index b713c19447..7cb9a8c79a 100644
+--- a/qtbase/src/platformsupport/input/xkbcommon/qxkbcommon.cpp
++++ b/qtbase/src/platformsupport/input/xkbcommon/qxkbcommon.cpp
+@@ -95,6 +95,7 @@ static constexpr const auto KeyTbl = qMakeArray(
+ Xkb2Qt<XKB_KEY_Clear, Qt::Key_Delete>,
+ Xkb2Qt<XKB_KEY_Pause, Qt::Key_Pause>,
+ Xkb2Qt<XKB_KEY_Print, Qt::Key_Print>,
++ Xkb2Qt<XKB_KEY_Sys_Req, Qt::Key_SysReq>,
+ Xkb2Qt<0x1005FF60, Qt::Key_SysReq>, // hardcoded Sun SysReq
+ Xkb2Qt<0x1007ff00, Qt::Key_SysReq>, // hardcoded X386 SysReq
+
+@@ -471,7 +472,7 @@ QVector<xkb_keysym_t> QXkbCommon::toKeysym(QKeyEvent *event)
+ } else if (event->modifiers() & Qt::KeypadModifier) {
+ if (qtKey >= Qt::Key_0 && qtKey <= Qt::Key_9)
+ keysyms.append(XKB_KEY_KP_0 + (qtKey - Qt::Key_0));
+- } else if (isLatin(qtKey) && event->text().isUpper()) {
++ } else if (isLatin1(qtKey) && event->text().isUpper()) {
+ keysyms.append(qtKey);
+ }
+
+@@ -523,7 +524,7 @@ int QXkbCommon::keysymToQtKey(xkb_keysym_t keysym, Qt::KeyboardModifiers modifie
+ // With standard shortcuts we should prefer a latin character, this is
+ // for checks like "some qkeyevent == QKeySequence::Copy" to work even
+ // when using for example 'russian' keyboard layout.
+- if (!QXkbCommon::isLatin(keysym)) {
++ if (!QXkbCommon::isLatin1(keysym)) {
+ xkb_keysym_t latinKeysym = QXkbCommon::lookupLatinKeysym(state, code);
+ if (latinKeysym != XKB_KEY_NoSymbol)
+ keysym = latinKeysym;
+@@ -546,7 +547,7 @@ static int keysymToQtKey_internal(xkb_keysym_t keysym, Qt::KeyboardModifiers mod
+ } else if (keysym >= XKB_KEY_KP_0 && keysym <= XKB_KEY_KP_9) {
+ // numeric keypad keys
+ qtKey = Qt::Key_0 + (keysym - XKB_KEY_KP_0);
+- } else if (QXkbCommon::isLatin(keysym)) {
++ } else if (QXkbCommon::isLatin1(keysym)) {
+ qtKey = QXkbCommon::qxkbcommon_xkb_keysym_to_upper(keysym);
+ } else {
+ // check if we have a direct mapping
+@@ -678,7 +679,7 @@ QList<int> QXkbCommon::possibleKeys(xkb_state *state, const QKeyEvent *event,
+ Qt::KeyboardModifiers neededMods = ModsTbl[i];
+ if ((modifiers & neededMods) == neededMods) {
+ if (i == 8) {
+- if (isLatin(baseQtKey))
++ if (isLatin1(baseQtKey))
+ continue;
+ // add a latin key as a fall back key
+ sym = lookupLatinKeysym(state, keycode);
+@@ -733,7 +734,7 @@ void QXkbCommon::verifyHasLatinLayout(xkb_keymap *keymap)
+ for (xkb_layout_index_t layout = 0; layout < layoutCount; ++layout) {
+ for (xkb_keycode_t code = minKeycode; code < maxKeycode; ++code) {
+ xkb_keymap_key_get_syms_by_level(keymap, code, layout, 0, &keysyms);
+- if (keysyms && isLatin(keysyms[0]))
++ if (keysyms && isLatin1(keysyms[0]))
+ nrLatinKeys++;
+ if (nrLatinKeys > 10) // arbitrarily chosen threshold
+ return;
+@@ -766,7 +767,7 @@ xkb_keysym_t QXkbCommon::lookupLatinKeysym(xkb_state *state, xkb_keycode_t keyco
+ xkb_level_index_t level = xkb_state_key_get_level(state, keycode, layout);
+ if (xkb_keymap_key_get_syms_by_level(keymap, keycode, layout, level, &syms) != 1)
+ continue;
+- if (isLatin(syms[0])) {
++ if (isLatin1(syms[0])) {
+ sym = syms[0];
+ break;
+ }
+diff --git a/qtbase/src/platformsupport/input/xkbcommon/qxkbcommon_p.h b/qtbase/src/platformsupport/input/xkbcommon/qxkbcommon_p.h
+index 561eae03db..8389bd8f5a 100644
+--- a/qtbase/src/platformsupport/input/xkbcommon/qxkbcommon_p.h
++++ b/qtbase/src/platformsupport/input/xkbcommon/qxkbcommon_p.h
+@@ -94,8 +94,8 @@ public:
+ static void verifyHasLatinLayout(xkb_keymap *keymap);
+ static xkb_keysym_t lookupLatinKeysym(xkb_state *state, xkb_keycode_t keycode);
+
+- static bool isLatin(xkb_keysym_t sym) {
+- return ((sym >= 'a' && sym <= 'z') || (sym >= 'A' && sym <= 'Z'));
++ static bool isLatin1(xkb_keysym_t sym) {
++ return sym <= 0xff;
+ }
+ static bool isKeypad(xkb_keysym_t sym) {
+ return sym >= XKB_KEY_KP_Space && sym <= XKB_KEY_KP_9;
+diff --git a/qtbase/src/platformsupport/kmsconvenience/qkmsdevice.cpp b/qtbase/src/platformsupport/kmsconvenience/qkmsdevice.cpp
+index 8cd7f9b368..406f84663f 100644
+--- a/qtbase/src/platformsupport/kmsconvenience/qkmsdevice.cpp
++++ b/qtbase/src/platformsupport/kmsconvenience/qkmsdevice.cpp
+@@ -318,7 +318,7 @@ QPlatformScreen *QKmsDevice::createScreenForConnector(drmModeResPtr resources,
+
+ if (current < 0 && crtc_mode.clock != 0) {
+ modes << crtc_mode;
+- current = mode.size() - 1;
++ current = modes.size() - 1;
+ }
+
+ if (configuration == OutputConfigCurrent)
+diff --git a/qtbase/src/platformsupport/linuxaccessibility/atspiadaptor.cpp b/qtbase/src/platformsupport/linuxaccessibility/atspiadaptor.cpp
+index 9153fd20bb..255ea5e33e 100644
+--- a/qtbase/src/platformsupport/linuxaccessibility/atspiadaptor.cpp
++++ b/qtbase/src/platformsupport/linuxaccessibility/atspiadaptor.cpp
+@@ -194,6 +194,9 @@ QString AtSpiAdaptor::introspect(const QString &path) const
+ " <arg direction=\"out\" type=\"(so)\"/>\n"
+ " <annotation value=\"QSpiObjectReference\" name=\"org.qtproject.QtDBus.QtTypeName.Out0\"/>\n"
+ " </method>\n"
++ " <method name=\"GetAccessibleId\">\n"
++ " <arg direction=\"out\" type=\"s\"/>\n"
++ " </method>\n"
+ " </interface>\n"
+ );
+
+@@ -913,8 +916,17 @@ void AtSpiAdaptor::notify(QAccessibleEvent *event)
+ }
+ case QAccessible::NameChanged: {
+ if (sendObject || sendObject_property_change || sendObject_property_change_accessible_name) {
+- QString path = pathForInterface(event->accessibleInterface());
+- QVariantList args = packDBusSignalArguments(QLatin1String("accessible-name"), 0, 0, variantForPath(path));
++ QAccessibleInterface *iface = event->accessibleInterface();
++ if (!iface) {
++ qCDebug(lcAccessibilityAtspi,
++ "NameChanged event from invalid accessible.");
++ return;
++ }
++
++ QString path = pathForInterface(iface);
++ QVariantList args = packDBusSignalArguments(
++ QLatin1String("accessible-name"), 0, 0,
++ QVariant::fromValue(QDBusVariant(iface->text(QAccessible::Name))));
+ sendDBusSignal(path, QLatin1String(ATSPI_DBUS_INTERFACE_EVENT_OBJECT),
+ QLatin1String("PropertyChange"), args);
+ }
+@@ -922,8 +934,17 @@ void AtSpiAdaptor::notify(QAccessibleEvent *event)
+ }
+ case QAccessible::DescriptionChanged: {
+ if (sendObject || sendObject_property_change || sendObject_property_change_accessible_description) {
+- QString path = pathForInterface(event->accessibleInterface());
+- QVariantList args = packDBusSignalArguments(QLatin1String("accessible-description"), 0, 0, variantForPath(path));
++ QAccessibleInterface *iface = event->accessibleInterface();
++ if (!iface) {
++ qCDebug(lcAccessibilityAtspi,
++ "DescriptionChanged event from invalid accessible.");
++ return;
++ }
++
++ QString path = pathForInterface(iface);
++ QVariantList args = packDBusSignalArguments(
++ QLatin1String("accessible-description"), 0, 0,
++ QVariant::fromValue(QDBusVariant(iface->text(QAccessible::Description))));
+ sendDBusSignal(path, QLatin1String(ATSPI_DBUS_INTERFACE_EVENT_OBJECT),
+ QLatin1String("PropertyChange"), args);
+ }
+@@ -1038,7 +1059,9 @@ void AtSpiAdaptor::notify(QAccessibleEvent *event)
+ // Combo Box with AT-SPI likes to be special
+ // It requires a name-change to update caches and then selection-changed
+ QString path = pathForInterface(iface);
+- QVariantList args1 = packDBusSignalArguments(QLatin1String("accessible-name"), 0, 0, variantForPath(path));
++ QVariantList args1 = packDBusSignalArguments(
++ QLatin1String("accessible-name"), 0, 0,
++ QVariant::fromValue(QDBusVariant(iface->text(QAccessible::Name))));
+ sendDBusSignal(path, QLatin1String(ATSPI_DBUS_INTERFACE_EVENT_OBJECT),
+ QLatin1String("PropertyChange"), args1);
+ QVariantList args2 = packDBusSignalArguments(QString(), 0, 0, QVariant::fromValue(QDBusVariant(QVariant(0))));
+@@ -1358,6 +1381,26 @@ void AtSpiAdaptor::registerApplication()
+ delete registry;
+ }
+
++namespace {
++QString accessibleIdForAccessible(QAccessibleInterface *accessible)
++{
++ QString result;
++ while (accessible) {
++ if (!result.isEmpty())
++ result.prepend(QLatin1Char('.'));
++ if (auto obj = accessible->object()) {
++ const QString name = obj->objectName();
++ if (!name.isEmpty())
++ result.prepend(name);
++ else
++ result.prepend(QString::fromUtf8(obj->metaObject()->className()));
++ }
++ accessible = accessible->parent();
++ }
++ return result;
++}
++} // namespace
++
+ // Accessible
+ bool AtSpiAdaptor::accessibleInterface(QAccessibleInterface *interface, const QString &function, const QDBusMessage &message, const QDBusConnection &connection)
+ {
+@@ -1441,6 +1484,9 @@ bool AtSpiAdaptor::accessibleInterface(QAccessibleInterface *interface, const QS
+ children << ref;
+ }
+ connection.send(message.createReply(QVariant::fromValue(children)));
++ } else if (function == QLatin1String("GetAccessibleId")) {
++ sendReply(connection, message,
++ QVariant::fromValue(QDBusVariant(accessibleIdForAccessible(interface))));
+ } else {
+ qCDebug(lcAccessibilityAtspi) << "WARNING: AtSpiAdaptor::accessibleInterface does not implement " << function << message.path();
+ return false;
+diff --git a/qtbase/src/platformsupport/linuxaccessibility/dbusconnection.cpp b/qtbase/src/platformsupport/linuxaccessibility/dbusconnection.cpp
+index 45ddc8e496..cc734abc63 100644
+--- a/qtbase/src/platformsupport/linuxaccessibility/dbusconnection.cpp
++++ b/qtbase/src/platformsupport/linuxaccessibility/dbusconnection.cpp
+@@ -69,6 +69,21 @@ QT_BEGIN_NAMESPACE
+ DBusConnection::DBusConnection(QObject *parent)
+ : QObject(parent), m_a11yConnection(QString()), m_enabled(false)
+ {
++ // If the bus is explicitly set via env var it overrides everything else.
++ QByteArray addressEnv = qgetenv("AT_SPI_BUS_ADDRESS");
++ if (!addressEnv.isEmpty()) {
++ // Only connect on next loop run, connections to our enabled signal are
++ // only established after the ctor returns.
++ QMetaObject::invokeMethod(
++ this,
++ [this, addressEnv] {
++ m_enabled = true;
++ connectA11yBus(QString::fromLocal8Bit(addressEnv));
++ },
++ Qt::QueuedConnection);
++ return;
++ }
++
+ // Start monitoring if "org.a11y.Bus" is registered as DBus service.
+ QDBusConnection c = QDBusConnection::sessionBus();
+ if (!c.isConnected()) {
+diff --git a/qtbase/src/platformsupport/services/genericunix/qgenericunixservices.cpp b/qtbase/src/platformsupport/services/genericunix/qgenericunixservices.cpp
+index 1a3cab275d..2abe039126 100644
+--- a/qtbase/src/platformsupport/services/genericunix/qgenericunixservices.cpp
++++ b/qtbase/src/platformsupport/services/genericunix/qgenericunixservices.cpp
+@@ -51,6 +51,9 @@
+ #include <QtCore/QStandardPaths>
+ #include <QtCore/QUrl>
+
++#include <QtGui/QGuiApplication>
++#include <QtGui/QWindow>
++
+ #if QT_CONFIG(dbus)
+ // These QtCore includes are needed for xdg-desktop-portal support
+ #include <QtCore/private/qcore_unix_p.h>
+@@ -58,6 +61,8 @@
+ #include <QtCore/QFileInfo>
+ #include <QtCore/QUrlQuery>
+
++#include <QtGui/QColor>
++
+ #include <QtDBus/QDBusConnection>
+ #include <QtDBus/QDBusMessage>
+ #include <QtDBus/QDBusPendingCall>
+@@ -142,6 +147,8 @@ static inline bool detectWebBrowser(const QByteArray &desktop,
+ }
+
+ if (desktop == QByteArray("KDE")) {
++ if (checkExecutable(QStringLiteral("kde-open5"), browser))
++ return true;
+ // Konqueror launcher
+ if (checkExecutable(QStringLiteral("kfmclient"), browser)) {
+ browser->append(QLatin1String(" exec"));
+@@ -296,8 +303,135 @@ static inline QDBusMessage xdgDesktopPortalSendEmail(const QUrl &url)
+
+ return QDBusConnection::sessionBus().call(message);
+ }
++
++namespace {
++struct XDGDesktopColor
++{
++ double r = 0;
++ double g = 0;
++ double b = 0;
++
++ QColor toQColor() const
++ {
++ constexpr auto rgbMax = 255;
++ return { static_cast<int>(r * rgbMax), static_cast<int>(g * rgbMax),
++ static_cast<int>(b * rgbMax) };
++ }
++};
++
++const QDBusArgument &operator>>(const QDBusArgument &argument, XDGDesktopColor &myStruct)
++{
++ argument.beginStructure();
++ argument >> myStruct.r >> myStruct.g >> myStruct.b;
++ argument.endStructure();
++ return argument;
++}
++
++class XdgDesktopPortalColorPicker : public QPlatformServiceColorPicker
++{
++ Q_OBJECT
++public:
++ XdgDesktopPortalColorPicker(const QString &parentWindowId, QWindow *parent)
++ : QPlatformServiceColorPicker(parent), m_parentWindowId(parentWindowId)
++ {
++ }
++
++ void pickColor() override
++ {
++ // DBus signature:
++ // PickColor (IN s parent_window,
++ // IN a{sv} options
++ // OUT o handle)
++ // Options:
++ // handle_token (s) - A string that will be used as the last element of the @handle.
++
++ QDBusMessage message = QDBusMessage::createMethodCall(
++ QStringLiteral("org.freedesktop.portal.Desktop"), QStringLiteral("/org/freedesktop/portal/desktop"),
++ QStringLiteral("org.freedesktop.portal.Screenshot"), QStringLiteral("PickColor"));
++ message << m_parentWindowId << QVariantMap();
++
++ QDBusPendingCall pendingCall = QDBusConnection::sessionBus().asyncCall(message);
++ auto watcher = new QDBusPendingCallWatcher(pendingCall, this);
++ connect(watcher, &QDBusPendingCallWatcher::finished, this,
++ [this](QDBusPendingCallWatcher *watcher) {
++ watcher->deleteLater();
++ QDBusPendingReply<QDBusObjectPath> reply = *watcher;
++ if (reply.isError()) {
++ qWarning("DBus call to pick color failed: %s",
++ qPrintable(reply.error().message()));
++ Q_EMIT colorPicked({});
++ } else {
++ QDBusConnection::sessionBus().connect(
++ QStringLiteral("org.freedesktop.portal.Desktop"), reply.value().path(),
++ QStringLiteral("org.freedesktop.portal.Request"), QStringLiteral("Response"), this,
++ // clang-format off
++ SLOT(gotColorResponse(uint,QVariantMap))
++ // clang-format on
++ );
++ }
++ });
++ }
++
++private Q_SLOTS:
++ void gotColorResponse(uint result, const QVariantMap &map)
++ {
++ if (result != 0)
++ return;
++ XDGDesktopColor color{};
++ map.value(QStringLiteral("color")).value<QDBusArgument>() >> color;
++ Q_EMIT colorPicked(color.toQColor());
++ deleteLater();
++ }
++
++private:
++ const QString m_parentWindowId;
++};
++} // namespace
++
+ #endif // QT_CONFIG(dbus)
+
++QGenericUnixServices::QGenericUnixServices()
++{
++#if QT_CONFIG(dbus)
++ if (qEnvironmentVariableIntValue("QT_NO_XDG_DESKTOP_PORTAL") > 0) {
++ return;
++ }
++ QDBusMessage message = QDBusMessage::createMethodCall(
++ QStringLiteral("org.freedesktop.portal.Desktop"), QStringLiteral("/org/freedesktop/portal/desktop"),
++ QStringLiteral("org.freedesktop.DBus.Properties"), QStringLiteral("Get"));
++ message << QStringLiteral("org.freedesktop.portal.Screenshot")
++ << QStringLiteral("version");
++
++ QDBusPendingCall pendingCall = QDBusConnection::sessionBus().asyncCall(message);
++ auto watcher = new QDBusPendingCallWatcher(pendingCall);
++ QObject::connect(watcher, &QDBusPendingCallWatcher::finished, watcher,
++ [this](QDBusPendingCallWatcher *watcher) {
++ watcher->deleteLater();
++ QDBusPendingReply<QVariant> reply = *watcher;
++ if (!reply.isError() && reply.value().toUInt() >= 2)
++ m_hasScreenshotPortalWithColorPicking = true;
++ });
++
++#endif
++}
++
++QPlatformServiceColorPicker *QGenericUnixServices::colorPicker(QWindow *parent)
++{
++#if QT_CONFIG(dbus)
++ // Make double sure that we are in a wayland environment. In particular check
++ // WAYLAND_DISPLAY so also XWayland apps benefit from portal-based color picking.
++ // Outside wayland we'll rather rely on other means than the XDG desktop portal.
++ if (!qEnvironmentVariableIsEmpty("WAYLAND_DISPLAY")
++ || QGuiApplication::platformName().startsWith(QLatin1String("wayland"))) {
++ return new XdgDesktopPortalColorPicker(portalWindowIdentifier(parent), parent);
++ }
++ return nullptr;
++#else
++ Q_UNUSED(parent);
++ return nullptr;
++#endif
++}
++
+ QByteArray QGenericUnixServices::desktopEnvironment() const
+ {
+ static const QByteArray result = detectDesktopEnvironment();
+@@ -352,6 +486,8 @@ bool QGenericUnixServices::openDocument(const QUrl &url)
+ }
+
+ #else
++QGenericUnixServices::QGenericUnixServices() = default;
++
+ QByteArray QGenericUnixServices::desktopEnvironment() const
+ {
+ return QByteArrayLiteral("UNKNOWN");
+@@ -371,6 +507,30 @@ bool QGenericUnixServices::openDocument(const QUrl &url)
+ return false;
+ }
+
++QPlatformServiceColorPicker *QGenericUnixServices::colorPicker(QWindow *parent)
++{
++ Q_UNUSED(parent);
++ return nullptr;
++}
++
+ #endif // QT_NO_MULTIPROCESS
+
++QString QGenericUnixServices::portalWindowIdentifier(QWindow *window)
++{
++ if (QGuiApplication::platformName() == QLatin1String("xcb"))
++ return QStringLiteral("x11:") + QString::number(window->winId(), 16);
++ return QString();
++}
++
++bool QGenericUnixServices::hasCapability(Capability capability) const
++{
++ switch (capability) {
++ case Capability::ColorPicking:
++ return m_hasScreenshotPortalWithColorPicking;
++ }
++ return false;
++}
++
+ QT_END_NAMESPACE
++
++#include "qgenericunixservices.moc"
+diff --git a/qtbase/src/platformsupport/services/genericunix/qgenericunixservices_p.h b/qtbase/src/platformsupport/services/genericunix/qgenericunixservices_p.h
+index 8ac3de6f03..30924e64bd 100644
+--- a/qtbase/src/platformsupport/services/genericunix/qgenericunixservices_p.h
++++ b/qtbase/src/platformsupport/services/genericunix/qgenericunixservices_p.h
+@@ -59,16 +59,21 @@ QT_BEGIN_NAMESPACE
+ class QGenericUnixServices : public QPlatformServices
+ {
+ public:
+- QGenericUnixServices() {}
++ QGenericUnixServices();
+
+ QByteArray desktopEnvironment() const override;
+
++ bool hasCapability(Capability capability) const override;
+ bool openUrl(const QUrl &url) override;
+ bool openDocument(const QUrl &url) override;
++ QPlatformServiceColorPicker *colorPicker(QWindow *parent = nullptr) override;
++
++ virtual QString portalWindowIdentifier(QWindow *window);
+
+ private:
+ QString m_webBrowser;
+ QString m_documentLauncher;
++ bool m_hasScreenshotPortalWithColorPicking = false;
+ };
+
+ QT_END_NAMESPACE
+diff --git a/qtbase/src/platformsupport/themes/genericunix/dbusmenu/qdbusmenuconnection.cpp b/qtbase/src/platformsupport/themes/genericunix/dbusmenu/qdbusmenuconnection.cpp
+index 09470bccc6..cc7c7d4d8a 100644
+--- a/qtbase/src/platformsupport/themes/genericunix/dbusmenu/qdbusmenuconnection.cpp
++++ b/qtbase/src/platformsupport/themes/genericunix/dbusmenu/qdbusmenuconnection.cpp
+@@ -69,6 +69,7 @@ const QString MenuBarPath = QLatin1String("/MenuBar");
+ */
+ QDBusMenuConnection::QDBusMenuConnection(QObject *parent, const QString &serviceName)
+ : QObject(parent)
++ , m_serviceName(serviceName)
+ , m_connection(serviceName.isNull() ? QDBusConnection::sessionBus()
+ : QDBusConnection::connectToBus(QDBusConnection::SessionBus, serviceName))
+ , m_dbusWatcher(new QDBusServiceWatcher(StatusNotifierWatcherService, m_connection, QDBusServiceWatcher::WatchForRegistration, this))
+@@ -83,6 +84,12 @@ QDBusMenuConnection::QDBusMenuConnection(QObject *parent, const QString &service
+ #endif
+ }
+
++QDBusMenuConnection::~QDBusMenuConnection()
++{
++ if (!m_serviceName.isEmpty() && m_connection.isConnected())
++ QDBusConnection::disconnectFromBus(m_serviceName);
++}
++
+ void QDBusMenuConnection::dbusError(const QDBusError &error)
+ {
+ qWarning() << "QDBusTrayIcon encountered a D-Bus error:" << error;
+@@ -105,13 +112,7 @@ void QDBusMenuConnection::unregisterTrayIconMenu(QDBusTrayIcon *item)
+
+ bool QDBusMenuConnection::registerTrayIcon(QDBusTrayIcon *item)
+ {
+- bool success = connection().registerService(item->instanceId());
+- if (!success) {
+- qWarning() << "failed to register service" << item->instanceId();
+- return false;
+- }
+-
+- success = connection().registerObject(StatusNotifierItemPath, item);
++ bool success = connection().registerObject(StatusNotifierItemPath, item);
+ if (!success) {
+ unregisterTrayIcon(item);
+ qWarning() << "failed to register" << item->instanceId() << StatusNotifierItemPath;
+@@ -126,21 +127,18 @@ bool QDBusMenuConnection::registerTrayIcon(QDBusTrayIcon *item)
+
+ bool QDBusMenuConnection::registerTrayIconWithWatcher(QDBusTrayIcon *item)
+ {
++ Q_UNUSED(item);
+ QDBusMessage registerMethod = QDBusMessage::createMethodCall(
+ StatusNotifierWatcherService, StatusNotifierWatcherPath, StatusNotifierWatcherService,
+ QLatin1String("RegisterStatusNotifierItem"));
+- registerMethod.setArguments(QVariantList() << item->instanceId());
++ registerMethod.setArguments(QVariantList() << m_connection.baseService());
+ return m_connection.callWithCallback(registerMethod, this, SIGNAL(trayIconRegistered()), SLOT(dbusError(QDBusError)));
+ }
+
+-bool QDBusMenuConnection::unregisterTrayIcon(QDBusTrayIcon *item)
++void QDBusMenuConnection::unregisterTrayIcon(QDBusTrayIcon *item)
+ {
+ unregisterTrayIconMenu(item);
+ connection().unregisterObject(StatusNotifierItemPath);
+- bool success = connection().unregisterService(item->instanceId());
+- if (!success)
+- qWarning() << "failed to unregister service" << item->instanceId();
+- return success;
+ }
+ #endif // QT_NO_SYSTEMTRAYICON
+
+diff --git a/qtbase/src/platformsupport/themes/genericunix/dbusmenu/qdbusmenuconnection_p.h b/qtbase/src/platformsupport/themes/genericunix/dbusmenu/qdbusmenuconnection_p.h
+index f484795fbb..97bdfabb85 100644
+--- a/qtbase/src/platformsupport/themes/genericunix/dbusmenu/qdbusmenuconnection_p.h
++++ b/qtbase/src/platformsupport/themes/genericunix/dbusmenu/qdbusmenuconnection_p.h
+@@ -70,6 +70,7 @@ class QDBusMenuConnection : public QObject
+
+ public:
+ QDBusMenuConnection(QObject *parent = nullptr, const QString &serviceName = QString());
++ ~QDBusMenuConnection();
+ QDBusConnection connection() const { return m_connection; }
+ QDBusServiceWatcher *dbusWatcher() const { return m_dbusWatcher; }
+ bool isStatusNotifierHostRegistered() const { return m_statusNotifierHostRegistered; }
+@@ -78,7 +79,7 @@ public:
+ void unregisterTrayIconMenu(QDBusTrayIcon *item);
+ bool registerTrayIcon(QDBusTrayIcon *item);
+ bool registerTrayIconWithWatcher(QDBusTrayIcon *item);
+- bool unregisterTrayIcon(QDBusTrayIcon *item);
++ void unregisterTrayIcon(QDBusTrayIcon *item);
+ #endif // QT_NO_SYSTEMTRAYICON
+
+ Q_SIGNALS:
+@@ -90,6 +91,7 @@ private Q_SLOTS:
+ void dbusError(const QDBusError &error);
+
+ private:
++ QString m_serviceName;
+ QDBusConnection m_connection;
+ QDBusServiceWatcher *m_dbusWatcher;
+ bool m_statusNotifierHostRegistered;
+diff --git a/qtbase/src/platformsupport/themes/genericunix/dbustray/qdbustrayicon.cpp b/qtbase/src/platformsupport/themes/genericunix/dbustray/qdbustrayicon.cpp
+index bede70975a..76bfec5e5a 100644
+--- a/qtbase/src/platformsupport/themes/genericunix/dbustray/qdbustrayicon.cpp
++++ b/qtbase/src/platformsupport/themes/genericunix/dbustray/qdbustrayicon.cpp
+@@ -71,8 +71,12 @@ Q_LOGGING_CATEGORY(qLcTray, "qt.qpa.tray")
+ static QString iconTempPath()
+ {
+ QString tempPath = QStandardPaths::writableLocation(QStandardPaths::RuntimeLocation);
+- if (!tempPath.isEmpty())
++ if (!tempPath.isEmpty()) {
++ QString flatpakId = qEnvironmentVariable("FLATPAK_ID");
++ if (!flatpakId.isEmpty() && QFileInfo::exists(QLatin1String("/.flatpak-info")))
++ tempPath += QLatin1String("/app/") + flatpakId;
+ return tempPath;
++ }
+
+ tempPath = QStandardPaths::writableLocation(QStandardPaths::GenericCacheLocation);
+
+diff --git a/qtbase/src/platformsupport/themes/genericunix/qgenericunixthemes.cpp b/qtbase/src/platformsupport/themes/genericunix/qgenericunixthemes.cpp
+index cb1b39db64..6e01af052c 100644
+--- a/qtbase/src/platformsupport/themes/genericunix/qgenericunixthemes.cpp
++++ b/qtbase/src/platformsupport/themes/genericunix/qgenericunixthemes.cpp
+@@ -755,6 +755,9 @@ QVariant QGnomeTheme::themeHint(QPlatformTheme::ThemeHint hint) const
+ return QVariant(QChar(0x2022));
+ case QPlatformTheme::UiEffects:
+ return QVariant(int(HoverEffect));
++ case QPlatformTheme::ButtonPressKeys:
++ return QVariant::fromValue(
++ QList<Qt::Key>({ Qt::Key_Space, Qt::Key_Return, Qt::Key_Enter, Qt::Key_Select }));
+ default:
+ break;
+ }
+diff --git a/qtbase/src/plugins/platforms/eglfs/api/qeglfscursor.cpp b/qtbase/src/plugins/platforms/eglfs/api/qeglfscursor.cpp
+index 98e05195ee..1e92f43dec 100644
+--- a/qtbase/src/plugins/platforms/eglfs/api/qeglfscursor.cpp
++++ b/qtbase/src/plugins/platforms/eglfs/api/qeglfscursor.cpp
+@@ -343,8 +343,7 @@ void QEglFSCursor::paintOnScreen()
+ // screens are siblings of each other. When not enabled, the sibling list
+ // only contains m_screen itself.
+ for (QPlatformScreen *screen : m_screen->virtualSiblings()) {
+- if (screen->geometry().contains(cr.topLeft().toPoint() + m_cursor.hotSpot)
+- && QOpenGLContext::currentContext()->screen() == screen->screen())
++ if (screen->geometry().contains(cr.topLeft().toPoint() + m_cursor.hotSpot))
+ {
+ cr.translate(-screen->geometry().topLeft());
+ const QSize screenSize = screen->geometry().size();
+@@ -468,11 +467,12 @@ void QEglFSCursor::draw(const QRectF &r)
+ {
+ StateSaver stateSaver;
+
+- QEglFSCursorData &gfx = static_cast<QEglFSContext*>(QOpenGLContext::currentContext()->handle())->cursorData;
+- if (!gfx.program) {
+- // one time initialization
++ // one time initialization
++ if (!QOpenGLFunctions::d_ptr)
+ initializeOpenGLFunctions();
+
++ QEglFSCursorData &gfx = static_cast<QEglFSContext*>(QOpenGLContext::currentContext()->handle())->cursorData;
++ if (!gfx.program) {
+ createShaderPrograms();
+
+ if (!gfx.atlasTexture) {
+diff --git a/qtbase/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmseventreader.cpp b/qtbase/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmseventreader.cpp
+index 645a0ae2e9..3e0e406f1a 100644
+--- a/qtbase/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmseventreader.cpp
++++ b/qtbase/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmseventreader.cpp
+@@ -179,7 +179,7 @@ void QEglFSKmsEventReader::create(QEglFSKmsDevice *device)
+
+ m_device = device;
+
+- qCDebug(qLcEglfsKmsDebug, "Initalizing event reader for device %p fd %d",
++ qCDebug(qLcEglfsKmsDebug, "Initializing event reader for device %p fd %d",
+ m_device, m_device->fd());
+
+ m_thread = new QEglFSKmsEventReaderThread(m_device->fd());
+diff --git a/qtbase/src/plugins/platforms/offscreen/qoffscreenintegration.cpp b/qtbase/src/plugins/platforms/offscreen/qoffscreenintegration.cpp
+index 141fb68a23..d4294d425a 100644
+--- a/qtbase/src/plugins/platforms/offscreen/qoffscreenintegration.cpp
++++ b/qtbase/src/plugins/platforms/offscreen/qoffscreenintegration.cpp
+@@ -122,11 +122,13 @@ QOffscreenIntegration::QOffscreenIntegration()
+ #endif
+ m_services.reset(new QPlatformServices);
+
+- QWindowSystemInterface::handleScreenAdded(new QOffscreenScreen);
++ m_screen = new QOffscreenScreen;
++ QWindowSystemInterface::handleScreenAdded(m_screen);
+ }
+
+ QOffscreenIntegration::~QOffscreenIntegration()
+ {
++ QWindowSystemInterface::handleScreenRemoved(m_screen);
+ }
+
+ void QOffscreenIntegration::initialize()
+diff --git a/qtbase/src/plugins/platforms/offscreen/qoffscreenintegration.h b/qtbase/src/plugins/platforms/offscreen/qoffscreenintegration.h
+index 0ea90f6c2f..fe00fde07c 100644
+--- a/qtbase/src/plugins/platforms/offscreen/qoffscreenintegration.h
++++ b/qtbase/src/plugins/platforms/offscreen/qoffscreenintegration.h
+@@ -84,6 +84,7 @@ protected:
+ #endif
+ QScopedPointer<QPlatformInputContext> m_inputContext;
+ QScopedPointer<QPlatformServices> m_services;
++ QPlatformScreen *m_screen;
+ mutable QScopedPointer<QPlatformNativeInterface> m_nativeInterface;
+ };
+
+diff --git a/qtbase/src/plugins/platforms/windows/qwindowsglcontext.cpp b/qtbase/src/plugins/platforms/windows/qwindowsglcontext.cpp
+index 6fa5a8a2b3..1f49f0aefd 100644
+--- a/qtbase/src/plugins/platforms/windows/qwindowsglcontext.cpp
++++ b/qtbase/src/plugins/platforms/windows/qwindowsglcontext.cpp
+@@ -48,6 +48,7 @@
+ #include <qpa/qplatformnativeinterface.h>
+ #include <QtPlatformHeaders/qwglnativecontext.h>
+
++#include <private/qsystemlibrary_p.h>
+ #include <algorithm>
+
+ #include <wingdi.h>
+@@ -162,19 +163,25 @@ QFunctionPointer QWindowsOpengl32DLL::resolve(const char *name)
+
+ bool QWindowsOpengl32DLL::init(bool softwareRendering)
+ {
+- const QByteArray opengl32 = QByteArrayLiteral("opengl32.dll");
+- const QByteArray swopengl = QByteArrayLiteral("opengl32sw.dll");
++ const QByteArray opengl32 = QByteArrayLiteral("opengl32");
++ const QByteArray swopengl = QByteArrayLiteral("opengl32sw");
++ bool useSystemLib = false;
+
+ QByteArray openglDll = qgetenv("QT_OPENGL_DLL");
+- if (openglDll.isEmpty())
++ if (openglDll.isEmpty()) {
+ openglDll = softwareRendering ? swopengl : opengl32;
++ useSystemLib = !softwareRendering;
++ }
+
+ openglDll = openglDll.toLower();
+ m_nonOpengl32 = openglDll != opengl32;
+
+ qCDebug(lcQpaGl) << "Qt: Using WGL and OpenGL from" << openglDll;
+
+- m_lib = ::LoadLibraryA(openglDll.constData());
++ if (useSystemLib)
++ m_lib = QSystemLibrary::load((wchar_t*)(QString::fromLatin1(openglDll).utf16()));
++ else
++ m_lib = LoadLibraryA(openglDll.constData());
+ if (!m_lib) {
+ qErrnoWarning(::GetLastError(), "Failed to load %s", openglDll.constData());
+ return false;
+@@ -184,7 +191,7 @@ bool QWindowsOpengl32DLL::init(bool softwareRendering)
+ // Load opengl32.dll always. GDI functions like ChoosePixelFormat do
+ // GetModuleHandle for opengl32.dll and behave differently (and call back into
+ // opengl32) when the module is present. This is fine for dummy contexts and windows.
+- ::LoadLibraryA("opengl32.dll");
++ QSystemLibrary::load(L"opengl32");
+ }
+
+ wglCreateContext = reinterpret_cast<HGLRC (WINAPI *)(HDC)>(resolve("wglCreateContext"));
+diff --git a/qtbase/src/plugins/platforms/windows/qwindowsopengltester.cpp b/qtbase/src/plugins/platforms/windows/qwindowsopengltester.cpp
+index d7d186e804..9eb4011bf2 100644
+--- a/qtbase/src/plugins/platforms/windows/qwindowsopengltester.cpp
++++ b/qtbase/src/plugins/platforms/windows/qwindowsopengltester.cpp
+@@ -49,6 +49,7 @@
+ #include <QtCore/qstandardpaths.h>
+ #include <QtCore/qlibraryinfo.h>
+ #include <QtCore/qhash.h>
++#include <private/qsystemlibrary_p.h>
+
+ #ifndef QT_NO_OPENGL
+ #include <private/qopengl_p.h>
+@@ -396,7 +397,7 @@ bool QWindowsOpenGLTester::testDesktopGL()
+
+ // Test #1: Load opengl32.dll and try to resolve an OpenGL 2 function.
+ // This will typically fail on systems that do not have a real OpenGL driver.
+- lib = LoadLibraryA("opengl32.dll");
++ lib = QSystemLibrary::load(L"opengl32");
+ if (lib) {
+ CreateContext = reinterpret_cast<CreateContextType>(
+ reinterpret_cast<QFunctionPointer>(::GetProcAddress(lib, "wglCreateContext")));
+diff --git a/qtbase/src/plugins/platforms/xcb/nativepainting/qtessellator.cpp b/qtbase/src/plugins/platforms/xcb/nativepainting/qtessellator.cpp
+index 1afa00cfc9..118af6ce73 100644
+--- a/qtbase/src/plugins/platforms/xcb/nativepainting/qtessellator.cpp
++++ b/qtbase/src/plugins/platforms/xcb/nativepainting/qtessellator.cpp
+@@ -41,6 +41,7 @@
+
+ #include <QRect>
+ #include <QList>
++#include <QMap>
+ #include <QDebug>
+
+ #include <qmath.h>
+diff --git a/qtbase/src/plugins/platforms/xcb/qxcbconnection.cpp b/qtbase/src/plugins/platforms/xcb/qxcbconnection.cpp
+index 9e2a37a6a1..e6e175a118 100644
+--- a/qtbase/src/plugins/platforms/xcb/qxcbconnection.cpp
++++ b/qtbase/src/plugins/platforms/xcb/qxcbconnection.cpp
+@@ -488,12 +488,12 @@ void QXcbConnection::printXcbError(const char *message, xcb_generic_error_t *err
+ uint clamped_error_code = qMin<uint>(error->error_code, (sizeof(xcb_errors) / sizeof(xcb_errors[0])) - 1);
+ uint clamped_major_code = qMin<uint>(error->major_code, (sizeof(xcb_protocol_request_codes) / sizeof(xcb_protocol_request_codes[0])) - 1);
+
+- qCWarning(lcQpaXcb, "%s: %d (%s), sequence: %d, resource id: %d, major code: %d (%s), minor code: %d",
+- message,
+- int(error->error_code), xcb_errors[clamped_error_code],
+- int(error->sequence), int(error->resource_id),
+- int(error->major_code), xcb_protocol_request_codes[clamped_major_code],
+- int(error->minor_code));
++ qCDebug(lcQpaXcb, "%s: %d (%s), sequence: %d, resource id: %d, major code: %d (%s), minor code: %d",
++ message,
++ int(error->error_code), xcb_errors[clamped_error_code],
++ int(error->sequence), int(error->resource_id),
++ int(error->major_code), xcb_protocol_request_codes[clamped_major_code],
++ int(error->minor_code));
+ }
+
+ static Qt::MouseButtons translateMouseButtons(int s)
+@@ -702,6 +702,8 @@ void QXcbConnection::handleXcbEvent(xcb_generic_event_t *event)
+ QXcbVirtualDesktop *virtualDesktop = virtualDesktopForRootWindow(propertyNotify->window);
+ if (virtualDesktop)
+ virtualDesktop->updateWorkArea();
++ } else if (propertyNotify->atom == atom(QXcbAtom::_NET_SUPPORTED)) {
++ m_wmSupport->updateNetWMAtoms();
+ } else {
+ HANDLE_PLATFORM_WINDOW_EVENT(xcb_property_notify_event_t, window, handlePropertyNotifyEvent);
+ }
+@@ -750,7 +752,7 @@ void QXcbConnection::handleXcbEvent(xcb_generic_event_t *event)
+ case XCB_XKB_NEW_KEYBOARD_NOTIFY: {
+ xcb_xkb_new_keyboard_notify_event_t *ev = &xkb_event->new_keyboard_notify;
+ if (ev->changed & XCB_XKB_NKN_DETAIL_KEYCODES)
+- m_keyboard->updateKeymap(ev);
++ m_keyboard->updateKeymap();
+ break;
+ }
+ default:
+diff --git a/qtbase/src/plugins/platforms/xcb/qxcbintegration.cpp b/qtbase/src/plugins/platforms/xcb/qxcbintegration.cpp
+index 76869ced60..02d2eebb56 100644
+--- a/qtbase/src/plugins/platforms/xcb/qxcbintegration.cpp
++++ b/qtbase/src/plugins/platforms/xcb/qxcbintegration.cpp
+@@ -274,8 +274,7 @@ QPlatformWindow *QXcbIntegration::createForeignWindow(QWindow *window, WId nativ
+ #ifndef QT_NO_OPENGL
+ QPlatformOpenGLContext *QXcbIntegration::createPlatformOpenGLContext(QOpenGLContext *context) const
+ {
+- QXcbScreen *screen = static_cast<QXcbScreen *>(context->screen()->handle());
+- QXcbGlIntegration *glIntegration = screen->connection()->glIntegration();
++ QXcbGlIntegration *glIntegration = defaultConnection()->glIntegration();
+ if (!glIntegration) {
+ qWarning("QXcbIntegration: Cannot create platform OpenGL context, neither GLX nor EGL are enabled");
+ return nullptr;
+diff --git a/qtbase/src/plugins/platforms/xcb/qxcbkeyboard.cpp b/qtbase/src/plugins/platforms/xcb/qxcbkeyboard.cpp
+index efecd7e2d1..e8286381a2 100644
+--- a/qtbase/src/plugins/platforms/xcb/qxcbkeyboard.cpp
++++ b/qtbase/src/plugins/platforms/xcb/qxcbkeyboard.cpp
+@@ -365,17 +365,6 @@ void QXcbKeyboard::updateKeymap(xcb_mapping_notify_event_t *event)
+ updateKeymap();
+ }
+
+-void QXcbKeyboard::updateKeymap(xcb_xkb_new_keyboard_notify_event_t *event)
+-{
+- if (!event)
+- return;
+-
+- if (event->deviceID != event->oldDeviceID)
+- m_config = false;
+-
+- updateKeymap();
+-}
+-
+ void QXcbKeyboard::updateKeymap()
+ {
+ KeysymModifierMap keysymMods;
+@@ -383,6 +372,8 @@ void QXcbKeyboard::updateKeymap()
+ keysymMods = keysymsToModifiers();
+ updateModifiers(keysymMods);
+
++ m_config = true;
++
+ if (!m_xkbContext) {
+ m_xkbContext.reset(xkb_context_new(XKB_CONTEXT_NO_DEFAULT_INCLUDES));
+ if (!m_xkbContext) {
+@@ -398,13 +389,8 @@ void QXcbKeyboard::updateKeymap()
+ if (connection()->hasXKB()) {
+ m_xkbKeymap.reset(xkb_x11_keymap_new_from_device(m_xkbContext.get(), xcb_connection(),
+ core_device_id, XKB_KEYMAP_COMPILE_NO_FLAGS));
+- if (m_xkbKeymap) {
+- if (m_config)
+- m_xkbState.reset(xkb_state_new(m_xkbKeymap.get()));
+- else
+- m_xkbState.reset(xkb_x11_state_new_from_device(m_xkbKeymap.get(), xcb_connection(), core_device_id));
+-
+- }
++ if (m_xkbKeymap)
++ m_xkbState.reset(xkb_x11_state_new_from_device(m_xkbKeymap.get(), xcb_connection(), core_device_id));
+ } else {
+ m_xkbKeymap.reset(keymapFromCore(keysymMods));
+ if (m_xkbKeymap)
+@@ -425,8 +411,6 @@ void QXcbKeyboard::updateKeymap()
+ updateXKBMods();
+
+ QXkbCommon::verifyHasLatinLayout(m_xkbKeymap.get());
+-
+- m_config = true;
+ }
+
+ QList<int> QXcbKeyboard::possibleKeys(const QKeyEvent *event) const
+diff --git a/qtbase/src/plugins/platforms/xcb/qxcbkeyboard.h b/qtbase/src/plugins/platforms/xcb/qxcbkeyboard.h
+index b652c85fe3..0ee08aeff2 100644
+--- a/qtbase/src/plugins/platforms/xcb/qxcbkeyboard.h
++++ b/qtbase/src/plugins/platforms/xcb/qxcbkeyboard.h
+@@ -69,7 +69,6 @@ public:
+
+ Qt::KeyboardModifiers translateModifiers(int s) const;
+ void updateKeymap(xcb_mapping_notify_event_t *event);
+- void updateKeymap(xcb_xkb_new_keyboard_notify_event_t *event);
+ void updateKeymap();
+ QList<int> possibleKeys(const QKeyEvent *event) const;
+
+diff --git a/qtbase/src/plugins/platforms/xcb/qxcbwindow.cpp b/qtbase/src/plugins/platforms/xcb/qxcbwindow.cpp
+index ffda7b6a57..863e961f4c 100644
+--- a/qtbase/src/plugins/platforms/xcb/qxcbwindow.cpp
++++ b/qtbase/src/plugins/platforms/xcb/qxcbwindow.cpp
+@@ -564,11 +564,6 @@ void QXcbWindow::setGeometry(const QRect &rect)
+ {
+ QPlatformWindow::setGeometry(rect);
+
+- if (shouldDeferTask(Task::SetGeometry)) {
+- m_deferredGeometry = rect;
+- return;
+- }
+-
+ propagateSizeHints();
+
+ QXcbScreen *currentScreen = xcbScreen();
+@@ -693,9 +688,6 @@ void QXcbWindow::setVisible(bool visible)
+
+ void QXcbWindow::show()
+ {
+- if (shouldDeferTask(Task::Map))
+- return;
+-
+ if (window()->isTopLevel()) {
+
+ // update WM_NORMAL_HINTS
+@@ -706,7 +698,7 @@ void QXcbWindow::show()
+ if (isTransient(window())) {
+ const QWindow *tp = window()->transientParent();
+ if (tp && tp->handle())
+- transientXcbParent = static_cast<const QXcbWindow *>(tp->handle())->winId();
++ transientXcbParent = tp->handle()->winId();
+ // Default to client leader if there is no transient parent, else modal dialogs can
+ // be hidden by their parents.
+ if (!transientXcbParent)
+@@ -746,10 +738,6 @@ void QXcbWindow::show()
+
+ void QXcbWindow::hide()
+ {
+- if (shouldDeferTask(Task::Unmap))
+- return;
+-
+- m_wmStateValid = false;
+ xcb_unmap_window(xcb_connection(), m_window);
+
+ // send synthetic UnmapNotify event according to icccm 4.1.4
+@@ -909,9 +897,6 @@ QXcbWindow::NetWmStates QXcbWindow::netWmStates()
+
+ void QXcbWindow::setWindowFlags(Qt::WindowFlags flags)
+ {
+- if (shouldDeferTask(Task::SetWindowFlags))
+- return;
+-
+ Qt::WindowType type = static_cast<Qt::WindowType>(int(flags & Qt::WindowType_Mask));
+
+ if (type == Qt::ToolTip)
+@@ -941,8 +926,6 @@ void QXcbWindow::setWindowFlags(Qt::WindowFlags flags)
+
+ setTransparentForMouseEvents(flags & Qt::WindowTransparentForInput);
+ updateDoesNotAcceptFocus(flags & Qt::WindowDoesNotAcceptFocus);
+-
+- m_isWmManagedWindow = !(flags & Qt::X11BypassWindowManagerHint);
+ }
+
+ void QXcbWindow::setMotifWmHints(Qt::WindowFlags flags)
+@@ -1142,9 +1125,6 @@ void QXcbWindow::setWindowState(Qt::WindowStates state)
+ if (state == m_windowState)
+ return;
+
+- if (shouldDeferTask(Task::SetWindowState))
+- return;
+-
+ // unset old state
+ if (m_windowState & Qt::WindowMinimized)
+ xcb_map_window(xcb_connection(), m_window);
+@@ -1350,6 +1330,12 @@ void QXcbWindow::setWindowIcon(const QIcon &icon)
+ }
+
+ if (!icon_data.isEmpty()) {
++ // Ignore icon exceeding maximum xcb request length
++ if (icon_data.size() > xcb_get_maximum_request_length(xcb_connection())) {
++ qWarning("Ignoring window icon: Size %llu exceeds maximum xcb request length %u.",
++ icon_data.size(), xcb_get_maximum_request_length(xcb_connection()));
++ return;
++ }
+ xcb_change_property(xcb_connection(),
+ XCB_PROP_MODE_REPLACE,
+ m_window,
+@@ -1639,7 +1625,7 @@ void QXcbWindow::setWmWindowType(QXcbWindowFunctions::WmWindowTypes types, Qt::W
+ break;
+ }
+
+- if ((flags & Qt::FramelessWindowHint) && !(type & QXcbWindowFunctions::KdeOverride)) {
++ if ((flags & Qt::FramelessWindowHint) && !(types & QXcbWindowFunctions::KdeOverride)) {
+ // override netwm type - quick and easy for KDE noborder
+ atoms.append(atom(QXcbAtom::_KDE_NET_WM_WINDOW_TYPE_OVERRIDE));
+ }
+@@ -1894,10 +1880,6 @@ void QXcbWindow::handleUnmapNotifyEvent(const xcb_unmap_notify_event_t *event)
+ if (event->window == m_window) {
+ m_mapped = false;
+ QWindowSystemInterface::handleExposeEvent(window(), QRegion());
+- if (!m_isWmManagedWindow || parent()) {
+- m_wmStateValid = true;
+- handleDeferredTasks();
+- }
+ }
+ }
+
+@@ -2212,98 +2194,30 @@ void QXcbWindow::handleLeaveNotifyEvent(const xcb_leave_notify_event_t *event)
+ handleLeaveNotifyEvent(event->root_x, event->root_y, event->mode, event->detail, event->time);
+ }
+
+-bool QXcbWindow::shouldDeferTask(Task task)
+-{
+- if (m_wmStateValid)
+- return false;
+-
+- m_deferredTasks.append(task);
+- return true;
+-}
+-
+-void QXcbWindow::handleDeferredTasks()
+-{
+- Q_ASSERT(m_wmStateValid == true);
+- if (m_deferredTasks.isEmpty())
+- return;
+-
+- bool map = false;
+- bool unmap = false;
+-
+- QVector<Task> tasks;
+- for (auto taskIt = m_deferredTasks.rbegin(); taskIt != m_deferredTasks.rend(); ++taskIt) {
+- if (!tasks.contains(*taskIt))
+- tasks.prepend(*taskIt);
+- }
+-
+- for (Task task : tasks) {
+- switch (task) {
+- case Task::Map:
+- map = true;
+- unmap = false;
+- break;
+- case Task::Unmap:
+- unmap = true;
+- map = false;
+- break;
+- case Task::SetGeometry:
+- setGeometry(m_deferredGeometry);
+- break;
+- case Task::SetWindowFlags:
+- setWindowFlags(window()->flags());
+- break;
+- case Task::SetWindowState:
+- setWindowState(window()->windowState());
+- break;
+- }
+- }
+- m_deferredTasks.clear();
+-
+- if (map) {
+- Q_ASSERT(unmap == false);
+- show();
+- }
+- if (unmap) {
+- Q_ASSERT(map == false);
+- hide();
+- }
+-}
+-
+ void QXcbWindow::handlePropertyNotifyEvent(const xcb_property_notify_event_t *event)
+ {
+ connection()->setTime(event->time);
+
+- const bool wmStateChanged = event->atom == atom(QXcbAtom::WM_STATE);
+- const bool netWmStateChanged = event->atom == atom(QXcbAtom::_NET_WM_STATE);
+- if (netWmStateChanged || wmStateChanged) {
+- if (wmStateChanged && !m_wmStateValid && m_isWmManagedWindow) {
+- // ICCCM 4.1.4
+- // Clients that want to re-use a client window (e.g. by mapping it again)
+- // after withdrawing it must wait for the withdrawal to be complete before
+- // proceeding. The preferred method for doing this is for clients to wait for
+- // a window manager to update or remove the WM_STATE property.
+- m_wmStateValid = true;
+- handleDeferredTasks();
+- }
+- if (event->state == XCB_PROPERTY_DELETE)
++ const bool propertyDeleted = event->state == XCB_PROPERTY_DELETE;
++
++ if (event->atom == atom(QXcbAtom::_NET_WM_STATE) || event->atom == atom(QXcbAtom::WM_STATE)) {
++ if (propertyDeleted)
+ return;
+
+- if (wmStateChanged) {
++ Qt::WindowStates newState = Qt::WindowNoState;
++
++ if (event->atom == atom(QXcbAtom::WM_STATE)) { // WM_STATE: Quick check for 'Minimize'.
+ auto reply = Q_XCB_REPLY(xcb_get_property, xcb_connection(),
+ 0, m_window, atom(QXcbAtom::WM_STATE),
+ XCB_ATOM_ANY, 0, 1024);
+ if (reply && reply->format == 32 && reply->type == atom(QXcbAtom::WM_STATE)) {
+- auto data = static_cast<const quint32 *>(xcb_get_property_value(reply.get()));
+- if (reply->length != 0) {
+- const bool changedToWithdrawn = data[0] == XCB_ICCCM_WM_STATE_WITHDRAWN;
+- const bool changedToIconic = data[0] == XCB_ICCCM_WM_STATE_ICONIC;
+- m_minimized = changedToIconic || (changedToWithdrawn && m_minimized);
+- }
++ const quint32 *data = (const quint32 *)xcb_get_property_value(reply.get());
++ if (reply->length != 0)
++ m_minimized = (data[0] == XCB_ICCCM_WM_STATE_ICONIC
++ || (data[0] == XCB_ICCCM_WM_STATE_WITHDRAWN && m_minimized));
+ }
+ }
+
+- // _NET_WM_STATE handling
+- Qt::WindowStates newState = Qt::WindowNoState;
+ const NetWmStates states = netWmStates();
+ // _NET_WM_STATE_HIDDEN should be set by the Window Manager to indicate that a window would
+ // not be visible on the screen if its desktop/viewport were active and its coordinates were
+@@ -2325,6 +2239,7 @@ void QXcbWindow::handlePropertyNotifyEvent(const xcb_property_notify_event_t *ev
+ if ((m_windowState & Qt::WindowMinimized) && connection()->mouseGrabber() == this)
+ connection()->setMouseGrabber(nullptr);
+ }
++ return;
+ } else if (event->atom == atom(QXcbAtom::_NET_FRAME_EXTENTS)) {
+ m_dirtyFrameMargins = true;
+ }
+diff --git a/qtbase/src/plugins/platforms/xcb/qxcbwindow.h b/qtbase/src/plugins/platforms/xcb/qxcbwindow.h
+index 55af9279b1..6f5c1f5ed9 100644
+--- a/qtbase/src/plugins/platforms/xcb/qxcbwindow.h
++++ b/qtbase/src/plugins/platforms/xcb/qxcbwindow.h
+@@ -74,14 +74,6 @@ public:
+
+ Q_DECLARE_FLAGS(NetWmStates, NetWmState)
+
+- enum Task {
+- Map,
+- Unmap,
+- SetGeometry,
+- SetWindowFlags,
+- SetWindowState
+- };
+-
+ QXcbWindow(QWindow *window);
+ ~QXcbWindow();
+
+@@ -151,9 +143,6 @@ public:
+
+ QXcbWindow *toWindow() override;
+
+- bool shouldDeferTask(Task task);
+- void handleDeferredTasks();
+-
+ void handleMouseEvent(xcb_timestamp_t time, const QPoint &local, const QPoint &global,
+ Qt::KeyboardModifiers modifiers, QEvent::Type type, Qt::MouseEventSource source);
+
+@@ -292,11 +281,6 @@ protected:
+ int m_swapInterval = -1;
+
+ qreal m_sizeHintsScaleFactor = 1.0;
+-
+- bool m_wmStateValid = true;
+- QVector<Task> m_deferredTasks;
+- bool m_isWmManagedWindow = true;
+- QRect m_deferredGeometry;
+ };
+
+ class QXcbForeignWindow : public QXcbWindow
+diff --git a/qtbase/src/plugins/platformthemes/gtk3/qgtk3menu.cpp b/qtbase/src/plugins/platformthemes/gtk3/qgtk3menu.cpp
+index d9d117faeb..640b49daa0 100644
+--- a/qtbase/src/plugins/platformthemes/gtk3/qgtk3menu.cpp
++++ b/qtbase/src/plugins/platformthemes/gtk3/qgtk3menu.cpp
+@@ -85,6 +85,7 @@ QGtk3MenuItem::QGtk3MenuItem()
+ m_checkable(false),
+ m_checked(false),
+ m_enabled(true),
++ m_exclusive(false),
+ m_underline(false),
+ m_invalid(true),
+ m_menu(nullptr),
+diff --git a/qtbase/src/plugins/platformthemes/xdgdesktopportal/qxdgdesktopportalfiledialog.cpp b/qtbase/src/plugins/platformthemes/xdgdesktopportal/qxdgdesktopportalfiledialog.cpp
+index 0048bbc1e6..396e7f6d1c 100644
+--- a/qtbase/src/plugins/platformthemes/xdgdesktopportal/qxdgdesktopportalfiledialog.cpp
++++ b/qtbase/src/plugins/platformthemes/xdgdesktopportal/qxdgdesktopportalfiledialog.cpp
+@@ -102,15 +102,12 @@ const QDBusArgument &operator >>(const QDBusArgument &arg, QXdgDesktopPortalFile
+ class QXdgDesktopPortalFileDialogPrivate
+ {
+ public:
+- QXdgDesktopPortalFileDialogPrivate(QPlatformFileDialogHelper *nativeFileDialog)
++ QXdgDesktopPortalFileDialogPrivate(QPlatformFileDialogHelper *nativeFileDialog, uint fileChooserPortalVersion)
+ : nativeFileDialog(nativeFileDialog)
++ , fileChooserPortalVersion(fileChooserPortalVersion)
+ { }
+
+- WId winId = 0;
+- bool directoryMode = false;
+- bool modal = false;
+- bool multipleFiles = false;
+- bool saveFile = false;
++ QEventLoop loop;
+ QString acceptLabel;
+ QString directory;
+ QString title;
+@@ -121,19 +118,27 @@ public:
+ QString selectedMimeTypeFilter;
+ QString selectedNameFilter;
+ QStringList selectedFiles;
+- QPlatformFileDialogHelper *nativeFileDialog = nullptr;
++ std::unique_ptr<QPlatformFileDialogHelper> nativeFileDialog;
++ uint fileChooserPortalVersion = 0;
++ bool failedToOpen = false;
++ bool directoryMode = false;
++ bool multipleFiles = false;
++ bool saveFile = false;
+ };
+
+-QXdgDesktopPortalFileDialog::QXdgDesktopPortalFileDialog(QPlatformFileDialogHelper *nativeFileDialog)
++QXdgDesktopPortalFileDialog::QXdgDesktopPortalFileDialog(QPlatformFileDialogHelper *nativeFileDialog, uint fileChooserPortalVersion)
+ : QPlatformFileDialogHelper()
+- , d_ptr(new QXdgDesktopPortalFileDialogPrivate(nativeFileDialog))
++ , d_ptr(new QXdgDesktopPortalFileDialogPrivate(nativeFileDialog, fileChooserPortalVersion))
+ {
+ Q_D(QXdgDesktopPortalFileDialog);
+
+ if (d->nativeFileDialog) {
+- connect(d->nativeFileDialog, SIGNAL(accept()), this, SIGNAL(accept()));
+- connect(d->nativeFileDialog, SIGNAL(reject()), this, SIGNAL(reject()));
++ connect(d->nativeFileDialog.get(), SIGNAL(accept()), this, SIGNAL(accept()));
++ connect(d->nativeFileDialog.get(), SIGNAL(reject()), this, SIGNAL(reject()));
+ }
++
++ d->loop.connect(this, SIGNAL(accept()), SLOT(quit()));
++ d->loop.connect(this, SIGNAL(reject()), SLOT(quit()));
+ }
+
+ QXdgDesktopPortalFileDialog::~QXdgDesktopPortalFileDialog()
+@@ -177,7 +182,7 @@ void QXdgDesktopPortalFileDialog::initializeDialog()
+ setDirectory(options()->initialDirectory());
+ }
+
+-void QXdgDesktopPortalFileDialog::openPortal()
++void QXdgDesktopPortalFileDialog::openPortal(Qt::WindowFlags windowFlags, Qt::WindowModality windowModality, QWindow *parent)
+ {
+ Q_D(QXdgDesktopPortalFileDialog);
+
+@@ -185,13 +190,13 @@ void QXdgDesktopPortalFileDialog::openPortal()
+ QLatin1String("/org/freedesktop/portal/desktop"),
+ QLatin1String("org.freedesktop.portal.FileChooser"),
+ d->saveFile ? QLatin1String("SaveFile") : QLatin1String("OpenFile"));
+- QString parentWindowId = QLatin1String("x11:") + QString::number(d->winId, 16);
++ QString parentWindowId = QLatin1String("x11:") + QString::number(parent ? parent->winId() : 0, 16);
+
+ QVariantMap options;
+ if (!d->acceptLabel.isEmpty())
+ options.insert(QLatin1String("accept_label"), d->acceptLabel);
+
+- options.insert(QLatin1String("modal"), d->modal);
++ options.insert(QLatin1String("modal"), windowModality != Qt::NonModal);
+ options.insert(QLatin1String("multiple"), d->multipleFiles);
+ options.insert(QLatin1String("directory"), d->directoryMode);
+
+@@ -290,10 +295,18 @@ void QXdgDesktopPortalFileDialog::openPortal()
+
+ QDBusPendingCall pendingCall = QDBusConnection::sessionBus().asyncCall(message);
+ QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(pendingCall);
+- connect(watcher, &QDBusPendingCallWatcher::finished, this, [this] (QDBusPendingCallWatcher *watcher) {
++ connect(watcher, &QDBusPendingCallWatcher::finished, this, [=] (QDBusPendingCallWatcher *watcher) {
+ QDBusPendingReply<QDBusObjectPath> reply = *watcher;
+- if (reply.isError()) {
+- Q_EMIT reject();
++ // Any error means the dialog is not shown and we need to fallback
++ d->failedToOpen = reply.isError();
++ if (d->failedToOpen) {
++ if (d->nativeFileDialog) {
++ d->nativeFileDialog->show(windowFlags, windowModality, parent);
++ if (d->loop.isRunning())
++ d->nativeFileDialog->exec();
++ } else {
++ Q_EMIT reject();
++ }
+ } else {
+ QDBusConnection::sessionBus().connect(nullptr,
+ reply.value().path(),
+@@ -302,6 +315,7 @@ void QXdgDesktopPortalFileDialog::openPortal()
+ this,
+ SLOT(gotResponse(uint,QVariantMap)));
+ }
++ watcher->deleteLater();
+ });
+ }
+
+@@ -326,7 +340,7 @@ QUrl QXdgDesktopPortalFileDialog::directory() const
+ {
+ Q_D(const QXdgDesktopPortalFileDialog);
+
+- if (d->nativeFileDialog && (options()->fileMode() == QFileDialogOptions::Directory || options()->fileMode() == QFileDialogOptions::DirectoryOnly))
++ if (d->nativeFileDialog && useNativeFileDialog())
+ return d->nativeFileDialog->directory();
+
+ return d->directory;
+@@ -348,7 +362,7 @@ QList<QUrl> QXdgDesktopPortalFileDialog::selectedFiles() const
+ {
+ Q_D(const QXdgDesktopPortalFileDialog);
+
+- if (d->nativeFileDialog && (options()->fileMode() == QFileDialogOptions::Directory || options()->fileMode() == QFileDialogOptions::DirectoryOnly))
++ if (d->nativeFileDialog && useNativeFileDialog())
+ return d->nativeFileDialog->selectedFiles();
+
+ QList<QUrl> files;
+@@ -403,16 +417,13 @@ void QXdgDesktopPortalFileDialog::exec()
+ {
+ Q_D(QXdgDesktopPortalFileDialog);
+
+- if (d->nativeFileDialog && (options()->fileMode() == QFileDialogOptions::Directory || options()->fileMode() == QFileDialogOptions::DirectoryOnly)) {
++ if (d->nativeFileDialog && useNativeFileDialog()) {
+ d->nativeFileDialog->exec();
+ return;
+ }
+
+ // HACK we have to avoid returning until we emit that the dialog was accepted or rejected
+- QEventLoop loop;
+- loop.connect(this, SIGNAL(accept()), SLOT(quit()));
+- loop.connect(this, SIGNAL(reject()), SLOT(quit()));
+- loop.exec();
++ d->loop.exec();
+ }
+
+ void QXdgDesktopPortalFileDialog::hide()
+@@ -429,13 +440,10 @@ bool QXdgDesktopPortalFileDialog::show(Qt::WindowFlags windowFlags, Qt::WindowMo
+
+ initializeDialog();
+
+- d->modal = windowModality != Qt::NonModal;
+- d->winId = parent ? parent->winId() : 0;
+-
+- if (d->nativeFileDialog && (options()->fileMode() == QFileDialogOptions::Directory || options()->fileMode() == QFileDialogOptions::DirectoryOnly))
++ if (d->nativeFileDialog && useNativeFileDialog(OpenFallback))
+ return d->nativeFileDialog->show(windowFlags, windowModality, parent);
+
+- openPortal();
++ openPortal(windowFlags, windowModality, parent);
+
+ return true;
+ }
+@@ -465,4 +473,21 @@ void QXdgDesktopPortalFileDialog::gotResponse(uint response, const QVariantMap &
+ }
+ }
+
++bool QXdgDesktopPortalFileDialog::useNativeFileDialog(QXdgDesktopPortalFileDialog::FallbackType fallbackType) const
++{
++ Q_D(const QXdgDesktopPortalFileDialog);
++
++ if (d->failedToOpen && fallbackType != OpenFallback)
++ return true;
++
++ if (d->fileChooserPortalVersion < 3) {
++ if (options()->fileMode() == QFileDialogOptions::Directory)
++ return true;
++ else if (options()->fileMode() == QFileDialogOptions::DirectoryOnly)
++ return true;
++ }
++
++ return false;
++}
++
+ QT_END_NAMESPACE
+diff --git a/qtbase/src/plugins/platformthemes/xdgdesktopportal/qxdgdesktopportalfiledialog_p.h b/qtbase/src/plugins/platformthemes/xdgdesktopportal/qxdgdesktopportalfiledialog_p.h
+index 4f4de96ecf..65e22a5cf2 100644
+--- a/qtbase/src/plugins/platformthemes/xdgdesktopportal/qxdgdesktopportalfiledialog_p.h
++++ b/qtbase/src/plugins/platformthemes/xdgdesktopportal/qxdgdesktopportalfiledialog_p.h
+@@ -51,6 +51,11 @@ class QXdgDesktopPortalFileDialog : public QPlatformFileDialogHelper
+ Q_OBJECT
+ Q_DECLARE_PRIVATE(QXdgDesktopPortalFileDialog)
+ public:
++ enum FallbackType {
++ GenericFallback,
++ OpenFallback
++ };
++
+ enum ConditionType : uint {
+ GlobalPattern = 0,
+ MimeType = 1
+@@ -69,7 +74,7 @@ public:
+ };
+ typedef QVector<Filter> FilterList;
+
+- QXdgDesktopPortalFileDialog(QPlatformFileDialogHelper *nativeFileDialog = nullptr);
++ QXdgDesktopPortalFileDialog(QPlatformFileDialogHelper *nativeFileDialog = nullptr, uint fileChooserPortalVersion = 0);
+ ~QXdgDesktopPortalFileDialog();
+
+ bool defaultNameFilterDisables() const override;
+@@ -92,7 +97,8 @@ private Q_SLOTS:
+
+ private:
+ void initializeDialog();
+- void openPortal();
++ void openPortal(Qt::WindowFlags windowFlags, Qt::WindowModality windowModality, QWindow *parent);
++ bool useNativeFileDialog(FallbackType fallbackType = GenericFallback) const;
+
+ QScopedPointer<QXdgDesktopPortalFileDialogPrivate> d_ptr;
+ };
+diff --git a/qtbase/src/plugins/platformthemes/xdgdesktopportal/qxdgdesktopportaltheme.cpp b/qtbase/src/plugins/platformthemes/xdgdesktopportal/qxdgdesktopportaltheme.cpp
+index fb324afbd8..b809503122 100644
+--- a/qtbase/src/plugins/platformthemes/xdgdesktopportal/qxdgdesktopportaltheme.cpp
++++ b/qtbase/src/plugins/platformthemes/xdgdesktopportal/qxdgdesktopportaltheme.cpp
+@@ -111,6 +111,7 @@ QXdgDesktopPortalTheme::QXdgDesktopPortalTheme()
+ if (reply.isValid()) {
+ d->fileChooserPortalVersion = reply.value().toUInt();
+ }
++ watcher->deleteLater();
+ });
+ }
+
+@@ -152,11 +153,12 @@ QPlatformDialogHelper* QXdgDesktopPortalTheme::createPlatformDialogHelper(Dialog
+ {
+ Q_D(const QXdgDesktopPortalTheme);
+
+- if (type == FileDialog) {
++ if (type == FileDialog && d->fileChooserPortalVersion) {
+ // Older versions of FileChooser portal don't support opening directories, therefore we fallback
+ // to native file dialog opened inside the sandbox to open a directory.
+- if (d->fileChooserPortalVersion < 3 && d->baseTheme->usePlatformNativeDialog(type))
+- return new QXdgDesktopPortalFileDialog(static_cast<QPlatformFileDialogHelper*>(d->baseTheme->createPlatformDialogHelper(type)));
++ if (d->baseTheme->usePlatformNativeDialog(type))
++ return new QXdgDesktopPortalFileDialog(static_cast<QPlatformFileDialogHelper*>(d->baseTheme->createPlatformDialogHelper(type)),
++ d->fileChooserPortalVersion);
+
+ return new QXdgDesktopPortalFileDialog;
+ }
+diff --git a/qtbase/src/plugins/printsupport/cups/qcupsprintengine.cpp b/qtbase/src/plugins/printsupport/cups/qcupsprintengine.cpp
+index 43d5e119ad..1f9cbc4565 100644
+--- a/qtbase/src/plugins/printsupport/cups/qcupsprintengine.cpp
++++ b/qtbase/src/plugins/printsupport/cups/qcupsprintengine.cpp
+@@ -89,8 +89,10 @@ void QCupsPrintEngine::setProperty(PrintEnginePropertyKey key, const QVariant &v
+ break;
+ case PPK_Duplex: {
+ QPrint::DuplexMode mode = QPrint::DuplexMode(value.toInt());
+- if (mode != d->duplex && d->m_printDevice.supportedDuplexModes().contains(mode))
++ if (d->m_printDevice.supportedDuplexModes().contains(mode)) {
+ d->duplex = mode;
++ d->duplexRequestedExplicitly = true;
++ }
+ break;
+ }
+ case PPK_PrinterName:
+@@ -277,9 +279,12 @@ void QCupsPrintEnginePrivate::changePrinter(const QString &newPrinter)
+ m_printDevice.swap(printDevice);
+ printerName = m_printDevice.id();
+
+- // Check if new printer supports current settings, otherwise us defaults
+- if (duplex != QPrint::DuplexAuto && !m_printDevice.supportedDuplexModes().contains(duplex))
++ // in case a duplex value was explicitly set, check if new printer supports current value,
++ // otherwise use device default
++ if (!duplexRequestedExplicitly || !m_printDevice.supportedDuplexModes().contains(duplex)) {
+ duplex = m_printDevice.defaultDuplexMode();
++ duplexRequestedExplicitly = false;
++ }
+ QPrint::ColorMode colorMode = grayscale ? QPrint::GrayScale : QPrint::Color;
+ if (!m_printDevice.supportedColorModes().contains(colorMode))
+ grayscale = m_printDevice.defaultColorMode() == QPrint::GrayScale;
+diff --git a/qtbase/src/plugins/printsupport/cups/qcupsprintengine_p.h b/qtbase/src/plugins/printsupport/cups/qcupsprintengine_p.h
+index c021b0c643..8f81fe478d 100644
+--- a/qtbase/src/plugins/printsupport/cups/qcupsprintengine_p.h
++++ b/qtbase/src/plugins/printsupport/cups/qcupsprintengine_p.h
+@@ -100,6 +100,7 @@ private:
+ QStringList cupsOptions;
+ QString cupsTempFile;
+ QPrint::DuplexMode duplex;
++ bool duplexRequestedExplicitly = false;
+ };
+
+ QT_END_NAMESPACE
+diff --git a/qtbase/src/plugins/sqldrivers/ibase/qsql_ibase.cpp b/qtbase/src/plugins/sqldrivers/ibase/qsql_ibase.cpp
+index 67e7154fa6..40876152e5 100644
+--- a/qtbase/src/plugins/sqldrivers/ibase/qsql_ibase.cpp
++++ b/qtbase/src/plugins/sqldrivers/ibase/qsql_ibase.cpp
+@@ -817,7 +817,7 @@ bool QIBaseResultPrivate::writeArray(int column, const QList<QVariant> &list)
+ ba.resize(int(bufLen));
+
+ if (list.size() > arraySize) {
+- error = QLatin1String("Array size missmatch: size of %1 is %2, size of provided list is %3");
++ error = QLatin1String("Array size mismatch: size of %1 is %2, size of provided list is %3");
+ error = error.arg(QLatin1String(sqlname)).arg(arraySize).arg(list.size());
+ q->setLastError(QSqlError(error, QLatin1String(""), QSqlError::StatementError));
+ return false;
+diff --git a/qtbase/src/plugins/sqldrivers/mysql/qsql_mysql.cpp b/qtbase/src/plugins/sqldrivers/mysql/qsql_mysql.cpp
+index 7ca055eea2..6bc9d46755 100644
+--- a/qtbase/src/plugins/sqldrivers/mysql/qsql_mysql.cpp
++++ b/qtbase/src/plugins/sqldrivers/mysql/qsql_mysql.cpp
+@@ -223,7 +223,7 @@ public:
+ struct QMyField
+ {
+ char *outField = nullptr;
+- MYSQL_FIELD *myField = nullptr;
++ const MYSQL_FIELD *myField = nullptr;
+ QMetaType::Type type = QMetaType::UnknownType;
+ my_bool nullIndicator = false;
+ ulong bufLength = 0ul;
+@@ -361,7 +361,7 @@ static bool qIsInteger(int t)
+ void QMYSQLResultPrivate::bindBlobs()
+ {
+ int i;
+- MYSQL_FIELD *fieldInfo;
++ const MYSQL_FIELD *fieldInfo;
+ MYSQL_BIND *bind;
+
+ for(i = 0; i < fields.count(); ++i) {
+@@ -379,7 +379,6 @@ void QMYSQLResultPrivate::bindBlobs()
+ bool QMYSQLResultPrivate::bindInValues()
+ {
+ MYSQL_BIND *bind;
+- char *field;
+ int i = 0;
+
+ if (!meta)
+@@ -392,35 +391,34 @@ bool QMYSQLResultPrivate::bindInValues()
+ inBinds = new MYSQL_BIND[fields.size()];
+ memset(inBinds, 0, fields.size() * sizeof(MYSQL_BIND));
+
+- MYSQL_FIELD *fieldInfo;
++ const MYSQL_FIELD *fieldInfo;
+
+ while((fieldInfo = mysql_fetch_field(meta))) {
++ bind = &inBinds[i];
++
+ QMyField &f = fields[i];
+ f.myField = fieldInfo;
+-
++ bind->buffer_length = f.bufLength = fieldInfo->length + 1;
++ bind->buffer_type = fieldInfo->type;
+ f.type = qDecodeMYSQLType(fieldInfo->type, fieldInfo->flags);
+ if (qIsBlob(fieldInfo->type)) {
+ // the size of a blob-field is available as soon as we call
+ // mysql_stmt_store_result()
+ // after mysql_stmt_exec() in QMYSQLResult::exec()
+- fieldInfo->length = 0;
++ bind->buffer_length = f.bufLength = 0;
+ hasBlobs = true;
+ } else if (qIsInteger(f.type)) {
+- fieldInfo->length = 8;
++ bind->buffer_length = f.bufLength = 8;
+ } else {
+- fieldInfo->type = MYSQL_TYPE_STRING;
++ bind->buffer_type = MYSQL_TYPE_STRING;
+ }
+- bind = &inBinds[i];
+- field = new char[fieldInfo->length + 1];
+- memset(field, 0, fieldInfo->length + 1);
+
+- bind->buffer_type = fieldInfo->type;
+- bind->buffer = field;
+- bind->buffer_length = f.bufLength = fieldInfo->length + 1;
+ bind->is_null = &f.nullIndicator;
+ bind->length = &f.bufLength;
+ bind->is_unsigned = fieldInfo->flags & UNSIGNED_FLAG ? 1 : 0;
+- f.outField=field;
++
++ char *field = new char[bind->buffer_length + 1]{};
++ bind->buffer = f.outField = field;
+
+ ++i;
+ }
+@@ -1369,20 +1367,20 @@ bool QMYSQLDriver::open(const QString& db,
+ }
+
+ #if MYSQL_VERSION_ID >= 50007
+- if (mysql_get_client_version() >= 50503 && mysql_get_server_version(d->mysql) >= 50503) {
+- // force the communication to be utf8mb4 (only utf8mb4 supports 4-byte characters)
+- mysql_set_character_set(d->mysql, "utf8mb4");
++ // force the communication to be utf8mb4 (only utf8mb4 supports 4-byte characters)
++ if (mysql_set_character_set(d->mysql, "utf8mb4")) {
++ // this failed, try forcing it to utf (BMP only)
++ if (mysql_set_character_set(d->mysql, "utf8"))
++ qWarning() << "MySQL: Unable to set the client character set to utf8.";
+ #if QT_CONFIG(textcodec)
+- d->tc = QTextCodec::codecForName("UTF-8");
++ else
++ d->tc = codec(d->mysql);
+ #endif
+- } else
+- {
+- // force the communication to be utf8
+- mysql_set_character_set(d->mysql, "utf8");
++ }
+ #if QT_CONFIG(textcodec)
+- d->tc = codec(d->mysql);
++ else
++ d->tc = QTextCodec::codecForName("UTF-8");
+ #endif
+- }
+ #endif // MYSQL_VERSION_ID >= 50007
+
+ d->preparedQuerysEnabled = checkPreparedQueries(d->mysql);
+diff --git a/qtbase/src/printsupport/dialogs/images/print-24.png b/qtbase/src/printsupport/dialogs/images/printer-24.png
+similarity index 100%
+rename from src/printsupport/dialogs/images/print-24.png
+rename to src/printsupport/dialogs/images/printer-24.png
+diff --git a/qtbase/src/printsupport/dialogs/images/print-32.png b/qtbase/src/printsupport/dialogs/images/printer-32.png
+similarity index 100%
+rename from src/printsupport/dialogs/images/print-32.png
+rename to src/printsupport/dialogs/images/printer-32.png
+diff --git a/qtbase/src/printsupport/dialogs/images/view-page-sided-24.png b/qtbase/src/printsupport/dialogs/images/view-pages-facing-24.png
+similarity index 100%
+rename from src/printsupport/dialogs/images/view-page-sided-24.png
+rename to src/printsupport/dialogs/images/view-pages-facing-24.png
+diff --git a/qtbase/src/printsupport/dialogs/images/view-page-sided-32.png b/qtbase/src/printsupport/dialogs/images/view-pages-facing-32.png
+similarity index 100%
+rename from src/printsupport/dialogs/images/view-page-sided-32.png
+rename to src/printsupport/dialogs/images/view-pages-facing-32.png
+diff --git a/qtbase/src/printsupport/dialogs/images/view-page-multi-24.png b/qtbase/src/printsupport/dialogs/images/view-pages-overview-24.png
+similarity index 100%
+rename from src/printsupport/dialogs/images/view-page-multi-24.png
+rename to src/printsupport/dialogs/images/view-pages-overview-24.png
+diff --git a/qtbase/src/printsupport/dialogs/images/view-page-multi-32.png b/qtbase/src/printsupport/dialogs/images/view-pages-overview-32.png
+similarity index 100%
+rename from src/printsupport/dialogs/images/view-page-multi-32.png
+rename to src/printsupport/dialogs/images/view-pages-overview-32.png
+diff --git a/qtbase/src/printsupport/dialogs/images/view-page-one-24.png b/qtbase/src/printsupport/dialogs/images/view-pages-single-24.png
+similarity index 100%
+rename from src/printsupport/dialogs/images/view-page-one-24.png
+rename to src/printsupport/dialogs/images/view-pages-single-24.png
+diff --git a/qtbase/src/printsupport/dialogs/images/view-page-one-32.png b/qtbase/src/printsupport/dialogs/images/view-pages-single-32.png
+similarity index 100%
+rename from src/printsupport/dialogs/images/view-page-one-32.png
+rename to src/printsupport/dialogs/images/view-pages-single-32.png
+diff --git a/qtbase/src/printsupport/dialogs/images/fit-page-24.png b/qtbase/src/printsupport/dialogs/images/zoom-fit-page-24.png
+similarity index 100%
+rename from src/printsupport/dialogs/images/fit-page-24.png
+rename to src/printsupport/dialogs/images/zoom-fit-page-24.png
+diff --git a/qtbase/src/printsupport/dialogs/images/fit-page-32.png b/qtbase/src/printsupport/dialogs/images/zoom-fit-page-32.png
+similarity index 100%
+rename from src/printsupport/dialogs/images/fit-page-32.png
+rename to src/printsupport/dialogs/images/zoom-fit-page-32.png
+diff --git a/qtbase/src/printsupport/dialogs/images/fit-width-24.png b/qtbase/src/printsupport/dialogs/images/zoom-fit-width-24.png
+similarity index 100%
+rename from src/printsupport/dialogs/images/fit-width-24.png
+rename to src/printsupport/dialogs/images/zoom-fit-width-24.png
+diff --git a/qtbase/src/printsupport/dialogs/images/fit-width-32.png b/qtbase/src/printsupport/dialogs/images/zoom-fit-width-32.png
+similarity index 100%
+rename from src/printsupport/dialogs/images/fit-width-32.png
+rename to src/printsupport/dialogs/images/zoom-fit-width-32.png
+diff --git a/qtbase/src/printsupport/dialogs/qpagesetupdialog_unix.cpp b/qtbase/src/printsupport/dialogs/qpagesetupdialog_unix.cpp
+index 78e5b8d1ef..2a28516719 100644
+--- a/qtbase/src/printsupport/dialogs/qpagesetupdialog_unix.cpp
++++ b/qtbase/src/printsupport/dialogs/qpagesetupdialog_unix.cpp
+@@ -532,6 +532,7 @@ void QPageSetupWidget::updateWidget()
+ void QPageSetupWidget::setupPrinter() const
+ {
+ m_printer->setPageLayout(m_pageLayout);
++ m_printer->setPageOrientation(m_pageLayout.orientation());
+ #if QT_CONFIG(cups)
+ QCUPSSupport::PagesPerSheet pagesPerSheet = qvariant_cast<QCUPSSupport::PagesPerSheet>(m_ui.pagesPerSheetCombo->currentData()
+ );
+diff --git a/qtbase/src/printsupport/dialogs/qprintdialog.qrc b/qtbase/src/printsupport/dialogs/qprintdialog.qrc
+index 5a579baa55..10b8e1d341 100644
+--- a/qtbase/src/printsupport/dialogs/qprintdialog.qrc
++++ b/qtbase/src/printsupport/dialogs/qprintdialog.qrc
+@@ -1,9 +1,9 @@
+ <!DOCTYPE RCC><RCC version="1.0">
+ <qresource prefix="/qt-project.org/dialogs/qprintpreviewdialog">
+-<file>images/fit-page-24.png</file>
+-<file>images/fit-page-32.png</file>
+-<file>images/fit-width-24.png</file>
+-<file>images/fit-width-32.png</file>
++<file>images/zoom-fit-page-24.png</file>
++<file>images/zoom-fit-page-32.png</file>
++<file>images/zoom-fit-width-24.png</file>
++<file>images/zoom-fit-width-32.png</file>
+ <file>images/go-first-24.png</file>
+ <file>images/go-first-32.png</file>
+ <file>images/go-last-24.png</file>
+@@ -18,14 +18,14 @@
+ <file>images/layout-portrait-32.png</file>
+ <file>images/page-setup-24.png</file>
+ <file>images/page-setup-32.png</file>
+-<file>images/print-24.png</file>
+-<file>images/print-32.png</file>
+-<file>images/view-page-multi-24.png</file>
+-<file>images/view-page-multi-32.png</file>
+-<file>images/view-page-one-24.png</file>
+-<file>images/view-page-one-32.png</file>
+-<file>images/view-page-sided-24.png</file>
+-<file>images/view-page-sided-32.png</file>
++<file>images/printer-24.png</file>
++<file>images/printer-32.png</file>
++<file>images/view-pages-overview-24.png</file>
++<file>images/view-pages-overview-32.png</file>
++<file>images/view-pages-single-24.png</file>
++<file>images/view-pages-single-32.png</file>
++<file>images/view-pages-facing-24.png</file>
++<file>images/view-pages-facing-32.png</file>
+ <file>images/zoom-in-24.png</file>
+ <file>images/zoom-in-32.png</file>
+ <file>images/zoom-out-24.png</file>
+diff --git a/qtbase/src/printsupport/dialogs/qprintdialog_unix.cpp b/qtbase/src/printsupport/dialogs/qprintdialog_unix.cpp
+index c5b845f4ec..5a5ba1d0a8 100644
+--- a/qtbase/src/printsupport/dialogs/qprintdialog_unix.cpp
++++ b/qtbase/src/printsupport/dialogs/qprintdialog_unix.cpp
+@@ -702,13 +702,14 @@ void QPrintDialogPrivate::selectPrinter(const QPrinter::OutputFormat outputForma
+ else
+ options.grayscale->setChecked(true);
+
+- // keep duplex value explicitly set by user, if any, and selected printer supports it;
+- // use device default otherwise
++ // duplex priorities to be as follows:
++ // 1) a user-selected duplex value in the dialog has highest prority
++ // 2) duplex value set in the QPrinter
+ QPrint::DuplexMode duplex;
+ if (explicitDuplexMode != QPrint::DuplexAuto && supportedDuplexMode.contains(explicitDuplexMode))
+ duplex = explicitDuplexMode;
+ else
+- duplex = top->d->m_currentPrintDevice.defaultDuplexMode();
++ duplex = static_cast<QPrint::DuplexMode>(p->duplex());
+ switch (duplex) {
+ case QPrint::DuplexNone:
+ options.noDuplex->setChecked(true); break;
+@@ -1242,10 +1243,10 @@ void QUnixPrintWidgetPrivate::_q_printerChanged(int index)
+ QString filename = widget.filename->text();
+ widget.filename->setText(filename);
+ widget.lOutput->setEnabled(true);
+- if (optionsPane)
+- optionsPane->selectPrinter(QPrinter::PdfFormat);
+ printer->setOutputFormat(QPrinter::PdfFormat);
+ m_currentPrintDevice = QPrintDevice();
++ if (optionsPane)
++ optionsPane->selectPrinter(QPrinter::PdfFormat);
+ return;
+ }
+ }
+diff --git a/qtbase/src/printsupport/dialogs/qprintpreviewdialog.cpp b/qtbase/src/printsupport/dialogs/qprintpreviewdialog.cpp
+index 39575d5f57..23b7e89538 100644
+--- a/qtbase/src/printsupport/dialogs/qprintpreviewdialog.cpp
++++ b/qtbase/src/printsupport/dialogs/qprintpreviewdialog.cpp
+@@ -352,7 +352,7 @@ void QPrintPreviewDialogPrivate::init(QPrinter *_printer)
+ static inline void qt_setupActionIcon(QAction *action, QLatin1String name)
+ {
+ QLatin1String imagePrefix(":/qt-project.org/dialogs/qprintpreviewdialog/images/");
+- QIcon icon;
++ QIcon icon = QIcon::fromTheme(name);
+ icon.addFile(imagePrefix + name + QLatin1String("-24.png"), QSize(24, 24));
+ icon.addFile(imagePrefix + name + QLatin1String("-32.png"), QSize(32, 32));
+ action->setIcon(icon);
+@@ -383,8 +383,8 @@ void QPrintPreviewDialogPrivate::setupActions()
+ fitPageAction->setObjectName(QLatin1String("fitPageAction"));
+ fitWidthAction->setCheckable(true);
+ fitPageAction->setCheckable(true);
+- qt_setupActionIcon(fitWidthAction, QLatin1String("fit-width"));
+- qt_setupActionIcon(fitPageAction, QLatin1String("fit-page"));
++ qt_setupActionIcon(fitWidthAction, QLatin1String("zoom-fit-width"));
++ qt_setupActionIcon(fitPageAction, QLatin1String("zoom-fit-page"));
+ QObject::connect(fitGroup, SIGNAL(triggered(QAction*)), q, SLOT(_q_fit(QAction*)));
+
+ // Zoom
+@@ -410,9 +410,9 @@ void QPrintPreviewDialogPrivate::setupActions()
+ singleModeAction = modeGroup->addAction(QCoreApplication::translate("QPrintPreviewDialog", "Show single page"));
+ facingModeAction = modeGroup->addAction(QCoreApplication::translate("QPrintPreviewDialog", "Show facing pages"));
+ overviewModeAction = modeGroup->addAction(QCoreApplication::translate("QPrintPreviewDialog", "Show overview of all pages"));
+- qt_setupActionIcon(singleModeAction, QLatin1String("view-page-one"));
+- qt_setupActionIcon(facingModeAction, QLatin1String("view-page-sided"));
+- qt_setupActionIcon(overviewModeAction, QLatin1String("view-page-multi"));
++ qt_setupActionIcon(singleModeAction, QLatin1String("view-pages-single"));
++ qt_setupActionIcon(facingModeAction, QLatin1String("view-pages-facing"));
++ qt_setupActionIcon(overviewModeAction, QLatin1String("view-pages-overview"));
+ singleModeAction->setObjectName(QLatin1String("singleModeAction"));
+ facingModeAction->setObjectName(QLatin1String("facingModeAction"));
+ overviewModeAction->setObjectName(QLatin1String("overviewModeAction"));
+@@ -426,7 +426,7 @@ void QPrintPreviewDialogPrivate::setupActions()
+ printerGroup = new QActionGroup(q);
+ printAction = printerGroup->addAction(QCoreApplication::translate("QPrintPreviewDialog", "Print"));
+ pageSetupAction = printerGroup->addAction(QCoreApplication::translate("QPrintPreviewDialog", "Page setup"));
+- qt_setupActionIcon(printAction, QLatin1String("print"));
++ qt_setupActionIcon(printAction, QLatin1String("printer"));
+ qt_setupActionIcon(pageSetupAction, QLatin1String("page-setup"));
+ QObject::connect(printAction, SIGNAL(triggered(bool)), q, SLOT(_q_print()));
+ QObject::connect(pageSetupAction, SIGNAL(triggered(bool)), q, SLOT(_q_pageSetup()));
+diff --git a/qtbase/src/sql/kernel/qsqlquery.cpp b/qtbase/src/sql/kernel/qsqlquery.cpp
+index 32c6166c79..60afef10c3 100644
+--- a/qtbase/src/sql/kernel/qsqlquery.cpp
++++ b/qtbase/src/sql/kernel/qsqlquery.cpp
+@@ -1,6 +1,6 @@
+ /****************************************************************************
+ **
+-** Copyright (C) 2016 The Qt Company Ltd.
++** Copyright (C) 2022 The Qt Company Ltd.
+ ** Contact: https://www.qt.io/licensing/
+ **
+ ** This file is part of the QtSql module of the Qt Toolkit.
+@@ -377,6 +377,10 @@ bool QSqlQuery::exec(const QString& query)
+ QElapsedTimer t;
+ t.start();
+ #endif
++ if (!driver()) {
++ qWarning("QSqlQuery::exec: called before driver has been set up");
++ return false;
++ }
+ if (d->ref.loadRelaxed() != 1) {
+ bool fo = isForwardOnly();
+ *this = QSqlQuery(driver()->createResult());
+diff --git a/qtbase/src/testlib/qabstractitemmodeltester.cpp b/qtbase/src/testlib/qabstractitemmodeltester.cpp
+index 8efb9c53d4..ce062f66d7 100644
+--- a/qtbase/src/testlib/qabstractitemmodeltester.cpp
++++ b/qtbase/src/testlib/qabstractitemmodeltester.cpp
+@@ -454,7 +454,7 @@ void QAbstractItemModelTesterPrivate::parent()
+
+ // Common error test #2, make sure that a second level index has a parent
+ // that is the first level index.
+- if (model->rowCount(topIndex) > 0) {
++ if (model->rowCount(topIndex) > 0 && model->columnCount(topIndex) > 0) {
+ QModelIndex childIndex = model->index(0, 0, topIndex);
+ MODELTESTER_VERIFY(childIndex.isValid());
+ MODELTESTER_COMPARE(model->parent(childIndex), topIndex);
+diff --git a/qtbase/src/testlib/qasciikey.cpp b/qtbase/src/testlib/qasciikey.cpp
+index 9a308da2bc..93498b256f 100644
+--- a/qtbase/src/testlib/qasciikey.cpp
++++ b/qtbase/src/testlib/qasciikey.cpp
+@@ -498,6 +498,11 @@ char QTest::keyToAscii(Qt::Key key)
+ case Qt::Key_LaunchE : return 0; // = 0x10b0,
+ case Qt::Key_LaunchF : return 0; // = 0x10b1,
+
++ // Keypad navigation keys
++ case Qt::Key_Select : return 0; // = 0x01010000
++ case Qt::Key_Yes : return 0; // = 0x01010001
++ case Qt::Key_No : return 0; // = 0x01010002
++
+ default: QTEST_ASSERT(false); return 0;
+ }
+ }
+diff --git a/qtbase/src/testlib/qtestresult.cpp b/qtbase/src/testlib/qtestresult.cpp
+index 88028aac6e..2e89930776 100644
+--- a/qtbase/src/testlib/qtestresult.cpp
++++ b/qtbase/src/testlib/qtestresult.cpp
+@@ -251,7 +251,8 @@ bool QTestResult::verify(bool statement, const char *statementStr,
+ {
+ QTEST_ASSERT(statementStr);
+
+- char msg[1024] = {'\0'};
++ char msg[1024];
++ msg[0] = '\0';
+
+ if (QTestLog::verboseLevel() >= 2) {
+ qsnprintf(msg, 1024, "QVERIFY(%s)", statementStr);
+@@ -309,7 +310,8 @@ static bool compareHelper(bool success, const char *failureMsg,
+ bool hasValues = true)
+ {
+ const size_t maxMsgLen = 1024;
+- char msg[maxMsgLen] = {'\0'};
++ char msg[maxMsgLen];
++ msg[0] = '\0';
+
+ QTEST_ASSERT(expected);
+ QTEST_ASSERT(actual);
+diff --git a/qtbase/src/widgets/dialogs/qcolordialog.cpp b/qtbase/src/widgets/dialogs/qcolordialog.cpp
+index 4247731275..cb325be85c 100644
+--- a/qtbase/src/widgets/dialogs/qcolordialog.cpp
++++ b/qtbase/src/widgets/dialogs/qcolordialog.cpp
+@@ -78,7 +78,10 @@
+ #include "qwindow.h"
+
+ #include "private/qdialog_p.h"
++#include "private/qguiapplication_p.h"
+
++#include <qpa/qplatformservices.h>
++#include <qpa/qplatformintegration.h>
+ #include <algorithm>
+
+ QT_BEGIN_NAMESPACE
+@@ -1611,6 +1614,20 @@ void QColorDialogPrivate::_q_newStandard(int r, int c)
+ void QColorDialogPrivate::_q_pickScreenColor()
+ {
+ Q_Q(QColorDialog);
++
++ auto *platformServices = QGuiApplicationPrivate::platformIntegration()->services();
++ if (platformServices->hasCapability(QPlatformServices::Capability::ColorPicking)) {
++ if (auto *colorPicker = platformServices->colorPicker(q->windowHandle())) {
++ q->connect(colorPicker, &QPlatformServiceColorPicker::colorPicked, q,
++ [q, colorPicker](const QColor &color) {
++ colorPicker->deleteLater();
++ q->setCurrentColor(color);
++ });
++ colorPicker->pickColor();
++ return;
++ }
++ }
++
+ if (!colorPickingEventFilter)
+ colorPickingEventFilter = new QColorPickingEventFilter(this, q);
+ q->installEventFilter(colorPickingEventFilter);
+diff --git a/qtbase/src/widgets/itemviews/qabstractitemdelegate.cpp b/qtbase/src/widgets/itemviews/qabstractitemdelegate.cpp
+index e120817edc..8ea36b5427 100644
+--- a/qtbase/src/widgets/itemviews/qabstractitemdelegate.cpp
++++ b/qtbase/src/widgets/itemviews/qabstractitemdelegate.cpp
+@@ -400,12 +400,7 @@ bool QAbstractItemDelegate::helpEvent(QHelpEvent *event,
+ const QString tooltip = index.isValid() ?
+ d->textForRole(Qt::ToolTipRole, index.data(Qt::ToolTipRole), option.locale, precision) :
+ QString();
+- QRect rect;
+- if (index.isValid()) {
+- const QRect r = view->visualRect(index);
+- rect = QRect(view->mapToGlobal(r.topLeft()), r.size());
+- }
+- QToolTip::showText(he->globalPos(), tooltip, view, rect);
++ QToolTip::showText(he->globalPos(), tooltip, view->viewport(), option.rect);
+ event->setAccepted(!tooltip.isEmpty());
+ break;
+ }
+diff --git a/qtbase/src/widgets/itemviews/qlistview.cpp b/qtbase/src/widgets/itemviews/qlistview.cpp
+index 2b34476642..eebfaa030e 100644
+--- a/qtbase/src/widgets/itemviews/qlistview.cpp
++++ b/qtbase/src/widgets/itemviews/qlistview.cpp
+@@ -3386,6 +3386,7 @@ void QIconModeViewBase::updateContentsSize()
+ */
+ void QListView::currentChanged(const QModelIndex ¤t, const QModelIndex &previous)
+ {
++ QAbstractItemView::currentChanged(current, previous);
+ #ifndef QT_NO_ACCESSIBILITY
+ if (QAccessible::isActive()) {
+ if (current.isValid()) {
+@@ -3396,7 +3397,6 @@ void QListView::currentChanged(const QModelIndex ¤t, const QModelIndex &pr
+ }
+ }
+ #endif
+- QAbstractItemView::currentChanged(current, previous);
+ }
+
+ /*!
+diff --git a/qtbase/src/widgets/itemviews/qtableview.cpp b/qtbase/src/widgets/itemviews/qtableview.cpp
+index 934ac581b2..f79bb24249 100644
+--- a/qtbase/src/widgets/itemviews/qtableview.cpp
++++ b/qtbase/src/widgets/itemviews/qtableview.cpp
+@@ -1013,6 +1013,7 @@ void QTableViewPrivate::drawCell(QPainter *painter, const QStyleOptionViewItem &
+ int QTableViewPrivate::widthHintForIndex(const QModelIndex &index, int hint, const QStyleOptionViewItem &option) const
+ {
+ Q_Q(const QTableView);
++ const int oldHint = hint;
+ QWidget *editor = editorForIndex(index).widget.data();
+ if (editor && persistent.contains(editor)) {
+ hint = qMax(hint, editor->sizeHint().width());
+@@ -1021,6 +1022,17 @@ int QTableViewPrivate::widthHintForIndex(const QModelIndex &index, int hint, con
+ hint = qBound(min, hint, max);
+ }
+ hint = qMax(hint, q->itemDelegate(index)->sizeHint(option, index).width());
++
++ if (hasSpans()) {
++ auto span = spans.spanAt(index.column(), index.row());
++ if (span && span->m_left == index.column() && span->m_top == index.row()) {
++ // spans are screwed up when sections are moved
++ const auto left = logicalColumn(span->m_left);
++ for (int i = 1; i <= span->width(); ++i)
++ hint -= q->columnWidth(visualColumn(left + i));
++ }
++ hint = std::max(hint, oldHint);
++ }
+ return hint;
+ }
+
+@@ -1053,6 +1065,11 @@ int QTableViewPrivate::heightHintForIndex(const QModelIndex &index, int hint, QS
+ option.rect.setHeight(height);
+ option.rect.setX(q->columnViewportPosition(index.column()));
+ option.rect.setWidth(q->columnWidth(index.column()));
++ if (hasSpans()) {
++ auto span = spans.spanAt(index.column(), index.row());
++ if (span && span->m_left == index.column() && span->m_top == index.row())
++ option.rect.setWidth(std::max(option.rect.width(), visualSpanRect(*span).width()));
++ }
+ // 1px less space when grid is shown (see drawCell)
+ if (showGrid)
+ option.rect.setWidth(option.rect.width() - 1);
+diff --git a/qtbase/src/widgets/kernel/qaction.h b/qtbase/src/widgets/kernel/qaction.h
+index 258a1ea0a0..737c1e8285 100644
+--- a/qtbase/src/widgets/kernel/qaction.h
++++ b/qtbase/src/widgets/kernel/qaction.h
+@@ -81,7 +81,7 @@ class Q_WIDGETS_EXPORT QAction : public QObject
+ Q_PROPERTY(MenuRole menuRole READ menuRole WRITE setMenuRole NOTIFY changed)
+ Q_PROPERTY(bool iconVisibleInMenu READ isIconVisibleInMenu WRITE setIconVisibleInMenu NOTIFY changed)
+ Q_PROPERTY(bool shortcutVisibleInContextMenu READ isShortcutVisibleInContextMenu WRITE setShortcutVisibleInContextMenu NOTIFY changed)
+- Q_PROPERTY(Priority priority READ priority WRITE setPriority)
++ Q_PROPERTY(Priority priority READ priority WRITE setPriority NOTIFY changed)
+
+ public:
+ // note this is copied into qplatformmenu.h, which must stay in sync
+diff --git a/qtbase/src/widgets/kernel/qwidget.cpp b/qtbase/src/widgets/kernel/qwidget.cpp
+index 9eba1e001e..26f6d27e18 100644
+--- a/qtbase/src/widgets/kernel/qwidget.cpp
++++ b/qtbase/src/widgets/kernel/qwidget.cpp
+@@ -5296,7 +5296,7 @@ void QWidgetPrivate::drawWidget(QPaintDevice *pdev, const QRegion &rgn, const QP
+ QWidgetEffectSourcePrivate *sourced = static_cast<QWidgetEffectSourcePrivate *>
+ (source->d_func());
+ if (!sourced->context) {
+- const QRegion effectRgn(rgn.boundingRect());
++ const QRegion effectRgn((flags & UseEffectRegionBounds) ? rgn.boundingRect() : rgn);
+ QWidgetPaintContext context(pdev, effectRgn, offset, flags, sharedPainter, repaintManager);
+ sourced->context = &context;
+ if (!sharedPainter) {
+@@ -5328,6 +5328,7 @@ void QWidgetPrivate::drawWidget(QPaintDevice *pdev, const QRegion &rgn, const QP
+ }
+ }
+ #endif // QT_CONFIG(graphicseffect)
++ flags = flags & ~UseEffectRegionBounds;
+
+ const bool alsoOnScreen = flags & DrawPaintOnScreen;
+ const bool recursive = flags & DrawRecursive;
+diff --git a/qtbase/src/widgets/kernel/qwidget_p.h b/qtbase/src/widgets/kernel/qwidget_p.h
+index eef6b8fa2c..c432f4b5d5 100644
+--- a/qtbase/src/widgets/kernel/qwidget_p.h
++++ b/qtbase/src/widgets/kernel/qwidget_p.h
+@@ -229,7 +229,8 @@ public:
+ DontSubtractOpaqueChildren = 0x10,
+ DontDrawOpaqueChildren = 0x20,
+ DontDrawNativeChildren = 0x40,
+- DontSetCompositionMode = 0x80
++ DontSetCompositionMode = 0x80,
++ UseEffectRegionBounds = 0x100
+ };
+ Q_DECLARE_FLAGS(DrawWidgetFlags, DrawWidgetFlag)
+ Q_FLAG(DrawWidgetFlags)
+diff --git a/qtbase/src/widgets/kernel/qwidgetrepaintmanager.cpp b/qtbase/src/widgets/kernel/qwidgetrepaintmanager.cpp
+index 02880b34da..0d44e1326d 100644
+--- a/qtbase/src/widgets/kernel/qwidgetrepaintmanager.cpp
++++ b/qtbase/src/widgets/kernel/qwidgetrepaintmanager.cpp
+@@ -1018,7 +1018,8 @@ void QWidgetRepaintManager::paintAndFlush()
+
+ // Paint the rest with composition.
+ if (repaintAllWidgets || !dirtyCopy.isEmpty()) {
+- QWidgetPrivate::DrawWidgetFlags flags = QWidgetPrivate::DrawAsRoot | QWidgetPrivate::DrawRecursive;
++ QWidgetPrivate::DrawWidgetFlags flags = QWidgetPrivate::DrawAsRoot | QWidgetPrivate::DrawRecursive
++ | QWidgetPrivate::UseEffectRegionBounds;
+ tlw->d_func()->drawWidget(store->paintDevice(), dirtyCopy, QPoint(), flags, nullptr, this);
+ }
+
+diff --git a/qtbase/src/widgets/styles/qfusionstyle.cpp b/qtbase/src/widgets/styles/qfusionstyle.cpp
+index f4345d97c4..962912c838 100644
+--- a/qtbase/src/widgets/styles/qfusionstyle.cpp
++++ b/qtbase/src/widgets/styles/qfusionstyle.cpp
+@@ -1772,14 +1772,6 @@ void QFusionStyle::drawControl(ControlElement element, const QStyleOption *optio
+ proxy()->drawControl(CE_PushButtonLabel, &subopt, painter, widget);
+ }
+ break;
+- case CE_PushButtonLabel:
+- if (const QStyleOptionButton *button = qstyleoption_cast<const QStyleOptionButton *>(option)) {
+- QStyleOptionButton b(*button);
+- // no PM_ButtonShiftHorizontal and PM_ButtonShiftVertical for fusion style
+- b.state &= ~(State_On | State_Sunken);
+- QCommonStyle::drawControl(element, &b, painter, widget);
+- }
+- break;
+ case CE_MenuBarEmptyArea:
+ painter->save();
+ {
+diff --git a/qtbase/src/widgets/util/qcompleter.cpp b/qtbase/src/widgets/util/qcompleter.cpp
+index 18b24063d8..ef7207a8a3 100644
+--- a/qtbase/src/widgets/util/qcompleter.cpp
++++ b/qtbase/src/widgets/util/qcompleter.cpp
+@@ -1120,6 +1120,8 @@ void QCompleter::setModel(QAbstractItemModel *model)
+ {
+ Q_D(QCompleter);
+ QAbstractItemModel *oldModel = d->proxy->sourceModel();
++ if (oldModel == model)
++ return;
+ #if QT_CONFIG(filesystemmodel)
+ if (qobject_cast<const QFileSystemModel *>(oldModel))
+ setCompletionRole(Qt::EditRole); // QTBUG-54642, clear FileNameRole set by QFileSystemModel
+diff --git a/qtbase/src/widgets/widgets/qabstractbutton.cpp b/qtbase/src/widgets/widgets/qabstractbutton.cpp
+index a128b23950..dc40bf62fb 100644
+--- a/qtbase/src/widgets/widgets/qabstractbutton.cpp
++++ b/qtbase/src/widgets/widgets/qabstractbutton.cpp
+@@ -56,6 +56,7 @@
+ #ifndef QT_NO_ACCESSIBILITY
+ #include "qaccessible.h"
+ #endif
++#include <qpa/qplatformtheme.h>
+
+ #include <algorithm>
+
+@@ -1076,19 +1077,19 @@ void QAbstractButton::keyPressEvent(QKeyEvent *e)
+ {
+ Q_D(QAbstractButton);
+ bool next = true;
+- switch (e->key()) {
+- case Qt::Key_Enter:
+- case Qt::Key_Return:
+- e->ignore();
+- break;
+- case Qt::Key_Select:
+- case Qt::Key_Space:
+- if (!e->isAutoRepeat()) {
+- setDown(true);
+- repaint();
+- d->emitPressed();
+- }
+- break;
++
++ const auto key = static_cast<Qt::Key>(e->key());
++ const auto buttonPressKeys = QGuiApplicationPrivate::platformTheme()
++ ->themeHint(QPlatformTheme::ButtonPressKeys)
++ .value<QList<Qt::Key>>();
++ if (buttonPressKeys.contains(key) && !e->isAutoRepeat()) {
++ setDown(true);
++ repaint();
++ d->emitPressed();
++ return;
++ }
++
++ switch (key) {
+ case Qt::Key_Up:
+ next = false;
+ Q_FALLTHROUGH();
+@@ -1153,15 +1154,15 @@ void QAbstractButton::keyReleaseEvent(QKeyEvent *e)
+ if (!e->isAutoRepeat())
+ d->repeatTimer.stop();
+
+- switch (e->key()) {
+- case Qt::Key_Select:
+- case Qt::Key_Space:
+- if (!e->isAutoRepeat() && d->down)
+- d->click();
+- break;
+- default:
+- e->ignore();
++ const auto buttonPressKeys = QGuiApplicationPrivate::platformTheme()
++ ->themeHint(QPlatformTheme::ButtonPressKeys)
++ .value<QList<Qt::Key>>();
++ if (buttonPressKeys.contains(static_cast<Qt::Key>(e->key())) && !e->isAutoRepeat() && d->down) {
++ d->click();
++ return;
+ }
++
++ e->ignore();
+ }
+
+ /*!\reimp
+diff --git a/qtbase/src/widgets/widgets/qcombobox.cpp b/qtbase/src/widgets/widgets/qcombobox.cpp
+index 7a496c27e0..0a3d96647b 100644
+--- a/qtbase/src/widgets/widgets/qcombobox.cpp
++++ b/qtbase/src/widgets/widgets/qcombobox.cpp
+@@ -3352,7 +3352,23 @@ void QComboBox::keyPressEvent(QKeyEvent *e)
+
+ Move move = NoMove;
+ int newIndex = currentIndex();
+- switch (e->key()) {
++
++ bool pressLikeButton = !d->lineEdit;
++#ifdef QT_KEYPAD_NAVIGATION
++ pressLikeButton |= QApplicationPrivate::keypadNavigationEnabled() && !hasEditFocus();
++#endif
++ auto key = static_cast<Qt::Key>(e->key());
++ if (pressLikeButton) {
++ const auto buttonPressKeys = QGuiApplicationPrivate::platformTheme()
++ ->themeHint(QPlatformTheme::ButtonPressKeys)
++ .value<QList<Qt::Key>>();
++ if (buttonPressKeys.contains(key)) {
++ showPopup();
++ return;
++ }
++ }
++
++ switch (key) {
+ case Qt::Key_Up:
+ if (e->modifiers() & Qt::ControlModifier)
+ break; // pass to line edit for auto completion
+@@ -3394,26 +3410,11 @@ void QComboBox::keyPressEvent(QKeyEvent *e)
+ return;
+ }
+ break;
+- case Qt::Key_Space:
+- if (!d->lineEdit) {
+- showPopup();
+- return;
+- }
+- break;
+- case Qt::Key_Enter:
+- case Qt::Key_Return:
+ case Qt::Key_Escape:
+ if (!d->lineEdit)
+ e->ignore();
+ break;
+ #ifdef QT_KEYPAD_NAVIGATION
+- case Qt::Key_Select:
+- if (QApplicationPrivate::keypadNavigationEnabled()
+- && (!hasEditFocus() || !d->lineEdit)) {
+- showPopup();
+- return;
+- }
+- break;
+ case Qt::Key_Left:
+ case Qt::Key_Right:
+ if (QApplicationPrivate::keypadNavigationEnabled() && !hasEditFocus())
+diff --git a/qtbase/src/widgets/widgets/qdatetimeedit_p.h b/qtbase/src/widgets/widgets/qdatetimeedit_p.h
+index d36b6f8f9a..e0df5b5158 100644
+--- a/qtbase/src/widgets/widgets/qdatetimeedit_p.h
++++ b/qtbase/src/widgets/widgets/qdatetimeedit_p.h
+@@ -1,6 +1,6 @@
+ /****************************************************************************
+ **
+-** Copyright (C) 2018 The Qt Company Ltd.
++** Copyright (C) 2021 The Qt Company Ltd.
+ ** Contact: https://www.qt.io/licensing/
+ **
+ ** This file is part of the QtWidgets module of the Qt Toolkit.
+diff --git a/qtbase/src/widgets/widgets/qgroupbox.cpp b/qtbase/src/widgets/widgets/qgroupbox.cpp
+index 02a0bed325..3f3eccc370 100644
+--- a/qtbase/src/widgets/widgets/qgroupbox.cpp
++++ b/qtbase/src/widgets/widgets/qgroupbox.cpp
+@@ -54,6 +54,8 @@
+ #include "qaccessible.h"
+ #endif
+ #include <private/qwidget_p.h>
++#include <private/qguiapplication_p.h>
++#include <qpa/qplatformtheme.h>
+
+ #include "qdebug.h"
+
+@@ -360,7 +362,10 @@ bool QGroupBox::event(QEvent *e)
+ return true;
+ case QEvent::KeyPress: {
+ QKeyEvent *k = static_cast<QKeyEvent*>(e);
+- if (!k->isAutoRepeat() && (k->key() == Qt::Key_Select || k->key() == Qt::Key_Space)) {
++ const auto buttonPressKeys = QGuiApplicationPrivate::platformTheme()
++ ->themeHint(QPlatformTheme::ButtonPressKeys)
++ .value<QList<Qt::Key>>();
++ if (!k->isAutoRepeat() && buttonPressKeys.contains(static_cast<Qt::Key>(k->key()))) {
+ d->pressedControl = QStyle::SC_GroupBoxCheckBox;
+ update(style()->subControlRect(QStyle::CC_GroupBox, &box, QStyle::SC_GroupBoxCheckBox, this));
+ return true;
+@@ -369,7 +374,10 @@ bool QGroupBox::event(QEvent *e)
+ }
+ case QEvent::KeyRelease: {
+ QKeyEvent *k = static_cast<QKeyEvent*>(e);
+- if (!k->isAutoRepeat() && (k->key() == Qt::Key_Select || k->key() == Qt::Key_Space)) {
++ const auto buttonPressKeys = QGuiApplicationPrivate::platformTheme()
++ ->themeHint(QPlatformTheme::ButtonPressKeys)
++ .value<QList<Qt::Key>>();
++ if (!k->isAutoRepeat() && buttonPressKeys.contains(static_cast<Qt::Key>(k->key()))) {
+ bool toggle = (d->pressedControl == QStyle::SC_GroupBoxLabel
+ || d->pressedControl == QStyle::SC_GroupBoxCheckBox);
+ d->pressedControl = QStyle::SC_None;
+diff --git a/qtbase/src/widgets/widgets/qlabel.cpp b/qtbase/src/widgets/widgets/qlabel.cpp
+index 30ff80cbb0..cf2605c17c 100644
+--- a/qtbase/src/widgets/widgets/qlabel.cpp
++++ b/qtbase/src/widgets/widgets/qlabel.cpp
+@@ -421,9 +421,6 @@ void QLabel::setPixmap(const QPixmap &pixmap)
+ d->pixmap = new QPixmap(pixmap);
+ }
+
+- if (d->pixmap->depth() == 1 && !d->pixmap->mask())
+- d->pixmap->setMask(*((QBitmap *)d->pixmap));
+-
+ d->updateLabel();
+ }
+
+diff --git a/qtbase/src/widgets/widgets/qtoolbararealayout.cpp b/qtbase/src/widgets/widgets/qtoolbararealayout.cpp
+index 493c094cc1..d5f4b59017 100644
+--- a/qtbase/src/widgets/widgets/qtoolbararealayout.cpp
++++ b/qtbase/src/widgets/widgets/qtoolbararealayout.cpp
+@@ -1367,7 +1367,7 @@ bool QToolBarAreaLayout::restoreState(QDataStream &stream, const QList<QToolBar*
+ item.widgetItem = new QWidgetItemV2(toolBar);
+ toolBar->setOrientation(floating ? ((shown & 2) ? Qt::Vertical : Qt::Horizontal) : dock.o);
+ toolBar->setVisible(shown & 1);
+- toolBar->d_func()->setWindowState(floating, true, rect);
++ toolBar->d_func()->setWindowState(floating, false, rect);
+
+ item.preferredSize = item.size;
+ line.toolBarItems.append(item);
+diff --git a/qtbase/tests/auto/concurrent/qtconcurrentiteratekernel/tst_qtconcurrentiteratekernel.cpp b/qtbase/tests/auto/concurrent/qtconcurrentiteratekernel/tst_qtconcurrentiteratekernel.cpp
+index 212c0a2e13..3c77b1ba0b 100644
+--- a/qtbase/tests/auto/concurrent/qtconcurrentiteratekernel/tst_qtconcurrentiteratekernel.cpp
++++ b/qtbase/tests/auto/concurrent/qtconcurrentiteratekernel/tst_qtconcurrentiteratekernel.cpp
+@@ -126,8 +126,7 @@ public:
+
+ void tst_QtConcurrentIterateKernel::instantiate()
+ {
+- auto future = startThreadEngine(new PrintFor(0, 40)).startAsynchronously();
+- future.waitForFinished();
++ startThreadEngine(new PrintFor(0, 40)).startBlocking();
+ QCOMPARE(iterations.loadRelaxed(), 40);
+ }
+
+@@ -166,10 +165,8 @@ void tst_QtConcurrentIterateKernel::stresstest()
+ const int times = 50;
+ for (int i = 0; i < times; ++i) {
+ counter.storeRelaxed(0);
+- // ThreadEngine will delete f when it finishes
+- auto f = new CountFor(0, iterations);
+- auto future = f->startAsynchronously();
+- future.waitForFinished();
++ CountFor f(0, iterations);
++ f.startBlocking();
+ QCOMPARE(counter.loadRelaxed(), iterations);
+ }
+ }
+@@ -177,11 +174,8 @@ void tst_QtConcurrentIterateKernel::stresstest()
+ void tst_QtConcurrentIterateKernel::noIterations()
+ {
+ const int times = 20000;
+- for (int i = 0; i < times; ++i) {
+- auto future = startThreadEngine(new IterateKernel<TestIterator, void>(0, 0))
+- .startAsynchronously();
+- future.waitForFinished();
+- }
++ for (int i = 0; i < times; ++i)
++ startThreadEngine(new IterateKernel<TestIterator, void>(0, 0)).startBlocking();
+ }
+
+ QMutex threadsMutex;
+@@ -236,10 +230,8 @@ void tst_QtConcurrentIterateKernel::throttling()
+
+ threads.clear();
+
+- // ThreadEngine will delete f when it finishes
+- auto f = new ThrottleFor(0, totalIterations);
+- auto future = f->startAsynchronously();
+- future.waitForFinished();
++ ThrottleFor f(0, totalIterations);
++ f.startBlocking();
+
+ QCOMPARE(iterations.loadRelaxed(), totalIterations);
+
+diff --git a/qtbase/tests/auto/concurrent/qtconcurrentthreadengine/tst_qtconcurrentthreadengine.cpp b/qtbase/tests/auto/concurrent/qtconcurrentthreadengine/tst_qtconcurrentthreadengine.cpp
+index ac7be7acdd..81bc64c8d9 100644
+--- a/qtbase/tests/auto/concurrent/qtconcurrentthreadengine/tst_qtconcurrentthreadengine.cpp
++++ b/qtbase/tests/auto/concurrent/qtconcurrentthreadengine/tst_qtconcurrentthreadengine.cpp
+@@ -65,9 +65,16 @@ public:
+
+ void tst_QtConcurrentThreadEngine::runDirectly()
+ {
+- PrintUser *engine = new PrintUser();
+- QFuture<void> f = engine->startAsynchronously();
+- f.waitForFinished();
++ {
++ PrintUser engine;
++ engine.startSingleThreaded();
++ engine.startBlocking();
++ }
++ {
++ PrintUser *engine = new PrintUser();
++ QFuture<void> f = engine->startAsynchronously();
++ f.waitForFinished();
++ }
+ }
+
+ class StringResultUser : public ThreadEngine<QString>
+@@ -99,10 +106,8 @@ public:
+
+ void tst_QtConcurrentThreadEngine::result()
+ {
+- // ThreadEngine will delete 'engine' when it finishes
+- auto engine = new StringResultUser();
+- auto future = engine->startAsynchronously();
+- QCOMPARE(future.result(), QString("Foo"));
++ StringResultUser engine;
++ QCOMPARE(*engine.startBlocking(), QString("Foo"));
+ }
+
+ class VoidResultUser : public ThreadEngine<void>
+@@ -128,9 +133,17 @@ public:
+
+ void tst_QtConcurrentThreadEngine::runThroughStarter()
+ {
+- ThreadEngineStarter<QString> starter = startThreadEngine(new StringResultUser());
+- QFuture<QString> f = starter.startAsynchronously();
+- QCOMPARE(f.result(), QString("Foo"));
++ {
++ ThreadEngineStarter<QString> starter = startThreadEngine(new StringResultUser());
++ QFuture<QString> f = starter.startAsynchronously();
++ QCOMPARE(f.result(), QString("Foo"));
++ }
++
++ {
++ ThreadEngineStarter<QString> starter = startThreadEngine(new StringResultUser());
++ QString str = starter.startBlocking();
++ QCOMPARE(str, QString("Foo"));
++ }
+ }
+
+ class CancelUser : public ThreadEngine<void>
+@@ -213,6 +226,12 @@ void tst_QtConcurrentThreadEngine::throttle()
+ f.waitForFinished();
+ QCOMPARE(count.loadRelaxed(), 0);
+ }
++
++ for (int i = 0; i < repeats; ++i) {
++ ThrottleAlwaysUser t;
++ t.startBlocking();
++ QCOMPARE(count.loadRelaxed(), 0);
++ }
+ }
+
+ QSet<QThread *> threads;
+@@ -249,17 +268,35 @@ void tst_QtConcurrentThreadEngine::threadCount()
+ {
+ const int repeats = 10;
+ for (int i = 0; i < repeats; ++i) {
++ ThreadCountUser t;
++ t.startBlocking();
++ int count = threads.count();
++ int count_expected = QThreadPool::globalInstance()->maxThreadCount() + 1; // +1 for the main thread.
++ if (count != count_expected)
++ QEXPECT_FAIL("", "QTBUG-23333", Abort);
++ QCOMPARE(count, count_expected);
++
+ (new ThreadCountUser())->startAsynchronously().waitForFinished();
+- const auto count = threads.count();
+- const auto maxThreadCount = QThreadPool::globalInstance()->maxThreadCount();
+- QVERIFY(count <= maxThreadCount);
+- QVERIFY(!threads.contains(QThread::currentThread()));
++ count = threads.count();
++ count_expected = QThreadPool::globalInstance()->maxThreadCount();
++ if (count != count_expected)
++ QEXPECT_FAIL("", "QTBUG-23333", Abort);
++ QCOMPARE(count, count_expected);
+ }
+
+ // Set the finish flag immediately, this should give us one thread only.
+ for (int i = 0; i < repeats; ++i) {
++ ThreadCountUser t(true /*finishImmediately*/);
++ t.startBlocking();
++ int count = threads.count();
++ if (count != 1)
++ QEXPECT_FAIL("", "QTBUG-23333", Abort);
++ QCOMPARE(count, 1);
++
+ (new ThreadCountUser(true /*finishImmediately*/))->startAsynchronously().waitForFinished();
+- const auto count = threads.count();
++ count = threads.count();
++ if (count != 1)
++ QEXPECT_FAIL("", "QTBUG-23333", Abort);
+ QCOMPARE(count, 1);
+ QVERIFY(!threads.contains(QThread::currentThread()));
+ }
+@@ -400,6 +437,7 @@ public:
+
+ void tst_QtConcurrentThreadEngine::exceptions()
+ {
++ // Asynchronous mode:
+ {
+ bool caught = false;
+ try {
+@@ -412,6 +450,32 @@ void tst_QtConcurrentThreadEngine::exceptions()
+ QVERIFY2(caught, "did not get exception");
+ }
+
++ // Blocking mode:
++ // test throwing the exception from a worker thread.
++ {
++ bool caught = false;
++ try {
++ QtConcurrentExceptionThrower e(QThread::currentThread());
++ e.startBlocking();
++ } catch (const QException &) {
++ caught = true;
++ }
++ QVERIFY2(caught, "did not get exception");
++ }
++
++ // test throwing the exception from the main thread (different code path)
++ {
++ bool caught = false;
++ try {
++ QtConcurrentExceptionThrower e(0);
++ e.startBlocking();
++ } catch (const QException &) {
++ caught = true;
++ }
++ QVERIFY2(caught, "did not get exception");
++ }
++
++ // Asynchronous mode:
+ {
+ bool caught = false;
+ try {
+@@ -423,6 +487,31 @@ void tst_QtConcurrentThreadEngine::exceptions()
+ }
+ QVERIFY2(caught, "did not get exception");
+ }
++
++ // Blocking mode:
++ // test throwing the exception from a worker thread.
++ {
++ bool caught = false;
++ try {
++ UnrelatedExceptionThrower e(QThread::currentThread());
++ e.startBlocking();
++ } catch (const QUnhandledException &) {
++ caught = true;
++ }
++ QVERIFY2(caught, "did not get exception");
++ }
++
++ // test throwing the exception from the main thread (different code path)
++ {
++ bool caught = false;
++ try {
++ UnrelatedExceptionThrower e(0);
++ e.startBlocking();
++ } catch (const QUnhandledException &) {
++ caught = true;
++ }
++ QVERIFY2(caught, "did not get exception");
++ }
+ }
+
+ #endif
+diff --git a/qtbase/tests/auto/corelib/io/qbuffer/tst_qbuffer.cpp b/qtbase/tests/auto/corelib/io/qbuffer/tst_qbuffer.cpp
+index 4968742110..f4c3fb711d 100644
+--- a/qtbase/tests/auto/corelib/io/qbuffer/tst_qbuffer.cpp
++++ b/qtbase/tests/auto/corelib/io/qbuffer/tst_qbuffer.cpp
+@@ -42,6 +42,7 @@ private slots:
+ void writeBlock_data();
+ void writeBlock();
+ void seek();
++ void invalidSeeks();
+ void seekTest_data();
+ void seekTest();
+ void read_rawdata();
+@@ -286,6 +287,29 @@ void tst_QBuffer::seek()
+ QCOMPARE(buffer.size(), pos);
+ }
+
++void tst_QBuffer::invalidSeeks()
++{
++ if constexpr (sizeof(qsizetype) == sizeof(qint64)) {
++ // sizeof(qsizetype) == sizeof(qint64), so +1 would overflow
++ QSKIP("This is a 32-bit-only test.");
++ } else {
++ QBuffer buffer;
++ buffer.open(QIODevice::WriteOnly);
++ QCOMPARE(buffer.buffer().size(), qsizetype(0));
++ QCOMPARE(buffer.pos(), qint64(0));
++ constexpr qint64 MaxQByteArrayCapacity = (std::numeric_limits<qsizetype>::max)();
++ // this should fail fast, not after trying to allocate nearly 2 GiB of data,
++ // potentially crashing in the process:
++ QVERIFY(!buffer.seek(2 * MaxQByteArrayCapacity - 1));
++ QCOMPARE(buffer.buffer().size(), qsizetype(0));
++ QCOMPARE(buffer.pos(), qint64(0));
++ // ditto:
++ QVERIFY(!buffer.seek(MaxQByteArrayCapacity + 1));
++ QCOMPARE(buffer.buffer().size(), qsizetype(0));
++ QCOMPARE(buffer.pos(), qint64(0));
++ }
++}
++
+ void tst_QBuffer::seekTest_data()
+ {
+ writeBlock_data();
+diff --git a/qtbase/tests/auto/corelib/io/qiodevice/tst_qiodevice.cpp b/qtbase/tests/auto/corelib/io/qiodevice/tst_qiodevice.cpp
+index da5327594c..4a04e0f7c6 100644
+--- a/qtbase/tests/auto/corelib/io/qiodevice/tst_qiodevice.cpp
++++ b/qtbase/tests/auto/corelib/io/qiodevice/tst_qiodevice.cpp
+@@ -561,7 +561,8 @@ protected:
+ qint64 readData(char *data, qint64 maxSize) override
+ {
+ maxSize = qMin(maxSize, qint64(buf->size() - offset));
+- memcpy(data, buf->constData() + offset, maxSize);
++ if (maxSize > 0)
++ memcpy(data, buf->constData() + offset, maxSize);
+ offset += maxSize;
+ return maxSize;
+ }
+@@ -604,13 +605,15 @@ protected:
+ qint64 readData(char *data, qint64 maxSize) override
+ {
+ maxSize = qMin(maxSize, qint64(buf.size() - pos()));
+- memcpy(data, buf.constData() + pos(), maxSize);
++ if (maxSize > 0)
++ memcpy(data, buf.constData() + pos(), maxSize);
+ return maxSize;
+ }
+ qint64 writeData(const char *data, qint64 maxSize) override
+ {
+ maxSize = qMin(maxSize, qint64(buf.size() - pos()));
+- memcpy(buf.data() + pos(), data, maxSize);
++ if (maxSize > 0)
++ memcpy(buf.data() + pos(), data, maxSize);
+ return maxSize;
+ }
+
+diff --git a/qtbase/tests/auto/corelib/io/qprocess/tst_qprocess.cpp b/qtbase/tests/auto/corelib/io/qprocess/tst_qprocess.cpp
+index db60bead64..f345a44414 100644
+--- a/qtbase/tests/auto/corelib/io/qprocess/tst_qprocess.cpp
++++ b/qtbase/tests/auto/corelib/io/qprocess/tst_qprocess.cpp
+@@ -1,7 +1,8 @@
+ /****************************************************************************
+ **
+ ** Copyright (C) 2021 The Qt Company Ltd.
+-** Copyright (C) 2020 Intel Corporation.
++** Copyright (C) 2020 The Qt Company Ltd.
++** Copyright (C) 2022 Intel Corporation.
+ ** Contact: https://www.qt.io/licensing/
+ **
+ ** This file is part of the test suite of the Qt Toolkit.
+@@ -150,6 +151,8 @@ private slots:
+ void startStopStartStopBuffers();
+ void processEventsInAReadyReadSlot_data();
+ void processEventsInAReadyReadSlot();
++ void startFromCurrentWorkingDir_data();
++ void startFromCurrentWorkingDir();
+
+ // keep these at the end, since they use lots of processes and sometimes
+ // caused obscure failures to occur in tests that followed them (esp. on the Mac)
+@@ -2731,5 +2734,94 @@ void tst_QProcess::finishProcessBeforeReadingDone_deprecated()
+
+ #endif
+
++enum class ChdirMode {
++ None = 0,
++ InParent,
++ InChild
++};
++Q_DECLARE_METATYPE(ChdirMode)
++
++void tst_QProcess::startFromCurrentWorkingDir_data()
++{
++ qRegisterMetaType<ChdirMode>();
++ QTest::addColumn<QString>("programPrefix");
++ QTest::addColumn<ChdirMode>("chdirMode");
++ QTest::addColumn<bool>("success");
++
++ constexpr bool IsWindows = true
++#ifdef Q_OS_UNIX
++ && false
++#endif
++ ;
++
++ // baseline: trying to execute the directory, this can't possibly succeed!
++ QTest::newRow("plain-same-cwd") << QString() << ChdirMode::None << false;
++
++ // cross-platform behavior: neither OS searches the setWorkingDirectory()
++ // dir without "./"
++ QTest::newRow("plain-child-chdir") << QString() << ChdirMode::InChild << false;
++
++ // cross-platform behavior: both OSes search the parent's CWD with "./"
++ QTest::newRow("prefixed-parent-chdir") << "./" << ChdirMode::InParent << true;
++
++ // opposite behaviors: Windows searches the parent's CWD and Unix searches
++ // the child's with "./"
++ QTest::newRow("prefixed-child-chdir") << "./" << ChdirMode::InChild << !IsWindows;
++
++ // Windows searches the parent's CWD without "./"
++ QTest::newRow("plain-parent-chdir") << QString() << ChdirMode::InParent << IsWindows;
++}
++
++void tst_QProcess::startFromCurrentWorkingDir()
++{
++ QFETCH(QString, programPrefix);
++ QFETCH(ChdirMode, chdirMode);
++ QFETCH(bool, success);
++
++ QProcess process;
++ qRegisterMetaType<QProcess::ProcessError>();
++ QSignalSpy errorSpy(&process, &QProcess::errorOccurred);
++ QVERIFY(errorSpy.isValid());
++
++ // both the dir name and the executable name
++ const QString target = QStringLiteral("testProcessNormal");
++ process.setProgram(programPrefix + target);
++
++#ifdef Q_OS_UNIX
++ // Reset PATH, to be sure it doesn't contain . or the empty path.
++ // We can't do this on Windows because DLLs are searched in PATH
++ // and Windows always searches "." anyway.
++ auto restoreEnv = qScopeGuard([old = qgetenv("PATH")] {
++ qputenv("PATH", old);
++ });
++ qputenv("PATH", "/");
++#endif
++
++ switch (chdirMode) {
++ case ChdirMode::InParent: {
++ auto restoreCwd = qScopeGuard([old = QDir::currentPath()] {
++ QDir::setCurrent(old);
++ });
++ QVERIFY(QDir::setCurrent(target));
++ process.start();
++ break;
++ }
++ case ChdirMode::InChild:
++ process.setWorkingDirectory(target);
++ Q_FALLTHROUGH();
++ case ChdirMode::None:
++ process.start();
++ break;
++ }
++
++ QCOMPARE(process.waitForStarted(), success);
++ QCOMPARE(errorSpy.count(), int(!success));
++ if (success) {
++ QVERIFY(process.waitForFinished());
++ } else {
++ QCOMPARE(process.error(), QProcess::FailedToStart);
++ }
++}
++
+ QTEST_MAIN(tst_QProcess)
+ #include "tst_qprocess.moc"
+diff --git a/qtbase/tests/auto/corelib/itemmodels/qconcatenatetablesproxymodel/tst_qconcatenatetablesproxymodel.cpp b/qtbase/tests/auto/corelib/itemmodels/qconcatenatetablesproxymodel/tst_qconcatenatetablesproxymodel.cpp
+index e1ea7a4552..90972caa57 100644
+--- a/qtbase/tests/auto/corelib/itemmodels/qconcatenatetablesproxymodel/tst_qconcatenatetablesproxymodel.cpp
++++ b/qtbase/tests/auto/corelib/itemmodels/qconcatenatetablesproxymodel/tst_qconcatenatetablesproxymodel.cpp
+@@ -117,6 +117,7 @@ private Q_SLOTS:
+ void shouldPropagateDropAfterLastRow_data();
+ void shouldPropagateDropAfterLastRow();
+ void qtbug91788();
++ void qtbug91878();
+
+ private:
+ QStandardItemModel mod;
+@@ -843,6 +844,22 @@ void tst_QConcatenateTablesProxyModel::qtbug91788()
+ QCOMPARE(proxyConcat.columnCount(), 0);
+ }
+
++void tst_QConcatenateTablesProxyModel::qtbug91878()
++{
++ QStandardItemModel m;
++ m.setRowCount(4);
++ m.setColumnCount(4);
++
++ QConcatenateTablesProxyModel pm;
++ QSortFilterProxyModel proxyFilter;
++ proxyFilter.setSourceModel(&pm);
++ proxyFilter.setFilterFixedString("something");
++ pm.addSourceModel(&m); // This should not assert
++
++ QCOMPARE(pm.columnCount(), 4);
++ QCOMPARE(pm.rowCount(), 4);
++}
++
+ QTEST_GUILESS_MAIN(tst_QConcatenateTablesProxyModel)
+
+ #include "tst_qconcatenatetablesproxymodel.moc"
+diff --git a/qtbase/tests/auto/corelib/kernel/qobject/tst_qobject.cpp b/qtbase/tests/auto/corelib/kernel/qobject/tst_qobject.cpp
+index 9bd66c0835..ed4a0bae5d 100644
+--- a/qtbase/tests/auto/corelib/kernel/qobject/tst_qobject.cpp
++++ b/qtbase/tests/auto/corelib/kernel/qobject/tst_qobject.cpp
+@@ -158,6 +158,7 @@ private slots:
+ void nullReceiver();
+ void functorReferencesConnection();
+ void disconnectDisconnects();
++ void declarativeData();
+ };
+
+ struct QObjectCreatedOnShutdown
+@@ -7679,5 +7680,81 @@ void tst_QObject::disconnectDisconnects()
+ Q_STATIC_ASSERT(QtPrivate::HasQ_OBJECT_Macro<tst_QObject>::Value);
+ Q_STATIC_ASSERT(!QtPrivate::HasQ_OBJECT_Macro<SiblingDeleter>::Value);
+
++#ifdef QT_BUILD_INTERNAL
++/*
++ Since QObjectPrivate stores the declarativeData pointer in a union with the pointer
++ to the currently destroyed child, calls to the QtDeclarative handlers need to be
++ correctly guarded. QTBUG-105286
++*/
++namespace QtDeclarative {
++static QAbstractDeclarativeData *theData;
++
++static void destroyed(QAbstractDeclarativeData *data, QObject *)
++{
++ QCOMPARE(data, theData);
++}
++static void signalEmitted(QAbstractDeclarativeData *data, QObject *, int, void **)
++{
++ QCOMPARE(data, theData);
++}
++// we can't use QCOMPARE in the next two functions, as they don't return void
++static int receivers(QAbstractDeclarativeData *data, const QObject *, int)
++{
++ QTest::qCompare(data, theData, "data", "theData", __FILE__, __LINE__);
++ return 0;
++}
++static bool isSignalConnected(QAbstractDeclarativeData *data, const QObject *, int)
++{
++ QTest::qCompare(data, theData, "data", "theData", __FILE__, __LINE__);
++ return true;
++}
++
++class Object : public QObject
++{
++ Q_OBJECT
++public:
++ using QObject::QObject;
++ ~Object()
++ {
++ if (Object *p = static_cast<Object *>(parent()))
++ p->emitSignal();
++ }
++
++ void emitSignal()
++ {
++ emit theSignal();
++ }
++
++signals:
++ void theSignal();
++};
++
++}
++#endif
++
++void tst_QObject::declarativeData()
++{
++#ifdef QT_BUILD_INTERNAL
++ QScopedValueRollback destroyed(QAbstractDeclarativeData::destroyed,
++ QtDeclarative::destroyed);
++ QScopedValueRollback signalEmitted(QAbstractDeclarativeData::signalEmitted,
++ QtDeclarative::signalEmitted);
++ QScopedValueRollback receivers(QAbstractDeclarativeData::receivers,
++ QtDeclarative::receivers);
++ QScopedValueRollback isSignalConnected(QAbstractDeclarativeData::isSignalConnected,
++ QtDeclarative::isSignalConnected);
++
++ QtDeclarative::Object p;
++ QObjectPrivate *priv = QObjectPrivate::get(&p);
++ priv->declarativeData = QtDeclarative::theData = new QAbstractDeclarativeData;
++
++ connect(&p, &QtDeclarative::Object::theSignal, &p, []{
++ });
++
++ QtDeclarative::Object *child = new QtDeclarative::Object;
++ child->setParent(&p);
++#endif
++}
++
+ QTEST_MAIN(tst_QObject)
+ #include "tst_qobject.moc"
+diff --git a/qtbase/tests/auto/corelib/mimetypes/qmimedatabase/tst_qmimedatabase.cpp b/qtbase/tests/auto/corelib/mimetypes/qmimedatabase/tst_qmimedatabase.cpp
+index 0ea422ecbc..1a3256534b 100644
+--- a/qtbase/tests/auto/corelib/mimetypes/qmimedatabase/tst_qmimedatabase.cpp
++++ b/qtbase/tests/auto/corelib/mimetypes/qmimedatabase/tst_qmimedatabase.cpp
+@@ -70,15 +70,15 @@ static inline QString testSuiteWarning()
+
+ QString result;
+ QTextStream str(&result);
+- str << "\nCannot find the shared-mime-info test suite\nstarting from: "
++ str << "\nCannot find the shared-mime-info test suite\nin the parent of: "
+ << QDir::toNativeSeparators(QDir::currentPath()) << "\n"
+ "cd " << QDir::toNativeSeparators(QStringLiteral("tests/auto/corelib/mimetypes/qmimedatabase")) << "\n"
+- "wget http://cgit.freedesktop.org/xdg/shared-mime-info/snapshot/Release-1-10.zip\n"
+- "unzip Release-1-10.zip\n";
++ "wget https://gitlab.freedesktop.org/xdg/shared-mime-info/-/archive/2.1/shared-mime-info-2.1.zip\n"
++ "unzip shared-mime-info-2.1.zip\n";
+ #ifdef Q_OS_WIN
+- str << "mkdir testfiles\nxcopy /s Release-1-10 s-m-i\n";
++ str << "mkdir testfiles\nxcopy /s shared-mime-info-2.1 s-m-i\n";
+ #else
+- str << "ln -s Release-1-10 s-m-i\n";
++ str << "ln -s shared-mime-info-2.1 s-m-i\n";
+ #endif
+ return result;
+ }
+@@ -154,7 +154,7 @@ void tst_QMimeDatabase::initTestCase()
+ QVERIFY2(copyResourceFile(xmlFileName, xmlTargetFileName, &errorMessage), qPrintable(errorMessage));
+ #endif
+
+- m_testSuite = QFINDTESTDATA("s-m-i/tests");
++ m_testSuite = QFINDTESTDATA("s-m-i/tests/mime-detection");
+ if (m_testSuite.isEmpty())
+ qWarning("%s", qPrintable(testSuiteWarning()));
+
+@@ -611,7 +611,7 @@ void tst_QMimeDatabase::allMimeTypes()
+ QVERIFY(!lst.isEmpty());
+
+ // Hardcoding this is the only way to check both providers find the same number of mimetypes.
+- QCOMPARE(lst.count(), 779);
++ QCOMPARE(lst.count(), 811);
+
+ foreach (const QMimeType &mime, lst) {
+ const QString name = mime.name();
+@@ -631,10 +631,9 @@ void tst_QMimeDatabase::suffixes_data()
+
+ QTest::newRow("mimetype with a single pattern") << "application/pdf" << "*.pdf" << "pdf";
+ QTest::newRow("mimetype with multiple patterns") << "application/x-kpresenter" << "*.kpr;*.kpt" << "kpr";
+- QTest::newRow("jpeg") << "image/jpeg" << "*.jpe;*.jpg;*.jpeg" << "jpeg";
+- //if (KMimeType::sharedMimeInfoVersion() > KDE_MAKE_VERSION(0, 60, 0)) {
+- QTest::newRow("mimetype with many patterns") << "application/vnd.wordperfect" << "*.wp;*.wp4;*.wp5;*.wp6;*.wpd;*.wpp" << "wp";
+- //}
++ // The preferred suffix for image/jpeg is *.jpg, as per https://bugs.kde.org/show_bug.cgi?id=176737
++ QTest::newRow("jpeg") << "image/jpeg" << "*.jpe;*.jpg;*.jpeg" << "jpg";
++ QTest::newRow("mimetype with many patterns") << "application/vnd.wordperfect" << "*.wp;*.wp4;*.wp5;*.wp6;*.wpd;*.wpp" << "wp";
+ QTest::newRow("oasis text mimetype") << "application/vnd.oasis.opendocument.text" << "*.odt" << "odt";
+ QTest::newRow("oasis presentation mimetype") << "application/vnd.oasis.opendocument.presentation" << "*.odp" << "odp";
+ QTest::newRow("mimetype with multiple patterns") << "text/plain" << "*.asc;*.txt;*,v" << "txt";
+diff --git a/qtbase/tests/auto/corelib/serialization/json/tst_qtjson.cpp b/qtbase/tests/auto/corelib/serialization/json/tst_qtjson.cpp
+index 3e58dd03cc..c8f82ef5d5 100644
+--- a/qtbase/tests/auto/corelib/serialization/json/tst_qtjson.cpp
++++ b/qtbase/tests/auto/corelib/serialization/json/tst_qtjson.cpp
+@@ -176,6 +176,8 @@ private Q_SLOTS:
+ void fromToVariantConversions_data();
+ void fromToVariantConversions();
+
++ void noLeakOnNameClash();
++
+ private:
+ QString testDataDir;
+ };
+@@ -3685,5 +3687,23 @@ void tst_QtJson::fromToVariantConversions()
+ }
+ }
+
++void tst_QtJson::noLeakOnNameClash()
++{
++ QJsonDocument doc = QJsonDocument::fromJson("{\"\":{\"\":0},\"\":0}");
++ QVERIFY(!doc.isNull());
++ const QJsonObject obj = doc.object();
++
++ // Removed the duplicate key.
++ QCOMPARE(obj.length(), 1);
++
++ // Retained the last of the duplicates.
++ const QJsonValue val = obj.begin().value();
++ QVERIFY(val.isDouble());
++ QCOMPARE(val.toDouble(), 0.0);
++
++ // It should not leak.
++ // In particular it should not forget to deref the container for the inner object.
++}
++
+ QTEST_MAIN(tst_QtJson)
+ #include "tst_qtjson.moc"
+diff --git a/qtbase/tests/auto/corelib/time/qtimezone/tst_qtimezone.cpp b/qtbase/tests/auto/corelib/time/qtimezone/tst_qtimezone.cpp
+index a59b58d57f..241c3e84ac 100644
+--- a/qtbase/tests/auto/corelib/time/qtimezone/tst_qtimezone.cpp
++++ b/qtbase/tests/auto/corelib/time/qtimezone/tst_qtimezone.cpp
+@@ -63,6 +63,7 @@ private slots:
+ void isValidId_data();
+ void isValidId();
+ void malformed();
++ void serialize();
+ // Backend tests
+ void utcTest();
+ void icuTest();
+@@ -947,6 +948,33 @@ void tst_QTimeZone::malformed()
+ barf.offsetFromUtc(now);
+ }
+
++void tst_QTimeZone::serialize()
++{
++ int parts = 0;
++#ifndef QT_NO_DEBUG_STREAM
++ qDebug() << QTimeZone(); // to verify no crash
++ parts++;
++#endif
++#ifndef QT_NO_DATASTREAM
++ QByteArray blob;
++ {
++ QDataStream stream(&blob, QIODevice::WriteOnly);
++ stream << QTimeZone("Europe/Oslo") << QTimeZone(420) << QTimeZone() << qint64(-1);
++ }
++ QDataStream stream(&blob, QIODevice::ReadOnly);
++ QTimeZone invalid, offset, oslo;
++ qint64 minusone;
++ stream >> oslo >> offset >> invalid >> minusone;
++ QCOMPARE(oslo, QTimeZone("Europe/Oslo"));
++ QCOMPARE(offset, QTimeZone(420));
++ QVERIFY(!invalid.isValid());
++ QCOMPARE(minusone, qint64(-1));
++ parts++;
++#endif
++ if (!parts)
++ QSKIP("No serialization enabled");
++}
++
+ void tst_QTimeZone::utcTest()
+ {
+ #ifdef QT_BUILD_INTERNAL
+diff --git a/qtbase/tests/auto/dbus/qdbusinterface/tst_qdbusinterface.cpp b/qtbase/tests/auto/dbus/qdbusinterface/tst_qdbusinterface.cpp
+index 05480c6dd2..70f4c75756 100644
+--- a/qtbase/tests/auto/dbus/qdbusinterface/tst_qdbusinterface.cpp
++++ b/qtbase/tests/auto/dbus/qdbusinterface/tst_qdbusinterface.cpp
+@@ -324,6 +324,13 @@ void tst_QDBusInterface::notValid()
+
+ QVERIFY(!interface.isValid());
+ QVERIFY(!QMetaObject::invokeMethod(&interface, "ListNames", Qt::DirectConnection));
++
++ // With a connection, but empty/null service and path specified
++ QDBusConnection con = QDBusConnection::sessionBus();
++ QVERIFY(con.isConnected());
++ QDBusInterface iface({}, {}, {}, con);
++ QVERIFY(!iface.isValid());
++ QVERIFY(!QMetaObject::invokeMethod(&interface, "ListNames", Qt::DirectConnection));
+ }
+
+ void tst_QDBusInterface::notValidDerived()
+diff --git a/qtbase/tests/auto/gui/kernel/qkeysequence/tst_qkeysequence.cpp b/qtbase/tests/auto/gui/kernel/qkeysequence/tst_qkeysequence.cpp
+index 874468c954..04ceb4ab65 100644
+--- a/qtbase/tests/auto/gui/kernel/qkeysequence/tst_qkeysequence.cpp
++++ b/qtbase/tests/auto/gui/kernel/qkeysequence/tst_qkeysequence.cpp
+@@ -507,6 +507,10 @@ void tst_QKeySequence::toStringFromKeycode_data()
+ QTest::newRow("Ctrl+Alt+Num+Del") << QKeySequence(Qt::ControlModifier | Qt::AltModifier | Qt::KeypadModifier | Qt::Key_Delete) << "Ctrl+Alt+Num+Del";
+ QTest::newRow("Ctrl+Ins") << QKeySequence(Qt::ControlModifier | Qt::Key_Insert) << "Ctrl+Ins";
+ QTest::newRow("Ctrl+Num+Ins(1)") << QKeySequence(Qt::Key_Insert | Qt::KeypadModifier | Qt::ControlModifier) << "Ctrl+Num+Ins";
++ QTest::newRow("Ctrl") << QKeySequence(Qt::Key_Control) << "Control";
++ QTest::newRow("Alt") << QKeySequence(Qt::Key_Alt) << "Alt";
++ QTest::newRow("Shift") << QKeySequence(Qt::Key_Shift) << "Shift";
++ QTest::newRow("Meta") << QKeySequence(Qt::Key_Meta) << "Meta";
+ }
+
+ void tst_QKeySequence::toStringFromKeycode()
+diff --git a/qtbase/tests/auto/gui/text/qfontdatabase/tst_qfontdatabase.cpp b/qtbase/tests/auto/gui/text/qfontdatabase/tst_qfontdatabase.cpp
+index 15e0ecadaa..b4eca74283 100644
+--- a/qtbase/tests/auto/gui/text/qfontdatabase/tst_qfontdatabase.cpp
++++ b/qtbase/tests/auto/gui/text/qfontdatabase/tst_qfontdatabase.cpp
+@@ -81,6 +81,8 @@ private slots:
+ void registerOpenTypePreferredNamesSystem();
+ void registerOpenTypePreferredNamesApplication();
+
++ void stretchRespected();
++
+ private:
+ QString m_ledFont;
+ QString m_testFont;
+@@ -355,6 +357,28 @@ static QString testString()
+ return QStringLiteral("foo bar");
+ }
+
++void tst_QFontDatabase::stretchRespected()
++{
++ int italicId = QFontDatabase::addApplicationFont(m_testFontItalic);
++ QVERIFY(italicId != -1);
++
++ QVERIFY(!QFontDatabase::applicationFontFamilies(italicId).isEmpty());
++
++ QString italicFontName = QFontDatabase::applicationFontFamilies(italicId).first();
++
++ QFont italicFont = QFontDatabase().font(italicFontName,
++ QString::fromLatin1("Italic"), 14);
++ QVERIFY(italicFont.italic());
++
++ QFont italicStretchedFont = italicFont;
++ italicStretchedFont.setStretch( 400 );
++
++ QVERIFY(QFontMetricsF(italicFont).horizontalAdvance(QStringLiteral("foobar")) <
++ QFontMetricsF(italicStretchedFont).horizontalAdvance(QStringLiteral("foobar")));
++
++ QFontDatabase::removeApplicationFont(italicId);
++}
++
+ void tst_QFontDatabase::condensedFontWidthNoFontMerging()
+ {
+ int regularFontId = QFontDatabase::addApplicationFont(m_testFont);
+diff --git a/qtbase/tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp b/qtbase/tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp
+index 3d4a094c43..b423e11a99 100644
+--- a/qtbase/tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp
++++ b/qtbase/tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp
+@@ -281,6 +281,7 @@ private Q_SLOTS:
+ void ioGetFromFileSpecial();
+ void ioGetFromFile_data();
+ void ioGetFromFile();
++ void ioGetFromFileUrl();
+ void ioGetFromFtp_data();
+ void ioGetFromFtp();
+ void ioGetFromFtpWithReuse();
+@@ -3300,6 +3301,18 @@ void tst_QNetworkReply::ioGetFromFile()
+ QCOMPARE(reader.data, data);
+ }
+
++void tst_QNetworkReply::ioGetFromFileUrl()
++{
++ // This immediately fails on non-windows platforms:
++ QNetworkRequest request(QUrl("file://unc-server/some/path"));
++ QNetworkReplyPtr reply(manager.get(request));
++ QSignalSpy finishedSpy(reply.get(), &QNetworkReply::finished);
++ // QTBUG-105618: This would, on non-Windows platforms, never happen because the signal
++ // was emitted before the constructor finished, leaving no chance at all to connect to the
++ // signal
++ QVERIFY(finishedSpy.wait());
++}
++
+ void tst_QNetworkReply::ioGetFromFtp_data()
+ {
+ QTest::addColumn<QString>("fileName");
+diff --git a/qtbase/tests/auto/network/ssl/qsslsocket/certs/fluke.cert b/qtbase/tests/auto/network/ssl/qsslsocket/certs/fluke.cert
+index 069fa6b341..4cc4d9a5ea 100644
+--- a/qtbase/tests/auto/network/ssl/qsslsocket/certs/fluke.cert
++++ b/qtbase/tests/auto/network/ssl/qsslsocket/certs/fluke.cert
+@@ -1,75 +1,34 @@
+-Certificate:
+- Data:
+- Version: 3 (0x2)
+- Serial Number: 0 (0x0)
+- Signature Algorithm: sha1WithRSAEncryption
+- Issuer: C=NO, ST=Oslo, L=Nydalen, O=Nokia Corporation and/or its subsidiary(-ies), OU=Development, CN=fluke.troll.no/emailAddress=ahanssen@trolltech.com
+- Validity
+- Not Before: Dec 4 01:10:32 2007 GMT
+- Not After : Apr 21 01:10:32 2035 GMT
+- Subject: C=NO, ST=Oslo, O=Nokia Corporation and/or its subsidiary(-ies), OU=Development, CN=fluke.troll.no
+- Subject Public Key Info:
+- Public Key Algorithm: rsaEncryption
+- RSA Public Key: (1024 bit)
+- Modulus (1024 bit):
+- 00:a7:c8:a0:4a:c4:19:05:1b:66:ba:32:e2:d2:f1:
+- 1c:6f:17:82:e4:39:2e:01:51:90:db:04:34:32:11:
+- 21:c2:0d:6f:59:d8:53:90:54:3f:83:8f:a9:d3:b3:
+- d5:ee:1a:9b:80:ae:c3:25:c9:5e:a5:af:4b:60:05:
+- aa:a0:d1:91:01:1f:ca:04:83:e3:58:1c:99:32:45:
+- 84:70:72:58:03:98:4a:63:8b:41:f5:08:49:d2:91:
+- 02:60:6b:e4:64:fe:dd:a0:aa:74:08:e9:34:4c:91:
+- 5f:12:3d:37:4d:54:2c:ad:7f:5b:98:60:36:02:8c:
+- 3b:f6:45:f3:27:6a:9b:94:9d
+- Exponent: 65537 (0x10001)
+- X509v3 extensions:
+- X509v3 Basic Constraints:
+- CA:FALSE
+- Netscape Comment:
+- OpenSSL Generated Certificate
+- X509v3 Subject Key Identifier:
+- 21:85:04:3D:23:01:66:E5:F7:9F:1A:84:24:8A:AF:0A:79:F4:E5:AC
+- X509v3 Authority Key Identifier:
+- DirName:/C=NO/ST=Oslo/L=Nydalen/O=Nokia Corporation and/or its subsidiary(-ies)/OU=Development/CN=fluke.troll.no/emailAddress=ahanssen@trolltech.com
+- serial:8E:A8:B4:E8:91:B7:54:2E
+-
+- Signature Algorithm: sha1WithRSAEncryption
+- 6d:57:5f:d1:05:43:f0:62:05:ec:2a:71:a5:dc:19:08:f2:c4:
+- a6:bd:bb:25:d9:ca:89:01:0e:e4:cf:1f:c1:8c:c8:24:18:35:
+- 53:59:7b:c0:43:b4:32:e6:98:b2:a6:ef:15:05:0b:48:5f:e1:
+- a0:0c:97:a9:a1:77:d8:35:18:30:bc:a9:8f:d3:b7:54:c7:f1:
+- a9:9e:5d:e6:19:bf:f6:3c:5b:2b:d8:e4:3e:62:18:88:8b:d3:
+- 24:e1:40:9b:0c:e6:29:16:62:ab:ea:05:24:70:36:aa:55:93:
+- ef:02:81:1b:23:10:a2:04:eb:56:95:75:fc:f8:94:b1:5d:42:
+- c5:3f:36:44:85:5d:3a:2e:90:46:8a:a2:b9:6f:87:ae:0c:15:
+- 40:19:31:90:fc:3b:25:bb:ae:f1:66:13:0d:85:90:d9:49:34:
+- 8f:f2:5d:f9:7a:db:4d:5d:27:f6:76:9d:35:8c:06:a6:4c:a3:
+- b1:b2:b6:6f:1d:d7:a3:00:fd:72:eb:9e:ea:44:a1:af:21:34:
+- 7d:c7:42:e2:49:91:19:8b:c0:ad:ba:82:80:a8:71:70:f4:35:
+- 31:91:63:84:20:95:e9:60:af:64:8b:cc:ff:3d:8a:76:74:3d:
+- c8:55:6d:e4:8e:c3:2b:1c:e8:42:18:ae:9f:e6:6b:9c:34:06:
+- ec:6a:f2:c3
+ -----BEGIN CERTIFICATE-----
+-MIIEEzCCAvugAwIBAgIBADANBgkqhkiG9w0BAQUFADCBnDELMAkGA1UEBhMCTk8x
+-DTALBgNVBAgTBE9zbG8xEDAOBgNVBAcTB055ZGFsZW4xFjAUBgNVBAoTDVRyb2xs
+-dGVjaCBBU0ExFDASBgNVBAsTC0RldmVsb3BtZW50MRcwFQYDVQQDEw5mbHVrZS50
+-cm9sbC5ubzElMCMGCSqGSIb3DQEJARYWYWhhbnNzZW5AdHJvbGx0ZWNoLmNvbTAe
+-Fw0wNzEyMDQwMTEwMzJaFw0zNTA0MjEwMTEwMzJaMGMxCzAJBgNVBAYTAk5PMQ0w
+-CwYDVQQIEwRPc2xvMRYwFAYDVQQKEw1Ucm9sbHRlY2ggQVNBMRQwEgYDVQQLEwtE
+-ZXZlbG9wbWVudDEXMBUGA1UEAxMOZmx1a2UudHJvbGwubm8wgZ8wDQYJKoZIhvcN
+-AQEBBQADgY0AMIGJAoGBAKfIoErEGQUbZroy4tLxHG8XguQ5LgFRkNsENDIRIcIN
+-b1nYU5BUP4OPqdOz1e4am4CuwyXJXqWvS2AFqqDRkQEfygSD41gcmTJFhHByWAOY
+-SmOLQfUISdKRAmBr5GT+3aCqdAjpNEyRXxI9N01ULK1/W5hgNgKMO/ZF8ydqm5Sd
+-AgMBAAGjggEaMIIBFjAJBgNVHRMEAjAAMCwGCWCGSAGG+EIBDQQfFh1PcGVuU1NM
+-IEdlbmVyYXRlZCBDZXJ0aWZpY2F0ZTAdBgNVHQ4EFgQUIYUEPSMBZuX3nxqEJIqv
+-Cnn05awwgbsGA1UdIwSBszCBsKGBoqSBnzCBnDELMAkGA1UEBhMCTk8xDTALBgNV
+-BAgTBE9zbG8xEDAOBgNVBAcTB055ZGFsZW4xFjAUBgNVBAoTDVRyb2xsdGVjaCBB
+-U0ExFDASBgNVBAsTC0RldmVsb3BtZW50MRcwFQYDVQQDEw5mbHVrZS50cm9sbC5u
+-bzElMCMGCSqGSIb3DQEJARYWYWhhbnNzZW5AdHJvbGx0ZWNoLmNvbYIJAI6otOiR
+-t1QuMA0GCSqGSIb3DQEBBQUAA4IBAQBtV1/RBUPwYgXsKnGl3BkI8sSmvbsl2cqJ
+-AQ7kzx/BjMgkGDVTWXvAQ7Qy5piypu8VBQtIX+GgDJepoXfYNRgwvKmP07dUx/Gp
+-nl3mGb/2PFsr2OQ+YhiIi9Mk4UCbDOYpFmKr6gUkcDaqVZPvAoEbIxCiBOtWlXX8
+-+JSxXULFPzZEhV06LpBGiqK5b4euDBVAGTGQ/Dslu67xZhMNhZDZSTSP8l35ettN
+-XSf2dp01jAamTKOxsrZvHdejAP1y657qRKGvITR9x0LiSZEZi8CtuoKAqHFw9DUx
+-kWOEIJXpYK9ki8z/PYp2dD3IVW3kjsMrHOhCGK6f5mucNAbsavLD
++MIIF6zCCA9OgAwIBAgIUfo9amJtJGWqWE6f+SkAO85zkGr4wDQYJKoZIhvcNAQEL
++BQAwgYMxCzAJBgNVBAYTAk5PMQ0wCwYDVQQIDARPc2xvMQ0wCwYDVQQHDARPc2xv
++MRcwFQYDVQQKDA5UaGUgUXQgQ29tcGFueTEMMAoGA1UECwwDUiZEMRIwEAYDVQQD
++DAlIMiBUZXN0ZXIxGzAZBgkqhkiG9w0BCQEWDG1pbmltaUBxdC5pbzAgFw0yMDEw
++MjYxMjAxMzFaGA8yMTIwMTAwMjEyMDEzMVowgYMxCzAJBgNVBAYTAk5PMQ0wCwYD
++VQQIDARPc2xvMQ0wCwYDVQQHDARPc2xvMRcwFQYDVQQKDA5UaGUgUXQgQ29tcGFu
++eTEMMAoGA1UECwwDUiZEMRIwEAYDVQQDDAlIMiBUZXN0ZXIxGzAZBgkqhkiG9w0B
++CQEWDG1pbmltaUBxdC5pbzCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIB
++AOiUp5+E4blouKH7q+rVNR8NoYX2XkBW+q+rpy1zu5ssRSzbqxAjDx9dkht7Qlnf
++VlDT00JvpOWdeuPon5915edQRsY4Unl6mKH29ra3OtUa1/yCJXsGVJTKCj7k4Bxb
++5mZzb/fTlZntMLdTIBMfUbw62FKir1WjKIcJ9fCoG8JaGeKVO4Rh5p0ezd4UUUId
++r1BXl5Nqdqy2vTMsEDnjOsD3egkv8I2SKN4O6n/C3wWYpMOWYZkGoZiKz7rJs/i/
++ez7bsV7JlwdzTlhpJzkcOSVFBP6JlEOxTNNxZ1wtKy7PtZGmsSSATq2e6+bw38Ae
++Op0XnzzqcGjtDDofBmT7OFzZWjS9VZS6+DOOe2QHWle1nCHcHyH4ku6IRlsr9xkR
++NAIlOfnvHHxqJUenoeaZ4oQDjCBKS1KXygJO/tL7BLTQVn/xK1EmPvKNnjzWk4tR
++PnibUhhs5635qpOU/YPqFBh1JjVruZbsWcDAhRcew0uxONXOa9E+4lttQ9ySYa1A
++LvWqJuAX7gu2BsBMLyqfm811YnA7CIFMyO+HlqmkLFfv5L/xIRAXR7l26YGO0VwX
++CGjMfz4NVPMMke4nB7qa9NkpXQBQKMms3Qzd5JW0Hy9Ruj5O8GPcFZmV0twjd1uJ
++PD/cAjkWLaXjdNsJ16QWc2nghQRS6HYqKRX6j+CXOxupAgMBAAGjUzBRMB0GA1Ud
++DgQWBBRSCOU58j9NJZkMamt623qyCrhN3TAfBgNVHSMEGDAWgBRSCOU58j9NJZkM
++amt623qyCrhN3TAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEBCwUAA4ICAQCq
++q4jxsWeNDv5Nq14hJtF9HB+ZL64zcZtRjJP1YgNs0QppKICmjPOL2nIMGmI/jKrs
++0eGAL/9XXNVHPxm1OPOncvimMMmU6emZfpMdEtTfKP43+Pg9HgKRjLoQp406vGeQ
++8ki/mbBhrItVPgEm3tu2AFA02XTYi+YxCI9kRZLGkM3FbgtOuTLPl0Z9y+kiPc9F
++uCSC03anBEqv+vDSI8+wODymQ/IJ3Jyz1lxIRDfp4qAekmy0jU2c91VOHHEmOmqq
++kqygGFRdwbe99m9yP63r6q0b5K3X2UnJ6bns0hmTwThYwpVPXLU8jdaTddbMukN2
++/Ef96Tsw8nWOEOPMySHOTIPgwyZRp26b0kA9EmhLwOP401SxXVQCmSRmtwNagmtg
++jJKmZoYBN+//D45ibK8z6Q0oOm9P+Whf/uUXehcRxBxyV3xz7k0wKGQbHj/ddwcy
++IUoIN4lrAlib+lK170kTKN352PDmrpo2gmIzPEsfurKAIMSelDl6H+kih16BtZ8y
++Nz6fh9Soqrg3OSAware8pxV7k51crBMoPLN78KoRV8MFCK4K7Fddq4rRISq6hiXq
++r1nsjoEPuKM9huprmZVZe9t5YcDa2I+wb3IiE3uwpZbAdaLDyQ5n6F/qpsiIkZXn
++gtcF7oqpG5oYrwCcZ53y/ezUgUg7PlSz2XwAGvQtgg==
+ -----END CERTIFICATE-----
+diff --git a/qtbase/tests/auto/network/ssl/qsslsocket/certs/fluke.key b/qtbase/tests/auto/network/ssl/qsslsocket/certs/fluke.key
+index 9d1664d609..337ce541a6 100644
+--- a/qtbase/tests/auto/network/ssl/qsslsocket/certs/fluke.key
++++ b/qtbase/tests/auto/network/ssl/qsslsocket/certs/fluke.key
+@@ -1,15 +1,52 @@
+------BEGIN RSA PRIVATE KEY-----
+-MIICXAIBAAKBgQCnyKBKxBkFG2a6MuLS8RxvF4LkOS4BUZDbBDQyESHCDW9Z2FOQ
+-VD+Dj6nTs9XuGpuArsMlyV6lr0tgBaqg0ZEBH8oEg+NYHJkyRYRwclgDmEpji0H1
+-CEnSkQJga+Rk/t2gqnQI6TRMkV8SPTdNVCytf1uYYDYCjDv2RfMnapuUnQIDAQAB
+-AoGANFzLkanTeSGNFM0uttBipFT9F4a00dqHz6JnO7zXAT26I5r8sU1pqQBb6uLz
+-/+Qz5Zwk8RUAQcsMRgJetuPQUb0JZjF6Duv24hNazqXBCu7AZzUenjafwmKC/8ri
+-KpX3fTwqzfzi//FKGgbXQ80yykSSliDL3kn/drATxsLCgQECQQDXhEFWLJ0vVZ1s
+-1Ekf+3NITE+DR16X+LQ4W6vyEHAjTbaNWtcTKdAWLA2l6N4WAAPYSi6awm+zMxx4
+-VomVTsjdAkEAx0z+e7natLeFcrrq8pbU+wa6SAP1VfhQWKitxL1e7u/QO90NCpxE
+-oQYKzMkmmpOOFjQwEMAy1dvFMbm4LHlewQJAC/ksDBaUcQHHqjktCtrUb8rVjAyW
+-A8lscckeB2fEYyG5J6dJVaY4ClNOOs5yMDS2Afk1F6H/xKvtQ/5CzInA/QJATDub
+-K+BPU8jO9q+gpuIi3VIZdupssVGmCgObVCHLakG4uO04y9IyPhV9lA9tALtoIf4c
+-VIvv5fWGXBrZ48kZAQJBAJmVCdzQxd9LZI5vxijUCj5EI4e+x5DRqVUvyP8KCZrC
+-AiNyoDP85T+hBZaSXK3aYGpVwelyj3bvo1GrTNwNWLw=
+------END RSA PRIVATE KEY-----
++-----BEGIN PRIVATE KEY-----
++MIIJQgIBADANBgkqhkiG9w0BAQEFAASCCSwwggkoAgEAAoICAQDolKefhOG5aLih
+++6vq1TUfDaGF9l5AVvqvq6ctc7ubLEUs26sQIw8fXZIbe0JZ31ZQ09NCb6TlnXrj
++6J+fdeXnUEbGOFJ5epih9va2tzrVGtf8giV7BlSUygo+5OAcW+Zmc2/305WZ7TC3
++UyATH1G8OthSoq9VoyiHCfXwqBvCWhnilTuEYeadHs3eFFFCHa9QV5eTanastr0z
++LBA54zrA93oJL/CNkijeDup/wt8FmKTDlmGZBqGYis+6ybP4v3s+27FeyZcHc05Y
++aSc5HDklRQT+iZRDsUzTcWdcLSsuz7WRprEkgE6tnuvm8N/AHjqdF5886nBo7Qw6
++HwZk+zhc2Vo0vVWUuvgzjntkB1pXtZwh3B8h+JLuiEZbK/cZETQCJTn57xx8aiVH
++p6HmmeKEA4wgSktSl8oCTv7S+wS00FZ/8StRJj7yjZ481pOLUT54m1IYbOet+aqT
++lP2D6hQYdSY1a7mW7FnAwIUXHsNLsTjVzmvRPuJbbUPckmGtQC71qibgF+4LtgbA
++TC8qn5vNdWJwOwiBTMjvh5appCxX7+S/8SEQF0e5dumBjtFcFwhozH8+DVTzDJHu
++Jwe6mvTZKV0AUCjJrN0M3eSVtB8vUbo+TvBj3BWZldLcI3dbiTw/3AI5Fi2l43Tb
++CdekFnNp4IUEUuh2KikV+o/glzsbqQIDAQABAoICAFw1q6tr5I48vY7DF+rXsuLn
++5ZUWE1IQ6fzB4lr72nJv/9EEGnMgYzt9PpMUsD6vdCpBgS2C0+6RHArFzJtNA+RM
++iHLIG7K7702veyr/xBx/MwiSlMeMv/XpkFxVI6E6skMGG2s3AMXxKvJTy5CpRx+I
++eQFyLG+Ya1X2lgJes/q+/CpAHkOjCOpcLySQC5NZ74q734V7nSdmn+Zs3tYEh+O/
++eiuwTP/j5b38Te5vVTqDxTciJPmljmXLCwa0N100lWlbcpvw8qbqiTI2Jm3XCbUE
++AzHjW9vmrF3cRS1fXxKFGShw3SRqlkbxjfeWoi8qDPUBS4m8LOr8qG9Wo5Nfon0z
++zLP4bci3zHDvVcaaZrrsUBs/yZbg+Dgka1DmX7ekmeccr2yTdKDFgPupYUyxVbTl
++a9ZLJysjFD7rgBv1ZclHonLp6Vbm+ZoTqvteo4ikAy6L9RtBWJ23XEK34PkP/+c5
++2vWZaOrnjSeBHbFce8cdJSxqWpP+eSCI5I9XbDrYFIsQ/gqKgtzDKy2ihJ2Y8STL
++yO4hyFPFjxc+Gg4/P2PpmT5CY2ty44M0BWs+JGW96CJPrrplf2lmQUQJj5LZY66X
++Z/4C9L7ZYtKZ+bs5SvU46yWugAvQZX22Xm9xLXWyVXRdx3bj+3M3fDnF9di/zdbh
++CgLx7oWPNrXc7FCajnn9AoIBAQD5FMYwRpw9NWT9WDxQwx+cSI4Icbd88ByTW63S
++LzeRwZA0J9/SfwO+aBRupzc9GkGXCiZcGMw3AGsCtig8yFlw8E5KnzN7KlftDMnM
++9NUxxzlR8VwKyLnZfG7sDTl057ZlUujnqhmt/F8F7dIy7FVO1dE/8nngA+FYTCOG
++UZdGjwyBDlDM0JJdUWGY3xslutcpCDN5mzSTKjy9drMvImAshRawxRF6WBpn7vr2
++nC6vciqfx1Mzx1vyk0Jm0ilaydDdLMADjt/iL4Nkr0BEs4k+UzQiKDwp8gu7abQ1
++eBfxd9Iar4htQa2I1Ewl6P01G/q+ZYwgHhJ9RVn4AxQXefILAoIBAQDvCouORdQX
++C8wsyp7MwXlF/3NQeNN5/+B2mhbxrBOf7PmMCXLnkRWcjwJtzypWFqJ0sqai/2+0
++bqbMcjX5maT8stT2shl3zXe/Ejt2e3TBYpc1tyuses8Kb5BMU8hu6tTd3G2CMXpD
++dT6DVemJZCTtwj9aBNIxSizvlgMolJnCpzhPnlfHSI6E+g3m/LTTo3HwbjMSw/Uq
++irgjOpI2wSBB6LZPSgjvfcYPRyWUk16L4A5uSX0cADnovDFLa5/h0wJvN/OoCSQg
++rLCXG5E18EyL5Wc58BCY1ZvxmjG3lQtgPxYu2Jwc36R/y/JKlxW5suER5ZNpbbD4
++uOyTt2VxMQ2bAoIBAQC5+MzRFqdo/AjfL5Y5JrbfVTzXCTDa09xCGd16ZU60QTWN
+++4ed/r+o1sUKqUcRFB2MzEM/2DQBjQpZB/CbEWvWa1XJWXxypXbowveZU+QqOnmN
++uQvj8WLyA3o+PNF9e9QvauwCrHpn8VpxbtPWuaYoKnUFreFZZQxHhPGxRBIS2JOZ
++eDrT8ZaWnkCkh1AZp5smQ71LOprSlmKrg4jd1GjCVMxQR5N5KXbtyv0OTCZ/UFqK
++2aRBsMPyJgkaBChkZPLRcKwc+/wlQRx1fHQb14DNTApMxoXFO7eOwqmOkpAt9iyl
++SBIwoS0UUI5ab88+bBmXNvKcuFdNuQ4nowTJUn9pAoIBADMNkILBXSvS5DeIyuO2
++Sp1tkoZUV+5NfPY3sMDK3KIibaW/+t+EOBZo4L7tKQCb8vRzl21mmsfxfgRaPDbj
++3r3tv9g0b4YLxxBy52pFscj/soXRai17SS7UZwA2QK+XzgDYbDcLNC6mIsTQG4Gx
++dsWk3/zs3KuUSQaehmwrWK+fIUK38c1pLK8v7LoxrLkqxlHwZ04RthHw8KTthH7X
++Pnl1J0LF8CSeOyfWLSuPUfkT0GEzptnNHpEbaHfQM6R6eaGhVJPF6AZme4y6YYgg
++m2ihhSt1n0XVEWpHYWjxFy3mK2mz75unFC4LM+NEY2p2zuUQoCw7NjnY3QYrfCnx
++rRMCggEAXeXsMSLFjjyuoL7iKbAxo52HD/P0fBoy58LyRcwfNVr0lvYan4pYEx+o
++KijIh9K16PqXZXKMA9v003B+ulmF8bJ7SddCZ5NGvnFhUTDe4DdTKgp2RuwQ3Bsc
++3skPIDbhVETyOLCtys34USHrq8U/0DlGY3eLRfxw9GnbKxSBGa/KEu/qQLPNUo50
++7xHZDg7GKeC3kqNJeqKM9rkp0VzIGkEnaD9127LeNDmERDfftxJzFoC/THvUBLfU
++6Sus2ZYwRE8VFvKC30Q45t/c54X3IuhYvAuiCuTmyfE4ruyzyOwKzhUkeeLq1APX
++g0veFbyfzlJ0q8qzD/iffqqIa2ZSmQ==
++-----END PRIVATE KEY-----
+diff --git a/qtbase/tests/auto/other/qaccessibilitylinux/tst_qaccessibilitylinux.cpp b/qtbase/tests/auto/other/qaccessibilitylinux/tst_qaccessibilitylinux.cpp
+index 7ba3715e13..752aa122f6 100644
+--- a/qtbase/tests/auto/other/qaccessibilitylinux/tst_qaccessibilitylinux.cpp
++++ b/qtbase/tests/auto/other/qaccessibilitylinux/tst_qaccessibilitylinux.cpp
+@@ -179,6 +179,7 @@ void tst_QAccessibilityLinux::initTestCase()
+ QVERIFY(!address.isEmpty());
+
+ m_window = new AccessibleTestWindow();
++ m_window->setObjectName("mainWindow"_L1);
+ m_window->show();
+
+ QVERIFY(QTest::qWaitForWindowExposed(m_window));
+@@ -236,8 +237,11 @@ bool hasState(QDBusInterface *interface, AtspiStateType state)
+ void tst_QAccessibilityLinux::testLabel()
+ {
+ QLabel *l = new QLabel(m_window);
++ l->setObjectName("theObjectName"_L1);
+ l->setText("Hello A11y");
+ m_window->addWidget(l);
++ auto a11yEmpty = new QLabel(m_window);
++ m_window->addWidget(l);
+
+ // Application
+ QCOMPARE(getParent(mainWindow), QLatin1String(ATSPI_DBUS_PATH_ROOT));
+@@ -249,6 +253,8 @@ void tst_QAccessibilityLinux::testLabel()
+ QCOMPARE(getChildren(labelInterface).count(), 0);
+ QCOMPARE(labelInterface->call(QDBus::Block, "GetRoleName").arguments().first().toString(), QLatin1String("label"));
+ QCOMPARE(labelInterface->call(QDBus::Block, "GetRole").arguments().first().toUInt(), 29u);
++ QCOMPARE(labelInterface->call(QDBus::Block, "GetAccessibleId").arguments().first().toString(),
++ QLatin1String("mainWindow.theObjectName"));
+ QCOMPARE(getParent(labelInterface), mainWindow->path());
+ QVERIFY(!hasState(labelInterface, ATSPI_STATE_EDITABLE));
+ QVERIFY(hasState(labelInterface, ATSPI_STATE_READ_ONLY));
+@@ -256,7 +262,12 @@ void tst_QAccessibilityLinux::testLabel()
+ l->setText("New text");
+ QCOMPARE(labelInterface->property("Name").toString(), l->text());
+
++ auto *a11yEmptyInterface = getInterface(children.at(1), "org.a11y.atspi.Accessible");
++ QCOMPARE(a11yEmptyInterface->call(QDBus::Block, "GetAccessibleId").arguments().first().toString(),
++ QLatin1String("mainWindow.QLabel"));
++
+ m_window->clearChildren();
++ delete a11yEmptyInterface;
+ delete labelInterface;
+ }
+
+diff --git a/qtbase/tests/auto/sql/kernel/qsqlquery/tst_qsqlquery.cpp b/qtbase/tests/auto/sql/kernel/qsqlquery/tst_qsqlquery.cpp
+index 76df61c892..6d6d65b791 100644
+--- a/qtbase/tests/auto/sql/kernel/qsqlquery/tst_qsqlquery.cpp
++++ b/qtbase/tests/auto/sql/kernel/qsqlquery/tst_qsqlquery.cpp
+@@ -1,6 +1,6 @@
+ /****************************************************************************
+ **
+-** Copyright (C) 2016 The Qt Company Ltd.
++** Copyright (C) 2022 The Qt Company Ltd.
+ ** Contact: https://www.qt.io/licensing/
+ **
+ ** This file is part of the test suite of the Qt Toolkit.
+@@ -68,6 +68,8 @@ private slots:
+ void query_exec();
+ void execErrorRecovery_data() { generic_data(); }
+ void execErrorRecovery();
++ void prematureExec_data() { generic_data(); }
++ void prematureExec();
+ void first_data() { generic_data(); }
+ void first();
+ void next_data() { generic_data(); }
+@@ -2770,6 +2772,35 @@ void tst_QSqlQuery::execErrorRecovery()
+ QVERIFY_SQL( q, exec() );
+ }
+
++void tst_QSqlQuery::prematureExec()
++{
++ QFETCH(QString, dbName);
++ // We only want the engine name, for addDatabase():
++ int cut = dbName.indexOf(QChar('@'));
++ if (cut < 0)
++ QSKIP("Failed to parse database type out of name");
++ dbName.truncate(cut);
++ cut = dbName.indexOf(QChar('_'));
++ if (cut >= 0)
++ dbName = dbName.mid(cut + 1);
++
++ auto db = QSqlDatabase::addDatabase(dbName);
++ QSqlQuery q(db);
++
++ QTest::ignoreMessage(QtWarningMsg,
++ "QSqlDatabasePrivate::removeDatabase: connection "
++ "'qt_sql_default_connection' is still in use, all "
++ "queries will cease to work.");
++ QTest::ignoreMessage(QtWarningMsg,
++ "QSqlDatabasePrivate::addDatabase: duplicate connection name "
++ "'qt_sql_default_connection', old connection removed.");
++ auto otherDb = QSqlDatabase::addDatabase(dbName);
++
++ QTest::ignoreMessage(QtWarningMsg, "QSqlQuery::exec: called before driver has been set up");
++ // QTBUG-100037: shouldn't crash !
++ QVERIFY(!q.exec("select stuff from TheVoid"));
++}
++
+ void tst_QSqlQuery::lastInsertId()
+ {
+ QFETCH( QString, dbName );
+diff --git a/qtbase/tests/auto/testlib/qabstractitemmodeltester/tst_qabstractitemmodeltester.cpp b/qtbase/tests/auto/testlib/qabstractitemmodeltester/tst_qabstractitemmodeltester.cpp
+index 4aa3f8d60b..d2050a61aa 100644
+--- a/qtbase/tests/auto/testlib/qabstractitemmodeltester/tst_qabstractitemmodeltester.cpp
++++ b/qtbase/tests/auto/testlib/qabstractitemmodeltester/tst_qabstractitemmodeltester.cpp
+@@ -115,6 +115,10 @@ void tst_QAbstractItemModelTester::standardItemModelZeroColumns()
+ // QTBUG-92886
+ model.insertRows(0, 5);
+ model.removeRows(1, 2);
++
++ const QModelIndex parentIndex = model.index(0, 0);
++ model.insertRows(0, 5, parentIndex);
++ model.removeRows(1, 2, parentIndex);
+ }
+
+ void tst_QAbstractItemModelTester::testInsertThroughProxy()
+diff --git a/qtbase/tests/auto/tools/moc/allmocs_baseline_in.json b/qtbase/tests/auto/tools/moc/allmocs_baseline_in.json
+index 12a4a22a19..ce518e78fb 100644
+--- a/qtbase/tests/auto/tools/moc/allmocs_baseline_in.json
++++ b/qtbase/tests/auto/tools/moc/allmocs_baseline_in.json
+@@ -668,50 +668,6 @@
+ "inputFile": "task192552.h",
+ "outputRevision": 67
+ },
+- {
+- "classes": [
+- {
+- "className": "InlineSlotsWithThrowDeclaration",
+- "object": true,
+- "qualifiedClassName": "InlineSlotsWithThrowDeclaration",
+- "slots": [
+- {
+- "access": "public",
+- "name": "a",
+- "returnType": "void"
+- },
+- {
+- "access": "public",
+- "name": "b",
+- "returnType": "void"
+- },
+- {
+- "access": "public",
+- "name": "c",
+- "returnType": "void"
+- },
+- {
+- "access": "public",
+- "name": "d",
+- "returnType": "void"
+- },
+- {
+- "access": "public",
+- "name": "e",
+- "returnType": "void"
+- }
+- ],
+- "superClasses": [
+- {
+- "access": "public",
+- "name": "QObject"
+- }
+- ]
+- }
+- ],
+- "inputFile": "task189996.h",
+- "outputRevision": 67
+- },
+ {
+ "classes": [
+ {
+diff --git a/qtbase/tests/auto/tools/moc/moc.pro b/qtbase/tests/auto/tools/moc/moc.pro
+index c324b3a8cd..4aceb78dc0 100644
+--- a/qtbase/tests/auto/tools/moc/moc.pro
++++ b/qtbase/tests/auto/tools/moc/moc.pro
+@@ -15,7 +15,7 @@ cross_compile: DEFINES += MOC_CROSS_COMPILED
+ HEADERS += using-namespaces.h no-keywords.h task87883.h c-comments.h backslash-newlines.h oldstyle-casts.h \
+ slots-with-void-template.h qinvokable.h namespaced-flags.h trigraphs.h \
+ escapes-in-string-literals.h cstyle-enums.h qprivateslots.h gadgetwithnoenums.h \
+- dir-in-include-path.h single_function_keyword.h task192552.h task189996.h \
++ dir-in-include-path.h single_function_keyword.h task192552.h \
+ task234909.h task240368.h pure-virtual-signals.h cxx11-enums.h \
+ cxx11-final-classes.h \
+ cxx11-explicit-override-control.h \
+diff --git a/qtbase/tests/auto/tools/moc/task189996.h b/qtbase/tests/auto/tools/moc/task189996.h
+deleted file mode 100644
+index f94a051b3a..0000000000
+--- a/qtbase/tests/auto/tools/moc/task189996.h
++++ /dev/null
+@@ -1,47 +0,0 @@
+-/****************************************************************************
+-**
+-** Copyright (C) 2016 The Qt Company Ltd.
+-** Contact: https://www.qt.io/licensing/
+-**
+-** This file is part of the test suite of the Qt Toolkit.
+-**
+-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+-** Commercial License Usage
+-** Licensees holding valid commercial Qt licenses may use this file in
+-** accordance with the commercial license agreement provided with the
+-** Software or, alternatively, in accordance with the terms contained in
+-** a written agreement between you and The Qt Company. For licensing terms
+-** and conditions see https://www.qt.io/terms-conditions. For further
+-** information use the contact form at https://www.qt.io/contact-us.
+-**
+-** GNU General Public License Usage
+-** Alternatively, this file may be used under the terms of the GNU
+-** General Public License version 3 as published by the Free Software
+-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+-** included in the packaging of this file. Please review the following
+-** information to ensure the GNU General Public License requirements will
+-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+-**
+-** $QT_END_LICENSE$
+-**
+-****************************************************************************/
+-// inline functions can have throw declarations
+-
+-#ifndef TASK189996_H
+-#define TASK189996_H
+-
+-#include <QObject>
+-
+-class InlineSlotsWithThrowDeclaration : public QObject
+-{
+- Q_OBJECT
+-
+-public slots:
+- void a() throw() { }
+- void b() const throw() { }
+- void c() throw();
+- void d() throw(int) { }
+- void e() const throw(int,double) { }
+-};
+-
+-#endif
+diff --git a/qtbase/tests/auto/tools/moc/tst_moc.cpp b/qtbase/tests/auto/tools/moc/tst_moc.cpp
+index c716aead21..15dd9e41e5 100644
+--- a/qtbase/tests/auto/tools/moc/tst_moc.cpp
++++ b/qtbase/tests/auto/tools/moc/tst_moc.cpp
+@@ -631,7 +631,6 @@ public:
+ private slots:
+ void initTestCase();
+
+- void slotWithException() throw(MyStruct);
+ void dontStripNamespaces();
+ void oldStyleCasts();
+ void warnOnExtraSignalSlotQualifiaction();
+@@ -673,7 +672,6 @@ private slots:
+ void templateGtGt();
+ void qprivateslots();
+ void qprivateproperties();
+- void inlineSlotsWithThrowDeclaration();
+ void warnOnPropertyWithoutREAD();
+ void constructors();
+ void typenameWithUnsigned();
+@@ -784,12 +782,6 @@ void tst_Moc::initTestCase()
+ #endif
+ }
+
+-void tst_Moc::slotWithException() throw(MyStruct)
+-{
+- // be happy
+- QVERIFY(true);
+-}
+-
+ void tst_Moc::dontStripNamespaces()
+ {
+ Sender sender;
+@@ -824,7 +816,7 @@ void tst_Moc::oldStyleCasts()
+
+ QStringList args;
+ args << "-c" << "-x" << "c++" << "-Wold-style-cast" << "-I" << "."
+- << "-I" << qtIncludePath << "-o" << "/dev/null" << "-fPIC" << "-std=c++11" << "-";
++ << "-I" << qtIncludePath << "-o" << "/dev/null" << "-fPIC" << "-std=c++1z" << "-";
+ proc.start("gcc", args);
+ QVERIFY(proc.waitForStarted());
+ proc.write(mocOut);
+@@ -894,7 +886,7 @@ void tst_Moc::inputFileNameWithDotsButNoExtension()
+
+ QStringList args;
+ args << "-c" << "-x" << "c++" << "-I" << ".."
+- << "-I" << qtIncludePath << "-o" << "/dev/null" << "-fPIC" << "-std=c++11" << "-";
++ << "-I" << qtIncludePath << "-o" << "/dev/null" << "-fPIC" << "-std=c++1z" << "-";
+ proc.start("gcc", args);
+ QVERIFY(proc.waitForStarted());
+ proc.write(mocOut);
+@@ -1174,7 +1166,7 @@ void tst_Moc::ignoreOptionClashes()
+ QStringList gccArgs;
+ gccArgs << "-c" << "-x" << "c++" << "-I" << ".."
+ << "-I" << qtIncludePath << "-I" << includeDir << "-o" << "/dev/null"
+- << "-fPIC" << "-std=c++11" << "-";
++ << "-fPIC" << "-std=c++1z" << "-";
+ proc.start("gcc", gccArgs);
+ QVERIFY(proc.waitForStarted());
+ proc.write(mocOut);
+@@ -1593,21 +1585,6 @@ void tst_Moc::qprivateproperties()
+
+ }
+
+-#include "task189996.h"
+-
+-void InlineSlotsWithThrowDeclaration::c() throw() {}
+-
+-void tst_Moc::inlineSlotsWithThrowDeclaration()
+-{
+- InlineSlotsWithThrowDeclaration tst;
+- const QMetaObject *mobj = tst.metaObject();
+- QVERIFY(mobj->indexOfSlot("a()") != -1);
+- QVERIFY(mobj->indexOfSlot("b()") != -1);
+- QVERIFY(mobj->indexOfSlot("c()") != -1);
+- QVERIFY(mobj->indexOfSlot("d()") != -1);
+- QVERIFY(mobj->indexOfSlot("e()") != -1);
+-}
+-
+ void tst_Moc::warnOnPropertyWithoutREAD()
+ {
+ #ifdef MOC_CROSS_COMPILED
+@@ -1869,7 +1846,7 @@ void tst_Moc::notifyError()
+
+ QStringList args;
+ args << "-c" << "-x" << "c++" << "-I" << "."
+- << "-I" << qtIncludePath << "-o" << "/dev/null" << "-fPIC" << "-std=c++11" << "-";
++ << "-I" << qtIncludePath << "-o" << "/dev/null" << "-fPIC" << "-std=c++1z" << "-";
+ proc.start("gcc", args);
+ QVERIFY(proc.waitForStarted());
+ proc.write(mocOut);
+diff --git a/qtbase/tests/auto/widgets/itemviews/qheaderview/tst_qheaderview.cpp b/qtbase/tests/auto/widgets/itemviews/qheaderview/tst_qheaderview.cpp
+index c355ee9665..88c09de8e0 100644
+--- a/qtbase/tests/auto/widgets/itemviews/qheaderview/tst_qheaderview.cpp
++++ b/qtbase/tests/auto/widgets/itemviews/qheaderview/tst_qheaderview.cpp
+@@ -251,6 +251,7 @@ private slots:
+ void testResetCachedSizeHint();
+ void statusTips();
+ void testRemovingColumnsViaLayoutChanged();
++ void testModelMovingColumns();
+
+ protected:
+ void setupTestData(bool use_reset_model = false);
+@@ -360,6 +361,12 @@ public:
+ endRemoveColumns();
+ }
+
++ void moveColumn(int from, int to)
++ {
++ beginMoveColumns(QModelIndex(), from, from, QModelIndex(), to);
++ endMoveColumns();
++ }
++
+ void cleanup()
+ {
+ emit layoutAboutToBeChanged();
+@@ -3627,5 +3634,18 @@ void tst_QHeaderView::testRemovingColumnsViaLayoutChanged()
+ // The main point of this test is that the section-size restoring code didn't go out of bounds.
+ }
+
++void tst_QHeaderView::testModelMovingColumns()
++{
++ QtTestModel model(10, 10);
++ QHeaderView hv(Qt::Horizontal);
++ hv.setModel(&model);
++ hv.resizeSections(QHeaderView::ResizeToContents);
++ hv.show();
++
++ QPersistentModelIndex index3 = model.index(0, 3);
++ model.moveColumn(3, 1);
++ QCOMPARE(index3.column(), 1);
++}
++
+ QTEST_MAIN(tst_QHeaderView)
+ #include "tst_qheaderview.moc"
+diff --git a/qtbase/tests/auto/widgets/itemviews/qtableview/tst_qtableview.cpp b/qtbase/tests/auto/widgets/itemviews/qtableview/tst_qtableview.cpp
+index 761357b252..06bb706074 100644
+--- a/qtbase/tests/auto/widgets/itemviews/qtableview/tst_qtableview.cpp
++++ b/qtbase/tests/auto/widgets/itemviews/qtableview/tst_qtableview.cpp
+@@ -397,6 +397,7 @@ private slots:
+ void checkHeaderMinSize();
+
+ void resizeToContents();
++ void resizeToContentsSpans();
+
+ void tabFocus();
+ void bigModel();
+@@ -3721,6 +3722,70 @@ void tst_QTableView::resizeToContents()
+
+ }
+
++
++class SpanModel : public QAbstractTableModel
++{
++public:
++ SpanModel(bool sectionsMoved)
++ : _sectionsMoved(sectionsMoved)
++ {}
++ int columnCount(const QModelIndex & = {}) const override { return 2; }
++ int rowCount(const QModelIndex & = {}) const override { return 1; }
++ QVariant data(const QModelIndex &idx, int role = Qt::DisplayRole) const override
++ {
++ if (role != Qt::DisplayRole)
++ return QVariant();
++ const int col = _sectionsMoved ? 1 - idx.column() : idx.column();
++ if (col == 0)
++ return "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.";
++ return QVariant();
++ }
++private:
++ bool _sectionsMoved;
++};
++
++
++void tst_QTableView::resizeToContentsSpans()
++{
++ SpanModel model1(false);
++ SpanModel model2(true);
++ QTableView view1, view2, view3;
++ view1.setModel(&model1);
++ view2.setModel(&model2);
++ view2.horizontalHeader()->moveSection(0, 1);
++ view3.setModel(&model1);
++
++ view1.setSpan(0, 0, 1, 2);
++ view2.setSpan(0, 1, 1, 2);
++ view1.show();
++ view2.show();
++ view3.show();
++ QVERIFY(QTest::qWaitForWindowExposed(&view1));
++ QVERIFY(QTest::qWaitForWindowExposed(&view2));
++ QVERIFY(QTest::qWaitForWindowExposed(&view3));
++ view1.setColumnWidth(0, 100);
++ view1.setColumnWidth(1, 100);
++ view2.setColumnWidth(0, 100);
++ view2.setColumnWidth(1, 100);
++ view3.setColumnWidth(0, 200);
++
++ view1.resizeRowToContents(0);
++ view2.resizeRowToContents(0);
++ view3.resizeRowToContents(0);
++ QCOMPARE(view1.rowHeight(0), view3.rowHeight(0));
++ QCOMPARE(view2.rowHeight(0), view3.rowHeight(0));
++
++ view3.resizeColumnToContents(0);
++ view3.resizeRowToContents(0);
++ // height should be only 1 text line for easy testing
++ view1.setRowHeight(0, view3.verticalHeader()->sectionSize(0));
++ view2.setRowHeight(0, view3.verticalHeader()->sectionSize(0));
++ view1.resizeColumnToContents(0);
++ view2.resizeColumnToContents(1);
++ QCOMPARE(view1.columnWidth(0), view3.columnWidth(0) - view1.columnWidth(1));
++ QCOMPARE(view2.columnWidth(0), view3.columnWidth(0) - view2.columnWidth(1));
++}
++
+ QT_BEGIN_NAMESPACE
+ extern bool Q_WIDGETS_EXPORT qt_tab_all_widgets(); // qapplication.cpp
+ QT_END_NAMESPACE
+diff --git a/qtbase/tests/auto/widgets/kernel/qapplication/tst_qapplication.cpp b/qtbase/tests/auto/widgets/kernel/qapplication/tst_qapplication.cpp
+index a3b8ef78d8..4955cebd5d 100644
+--- a/qtbase/tests/auto/widgets/kernel/qapplication/tst_qapplication.cpp
++++ b/qtbase/tests/auto/widgets/kernel/qapplication/tst_qapplication.cpp
+@@ -1498,7 +1498,7 @@ void tst_QApplication::desktopSettingsAware()
+ environment += QLatin1String("QT_MAC_DISABLE_FOREGROUND_APPLICATION_TRANSFORM=1");
+ testProcess.setEnvironment(environment);
+ #endif
+- testProcess.start("desktopsettingsaware_helper");
++ testProcess.start("./desktopsettingsaware_helper");
+ QVERIFY2(testProcess.waitForStarted(),
+ qPrintable(QString::fromLatin1("Cannot start 'desktopsettingsaware_helper': %1").arg(testProcess.errorString())));
+ QVERIFY(testProcess.waitForFinished(10000));
+@@ -2452,7 +2452,7 @@ void tst_QApplication::qtbug_12673()
+ #if QT_CONFIG(process)
+ QProcess testProcess;
+ QStringList arguments;
+- testProcess.start("modal_helper", arguments);
++ testProcess.start("./modal_helper", arguments);
+ QVERIFY2(testProcess.waitForStarted(),
+ qPrintable(QString::fromLatin1("Cannot start 'modal_helper': %1").arg(testProcess.errorString())));
+ QVERIFY(testProcess.waitForFinished(20000));
+diff --git a/qtbase/tests/auto/widgets/widgets/qabstractbutton/tst_qabstractbutton.cpp b/qtbase/tests/auto/widgets/widgets/qabstractbutton/tst_qabstractbutton.cpp
+index eb108a40de..dca5528c1b 100644
+--- a/qtbase/tests/auto/widgets/widgets/qabstractbutton/tst_qabstractbutton.cpp
++++ b/qtbase/tests/auto/widgets/widgets/qabstractbutton/tst_qabstractbutton.cpp
+@@ -41,6 +41,7 @@
+
+ #include <private/qguiapplication_p.h>
+ #include <qpa/qplatformintegration.h>
++#include <qpa/qplatformtheme.h>
+
+ class tst_QAbstractButton : public QObject
+ {
+@@ -76,6 +77,8 @@ private slots:
+ void keyNavigation();
+ #endif
+
++ void buttonPressKeys();
++
+ protected slots:
+ void onClicked();
+ void onToggled( bool on );
+@@ -269,7 +272,13 @@ void tst_QAbstractButton::setAutoRepeat()
+ QCOMPARE(press_count, click_count);
+ QVERIFY(click_count > 1);
+ break;
+- case 4:
++ case 4: {
++ const auto buttonPressKeys = QGuiApplicationPrivate::platformTheme()
++ ->themeHint(QPlatformTheme::ButtonPressKeys)
++ .value<QList<Qt::Key>>();
++ if (buttonPressKeys.contains(Qt::Key_Enter)) {
++ QSKIP("platform theme has Key_Enter in ButtonPressKeys");
++ }
+ // check that pressing ENTER has no effect when autorepeat is false
+ testWidget->setDown( false );
+ testWidget->setAutoRepeat( false );
+@@ -286,7 +295,14 @@ void tst_QAbstractButton::setAutoRepeat()
+
+ QVERIFY( click_count == 0 );
+ break;
+- case 5:
++ }
++ case 5: {
++ const auto buttonPressKeys = QGuiApplicationPrivate::platformTheme()
++ ->themeHint(QPlatformTheme::ButtonPressKeys)
++ .value<QList<Qt::Key>>();
++ if (buttonPressKeys.contains(Qt::Key_Enter)) {
++ QSKIP("platform theme has Key_Enter in ButtonPressKeys");
++ }
+ // check that pressing ENTER has no effect when autorepeat is true
+ testWidget->setDown( false );
+ testWidget->setAutoRepeat( true );
+@@ -304,6 +320,7 @@ void tst_QAbstractButton::setAutoRepeat()
+
+ QVERIFY( click_count == 0 );
+ break;
++ }
+ case 6:
+ // verify autorepeat is off by default.
+ MyButton tmp( 0);
+@@ -651,5 +668,16 @@ void tst_QAbstractButton::keyNavigation()
+ }
+ #endif
+
++void tst_QAbstractButton::buttonPressKeys()
++{
++ const auto buttonPressKeys = QGuiApplicationPrivate::platformTheme()
++ ->themeHint(QPlatformTheme::ButtonPressKeys)
++ .value<QList<Qt::Key>>();
++ for (int i = 0; i < buttonPressKeys.length(); ++i) {
++ QTest::keyClick(testWidget, buttonPressKeys[i]);
++ QCOMPARE(click_count, i + 1);
++ }
++}
++
+ QTEST_MAIN(tst_QAbstractButton)
+ #include "tst_qabstractbutton.moc"
+diff --git a/qtbase/tests/auto/widgets/widgets/qcombobox/tst_qcombobox.cpp b/qtbase/tests/auto/widgets/widgets/qcombobox/tst_qcombobox.cpp
+index 32437050f5..46b5af6d63 100644
+--- a/qtbase/tests/auto/widgets/widgets/qcombobox/tst_qcombobox.cpp
++++ b/qtbase/tests/auto/widgets/widgets/qcombobox/tst_qcombobox.cpp
+@@ -168,6 +168,7 @@ private slots:
+ void checkMenuItemPosWhenStyleSheetIsSet();
+ void checkEmbeddedLineEditWhenStyleSheetIsSet();
+ void propagateStyleChanges();
++ void buttonPressKeys();
+
+ private:
+ PlatformInputContext m_platformInputContext;
+@@ -1682,6 +1683,16 @@ void tst_QComboBox::setModel()
+ QCOMPARE(box.rootModelIndex(), rootModelIndex);
+ box.setModel(box.model());
+ QCOMPARE(box.rootModelIndex(), rootModelIndex);
++
++ // check that setting the same model as the completer's doesn't crash
++ QCompleter *completer = new QCompleter(&box);
++ box.setEditable(true);
++ box.setCompleter(completer);
++ auto *listModel = new QStringListModel({ "one", "two" }, completer);
++ completer->setModel(listModel);
++ QCOMPARE(listModel->rowCount(), 2); // make sure it wasn't deleted
++ box.setModel(listModel);
++ QCOMPARE(listModel->rowCount(), 2); // make sure it wasn't deleted
+ }
+
+ void tst_QComboBox::setCustomModelAndView()
+@@ -3632,5 +3643,24 @@ void tst_QComboBox::propagateStyleChanges()
+ QVERIFY(frameStyle.inquired);
+ }
+
++void tst_QComboBox::buttonPressKeys()
++{
++ QComboBox comboBox;
++ comboBox.setEditable(false);
++ comboBox.addItem(QString::number(1));
++ comboBox.addItem(QString::number(2));
++ const auto buttonPressKeys = QGuiApplicationPrivate::platformTheme()
++ ->themeHint(QPlatformTheme::ButtonPressKeys)
++ .value<QList<Qt::Key>>();
++ for (int i = 0; i < buttonPressKeys.length(); ++i) {
++ QTest::keyClick(&comboBox, buttonPressKeys[i]);
++ // On some platforms, a window will not be immediately visible,
++ // but take some event-loop iterations to complete.
++ // Using QTRY_VERIFY to deal with that.
++ QTRY_VERIFY(comboBox.view()->isVisible());
++ comboBox.hidePopup();
++ }
++}
++
+ QTEST_MAIN(tst_QComboBox)
+ #include "tst_qcombobox.moc"
+diff --git a/qtbase/tests/auto/widgets/widgets/qcommandlinkbutton/qcommandlinkbutton.pro b/qtbase/tests/auto/widgets/widgets/qcommandlinkbutton/qcommandlinkbutton.pro
+index be3cfcd104..c228fdfcca 100644
+--- a/qtbase/tests/auto/widgets/widgets/qcommandlinkbutton/qcommandlinkbutton.pro
++++ b/qtbase/tests/auto/widgets/widgets/qcommandlinkbutton/qcommandlinkbutton.pro
+@@ -1,6 +1,6 @@
+ CONFIG += testcase
+ TARGET = tst_qcommandlinkbutton
+-QT += widgets testlib
++QT += widgets testlib gui-private
+ SOURCES += tst_qcommandlinkbutton.cpp
+
+
+diff --git a/qtbase/tests/auto/widgets/widgets/qcommandlinkbutton/tst_qcommandlinkbutton.cpp b/qtbase/tests/auto/widgets/widgets/qcommandlinkbutton/tst_qcommandlinkbutton.cpp
+index 0044d33c66..4cf06296e4 100644
+--- a/qtbase/tests/auto/widgets/widgets/qcommandlinkbutton/tst_qcommandlinkbutton.cpp
++++ b/qtbase/tests/auto/widgets/widgets/qcommandlinkbutton/tst_qcommandlinkbutton.cpp
+@@ -40,6 +40,9 @@
+ #include <QGridLayout>
+ #include <QPainter>
+
++#include <private/qguiapplication_p.h>
++#include <qpa/qplatformtheme.h>
++
+ class tst_QCommandLinkButton : public QObject
+ {
+ Q_OBJECT
+@@ -223,6 +226,13 @@ void tst_QCommandLinkButton::setAutoRepeat()
+ // check that pressing ENTER has no effect
+ resetCounters();
+ testWidget->setDown( false );
++ // Skip after reset if ButtonPressKeys has Key_Enter
++ const auto buttonPressKeys = QGuiApplicationPrivate::platformTheme()
++ ->themeHint(QPlatformTheme::ButtonPressKeys)
++ .value<QList<Qt::Key>>();
++ if (buttonPressKeys.contains(Qt::Key_Enter)) {
++ return;
++ }
+ testWidget->setAutoRepeat( false );
+ QTest::keyPress( testWidget, Qt::Key_Enter );
+
+@@ -255,6 +265,14 @@ void tst_QCommandLinkButton::pressed()
+ QCOMPARE( press_count, (uint)1 );
+ QCOMPARE( release_count, (uint)1 );
+
++ // Skip if ButtonPressKeys has Key_Enter
++ const auto buttonPressKeys = QGuiApplicationPrivate::platformTheme()
++ ->themeHint(QPlatformTheme::ButtonPressKeys)
++ .value<QList<Qt::Key>>();
++ if (buttonPressKeys.contains(Qt::Key_Enter)) {
++ return;
++ }
++
+ QTest::keyPress( testWidget,Qt::Key_Enter );
+ QCOMPARE( press_count, (uint)1 );
+ QCOMPARE( release_count, (uint)1 );
+diff --git a/qtbase/tests/auto/widgets/widgets/qgroupbox/qgroupbox.pro b/qtbase/tests/auto/widgets/widgets/qgroupbox/qgroupbox.pro
+index 4a5e76ff65..a235fa1fac 100644
+--- a/qtbase/tests/auto/widgets/widgets/qgroupbox/qgroupbox.pro
++++ b/qtbase/tests/auto/widgets/widgets/qgroupbox/qgroupbox.pro
+@@ -1,6 +1,6 @@
+ CONFIG += testcase
+ TARGET = tst_qgroupbox
+-QT += widgets testlib
++QT += widgets testlib gui-private
+ SOURCES += tst_qgroupbox.cpp
+
+
+diff --git a/qtbase/tests/auto/widgets/widgets/qgroupbox/tst_qgroupbox.cpp b/qtbase/tests/auto/widgets/widgets/qgroupbox/tst_qgroupbox.cpp
+index 4fb5d262ca..d8d7562b73 100644
+--- a/qtbase/tests/auto/widgets/widgets/qgroupbox/tst_qgroupbox.cpp
++++ b/qtbase/tests/auto/widgets/widgets/qgroupbox/tst_qgroupbox.cpp
+@@ -35,6 +35,9 @@
+ #include <QRadioButton>
+ #include <QDialog>
+
++#include <private/qguiapplication_p.h>
++#include <qpa/qplatformtheme.h>
++
+ #include "qgroupbox.h"
+
+ class tst_QGroupBox : public QObject
+@@ -69,6 +72,7 @@ private slots:
+ void propagateFocus();
+ void task_QTBUG_19170_ignoreMouseReleaseEvent();
+ void task_QTBUG_15519_propagateMouseEvents();
++ void buttonPressKeys();
+
+ private:
+ bool checked;
+@@ -610,6 +614,20 @@ void tst_QGroupBox::task_QTBUG_15519_propagateMouseEvents()
+ QCOMPARE(parent.mouseMoved, true);
+ }
+
++void tst_QGroupBox::buttonPressKeys()
++{
++ QGroupBox groupBox;
++ groupBox.setCheckable(true);
++ QSignalSpy clickedSpy(&groupBox, &QGroupBox::clicked);
++ const auto buttonPressKeys = QGuiApplicationPrivate::platformTheme()
++ ->themeHint(QPlatformTheme::ButtonPressKeys)
++ .value<QList<Qt::Key>>();
++ for (int i = 0; i < buttonPressKeys.length(); ++i) {
++ QTest::keyClick(&groupBox, buttonPressKeys[i]);
++ QCOMPARE(clickedSpy.length(), i + 1);
++ }
++}
++
+ void tst_QGroupBox::sendMouseMoveEvent(QWidget *widget, const QPoint &localPos)
+ {
+ // Send a MouseMove event without actually moving the pointer
+diff --git a/qtbase/tests/auto/widgets/widgets/qpushbutton/qpushbutton.pro b/qtbase/tests/auto/widgets/widgets/qpushbutton/qpushbutton.pro
+index 353ad06ca2..e55f6148f2 100644
+--- a/qtbase/tests/auto/widgets/widgets/qpushbutton/qpushbutton.pro
++++ b/qtbase/tests/auto/widgets/widgets/qpushbutton/qpushbutton.pro
+@@ -1,6 +1,6 @@
+ CONFIG += testcase
+ TARGET = tst_qpushbutton
+-QT += widgets testlib
++QT += widgets testlib gui-private
+ SOURCES += tst_qpushbutton.cpp
+
+
+diff --git a/qtbase/tests/auto/widgets/widgets/qpushbutton/tst_qpushbutton.cpp b/qtbase/tests/auto/widgets/widgets/qpushbutton/tst_qpushbutton.cpp
+index e818514a79..4043e9326a 100644
+--- a/qtbase/tests/auto/widgets/widgets/qpushbutton/tst_qpushbutton.cpp
++++ b/qtbase/tests/auto/widgets/widgets/qpushbutton/tst_qpushbutton.cpp
+@@ -41,6 +41,9 @@
+ #include <QStyleFactory>
+ #include <QTabWidget>
+
++#include <private/qguiapplication_p.h>
++#include <qpa/qplatformtheme.h>
++
+ class tst_QPushButton : public QObject
+ {
+ Q_OBJECT
+@@ -212,6 +215,13 @@ void tst_QPushButton::autoRepeat()
+ // check that pressing ENTER has no effect
+ resetCounters();
+ testWidget->setDown( false );
++ // Skip after reset if ButtonPressKeys has Key_Enter
++ const auto buttonPressKeys = QGuiApplicationPrivate::platformTheme()
++ ->themeHint(QPlatformTheme::ButtonPressKeys)
++ .value<QList<Qt::Key>>();
++ if (buttonPressKeys.contains(Qt::Key_Enter)) {
++ return;
++ }
+ testWidget->setAutoRepeat( false );
+ QTest::keyPress( testWidget, Qt::Key_Enter );
+
+@@ -247,6 +257,14 @@ void tst_QPushButton::pressed()
+ QCOMPARE( press_count, (uint)1 );
+ QCOMPARE( release_count, (uint)1 );
+
++ // Skip if ButtonPressKeys has Key_Enter
++ const auto buttonPressKeys = QGuiApplicationPrivate::platformTheme()
++ ->themeHint(QPlatformTheme::ButtonPressKeys)
++ .value<QList<Qt::Key>>();
++ if (buttonPressKeys.contains(Qt::Key_Enter)) {
++ return;
++ }
++
+ QTest::keyPress( testWidget,Qt::Key_Enter );
+ QCOMPARE( press_count, (uint)1 );
+ QCOMPARE( release_count, (uint)1 );
+diff --git a/qtbase/tests/manual/rhi/cubemap_render/buildshader.bat b/qtbase/tests/manual/rhi/cubemap_render/buildshader.bat
+old mode 100755
+new mode 100644
+Submodule qtconnectivity e957d481..056294c0:
+diff --git a/qtconnectivity/src/bluetooth/bluez/hcimanager.cpp b/qtconnectivity/src/bluetooth/bluez/hcimanager.cpp
+index e2635fae..a8b8e3b9 100644
+--- a/qtconnectivity/src/bluetooth/bluez/hcimanager.cpp
++++ b/qtconnectivity/src/bluetooth/bluez/hcimanager.cpp
+@@ -563,9 +563,11 @@ void HciManager::handleHciAclPacket(const quint8 *data, int size)
+
+ void HciManager::handleLeMetaEvent(const quint8 *data)
+ {
+- // Spec v4.2, Vol 2, part E, 7.7.65ff
++ // Spec v5.3, Vol 4, part E, 7.7.65.*
+ switch (*data) {
+- case 0x1: {
++ case 0x1: // HCI_LE_Connection_Complete
++ case 0xA: // HCI_LE_Enhanced_Connection_Complete
++ {
+ const quint16 handle = bt_get_le16(data + 2);
+ emit connectionComplete(handle);
+ break;
+diff --git a/qtconnectivity/src/bluetooth/qbluetoothservicediscoveryagent_bluez.cpp b/qtconnectivity/src/bluetooth/qbluetoothservicediscoveryagent_bluez.cpp
+index 6a93143b..4a18cfc7 100644
+--- a/qtconnectivity/src/bluetooth/qbluetoothservicediscoveryagent_bluez.cpp
++++ b/qtconnectivity/src/bluetooth/qbluetoothservicediscoveryagent_bluez.cpp
+@@ -320,7 +320,10 @@ void QBluetoothServiceDiscoveryAgentPrivate::_q_finishSdpScan(QBluetoothServiceD
+ for (const QBluetoothUuid &id : serviceClassUuids) {
+ if (id.minimumSize() == 16) {
+ serviceInfo.setServiceUuid(id);
+- serviceInfo.setServiceName(QBluetoothServiceDiscoveryAgent::tr("Custom Service"));
++ if (serviceInfo.serviceName().isEmpty()) {
++ serviceInfo.setServiceName(
++ QBluetoothServiceDiscoveryAgent::tr("Custom Service"));
++ }
+ QBluetoothServiceInfo::Sequence modSeq =
+ serviceInfo.attribute(QBluetoothServiceInfo::ServiceClassIds).value<QBluetoothServiceInfo::Sequence>();
+ modSeq.removeOne(QVariant::fromValue(id));
+@@ -334,8 +337,10 @@ void QBluetoothServiceDiscoveryAgentPrivate::_q_finishSdpScan(QBluetoothServiceD
+ qCDebug(QT_BT_BLUEZ) << "Discovered services" << discoveredDevices.at(0).address().toString()
+ << serviceInfo.serviceName() << serviceInfo.serviceUuid()
+ << ">>>" << serviceInfo.serviceClassUuids();
+-
+- emit q->serviceDiscovered(serviceInfo);
++ // Use queued connection to allow us finish the service looping; the application
++ // might call stop() when it has detected the service-of-interest.
++ QMetaObject::invokeMethod(q, "serviceDiscovered", Qt::QueuedConnection,
++ Q_ARG(QBluetoothServiceInfo, serviceInfo));
+ }
+ }
+ }
+diff --git a/qtconnectivity/src/bluetooth/qbluetoothsocket.cpp b/qtconnectivity/src/bluetooth/qbluetoothsocket.cpp
+index e4d85447..aadd4755 100644
+--- a/qtconnectivity/src/bluetooth/qbluetoothsocket.cpp
++++ b/qtconnectivity/src/bluetooth/qbluetoothsocket.cpp
+@@ -593,7 +593,7 @@ void QBluetoothSocket::setSocketState(QBluetoothSocket::SocketState state)
+ bool QBluetoothSocket::canReadLine() const
+ {
+ Q_D(const QBluetoothSocketBase);
+- return d->canReadLine();
++ return d->canReadLine() || QIODevice::canReadLine();
+ }
+
+ /*!
+diff --git a/qtconnectivity/src/bluetooth/qbluetoothsocket_bluezdbus.cpp b/qtconnectivity/src/bluetooth/qbluetoothsocket_bluezdbus.cpp
+index 084aa958..d6aa17a7 100644
+--- a/qtconnectivity/src/bluetooth/qbluetoothsocket_bluezdbus.cpp
++++ b/qtconnectivity/src/bluetooth/qbluetoothsocket_bluezdbus.cpp
+@@ -284,6 +284,10 @@ void QBluetoothSocketPrivateBluezDBus::connectToService(
+ return;
+ }
+
++ if (service.socketProtocol() != QBluetoothServiceInfo::Protocol::UnknownProtocol)
++ socketType = service.socketProtocol();
++ qCDebug(QT_BT_BLUEZ) << "Socket protocol used:" << socketType;
++
+ connectToService(service.device().address(), targetService, openMode);
+ }
+
+diff --git a/qtconnectivity/tests/auto/qbluetoothsocket/tst_qbluetoothsocket.cpp b/qtconnectivity/tests/auto/qbluetoothsocket/tst_qbluetoothsocket.cpp
+index 05bc1a0f..a7b5ef1f 100644
+--- a/qtconnectivity/tests/auto/qbluetoothsocket/tst_qbluetoothsocket.cpp
++++ b/qtconnectivity/tests/auto/qbluetoothsocket/tst_qbluetoothsocket.cpp
+@@ -142,7 +142,7 @@ void tst_QBluetoothSocket::initTestCase()
+ qDebug() << "Starting discovery";
+
+ sda->setUuidFilter(QBluetoothUuid(QString(TEST_SERVICE_UUID)));
+- sda->start(QBluetoothServiceDiscoveryAgent::MinimalDiscovery);
++ sda->start(QBluetoothServiceDiscoveryAgent::FullDiscovery);
+
+ for (int connectTime = MaxConnectTime; !done_discovery && connectTime > 0; connectTime -= 1000)
+ QTest::qWait(1000);
+Submodule qtdeclarative f5701f0d..8defe7bf:
+diff --git a/qtdeclarative/src/qml/common/qqmljsfixedpoolarray_p.h b/qtdeclarative/src/qml/common/qqmljsfixedpoolarray_p.h
+index b65b994d6c..15a8cd6878 100644
+--- a/qtdeclarative/src/qml/common/qqmljsfixedpoolarray_p.h
++++ b/qtdeclarative/src/qml/common/qqmljsfixedpoolarray_p.h
+@@ -86,7 +86,7 @@ public:
+ if (QTypeInfo<T>::isComplex) {
+ for (int i = 0; i < count; ++i)
+ new (data + i) T(vector.at(i));
+- } else {
++ } else if (count) {
+ memcpy(data, static_cast<const void*>(vector.constData()), count * sizeof(T));
+ }
+ }
+diff --git a/qtdeclarative/src/qml/jsruntime/qv4qobjectwrapper.cpp b/qtdeclarative/src/qml/jsruntime/qv4qobjectwrapper.cpp
+index e57cdd8278..94613598af 100644
+--- a/qtdeclarative/src/qml/jsruntime/qv4qobjectwrapper.cpp
++++ b/qtdeclarative/src/qml/jsruntime/qv4qobjectwrapper.cpp
+@@ -1145,8 +1145,7 @@ void Heap::QObjectWrapper::markObjects(Heap::Base *that, QV4::MarkStack *markSta
+ void QObjectWrapper::destroyObject(bool lastCall)
+ {
+ Heap::QObjectWrapper *h = d();
+- if (!h->internalClass)
+- return; // destroyObject already got called
++ Q_ASSERT(h->internalClass);
+
+ if (h->object()) {
+ QQmlData *ddata = QQmlData::get(h->object(), false);
+@@ -1176,7 +1175,7 @@ void QObjectWrapper::destroyObject(bool lastCall)
+ }
+ }
+
+- h->~Data();
++ h->destroy();
+ }
+
+
+diff --git a/qtdeclarative/src/qml/memory/qv4mm.cpp b/qtdeclarative/src/qml/memory/qv4mm.cpp
+index 06caf04e5a..da149a67c4 100644
+--- a/qtdeclarative/src/qml/memory/qv4mm.cpp
++++ b/qtdeclarative/src/qml/memory/qv4mm.cpp
+@@ -981,7 +981,7 @@ void MemoryManager::sweep(bool lastSweep, ClassDestroyStatsCallback classCountPt
+
+ if (MultiplyWrappedQObjectMap *multiplyWrappedQObjects = engine->m_multiplyWrappedQObjects) {
+ for (MultiplyWrappedQObjectMap::Iterator it = multiplyWrappedQObjects->begin(); it != multiplyWrappedQObjects->end();) {
+- if (!it.value().isNullOrUndefined())
++ if (it.value().isNullOrUndefined())
+ it = multiplyWrappedQObjects->erase(it);
+ else
+ ++it;
+diff --git a/qtdeclarative/src/qmlmodels/qqmldelegatemodel.cpp b/qtdeclarative/src/qmlmodels/qqmldelegatemodel.cpp
+index 2079a8ed04..a577cb2351 100644
+--- a/qtdeclarative/src/qmlmodels/qqmldelegatemodel.cpp
++++ b/qtdeclarative/src/qmlmodels/qqmldelegatemodel.cpp
+@@ -389,6 +389,12 @@ void QQmlDelegateModelPrivate::connectToAbstractItemModel()
+ q, QQmlDelegateModel, SLOT(_q_rowsRemoved(QModelIndex,int,int)));
+ qmlobject_connect(aim, QAbstractItemModel, SIGNAL(rowsAboutToBeRemoved(QModelIndex,int,int)),
+ q, QQmlDelegateModel, SLOT(_q_rowsAboutToBeRemoved(QModelIndex,int,int)));
++ qmlobject_connect(aim, QAbstractItemModel, SIGNAL(columnsInserted(QModelIndex,int,int)),
++ q, QQmlDelegateModel, SLOT(_q_columnsInserted(QModelIndex,int,int)));
++ qmlobject_connect(aim, QAbstractItemModel, SIGNAL(columnsRemoved(QModelIndex,int,int)),
++ q, QQmlDelegateModel, SLOT(_q_columnsRemoved(QModelIndex,int,int)));
++ qmlobject_connect(aim, QAbstractItemModel, SIGNAL(columnsMoved(QModelIndex,int,int,QModelIndex,int)),
++ q, QQmlDelegateModel, SLOT(_q_columnsMoved(QModelIndex,int,int,QModelIndex,int)));
+ qmlobject_connect(aim, QAbstractItemModel, SIGNAL(dataChanged(QModelIndex,QModelIndex,QVector<int>)),
+ q, QQmlDelegateModel, SLOT(_q_dataChanged(QModelIndex,QModelIndex,QVector<int>)));
+ qmlobject_connect(aim, QAbstractItemModel, SIGNAL(rowsMoved(QModelIndex,int,int,QModelIndex,int)),
+@@ -413,6 +419,12 @@ void QQmlDelegateModelPrivate::disconnectFromAbstractItemModel()
+ q, SLOT(_q_rowsAboutToBeRemoved(QModelIndex,int,int)));
+ QObject::disconnect(aim, SIGNAL(rowsRemoved(QModelIndex,int,int)),
+ q, SLOT(_q_rowsRemoved(QModelIndex,int,int)));
++ QObject::disconnect(aim, SIGNAL(columnsInserted(QModelIndex,int,int)), q,
++ SLOT(_q_columnsInserted(QModelIndex,int,int)));
++ QObject::disconnect(aim, SIGNAL(columnsRemoved(QModelIndex,int,int)), q,
++ SLOT(_q_columnsRemoved(QModelIndex,int,int)));
++ QObject::disconnect(aim, SIGNAL(columnsMoved(QModelIndex,int,int,QModelIndex,int)), q,
++ SLOT(_q_columnsMoved(QModelIndex,int,int,QModelIndex,int)));
+ QObject::disconnect(aim, SIGNAL(dataChanged(QModelIndex,QModelIndex,QVector<int>)),
+ q, SLOT(_q_dataChanged(QModelIndex,QModelIndex,QVector<int>)));
+ QObject::disconnect(aim, SIGNAL(rowsMoved(QModelIndex,int,int,QModelIndex,int)),
+@@ -1973,6 +1985,38 @@ void QQmlDelegateModel::_q_rowsMoved(
+ }
+ }
+
++void QQmlDelegateModel::_q_columnsInserted(const QModelIndex &parent, int begin, int end)
++{
++ Q_D(QQmlDelegateModel);
++ Q_UNUSED(end);
++ if (parent == d->m_adaptorModel.rootIndex && begin == 0) {
++ // mark all items as changed
++ _q_itemsChanged(0, d->m_count, QVector<int>());
++ }
++}
++
++void QQmlDelegateModel::_q_columnsRemoved(const QModelIndex &parent, int begin, int end)
++{
++ Q_D(QQmlDelegateModel);
++ Q_UNUSED(end);
++ if (parent == d->m_adaptorModel.rootIndex && begin == 0) {
++ // mark all items as changed
++ _q_itemsChanged(0, d->m_count, QVector<int>());
++ }
++}
++
++void QQmlDelegateModel::_q_columnsMoved(const QModelIndex &parent, int start, int end,
++ const QModelIndex &destination, int column)
++{
++ Q_D(QQmlDelegateModel);
++ Q_UNUSED(end);
++ if ((parent == d->m_adaptorModel.rootIndex && start == 0)
++ || (destination == d->m_adaptorModel.rootIndex && column == 0)) {
++ // mark all items as changed
++ _q_itemsChanged(0, d->m_count, QVector<int>());
++ }
++}
++
+ void QQmlDelegateModel::_q_dataChanged(const QModelIndex &begin, const QModelIndex &end, const QVector<int> &roles)
+ {
+ Q_D(QQmlDelegateModel);
+diff --git a/qtdeclarative/src/qmlmodels/qqmldelegatemodel_p.h b/qtdeclarative/src/qmlmodels/qqmldelegatemodel_p.h
+index 8aab4badca..d140bfbaaf 100644
+--- a/qtdeclarative/src/qmlmodels/qqmldelegatemodel_p.h
++++ b/qtdeclarative/src/qmlmodels/qqmldelegatemodel_p.h
+@@ -152,6 +152,9 @@ private Q_SLOTS:
+ void _q_itemsMoved(int from, int to, int count);
+ void _q_modelReset();
+ void _q_rowsInserted(const QModelIndex &,int,int);
++ void _q_columnsInserted(const QModelIndex &, int, int);
++ void _q_columnsRemoved(const QModelIndex &, int, int);
++ void _q_columnsMoved(const QModelIndex &, int, int, const QModelIndex &, int);
+ void _q_rowsAboutToBeRemoved(const QModelIndex &parent, int begin, int end);
+ void _q_rowsRemoved(const QModelIndex &,int,int);
+ void _q_rowsMoved(const QModelIndex &, int, int, const QModelIndex &, int);
+diff --git a/qtdeclarative/src/quick/accessible/qaccessiblequickitem.cpp b/qtdeclarative/src/quick/accessible/qaccessiblequickitem.cpp
+index 85719fdc80..78e2ab302c 100644
+--- a/qtdeclarative/src/quick/accessible/qaccessiblequickitem.cpp
++++ b/qtdeclarative/src/quick/accessible/qaccessiblequickitem.cpp
+@@ -46,6 +46,7 @@
+ #include "QtQuick/private/qquicktextinput_p.h"
+ #include "QtQuick/private/qquickaccessibleattached_p.h"
+ #include "QtQuick/qquicktextdocument.h"
++#include "QtQuick/qquickrendercontrol.h"
+ QT_BEGIN_NAMESPACE
+
+ #if QT_CONFIG(accessibility)
+@@ -57,7 +58,19 @@ QAccessibleQuickItem::QAccessibleQuickItem(QQuickItem *item)
+
+ QWindow *QAccessibleQuickItem::window() const
+ {
+- return item()->window();
++ QQuickWindow *window = item()->window();
++
++ // For QQuickWidget the above window will be the offscreen QQuickWindow,
++ // which is not a part of the accessibility tree. Detect this case and
++ // return the window for the QQuickWidget instead.
++ if (window && !window->handle()) {
++ if (QQuickRenderControl *renderControl = QQuickWindowPrivate::get(window)->renderControl) {
++ if (QWindow *renderWindow = renderControl->renderWindow(nullptr))
++ return renderWindow;
++ }
++ }
++
++ return window;
+ }
+
+ int QAccessibleQuickItem::childCount() const
+@@ -113,19 +126,15 @@ QAccessibleInterface *QAccessibleQuickItem::childAt(int x, int y) const
+ QAccessibleInterface *QAccessibleQuickItem::parent() const
+ {
+ QQuickItem *parent = item()->parentItem();
+- QQuickWindow *window = item()->window();
+- QQuickItem *ci = window ? window->contentItem() : nullptr;
++ QQuickWindow *itemWindow = item()->window();
++ QQuickItem *ci = itemWindow ? itemWindow->contentItem() : nullptr;
+ while (parent && !QQuickItemPrivate::get(parent)->isAccessible && parent != ci)
+ parent = parent->parentItem();
+
+ if (parent) {
+ if (parent == ci) {
+- // Jump out to the scene widget if the parent is the root item.
+- // There are two root items, QQuickWindow::rootItem and
+- // QQuickView::declarativeRoot. The former is the true root item,
+- // but is not a part of the accessibility tree. Check if we hit
+- // it here and return an interface for the scene instead.
+- return QAccessible::queryAccessibleInterface(window);
++ // Jump out to the window if the parent is the root item
++ return QAccessible::queryAccessibleInterface(window());
+ } else {
+ while (parent && !parent->d_func()->isAccessible)
+ parent = parent->parentItem();
+@@ -188,7 +197,7 @@ QAccessible::State QAccessibleQuickItem::state() const
+ QRect viewRect_ = viewRect();
+ QRect itemRect = rect();
+
+- if (viewRect_.isNull() || itemRect.isNull() || !item()->window() || !item()->window()->isVisible() ||!item()->isVisible() || qFuzzyIsNull(item()->opacity()))
++ if (viewRect_.isNull() || itemRect.isNull() || !window() || !window()->isVisible() ||!item()->isVisible() || qFuzzyIsNull(item()->opacity()))
+ state.invisible = true;
+ if (!viewRect_.intersects(itemRect))
+ state.offscreen = true;
+@@ -201,6 +210,10 @@ QAccessible::State QAccessibleQuickItem::state() const
+ if (role() == QAccessible::EditableText)
+ if (auto ti = qobject_cast<QQuickTextInput *>(item()))
+ state.passwordEdit = ti->echoMode() != QQuickTextInput::Normal;
++ if (!item()->isEnabled()) {
++ state.focusable = false;
++ state.disabled = true;
++ }
+ return state;
+ }
+
+diff --git a/qtdeclarative/src/quick/accessible/qaccessiblequickview_p.h b/qtdeclarative/src/quick/accessible/qaccessiblequickview_p.h
+index 39ffcaf39c..8baa01330c 100644
+--- a/qtdeclarative/src/quick/accessible/qaccessiblequickview_p.h
++++ b/qtdeclarative/src/quick/accessible/qaccessiblequickview_p.h
+@@ -58,7 +58,7 @@ QT_BEGIN_NAMESPACE
+
+ #if QT_CONFIG(accessibility)
+
+-class QAccessibleQuickWindow : public QAccessibleObject
++class Q_QUICK_EXPORT QAccessibleQuickWindow : public QAccessibleObject
+ {
+ public:
+ QAccessibleQuickWindow(QQuickWindow *object);
+diff --git a/qtdeclarative/src/quick/items/qquickdrag.cpp b/qtdeclarative/src/quick/items/qquickdrag.cpp
+index 8321fcfeed..383078b3b9 100644
+--- a/qtdeclarative/src/quick/items/qquickdrag.cpp
++++ b/qtdeclarative/src/quick/items/qquickdrag.cpp
+@@ -481,7 +481,9 @@ void QQuickDragAttached::setKeys(const QStringList &keys)
+ \qmlattachedproperty stringlist QtQuick::Drag::mimeData
+ \since 5.2
+
+- This property holds a map of mimeData that is used during startDrag.
++ This property holds a map from mime type to data that is used during startDrag.
++ The mime data needs to be a \c string, or an \c ArrayBuffer with the data encoded
++ according to the mime type.
+ */
+
+ QVariantMap QQuickDragAttached::mimeData() const
+@@ -766,8 +768,12 @@ Qt::DropAction QQuickDragAttachedPrivate::startDrag(Qt::DropActions supportedAct
+ QDrag *drag = new QDrag(source ? source : q);
+ QMimeData *mimeData = new QMimeData();
+
+- for (auto it = externalMimeData.cbegin(), end = externalMimeData.cend(); it != end; ++it)
+- mimeData->setData(it.key(), it.value().toString().toUtf8());
++ for (auto it = externalMimeData.cbegin(), end = externalMimeData.cend(); it != end; ++it) {
++ if (static_cast<QMetaType::Type>(it.value().type()) == QMetaType::QByteArray)
++ mimeData->setData(it.key(), it.value().toByteArray());
++ else
++ mimeData->setData(it.key(), it.value().toString().toUtf8());
++ }
+
+ drag->setMimeData(mimeData);
+ if (pixmapLoader.isReady()) {
+diff --git a/qtdeclarative/src/quick/items/qquickitem.cpp b/qtdeclarative/src/quick/items/qquickitem.cpp
+index 75f1457816..dec0ae19ae 100644
+--- a/qtdeclarative/src/quick/items/qquickitem.cpp
++++ b/qtdeclarative/src/quick/items/qquickitem.cpp
+@@ -59,6 +59,7 @@
+ #include <QtCore/private/qnumeric_p.h>
+ #include <QtGui/qpa/qplatformtheme.h>
+ #include <QtCore/qloggingcategory.h>
++#include <QtCore/private/qduplicatetracker_p.h>
+
+ #include <private/qqmlglobal_p.h>
+ #include <private/qqmlengine_p.h>
+@@ -2326,6 +2327,7 @@ QQuickItem::QQuickItem(QQuickItemPrivate &dd, QQuickItem *parent)
+ QQuickItem::~QQuickItem()
+ {
+ Q_D(QQuickItem);
++ d->inDestructor = true;
+
+ if (d->windowRefCount > 1)
+ d->windowRefCount = 1; // Make sure window is set to null in next call to derefWindow().
+@@ -2526,6 +2528,7 @@ QQuickItem* QQuickItemPrivate::nextPrevItemInTabFocusChain(QQuickItem *item, boo
+ QQuickItem *current = item;
+ qCDebug(DBG_FOCUS) << "QQuickItemPrivate::nextPrevItemInTabFocusChain: startItem:" << startItem;
+ qCDebug(DBG_FOCUS) << "QQuickItemPrivate::nextPrevItemInTabFocusChain: firstFromItem:" << firstFromItem;
++ QDuplicateTracker<QQuickItem *> cycleDetector;
+ do {
+ qCDebug(DBG_FOCUS) << "QQuickItemPrivate::nextPrevItemInTabFocusChain: current:" << current;
+ qCDebug(DBG_FOCUS) << "QQuickItemPrivate::nextPrevItemInTabFocusChain: from:" << from;
+@@ -2592,7 +2595,10 @@ QQuickItem* QQuickItemPrivate::nextPrevItemInTabFocusChain(QQuickItem *item, boo
+ // traversed all of the chain (by compare the [current] item with [startItem])
+ // Since the [startItem] might be promoted to its parent if it is invisible,
+ // we still have to check [current] item with original start item
+- if ((current == startItem || current == originalStartItem) && from == firstFromItem) {
++ // We might also run into a cycle before we reach firstFromItem again
++ // but note that we have to ignore current if we are meant to skip it
++ if (((current == startItem || current == originalStartItem) && from == firstFromItem) ||
++ (!skip && cycleDetector.hasSeen(current))) {
+ // wrapped around, avoid endless loops
+ if (item == contentItem) {
+ qCDebug(DBG_FOCUS) << "QQuickItemPrivate::nextPrevItemInTabFocusChain: looped, return contentItem";
+@@ -2689,9 +2695,8 @@ void QQuickItem::setParentItem(QQuickItem *parentItem)
+
+ const bool wasVisible = isVisible();
+ op->removeChild(this);
+- if (wasVisible) {
++ if (wasVisible && !op->inDestructor)
+ emit oldParentItem->visibleChildrenChanged();
+- }
+ } else if (d->window) {
+ QQuickWindowPrivate::get(d->window)->parentlessItems.remove(this);
+ }
+@@ -2768,8 +2773,9 @@ void QQuickItem::setParentItem(QQuickItem *parentItem)
+
+ d->itemChange(ItemParentHasChanged, d->parentItem);
+
+- emit parentChanged(d->parentItem);
+- if (isVisible() && d->parentItem)
++ if (!d->inDestructor)
++ emit parentChanged(d->parentItem);
++ if (isVisible() && d->parentItem && !QQuickItemPrivate::get(d->parentItem)->inDestructor)
+ emit d->parentItem->visibleChildrenChanged();
+ }
+
+@@ -2965,7 +2971,8 @@ void QQuickItemPrivate::removeChild(QQuickItem *child)
+
+ itemChange(QQuickItem::ItemChildRemovedChange, child);
+
+- emit q->childrenChanged();
++ if (!inDestructor)
++ emit q->childrenChanged();
+ }
+
+ void QQuickItemPrivate::refWindow(QQuickWindow *c)
+@@ -3194,6 +3201,7 @@ QQuickItemPrivate::QQuickItemPrivate()
+ , touchEnabled(false)
+ #endif
+ , hasCursorHandler(false)
++ , inDestructor(false)
+ , dirtyAttributes(0)
+ , nextDirtyItem(nullptr)
+ , prevDirtyItem(nullptr)
+@@ -5120,6 +5128,13 @@ void QQuickItem::componentComplete()
+ d->addToDirtyList();
+ QQuickWindowPrivate::get(d->window)->dirtyItem(this);
+ }
++
++#if QT_CONFIG(accessibility)
++ if (d->isAccessible && d->effectiveVisible) {
++ QAccessibleEvent ev(this, QAccessible::ObjectShow);
++ QAccessible::updateAccessibility(&ev);
++ }
++#endif
+ }
+
+ QQuickStateGroup *QQuickItemPrivate::_states()
+@@ -6106,9 +6121,11 @@ bool QQuickItemPrivate::setEffectiveVisibleRecur(bool newEffectiveVisible)
+ QAccessible::updateAccessibility(&ev);
+ }
+ #endif
+- emit q->visibleChanged();
+- if (childVisibilityChanged)
+- emit q->visibleChildrenChanged();
++ if (!inDestructor) {
++ emit q->visibleChanged();
++ if (childVisibilityChanged)
++ emit q->visibleChildrenChanged();
++ }
+
+ return true; // effective visibility DID change
+ }
+@@ -6157,6 +6174,15 @@ void QQuickItemPrivate::setEffectiveEnableRecur(QQuickItem *scope, bool newEffec
+ }
+
+ itemChange(QQuickItem::ItemEnabledHasChanged, effectiveEnable);
++#if QT_CONFIG(accessibility)
++ if (isAccessible) {
++ QAccessible::State changedState;
++ changedState.disabled = true;
++ changedState.focusable = true;
++ QAccessibleStateChangeEvent ev(q, changedState);
++ QAccessible::updateAccessibility(&ev);
++ }
++#endif
+ emit q->enabledChanged();
+ }
+
+diff --git a/qtdeclarative/src/quick/items/qquickitem_p.h b/qtdeclarative/src/quick/items/qquickitem_p.h
+index 841d91bb40..ade8fb61f2 100644
+--- a/qtdeclarative/src/quick/items/qquickitem_p.h
++++ b/qtdeclarative/src/quick/items/qquickitem_p.h
+@@ -472,6 +472,7 @@ public:
+ bool replayingPressEvent:1;
+ bool touchEnabled:1;
+ bool hasCursorHandler:1;
++ quint32 inDestructor:1; // has entered ~QQuickItem
+
+ enum DirtyType {
+ TransformOrigin = 0x00000001,
+diff --git a/qtdeclarative/src/quick/items/qquickitemview.cpp b/qtdeclarative/src/quick/items/qquickitemview.cpp
+index 010a0152e1..f8ad168a17 100644
+--- a/qtdeclarative/src/quick/items/qquickitemview.cpp
++++ b/qtdeclarative/src/quick/items/qquickitemview.cpp
+@@ -1785,7 +1785,7 @@ void QQuickItemViewPrivate::refill(qreal from, qreal to)
+
+ do {
+ bufferPause.stop();
+- if (currentChanges.hasPendingChanges() || bufferedChanges.hasPendingChanges()) {
++ if (currentChanges.hasPendingChanges() || bufferedChanges.hasPendingChanges() || currentChanges.active) {
+ currentChanges.reset();
+ bufferedChanges.reset();
+ releaseVisibleItems(reusableFlag);
+diff --git a/qtdeclarative/src/quick/items/qquickmousearea_p_p.h b/qtdeclarative/src/quick/items/qquickmousearea_p_p.h
+index fba383e268..0d63618622 100644
+--- a/qtdeclarative/src/quick/items/qquickmousearea_p_p.h
++++ b/qtdeclarative/src/quick/items/qquickmousearea_p_p.h
+@@ -61,7 +61,6 @@ QT_BEGIN_NAMESPACE
+
+ class QQuickMouseEvent;
+ class QQuickMouseArea;
+-class QQuickPointerMask;
+ class QQuickMouseAreaPrivate : public QQuickItemPrivate
+ {
+ Q_DECLARE_PUBLIC(QQuickMouseArea)
+@@ -100,7 +99,6 @@ public:
+ #if QT_CONFIG(quick_draganddrop)
+ QQuickDrag *drag;
+ #endif
+- QPointer<QQuickPointerMask> mask;
+ QPointF startScene;
+ QPointF targetStartPos;
+ QPointF lastPos;
+diff --git a/qtdeclarative/src/quick/items/qquicktext.cpp b/qtdeclarative/src/quick/items/qquicktext.cpp
+index 6230186933..e823ca1095 100644
+--- a/qtdeclarative/src/quick/items/qquicktext.cpp
++++ b/qtdeclarative/src/quick/items/qquicktext.cpp
+@@ -2168,7 +2168,7 @@ void QQuickText::resetMaximumLineCount()
+ <img src="" align="top,middle,bottom" width="" height=""> - inline images
+ <ol type="">, <ul type=""> and <li> - ordered and unordered lists
+ <pre></pre> - preformatted
+- > < &
++ > < & " '
+ \endcode
+
+ \c Text.StyledText parser is strict, requiring tags to be correctly nested.
+diff --git a/qtdeclarative/src/quick/scenegraph/qsgrhidistancefieldglyphcache.cpp b/qtdeclarative/src/quick/scenegraph/qsgrhidistancefieldglyphcache.cpp
+index eb4db0f85e..2325a2665b 100644
+--- a/qtdeclarative/src/quick/scenegraph/qsgrhidistancefieldglyphcache.cpp
++++ b/qtdeclarative/src/quick/scenegraph/qsgrhidistancefieldglyphcache.cpp
+@@ -446,7 +446,7 @@ bool QSGRhiDistanceFieldGlyphCache::loadPregeneratedCache(const QRawFont &font)
+
+ const char *textureRecord = allocatorData;
+ for (int i = 0; i < textureCount; ++i, textureRecord += Qtdf::TextureRecordSize) {
+- if (textureRecord + Qtdf::TextureRecordSize > qtdfTableEnd) {
++ if (qtdfTableEnd - textureRecord < Qtdf::TextureRecordSize) {
+ qWarning("qtdf table too small in font '%s'.",
+ qPrintable(font.familyName()));
+ return false;
+@@ -462,7 +462,7 @@ bool QSGRhiDistanceFieldGlyphCache::loadPregeneratedCache(const QRawFont &font)
+
+ const char *glyphRecord = textureRecord;
+ for (quint32 i = 0; i < glyphCount; ++i, glyphRecord += Qtdf::GlyphRecordSize) {
+- if (glyphRecord + Qtdf::GlyphRecordSize > qtdfTableEnd) {
++ if (qtdfTableEnd - glyphRecord < Qtdf:: GlyphRecordSize) {
+ qWarning("qtdf table too small in font '%s'.",
+ qPrintable(font.familyName()));
+ return false;
+@@ -512,8 +512,8 @@ bool QSGRhiDistanceFieldGlyphCache::loadPregeneratedCache(const QRawFont &font)
+
+ int width = texInfo->allocatedArea.width();
+ int height = texInfo->allocatedArea.height();
+- qint64 size = width * height;
+- if (reinterpret_cast<const char *>(textureData + size) > qtdfTableEnd) {
++ qint64 size = qint64(width) * height;
++ if (qtdfTableEnd - reinterpret_cast<const char *>(textureData) < size) {
+ qWarning("qtdf table too small in font '%s'.",
+ qPrintable(font.familyName()));
+ return false;
+diff --git a/qtdeclarative/src/quick/util/qquickstyledtext.cpp b/qtdeclarative/src/quick/util/qquickstyledtext.cpp
+index d531fc9205..a25af90414 100644
+--- a/qtdeclarative/src/quick/util/qquickstyledtext.cpp
++++ b/qtdeclarative/src/quick/util/qquickstyledtext.cpp
+@@ -564,6 +564,8 @@ void QQuickStyledTextPrivate::parseEntity(const QChar *&ch, const QString &textI
+ textOut += QChar(60);
+ else if (entity == QLatin1String("amp"))
+ textOut += QChar(38);
++ else if (entity == QLatin1String("apos"))
++ textOut += QChar(39);
+ else if (entity == QLatin1String("quot"))
+ textOut += QChar(34);
+ else if (entity == QLatin1String("nbsp"))
+diff --git a/qtdeclarative/src/quickwidgets/qaccessiblequickwidget.cpp b/qtdeclarative/src/quickwidgets/qaccessiblequickwidget.cpp
+new file mode 100644
+index 0000000000..8a1c901880
+--- /dev/null
++++ b/qtdeclarative/src/quickwidgets/qaccessiblequickwidget.cpp
+@@ -0,0 +1,110 @@
++/****************************************************************************
++**
++** Copyright (C) 2021 The Qt Company Ltd.
++** Contact: https://www.qt.io/licensing/
++**
++** This file is part of the QtQuick module of the Qt Toolkit.
++**
++** $QT_BEGIN_LICENSE:LGPL$
++** Commercial License Usage
++** Licensees holding valid commercial Qt licenses may use this file in
++** accordance with the commercial license agreement provided with the
++** Software or, alternatively, in accordance with the terms contained in
++** a written agreement between you and The Qt Company. For licensing terms
++** and conditions see https://www.qt.io/terms-conditions. For further
++** information use the contact form at https://www.qt.io/contact-us.
++**
++** GNU Lesser General Public License Usage
++** Alternatively, this file may be used under the terms of the GNU Lesser
++** General Public License version 3 as published by the Free Software
++** Foundation and appearing in the file LICENSE.LGPL3 included in the
++** packaging of this file. Please review the following information to
++** ensure the GNU Lesser General Public License version 3 requirements
++** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
++**
++** GNU General Public License Usage
++** Alternatively, this file may be used under the terms of the GNU
++** General Public License version 2.0 or (at your option) the GNU General
++** Public license version 3 or any later version approved by the KDE Free
++** Qt Foundation. The licenses are as published by the Free Software
++** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
++** included in the packaging of this file. Please review the following
++** information to ensure the GNU General Public License requirements will
++** be met: https://www.gnu.org/licenses/gpl-2.0.html and
++** https://www.gnu.org/licenses/gpl-3.0.html.
++**
++** $QT_END_LICENSE$
++**
++****************************************************************************/
++
++#include "qaccessiblequickwidget_p.h"
++
++#include "qquickwidget_p.h"
++
++QT_BEGIN_NAMESPACE
++
++#if QT_CONFIG(accessibility)
++
++QAccessibleQuickWidget::QAccessibleQuickWidget(QQuickWidget* widget)
++: QAccessibleWidget(widget)
++, m_accessibleWindow(QQuickWidgetPrivate::get(widget)->offscreenWindow)
++{
++ // NOTE: m_accessibleWindow is a QAccessibleQuickWindow, and not a
++ // QAccessibleQuickWidgetOffscreenWindow (defined below). This means
++ // it will return the Quick item child interfaces, which is what's needed here
++ // (unlike QAccessibleQuickWidgetOffscreenWindow, which will report 0 children).
++}
++
++QAccessibleInterface *QAccessibleQuickWidget::child(int index) const
++{
++ return m_accessibleWindow.child(index);
++}
++
++int QAccessibleQuickWidget::childCount() const
++{
++ return m_accessibleWindow.childCount();
++}
++
++int QAccessibleQuickWidget::indexOfChild(const QAccessibleInterface *iface) const
++{
++ return m_accessibleWindow.indexOfChild(iface);
++}
++
++QAccessibleInterface *QAccessibleQuickWidget::childAt(int x, int y) const
++{
++ return m_accessibleWindow.childAt(x, y);
++}
++
++QAccessibleQuickWidgetOffscreenWindow::QAccessibleQuickWidgetOffscreenWindow(QQuickWindow *window)
++:QAccessibleQuickWindow(window)
++{
++
++}
++
++QAccessibleInterface *QAccessibleQuickWidgetOffscreenWindow::child(int index) const
++{
++ Q_UNUSED(index);
++ return nullptr;
++}
++
++int QAccessibleQuickWidgetOffscreenWindow::childCount() const
++{
++ return 0;
++}
++
++int QAccessibleQuickWidgetOffscreenWindow::indexOfChild(const QAccessibleInterface *iface) const
++{
++ Q_UNUSED(iface);
++ return -1;
++}
++
++QAccessibleInterface *QAccessibleQuickWidgetOffscreenWindow::QAccessibleQuickWidgetOffscreenWindow::childAt(int x, int y) const
++{
++ Q_UNUSED(x);
++ Q_UNUSED(y);
++ return nullptr;
++}
++
++#endif // accessibility
++
++QT_END_NAMESPACE
+diff --git a/qtdeclarative/src/quickwidgets/qaccessiblequickwidget_p.h b/qtdeclarative/src/quickwidgets/qaccessiblequickwidget_p.h
+new file mode 100644
+index 0000000000..7c2ab930e0
+--- /dev/null
++++ b/qtdeclarative/src/quickwidgets/qaccessiblequickwidget_p.h
+@@ -0,0 +1,95 @@
++/****************************************************************************
++**
++** Copyright (C) 2021 The Qt Company Ltd.
++** Contact: https://www.qt.io/licensing/
++**
++** This file is part of the QtQuick module of the Qt Toolkit.
++**
++** $QT_BEGIN_LICENSE:LGPL$
++** Commercial License Usage
++** Licensees holding valid commercial Qt licenses may use this file in
++** accordance with the commercial license agreement provided with the
++** Software or, alternatively, in accordance with the terms contained in
++** a written agreement between you and The Qt Company. For licensing terms
++** and conditions see https://www.qt.io/terms-conditions. For further
++** information use the contact form at https://www.qt.io/contact-us.
++**
++** GNU Lesser General Public License Usage
++** Alternatively, this file may be used under the terms of the GNU Lesser
++** General Public License version 3 as published by the Free Software
++** Foundation and appearing in the file LICENSE.LGPL3 included in the
++** packaging of this file. Please review the following information to
++** ensure the GNU Lesser General Public License version 3 requirements
++** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
++**
++** GNU General Public License Usage
++** Alternatively, this file may be used under the terms of the GNU
++** General Public License version 2.0 or (at your option) the GNU General
++** Public license version 3 or any later version approved by the KDE Free
++** Qt Foundation. The licenses are as published by the Free Software
++** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
++** included in the packaging of this file. Please review the following
++** information to ensure the GNU General Public License requirements will
++** be met: https://www.gnu.org/licenses/gpl-2.0.html and
++** https://www.gnu.org/licenses/gpl-3.0.html.
++**
++** $QT_END_LICENSE$
++**
++****************************************************************************/
++
++#ifndef QACCESSIBLEQUICKWIDGET_H
++#define QACCESSIBLEQUICKWIDGET_H
++
++//
++// W A R N I N G
++// -------------
++//
++// This file is not part of the Qt API. It exists purely as an
++// implementation detail. This header file may change from version to
++// version without notice, or even be removed.
++//
++// We mean it.
++//
++
++#include "qquickwidget.h"
++#include <QtWidgets/qaccessiblewidget.h>
++
++#include <private/qaccessiblequickview_p.h>
++
++QT_BEGIN_NAMESPACE
++
++#if QT_CONFIG(accessibility)
++
++// These classes implement the QQuickWiget accessibility switcharoo,
++// where the child items of the QQuickWidgetOffscreenWindow are reported
++// as child accessible interfaces of the QAccessibleQuickWidget.
++class QAccessibleQuickWidget: public QAccessibleWidget
++{
++public:
++ QAccessibleQuickWidget(QQuickWidget* widget);
++
++ QAccessibleInterface *child(int index) const override;
++ int childCount() const override;
++ int indexOfChild(const QAccessibleInterface *iface) const override;
++ QAccessibleInterface *childAt(int x, int y) const override;
++
++private:
++ QAccessibleQuickWindow m_accessibleWindow;
++ Q_DISABLE_COPY(QAccessibleQuickWidget)
++};
++
++class QAccessibleQuickWidgetOffscreenWindow: public QAccessibleQuickWindow
++{
++public:
++ QAccessibleQuickWidgetOffscreenWindow(QQuickWindow *window);
++ QAccessibleInterface *child(int index) const override;
++ int childCount() const override;
++ int indexOfChild(const QAccessibleInterface *iface) const override;
++ QAccessibleInterface *childAt(int x, int y) const override;
++};
++
++#endif // accessibility
++
++QT_END_NAMESPACE
++
++#endif
+diff --git a/qtdeclarative/src/quickwidgets/qaccessiblequickwidgetfactory.cpp b/qtdeclarative/src/quickwidgets/qaccessiblequickwidgetfactory.cpp
+new file mode 100644
+index 0000000000..7ba88a1769
+--- /dev/null
++++ b/qtdeclarative/src/quickwidgets/qaccessiblequickwidgetfactory.cpp
+@@ -0,0 +1,60 @@
++/****************************************************************************
++**
++** Copyright (C) 2021 The Qt Company Ltd.
++** Contact: https://www.qt.io/licensing/
++**
++** This file is part of the QtQuick module of the Qt Toolkit.
++**
++** $QT_BEGIN_LICENSE:LGPL$
++** Commercial License Usage
++** Licensees holding valid commercial Qt licenses may use this file in
++** accordance with the commercial license agreement provided with the
++** Software or, alternatively, in accordance with the terms contained in
++** a written agreement between you and The Qt Company. For licensing terms
++** and conditions see https://www.qt.io/terms-conditions. For further
++** information use the contact form at https://www.qt.io/contact-us.
++**
++** GNU Lesser General Public License Usage
++** Alternatively, this file may be used under the terms of the GNU Lesser
++** General Public License version 3 as published by the Free Software
++** Foundation and appearing in the file LICENSE.LGPL3 included in the
++** packaging of this file. Please review the following information to
++** ensure the GNU Lesser General Public License version 3 requirements
++** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
++**
++** GNU General Public License Usage
++** Alternatively, this file may be used under the terms of the GNU
++** General Public License version 2.0 or (at your option) the GNU General
++** Public license version 3 or any later version approved by the KDE Free
++** Qt Foundation. The licenses are as published by the Free Software
++** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
++** included in the packaging of this file. Please review the following
++** information to ensure the GNU General Public License requirements will
++** be met: https://www.gnu.org/licenses/gpl-2.0.html and
++** https://www.gnu.org/licenses/gpl-3.0.html.
++**
++** $QT_END_LICENSE$
++**
++****************************************************************************/
++
++#include "qaccessiblequickwidgetfactory_p.h"
++#include "qaccessiblequickwidget_p.h"
++
++QT_BEGIN_NAMESPACE
++
++#if QT_CONFIG(accessibility)
++
++QAccessibleInterface *qAccessibleQuickWidgetFactory(const QString &classname, QObject *object)
++{
++ if (classname == QLatin1String("QQuickWidget")) {
++ return new QAccessibleQuickWidget(qobject_cast<QQuickWidget *>(object));
++ } else if (classname == QLatin1String("QQuickWidgetOffscreenWindow")) {
++ return new QAccessibleQuickWidgetOffscreenWindow(qobject_cast<QQuickWindow *>(object));
++ }
++ return 0;
++}
++
++#endif // accessibility
++
++QT_END_NAMESPACE
++
+diff --git a/qtdeclarative/src/quickwidgets/qaccessiblequickwidgetfactory_p.h b/qtdeclarative/src/quickwidgets/qaccessiblequickwidgetfactory_p.h
+new file mode 100644
+index 0000000000..8c63b09f81
+--- /dev/null
++++ b/qtdeclarative/src/quickwidgets/qaccessiblequickwidgetfactory_p.h
+@@ -0,0 +1,66 @@
++/****************************************************************************
++**
++** Copyright (C) 2021 The Qt Company Ltd.
++** Contact: https://www.qt.io/licensing/
++**
++** This file is part of the QtQuick module of the Qt Toolkit.
++**
++** $QT_BEGIN_LICENSE:LGPL$
++** Commercial License Usage
++** Licensees holding valid commercial Qt licenses may use this file in
++** accordance with the commercial license agreement provided with the
++** Software or, alternatively, in accordance with the terms contained in
++** a written agreement between you and The Qt Company. For licensing terms
++** and conditions see https://www.qt.io/terms-conditions. For further
++** information use the contact form at https://www.qt.io/contact-us.
++**
++** GNU Lesser General Public License Usage
++** Alternatively, this file may be used under the terms of the GNU Lesser
++** General Public License version 3 as published by the Free Software
++** Foundation and appearing in the file LICENSE.LGPL3 included in the
++** packaging of this file. Please review the following information to
++** ensure the GNU Lesser General Public License version 3 requirements
++** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
++**
++** GNU General Public License Usage
++** Alternatively, this file may be used under the terms of the GNU
++** General Public License version 2.0 or (at your option) the GNU General
++** Public license version 3 or any later version approved by the KDE Free
++** Qt Foundation. The licenses are as published by the Free Software
++** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
++** included in the packaging of this file. Please review the following
++** information to ensure the GNU General Public License requirements will
++** be met: https://www.gnu.org/licenses/gpl-2.0.html and
++** https://www.gnu.org/licenses/gpl-3.0.html.
++**
++** $QT_END_LICENSE$
++**
++****************************************************************************/
++
++#include <QtGui/qaccessible.h>
++
++#ifndef QACCESSIBLEQUICKWIDGETFACTORY_H
++#define QACCESSIBLEQUICKWIDGETFACTORY_H
++
++//
++// W A R N I N G
++// -------------
++//
++// This file is not part of the Qt API. It exists purely as an
++// implementation detail. This header file may change from version to
++// version without notice, or even be removed.
++//
++// We mean it.
++//
++
++QT_BEGIN_NAMESPACE
++
++#if QT_CONFIG(accessibility)
++
++QAccessibleInterface *qAccessibleQuickWidgetFactory(const QString &classname, QObject *object);
++
++#endif
++
++QT_END_NAMESPACE
++
++#endif
+diff --git a/qtdeclarative/src/quickwidgets/qquickwidget.cpp b/qtdeclarative/src/quickwidgets/qquickwidget.cpp
+index 39780f8de3..9c97b43518 100644
+--- a/qtdeclarative/src/quickwidgets/qquickwidget.cpp
++++ b/qtdeclarative/src/quickwidgets/qquickwidget.cpp
+@@ -39,6 +39,7 @@
+
+ #include "qquickwidget.h"
+ #include "qquickwidget_p.h"
++#include "qaccessiblequickwidgetfactory_p.h"
+
+ #include "private/qquickwindow_p.h"
+ #include "private/qquickitem_p.h"
+@@ -75,9 +76,16 @@
+
+ QT_BEGIN_NAMESPACE
+
++QQuickWidgetOffscreenWindow::QQuickWidgetOffscreenWindow(QQuickWindowPrivate &dd, QQuickRenderControl *control)
++:QQuickWindow(dd, control)
++{
++ setTitle(QString::fromLatin1("Offscreen"));
++ setObjectName(QString::fromLatin1("QQuickOffScreenWindow"));
++}
++
+ // override setVisble to prevent accidental offscreen window being created
+ // by base class.
+-class QQuickOffcreenWindowPrivate: public QQuickWindowPrivate {
++class QQuickWidgetOffscreenWindowPrivate: public QQuickWindowPrivate {
+ public:
+ void setVisible(bool visible) override {
+ Q_Q(QWindow);
+@@ -105,9 +113,8 @@ void QQuickWidgetPrivate::init(QQmlEngine* e)
+ Q_Q(QQuickWidget);
+
+ renderControl = new QQuickWidgetRenderControl(q);
+- offscreenWindow = new QQuickWindow(*new QQuickOffcreenWindowPrivate(),renderControl);
+- offscreenWindow->setTitle(QString::fromLatin1("Offscreen"));
+- offscreenWindow->setObjectName(QString::fromLatin1("QQuickOffScreenWindow"));
++ offscreenWindow = new QQuickWidgetOffscreenWindow(*new QQuickWidgetOffscreenWindowPrivate(), renderControl);
++ offscreenWindow->setScreen(q->screen());
+ // Do not call create() on offscreenWindow.
+
+ // Check if the Software Adaptation is being used
+@@ -138,6 +145,10 @@ void QQuickWidgetPrivate::init(QQmlEngine* e)
+ QWidget::connect(offscreenWindow, &QQuickWindow::focusObjectChanged, q, &QQuickWidget::propagateFocusObjectChanged);
+ QObject::connect(renderControl, SIGNAL(renderRequested()), q, SLOT(triggerUpdate()));
+ QObject::connect(renderControl, SIGNAL(sceneChanged()), q, SLOT(triggerUpdate()));
++
++#if QT_CONFIG(accessibility)
++ QAccessible::installFactory(&qAccessibleQuickWidgetFactory);
++#endif
+ }
+
+ void QQuickWidgetPrivate::ensureEngine() const
+@@ -901,9 +912,7 @@ void QQuickWidgetPrivate::createContext()
+
+ context = new QOpenGLContext;
+ context->setFormat(offscreenWindow->requestedFormat());
+- const QWindow *win = q->window()->windowHandle();
+- if (win && win->screen())
+- context->setScreen(win->screen());
++ context->setScreen(q->screen());
+ QOpenGLContext *shareContext = qt_gl_global_share_context();
+ if (!shareContext)
+ shareContext = QWidgetPrivate::get(q->window())->shareContext();
+@@ -1520,19 +1529,16 @@ bool QQuickWidget::event(QEvent *e)
+ d->handleWindowChange();
+ break;
+
+- case QEvent::ScreenChangeInternal:
+- if (QWindow *window = this->window()->windowHandle()) {
+- QScreen *newScreen = window->screen();
+-
+- if (d->offscreenWindow)
+- d->offscreenWindow->setScreen(newScreen);
+- if (d->offscreenSurface)
+- d->offscreenSurface->setScreen(newScreen);
++ case QEvent::ScreenChangeInternal: {
++ QScreen *newScreen = screen();
++ if (d->offscreenWindow)
++ d->offscreenWindow->setScreen(newScreen);
++ if (d->offscreenSurface)
++ d->offscreenSurface->setScreen(newScreen);
+ #if QT_CONFIG(opengl)
+- if (d->context)
+- d->context->setScreen(newScreen);
++ if (d->context)
++ d->context->setScreen(newScreen);
+ #endif
+- }
+
+ if (d->useSoftwareRenderer
+ #if QT_CONFIG(opengl)
+@@ -1545,7 +1551,7 @@ bool QQuickWidget::event(QEvent *e)
+ d->render(true);
+ }
+ break;
+-
++ }
+ case QEvent::Show:
+ case QEvent::Move:
+ d->updatePosition();
+diff --git a/qtdeclarative/src/quickwidgets/qquickwidget_p.h b/qtdeclarative/src/quickwidgets/qquickwidget_p.h
+index 881f7f9220..1a946bcc71 100644
+--- a/qtdeclarative/src/quickwidgets/qquickwidget_p.h
++++ b/qtdeclarative/src/quickwidgets/qquickwidget_p.h
+@@ -148,6 +148,14 @@ public:
+ bool forceFullUpdate;
+ };
+
++class QQuickWidgetOffscreenWindow: public QQuickWindow
++{
++ Q_OBJECT
++
++public:
++ QQuickWidgetOffscreenWindow(QQuickWindowPrivate &dd, QQuickRenderControl *control);
++};
++
+ QT_END_NAMESPACE
+
+ #endif // QQuickWidget_P_H
+diff --git a/qtdeclarative/src/quickwidgets/quickwidgets.pro b/qtdeclarative/src/quickwidgets/quickwidgets.pro
+index 2438e577ae..85d156b8a3 100644
+--- a/qtdeclarative/src/quickwidgets/quickwidgets.pro
++++ b/qtdeclarative/src/quickwidgets/quickwidgets.pro
+@@ -7,9 +7,13 @@ DEFINES += QT_NO_URL_CAST_FROM_STRING QT_NO_INTEGER_EVENT_COORDINATES QT_NO_FO
+ HEADERS += \
+ qquickwidget.h \
+ qquickwidget_p.h \
+- qtquickwidgetsglobal.h
++ qtquickwidgetsglobal.h \
++ qaccessiblequickwidget_p.h \
++ qaccessiblequickwidgetfactory_p.h
+
+ SOURCES += \
+- qquickwidget.cpp
++ qquickwidget.cpp \
++ qaccessiblequickwidget.cpp \
++ qaccessiblequickwidgetfactory.cpp
+
+ load(qt_module)
+diff --git a/qtdeclarative/tests/auto/qml/qjsengine/tst_qjsengine.cpp b/qtdeclarative/tests/auto/qml/qjsengine/tst_qjsengine.cpp
+index 3b7d74df63..b75bf820d5 100644
+--- a/qtdeclarative/tests/auto/qml/qjsengine/tst_qjsengine.cpp
++++ b/qtdeclarative/tests/auto/qml/qjsengine/tst_qjsengine.cpp
+@@ -102,6 +102,7 @@ private slots:
+ void valueConversion_RegularExpression();
+ void castWithMultipleInheritance();
+ void collectGarbage();
++ void collectGarbageNestedWrappersTwoEngines();
+ void gcWithNestedDataStructure();
+ void stacktrace();
+ void numberParsing_data();
+@@ -1809,6 +1810,44 @@ void tst_QJSEngine::collectGarbage()
+ QVERIFY(ptr.isNull());
+ }
+
++class TestObjectContainer : public QObject
++{
++ Q_OBJECT
++ Q_PROPERTY(QObject *dummy MEMBER m_dummy CONSTANT)
++
++public:
++ TestObjectContainer() : m_dummy(new QObject(this)) {}
++
++private:
++ QObject *m_dummy;
++};
++
++void tst_QJSEngine::collectGarbageNestedWrappersTwoEngines()
++{
++ QJSEngine engine1;
++ QJSEngine engine2;
++
++ TestObjectContainer container;
++ QQmlEngine::setObjectOwnership(&container, QQmlEngine::CppOwnership);
++
++ engine1.globalObject().setProperty("foobar", engine1.newQObject(&container));
++ engine2.globalObject().setProperty("foobar", engine2.newQObject(&container));
++
++ engine1.evaluate("foobar.dummy.baz = 42");
++ engine2.evaluate("foobar.dummy.baz = 43");
++
++ QCOMPARE(engine1.evaluate("foobar.dummy.baz").toInt(), 42);
++ QCOMPARE(engine2.evaluate("foobar.dummy.baz").toInt(), 43);
++
++ engine1.collectGarbage();
++ engine2.collectGarbage();
++
++ // The GC should not collect dummy object wrappers neither in engine1 nor engine2, we
++ // verify that by checking whether the baz property still has its previous value.
++ QCOMPARE(engine1.evaluate("foobar.dummy.baz").toInt(), 42);
++ QCOMPARE(engine2.evaluate("foobar.dummy.baz").toInt(), 43);
++}
++
+ void tst_QJSEngine::gcWithNestedDataStructure()
+ {
+ // The GC must be able to traverse deeply nested objects, otherwise this
+diff --git a/qtdeclarative/tests/auto/qml/qqmldelegatemodel/data/redrawUponColumnChange.qml b/qtdeclarative/tests/auto/qml/qqmldelegatemodel/data/redrawUponColumnChange.qml
+new file mode 100644
+index 0000000000..206133bb39
+--- /dev/null
++++ b/qtdeclarative/tests/auto/qml/qqmldelegatemodel/data/redrawUponColumnChange.qml
+@@ -0,0 +1,11 @@
++import QtQuick 2.8
++
++ListView {
++ id: root
++ width: 200
++ height: 200
++
++ delegate: Text {
++ text: display
++ }
++}
+diff --git a/qtdeclarative/tests/auto/qml/qqmldelegatemodel/tst_qqmldelegatemodel.cpp b/qtdeclarative/tests/auto/qml/qqmldelegatemodel/tst_qqmldelegatemodel.cpp
+index 35f1e2c94d..1722447830 100644
+--- a/qtdeclarative/tests/auto/qml/qqmldelegatemodel/tst_qqmldelegatemodel.cpp
++++ b/qtdeclarative/tests/auto/qml/qqmldelegatemodel/tst_qqmldelegatemodel.cpp
+@@ -27,6 +27,8 @@
+ ****************************************************************************/
+
+ #include <QtTest/qtest.h>
++#include <QtCore/QConcatenateTablesProxyModel>
++#include <QtGui/QStandardItemModel>
+ #include <QtQml/qqmlcomponent.h>
+ #include <QtQmlModels/private/qqmldelegatemodel_p.h>
+ #include <QtQuick/qquickview.h>
+@@ -47,6 +49,7 @@ private slots:
+ void filterOnGroup_removeWhenCompleted();
+ void qtbug_86017();
+ void contextAccessedByHandler();
++ void redrawUponColumnChange();
+ };
+
+ class AbstractItemModel : public QAbstractItemModel
+@@ -186,6 +189,30 @@ void tst_QQmlDelegateModel::contextAccessedByHandler()
+ QVERIFY(root->property("works").toBool());
+ }
+
++void tst_QQmlDelegateModel::redrawUponColumnChange()
++{
++ QStandardItemModel m1;
++ m1.appendRow({
++ new QStandardItem("Banana"),
++ new QStandardItem("Coconut"),
++ });
++
++ QQuickView view(testFileUrl("redrawUponColumnChange.qml"));
++ QCOMPARE(view.status(), QQuickView::Ready);
++ view.show();
++ QQuickItem *root = view.rootObject();
++ root->setProperty("model", QVariant::fromValue<QObject *>(&m1));
++
++ QObject *item = root->property("currentItem").value<QObject *>();
++ QVERIFY(item);
++ QCOMPARE(item->property("text").toString(), "Banana");
++
++ QVERIFY(root);
++ m1.removeColumn(0);
++
++ QCOMPARE(item->property("text").toString(), "Coconut");
++}
++
+ QTEST_MAIN(tst_QQmlDelegateModel)
+
+ #include "tst_qqmldelegatemodel.moc"
+diff --git a/qtdeclarative/tests/auto/qml/qv4mm/tst_qv4mm.cpp b/qtdeclarative/tests/auto/qml/qv4mm/tst_qv4mm.cpp
+index 5d635aa63b..824fd89e5b 100644
+--- a/qtdeclarative/tests/auto/qml/qv4mm/tst_qv4mm.cpp
++++ b/qtdeclarative/tests/auto/qml/qv4mm/tst_qv4mm.cpp
+@@ -76,10 +76,10 @@ void tst_qv4mm::multiWrappedQObjects()
+ QCOMPARE(engine1.memoryManager->m_pendingFreedObjectWrapperValue.size(), 1);
+ QCOMPARE(engine2.memoryManager->m_pendingFreedObjectWrapperValue.size(), 0);
+
+- // Moves the additional WeakValue from m_multiplyWrappedQObjects to
+- // m_pendingFreedObjectWrapperValue. It's still alive after all.
++ // The additional WeakValue from m_multiplyWrappedQObjects hasn't been moved
++ // to m_pendingFreedObjectWrapperValue yet. It's still alive after all.
+ engine1.memoryManager->runGC();
+- QCOMPARE(engine1.memoryManager->m_pendingFreedObjectWrapperValue.size(), 2);
++ QCOMPARE(engine1.memoryManager->m_pendingFreedObjectWrapperValue.size(), 1);
+
+ // engine2 doesn't own the object as engine1 was the first to wrap it above.
+ // Therefore, no effect here.
+diff --git a/qtdeclarative/tests/auto/quick/qquickitem2/data/activeFocusOnTab_infiniteLoop3.qml b/qtdeclarative/tests/auto/quick/qquickitem2/data/activeFocusOnTab_infiniteLoop3.qml
+new file mode 100644
+index 0000000000..889e480f3b
+--- /dev/null
++++ b/qtdeclarative/tests/auto/quick/qquickitem2/data/activeFocusOnTab_infiniteLoop3.qml
+@@ -0,0 +1,13 @@
++import QtQuick 2.6
++
++Item {
++ visible: true
++ Item {
++ visible: false
++ Item {
++ objectName: "hiddenChild"
++ activeFocusOnTab: true
++ focus: true
++ }
++ }
++}
+diff --git a/qtdeclarative/tests/auto/quick/qquickitem2/tst_qquickitem.cpp b/qtdeclarative/tests/auto/quick/qquickitem2/tst_qquickitem.cpp
+index c8f251dbe1..c8ef36ee68 100644
+--- a/qtdeclarative/tests/auto/quick/qquickitem2/tst_qquickitem.cpp
++++ b/qtdeclarative/tests/auto/quick/qquickitem2/tst_qquickitem.cpp
+@@ -67,6 +67,7 @@ private slots:
+ void activeFocusOnTab10();
+ void activeFocusOnTab_infiniteLoop_data();
+ void activeFocusOnTab_infiniteLoop();
++ void activeFocusOnTab_infiniteLoopControls();
+
+ void nextItemInFocusChain();
+ void nextItemInFocusChain2();
+@@ -1057,6 +1058,17 @@ void tst_QQuickItem::activeFocusOnTab_infiniteLoop()
+ QCOMPARE(item, window->rootObject());
+ }
+
++
++void tst_QQuickItem::activeFocusOnTab_infiniteLoopControls()
++{
++ auto source = testFileUrl("activeFocusOnTab_infiniteLoop3.qml");
++ QScopedPointer<QQuickView>window(new QQuickView());
++ window->setSource(source);
++ window->show();
++ QVERIFY(window->errors().isEmpty());
++ QTest::keyClick(window.get(), Qt::Key_Tab); // should not hang
++}
++
+ void tst_QQuickItem::nextItemInFocusChain()
+ {
+ if (!qt_tab_all_widgets())
+Submodule qtdoc c0c7bf07...79d6ef69:
+Submodule qtimageformats 2dcf2899..abe44c0f:
+diff --git a/qtimageformats/src/plugins/imageformats/icns/qicnshandler.cpp b/qtimageformats/src/plugins/imageformats/icns/qicnshandler.cpp
+index dde783c..1bf9074 100644
+--- a/qtimageformats/src/plugins/imageformats/icns/qicnshandler.cpp
++++ b/qtimageformats/src/plugins/imageformats/icns/qicnshandler.cpp
+@@ -462,8 +462,12 @@ static bool parseIconEntryInfo(ICNSEntry &icon)
+ if (isIconCompressed(icon))
+ return true;
+ // Icon depth:
+- if (!depth.isEmpty())
+- icon.depth = ICNSEntry::Depth(depth.toUInt());
++ if (!depth.isEmpty()) {
++ const uint depthUInt = depth.toUInt();
++ if (depthUInt > 32)
++ return false;
++ icon.depth = ICNSEntry::Depth(depthUInt);
++ }
+ // Try mono if depth not found
+ if (icon.depth == ICNSEntry::DepthUnknown)
+ icon.depth = ICNSEntry::DepthMono;
+@@ -515,6 +519,9 @@ static bool parseIconEntryInfo(ICNSEntry &icon)
+ }
+ icon.height = icon.width;
+ }
++ // Sanity check
++ if (icon.width == 0 || icon.width > 4096)
++ return false;
+ return true;
+ }
+
+@@ -685,7 +692,7 @@ bool QICNSHandler::canRead() const
+ bool QICNSHandler::read(QImage *outImage)
+ {
+ QImage img;
+- if (!ensureScanned()) {
++ if (!ensureScanned() || m_currentIconIndex >= m_icons.size()) {
+ qWarning("QICNSHandler::read(): The device wasn't parsed properly!");
+ return false;
+ }
+@@ -892,7 +899,7 @@ bool QICNSHandler::scanDevice()
+ return false;
+
+ const qint64 blockDataOffset = device()->pos();
+- if (!isBlockHeaderValid(blockHeader)) {
++ if (!isBlockHeaderValid(blockHeader, ICNSBlockHeaderSize + filelength - blockDataOffset)) {
+ qWarning("QICNSHandler::scanDevice(): Failed, bad header at pos %s. OSType \"%s\", length %u",
+ QByteArray::number(blockDataOffset).constData(),
+ nameFromOSType(blockHeader.ostype).constData(), blockHeader.length);
+@@ -927,11 +934,14 @@ bool QICNSHandler::scanDevice()
+ case ICNSBlockHeader::TypeOdrp:
+ // Icns container seems to have an embedded icon variant container
+ // Let's start a scan for entries
+- while (device()->pos() < nextBlockOffset) {
++ while (!stream.atEnd() && device()->pos() < nextBlockOffset) {
+ ICNSBlockHeader icon;
+ stream >> icon;
++ if (stream.status() != QDataStream::Ok)
++ return false;
+ // Check for incorrect variant entry header and stop scan
+- if (!isBlockHeaderValid(icon, blockDataLength))
++ quint64 remaining = blockDataLength - (device()->pos() - blockDataOffset);
++ if (!isBlockHeaderValid(icon, ICNSBlockHeaderSize + remaining))
+ break;
+ if (!addEntry(icon, device()->pos(), blockHeader.ostype))
+ return false;
+@@ -1003,7 +1013,7 @@ bool QICNSHandler::scanDevice()
+ break;
+ }
+ }
+- return true;
++ return (m_icons.size() > 0);
+ }
+
+ const ICNSEntry &QICNSHandler::getIconMask(const ICNSEntry &icon) const
+diff --git a/qtimageformats/src/plugins/imageformats/jp2/qjp2handler.cpp b/qtimageformats/src/plugins/imageformats/jp2/qjp2handler.cpp
+index 5082023..cb34374 100644
+--- a/qtimageformats/src/plugins/imageformats/jp2/qjp2handler.cpp
++++ b/qtimageformats/src/plugins/imageformats/jp2/qjp2handler.cpp
+@@ -43,6 +43,7 @@
+ #include "qimage.h"
+ #include "qvariant.h"
+ #include "qcolor.h"
++#include "qimagereader.h"
+
+ #include <jasper/jasper.h>
+ #include <math.h> // for pow
+@@ -333,16 +334,46 @@ private:
+ Jpeg2000JasperReader::Jpeg2000JasperReader(QIODevice *iod, SubFormat format)
+ : jasperOk(true), ioDevice(iod), format(format), hasAlpha(false)
+ {
++#if JAS_VERSION_MAJOR < 3
+ if (jas_init()) {
+ jasperOk = false;
+ qDebug("Jasper Library initialization failed");
+ }
++#else
++ jas_conf_clear();
++#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
++ jas_conf_set_max_mem_usage(QImageReader::allocationLimit() * 1024 * 1024);
++#else
++ // 128MB seems to be enough.
++ jas_conf_set_max_mem_usage(128 * 1024 * 1024);
++#endif
++ if (jas_init_library()) {
++ jasperOk = false;
++ qDebug("Jasper library initialization failed");
++ }
++ if (jas_init_thread()) {
++ jas_cleanup_library();
++ jasperOk = false;
++ qDebug("Jasper thread initialization failed");
++ }
++#endif
+ }
+
+ Jpeg2000JasperReader::~Jpeg2000JasperReader()
+ {
++#if JAS_VERSION_MAJOR < 3
+ if (jasperOk)
+ jas_cleanup();
++#else
++ if (jasperOk) {
++ if (jas_cleanup_thread()) {
++ qDebug("Jasper thread cleanup failed");
++ }
++ if (jas_cleanup_library()) {
++ qDebug("Jasper library cleanup failed");
++ }
++ }
++#endif
+ }
+
+ /*! \internal
+@@ -857,7 +888,7 @@ bool Jpeg2000JasperReader::write(const QImage &image, int quality)
+ }
+
+ // Open an empty jasper stream that grows automatically
+- jas_stream_t * memory_stream = jas_stream_memopen(0, -1);
++ jas_stream_t * memory_stream = jas_stream_memopen(0, 0);
+
+ // Jasper wants a non-const string.
+ char *str = qstrdup(jasperFormatString.toLatin1().constData());
+diff --git a/qtimageformats/src/plugins/imageformats/tiff/qtiffhandler.cpp b/qtimageformats/src/plugins/imageformats/tiff/qtiffhandler.cpp
+index 1386750..ac8956c 100644
+--- a/qtimageformats/src/plugins/imageformats/tiff/qtiffhandler.cpp
++++ b/qtimageformats/src/plugins/imageformats/tiff/qtiffhandler.cpp
+@@ -361,6 +361,8 @@ bool QTiffHandler::read(QImage *image)
+ }
+
+ TIFF *const tiff = d->tiff;
++ if (TIFFIsTiled(tiff) && TIFFTileSize64(tiff) > uint64_t(image->sizeInBytes())) // Corrupt image
++ return false;
+ const quint32 width = d->size.width();
+ const quint32 height = d->size.height();
+
+diff --git a/qtimageformats/src/plugins/imageformats/webp/qwebphandler.cpp b/qtimageformats/src/plugins/imageformats/webp/qwebphandler.cpp
+index 82d38cb..d02eb05 100644
+--- a/qtimageformats/src/plugins/imageformats/webp/qwebphandler.cpp
++++ b/qtimageformats/src/plugins/imageformats/webp/qwebphandler.cpp
+@@ -45,6 +45,7 @@
+ #include <qdebug.h>
+ #include <qpainter.h>
+ #include <qvariant.h>
++#include <QtEndian>
+
+ static const int riffHeaderSize = 12; // RIFF_HEADER_SIZE from webp/format_constants.h
+
+@@ -102,21 +103,23 @@ bool QWebpHandler::ensureScanned() const
+
+ m_scanState = ScanError;
+
+- if (device()->isSequential()) {
+- qWarning() << "Sequential devices are not supported";
++ QWebpHandler *that = const_cast<QWebpHandler *>(this);
++ const int headerBytesNeeded = sizeof(WebPBitstreamFeatures);
++ QByteArray header = device()->peek(headerBytesNeeded);
++ if (header.size() < headerBytesNeeded)
+ return false;
+- }
+
+- qint64 oldPos = device()->pos();
+- device()->seek(0);
+-
+- QWebpHandler *that = const_cast<QWebpHandler *>(this);
+- QByteArray header = device()->peek(sizeof(WebPBitstreamFeatures));
++ // We do no random access during decoding, just a readAll() of the whole image file. So if
++ // if it is all available already, we can accept a sequential device. The riff header contains
++ // the file size minus 8 bytes header
++ qint64 byteSize = qFromLittleEndian<quint32>(header.constData() + 4);
++ if (device()->isSequential() && device()->bytesAvailable() < byteSize + 8) {
++ qWarning() << "QWebpHandler: Insufficient data available in sequential device";
++ return false;
++ }
+ if (WebPGetFeatures((const uint8_t*)header.constData(), header.size(), &(that->m_features)) == VP8_STATUS_OK) {
+ if (m_features.has_animation) {
+ // For animation, we have to read and scan whole file to determine loop count and images count
+- device()->seek(oldPos);
+-
+ if (that->ensureDemuxer()) {
+ that->m_loop = WebPDemuxGetI(m_demuxer, WEBP_FF_LOOP_COUNT);
+ that->m_frameCount = WebPDemuxGetI(m_demuxer, WEBP_FF_FRAME_COUNT);
+@@ -126,17 +129,13 @@ bool QWebpHandler::ensureScanned() const
+ if (that->m_features.has_alpha)
+ that->m_composited->fill(Qt::transparent);
+
+- // We do not reset device position since we have read in all data
+ m_scanState = ScanSuccess;
+- return true;
+ }
+ } else {
+ m_scanState = ScanSuccess;
+ }
+ }
+
+- device()->seek(oldPos);
+-
+ return m_scanState == ScanSuccess;
+ }
+
+@@ -159,7 +158,7 @@ bool QWebpHandler::ensureDemuxer()
+
+ bool QWebpHandler::read(QImage *image)
+ {
+- if (!ensureScanned() || device()->isSequential() || !ensureDemuxer())
++ if (!ensureScanned() || !ensureDemuxer())
+ return false;
+
+ QRect prevFrameRect;
+Submodule qtlocation 98a5c511..f991e28c:
+diff --git a/qtlocation/src/location/configure.json b/qtlocation/src/location/configure.json
+index 6d01a9a3..d1e623a1 100644
+--- a/qtlocation/src/location/configure.json
++++ b/qtlocation/src/location/configure.json
+@@ -9,7 +9,7 @@
+ "label": "Qt.labs.location experimental QML plugin",
+ "purpose": "Provides experimental QtLocation QML types",
+ "section": "Location",
+- "condition": "config.opengl",
++ "condition": "features.opengl",
+ "output": [ "privateFeature" ]
+ },
+ "geoservices_osm": {
+diff --git a/qtlocation/src/location/labs/qsg/qgeomapobjectqsgsupport.cpp b/qtlocation/src/location/labs/qsg/qgeomapobjectqsgsupport.cpp
+index a978573d..11e1466f 100644
+--- a/qtlocation/src/location/labs/qsg/qgeomapobjectqsgsupport.cpp
++++ b/qtlocation/src/location/labs/qsg/qgeomapobjectqsgsupport.cpp
+@@ -158,7 +158,7 @@ void QGeoMapObjectQSGSupport::updateMapObjects(QSGNode *root, QQuickWindow *wind
+ if (!root)
+ return;
+
+- if (m_mapObjectsRootNode && m_mapObjectsRootNode->parent())
++ if (m_mapObjectsRootNode && !m_mapObjectsRootNode->parent())
+ root->appendChildNode(m_mapObjectsRootNode.get());
+
+ if (!m_mapObjectsRootNode) {
+diff --git a/qtlocation/src/plugins/geoservices/esri/geocodingmanagerengine_esri.cpp b/qtlocation/src/plugins/geoservices/esri/geocodingmanagerengine_esri.cpp
+index 5a40467e..d123c6a8 100644
+--- a/qtlocation/src/plugins/geoservices/esri/geocodingmanagerengine_esri.cpp
++++ b/qtlocation/src/plugins/geoservices/esri/geocodingmanagerengine_esri.cpp
+@@ -59,8 +59,10 @@ QT_BEGIN_NAMESPACE
+ static const QString kPrefixEsri(QStringLiteral("esri."));
+ static const QString kParamUserAgent(kPrefixEsri + QStringLiteral("useragent"));
+
+-static const QString kUrlGeocode(QStringLiteral("http://geocode.arcgis.com/arcgis/rest/services/World/GeocodeServer/findAddressCandidates"));
+-static const QString kUrlReverseGeocode(QStringLiteral("http://geocode.arcgis.com/arcgis/rest/services/World/GeocodeServer/reverseGeocode"));
++static const QString kUrlGeocode(QStringLiteral("https://geocode.arcgis.com/arcgis/rest/services/"
++ "World/GeocodeServer/findAddressCandidates"));
++static const QString kUrlReverseGeocode(QStringLiteral(
++ "https://geocode.arcgis.com/arcgis/rest/services/World/GeocodeServer/reverseGeocode"));
+
+ static QString addressToQuery(const QGeoAddress &address)
+ {
+diff --git a/qtlocation/src/plugins/geoservices/esri/georoutejsonparser_esri.cpp b/qtlocation/src/plugins/geoservices/esri/georoutejsonparser_esri.cpp
+index 17492d94..96c12b1b 100644
+--- a/qtlocation/src/plugins/geoservices/esri/georoutejsonparser_esri.cpp
++++ b/qtlocation/src/plugins/geoservices/esri/georoutejsonparser_esri.cpp
+@@ -46,7 +46,8 @@
+
+ QT_BEGIN_NAMESPACE
+
+-// JSON reference: http://resources.arcgis.com/en/help/arcgis-rest-api/#/Route_service_with_synchronous_execution/02r300000036000000/
++// JSON reference:
++// https://resources.arcgis.com/en/help/arcgis-rest-api/#/Route_service_with_synchronous_execution/02r300000036000000/
+
+ static const QString kErrorMessage(QStringLiteral("Error %1: %2."));
+ static const QString kErrorJson(QStringLiteral("Error: invalide JSON document."));
+diff --git a/qtlocation/src/plugins/geoservices/esri/georoutereply_esri.cpp b/qtlocation/src/plugins/geoservices/esri/georoutereply_esri.cpp
+index 8cadfb29..92b6bb13 100644
+--- a/qtlocation/src/plugins/geoservices/esri/georoutereply_esri.cpp
++++ b/qtlocation/src/plugins/geoservices/esri/georoutereply_esri.cpp
+@@ -44,7 +44,8 @@
+
+ QT_BEGIN_NAMESPACE
+
+-// JSON reference: http://resources.arcgis.com/en/help/arcgis-rest-api/#/Route_service_with_synchronous_execution/02r300000036000000/
++// JSON reference:
++// https://resources.arcgis.com/en/help/arcgis-rest-api/#/Route_service_with_synchronous_execution/02r300000036000000/
+
+ GeoRouteReplyEsri::GeoRouteReplyEsri(QNetworkReply *reply, const QGeoRouteRequest &request,
+ QObject *parent) :
+diff --git a/qtlocation/src/plugins/geoservices/esri/georoutingmanagerengine_esri.cpp b/qtlocation/src/plugins/geoservices/esri/georoutingmanagerengine_esri.cpp
+index 0e6bc2c7..ed613f4b 100644
+--- a/qtlocation/src/plugins/geoservices/esri/georoutingmanagerengine_esri.cpp
++++ b/qtlocation/src/plugins/geoservices/esri/georoutingmanagerengine_esri.cpp
+@@ -48,7 +48,8 @@ static const QString kPrefixEsri(QStringLiteral("esri."));
+ static const QString kParamUserAgent(kPrefixEsri + QStringLiteral("useragent"));
+ static const QString kParamToken(kPrefixEsri + QStringLiteral("token"));
+
+-static const QString kUrlRouting(QStringLiteral("http://route.arcgis.com/arcgis/rest/services/World/Route/NAServer/Route_World/solve"));
++static const QString kUrlRouting(QStringLiteral(
++ "https://route.arcgis.com/arcgis/rest/services/World/Route/NAServer/Route_World/solve"));
+
+ GeoRoutingManagerEngineEsri::GeoRoutingManagerEngineEsri(const QVariantMap ¶meters,
+ QGeoServiceProvider::Error *error,
+@@ -70,7 +71,8 @@ GeoRoutingManagerEngineEsri::~GeoRoutingManagerEngineEsri()
+ {
+ }
+
+-// REST reference: http://resources.arcgis.com/en/help/arcgis-rest-api/index.html#//02r300000036000000
++// REST reference:
++// https://resources.arcgis.com/en/help/arcgis-rest-api/index.html#//02r300000036000000
+
+ QGeoRouteReply *GeoRoutingManagerEngineEsri::calculateRoute(const QGeoRouteRequest &request)
+ {
+@@ -125,7 +127,7 @@ void GeoRoutingManagerEngineEsri::replyError(QGeoRouteReply::Error errorCode, co
+ QString GeoRoutingManagerEngineEsri::preferedDirectionLangage()
+ {
+ // list of supported langages is defined in:
+- // http://resources.arcgis.com/en/help/arcgis-rest-api/index.html#//02r300000036000000
++ // https://resources.arcgis.com/en/help/arcgis-rest-api/index.html#//02r300000036000000
+ const QStringList supportedLanguages = {
+ "ar", // Generate directions in Arabic
+ "cs", // Generate directions in Czech
+diff --git a/qtlocation/src/plugins/geoservices/esri/geotiledmappingmanagerengine_esri.cpp b/qtlocation/src/plugins/geoservices/esri/geotiledmappingmanagerengine_esri.cpp
+index 5d15835d..24148f95 100644
+--- a/qtlocation/src/plugins/geoservices/esri/geotiledmappingmanagerengine_esri.cpp
++++ b/qtlocation/src/plugins/geoservices/esri/geotiledmappingmanagerengine_esri.cpp
+@@ -230,7 +230,8 @@ QGeoMap *GeoTiledMappingManagerEngineEsri::createMap()
+ // ${y} = Y
+ // ${token} = Token
+
+-// template = 'http://services.arcgisonline.com/ArcGIS/rest/services/World_Topo_Map/MapServer/tile/{{z}}/{{y}}/{{x}}.png'
++// template =
++// 'https://services.arcgisonline.com/ArcGIS/rest/services/World_Topo_Map/MapServer/tile/{{z}}/{{y}}/{{x}}.png'
+
+ bool GeoTiledMappingManagerEngineEsri::initializeMapSources(QGeoServiceProvider::Error *error,
+ QString *errorString,
+diff --git a/qtlocation/src/plugins/geoservices/esri/maps.json b/qtlocation/src/plugins/geoservices/esri/maps.json
+index 8167ae7d..862e087d 100644
+--- a/qtlocation/src/plugins/geoservices/esri/maps.json
++++ b/qtlocation/src/plugins/geoservices/esri/maps.json
+@@ -6,8 +6,8 @@
+ "description": "ArcGIS Online World Street Map",
+ "mobile": true,
+ "night": false,
+- "url": "http://services.arcgisonline.com/ArcGIS/rest/services/World_Street_Map/MapServer",
+- "copyrightText": "© <a href='http://www.arcgis.com/home/item.html?id=3b93337983e9436f8db950e38a8629af'>Esri</a> contributors"
++ "url": "https://services.arcgisonline.com/ArcGIS/rest/services/World_Street_Map/MapServer",
++ "copyrightText": "© <a href='https://www.arcgis.com/home/item.html?id=3b93337983e9436f8db950e38a8629af'>Esri</a> contributors"
+ },
+
+ {
+@@ -16,8 +16,8 @@
+ "": "ArcGIS Online World Imagery",
+ "mobile": true,
+ "night": false,
+- "url": "http://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer",
+- "copyrightText": "© <a href='http://www.arcgis.com/home/item.html?id=10df2279f9684e4a9f6a7f08febac2a9'>Esri</a> contributors"
++ "url": "https://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer",
++ "copyrightText": "© <a href='https://www.arcgis.com/home/item.html?id=10df2279f9684e4a9f6a7f08febac2a9'>Esri</a> contributors"
+ },
+
+ {
+@@ -26,8 +26,8 @@
+ "description": "ArcGIS Online World Terrain Base",
+ "mobile": false,
+ "night": false,
+- "url": "http://server.arcgisonline.com/ArcGIS/rest/services/World_Terrain_Base/MapServer",
+- "copyrightText": "© <a href='http://www.arcgis.com/home/item.html?id=c61ad8ab017d49e1a82f580ee1298931'>Esri</a> contributors"
++ "url": "https://server.arcgisonline.com/ArcGIS/rest/services/World_Terrain_Base/MapServer",
++ "copyrightText": "© <a href='https://www.arcgis.com/home/item.html?id=c61ad8ab017d49e1a82f580ee1298931'>Esri</a> contributors"
+ },
+
+ {
+@@ -36,8 +36,8 @@
+ "description": "ArcGIS Online World Topography",
+ "mobile": true,
+ "night": false,
+- "url": "http://server.arcgisonline.com/ArcGIS/rest/services/World_Topo_Map/MapServer",
+- "copyrightText": "© <a href='http://www.arcgis.com/home/item.html?id=30e5fe3149c34df1ba922e6f5bbf808f'>Esri</a> contributors"
++ "url": "https://server.arcgisonline.com/ArcGIS/rest/services/World_Topo_Map/MapServer",
++ "copyrightText": "© <a href='https://www.arcgis.com/home/item.html?id=30e5fe3149c34df1ba922e6f5bbf808f'>Esri</a> contributors"
+ },
+
+ {
+@@ -46,8 +46,8 @@
+ "description": "This map presents land cover and detailed topographic maps for the United States.",
+ "mobile": true,
+ "night": false,
+- "url": "http://services.arcgisonline.com/ArcGIS/rest/services/USA_Topo_Maps/MapServer",
+- "copyrightText": "© <a href='http://www.arcgis.com/home/item.html?id=99cd5fbd98934028802b4f797c4b1732'>Esri</a> contributors"
++ "url": "https://services.arcgisonline.com/ArcGIS/rest/services/USA_Topo_Maps/MapServer",
++ "copyrightText": "© <a href='https://www.arcgis.com/home/item.html?id=99cd5fbd98934028802b4f797c4b1732'>Esri</a> contributors"
+ },
+
+ {
+@@ -56,8 +56,8 @@
+ "description": "National Geographic World Map",
+ "mobile": false,
+ "night": false,
+- "url": "http://services.arcgisonline.com/ArcGIS/rest/services/NatGeo_World_Map/MapServer",
+- "copyrightText": "© <a href='http://www.arcgis.com/home/item.html?id=b9b1b422198944fbbd5250b3241691b6'>Esri</a> contributors"
++ "url": "https://services.arcgisonline.com/ArcGIS/rest/services/NatGeo_World_Map/MapServer",
++ "copyrightText": "© <a href='https://www.arcgis.com/home/item.html?id=b9b1b422198944fbbd5250b3241691b6'>Esri</a> contributors"
+ },
+
+ {
+@@ -66,8 +66,8 @@
+ "description": "Thematic content providing a neutral background with minimal colors",
+ "mobile": true,
+ "night": false,
+- "url": "http://services.arcgisonline.com/ArcGIS/rest/services/Canvas/World_Light_Gray_Base/MapServer",
+- "copyrightText": "© <a href='http://www.arcgis.com/home/item.html?id=ed712cb1db3e4bae9e85329040fb9a49'>Esri</a> contributors"
++ "url": "https://services.arcgisonline.com/ArcGIS/rest/services/Canvas/World_Light_Gray_Base/MapServer",
++ "copyrightText": "© <a href='https://www.arcgis.com/home/item.html?id=ed712cb1db3e4bae9e85329040fb9a49'>Esri</a> contributors"
+ },
+
+ {
+@@ -76,8 +76,8 @@
+ "description": "Natural Earth physical map for the world",
+ "mobile": false,
+ "night": false,
+- "url": "http://server.arcgisonline.com/ArcGIS/rest/services/World_Physical_Map/MapServer",
+- "copyrightText": "© <a href='http://www.arcgis.com/home/item.html?id=c4ec722a1cd34cf0a23904aadf8923a0'>Esri</a> contributors"
++ "url": "https://server.arcgisonline.com/ArcGIS/rest/services/World_Physical_Map/MapServer",
++ "copyrightText": "© <a href='https://www.arcgis.com/home/item.html?id=c4ec722a1cd34cf0a23904aadf8923a0'>Esri</a> contributors"
+ },
+
+ {
+@@ -86,8 +86,8 @@
+ "description": "Portrays surface elevation as shaded relief",
+ "mobile": false,
+ "night": false,
+- "url": "http://server.arcgisonline.com/ArcGIS/rest/services/World_Shaded_Relief/MapServer",
+- "copyrightText": "© <a href='http://www.arcgis.com/home/item.html?id=9c5370d0b54f4de1b48a3792d7377ff2'>Esri</a> contributors"
++ "url": "https://server.arcgisonline.com/ArcGIS/rest/services/World_Shaded_Relief/MapServer",
++ "copyrightText": "© <a href='https://www.arcgis.com/home/item.html?id=9c5370d0b54f4de1b48a3792d7377ff2'>Esri</a> contributors"
+ },
+
+ {
+@@ -96,8 +96,8 @@
+ "description": "This map is designed to be used as a basemap by marine GIS professionals and as a reference map by anyone interested in ocean data",
+ "mobile": false,
+ "night": false,
+- "url": "http://server.arcgisonline.com/arcgis/rest/services/Ocean/World_Ocean_Base/MapServer",
+- "copyrightText": "© <a href='http://www.arcgis.com/home/item.html?id=1e126e7520f9466c9ca28b8f28b5e500'>Esri</a> contributors"
++ "url": "https://server.arcgisonline.com/arcgis/rest/services/Ocean/World_Ocean_Base/MapServer",
++ "copyrightText": "© <a href='https://www.arcgis.com/home/item.html?id=1e126e7520f9466c9ca28b8f28b5e500'>Esri</a> contributors"
+ },
+
+ {
+@@ -106,8 +106,8 @@
+ "description": "Thematic content providing a neutral background with minimal colors",
+ "mobile": false,
+ "night": true,
+- "url": "http://services.arcgisonline.com/ArcGIS/rest/services/Canvas/World_Dark_Gray_Base/MapServer",
+- "copyrightText": "© <a href='http://www.arcgis.com/home/item.html?id=a284a9b99b3446a3910d4144a50990f6'>Esri</a> contributors"
++ "url": "https://services.arcgisonline.com/ArcGIS/rest/services/Canvas/World_Dark_Gray_Base/MapServer",
++ "copyrightText": "© <a href='https://www.arcgis.com/home/item.html?id=a284a9b99b3446a3910d4144a50990f6'>Esri</a> contributors"
+ },
+
+ {
+@@ -116,8 +116,8 @@
+ "description": "DeLorme’s topographic basemap is a seamless global data set that portrays transportation, hydrography, jurisdiction boundaries, and major geographic features",
+ "mobile": false,
+ "night": false,
+- "url": "http://server.arcgisonline.com/ArcGIS/rest/services/Specialty/DeLorme_World_Base_Map/MapServer",
+- "copyrightText": "© <a href='http://www.arcgis.com/home/item.html?id=b165c3df453e4be6b5ac4fdb241effbe'>Esri</a> contributors"
++ "url": "https://server.arcgisonline.com/ArcGIS/rest/services/Specialty/DeLorme_World_Base_Map/MapServer",
++ "copyrightText": "© <a href='https://www.arcgis.com/home/item.html?id=b165c3df453e4be6b5ac4fdb241effbe'>Esri</a> contributors"
+ }
+ ]
+ }
+diff --git a/qtlocation/src/plugins/geoservices/esri/placemanagerengine_esri.cpp b/qtlocation/src/plugins/geoservices/esri/placemanagerengine_esri.cpp
+index 3858ddf5..af66f28e 100644
+--- a/qtlocation/src/plugins/geoservices/esri/placemanagerengine_esri.cpp
++++ b/qtlocation/src/plugins/geoservices/esri/placemanagerengine_esri.cpp
+@@ -63,8 +63,10 @@ static const QString kCountriesKey(QStringLiteral("detailedCountries"));
+ static const QString kLocalizedNamesKey(QStringLiteral("localizedNames"));
+ static const QString kMaxLocationsKey(QStringLiteral("maxLocations"));
+
+-static const QUrl kUrlGeocodeServer("http://geocode.arcgis.com/arcgis/rest/services/World/GeocodeServer?f=pjson");
+-static const QUrl kUrlFindAddressCandidates("http://geocode.arcgis.com/arcgis/rest/services/World/GeocodeServer/findAddressCandidates");
++static const QUrl kUrlGeocodeServer(
++ "https://geocode.arcgis.com/arcgis/rest/services/World/GeocodeServer?f=pjson");
++static const QUrl kUrlFindAddressCandidates("https://geocode.arcgis.com/arcgis/rest/services/World/"
++ "GeocodeServer/findAddressCandidates");
+
+ PlaceManagerEngineEsri::PlaceManagerEngineEsri(const QVariantMap ¶meters, QGeoServiceProvider::Error *error,
+ QString *errorString) :
+Submodule qtmultimedia f0344079..0d7cc33a:
+diff --git a/qtmultimedia/src/plugins/pulseaudio/qaudioinput_pulse.cpp b/qtmultimedia/src/plugins/pulseaudio/qaudioinput_pulse.cpp
+index 2b5325132..b68b4af1b 100644
+--- a/qtmultimedia/src/plugins/pulseaudio/qaudioinput_pulse.cpp
++++ b/qtmultimedia/src/plugins/pulseaudio/qaudioinput_pulse.cpp
+@@ -402,6 +402,8 @@ int QPulseAudioInput::bytesReady() const
+
+ qint64 QPulseAudioInput::read(char *data, qint64 len)
+ {
++ Q_ASSERT(data != nullptr || len == 0);
++
+ m_bytesAvailable = checkBytesReady();
+
+ setError(QAudio::NoError);
+@@ -411,7 +413,8 @@ qint64 QPulseAudioInput::read(char *data, qint64 len)
+
+ if (!m_pullMode && !m_tempBuffer.isEmpty()) {
+ readBytes = qMin(static_cast<int>(len), m_tempBuffer.size());
+- memcpy(data, m_tempBuffer.constData(), readBytes);
++ if (readBytes)
++ memcpy(data, m_tempBuffer.constData(), readBytes);
+ m_totalTimeValue += readBytes;
+
+ if (readBytes < m_tempBuffer.size()) {
+@@ -502,9 +505,10 @@ qint64 QPulseAudioInput::read(char *data, qint64 len)
+
+ void QPulseAudioInput::applyVolume(const void *src, void *dest, int len)
+ {
++ Q_ASSERT((src && dest) || len == 0);
+ if (m_volume < 1.f)
+ QAudioHelperInternal::qMultiplySamples(m_volume, m_format, src, dest, len);
+- else
++ else if (len)
+ memcpy(dest, src, len);
+ }
+
+Submodule qtpim 02efef5e...f9a8f0fc (commits not present)
+Submodule qtquick3d b85cf622..47defc8b:
+diff --git a/qtquick3d/src/plugins/assetimporters/assimp/assimp.pro b/qtquick3d/src/plugins/assetimporters/assimp/assimp.pro
+index ca5c499e..174a075b 100644
+--- a/qtquick3d/src/plugins/assetimporters/assimp/assimp.pro
++++ b/qtquick3d/src/plugins/assetimporters/assimp/assimp.pro
+@@ -10,7 +10,7 @@ QT_FOR_CONFIG += assetimporters-private
+ include($$OUT_PWD/../qtassetimporters-config.pri)
+
+ qtConfig(system-assimp):!if(cross_compile:host_build) {
+- QMAKE_USE_PRIVATE += assimp
++ QMAKE_USE_PRIVATE += quick3d-assimp
+ } else {
+ include(../../../3rdparty/assimp/assimp.pri)
+ }
+Submodule qtquickcontrols2 3a657dc0..56ce8233:
+diff --git a/qtquickcontrols2/src/imports/platform/widgets/qwidgetplatformmenu.cpp b/qtquickcontrols2/src/imports/platform/widgets/qwidgetplatformmenu.cpp
+index e5fe734f7..e36922775 100644
+--- a/qtquickcontrols2/src/imports/platform/widgets/qwidgetplatformmenu.cpp
++++ b/qtquickcontrols2/src/imports/platform/widgets/qwidgetplatformmenu.cpp
+@@ -38,6 +38,7 @@
+ #include "qwidgetplatformmenuitem_p.h"
+
+ #include <QtGui/qwindow.h>
++#include <QtGui/private/qhighdpiscaling_p.h>
+ #include <QtWidgets/qmenu.h>
+ #include <QtWidgets/qaction.h>
+
+@@ -145,7 +146,7 @@ void QWidgetPlatformMenu::showPopup(const QWindow *window, const QRect &targetRe
+
+ QPoint targetPos = targetRect.bottomLeft();
+ if (window)
+- targetPos = window->mapToGlobal(targetPos);
++ targetPos = window->mapToGlobal(QHighDpi::fromNativeLocalPosition(targetPos, window));
+
+ const QWidgetPlatformMenuItem *widgetItem = qobject_cast<const QWidgetPlatformMenuItem *>(item);
+ m_menu->popup(targetPos, widgetItem ? widgetItem->action() : nullptr);
+diff --git a/qtquickcontrols2/src/quicktemplates2/qquickabstractbutton.cpp b/qtquickcontrols2/src/quicktemplates2/qquickabstractbutton.cpp
+index 950e4e099..b81fbea0b 100644
+--- a/qtquickcontrols2/src/quicktemplates2/qquickabstractbutton.cpp
++++ b/qtquickcontrols2/src/quicktemplates2/qquickabstractbutton.cpp
+@@ -387,6 +387,17 @@ void QQuickAbstractButtonPrivate::itemImplicitHeightChanged(QQuickItem *item)
+ emit q->implicitIndicatorHeightChanged();
+ }
+
++void QQuickAbstractButtonPrivate::itemDestroyed(QQuickItem *item)
++{
++ Q_Q(QQuickAbstractButton);
++ QQuickControlPrivate::itemDestroyed(item);
++ if (item == indicator) {
++ indicator = nullptr;
++ emit q->implicitIndicatorWidthChanged();
++ emit q->implicitIndicatorHeightChanged();
++ }
++}
++
+ QQuickAbstractButton *QQuickAbstractButtonPrivate::findCheckedButton() const
+ {
+ Q_Q(const QQuickAbstractButton);
+@@ -1176,6 +1187,12 @@ QAccessible::Role QQuickAbstractButton::accessibleRole() const
+ }
+ return QAccessible::Button;
+ }
++
++void QQuickAbstractButton::accessiblePressAction()
++{
++ Q_D(QQuickAbstractButton);
++ d->trigger();
++}
+ #endif
+
+ QT_END_NAMESPACE
+diff --git a/qtquickcontrols2/src/quicktemplates2/qquickabstractbutton_p.h b/qtquickcontrols2/src/quicktemplates2/qquickabstractbutton_p.h
+index 0fa48980e..ab66220d0 100644
+--- a/qtquickcontrols2/src/quicktemplates2/qquickabstractbutton_p.h
++++ b/qtquickcontrols2/src/quicktemplates2/qquickabstractbutton_p.h
+@@ -209,6 +209,7 @@ protected:
+ #if QT_CONFIG(accessibility)
+ void accessibilityActiveChanged(bool active) override;
+ QAccessible::Role accessibleRole() const override;
++ Q_INVOKABLE void accessiblePressAction();
+ #endif
+
+ private:
+diff --git a/qtquickcontrols2/src/quicktemplates2/qquickabstractbutton_p_p.h b/qtquickcontrols2/src/quicktemplates2/qquickabstractbutton_p_p.h
+index 9291c1a87..b729720f2 100644
+--- a/qtquickcontrols2/src/quicktemplates2/qquickabstractbutton_p_p.h
++++ b/qtquickcontrols2/src/quicktemplates2/qquickabstractbutton_p_p.h
+@@ -109,6 +109,7 @@ public:
+
+ void itemImplicitWidthChanged(QQuickItem *item) override;
+ void itemImplicitHeightChanged(QQuickItem *item) override;
++ void itemDestroyed(QQuickItem *item) override;
+
+ // copied from qabstractbutton.cpp
+ static const int AUTO_REPEAT_DELAY = 300;
+diff --git a/qtquickcontrols2/src/quicktemplates2/qquickaction.cpp b/qtquickcontrols2/src/quicktemplates2/qquickaction.cpp
+index 2041e7741..8610cdfae 100644
+--- a/qtquickcontrols2/src/quicktemplates2/qquickaction.cpp
++++ b/qtquickcontrols2/src/quicktemplates2/qquickaction.cpp
+@@ -145,7 +145,7 @@ int QQuickActionPrivate::ShortcutEntry::shortcutId() const
+
+ void QQuickActionPrivate::ShortcutEntry::grab(const QKeySequence &shortcut, bool enabled)
+ {
+- if (shortcut.isEmpty())
++ if (shortcut.isEmpty() || m_shortcutId)
+ return;
+
+ Qt::ShortcutContext context = Qt::WindowShortcut; // TODO
+diff --git a/qtquickcontrols2/src/quicktemplates2/qquickcontainer.cpp b/qtquickcontrols2/src/quicktemplates2/qquickcontainer.cpp
+index f38c2b09c..6eed2a024 100644
+--- a/qtquickcontrols2/src/quicktemplates2/qquickcontainer.cpp
++++ b/qtquickcontrols2/src/quicktemplates2/qquickcontainer.cpp
+@@ -225,6 +225,7 @@ void QQuickContainerPrivate::cleanup()
+ QObject::disconnect(contentModel, &QQmlObjectModel::countChanged, q, &QQuickContainer::countChanged);
+ QObject::disconnect(contentModel, &QQmlObjectModel::childrenChanged, q, &QQuickContainer::contentChildrenChanged);
+ delete contentModel;
++ contentModel = nullptr;
+ }
+
+ QQuickItem *QQuickContainerPrivate::itemAt(int index) const
+@@ -436,7 +437,7 @@ void QQuickContainerPrivate::contentChildren_clear(QQmlListProperty<QQuickItem>
+ void QQuickContainerPrivate::updateContentWidth()
+ {
+ Q_Q(QQuickContainer);
+- if (hasContentWidth || qFuzzyCompare(contentWidth, implicitContentWidth))
++ if (hasContentWidth || qFuzzyCompare(contentWidth, implicitContentWidth) || !contentModel)
+ return;
+
+ contentWidth = implicitContentWidth;
+@@ -446,7 +447,7 @@ void QQuickContainerPrivate::updateContentWidth()
+ void QQuickContainerPrivate::updateContentHeight()
+ {
+ Q_Q(QQuickContainer);
+- if (hasContentHeight || qFuzzyCompare(contentHeight, implicitContentHeight))
++ if (hasContentHeight || qFuzzyCompare(contentHeight, implicitContentHeight) || !contentModel)
+ return;
+
+ contentHeight = implicitContentHeight;
+diff --git a/qtquickcontrols2/src/quicktemplates2/qquickcontrol.cpp b/qtquickcontrols2/src/quicktemplates2/qquickcontrol.cpp
+index bbbd0e622..1f4b47343 100644
+--- a/qtquickcontrols2/src/quicktemplates2/qquickcontrol.cpp
++++ b/qtquickcontrols2/src/quicktemplates2/qquickcontrol.cpp
+@@ -845,6 +845,13 @@ void QQuickControlPrivate::executeBackground(bool complete)
+ quickCompleteDeferred(q, backgroundName(), background);
+ }
+
++/*
++ \internal
++
++ Hides an item that was replaced by a newer one, rather than
++ deleting it, as the item is typically created in QML and hence
++ we don't own it.
++*/
+ void QQuickControlPrivate::hideOldItem(QQuickItem *item)
+ {
+ if (!item)
+@@ -863,6 +870,29 @@ void QQuickControlPrivate::hideOldItem(QQuickItem *item)
+ #endif
+ }
+
++/*
++ \internal
++
++ Named "unhide" because it's used for cases where an item
++ that was previously hidden by \l hideOldItem() wants to be
++ shown by a control again, such as a ScrollBar in ScrollView.
++*/
++void QQuickControlPrivate::unhideOldItem(QQuickControl *control, QQuickItem *item)
++{
++ Q_ASSERT(item);
++ qCDebug(lcItemManagement) << "unhiding old item" << item;
++
++ item->setVisible(true);
++ item->setParentItem(control);
++
++#if QT_CONFIG(accessibility)
++ // Add the item back in to the accessibility tree.
++ QQuickAccessibleAttached *accessible = accessibleAttached(item);
++ if (accessible)
++ accessible->setIgnored(false);
++#endif
++}
++
+ void QQuickControlPrivate::updateBaselineOffset()
+ {
+ Q_Q(QQuickControl);
+diff --git a/qtquickcontrols2/src/quicktemplates2/qquickcontrol_p_p.h b/qtquickcontrols2/src/quicktemplates2/qquickcontrol_p_p.h
+index 8e979079e..a6e624c91 100644
+--- a/qtquickcontrols2/src/quicktemplates2/qquickcontrol_p_p.h
++++ b/qtquickcontrols2/src/quicktemplates2/qquickcontrol_p_p.h
+@@ -173,6 +173,7 @@ public:
+ virtual void executeBackground(bool complete = false);
+
+ static void hideOldItem(QQuickItem *item);
++ static void unhideOldItem(QQuickControl *control, QQuickItem *item);
+
+ void updateBaselineOffset();
+
+diff --git a/qtquickcontrols2/src/quicktemplates2/qquickdialogbuttonbox.cpp b/qtquickcontrols2/src/quicktemplates2/qquickdialogbuttonbox.cpp
+index e6db14eb5..6197d1547 100644
+--- a/qtquickcontrols2/src/quicktemplates2/qquickdialogbuttonbox.cpp
++++ b/qtquickcontrols2/src/quicktemplates2/qquickdialogbuttonbox.cpp
+@@ -237,7 +237,7 @@ static QRectF alignedRect(Qt::LayoutDirection direction, Qt::Alignment alignment
+ void QQuickDialogButtonBoxPrivate::resizeContent()
+ {
+ Q_Q(QQuickDialogButtonBox);
+- if (!contentItem)
++ if (!contentItem || !contentModel)
+ return;
+
+ QRectF geometry = q->boundingRect().adjusted(q->leftPadding(), q->topPadding(), -q->rightPadding(), -q->bottomPadding());
+@@ -322,6 +322,9 @@ void QQuickDialogButtonBoxPrivate::updateLayout()
+ qreal QQuickDialogButtonBoxPrivate::getContentWidth() const
+ {
+ Q_Q(const QQuickDialogButtonBox);
++ if (!contentModel)
++ return 0;
++
+ const int count = contentModel->count();
+ const qreal totalSpacing = qMax(0, count - 1) * spacing;
+ qreal totalWidth = totalSpacing;
+@@ -341,6 +344,9 @@ qreal QQuickDialogButtonBoxPrivate::getContentWidth() const
+ qreal QQuickDialogButtonBoxPrivate::getContentHeight() const
+ {
+ Q_Q(const QQuickDialogButtonBox);
++ if (!contentModel)
++ return 0;
++
+ const int count = contentModel->count();
+ qreal maxHeight = 0;
+ for (int i = 0; i < count; ++i) {
+diff --git a/qtquickcontrols2/src/quicktemplates2/qquickoverlay.cpp b/qtquickcontrols2/src/quicktemplates2/qquickoverlay.cpp
+index 91bd59184..0ce518f84 100644
+--- a/qtquickcontrols2/src/quicktemplates2/qquickoverlay.cpp
++++ b/qtquickcontrols2/src/quicktemplates2/qquickoverlay.cpp
+@@ -399,8 +399,11 @@ void QQuickOverlay::itemChange(ItemChange change, const ItemChangeData &data)
+ Q_D(QQuickOverlay);
+ QQuickItem::itemChange(change, data);
+
+- if (change == ItemChildAddedChange || change == ItemChildRemovedChange)
++ if (change == ItemChildAddedChange || change == ItemChildRemovedChange) {
+ setVisible(!d->allDrawers.isEmpty() || !childItems().isEmpty());
++ if (data.item->parent() == d->mouseGrabberPopup)
++ d->setMouseGrabberPopup(nullptr);
++ }
+ }
+
+ void QQuickOverlay::geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry)
+diff --git a/qtquickcontrols2/src/quicktemplates2/qquickscrollbar.cpp b/qtquickcontrols2/src/quicktemplates2/qquickscrollbar.cpp
+index 4e2f509db..1c4b308cd 100644
+--- a/qtquickcontrols2/src/quicktemplates2/qquickscrollbar.cpp
++++ b/qtquickcontrols2/src/quicktemplates2/qquickscrollbar.cpp
+@@ -797,6 +797,14 @@ void QQuickScrollBarAttachedPrivate::initHorizontal()
+ if (parent && parent == flickable->parentItem())
+ horizontal->stackAfter(flickable);
+
++ // If a scroll bar was previously hidden (due to e.g. setting a new contentItem
++ // on a ScrollView), we need to make sure that we un-hide it.
++ // We don't bother checking if the item is actually the old one, because
++ // if it's not, all of the things the function does (setting parent, visibility, etc.)
++ // should be no-ops anyway.
++ if (auto control = qobject_cast<QQuickControl*>(q_ptr->parent()))
++ QQuickControlPrivate::unhideOldItem(control, horizontal);
++
+ layoutHorizontal();
+ horizontal->setSize(area->property("widthRatio").toReal());
+ horizontal->setPosition(area->property("xPosition").toReal());
+@@ -818,6 +826,9 @@ void QQuickScrollBarAttachedPrivate::initVertical()
+ if (parent && parent == flickable->parentItem())
+ vertical->stackAfter(flickable);
+
++ if (auto control = qobject_cast<QQuickControl*>(q_ptr->parent()))
++ QQuickControlPrivate::unhideOldItem(control, vertical);
++
+ layoutVertical();
+ vertical->setSize(area->property("heightRatio").toReal());
+ vertical->setPosition(area->property("yPosition").toReal());
+diff --git a/qtquickcontrols2/tests/auto/controls/data/tst_scrollview.qml b/qtquickcontrols2/tests/auto/controls/data/tst_scrollview.qml
+index 0e8b08352..cd4931184 100644
+--- a/qtquickcontrols2/tests/auto/controls/data/tst_scrollview.qml
++++ b/qtquickcontrols2/tests/auto/controls/data/tst_scrollview.qml
+@@ -576,4 +576,51 @@ TestCase {
+ verify(newHorizontalScrollBar.visible)
+ verify(!oldHorizontalScrollBar.visible)
+ }
++
++ Component {
++ id: bindingToContentItemAndStandaloneFlickable
++
++ Item {
++ width: 200
++ height: 200
++
++ property alias scrollView: scrollView
++
++ ScrollView {
++ id: scrollView
++ anchors.fill: parent
++ contentItem: listView
++
++ property Item someBinding: contentItem
++ }
++ ListView {
++ id: listView
++ model: 10
++ delegate: ItemDelegate {
++ text: modelData
++ width: listView.width
++ }
++ }
++ }
++ }
++
++ // Tests that scroll bars show up for a ScrollView where
++ // - its contentItem is declared as a standalone, separate item
++ // - there is a binding to contentItem (which causes a default Flickable to be created)
++ function test_bindingToContentItemAndStandaloneFlickable() {
++ let root = createTemporaryObject(bindingToContentItemAndStandaloneFlickable, testCase)
++ verify(root)
++
++ let control = root.scrollView
++ let verticalScrollBar = control.ScrollBar.vertical
++ let horizontalScrollBar = control.ScrollBar.horizontal
++ compare(verticalScrollBar.parent, control)
++ compare(horizontalScrollBar.parent, control)
++ verify(verticalScrollBar.visible)
++ verify(horizontalScrollBar.visible)
++
++ mouseDrag(verticalScrollBar, verticalScrollBar.width / 2, verticalScrollBar.height / 2, 0, 50)
++ verify(verticalScrollBar.active)
++ verify(horizontalScrollBar.active)
++ }
+ }
+diff --git a/qtquickcontrols2/tests/auto/controls/data/tst_switch.qml b/qtquickcontrols2/tests/auto/controls/data/tst_switch.qml
+index b3fab41ca..10b6baa02 100644
+--- a/qtquickcontrols2/tests/auto/controls/data/tst_switch.qml
++++ b/qtquickcontrols2/tests/auto/controls/data/tst_switch.qml
+@@ -608,4 +608,27 @@ TestCase {
+ mouseClick(control.indicator)
+ verify(control.activeFocus)
+ }
++
++ Component {
++ id: deletionOrder1
++ Item {
++ Image { id: innerImage }
++ Switch { indicator: innerImage }
++ }
++ }
++
++ Component {
++ id: deletionOrder2
++ Item {
++ Switch { indicator: innerImage }
++ Image { id: innerImage }
++ }
++ }
++
++ function test_deletionOrder() {
++ var control1 = createTemporaryObject(deletionOrder1, testCase)
++ verify(control1)
++ var control2 = createTemporaryObject(deletionOrder2, testCase)
++ verify(control2)
++ }
+ }
+diff --git a/qtquickcontrols2/tests/auto/qquickpopup/data/releaseAfterExitTransition.qml b/qtquickcontrols2/tests/auto/qquickpopup/data/releaseAfterExitTransition.qml
+new file mode 100644
+index 000000000..9e4598b9f
+--- /dev/null
++++ b/qtquickcontrols2/tests/auto/qquickpopup/data/releaseAfterExitTransition.qml
+@@ -0,0 +1,78 @@
++/****************************************************************************
++**
++** Copyright (C) 2021 The Qt Company Ltd.
++** Contact: https://www.qt.io/licensing/
++**
++** This file is part of the test suite of the Qt Toolkit.
++**
++** $QT_BEGIN_LICENSE:BSD$
++** Commercial License Usage
++** Licensees holding valid commercial Qt licenses may use this file in
++** accordance with the commercial license agreement provided with the
++** Software or, alternatively, in accordance with the terms contained in
++** a written agreement between you and The Qt Company. For licensing terms
++** and conditions see https://www.qt.io/terms-conditions. For further
++** information use the contact form at https://www.qt.io/contact-us.
++**
++** BSD License Usage
++** Alternatively, you may use this file under the terms of the BSD license
++** as follows:
++**
++** "Redistribution and use in source and binary forms, with or without
++** modification, are permitted provided that the following conditions are
++** met:
++** * Redistributions of source code must retain the above copyright
++** notice, this list of conditions and the following disclaimer.
++** * Redistributions in binary form must reproduce the above copyright
++** notice, this list of conditions and the following disclaimer in
++** the documentation and/or other materials provided with the
++** distribution.
++** * Neither the name of The Qt Company Ltd nor the names of its
++** contributors may be used to endorse or promote products derived
++** from this software without specific prior written permission.
++**
++**
++** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
++** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
++** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
++** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
++** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
++** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
++** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
++** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
++** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
++** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
++** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
++**
++** $QT_END_LICENSE$
++**
++****************************************************************************/
++
++import QtQuick 2.15
++import QtQuick.Controls 2.15
++
++ApplicationWindow {
++ id: window
++ width: 400
++ height: 400
++ title: "releaseAfterExitTransition"
++
++ property alias popup: popup
++ property alias modalPopup: modalPopup
++
++ Popup {
++ id: popup
++ y: parent.height - height
++ width: 50
++ height: 50
++ }
++
++ Popup {
++ id: modalPopup
++ modal: true
++ y: parent.height - height
++ width: 50
++ height: 50
++ exit: Transition { PauseAnimation { duration: 100 } }
++ }
++}
+diff --git a/qtquickcontrols2/tests/auto/qquickpopup/tst_qquickpopup.cpp b/qtquickcontrols2/tests/auto/qquickpopup/tst_qquickpopup.cpp
+index 54952d128..3d50e2dd4 100644
+--- a/qtquickcontrols2/tests/auto/qquickpopup/tst_qquickpopup.cpp
++++ b/qtquickcontrols2/tests/auto/qquickpopup/tst_qquickpopup.cpp
+@@ -100,6 +100,7 @@ private slots:
+ void invisibleToolTipOpen();
+ void centerInOverlayWithinStackViewItem();
+ void destroyDuringExitTransition();
++ void releaseAfterExitTransition();
+ };
+
+ void tst_QQuickPopup::initTestCase()
+@@ -1575,6 +1576,34 @@ void tst_QQuickPopup::destroyDuringExitTransition()
+ QVERIFY(!button->isDown());
+ }
+
++void tst_QQuickPopup::releaseAfterExitTransition()
++{
++ QQuickApplicationHelper helper(this, "releaseAfterExitTransition.qml");
++ QVERIFY2(helper.ready, helper.failureMessage());
++
++ QQuickWindow *window = helper.window;
++ window->show();
++ QVERIFY(QTest::qWaitForWindowActive(window));
++
++ QQuickOverlay *overlay = QQuickOverlay::overlay(window);
++ QQuickPopup *modalPopup = window->property("modalPopup").value<QQuickPopup *>();
++ QQuickPopup *popup = window->property("popup").value<QQuickPopup *>();
++
++ modalPopup->open();
++ QTRY_VERIFY(modalPopup->isOpened());
++
++ QTest::mousePress(window, Qt::LeftButton, Qt::NoModifier, QPoint(1, 1));
++ // wait until the transition is finished and the overlay hides itself
++ QTRY_VERIFY(!overlay->isVisible());
++ QTest::mouseRelease(window, Qt::LeftButton, Qt::NoModifier, QPoint(1, 1));
++
++ popup->open();
++ QTRY_VERIFY(popup->isOpened());
++ QTest::mouseClick(window, Qt::LeftButton, Qt::NoModifier, QPoint(1, 1));
++ QTRY_VERIFY(!popup->isOpened());
++}
++
++
+ QTEST_QUICKCONTROLS_MAIN(tst_QQuickPopup)
+
+ #include "tst_qquickpopup.moc"
+Submodule qtscript 5be95f96...4d8e4bd2 (commits not present)
+Submodule qtspeech 17fc9fde..255845e2:
+diff --git a/qtspeech/src/plugins/tts/speechdispatcher/qtexttospeech_speechd.cpp b/qtspeech/src/plugins/tts/speechdispatcher/qtexttospeech_speechd.cpp
+index 6eb74b8..bcc7dd1 100644
+--- a/qtspeech/src/plugins/tts/speechdispatcher/qtexttospeech_speechd.cpp
++++ b/qtspeech/src/plugins/tts/speechdispatcher/qtexttospeech_speechd.cpp
+@@ -357,7 +357,9 @@ QVector<QLocale> QTextToSpeechEngineSpeechd::availableLocales() const
+
+ QVector<QVoice> QTextToSpeechEngineSpeechd::availableVoices() const
+ {
+- return m_voices.values(m_currentLocale.name()).toVector();
++ QList<QVoice> resultList = m_voices.values(m_currentLocale.name());
++ std::reverse(resultList.begin(), resultList.end());
++ return resultList.toVector();
+ }
+
+ // We have no way of knowing our own client_id since speech-dispatcher seems to be incomplete
+Submodule qtsvg 0c05780e..a7a0f249:
+diff --git a/qtsvg/src/plugins/imageformats/svg/qsvgiohandler.cpp b/qtsvg/src/plugins/imageformats/svg/qsvgiohandler.cpp
+index 561e77e..12e0574 100644
+--- a/qtsvg/src/plugins/imageformats/svg/qsvgiohandler.cpp
++++ b/qtsvg/src/plugins/imageformats/svg/qsvgiohandler.cpp
+@@ -191,6 +191,8 @@ bool QSvgIOHandler::read(QImage *image)
+ }
+ }
+ if (!finalSize.isEmpty()) {
++ if (qMax(finalSize.width(), finalSize.height()) > 0xffff)
++ return false; // Assume corrupted file
+ image->fill(d->backColor.rgba());
+ QPainter p(image);
+ d->r.render(&p, bounds);
+diff --git a/qtsvg/src/svg/qsvghandler.cpp b/qtsvg/src/svg/qsvghandler.cpp
+index a5f877f..8dda563 100644
+--- a/qtsvg/src/svg/qsvghandler.cpp
++++ b/qtsvg/src/svg/qsvghandler.cpp
+@@ -1393,9 +1393,10 @@ static void parseFont(QSvgNode *node,
+ case FontSizeNone:
+ break;
+ case FontSizeValue: {
+- QSvgHandler::LengthType dummy; // should always be pixel size
+- fontStyle->setSize(qMin(parseLength(attributes.fontSize, dummy, handler),
+- qreal(0xffff)));
++ QSvgHandler::LengthType type;
++ qreal fs = parseLength(attributes.fontSize, type, handler);
++ fs = convertToPixels(fs, true, type);
++ fontStyle->setSize(qMin(fs, qreal(0xffff)));
+ }
+ break;
+ default:
+@@ -2513,6 +2514,8 @@ static bool parseAnimateTransformNode(QSvgNode *parent,
+ ++s;
+ }
+ }
++ if (vals.count() % 3 != 0)
++ return false;
+
+ bool ok = true;
+ int begin = parseClockValue(beginStr, &ok);
+@@ -2576,6 +2579,8 @@ static QSvgNode *createCircleNode(QSvgNode *parent,
+ qreal ncx = toDouble(cx);
+ qreal ncy = toDouble(cy);
+ qreal nr = toDouble(r);
++ if (nr < 0.0)
++ return nullptr;
+
+ QRectF rect(ncx-nr, ncy-nr, nr*2, nr*2);
+ QSvgNode *circle = new QSvgCircle(parent, rect);
+@@ -3046,15 +3051,16 @@ static QSvgStyleProperty *createRadialGradientNode(QSvgNode *node,
+
+ qreal ncx = 0.5;
+ qreal ncy = 0.5;
+- qreal nr = 0.5;
+ if (!cx.isEmpty())
+ ncx = toDouble(cx);
+ if (!cy.isEmpty())
+ ncy = toDouble(cy);
++
++ qreal nr = 0.0;
+ if (!r.isEmpty())
+ nr = toDouble(r);
+- if (nr < 0.5)
+- nr = 0.5;
++ if (nr <= 0.0)
++ return nullptr;
+
+ qreal nfx = ncx;
+ if (!fx.isEmpty())
+@@ -3350,7 +3356,9 @@ static QSvgNode *createTextNode(QSvgNode *parent,
+ //### editable and rotate not handled
+ QSvgHandler::LengthType type;
+ qreal nx = parseLength(x, type, handler);
++ nx = convertToPixels(nx, true, type);
+ qreal ny = parseLength(y, type, handler);
++ ny = convertToPixels(ny, true, type);
+
+ QSvgNode *text = new QSvgText(parent, QPointF(nx, ny));
+ return text;
+@@ -3691,9 +3699,7 @@ void QSvgHandler::parse()
+ case QXmlStreamReader::EndElement:
+ endElement(xml->name());
+ ++remainingUnfinishedElements;
+- // if we are using somebody else's qxmlstreamreader
+- // we should not read until the end of the stream
+- done = !m_ownsReader && (xml->name() == QLatin1String("svg"));
++ done = (xml->name() == QLatin1String("svg"));
+ break;
+ case QXmlStreamReader::Characters:
+ characters(xml->text());
+diff --git a/qtsvg/src/svg/qsvgstructure.cpp b/qtsvg/src/svg/qsvgstructure.cpp
+index b89608b..89c9e4e 100644
+--- a/qtsvg/src/svg/qsvgstructure.cpp
++++ b/qtsvg/src/svg/qsvgstructure.cpp
+@@ -255,9 +255,13 @@ inline static bool isSupportedSvgFeature(const QString &str)
+ };
+
+ if (str.length() <= MAX_WORD_LENGTH && str.length() >= MIN_WORD_LENGTH) {
++ const char16_t unicode44 = str.at(44).unicode();
++ const char16_t unicode45 = str.at(45).unicode();
++ if (unicode44 >= sizeof(asso_values) || unicode45 >= sizeof(asso_values))
++ return false;
+ const int key = str.length()
+- + asso_values[str.at(45).unicode()]
+- + asso_values[str.at(44).unicode()];
++ + asso_values[unicode45]
++ + asso_values[unicode44];
+ if (key <= MAX_HASH_VALUE && key >= 0)
+ return str == QLatin1String(wordlist[key]);
+ }
+diff --git a/qtsvg/src/svg/qsvgtinydocument.cpp b/qtsvg/src/svg/qsvgtinydocument.cpp
+index 63d0797..19e7154 100644
+--- a/qtsvg/src/svg/qsvgtinydocument.cpp
++++ b/qtsvg/src/svg/qsvgtinydocument.cpp
+@@ -433,8 +433,16 @@ void QSvgTinyDocument::draw(QPainter *p, QSvgExtraStates &)
+ draw(p);
+ }
+
++static bool isValidMatrix(const QTransform &transform)
++{
++ qreal determinant = transform.determinant();
++ return qIsFinite(determinant);
++}
++
+ void QSvgTinyDocument::mapSourceToTarget(QPainter *p, const QRectF &targetRect, const QRectF &sourceRect)
+ {
++ QTransform oldTransform = p->worldTransform();
++
+ QRectF target = targetRect;
+ if (target.isEmpty()) {
+ QPaintDevice *dev = p->device();
+@@ -487,6 +495,9 @@ void QSvgTinyDocument::mapSourceToTarget(QPainter *p, const QRectF &targetRect,
+ }
+ #endif
+ }
++
++ if (!isValidMatrix(p->worldTransform()))
++ p->setWorldTransform(oldTransform);
+ }
+
+ QRectF QSvgTinyDocument::boundsOnElement(const QString &id) const
+diff --git a/qtsvg/tests/auto/qsvgrenderer/tst_qsvgrenderer.cpp b/qtsvg/tests/auto/qsvgrenderer/tst_qsvgrenderer.cpp
+index 36c76ec..db71e02 100644
+--- a/qtsvg/tests/auto/qsvgrenderer/tst_qsvgrenderer.cpp
++++ b/qtsvg/tests/auto/qsvgrenderer/tst_qsvgrenderer.cpp
+@@ -86,6 +86,8 @@ private slots:
+ void oss_fuzz_23731();
+ void oss_fuzz_24131();
+ void oss_fuzz_24738();
++ void illegalAnimateTransform_data();
++ void illegalAnimateTransform();
+
+ #ifndef QT_NO_COMPRESS
+ void testGzLoading();
+@@ -1646,5 +1648,22 @@ void tst_QSvgRenderer::oss_fuzz_24738()
+ QSvgRenderer().load(QByteArray("<svg><path d=\"a 2 1e-212.....\">"));
+ }
+
++void tst_QSvgRenderer::illegalAnimateTransform_data()
++{
++ QTest::addColumn<QByteArray>("svg");
++
++ QTest::newRow("case1") << QByteArray("<svg><animateTransform type=\"rotate\" begin=\"1\" dur=\"2\" values=\"8,0,5,0\">");
++ QTest::newRow("case2") << QByteArray("<svg><animateTransform type=\"rotate\" begin=\"1\" dur=\"2\" values=\"1,2\">");
++ QTest::newRow("case3") << QByteArray("<svg><animateTransform type=\"rotate\" begin=\"1\" dur=\"2\" from=\".. 5 2\" to=\"f\">");
++ QTest::newRow("case4") << QByteArray("<svg><animateTransform type=\"scale\" begin=\"1\" dur=\"2\" by=\"--,..\">");
++}
++
++void tst_QSvgRenderer::illegalAnimateTransform()
++{
++ QFETCH(QByteArray, svg);
++ QSvgRenderer renderer;
++ QVERIFY(!renderer.load(svg)); // also shouldn't assert
++}
++
+ QTEST_MAIN(tst_QSvgRenderer)
+ #include "tst_qsvgrenderer.moc"
+Submodule qttools 6914f7c8..090e526e:
+diff --git a/qttools/src/assistant/qhelpgenerator/helpgenerator.cpp b/qttools/src/assistant/qhelpgenerator/helpgenerator.cpp
+index feab1e2d5..cbfb82507 100644
+--- a/qttools/src/assistant/qhelpgenerator/helpgenerator.cpp
++++ b/qttools/src/assistant/qhelpgenerator/helpgenerator.cpp
+@@ -445,7 +445,9 @@ bool HelpGeneratorPrivate::insertFiles(const QStringList &files, const QString &
+ if (filterSetId < 0)
+ return false;
+ ++filterSetId;
+- for (int attId : qAsConst(filterAtts)) {
++ QList<int> attValues = filterAtts.values();
++ std::sort(attValues.begin(), attValues.end());
++ for (int attId : qAsConst(attValues)) {
+ m_query->prepare(QLatin1String("INSERT INTO FileAttributeSetTable "
+ "VALUES(?, ?)"));
+ m_query->bindValue(0, filterSetId);
+Submodule qtwayland dfb0129c..2904e1b3:
+diff --git a/qtwayland/src/client/configure.json b/qtwayland/src/client/configure.json
+index 2f424580..29222357 100644
+--- a/qtwayland/src/client/configure.json
++++ b/qtwayland/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/qtwayland/src/client/global/qwaylandclientextension.cpp b/qtwayland/src/client/global/qwaylandclientextension.cpp
+index 125b1e19..edccfe63 100644
+--- a/qtwayland/src/client/global/qwaylandclientextension.cpp
++++ b/qtwayland/src/client/global/qwaylandclientextension.cpp
+@@ -74,7 +74,10 @@ void QWaylandClientExtensionPrivate::handleRegistryGlobal(void *data, ::wl_regis
+ void QWaylandClientExtension::addRegistryListener()
+ {
+ Q_D(QWaylandClientExtension);
+- d->waylandIntegration->display()->addRegistryListener(&QWaylandClientExtensionPrivate::handleRegistryGlobal, this);
++ if (!d->registered) {
++ d->waylandIntegration->display()->addRegistryListener(&QWaylandClientExtensionPrivate::handleRegistryGlobal, this);
++ d->registered = true;
++ }
+ }
+
+ QWaylandClientExtension::QWaylandClientExtension(const int ver)
+@@ -88,6 +91,13 @@ QWaylandClientExtension::QWaylandClientExtension(const int ver)
+ QMetaObject::invokeMethod(this, "addRegistryListener", Qt::QueuedConnection);
+ }
+
++QWaylandClientExtension::~QWaylandClientExtension()
++{
++ Q_D(QWaylandClientExtension);
++ if (d->registered && !QCoreApplication::closingDown())
++ d->waylandIntegration->display()->removeListener(&QWaylandClientExtensionPrivate::handleRegistryGlobal, this);
++}
++
+ QtWaylandClient::QWaylandIntegration *QWaylandClientExtension::integration() const
+ {
+ Q_D(const QWaylandClientExtension);
+diff --git a/qtwayland/src/client/global/qwaylandclientextension.h b/qtwayland/src/client/global/qwaylandclientextension.h
+index 98272e57..5bd28398 100644
+--- a/qtwayland/src/client/global/qwaylandclientextension.h
++++ b/qtwayland/src/client/global/qwaylandclientextension.h
+@@ -63,6 +63,7 @@ class Q_WAYLAND_CLIENT_EXPORT QWaylandClientExtension : public QObject
+ Q_PROPERTY(bool active READ isActive NOTIFY activeChanged)
+ public:
+ QWaylandClientExtension(const int version);
++ ~QWaylandClientExtension();
+
+ QtWaylandClient::QWaylandIntegration *integration() const;
+ int version() const;
+diff --git a/qtwayland/src/client/global/qwaylandclientextension_p.h b/qtwayland/src/client/global/qwaylandclientextension_p.h
+index 69cc46a0..9091efbe 100644
+--- a/qtwayland/src/client/global/qwaylandclientextension_p.h
++++ b/qtwayland/src/client/global/qwaylandclientextension_p.h
+@@ -68,6 +68,7 @@ public:
+ QtWaylandClient::QWaylandIntegration *waylandIntegration = nullptr;
+ int version = -1;
+ bool active = false;
++ bool registered = false;
+ };
+
+ class Q_WAYLAND_CLIENT_EXPORT QWaylandClientExtensionTemplatePrivate : public QWaylandClientExtensionPrivate
+diff --git a/qtwayland/src/client/qwaylanddatadevice.cpp b/qtwayland/src/client/qwaylanddatadevice.cpp
+index 7e2e3308..e3e60ed5 100644
+--- a/qtwayland/src/client/qwaylanddatadevice.cpp
++++ b/qtwayland/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,7 +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::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;
+@@ -152,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;
+ }
+@@ -162,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();
+ }
+ }
+
+@@ -186,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,
+@@ -197,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()
+@@ -235,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());
+
+@@ -246,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)
+
+@@ -277,14 +296,10 @@ void QWaylandDataDevice::selectionSourceCancelled()
+ #if QT_CONFIG(draganddrop)
+ void QWaylandDataDevice::dragSourceCancelled()
+ {
++ static_cast<QWaylandDrag *>(QGuiApplicationPrivate::platformIntegration()->drag())->finishDrag();
+ 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));
+@@ -297,6 +312,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/qtwayland/src/client/qwaylanddatadevice_p.h b/qtwayland/src/client/qwaylanddatadevice_p.h
+index 16c3ad28..801dcc2c 100644
+--- a/qtwayland/src/client/qwaylanddatadevice_p.h
++++ b/qtwayland/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/qtwayland/src/client/qwaylanddatadevicemanager.cpp b/qtwayland/src/client/qwaylanddatadevicemanager.cpp
+index 35d67307..6dc4f77f 100644
+--- a/qtwayland/src/client/qwaylanddatadevicemanager.cpp
++++ b/qtwayland/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/qtwayland/src/client/qwaylanddatadevicemanager_p.h b/qtwayland/src/client/qwaylanddatadevicemanager_p.h
+index bd05c0fb..510d9be4 100644
+--- a/qtwayland/src/client/qwaylanddatadevicemanager_p.h
++++ b/qtwayland/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/qtwayland/src/client/qwaylanddataoffer.cpp b/qtwayland/src/client/qwaylanddataoffer.cpp
+index 2297e8a1..fe0ea8c9 100644
+--- a/qtwayland/src/client/qwaylanddataoffer.cpp
++++ b/qtwayland/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)
+ {
+@@ -163,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");
+diff --git a/qtwayland/src/client/qwaylanddataoffer_p.h b/qtwayland/src/client/qwaylanddataoffer_p.h
+index 9cf1483c..6f667398 100644
+--- a/qtwayland/src/client/qwaylanddataoffer_p.h
++++ b/qtwayland/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/qtwayland/src/client/qwaylanddatasource.cpp b/qtwayland/src/client/qwaylanddatasource.cpp
+index f45122fb..5599cbd4 100644
+--- a/qtwayland/src/client/qwaylanddatasource.cpp
++++ b/qtwayland/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/qtwayland/src/client/qwaylanddatasource_p.h b/qtwayland/src/client/qwaylanddatasource_p.h
+index 25afff79..96f07bc3 100644
+--- a/qtwayland/src/client/qwaylanddatasource_p.h
++++ b/qtwayland/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/qtwayland/src/client/qwaylanddisplay.cpp b/qtwayland/src/client/qwaylanddisplay.cpp
+index f10c1f79..c01e238b 100644
+--- a/qtwayland/src/client/qwaylanddisplay.cpp
++++ b/qtwayland/src/client/qwaylanddisplay.cpp
+@@ -85,10 +85,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)
+@@ -158,17 +351,16 @@ 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)
+ {
++ if (m_eventThread)
++ m_eventThread->stop();
++
++ if (m_frameEventQueueThread)
++ m_frameEventQueueThread->stop();
++
+ if (mSyncCallback)
+ wl_callback_destroy(mSyncCallback);
+
+@@ -187,6 +379,21 @@ 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
++// 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()
+@@ -203,98 +410,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
+@@ -345,7 +491,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));
+@@ -354,7 +500,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));
+@@ -369,6 +515,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));
+@@ -427,6 +575,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;
+ }
+@@ -452,9 +607,10 @@ void QWaylandDisplay::addRegistryListener(RegistryListener listener, void *data)
+
+ void QWaylandDisplay::removeListener(RegistryListener listener, void *data)
+ {
+- std::remove_if(mRegistryListeners.begin(), mRegistryListeners.end(), [=](Listener l){
++ auto iter = std::remove_if(mRegistryListeners.begin(), mRegistryListeners.end(), [=](Listener l){
+ return (l.listener == listener && l.data == data);
+ });
++ mRegistryListeners.erase(iter, mRegistryListeners.end());
+ }
+
+ uint32_t QWaylandDisplay::currentTimeMillisec()
+@@ -467,50 +623,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
+@@ -574,14 +689,10 @@ void QWaylandDisplay::handleKeyboardFocusChanged(QWaylandInputDevice *inputDevic
+ if (mLastKeyboardFocus == keyboardFocus)
+ return;
+
+- if (mWaylandIntegration->mShellIntegration) {
+- mWaylandIntegration->mShellIntegration->handleKeyboardFocusChanged(keyboardFocus, mLastKeyboardFocus);
+- } else {
+- if (keyboardFocus)
+- handleWindowActivated(keyboardFocus);
+- if (mLastKeyboardFocus)
+- handleWindowDeactivated(mLastKeyboardFocus);
+- }
++ if (keyboardFocus)
++ handleWindowActivated(keyboardFocus);
++ if (mLastKeyboardFocus)
++ handleWindowDeactivated(mLastKeyboardFocus);
+
+ mLastKeyboardFocus = keyboardFocus;
+ }
+@@ -600,6 +711,19 @@ void QWaylandDisplay::handleWaylandSync()
+ QWindow *activeWindow = mActiveWindows.empty() ? nullptr : mActiveWindows.last()->window();
+ if (activeWindow != QGuiApplication::focusWindow())
+ QWindowSystemInterface::handleWindowActivated(activeWindow);
++
++ if (!activeWindow) {
++ if (lastInputDevice()) {
++#if QT_CONFIG(clipboard)
++ if (auto *dataDevice = lastInputDevice()->dataDevice())
++ dataDevice->invalidateSelectionOffer();
++#endif
++#if QT_CONFIG(wayland_client_primary_selection)
++ if (auto *device = lastInputDevice()->primarySelectionDevice())
++ device->invalidateSelectionOffer();
++#endif
++ }
++ }
+ }
+
+ const wl_callback_listener QWaylandDisplay::syncCallbackListener = {
+@@ -626,6 +750,13 @@ QWaylandInputDevice *QWaylandDisplay::defaultInputDevice() const
+ return mInputDevices.isEmpty() ? 0 : mInputDevices.first();
+ }
+
++bool QWaylandDisplay::isKeyboardAvailable() const
++{
++ return std::any_of(
++ mInputDevices.constBegin(), mInputDevices.constEnd(),
++ [this](const QWaylandInputDevice *device) { return device->keyboard() != nullptr; });
++}
++
+ #if QT_CONFIG(cursor)
+
+ QWaylandCursor *QWaylandDisplay::waylandCursor()
+@@ -652,4 +783,6 @@ QWaylandCursorTheme *QWaylandDisplay::loadCursorTheme(const QString &name, int p
+
+ } // namespace QtWaylandClient
+
++#include "qwaylanddisplay.moc"
++
+ QT_END_NAMESPACE
+diff --git a/qtwayland/src/client/qwaylanddisplay_p.h b/qtwayland/src/client/qwaylanddisplay_p.h
+index 3b092bc8..42bc661d 100644
+--- a/qtwayland/src/client/qwaylanddisplay_p.h
++++ b/qtwayland/src/client/qwaylanddisplay_p.h
+@@ -109,6 +109,7 @@ class QWaylandSurface;
+ class QWaylandShellIntegration;
+ class QWaylandCursor;
+ class QWaylandCursorTheme;
++class EventThread;
+
+ typedef void (*RegistryListener)(void *data,
+ struct wl_registry *registry,
+@@ -120,15 +121,11 @@ 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;
+
++ void initialize();
++
+ #if QT_CONFIG(xkbcommon)
+ struct xkb_context *xkbContext() const { return mXkbContext.get(); }
+ #endif
+@@ -210,11 +207,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();
+@@ -237,6 +234,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;
+@@ -273,11 +273,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/qtwayland/src/client/qwaylanddnd.cpp b/qtwayland/src/client/qwaylanddnd.cpp
+index 6535aa16..7c53f5fa 100644
+--- a/qtwayland/src/client/qwaylanddnd.cpp
++++ b/qtwayland/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
+@@ -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)
+@@ -103,33 +106,41 @@ 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);
++
++ if (drag())
++ drag()->deleteLater();
++}
++
++bool QWaylandDrag::ownsDragObject() const
++{
++ return true;
+ }
+
+ }
+diff --git a/qtwayland/src/client/qwaylanddnd_p.h b/qtwayland/src/client/qwaylanddnd_p.h
+index 474fe2ab..46f629ac 100644
+--- a/qtwayland/src/client/qwaylanddnd_p.h
++++ b/qtwayland/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;
+@@ -82,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;
+diff --git a/qtwayland/src/client/qwaylandinputdevice.cpp b/qtwayland/src/client/qwaylandinputdevice.cpp
+index 613fe862..4b90de84 100644
+--- a/qtwayland/src/client/qwaylandinputdevice.cpp
++++ b/qtwayland/src/client/qwaylandinputdevice.cpp
+@@ -685,6 +685,11 @@ public:
+
+ void QWaylandInputDevice::Pointer::pointer_leave(uint32_t time, struct wl_surface *surface)
+ {
++ invalidateFocus();
++ mButtons = Qt::NoButton;
++
++ mParent->mTime = time;
++
+ // The event may arrive after destroying the window, indicated by
+ // a null surface.
+ if (!surface)
+@@ -696,11 +701,6 @@ void QWaylandInputDevice::Pointer::pointer_leave(uint32_t time, struct wl_surfac
+
+ if (!QWaylandWindow::mouseGrab())
+ setFrameEvent(new LeaveEvent(window, mSurfacePos, mGlobalPos));
+-
+- invalidateFocus();
+- mButtons = Qt::NoButton;
+-
+- mParent->mTime = time;
+ }
+
+ class MotionEvent : public QWaylandPointerEvent
+@@ -1300,14 +1300,6 @@ void QWaylandInputDevice::Keyboard::handleFocusDestroyed()
+ void QWaylandInputDevice::Keyboard::handleFocusLost()
+ {
+ mFocus = nullptr;
+-#if QT_CONFIG(clipboard)
+- if (auto *dataDevice = mParent->dataDevice())
+- dataDevice->invalidateSelectionOffer();
+-#endif
+-#if QT_CONFIG(wayland_client_primary_selection)
+- if (auto *device = mParent->primarySelectionDevice())
+- device->invalidateSelectionOffer();
+-#endif
+ mParent->mQDisplay->handleKeyboardFocusChanged(mParent);
+ mRepeatTimer.stop();
+ }
+@@ -1396,6 +1388,7 @@ void QWaylandInputDevice::Touch::touch_cancel()
+ if (touchExt)
+ touchExt->touchCanceled();
+
++ mFocus = nullptr;
+ QWindowSystemInterface::handleTouchCancelEvent(nullptr, mParent->mTouchDevice);
+ }
+
+diff --git a/qtwayland/src/client/qwaylandintegration.cpp b/qtwayland/src/client/qwaylandintegration.cpp
+index c53ccb78..54861600 100644
+--- a/qtwayland/src/client/qwaylandintegration.cpp
++++ b/qtwayland/src/client/qwaylandintegration.cpp
+@@ -125,6 +125,9 @@ QWaylandIntegration::QWaylandIntegration()
+ #endif
+
+ reconfigureInputContext();
++
++ QWaylandWindow::fixedToplevelPositions =
++ !qEnvironmentVariableIsSet("QT_WAYLAND_DISABLE_FIXED_POSITIONS");
+ }
+
+ QWaylandIntegration::~QWaylandIntegration()
+@@ -192,14 +195,18 @@ QAbstractEventDispatcher *QWaylandIntegration::createEventDispatcher() const
+
+ void QWaylandIntegration::initialize()
+ {
++ mDisplay->initEventThread();
++
++ // 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()));
+
+- 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()));
+-
+ // Qt does not support running with no screens
+ mDisplay->ensureScreen();
+ }
+@@ -262,6 +269,14 @@ QWaylandDisplay *QWaylandIntegration::display() const
+ return mDisplay.data();
+ }
+
++Qt::KeyboardModifiers QWaylandIntegration::queryKeyboardModifiers() const
++{
++ if (auto *seat = mDisplay->currentInputDevice()) {
++ return seat->modifiers();
++ }
++ return Qt::NoModifier;
++}
++
+ QList<int> QWaylandIntegration::possibleKeys(const QKeyEvent *event) const
+ {
+ if (auto *seat = mDisplay->currentInputDevice())
+@@ -479,7 +494,7 @@ void QWaylandIntegration::reconfigureInputContext()
+ }
+ #endif
+
+- qCDebug(lcQpaWayland) << "using input method:" << inputContext()->metaObject()->className();
++ qCDebug(lcQpaWayland) << "using input method:" << (inputContext() ? inputContext()->metaObject()->className() : "<none>");
+ }
+
+ QWaylandShellIntegration *QWaylandIntegration::createShellIntegration(const QString &integrationName)
+diff --git a/qtwayland/src/client/qwaylandintegration_p.h b/qtwayland/src/client/qwaylandintegration_p.h
+index ff70ae25..73b80658 100644
+--- a/qtwayland/src/client/qwaylandintegration_p.h
++++ b/qtwayland/src/client/qwaylandintegration_p.h
+@@ -107,6 +107,8 @@ public:
+
+ QWaylandDisplay *display() const;
+
++ Qt::KeyboardModifiers queryKeyboardModifiers() const override;
++
+ QList<int> possibleKeys(const QKeyEvent *event) const override;
+
+ QStringList themeNames() const override;
+diff --git a/qtwayland/src/client/qwaylandprimaryselectionv1.cpp b/qtwayland/src/client/qwaylandprimaryselectionv1.cpp
+index 832f9678..ea508771 100644
+--- a/qtwayland/src/client/qwaylandprimaryselectionv1.cpp
++++ b/qtwayland/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)
+diff --git a/qtwayland/src/client/qwaylandscreen.cpp b/qtwayland/src/client/qwaylandscreen.cpp
+index 6cb337de..5537dafd 100644
+--- a/qtwayland/src/client/qwaylandscreen.cpp
++++ b/qtwayland/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))
+@@ -72,7 +72,7 @@ QWaylandScreen::QWaylandScreen(QWaylandDisplay *waylandDisplay, int version, uin
+ qCWarning(lcQpaWayland) << "wl_output done event not supported by compositor,"
+ << "QScreen may not work correctly";
+ mWaylandDisplay->forceRoundTrip(); // Give the compositor a chance to send geometry etc.
+- mOutputDone = true; // Fake the done event
++ mProcessedEvents |= OutputDoneEvent; // Fake the done event
+ maybeInitialize();
+ }
+ }
+@@ -81,16 +81,29 @@ 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
++{
++ uint ret = OutputDoneEvent;
++
++ if (mWaylandDisplay->xdgOutputManager()) {
++ ret |= XdgOutputNameEvent;
++
++ if (mWaylandDisplay->xdgOutputManager()->version() < 3)
++ ret |= XdgOutputDoneEvent;
++ }
++ return ret;
+ }
+
+ void QWaylandScreen::maybeInitialize()
+ {
+ Q_ASSERT(!mInitialized);
+
+- if (!mOutputDone)
+- return;
+-
+- if (mWaylandDisplay->xdgOutputManager() && !mXdgOutputDone)
++ const uint requiredEvents = this->requiredEvents();
++ if ((mProcessedEvents & requiredEvents) != requiredEvents)
+ return;
+
+ mInitialized = true;
+@@ -276,9 +289,8 @@ void QWaylandScreen::output_scale(int32_t factor)
+
+ void QWaylandScreen::output_done()
+ {
+- mOutputDone = true;
+- if (zxdg_output_v1::isInitialized() && mWaylandDisplay->xdgOutputManager()->version() >= 3)
+- mXdgOutputDone = true;
++ mProcessedEvents |= OutputDoneEvent;
++
+ if (mInitialized) {
+ updateOutputProperties();
+ if (zxdg_output_v1::isInitialized())
+@@ -339,7 +351,7 @@ void QWaylandScreen::zxdg_output_v1_done()
+ if (Q_UNLIKELY(mWaylandDisplay->xdgOutputManager()->version() >= 3))
+ qWarning(lcQpaWayland) << "zxdg_output_v1.done received on version 3 or newer, this is most likely a bug in the compositor";
+
+- mXdgOutputDone = true;
++ mProcessedEvents |= XdgOutputDoneEvent;
+ if (mInitialized)
+ updateXdgOutputProperties();
+ else
+@@ -348,7 +360,11 @@ void QWaylandScreen::zxdg_output_v1_done()
+
+ void QWaylandScreen::zxdg_output_v1_name(const QString &name)
+ {
++ if (Q_UNLIKELY(mInitialized))
++ qWarning(lcQpaWayland) << "zxdg_output_v1.name received after output has been initialized, this is most likely a bug in the compositor";
++
+ mOutputName = name;
++ mProcessedEvents |= XdgOutputNameEvent;
+ }
+
+ void QWaylandScreen::updateXdgOutputProperties()
+diff --git a/qtwayland/src/client/qwaylandscreen_p.h b/qtwayland/src/client/qwaylandscreen_p.h
+index df1c94f2..050cfdc0 100644
+--- a/qtwayland/src/client/qwaylandscreen_p.h
++++ b/qtwayland/src/client/qwaylandscreen_p.h
+@@ -116,6 +116,13 @@ public:
+ static QWaylandScreen *fromWlOutput(::wl_output *output);
+
+ private:
++ enum Event : uint {
++ XdgOutputDoneEvent = 0x1,
++ OutputDoneEvent = 0x2,
++ XdgOutputNameEvent = 0x4,
++ };
++ uint requiredEvents() const;
++
+ void output_mode(uint32_t flags, int width, int height, int refresh) override;
+ void output_geometry(int32_t x, int32_t y,
+ int32_t width, int32_t height,
+@@ -148,8 +155,7 @@ private:
+ QSize mPhysicalSize;
+ QString mOutputName;
+ Qt::ScreenOrientation m_orientation = Qt::PrimaryOrientation;
+- bool mOutputDone = false;
+- bool mXdgOutputDone = false;
++ uint mProcessedEvents = 0;
+ bool mInitialized = false;
+
+ #if QT_CONFIG(cursor)
+diff --git a/qtwayland/src/client/qwaylandshmbackingstore.cpp b/qtwayland/src/client/qwaylandshmbackingstore.cpp
+index dc7ff670..41cffdf7 100644
+--- a/qtwayland/src/client/qwaylandshmbackingstore.cpp
++++ b/qtwayland/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
+@@ -74,8 +78,10 @@ QWaylandShmBuffer::QWaylandShmBuffer(QWaylandDisplay *display,
+ int alloc = stride * size.height();
+ int fd = -1;
+
+-#ifdef SYS_memfd_create
+- fd = syscall(SYS_memfd_create, "wayland-shm", MFD_CLOEXEC);
++#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);
+ #endif
+
+ QScopedPointer<QFile> filePointer;
+diff --git a/qtwayland/src/client/qwaylandwindow.cpp b/qtwayland/src/client/qwaylandwindow.cpp
+index cb82857a..fb2c59dc 100644
+--- a/qtwayland/src/client/qwaylandwindow.cpp
++++ b/qtwayland/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,9 +94,6 @@ QWaylandWindow::QWaylandWindow(QWindow *window, QWaylandDisplay *display)
+
+ QWaylandWindow::~QWaylandWindow()
+ {
+- mDisplay->destroyFrameQueue(mFrameQueue);
+- mDisplay->handleWindowDestroyed(this);
+-
+ delete mWindowDecoration;
+
+ if (mSurface)
+@@ -243,6 +239,7 @@ bool QWaylandWindow::shouldCreateSubSurface() const
+
+ void QWaylandWindow::reset()
+ {
++ closeChildPopups();
+ delete mShellSurface;
+ mShellSurface = nullptr;
+ delete mSubSurfaceWindow;
+@@ -255,17 +252,22 @@ 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();
+ mQueuedBuffer = nullptr;
++
++ mDisplay->handleWindowDestroyed(this);
+ }
+
+ QWaylandWindow *QWaylandWindow::fromWlSurface(::wl_surface *surface)
+@@ -351,19 +353,25 @@ 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()) {
+ 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());
+@@ -374,7 +382,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)
+@@ -399,21 +407,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);
+@@ -433,10 +426,7 @@ void QWaylandWindow::setVisible(bool visible)
+ lastVisible = visible;
+
+ if (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
+@@ -444,7 +434,6 @@ void QWaylandWindow::setVisible(bool visible)
+ // QWaylandShmBackingStore::beginPaint().
+ } else {
+ sendExposeEvent(QRect());
+- closePopups(this);
+ reset();
+ }
+ }
+@@ -556,12 +545,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();
+
+@@ -583,7 +572,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)
+@@ -619,8 +612,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();
+@@ -635,42 +634,53 @@ 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);
+- 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();
+
+ // 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;
+- };
++ 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();
++ };
+
++ 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();
+ }
+
+ 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";
+@@ -868,6 +878,17 @@ bool QWaylandWindow::createDecoration()
+ subsurf->set_position(pos.x() + m.left(), pos.y() + m.top());
+ }
+ sendExposeEvent(QRect(QPoint(), geometry().size()));
++
++ // This is a special case where the buffer is recreated, but since
++ // the content rect remains the same, the widgets remain the same
++ // size and are not redrawn, leaving the new buffer empty. As a simple
++ // work-around, we trigger a full extra update whenever the client-side
++ // window decorations are toggled while the window is showing.
++ // Note: createDecoration() is sometimes called from the render thread
++ // of Qt Quick. This is essentially wrong and could potentially cause problems,
++ // but until the underlying issue has been fixed, we have to use invokeMethod()
++ // here to avoid asserts.
++ QMetaObject::invokeMethod(window(), &QWindow::requestUpdate);
+ }
+
+ return mWindowDecoration;
+@@ -1023,6 +1044,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) {
+@@ -1094,10 +1122,18 @@ bool QWaylandWindow::setMouseGrabEnabled(bool grab)
+ return true;
+ }
+
++Qt::WindowStates QWaylandWindow::windowStates() const
++{
++ return mLastReportedWindowStates;
++}
++
+ void QWaylandWindow::handleWindowStatesChanged(Qt::WindowStates states)
+ {
+ createDecoration();
+- QWindowSystemInterface::handleWindowStateChanged(window(), states, mLastReportedWindowStates);
++ Qt::WindowStates statesWithoutActive = states & ~Qt::WindowActive;
++ Qt::WindowStates lastStatesWithoutActive = mLastReportedWindowStates & ~Qt::WindowActive;
++ QWindowSystemInterface::handleWindowStateChanged(window(), statesWithoutActive,
++ lastStatesWithoutActive);
+ mLastReportedWindowStates = states;
+ }
+
+@@ -1139,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()
+@@ -1160,8 +1201,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
+@@ -1174,7 +1218,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);
+ }
+@@ -1185,19 +1234,18 @@ void QWaylandWindow::requestUpdate()
+ void QWaylandWindow::handleUpdate()
+ {
+ qCDebug(lcWaylandBackingstore) << "handleUpdate" << QThread::currentThread();
++
+ // TODO: Should sync subsurfaces avoid requesting frame callbacks?
+ QReadLocker lock(&mSurfaceLock);
+ if (!mSurface)
+ return;
+
+- if (mFrameCallback) {
+- wl_callback_destroy(mFrameCallback);
+- mFrameCallback = nullptr;
+- }
++ QMutexLocker locker(&mFrameSyncMutex);
++ if (mWaitingForFrameCallback)
++ return;
+
+- 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);
++ 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);
+@@ -1207,6 +1255,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);
+@@ -1267,6 +1317,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/qtwayland/src/client/qwaylandwindow_p.h b/qtwayland/src/client/qwaylandwindow_p.h
+index 01337cff..2f219d8c 100644
+--- a/qtwayland/src/client/qwaylandwindow_p.h
++++ b/qtwayland/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;
+@@ -148,6 +151,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;
+@@ -206,6 +210,10 @@ public:
+ void handleUpdate();
+ void deliverUpdateRequest() override;
+
++ void addChildPopup(QWaylandWindow* child);
++ void removeChildPopup(QWaylandWindow* child);
++ void closeChildPopups();
++
+ public slots:
+ void applyConfigure();
+
+@@ -215,7 +223,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;
+@@ -225,13 +237,14 @@ protected:
+ Qt::MouseButtons mMousePressedInContentArea = Qt::NoButton;
+
+ 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;
+- QWaylandDisplay::FrameQueue mFrameQueue;
++ 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;
+
+ // True when we have called deliverRequestUpdate, but the client has not yet attached a new buffer
+@@ -261,6 +274,8 @@ protected:
+ QWaylandBuffer *mQueuedBuffer = nullptr;
+ QRegion mQueuedBufferDamage;
+
++ QList<QPointer<QWaylandWindow>> mChildPopups;
++
+ private:
+ void setGeometry_helper(const QRect &rect);
+ void initWindow();
+@@ -283,12 +298,10 @@ private:
+ QRect mLastExposeGeometry;
+
+ static const wl_callback_listener callbackListener;
+- void handleFrameCallback();
++ void handleFrameCallback(struct ::wl_callback* callback);
+
+ static QWaylandWindow *mMouseGrab;
+
+- mutable QReadWriteLock mSurfaceLock;
+-
+ friend class QWaylandSubSurface;
+ };
+
+diff --git a/qtwayland/src/client/shellintegration/qwaylandshellintegration_p.h b/qtwayland/src/client/shellintegration/qwaylandshellintegration_p.h
+index ccad0048..4cc9b3b8 100644
+--- a/qtwayland/src/client/shellintegration/qwaylandshellintegration_p.h
++++ b/qtwayland/src/client/shellintegration/qwaylandshellintegration_p.h
+@@ -73,11 +73,10 @@ public:
+ return true;
+ }
+ virtual QWaylandShellSurface *createShellSurface(QWaylandWindow *window) = 0;
++ // kept for binary compat with layer-shell-qt
+ virtual void handleKeyboardFocusChanged(QWaylandWindow *newFocus, QWaylandWindow *oldFocus) {
+- if (newFocus)
+- m_display->handleWindowActivated(newFocus);
+- if (oldFocus)
+- m_display->handleWindowDeactivated(oldFocus);
++ Q_UNUSED(newFocus);
++ Q_UNUSED(oldFocus);
+ }
+ virtual void *nativeResourceForWindow(const QByteArray &resource, QWindow *window) {
+ Q_UNUSED(resource);
+diff --git a/qtwayland/src/compositor/configure.json b/qtwayland/src/compositor/configure.json
+index bcfd5215..da95d07b 100644
+--- a/qtwayland/src/compositor/configure.json
++++ b/qtwayland/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"
+ }
+ },
+
+diff --git a/qtwayland/src/hardwareintegration/client/wayland-egl/qwaylandeglwindow.cpp b/qtwayland/src/hardwareintegration/client/wayland-egl/qwaylandeglwindow.cpp
+index 7889f575..64140672 100644
+--- a/qtwayland/src/hardwareintegration/client/wayland-egl/qwaylandeglwindow.cpp
++++ b/qtwayland/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>
+@@ -124,6 +125,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();
+@@ -131,14 +133,16 @@ void QWaylandEglWindow::updateSurface(bool create)
+ if (!disableResizeCheck) {
+ wl_egl_window_get_attached_size(m_waylandEglWindow, ¤t_width, ¤t_height);
+ }
+- if (disableResizeCheck || (current_width != sizeWithMargins.width() || current_height != sizeWithMargins.height())) {
++ if (disableResizeCheck || (current_width != sizeWithMargins.width() || current_height != sizeWithMargins.height()) || m_requestedSize != sizeWithMargins) {
+ wl_egl_window_resize(m_waylandEglWindow, sizeWithMargins.width(), sizeWithMargins.height(), mOffset.x(), mOffset.y());
++ m_requestedSize = sizeWithMargins;
+ mOffset = QPoint();
+
+ 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;
+ }
+
+ if (!m_eglSurface && m_waylandEglWindow && create) {
+diff --git a/qtwayland/src/hardwareintegration/client/wayland-egl/qwaylandeglwindow.h b/qtwayland/src/hardwareintegration/client/wayland-egl/qwaylandeglwindow.h
+index 5b1f4d56..0079dfef 100644
+--- a/qtwayland/src/hardwareintegration/client/wayland-egl/qwaylandeglwindow.h
++++ b/qtwayland/src/hardwareintegration/client/wayland-egl/qwaylandeglwindow.h
+@@ -88,6 +88,7 @@ private:
+ mutable QOpenGLFramebufferObject *m_contentFBO = nullptr;
+
+ QSurfaceFormat m_format;
++ QSize m_requestedSize;
+ };
+
+ }
+diff --git a/qtwayland/src/hardwareintegration/compositor/linux-dmabuf-unstable-v1/linuxdmabuf.h b/qtwayland/src/hardwareintegration/compositor/linux-dmabuf-unstable-v1/linuxdmabuf.h
+index 56a710c3..c6a8b6c6 100644
+--- a/qtwayland/src/hardwareintegration/compositor/linux-dmabuf-unstable-v1/linuxdmabuf.h
++++ b/qtwayland/src/hardwareintegration/compositor/linux-dmabuf-unstable-v1/linuxdmabuf.h
+@@ -41,6 +41,8 @@
+ #include <QtCore/QTextStream>
+ #include <QtGui/QOpenGLTexture>
+
++#include <array>
++
+ #include <EGL/egl.h>
+ #include <EGL/eglext.h>
+
+diff --git a/qtwayland/src/plugins/decorations/bradient/main.cpp b/qtwayland/src/plugins/decorations/bradient/main.cpp
+index e75fda3c..fa885143 100644
+--- a/qtwayland/src/plugins/decorations/bradient/main.cpp
++++ b/qtwayland/src/plugins/decorations/bradient/main.cpp
+@@ -164,13 +164,10 @@ void QWaylandBradientDecoration::paint(QPaintDevice *device)
+ // Window icon
+ QIcon icon = waylandWindow()->windowIcon();
+ if (!icon.isNull()) {
+- QPixmap pixmap = icon.pixmap(QSize(128, 128));
+- QPixmap scaled = pixmap.scaled(22, 22, Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
+-
+ QRectF iconRect(0, 0, 22, 22);
+- p.drawPixmap(iconRect.adjusted(margins().left() + BUTTON_SPACING, 4,
+- margins().left() + BUTTON_SPACING, 4),
+- scaled, iconRect);
++ iconRect.adjust(margins().left() + BUTTON_SPACING, 4,
++ margins().left() + BUTTON_SPACING, 4),
++ icon.paint(&p, iconRect.toRect());
+ }
+
+ // Window title
+diff --git a/qtwayland/src/plugins/shellintegration/xdg-shell-v5/qwaylandxdgpopupv5.cpp b/qtwayland/src/plugins/shellintegration/xdg-shell-v5/qwaylandxdgpopupv5.cpp
+index 85d25e3c..60bdd491 100644
+--- a/qtwayland/src/plugins/shellintegration/xdg-shell-v5/qwaylandxdgpopupv5.cpp
++++ b/qtwayland/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/qtwayland/src/plugins/shellintegration/xdg-shell-v5/qwaylandxdgpopupv5_p.h b/qtwayland/src/plugins/shellintegration/xdg-shell-v5/qwaylandxdgpopupv5_p.h
+index 7494f6a6..d85f130b 100644
+--- a/qtwayland/src/plugins/shellintegration/xdg-shell-v5/qwaylandxdgpopupv5_p.h
++++ b/qtwayland/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/qtwayland/src/plugins/shellintegration/xdg-shell-v5/qwaylandxdgshellv5.cpp b/qtwayland/src/plugins/shellintegration/xdg-shell-v5/qwaylandxdgshellv5.cpp
+index 7e242c4a..def8452a 100644
+--- a/qtwayland/src/plugins/shellintegration/xdg-shell-v5/qwaylandxdgshellv5.cpp
++++ b/qtwayland/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/qtwayland/src/plugins/shellintegration/xdg-shell-v5/qwaylandxdgshellv5integration.cpp b/qtwayland/src/plugins/shellintegration/xdg-shell-v5/qwaylandxdgshellv5integration.cpp
+index 4e25949f..cfc60939 100644
+--- a/qtwayland/src/plugins/shellintegration/xdg-shell-v5/qwaylandxdgshellv5integration.cpp
++++ b/qtwayland/src/plugins/shellintegration/xdg-shell-v5/qwaylandxdgshellv5integration.cpp
+@@ -85,13 +85,6 @@ QWaylandShellSurface *QWaylandXdgShellV5Integration::createShellSurface(QWayland
+ return m_xdgShell->createXdgSurface(window);
+ }
+
+-void QWaylandXdgShellV5Integration::handleKeyboardFocusChanged(QWaylandWindow *newFocus, QWaylandWindow *oldFocus) {
+- if (newFocus && qobject_cast<QWaylandXdgPopupV5 *>(newFocus->shellSurface()))
+- m_display->handleWindowActivated(newFocus);
+- if (oldFocus && qobject_cast<QWaylandXdgPopupV5 *>(oldFocus->shellSurface()))
+- m_display->handleWindowDeactivated(oldFocus);
+-}
+-
+ }
+
+ QT_END_NAMESPACE
+diff --git a/qtwayland/src/plugins/shellintegration/xdg-shell-v5/qwaylandxdgshellv5integration_p.h b/qtwayland/src/plugins/shellintegration/xdg-shell-v5/qwaylandxdgshellv5integration_p.h
+index ce6bdb9e..aed88670 100644
+--- a/qtwayland/src/plugins/shellintegration/xdg-shell-v5/qwaylandxdgshellv5integration_p.h
++++ b/qtwayland/src/plugins/shellintegration/xdg-shell-v5/qwaylandxdgshellv5integration_p.h
+@@ -67,7 +67,6 @@ public:
+ QWaylandXdgShellV5Integration() {}
+ bool initialize(QWaylandDisplay *display) override;
+ QWaylandShellSurface *createShellSurface(QWaylandWindow *window) override;
+- void handleKeyboardFocusChanged(QWaylandWindow *newFocus, QWaylandWindow *oldFocus) override;
+
+ private:
+ QScopedPointer<QWaylandXdgShellV5> m_xdgShell;
+diff --git a/qtwayland/src/plugins/shellintegration/xdg-shell-v6/qwaylandxdgshellv6.cpp b/qtwayland/src/plugins/shellintegration/xdg-shell-v6/qwaylandxdgshellv6.cpp
+index 8c371661..151c78e3 100644
+--- a/qtwayland/src/plugins/shellintegration/xdg-shell-v6/qwaylandxdgshellv6.cpp
++++ b/qtwayland/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/qtwayland/src/plugins/shellintegration/xdg-shell-v6/qwaylandxdgshellv6integration.cpp b/qtwayland/src/plugins/shellintegration/xdg-shell-v6/qwaylandxdgshellv6integration.cpp
+index 03164316..e8da8ba1 100644
+--- a/qtwayland/src/plugins/shellintegration/xdg-shell-v6/qwaylandxdgshellv6integration.cpp
++++ b/qtwayland/src/plugins/shellintegration/xdg-shell-v6/qwaylandxdgshellv6integration.cpp
+@@ -68,20 +68,6 @@ QWaylandShellSurface *QWaylandXdgShellV6Integration::createShellSurface(QWayland
+ return m_xdgShell->getXdgSurface(window);
+ }
+
+-void QWaylandXdgShellV6Integration::handleKeyboardFocusChanged(QWaylandWindow *newFocus, QWaylandWindow *oldFocus)
+-{
+- if (newFocus) {
+- auto *xdgSurface = qobject_cast<QWaylandXdgSurfaceV6 *>(newFocus->shellSurface());
+- if (xdgSurface && !xdgSurface->handlesActiveState())
+- m_display->handleWindowActivated(newFocus);
+- }
+- if (oldFocus && qobject_cast<QWaylandXdgSurfaceV6 *>(oldFocus->shellSurface())) {
+- auto *xdgSurface = qobject_cast<QWaylandXdgSurfaceV6 *>(oldFocus->shellSurface());
+- if (xdgSurface && !xdgSurface->handlesActiveState())
+- m_display->handleWindowDeactivated(oldFocus);
+- }
+-}
+-
+ }
+
+ QT_END_NAMESPACE
+diff --git a/qtwayland/src/plugins/shellintegration/xdg-shell-v6/qwaylandxdgshellv6integration_p.h b/qtwayland/src/plugins/shellintegration/xdg-shell-v6/qwaylandxdgshellv6integration_p.h
+index 261f8cbb..c1bcd5c6 100644
+--- a/qtwayland/src/plugins/shellintegration/xdg-shell-v6/qwaylandxdgshellv6integration_p.h
++++ b/qtwayland/src/plugins/shellintegration/xdg-shell-v6/qwaylandxdgshellv6integration_p.h
+@@ -65,7 +65,6 @@ public:
+ QWaylandXdgShellV6Integration() {}
+ bool initialize(QWaylandDisplay *display) override;
+ QWaylandShellSurface *createShellSurface(QWaylandWindow *window) override;
+- void handleKeyboardFocusChanged(QWaylandWindow *newFocus, QWaylandWindow *oldFocus) override;
+
+ private:
+ QScopedPointer<QWaylandXdgShellV6> m_xdgShell;
+diff --git a/qtwayland/src/plugins/shellintegration/xdg-shell/qwaylandxdgshell.cpp b/qtwayland/src/plugins/shellintegration/xdg-shell/qwaylandxdgshell.cpp
+index f3e3c330..fa6d5808 100644
+--- a/qtwayland/src/plugins/shellintegration/xdg-shell/qwaylandxdgshell.cpp
++++ b/qtwayland/src/plugins/shellintegration/xdg-shell/qwaylandxdgshell.cpp
+@@ -67,11 +67,6 @@ QWaylandXdgSurface::Toplevel::Toplevel(QWaylandXdgSurface *xdgSurface)
+
+ QWaylandXdgSurface::Toplevel::~Toplevel()
+ {
+- if (m_applied.states & Qt::WindowActive) {
+- QWaylandWindow *window = m_xdgSurface->window();
+- window->display()->handleWindowDeactivated(window);
+- }
+-
+ // The protocol spec requires that the decoration object is deleted before xdg_toplevel.
+ delete m_decoration;
+ m_decoration = nullptr;
+@@ -85,16 +80,15 @@ void QWaylandXdgSurface::Toplevel::applyConfigure()
+ if (!(m_applied.states & (Qt::WindowMaximized|Qt::WindowFullScreen)))
+ 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)
++ && !m_xdgSurface->m_window->display()->isKeyboardAvailable())
+ 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)
++ && !m_xdgSurface->m_window->display()->isKeyboardAvailable())
+ m_xdgSurface->m_window->display()->handleWindowDeactivated(m_xdgSurface->m_window);
+
+- // TODO: none of the other plugins send WindowActive either, but is it on purpose?
+- Qt::WindowStates statesWithoutActive = m_pending.states & ~Qt::WindowActive;
+-
+- m_xdgSurface->m_window->handleWindowStatesChanged(statesWithoutActive);
++ m_xdgSurface->m_window->handleWindowStatesChanged(m_pending.states);
+
+ if (m_pending.size.isEmpty()) {
+ // An empty size in the configure means it's up to the client to choose the size
+@@ -105,8 +99,6 @@ void QWaylandXdgSurface::Toplevel::applyConfigure()
+ m_xdgSurface->m_window->resizeFromApplyConfigure(m_pending.size);
+ }
+
+- m_xdgSurface->setSizeHints();
+-
+ m_applied = m_pending;
+ qCDebug(lcQpaWayland) << "Applied pending xdg_toplevel configure event:" << m_applied.size << m_applied.states;
+ }
+@@ -203,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()
+@@ -216,10 +213,24 @@ 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
++ QWindow *leave = nullptr;
++ if (m_xdgSurface && m_xdgSurface->window())
++ leave = m_xdgSurface->window()->window();
++ QWindowSystemInterface::handleLeaveEvent(leave);
++
++ if (QWindow *enter = QGuiApplication::topLevelAt(QCursor::pos()))
++ QWindowSystemInterface::handleEnterEvent(enter, enter->mapFromGlobal(QCursor::pos()), QCursor::pos());
+ }
+ }
+
+@@ -257,6 +268,7 @@ QWaylandXdgSurface::QWaylandXdgSurface(QWaylandXdgShell *shell, ::xdg_surface *s
+ m_toplevel->set_parent(parentXdgSurface->m_toplevel->object());
+ }
+ }
++ setSizeHints();
+ }
+
+ QWaylandXdgSurface::~QWaylandXdgSurface()
+@@ -400,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
+@@ -414,8 +424,9 @@ void QWaylandXdgSurface::setPopup(QWaylandWindow *parent)
+ positioner->set_anchor(QtWayland::xdg_positioner::anchor_top_left);
+ positioner->set_gravity(QtWayland::xdg_positioner::gravity_bottom_right);
+ positioner->set_size(m_window->geometry().width(), m_window->geometry().height());
+- m_popup = new Popup(this, parentXdgSurface, positioner);
++ m_popup = new Popup(this, parent, positioner);
+ positioner->destroy();
++
+ delete positioner;
+ }
+
+@@ -437,6 +448,23 @@ void QWaylandXdgSurface::setGrabPopup(QWaylandWindow *parent, QWaylandInputDevic
+ }
+ setPopup(parent);
+ m_popup->grab(device, serial);
++
++ // Synthesize Qt enter/leave events for popup
++ if (!parent)
++ return;
++ QWindow *current = QGuiApplication::topLevelAt(QCursor::pos());
++ QWindow *leave = parent->window();
++ if (current != leave)
++ return;
++
++ QWindowSystemInterface::handleLeaveEvent(leave);
++
++ QWindow *enter = nullptr;
++ if (m_popup && m_popup->m_xdgSurface && m_popup->m_xdgSurface->window())
++ enter = m_popup->m_xdgSurface->window()->window();
++
++ if (enter)
++ QWindowSystemInterface::handleEnterEvent(enter, enter->mapFromGlobal(QCursor::pos()), QCursor::pos());
+ }
+
+ void QWaylandXdgSurface::xdg_surface_configure(uint32_t serial)
+diff --git a/qtwayland/src/plugins/shellintegration/xdg-shell/qwaylandxdgshell_p.h b/qtwayland/src/plugins/shellintegration/xdg-shell/qwaylandxdgshell_p.h
+index 96785205..4b518f0a 100644
+--- a/qtwayland/src/plugins/shellintegration/xdg-shell/qwaylandxdgshell_p.h
++++ b/qtwayland/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/qtwayland/src/plugins/shellintegration/xdg-shell/qwaylandxdgshellintegration.cpp b/qtwayland/src/plugins/shellintegration/xdg-shell/qwaylandxdgshellintegration.cpp
+index 8769d971..da0dd6a7 100644
+--- a/qtwayland/src/plugins/shellintegration/xdg-shell/qwaylandxdgshellintegration.cpp
++++ b/qtwayland/src/plugins/shellintegration/xdg-shell/qwaylandxdgshellintegration.cpp
+@@ -69,20 +69,6 @@ QWaylandShellSurface *QWaylandXdgShellIntegration::createShellSurface(QWaylandWi
+ return m_xdgShell->getXdgSurface(window);
+ }
+
+-void QWaylandXdgShellIntegration::handleKeyboardFocusChanged(QWaylandWindow *newFocus, QWaylandWindow *oldFocus)
+-{
+- if (newFocus) {
+- auto *xdgSurface = qobject_cast<QWaylandXdgSurface *>(newFocus->shellSurface());
+- if (xdgSurface && !xdgSurface->handlesActiveState())
+- m_display->handleWindowActivated(newFocus);
+- }
+- if (oldFocus && qobject_cast<QWaylandXdgSurface *>(oldFocus->shellSurface())) {
+- auto *xdgSurface = qobject_cast<QWaylandXdgSurface *>(oldFocus->shellSurface());
+- if (xdgSurface && !xdgSurface->handlesActiveState())
+- m_display->handleWindowDeactivated(oldFocus);
+- }
+-}
+-
+ }
+
+ QT_END_NAMESPACE
+diff --git a/qtwayland/src/plugins/shellintegration/xdg-shell/qwaylandxdgshellintegration_p.h b/qtwayland/src/plugins/shellintegration/xdg-shell/qwaylandxdgshellintegration_p.h
+index b6caa6c9..2f929f98 100644
+--- a/qtwayland/src/plugins/shellintegration/xdg-shell/qwaylandxdgshellintegration_p.h
++++ b/qtwayland/src/plugins/shellintegration/xdg-shell/qwaylandxdgshellintegration_p.h
+@@ -65,7 +65,6 @@ public:
+ QWaylandXdgShellIntegration() {}
+ bool initialize(QWaylandDisplay *display) override;
+ QWaylandShellSurface *createShellSurface(QWaylandWindow *window) override;
+- void handleKeyboardFocusChanged(QWaylandWindow *newFocus, QWaylandWindow *oldFocus) override;
+
+ private:
+ QScopedPointer<QWaylandXdgShell> m_xdgShell;
+diff --git a/qtwayland/src/shared/qwaylandinputmethodeventbuilder.cpp b/qtwayland/src/shared/qwaylandinputmethodeventbuilder.cpp
+index 526d0ef4..f50ccf30 100644
+--- a/qtwayland/src/shared/qwaylandinputmethodeventbuilder.cpp
++++ b/qtwayland/src/shared/qwaylandinputmethodeventbuilder.cpp
+@@ -39,7 +39,10 @@
+
+ #include "qwaylandinputmethodeventbuilder_p.h"
+
++#include <QBrush>
++#include <QGuiApplication>
+ #include <QInputMethod>
++#include <QPalette>
+ #include <QTextCharFormat>
+
+ #ifdef QT_BUILD_WAYLANDCOMPOSITOR_LIB
+@@ -81,32 +84,38 @@ void QWaylandInputMethodEventBuilder::addPreeditStyling(uint32_t index, uint32_t
+ QTextCharFormat format;
+
+ switch (style) {
+- case 0:
+- case 1:
++ case ZWP_TEXT_INPUT_V2_PREEDIT_STYLE_NONE:
++ break;
++ case ZWP_TEXT_INPUT_V2_PREEDIT_STYLE_DEFAULT:
++ case ZWP_TEXT_INPUT_V2_PREEDIT_STYLE_UNDERLINE:
+ format.setFontUnderline(true);
+ format.setUnderlineStyle(QTextCharFormat::SingleUnderline);
+ m_preeditStyles.append(QInputMethodEvent::Attribute(QInputMethodEvent::TextFormat, index, length, format));
+ break;
+- case 2:
+- case 3:
++ case ZWP_TEXT_INPUT_V2_PREEDIT_STYLE_ACTIVE:
++ case ZWP_TEXT_INPUT_V2_PREEDIT_STYLE_INACTIVE:
+ format.setFontWeight(QFont::Bold);
+ format.setFontUnderline(true);
+ format.setUnderlineStyle(QTextCharFormat::SingleUnderline);
+ m_preeditStyles.append(QInputMethodEvent::Attribute(QInputMethodEvent::TextFormat, index, length, format));
+ break;
+- case 4:
+- format.setFontUnderline(true);
+- format.setUnderlineStyle(QTextCharFormat::SingleUnderline);
+- m_preeditStyles.append(QInputMethodEvent::Attribute(QInputMethodEvent::TextFormat, index, length, format));
++ case ZWP_TEXT_INPUT_V2_PREEDIT_STYLE_HIGHLIGHT:
++ case ZWP_TEXT_INPUT_V2_PREEDIT_STYLE_SELECTION:
++ {
++ format.setFontUnderline(true);
++ format.setUnderlineStyle(QTextCharFormat::SingleUnderline);
++ QPalette palette = qApp->palette();
++ format.setBackground(QBrush(palette.color(QPalette::Active, QPalette::Highlight)));
++ format.setForeground(QBrush(palette.color(QPalette::Active, QPalette::HighlightedText)));
++ m_preeditStyles.append(QInputMethodEvent::Attribute(QInputMethodEvent::TextFormat, index, length, format));
++ }
+ break;
+- case 5:
++ case ZWP_TEXT_INPUT_V2_PREEDIT_STYLE_INCORRECT:
+ format.setFontUnderline(true);
+ format.setUnderlineStyle(QTextCharFormat::WaveUnderline);
+ format.setUnderlineColor(QColor(Qt::red));
+ m_preeditStyles.append(QInputMethodEvent::Attribute(QInputMethodEvent::TextFormat, index, length, format));
+ break;
+-// case QtWayland::wl_text_input::preedit_style_selection:
+-// case QtWayland::wl_text_input::preedit_style_none:
+ default:
+ break;
+ }
+@@ -153,7 +162,7 @@ QInputMethodEvent QWaylandInputMethodEventBuilder::buildPreedit(const QString &t
+
+ if (m_preeditCursor < 0) {
+ attributes.append(QInputMethodEvent::Attribute(QInputMethodEvent::Cursor, 0, 0, QVariant()));
+- } else if (m_preeditCursor > 0) {
++ } else {
+ attributes.append(QInputMethodEvent::Attribute(QInputMethodEvent::Cursor, indexFromWayland(text, m_preeditCursor), 1, QVariant()));
+ }
+
+diff --git a/qtwayland/src/shared/qwaylandmimehelper.cpp b/qtwayland/src/shared/qwaylandmimehelper.cpp
+index a5fdd34d..e2fe1928 100644
+--- a/qtwayland/src/shared/qwaylandmimehelper.cpp
++++ b/qtwayland/src/shared/qwaylandmimehelper.cpp
+@@ -60,7 +60,7 @@ QByteArray QWaylandMimeHelper::getByteArray(QMimeData *mimeData, const QString &
+ buf.open(QIODevice::ReadWrite);
+ QByteArray fmt = "BMP";
+ if (mimeType.startsWith(QLatin1String("image/"))) {
+- QByteArray imgFmt = mimeType.mid(6).toUpper().toLatin1();
++ QByteArray imgFmt = mimeType.mid(6).toLower().toLatin1();
+ if (QImageWriter::supportedImageFormats().contains(imgFmt))
+ fmt = imgFmt;
+ }
+@@ -74,7 +74,7 @@ QByteArray QWaylandMimeHelper::getByteArray(QMimeData *mimeData, const QString &
+ QList<QUrl> urls = mimeData->urls();
+ for (int i = 0; i < urls.count(); ++i) {
+ content.append(urls.at(i).toEncoded());
+- content.append('\n');
++ content.append("\r\n");
+ }
+ } else {
+ content = mimeData->data(mimeType);
+diff --git a/qtwayland/tests/auto/client/datadevicev1/tst_datadevicev1.cpp b/qtwayland/tests/auto/client/datadevicev1/tst_datadevicev1.cpp
+index 1568b3b9..067410d0 100644
+--- a/qtwayland/tests/auto/client/datadevicev1/tst_datadevicev1.cpp
++++ b/qtwayland/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:
+diff --git a/qtwayland/tests/auto/client/seatv5/tst_seatv5.cpp b/qtwayland/tests/auto/client/seatv5/tst_seatv5.cpp
+index 9312c2e5..2ea382f1 100644
+--- a/qtwayland/tests/auto/client/seatv5/tst_seatv5.cpp
++++ b/qtwayland/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, Qt::TouchPointPressed);
++ QCOMPARE(e.touchPoints.length(), 1);
++ QCOMPARE(e.touchPoints.first().pos(), 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/qtwayland/tests/auto/client/shared/corecompositor.cpp b/qtwayland/tests/auto/client/shared/corecompositor.cpp
+index 5c6c83ba..fa9b7662 100644
+--- a/qtwayland/tests/auto/client/shared/corecompositor.cpp
++++ b/qtwayland/tests/auto/client/shared/corecompositor.cpp
+@@ -27,6 +27,7 @@
+ ****************************************************************************/
+
+ #include "corecompositor.h"
++#include <thread>
+
+ namespace MockCompositor {
+
+diff --git a/qtwayland/tests/auto/client/shared/coreprotocol.cpp b/qtwayland/tests/auto/client/shared/coreprotocol.cpp
+index 0d988521..d1a2e7cb 100644
+--- a/qtwayland/tests/auto/client/shared/coreprotocol.cpp
++++ b/qtwayland/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/qtwayland/tests/auto/client/shared/coreprotocol.h b/qtwayland/tests/auto/client/shared/coreprotocol.h
+index a1af137a..210d8ddb 100644
+--- a/qtwayland/tests/auto/client/shared/coreprotocol.h
++++ b/qtwayland/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)
+ {}
+@@ -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;
+ };
+diff --git a/qtwayland/tests/auto/client/shared_old/mockcompositor.cpp b/qtwayland/tests/auto/client/shared_old/mockcompositor.cpp
+index a415cbf5..b1d3d07d 100644
+--- a/qtwayland/tests/auto/client/shared_old/mockcompositor.cpp
++++ b/qtwayland/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/qtwayland/tests/auto/client/shared_old/mocksurface.cpp b/qtwayland/tests/auto/client/shared_old/mocksurface.cpp
+index e9df5f90..c3246e4a 100644
+--- a/qtwayland/tests/auto/client/shared_old/mocksurface.cpp
++++ b/qtwayland/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/qtwayland/tests/auto/client/shared_old/mocksurface.h b/qtwayland/tests/auto/client/shared_old/mocksurface.h
+index 949dc23d..d176837e 100644
+--- a/qtwayland/tests/auto/client/shared_old/mocksurface.h
++++ b/qtwayland/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;
+diff --git a/qtwayland/tests/auto/client/surface/tst_surface.cpp b/qtwayland/tests/auto/client/surface/tst_surface.cpp
+index 95e4e609..60c672ce 100644
+--- a/qtwayland/tests/auto/client/surface/tst_surface.cpp
++++ b/qtwayland/tests/auto/client/surface/tst_surface.cpp
+@@ -129,6 +129,10 @@ void tst_surface::waitForFrameCallbackGl()
+ // Make sure we follow frame callbacks for some frames
+ for (int i = 0; i < 5; ++i) {
+ xdgPingAndWaitForPong(); // Make sure things have happened on the client
++ if (!qEnvironmentVariableIntValue("QT_WAYLAND_DISABLE_WINDOWDECORATION") && i == 0) {
++ QCOMPARE(bufferSpy.count(), 1);
++ bufferSpy.removeFirst();
++ }
+ exec([&] {
+ QVERIFY(bufferSpy.empty()); // Make sure no extra buffers have arrived
+ QVERIFY(!xdgToplevel()->surface()->m_waitingFrameCallbacks.empty());
+diff --git a/qtwayland/tests/auto/client/xdgshell/tst_xdgshell.cpp b/qtwayland/tests/auto/client/xdgshell/tst_xdgshell.cpp
+index 2277bbb8..747875b4 100644
+--- a/qtwayland/tests/auto/client/xdgshell/tst_xdgshell.cpp
++++ b/qtwayland/tests/auto/client/xdgshell/tst_xdgshell.cpp
+@@ -31,6 +31,7 @@
+ #include <QtGui/QOpenGLWindow>
+ #include <QtGui/qpa/qplatformnativeinterface.h>
+ #include <QtWaylandClient/private/wayland-wayland-client-protocol.h>
++#include <QtWaylandClient/private/qwaylandwindow_p.h>
+
+ using namespace MockCompositor;
+
+@@ -45,6 +46,7 @@ private slots:
+ void configureStates();
+ void popup();
+ void tooltipOnPopup();
++ void tooltipAndSiblingPopup();
+ void switchPopups();
+ void hidePopupParent();
+ void pongs();
+@@ -138,6 +140,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();
+@@ -154,9 +157,12 @@ void tst_xdgshell::configureStates()
+ // 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
+
+-// QEXPECT_FAIL("", "configure has already been acked, we shouldn't have to wait for isActive", Continue);
+-// QVERIFY(window.isActive());
+- QTRY_VERIFY(window.isActive()); // Just make sure it eventually get's set correctly
++ // window.windowstate() is driven by keyboard focus, however for decorations we want to follow
++ // XDGShell this is internal to QtWayland so it is queried directly
++ auto waylandWindow = static_cast<QtWaylandClient::QWaylandWindow *>(window.handle());
++ Q_ASSERT(waylandWindow);
++ QTRY_VERIFY(waylandWindow->windowStates().testFlag(
++ Qt::WindowActive)); // Just make sure it eventually get's set correctly
+
+ const QSize screenSize(640, 480);
+ const uint maximizedSerial = exec([=] {
+@@ -186,6 +192,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()
+@@ -340,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()
+ {
+@@ -505,7 +598,7 @@ void tst_xdgshell::minMaxSize()
+ window.show();
+ QCOMPOSITOR_TRY_VERIFY(xdgToplevel());
+
+- exec([=] { xdgToplevel()->sendCompleteConfigure(); });
++ // we don't roundtrip with our configuration the initial commit should be correct
+
+ QCOMPOSITOR_TRY_COMPARE(xdgToplevel()->m_committed.minSize, QSize(100, 100));
+ QCOMPOSITOR_TRY_COMPARE(xdgToplevel()->m_committed.maxSize, QSize(1000, 1000));
+Submodule qtwebchannel 618422ee..f8949655:
+diff --git a/qtwebchannel/src/webchannel/qmetaobjectpublisher.cpp b/qtwebchannel/src/webchannel/qmetaobjectpublisher.cpp
+index 536eb5c..898d769 100644
+--- a/qtwebchannel/src/webchannel/qmetaobjectpublisher.cpp
++++ b/qtwebchannel/src/webchannel/qmetaobjectpublisher.cpp
+@@ -186,8 +186,6 @@ Q_DECLARE_TYPEINFO(OverloadResolutionCandidate, Q_MOVABLE_TYPE);
+ QMetaObjectPublisher::QMetaObjectPublisher(QWebChannel *webChannel)
+ : QObject(webChannel)
+ , webChannel(webChannel)
+- , signalHandler(this)
+- , clientIsIdle(false)
+ , blockUpdates(false)
+ , propertyUpdatesInitialized(false)
+ {
+@@ -301,17 +299,17 @@ QJsonObject QMetaObjectPublisher::classInfoForObject(const QObject *object, QWeb
+ return data;
+ }
+
+-void QMetaObjectPublisher::setClientIsIdle(bool isIdle)
++void QMetaObjectPublisher::setClientIsIdle(bool isIdle, QWebChannelAbstractTransport *transport)
+ {
+- if (clientIsIdle == isIdle) {
+- return;
+- }
+- clientIsIdle = isIdle;
+- if (!isIdle && timer.isActive()) {
+- timer.stop();
+- } else if (isIdle && !timer.isActive()) {
+- timer.start(PROPERTY_UPDATE_INTERVAL, this);
+- }
++ transportState[transport].clientIsIdle = isIdle;
++ if (isIdle)
++ sendEnqueuedPropertyUpdates(transport);
++}
++
++bool QMetaObjectPublisher::isClientIdle(QWebChannelAbstractTransport *transport)
++{
++ auto found = transportState.find(transport);
++ return found != transportState.end() && found.value().clientIsIdle;
+ }
+
+ QJsonObject QMetaObjectPublisher::initializeClient(QWebChannelAbstractTransport *transport)
+@@ -333,6 +331,7 @@ QJsonObject QMetaObjectPublisher::initializeClient(QWebChannelAbstractTransport
+
+ void QMetaObjectPublisher::initializePropertyUpdates(const QObject *const object, const QJsonObject &objectInfo)
+ {
++ auto *signalHandler = signalHandlerFor(object);
+ foreach (const QJsonValue &propertyInfoVar, objectInfo[KEY_PROPERTIES].toArray()) {
+ const QJsonArray &propertyInfo = propertyInfoVar.toArray();
+ if (propertyInfo.size() < 2) {
+@@ -353,19 +352,19 @@ void QMetaObjectPublisher::initializePropertyUpdates(const QObject *const object
+
+ // Only connect for a property update once
+ if (connectedProperties.isEmpty()) {
+- signalHandler.connectTo(object, signalIndex);
++ signalHandler->connectTo(object, signalIndex);
+ }
+
+ connectedProperties.insert(propertyIndex);
+ }
+
+ // also always connect to destroyed signal
+- signalHandler.connectTo(object, s_destroyedSignalIndex);
++ signalHandler->connectTo(object, s_destroyedSignalIndex);
+ }
+
+ void QMetaObjectPublisher::sendPendingPropertyUpdates()
+ {
+- if (blockUpdates || !clientIsIdle || pendingPropertyUpdates.isEmpty()) {
++ if (blockUpdates) {
+ return;
+ }
+
+@@ -415,18 +414,19 @@ void QMetaObjectPublisher::sendPendingPropertyUpdates()
+
+ // data does not contain specific updates
+ if (!data.isEmpty()) {
+- setClientIsIdle(false);
+-
+ message[KEY_DATA] = data;
+- broadcastMessage(message);
++ enqueueBroadcastMessage(message);
+ }
+
+ // send every property update which is not supposed to be broadcasted
+ const QHash<QWebChannelAbstractTransport*, QJsonArray>::const_iterator suend = specificUpdates.constEnd();
+ for (QHash<QWebChannelAbstractTransport*, QJsonArray>::const_iterator it = specificUpdates.constBegin(); it != suend; ++it) {
+ message[KEY_DATA] = it.value();
+- it.key()->sendMessage(message);
++ enqueueMessage(message, it.key());
+ }
++
++ for (auto state = transportState.begin(); state != transportState.end(); ++state)
++ sendEnqueuedPropertyUpdates(state.key());
+ }
+
+ QVariant QMetaObjectPublisher::invokeMethod(QObject *const object, const QMetaMethod &method,
+@@ -572,7 +572,7 @@ void QMetaObjectPublisher::signalEmitted(const QObject *object, const int signal
+ }
+ } else {
+ pendingPropertyUpdates[object][signalIndex] = arguments;
+- if (clientIsIdle && !blockUpdates && !timer.isActive()) {
++ if (!blockUpdates && !timer.isActive()) {
+ timer.start(PROPERTY_UPDATE_INTERVAL, this);
+ }
+ }
+@@ -590,7 +590,7 @@ void QMetaObjectPublisher::objectDestroyed(const QObject *object)
+ // only remove from handler when we initialized the property updates
+ // cf: https://bugreports.qt.io/browse/QTBUG-60250
+ if (propertyUpdatesInitialized) {
+- signalHandler.remove(object);
++ signalHandlerFor(object)->remove(object);
+ signalToPropertyMap.remove(object);
+ }
+ pendingPropertyUpdates.remove(object);
+@@ -852,6 +852,52 @@ void QMetaObjectPublisher::broadcastMessage(const QJsonObject &message) const
+ }
+ }
+
++void QMetaObjectPublisher::enqueueBroadcastMessage(const QJsonObject &message)
++{
++ if (webChannel->d_func()->transports.isEmpty()) {
++ qWarning("QWebChannel is not connected to any transports, cannot send message: %s",
++ QJsonDocument(message).toJson().constData());
++ return;
++ }
++
++ for (auto *transport : webChannel->d_func()->transports) {
++ auto &state = transportState[transport];
++ state.queuedMessages.append(message);
++ }
++}
++
++void QMetaObjectPublisher::enqueueMessage(const QJsonObject &message,
++ QWebChannelAbstractTransport *transport)
++{
++ auto &state = transportState[transport];
++ state.queuedMessages.append(message);
++}
++
++void QMetaObjectPublisher::sendEnqueuedPropertyUpdates(QWebChannelAbstractTransport *transport)
++{
++ auto found = transportState.find(transport);
++ if (found != transportState.end() && found.value().clientIsIdle
++ && !found.value().queuedMessages.isEmpty()) {
++
++ // If the client is connected with an in-process transport, it can
++ // happen that a message triggers a subsequent property change. In
++ // that case, we need to ensure that the queued messages have already
++ // been cleared; otherwise the recursive call will send everythig again.
++ // Case in point: The qmlwebchannel tests fail if we don't clear the
++ // queued messages before sending them out.
++ // For that same reason set the client to "busy" (aka non-idle) just
++ // right before sending out the messages; otherwise a potential
++ // "Idle" type message will not correctly restore the Idle state.
++ const auto messages = std::move(found.value().queuedMessages);
++ Q_ASSERT(found.value().queuedMessages.isEmpty());
++ found.value().clientIsIdle = false;
++
++ for (const auto &message : messages) {
++ transport->sendMessage(message);
++ }
++ }
++}
++
+ void QMetaObjectPublisher::handleMessage(const QJsonObject &message, QWebChannelAbstractTransport *transport)
+ {
+ if (!webChannel->d_func()->transports.contains(transport)) {
+@@ -866,7 +912,7 @@ void QMetaObjectPublisher::handleMessage(const QJsonObject &message, QWebChannel
+
+ const MessageType type = toType(message.value(KEY_TYPE));
+ if (type == TypeIdle) {
+- setClientIsIdle(true);
++ setClientIsIdle(true, transport);
+ } else if (type == TypeInit) {
+ if (!message.contains(KEY_ID)) {
+ qWarning("JSON message object is missing the id property: %s",
+@@ -913,9 +959,9 @@ void QMetaObjectPublisher::handleMessage(const QJsonObject &message, QWebChannel
+ return;
+ transport->sendMessage(createResponse(message.value(KEY_ID), wrapResult(result, transport)));
+ } else if (type == TypeConnectToSignal) {
+- signalHandler.connectTo(object, message.value(KEY_SIGNAL).toInt(-1));
++ signalHandlerFor(object)->connectTo(object, message.value(KEY_SIGNAL).toInt(-1));
+ } else if (type == TypeDisconnectFromSignal) {
+- signalHandler.disconnectFrom(object, message.value(KEY_SIGNAL).toInt(-1));
++ signalHandlerFor(object)->disconnectFrom(object, message.value(KEY_SIGNAL).toInt(-1));
+ } else if (type == TypeSetProperty) {
+ setProperty(object, message.value(KEY_PROPERTY).toInt(-1),
+ message.value(KEY_VALUE));
+@@ -931,6 +977,7 @@ void QMetaObjectPublisher::setBlockUpdates(bool block)
+ blockUpdates = block;
+
+ if (!blockUpdates) {
++ timer.start(PROPERTY_UPDATE_INTERVAL, this);
+ sendPendingPropertyUpdates();
+ } else if (timer.isActive()) {
+ timer.stop();
+@@ -948,4 +995,15 @@ void QMetaObjectPublisher::timerEvent(QTimerEvent *event)
+ }
+ }
+
++SignalHandler<QMetaObjectPublisher> *QMetaObjectPublisher::signalHandlerFor(const QObject *object)
++{
++ auto thread = object->thread();
++ auto it = signalHandlers.find(thread);
++ if (it == signalHandlers.end()) {
++ it = signalHandlers.emplace(thread, this).first;
++ it->second.moveToThread(thread);
++ }
++ return &it->second;
++}
++
+ QT_END_NAMESPACE
+diff --git a/qtwebchannel/src/webchannel/qmetaobjectpublisher_p.h b/qtwebchannel/src/webchannel/qmetaobjectpublisher_p.h
+index bbd9875..4713ef1 100644
+--- a/qtwebchannel/src/webchannel/qmetaobjectpublisher_p.h
++++ b/qtwebchannel/src/webchannel/qmetaobjectpublisher_p.h
+@@ -59,6 +59,9 @@
+ #include <QBasicTimer>
+ #include <QPointer>
+ #include <QJsonObject>
++#include <QQueue>
++
++#include <unordered_map>
+
+ #include "qwebchannelglobal.h"
+
+@@ -109,17 +112,36 @@ public:
+ */
+ void broadcastMessage(const QJsonObject &message) const;
+
++ /**
++ * Enqueue the given @p message to all known transports.
++ */
++ void enqueueBroadcastMessage(const QJsonObject &message);
++
++ /**
++ * Enqueue the given @p message to @p transport.
++ */
++ void enqueueMessage(const QJsonObject &message, QWebChannelAbstractTransport *transport);
++
++ /**
++ * If client for given @p transport is idle, send queued messaged to @p transport and then mark
++ * the client as not idle.
++ */
++ void sendEnqueuedPropertyUpdates(QWebChannelAbstractTransport *transport);
++
+ /**
+ * Serialize the QMetaObject of @p object and return it in JSON form.
+ */
+ QJsonObject classInfoForObject(const QObject *object, QWebChannelAbstractTransport *transport);
+
+ /**
+- * Set the client to idle or busy, based on the value of @p isIdle.
+- *
+- * When the value changed, start/stop the property update timer accordingly.
++ * Set the client to idle or busy for a single @p transport, based on the value of @p isIdle.
++ */
++ void setClientIsIdle(bool isIdle, QWebChannelAbstractTransport *transport);
++
++ /**
++ * Check that client is idle for @p transport.
+ */
+- void setClientIsIdle(bool isIdle);
++ bool isClientIdle(QWebChannelAbstractTransport *transport);
+
+ /**
+ * Initialize clients by sending them the class information of the registered objects.
+@@ -272,10 +294,18 @@ private:
+ friend class TestWebChannel;
+
+ QWebChannel *webChannel;
+- SignalHandler<QMetaObjectPublisher> signalHandler;
++ std::unordered_map<const QThread*, SignalHandler<QMetaObjectPublisher>> signalHandlers;
++ SignalHandler<QMetaObjectPublisher> *signalHandlerFor(const QObject *object);
+
+- // true when the client is idle, false otherwise
+- bool clientIsIdle;
++ struct TransportState
++ {
++ TransportState() : clientIsIdle(false) { }
++ // true when the client is idle, false otherwise
++ bool clientIsIdle;
++ // messages to send
++ QQueue<QJsonObject> queuedMessages;
++ };
++ QHash<QWebChannelAbstractTransport *, TransportState> transportState;
+
+ // true when no property updates should be sent, false otherwise
+ bool blockUpdates;
+diff --git a/qtwebchannel/src/webchannel/signalhandler_p.h b/qtwebchannel/src/webchannel/signalhandler_p.h
+index 27afadb..d77373c 100644
+--- a/qtwebchannel/src/webchannel/signalhandler_p.h
++++ b/qtwebchannel/src/webchannel/signalhandler_p.h
+@@ -56,6 +56,7 @@
+ #include <QVector>
+ #include <QMetaMethod>
+ #include <QDebug>
++#include <QThread>
+
+ QT_BEGIN_NAMESPACE
+
+@@ -71,6 +72,7 @@ static const int s_destroyedSignalIndex = QObject::staticMetaObject.indexOfMetho
+ template<class Receiver>
+ class SignalHandler : public QObject
+ {
++ Q_DISABLE_COPY(SignalHandler)
+ public:
+ SignalHandler(Receiver *receiver, QObject *parent = 0);
+
+@@ -268,6 +270,7 @@ int SignalHandler<Receiver>::qt_metacall(QMetaObject::Call call, int methodId, v
+ if (call == QMetaObject::InvokeMetaMethod) {
+ const QObject *object = sender();
+ Q_ASSERT(object);
++ Q_ASSERT(QThread::currentThread() == object->thread());
+ Q_ASSERT(senderSignalIndex() == methodId);
+ Q_ASSERT(m_connectionsCounter.contains(object));
+ Q_ASSERT(m_connectionsCounter.value(object).contains(methodId));
+diff --git a/qtwebchannel/tests/auto/qml/testwebchannel.cpp b/qtwebchannel/tests/auto/qml/testwebchannel.cpp
+index 9891687..3ca81c2 100644
+--- a/qtwebchannel/tests/auto/qml/testwebchannel.cpp
++++ b/qtwebchannel/tests/auto/qml/testwebchannel.cpp
+@@ -46,7 +46,11 @@ TestWebChannel::~TestWebChannel()
+
+ bool TestWebChannel::clientIsIdle() const
+ {
+- return QWebChannel::d_func()->publisher->clientIsIdle;
++ for (auto *transport : QWebChannel::d_func()->transports) {
++ if (QWebChannel::d_func()->publisher->isClientIdle(transport))
++ return true;
++ }
++ return false;
+ }
+
+ QT_END_NAMESPACE
+diff --git a/qtwebchannel/tests/auto/webchannel/tst_webchannel.cpp b/qtwebchannel/tests/auto/webchannel/tst_webchannel.cpp
+index 181da9e..37f989a 100644
+--- a/qtwebchannel/tests/auto/webchannel/tst_webchannel.cpp
++++ b/qtwebchannel/tests/auto/webchannel/tst_webchannel.cpp
+@@ -785,7 +785,7 @@ void TestWebChannel::testTransportWrapObjectProperties()
+ DummyTransport *dummyTransport = new DummyTransport(this);
+ channel.connectTo(dummyTransport);
+ channel.d_func()->publisher->initializeClient(dummyTransport);
+- channel.d_func()->publisher->setClientIsIdle(true);
++ channel.d_func()->publisher->setClientIsIdle(true, dummyTransport);
+
+ QCOMPARE(channel.d_func()->publisher->transportedWrappedObjects.size(), 0);
+
+@@ -943,8 +943,6 @@ void TestWebChannel::testInfiniteRecursion()
+
+ void TestWebChannel::testAsyncObject()
+ {
+- QSKIP("This test is broken. See QTBUG-80729");
+-
+ QWebChannel channel;
+ channel.connectTo(m_dummyTransport);
+
+@@ -990,6 +988,50 @@ void TestWebChannel::testAsyncObject()
+ thread.wait();
+ }
+
++void TestWebChannel::testPropertyMultipleTransports()
++{
++ DummyTransport transport1;
++ DummyTransport transport2;
++
++ QWebChannel channel;
++ QMetaObjectPublisher *publisher = channel.d_func()->publisher;
++
++ TestObject testObj;
++ testObj.setObjectName("testObject");
++ channel.registerObject(testObj.objectName(), &testObj);
++ channel.connectTo(&transport1);
++ channel.connectTo(&transport2);
++
++ testObj.setProp("Hello");
++
++ publisher->initializeClient(&transport1);
++ publisher->initializeClient(&transport2);
++ publisher->setClientIsIdle(true, &transport1);
++ QCOMPARE(publisher->isClientIdle(&transport1), true);
++ QCOMPARE(publisher->isClientIdle(&transport2), false);
++ QVERIFY(transport1.messagesSent().isEmpty());
++ QVERIFY(transport2.messagesSent().isEmpty());
++
++ testObj.setProp("World");
++ QTRY_COMPARE_WITH_TIMEOUT(transport1.messagesSent().size(), 1u, 2000);
++ QCOMPARE(transport2.messagesSent().size(), 0u);
++ publisher->setClientIsIdle(true, &transport2);
++ QTRY_COMPARE_WITH_TIMEOUT(transport2.messagesSent().size(), 1u, 2000);
++ QCOMPARE(publisher->isClientIdle(&transport1), false);
++ QCOMPARE(publisher->isClientIdle(&transport2), false);
++
++ testObj.setProp("!!!");
++ publisher->setClientIsIdle(true, &transport2);
++ QCOMPARE(publisher->isClientIdle(&transport2), true);
++ QCOMPARE(publisher->isClientIdle(&transport1), false);
++ QTRY_COMPARE_WITH_TIMEOUT(transport2.messagesSent().size(), 2u, 2000);
++ QCOMPARE(transport1.messagesSent().size(), 1u);
++ publisher->setClientIsIdle(true, &transport1);
++ QTRY_COMPARE_WITH_TIMEOUT(transport1.messagesSent().size(), 2u, 2000);
++ QCOMPARE(publisher->isClientIdle(&transport1), false);
++ QCOMPARE(publisher->isClientIdle(&transport2), false);
++}
++
+ class FunctionWrapper : public QObject
+ {
+ Q_OBJECT
+@@ -1082,7 +1124,7 @@ void TestWebChannel::benchInitializeClients()
+
+ publisher->propertyUpdatesInitialized = false;
+ publisher->signalToPropertyMap.clear();
+- publisher->signalHandler.clear();
++ publisher->signalHandlers.clear();
+ }
+ }
+
+@@ -1107,7 +1149,7 @@ void TestWebChannel::benchPropertyUpdates()
+ obj->change();
+ }
+
+- channel.d_func()->publisher->clientIsIdle = true;
++ channel.d_func()->publisher->setClientIsIdle(true, m_dummyTransport);
+ channel.d_func()->publisher->sendPendingPropertyUpdates();
+ }
+ }
+diff --git a/qtwebchannel/tests/auto/webchannel/tst_webchannel.h b/qtwebchannel/tests/auto/webchannel/tst_webchannel.h
+index eae21f4..dd4e690 100644
+--- a/qtwebchannel/tests/auto/webchannel/tst_webchannel.h
++++ b/qtwebchannel/tests/auto/webchannel/tst_webchannel.h
+@@ -348,6 +348,7 @@ private slots:
+ void testJsonToVariant();
+ void testInfiniteRecursion();
+ void testAsyncObject();
++ void testPropertyMultipleTransports();
+ void testDeletionDuringMethodInvocation_data();
+ void testDeletionDuringMethodInvocation();
+
+Submodule qtwebengine f328054d...38e0df6c (commits not present)
+Submodule qtwebsockets 65850954..63fb8da1:
+diff --git a/qtwebsockets/src/websockets/qwebsocketdataprocessor.cpp b/qtwebsockets/src/websockets/qwebsocketdataprocessor.cpp
+index 2affdd5..95f1194 100644
+--- a/qtwebsockets/src/websockets/qwebsocketdataprocessor.cpp
++++ b/qtwebsockets/src/websockets/qwebsocketdataprocessor.cpp
+@@ -273,6 +273,7 @@ void QWebSocketDataProcessor::clear()
+ if (!m_pConverterState)
+ m_pConverterState = new QTextCodec::ConverterState(QTextCodec::ConvertInvalidToNull |
+ QTextCodec::IgnoreHeader);
++ frame.clear();
+ }
+
+ /*!
+diff --git a/qtwebsockets/src/websockets/qwebsocketprotocol.cpp b/qtwebsockets/src/websockets/qwebsocketprotocol.cpp
+index df87a93..d0465f1 100644
+--- a/qtwebsockets/src/websockets/qwebsocketprotocol.cpp
++++ b/qtwebsockets/src/websockets/qwebsocketprotocol.cpp
+@@ -210,7 +210,7 @@ void QWebSocketProtocol::mask(char *payload, quint64 size, quint32 maskingKey)
+ quint8((maskingKey & 0x0000FF00u) >> 8),
+ quint8((maskingKey & 0x000000FFu))
+ };
+- int i = 0;
++ quint64 i = 0;
+ while (size-- > 0)
+ *payload++ ^= mask[i++ % 4];
+ }
diff --git a/srcpkgs/qt5/template b/srcpkgs/qt5/template
index e0463e1c9198..ca1800ce9dc2 100644
--- a/srcpkgs/qt5/template
+++ b/srcpkgs/qt5/template
@@ -2,11 +2,11 @@
#
# revbump libqtxdg after bumping patch version
pkgname=qt5
-version=5.15.7+20221119
+version=5.15.8
+revision=1
+build_style=meta
# commit f8c9fb304bc3e53b3aa07f962cd74e9160decccc
# base repo: https://invent.kde.org/qt/qt/qt5
-revision=4
-build_style=meta
hostmakedepends="cmake clang flex perl glib-devel pkg-config
python re2c ruby which"
makedepends="SDL2-devel Vulkan-Headers alsa-lib-devel double-conversion-devel
@@ -29,8 +29,9 @@ homepage="https://qt.io/"
# tarball is generated with `git archive-all qt5-$version.tar.gz`
# to keep the size smaller qtwebengine, qtwebview, qtdocgallery, qtactiveqt and qtpim
# can be marked with the export-ignore attribute
-distfiles="https://void.johnnynator.dev/distfiles/qt5-${version}.tar.gz"
-checksum=9d57af471c78029a362276b7c99108ea009f511bb9ba6ff6cb884f6ddd255e9f
+#distfiles="https://void.johnnynator.dev/distfiles/qt5-${version}.tar.gz"
+distfiles="https://download.qt.io/archive/qt/5.15/${version}/single/qt-everywhere-opensource-src-${version}.tar.xz"
+checksum=776a9302c336671f9406a53bd30b8e36f825742b2ec44a57c08217bff0fa86b9
python_version=2 #unverified
replaces="qt5-doc<5.6.0 qt5-quick1<5.6.0 qt5-quick1-devel<5.6.0 qt5-webkit<5.6.0 qt5-webkit-devel<5.6.0
qt5-enginio<5.7.1 qt5-enginio-devel<5.7.1 qt5-plugin-gtk<5.7.1 qt5-canvas3d<5.13.0"
@@ -248,7 +249,6 @@ do_configure() {
# opts+=" -v"
opts+=" -skip qtwebengine"
opts+=" -skip qtwebview"
- opts+=" -skip qtdocgallery"
opts+=" -skip qtpim"
opts+=" -skip qtsystems"
opts+=" -skip qtspeech"
From ceb43f2aee8105b7cbf0daa7fc44cc3ef2984437 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:51 -0400
Subject: [PATCH 078/110] qt6-multimedia: revbump for ffmpeg-6.0
---
srcpkgs/qt6-multimedia/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/qt6-multimedia/template b/srcpkgs/qt6-multimedia/template
index d89e7d54eb5a..aae15e57ca7b 100644
--- a/srcpkgs/qt6-multimedia/template
+++ b/srcpkgs/qt6-multimedia/template
@@ -1,7 +1,7 @@
# Template file for 'qt6-multimedia'
pkgname=qt6-multimedia
version=6.4.2
-revision=1
+revision=2
build_style=cmake
configure_args="-DQT_FEATURE_gstreamer=ON"
hostmakedepends="perl qt6-declarative-host-tools pkg-config qt6-shadertools"
From 497f4fc6016b0987051fd6b383583d5630ab5689 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:51 -0400
Subject: [PATCH 079/110] qtav: revbump for ffmpeg4-4.4.3
---
srcpkgs/qtav/template | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/srcpkgs/qtav/template b/srcpkgs/qtav/template
index 34c30b2c0c78..2d00ad104355 100644
--- a/srcpkgs/qtav/template
+++ b/srcpkgs/qtav/template
@@ -1,10 +1,10 @@
# Template file for 'qtav'
pkgname=qtav
version=1.13.0
-revision=1
+revision=2
build_style=qmake
hostmakedepends="qt5-qmake qt5-host-tools"
-makedepends="ffmpeg-devel libass-devel libopenal-devel
+makedepends="ffmpeg4-devel libass-devel libopenal-devel
libva-glx-devel libXv-devel pulseaudio-devel
qt5-declarative-devel qt5-svg-devel
qt5-quickcontrols"
From 780df5f0e8766c14b09e548edbba07cbb0f53085 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:51 -0400
Subject: [PATCH 080/110] qtox: revbump for ffmpeg-6.0
---
srcpkgs/qtox/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/qtox/template b/srcpkgs/qtox/template
index 16019d7eaec9..5cea0b11b697 100644
--- a/srcpkgs/qtox/template
+++ b/srcpkgs/qtox/template
@@ -1,7 +1,7 @@
# Template file for 'qtox'
pkgname=qtox
version=1.17.6
-revision=2
+revision=3
build_style=cmake
configure_args="-DUPDATE_CHECK=OFF
-DGIT_DESCRIBE=${version}
From 95e70674c9f1128d3b2121d791e3e38bc49dd1f6 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:51 -0400
Subject: [PATCH 081/110] retroarch: revbump for ffmpeg-6.0
---
srcpkgs/retroarch/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/retroarch/template b/srcpkgs/retroarch/template
index 240d3df9db00..6d0b16ae2598 100644
--- a/srcpkgs/retroarch/template
+++ b/srcpkgs/retroarch/template
@@ -1,7 +1,7 @@
# Template file for 'retroarch'
pkgname=retroarch
version=1.14.0
-revision=1
+revision=2
build_style=configure
configure_args="--prefix=/usr --sysconfdir=/etc --enable-networking
--enable-udev --disable-builtinflac --disable-builtinglslang
From ef6b21095b8db3cbf4a58048903bd2ed0d7a37a4 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:51 -0400
Subject: [PATCH 082/110] scrcpy: revbump for ffmpeg-6.0
---
srcpkgs/scrcpy/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/scrcpy/template b/srcpkgs/scrcpy/template
index ee6e698e387f..8ada5ca4323f 100644
--- a/srcpkgs/scrcpy/template
+++ b/srcpkgs/scrcpy/template
@@ -1,7 +1,7 @@
# Template file for 'scrcpy'
pkgname=scrcpy
version=2.0
-revision=1
+revision=2
build_style=meson
configure_args="-Dcompile_server=false
-Dprebuilt_server=/usr/share/scrcpy/scrcpy-server-v${version}"
From f43c95897ec2557208adceaa2ea515548fb5aafc Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:51 -0400
Subject: [PATCH 083/110] spek-alternative: revbump for ffmpeg4-4.4.3
---
srcpkgs/spek-alternative/template | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/srcpkgs/spek-alternative/template b/srcpkgs/spek-alternative/template
index d65086b8f008..05246f1b8d0c 100644
--- a/srcpkgs/spek-alternative/template
+++ b/srcpkgs/spek-alternative/template
@@ -1,11 +1,11 @@
# Template file for 'spek-alternative'
pkgname=spek-alternative
version=0.8.2.3
-revision=1
+revision=2
build_style=gnu-configure
hostmakedepends="automake gettext-devel intltool libtool pkg-config wxWidgets-common"
-makedepends="ffmpeg-devel wxWidgets-gtk3-devel"
-depends="ffmpeg"
+makedepends="ffmpeg4-devel wxWidgets-gtk3-devel"
+depends="ffmpeg4"
short_desc="Acoustic spectrum analyser"
maintainer="Kartik Singh <kartik.ynwa@gmail.com>"
license="GPL-3.0-or-later"
From 7860618e990d9d8d68ec13049cd24ba38cbcf6c9 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:51 -0400
Subject: [PATCH 084/110] ssr: revbump for ffmpeg4-4.4.3
---
srcpkgs/ssr/template | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/srcpkgs/ssr/template b/srcpkgs/ssr/template
index b055b9ec0774..3448ca110eb0 100644
--- a/srcpkgs/ssr/template
+++ b/srcpkgs/ssr/template
@@ -1,11 +1,11 @@
# Template file for 'ssr'
pkgname=ssr
version=0.4.4
-revision=1
+revision=2
build_style=cmake
configure_args="-DWITH_QT5=ON"
hostmakedepends="pkg-config"
-makedepends="alsa-lib-devel ffmpeg-devel glu-devel jack-devel pulseaudio-devel
+makedepends="alsa-lib-devel ffmpeg4-devel glu-devel jack-devel pulseaudio-devel
qt5-tools-devel qt5-x11extras-devel libXinerama-devel v4l-utils-devel"
depends="desktop-file-utils hicolor-icon-theme"
short_desc="Simple Screen Recorder for programs and games"
From dfa84ffec0fc3ec7cfbb4666e2e7227f3db4d617 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:51 -0400
Subject: [PATCH 085/110] sumo: revbump for ffmpeg-6.0
---
srcpkgs/sumo/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/sumo/template b/srcpkgs/sumo/template
index 0f9b9ec815f5..a3fe134aa5ac 100644
--- a/srcpkgs/sumo/template
+++ b/srcpkgs/sumo/template
@@ -1,7 +1,7 @@
# Template file for 'sumo'
pkgname=sumo
version=1.12.0
-revision=5
+revision=6
build_style=cmake
hostmakedepends="libgdal-tools pkg-config swig python3-setuptools"
makedepends="python3-devel ffmpeg-devel fox-devel gl2ps-devel libgdal-devel
From 73eab171c21ee2c32b9e8c70568245bb7eccb6b0 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:52 -0400
Subject: [PATCH 086/110] synfig: revbump for ffmpeg-6.0 and mlt7
---
srcpkgs/synfig/patches/ffmpeg6.patch | 71 ++++++++++++++++++++++++++++
srcpkgs/synfig/template | 4 +-
2 files changed, 73 insertions(+), 2 deletions(-)
create mode 100644 srcpkgs/synfig/patches/ffmpeg6.patch
diff --git a/srcpkgs/synfig/patches/ffmpeg6.patch b/srcpkgs/synfig/patches/ffmpeg6.patch
new file mode 100644
index 000000000000..10780b42782f
--- /dev/null
+++ b/srcpkgs/synfig/patches/ffmpeg6.patch
@@ -0,0 +1,71 @@
+--- a/src/modules/mod_libavcodec/trgt_av.cpp 2022-10-25 09:14:12.000000000 -0400
++++ b/src/modules/mod_libavcodec/trgt_av.cpp 2023-05-05 21:34:17.899194559 -0400
+@@ -38,6 +41,7 @@
+ extern "C"
+ {
+ #ifdef HAVE_LIBAVFORMAT_AVFORMAT_H
++# include <libavcodec/avcodec.h>
+ # include <libavformat/avformat.h>
+ #elif defined(HAVE_AVFORMAT_H)
+ # include <avformat.h>
+@@ -155,11 +156,11 @@
+ }
+
+ bool open_video_stream() {
+- if (avcodec_open2(video_context, NULL, NULL) < 0) {
++ if (avcodec_open2(video_context, nullptr, nullptr) < 0) {
+ synfig::error("Target_LibAVCodec: could not open video codec");
+ // seems the calling of avcodec_free_context after error will cause crash
+ // so just forget about this context
+- video_context = NULL;
++ video_context = nullptr;
+ close();
+ return false;
+ }
+@@ -234,15 +235,21 @@
+ close();
+
+ if (!av_registered) {
++#if LIBAVCODEC_VERSION_MAJOR < 58 // FFMPEG < 4.0
+ av_register_all();
++#endif
+ av_registered = true;
+ }
+
+ // guess format
+- AVOutputFormat *format = av_guess_format(NULL, filename.c_str(), NULL);
++#if LIBAVCODEC_VERSION_MAJOR < 59 // FFMPEG < 5.0
++ AVOutputFormat* format = av_guess_format(nullptr, filename.c_str(), nullptr);
++#else
++ const AVOutputFormat* format = av_guess_format(nullptr, filename.c_str(), nullptr);
++#endif
+ if (!format) {
+ synfig::warning("Target_LibAVCodec: unable to guess the output format, defaulting to MPEG");
+- format = av_guess_format("mpeg", NULL, NULL);
++ format = av_guess_format("mpeg", nullptr, nullptr);
+ }
+ if (!format) {
+ synfig::error("Target_LibAVCodec: unable to find 'mpeg' output format");
+@@ -254,6 +261,7 @@
+ context = avformat_alloc_context();
+ assert(context);
+ context->oformat = format;
++#if LIBAVCODEC_VERSION_MAJOR < 58 // FFMPEG < 4.0
+ if (filename.size() + 1 > sizeof(context->filename)) {
+ synfig::error(
+ "Target_LibAVCodec: filename too long, max length is %d, filename is '%s'",
+@@ -263,6 +271,14 @@
+ return false;
+ }
+ memcpy(context->filename, filename.c_str(), filename.size() + 1);
++#else
++ context->url = av_strndup(filename.c_str(), filename.size());
++ if (!context->url) {
++ synfig::error("Target_LibAVCodec: cannot allocate space for filename");
++ close();
++ return false;
++ }
++#endif
+
+ packet = av_packet_alloc();
+ assert(packet);
diff --git a/srcpkgs/synfig/template b/srcpkgs/synfig/template
index 5f5f5bb3f4b2..6e0d713150ae 100644
--- a/srcpkgs/synfig/template
+++ b/srcpkgs/synfig/template
@@ -6,7 +6,7 @@ revision=2
build_style=gnu-configure
configure_args="--with-boost-libdir=${XBPS_CROSS_BASE}/usr/lib"
hostmakedepends="boost-build ImageMagick pkg-config intltool"
-makedepends="ETL gettext-devel libxml++-devel mlt-devel libmagick-devel
+makedepends="ETL gettext-devel libxml++-devel mlt7-devel libmagick-devel
libmng-devel boost-build boost-devel libopenexr-devel ffmpeg-devel"
depends="ImageMagick"
short_desc="CLI 2D vector and timeline-based animation software"
@@ -20,7 +20,7 @@ CXXFLAGS="-std=c++11 -DHAVE_LOCALE_H=1"
synfig-devel_package() {
depends="${sourcepkg}>=${version}_${revision}
- libopenexr-devel libxml++-devel mlt-devel"
+ libopenexr-devel libxml++-devel mlt7-devel"
short_desc+=" - development files"
pkg_install() {
vmove usr/bin/synfig-config
From 730277ca9899d55da547f420c2ec8ee5b969ea1b Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Fri, 5 May 2023 12:57:57 -0400
Subject: [PATCH 087/110] synfigstudio: revbump for synfig mlt7
---
srcpkgs/synfigstudio/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/synfigstudio/template b/srcpkgs/synfigstudio/template
index 91349169ed2b..af1c5a296ef0 100644
--- a/srcpkgs/synfigstudio/template
+++ b/srcpkgs/synfigstudio/template
@@ -2,7 +2,7 @@
# Should be kept in sync with 'synfig' and 'ETL'
pkgname=synfigstudio
version=1.4.4
-revision=2
+revision=3
build_style=gnu-configure
configure_args="--disable-update-mimedb"
hostmakedepends="pkg-config intltool gettext synfig"
From 1985dec1b7c0e7febf5caba5c08a442d57c9c335 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:52 -0400
Subject: [PATCH 088/110] telegram-desktop: revbump for ffmpeg-6.0
---
srcpkgs/telegram-desktop/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/telegram-desktop/template b/srcpkgs/telegram-desktop/template
index 60df3278b05e..83aa72a67448 100644
--- a/srcpkgs/telegram-desktop/template
+++ b/srcpkgs/telegram-desktop/template
@@ -1,7 +1,7 @@
# Template file for 'telegram-desktop'
pkgname=telegram-desktop
version=4.8.1
-revision=1
+revision=2
build_style=cmake
build_helper="qemu"
configure_args="-DTDESKTOP_API_ID=209235
From a2d86a1789d9ca0a2119aef9811526eb552eacee Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:52 -0400
Subject: [PATCH 089/110] tg_owt: revbump for ffmpeg-6.0
---
srcpkgs/tg_owt/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/tg_owt/template b/srcpkgs/tg_owt/template
index 97d195ddb34a..551614b24956 100644
--- a/srcpkgs/tg_owt/template
+++ b/srcpkgs/tg_owt/template
@@ -1,7 +1,7 @@
# Template file for 'tg_owt'
pkgname=tg_owt
version=0.0.0.20230107
-revision=1
+revision=2
_commit=5098730b9eb6173f0b52068fe2555b7c1015123a
_libyuv_commit=00950840d1c9bcbb3eb6ebc5aac5793e71166c8b
_abseil_commit=8c0b94e793a66495e0b1f34a5eb26bd7dc672db0
From a0d568dc8019abb4595d2815c48f4ebce9f5071b Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:52 -0400
Subject: [PATCH 090/110] timg: revbump for ffmpeg-6.0
---
srcpkgs/timg/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/timg/template b/srcpkgs/timg/template
index 91f1516b2597..334443d3f9bb 100644
--- a/srcpkgs/timg/template
+++ b/srcpkgs/timg/template
@@ -1,7 +1,7 @@
# Template file for 'timg'
pkgname=timg
version=1.4.4
-revision=1
+revision=2
build_style=cmake
configure_args="-DWITH_OPENSLIDE_SUPPORT=off -Wno-dev"
hostmakedepends="pkg-config git"
From ee3cd73c90ca2038047d68dd1e0cc9c040abc78f Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:52 -0400
Subject: [PATCH 091/110] tvheadend: revbump for ffmpeg4-4.4.3
---
srcpkgs/tvheadend/template | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/srcpkgs/tvheadend/template b/srcpkgs/tvheadend/template
index e6b16d7ccf3b..46b52b6fb7f9 100644
--- a/srcpkgs/tvheadend/template
+++ b/srcpkgs/tvheadend/template
@@ -1,14 +1,14 @@
# Template file for 'tvheadend'
pkgname=tvheadend
version=4.2.8
-revision=6
+revision=7
build_style=gnu-configure
configure_args="--enable-dvbscan --disable-ffmpeg_static
--disable-hdhomerun_static --disable-bintray_cache --disable-libx264_static
--disable-libx265_static --disable-libvpx_static --disable-libtheora_static
--disable-libvorbis_static --disable-libfdkaac_static"
hostmakedepends="gettext pkg-config python git which"
-makedepends="avahi-libs-devel openssl-devel zlib-devel libcurl-devel ffmpeg-devel"
+makedepends="avahi-libs-devel openssl-devel zlib-devel libcurl-devel ffmpeg4-devel"
short_desc="TV streaming server"
maintainer="lemmi <lemmi@nerd2nerd.org>"
license="GPL-3.0-only"
From 1cc46baceaa0ca0d6bbc9f441893eccd2a599161 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:52 -0400
Subject: [PATCH 092/110] unpaper: update to 7.0.0.
---
srcpkgs/unpaper/template | 16 ++++++++--------
1 file changed, 8 insertions(+), 8 deletions(-)
diff --git a/srcpkgs/unpaper/template b/srcpkgs/unpaper/template
index 38ed47a58401..1ff910e722af 100644
--- a/srcpkgs/unpaper/template
+++ b/srcpkgs/unpaper/template
@@ -1,13 +1,13 @@
# Template file for 'unpaper'
pkgname=unpaper
-version=6.1
-revision=3
-build_style=gnu-configure
+version=7.0.0
+revision=1
+build_style=meson
+hostmakedepends="pkg-config meson libxslt"
+makedepends="ffmpeg-devel python3-Sphinx"
+short_desc="Post-processing tool for scanned sheets of paper"
maintainer="Orphaned <orphan@voidlinux.org>"
-hostmakedepends="pkg-config libxslt"
-makedepends="ffmpeg-devel"
-license="GPL-2"
+license="GPL-2.0-or-later"
homepage="https://www.flameeyes.eu/projects/unpaper"
-short_desc="A post-processing tool for scanned sheets of paper"
distfiles="https://www.flameeyes.eu/files/${pkgname}-${version}.tar.xz"
-checksum=237c84f5da544b3f7709827f9f12c37c346cdf029b1128fb4633f9bafa5cb930
+checksum=2575fbbf26c22719d1cb882b59602c9900c7f747118ac130883f63419be46a80
From 3faa558ade3857867fab33a8042f68d9b135a12f Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:52 -0400
Subject: [PATCH 093/110] vba-m: revbump for ffmpeg-6.0
---
srcpkgs/vba-m/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/vba-m/template b/srcpkgs/vba-m/template
index ba153e0b58ca..aa6093645e97 100644
--- a/srcpkgs/vba-m/template
+++ b/srcpkgs/vba-m/template
@@ -2,7 +2,7 @@
pkgname=vba-m
reverts=1292_2
version=2.1.5
-revision=1
+revision=2
build_style=cmake
configure_args="-DENABLE_GTK=TRUE -DENABLE_FFMPEG=TRUE -DENABLE_LINK=TRUE -DCMAKE_BUILD_TYPE=Release"
hostmakedepends="gettext pkg-config unzip zip yasm wxWidgets-gtk3-devel"
From 61b604f3acdc80d3b903e9c9d466e9ad6b0c1c2c Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:52 -0400
Subject: [PATCH 094/110] vice: revbump for ffmpeg4-4.4.3
---
srcpkgs/vice/template | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/srcpkgs/vice/template b/srcpkgs/vice/template
index 0924767cfcfb..5981e45149d0 100644
--- a/srcpkgs/vice/template
+++ b/srcpkgs/vice/template
@@ -1,7 +1,7 @@
# Template file for 'vice'
pkgname=vice
version=3.5
-revision=1
+revision=2
build_style=gnu-configure
configure_args="
$(vopt_enable sdl2 sdlui2)
@@ -28,7 +28,7 @@ makedepends="
$(vopt_if gtk3 gtk+3-devel)
$(vopt_if gtk3 pulseaudio-devel)
$(vopt_if gtk3 pango-devel)
- $(vopt_if ffmpeg ffmpeg-devel)"
+ $(vopt_if ffmpeg ffmpeg4-devel)"
short_desc="Emulator for C64, C128, CBM-II, PET, VIC20, Plus4 and C16"
maintainer="Orphaned <orphan@voidlinux.org>"
license="GPL-2.0-or-later"
From a8cc6f977612d1516721b461a3f9a61ec7e03c4a Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:52 -0400
Subject: [PATCH 095/110] waypipe: revbump for ffmpeg-6.0
---
srcpkgs/waypipe/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/waypipe/template b/srcpkgs/waypipe/template
index 5c4161900060..1a46fe27f7d8 100644
--- a/srcpkgs/waypipe/template
+++ b/srcpkgs/waypipe/template
@@ -1,7 +1,7 @@
# Template file for 'waypipe'
pkgname=waypipe
version=0.8.4
-revision=1
+revision=2
build_style=meson
# lto is off because it causes linking errors in armv6l and armv7l (due to NEON)
configure_args="-Dwerror=false -Dwith_dmabuf=enabled -Dwith_lz4=enabled
From 167d1701a73c957716fcea8283493c4601a2bd71 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:52 -0400
Subject: [PATCH 096/110] wf-recorder: revbump for ffmpeg-6.0
---
srcpkgs/wf-recorder/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/wf-recorder/template b/srcpkgs/wf-recorder/template
index e278eb001600..5d014a5f28af 100644
--- a/srcpkgs/wf-recorder/template
+++ b/srcpkgs/wf-recorder/template
@@ -1,7 +1,7 @@
# Template file for 'wf-recorder'
pkgname=wf-recorder
version=0.3.0
-revision=1
+revision=2
build_style=meson
hostmakedepends="pkg-config scdoc wayland-devel"
makedepends="wayland-protocols wayland-devel ffmpeg-devel x264-devel
From fafbc03076ff966943c1bb00992598182a3348a3 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:52 -0400
Subject: [PATCH 097/110] xpra: revbump for ffmpeg-6.0
---
srcpkgs/xpra/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/xpra/template b/srcpkgs/xpra/template
index 38f83283b1e5..b6e01ff0a813 100644
--- a/srcpkgs/xpra/template
+++ b/srcpkgs/xpra/template
@@ -1,7 +1,7 @@
# Template file for 'xpra'
pkgname=xpra
version=4.4.4
-revision=1
+revision=2
build_style=python3-module
make_build_args="--without-cuda_kernels --without-cuda_rebuild"
make_install_args="$(vopt_with docs) ${make_build_args}"
From b009466a3cd8b4be508a9c6f3f77c76a1c2e9387 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Fri, 31 Mar 2023 09:07:40 -0400
Subject: [PATCH 098/110] nv-codec-headers: update to 12.0.16.0
---
srcpkgs/nv-codec-headers/template | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/srcpkgs/nv-codec-headers/template b/srcpkgs/nv-codec-headers/template
index 3d422a61e489..251e057f826f 100644
--- a/srcpkgs/nv-codec-headers/template
+++ b/srcpkgs/nv-codec-headers/template
@@ -1,6 +1,6 @@
# Template file for 'nv-codec-headers'
pkgname=nv-codec-headers
-version=11.1.5.1
+version=12.0.16.0
revision=1
build_style=gnu-makefile
short_desc="FFmpeg version of headers required to interface with Nvidias codec APIs"
@@ -8,7 +8,7 @@ maintainer="Orphaned <orphan@voidlinux.org>"
license="MIT"
homepage="http://git.videolan.org/?p=ffmpeg/nv-codec-headers.git"
distfiles="https://github.com/FFmpeg/nv-codec-headers/archive/n${version}.tar.gz"
-checksum=d095fbd56aa93772471a323be0ebe65504a0f43f06c76a30b6d25da77b06ae9c
+checksum=2a1533b65f55f9da52956faf0627ed3b74868ac0c7f269990edd21369113b48f
post_install() {
sed -n '4,25p' include/ffnvcodec/nvEncodeAPI.h > LICENSE
From 7f126a07dfab9cac6dab60bf4d3d442e3c418b69 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Fri, 31 Mar 2023 09:08:40 -0400
Subject: [PATCH 099/110] openimagedenoise: revbump for ffmpeg-6.0
---
srcpkgs/openimagedenoise/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/openimagedenoise/template b/srcpkgs/openimagedenoise/template
index db5ccdb055cc..cb90045afb63 100644
--- a/srcpkgs/openimagedenoise/template
+++ b/srcpkgs/openimagedenoise/template
@@ -1,7 +1,7 @@
# Template file for 'openimagedenoise'
pkgname=openimagedenoise
version=1.4.3
-revision=1
+revision=2
archs="x86_64*"
build_style=cmake
hostmakedepends="ispc python3"
From a91fc81e4fc3614c3bac333865153435f14695f3 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Mon, 3 Apr 2023 23:30:28 -0400
Subject: [PATCH 100/110] freecad: revbump for qt5-webengine-5.15.13
---
srcpkgs/freecad/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/freecad/template b/srcpkgs/freecad/template
index f62023ee8ce4..e301f32d3540 100644
--- a/srcpkgs/freecad/template
+++ b/srcpkgs/freecad/template
@@ -1,7 +1,7 @@
# Template file for 'freecad'
pkgname=freecad
version=0.20.2
-revision=3
+revision=4
build_style=cmake
_inst_prefix=/usr/lib/${pkgname}
From fd3fa2af3ec120dbafa6346307d0078408573bfa Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Mon, 3 Apr 2023 23:31:45 -0400
Subject: [PATCH 101/110] shotcut: revbump for mlt7-7.14.0
---
srcpkgs/shotcut/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/shotcut/template b/srcpkgs/shotcut/template
index 32583277dab2..8d8a7a0ebdeb 100644
--- a/srcpkgs/shotcut/template
+++ b/srcpkgs/shotcut/template
@@ -1,7 +1,7 @@
# Template file for 'shotcut'
pkgname=shotcut
version=22.12.21
-revision=1
+revision=2
build_style=cmake
configure_args="-DSHOTCUT_VERSION=${version}"
hostmakedepends="pkg-config qt5-tools-devel"
From 0100fe9a7f32b8219d919812729af4a10f69b736 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Mon, 3 Apr 2023 23:33:30 -0400
Subject: [PATCH 102/110] shiboken2: revbump for qt5-5.15.8
---
srcpkgs/shiboken2/patches/importlib-machinery-bypass.patch | 1 +
srcpkgs/shiboken2/template | 2 +-
2 files changed, 2 insertions(+), 1 deletion(-)
create mode 120000 srcpkgs/shiboken2/patches/importlib-machinery-bypass.patch
diff --git a/srcpkgs/shiboken2/patches/importlib-machinery-bypass.patch b/srcpkgs/shiboken2/patches/importlib-machinery-bypass.patch
new file mode 120000
index 000000000000..efcf3249bd88
--- /dev/null
+++ b/srcpkgs/shiboken2/patches/importlib-machinery-bypass.patch
@@ -0,0 +1 @@
+../../python3-pyside2/patches/importlib-machinery-bypass.patch
\ No newline at end of file
diff --git a/srcpkgs/shiboken2/template b/srcpkgs/shiboken2/template
index 084ecc3ba1e1..2a21998997eb 100644
--- a/srcpkgs/shiboken2/template
+++ b/srcpkgs/shiboken2/template
@@ -1,7 +1,7 @@
# Template file for 'shiboken2'
pkgname=shiboken2
version=5.15.7
-revision=1
+revision=2
_pkgname="pyside-setup-opensource-src-${version}"
build_wrksrc="sources/shiboken2"
build_style=cmake
From 61f5c014d608268edd5f5e4ff3fded78fe75d951 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Mon, 3 Apr 2023 23:33:53 -0400
Subject: [PATCH 103/110] python3-pyside2: update to 5.15.8
---
.../patches/importlib-machinery-bypass.patch | 15 +++++++++++++++
srcpkgs/python3-pyside2/template | 9 +++++----
2 files changed, 20 insertions(+), 4 deletions(-)
create mode 100644 srcpkgs/python3-pyside2/patches/importlib-machinery-bypass.patch
diff --git a/srcpkgs/python3-pyside2/patches/importlib-machinery-bypass.patch b/srcpkgs/python3-pyside2/patches/importlib-machinery-bypass.patch
new file mode 100644
index 000000000000..64c429584776
--- /dev/null
+++ b/srcpkgs/python3-pyside2/patches/importlib-machinery-bypass.patch
@@ -0,0 +1,15 @@
+Using this prevents an error around line 220 below it.
+"AttributeError: module 'importlib' has no attribute 'machinery'"
+The old backup logic is in place and compiles without issues.
+--- a/sources/shiboken2/libshiboken/embed/signature_bootstrap.py 2023-04-02 23:09:34.688912402 -0400
++++ b/sources/shiboken2/libshiboken/embed/signature_bootstrap.py 2023-04-02 23:10:03.395529582 -0400
+@@ -170,9 +170,6 @@
+
+ # 'zipstring_sequence' comes from signature.cpp
+ zipbytes = base64.b64decode(''.join(zipstring_sequence))
+- if sys.version_info[0] >= 3:
+- vzip = zipfile.ZipFile(io.BytesIO(zipbytes))
+- return sys.meta_path, EmbeddableZipImporter(vzip)
+
+ # Old version for Python 2.7, only.
+ import os
diff --git a/srcpkgs/python3-pyside2/template b/srcpkgs/python3-pyside2/template
index 50e6ff260d3b..b50e62bd215d 100644
--- a/srcpkgs/python3-pyside2/template
+++ b/srcpkgs/python3-pyside2/template
@@ -1,11 +1,12 @@
# Template file for 'python3-pyside2'
pkgname=python3-pyside2
-version=5.15.5
-revision=2
+version=5.15.8
+revision=1
_pkgname="pyside-setup-opensource-src-${version}"
build_wrksrc="sources/pyside2"
build_style=cmake
-configure_args="-DPYTHON_EXECUTABLE=/usr/bin/python"
+configure_args="-DPYTHON_EXECUTABLE=/usr/bin/python -DCMAKE_BUILD_TYPE=None
+ -DBUILD_TESTS=OFF"
hostmakedepends="cmake python3 shiboken2"
makedepends="python3-devel libshiboken2-devel qt5-devel
qt5-multimedia-devel qt5-tools-devel qt5-plugin-mysql qt5-plugin-odbc
@@ -23,7 +24,7 @@ maintainer="yopito <pierre.bourgin@free.fr>"
license="LGPL-3.0-or-later"
homepage="https://wiki.qt.io/Qt_for_Python"
distfiles="https://download.qt.io/official_releases/QtForPython/pyside2/PySide2-${version}-src/${_pkgname}.tar.xz"
-checksum=3920a4fb353300260c9bc46ff70f1fb975c5e7efa22e9d51222588928ce19b33
+checksum=23436302c8deb5b4cbc769b205d09604e38ba83b40708efccb7bd8c9af6f6b5d
build_options="webengine"
desc_option_webengine="Build Qt5 WebEngine bindings"
From 1dee8b5c6a512061489328b82f85562484e4226e Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Tue, 4 Apr 2023 11:14:35 -0400
Subject: [PATCH 104/110] konqueror: revbump for ffmpeg-6.0
---
srcpkgs/konqueror/template | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/srcpkgs/konqueror/template b/srcpkgs/konqueror/template
index d8d0e73a78ab..c5bdba601d3c 100644
--- a/srcpkgs/konqueror/template
+++ b/srcpkgs/konqueror/template
@@ -1,11 +1,11 @@
# Template file for 'konqueror'
pkgname=konqueror
version=23.04.0
-revision=1
+revision=2
build_style=cmake
configure_args="-DDESKTOPTOJSON_EXECUTABLE=/usr/bin/desktoptojson"
hostmakedepends="extra-cmake-modules python3 qt5-host-tools qt5-qmake kdoctools
-kcoreaddons kconfig gettext"
+ kcoreaddons kconfig gettext"
makedepends="qt5-devel qt5-webengine-devel qt5-declarative-devel
qt5-webchannel-devel qt5-location-devel kcmutils-devel kdelibs4support-devel
karchive-devel khtml-devel kdesu-devel kactivities5-devel"
From 3c1b795a0f956b3eafd40fb28c1c5c695151fc23 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Tue, 4 Apr 2023 11:14:58 -0400
Subject: [PATCH 105/110] qt5-speech: revbump for qt5-5.15.8
---
srcpkgs/qt5-speech/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/qt5-speech/template b/srcpkgs/qt5-speech/template
index 3ecd10d50650..2d7d4d4d2453 100644
--- a/srcpkgs/qt5-speech/template
+++ b/srcpkgs/qt5-speech/template
@@ -1,7 +1,7 @@
# Template file for 'qt5-speech'
pkgname=qt5-speech
version=5.15.7
-revision=2
+revision=3
_commit=d32f4a479d38a11f547598004b975f4356424a16
build_style=qmake
configure_args="-- -flite -flite-alsa -speechd"
From bad1654720dadba34414577b98cf2b23c56b91b3 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Tue, 4 Apr 2023 18:38:50 -0400
Subject: [PATCH 106/110] qt5-styleplugins: revbump for qt5-5.15.8
---
srcpkgs/qt5-styleplugins/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/qt5-styleplugins/template b/srcpkgs/qt5-styleplugins/template
index 96ed97d12cd2..30d93660a2a4 100644
--- a/srcpkgs/qt5-styleplugins/template
+++ b/srcpkgs/qt5-styleplugins/template
@@ -1,7 +1,7 @@
# Template file for 'qt5-styleplugins'
pkgname=qt5-styleplugins
version=5.0.0
-revision=20
+revision=21
_gitrev=335dbece103e2cbf6c7cf819ab6672c2956b17b3
build_style=qmake
hostmakedepends="pkg-config qt5-host-tools qt5-qmake"
From 0f5a8b040f5cad4d3fd3ad6a27af36e372e1fd05 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Thu, 27 Apr 2023 21:58:35 -0400
Subject: [PATCH 107/110] blender: update to 3.5.1
---
srcpkgs/blender/patches/numpy-2.24.patch | 22 ----------------------
srcpkgs/blender/template | 13 +++++++------
2 files changed, 7 insertions(+), 28 deletions(-)
delete mode 100644 srcpkgs/blender/patches/numpy-2.24.patch
diff --git a/srcpkgs/blender/patches/numpy-2.24.patch b/srcpkgs/blender/patches/numpy-2.24.patch
deleted file mode 100644
index 716315b74be7..000000000000
--- a/srcpkgs/blender/patches/numpy-2.24.patch
+++ /dev/null
@@ -1,22 +0,0 @@
-From 74e6e07cf7c67b55d384db72f5aa3892db8a3da6 Mon Sep 17 00:00:00 2001
-From: oreo639 <oreo6391@gmail.com>
-Date: Tue, 17 Jan 2023 14:36:54 -0800
-Subject: [PATCH] Remove usage of deprecated np.bool alias
-
----
- addons/io_scene_gltf2/blender/imp/gltf2_blender_mesh.py | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-diff --git a/addons/io_scene_gltf2/blender/imp/gltf2_blender_mesh.py b/addons/io_scene_gltf2/blender/imp/gltf2_blender_mesh.py
-index 6366434a6..8160c9e99 100644
---- a/release/scripts/addons/io_scene_gltf2/blender/imp/gltf2_blender_mesh.py
-+++ b/release/scripts/addons/io_scene_gltf2/blender/imp/gltf2_blender_mesh.py
-@@ -620,7 +620,7 @@ def set_poly_smoothing(gltf, pymesh, mesh, vert_normals, loop_vidxs):
- # Try to guess which polys should be flat based on the fact that all the
- # loop normals for a flat poly are = the poly's normal.
-
-- poly_smooths = np.empty(num_polys, dtype=np.bool)
-+ poly_smooths = np.empty(num_polys, dtype=bool)
-
- poly_normals = np.empty(num_polys * 3, dtype=np.float32)
- mesh.polygons.foreach_get('normal', poly_normals)
diff --git a/srcpkgs/blender/template b/srcpkgs/blender/template
index d18bc88838ff..900bc17937c3 100644
--- a/srcpkgs/blender/template
+++ b/srcpkgs/blender/template
@@ -1,7 +1,7 @@
# Template file for 'blender'
pkgname=blender
-version=3.4.1
-revision=4
+version=3.5.1
+revision=1
archs="x86_64* ppc64*"
build_style="cmake"
pycompile_dirs="/usr/share/blender/${version%.*}/scripts"
@@ -9,8 +9,8 @@ configure_args="-DWITH_INSTALL_PORTABLE=OFF -DWITH_PYTHON_INSTALL=OFF
-DWITH_JACK=ON -DWITH_CODEC_FFMPEG=ON -DWITH_CODEC_SNDFILE=ON -DWITH_OPENMP=ON
-DWITH_FFTW3=ON -DWITH_MOD_OCEANSIM=ON -DWITH_CYCLES_EMBREE=OFF -DWITH_OPENCOLORIO=ON
-DWITH_IMAGE_OPENEXR=ON -DWITH_IMAGE_OPENJPEG=ON -DWITH_OPENSUBDIV=ON
- -DWITH_OPENCOLLADA=ON -DWITH_SYSTEM_GLEW=ON -DWITH_OPENVDB=ON -DWITH_ALEMBIC=ON
- -DWITH_GHOST_X11=ON -DWITH_GHOST_WAYLAND=ON -DWITH_GHOST_LIBDECOR=ON
+ -DWITH_OPENCOLLADA=ON -DWITH_OPENVDB=ON -DWITH_ALEMBIC=ON
+ -DWITH_GHOST_X11=ON -DWITH_GHOST_WAYLAND=ON -DWITH_GHOST_WAYLAND_LIBDECOR=ON
-DWITH_BUILDINFO=OFF -DPYTHON_VERSION=${py3_ver} -DPYTHON_LIBPATH=/usr/lib
-DPYTHON_LIBRARY='python${py3_ver}${py3_abiver}'
-DPYTHON_INCLUDE_DIRS=/${py3_inc}"
@@ -22,14 +22,15 @@ makedepends="libgomp-devel libpng-devel tiff-devel python3-devel glu-devel
opencolorio-devel opencollada-devel python3-numpy libXrender-devel
OpenSubdiv-devel tbb-devel libxml2-devel openvdb-devel alembic-devel
pugixml-devel libXxf86vm-devel libepoxy-devel gmp-devel gmpxx-devel
- wayland-protocols wayland-devel libxkbcommon-devel libdecor-devel"
+ wayland-protocols wayland-devel libxkbcommon-devel libdecor-devel
+ level-zero-devel"
depends="desktop-file-utils hicolor-icon-theme"
short_desc="3D graphics creation suite"
maintainer="Enno Boland <gottox@voidlinux.org>"
license="GPL-3.0-or-later"
homepage="https://www.blender.org"
distfiles="https://download.blender.org/source/blender-${version}.tar.xz"
-checksum=247c4c1228270c9010f4721c985cb5b628ab50abcf9f2678630737142eeb91c3
+checksum=bd7428c7e6cba5a900216269c32111dffaabaf1bdb5472f231965e615174a809
python_version=3
LDFLAGS="-Wl,-z,stack-size=2097152"
# Blender tests are executed against a system installation of blender. This
From 4522c49f8a94d0ca61dbc103c0a5f6ffc5b869e5 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Sun, 30 Apr 2023 20:22:26 -0400
Subject: [PATCH 108/110] gst-plugins-ugly1: revbump for ffmpeg-6.0
---
srcpkgs/gst-plugins-ugly1/template | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/srcpkgs/gst-plugins-ugly1/template b/srcpkgs/gst-plugins-ugly1/template
index e254fd40f869..85ae64bc7a0a 100644
--- a/srcpkgs/gst-plugins-ugly1/template
+++ b/srcpkgs/gst-plugins-ugly1/template
@@ -1,6 +1,6 @@
# Template file for 'gst-plugins-ugly1'
pkgname=gst-plugins-ugly1
-version=1.20.3
+version=1.22.2
revision=1
build_style=meson
configure_args="-Damrnb=disabled -Damrwbdec=disabled -Dsidplay=disabled"
@@ -15,4 +15,4 @@ maintainer="Orphaned <orphan@voidlinux.org>"
license="LGPL-2.1-or-later"
homepage="https://gstreamer.freedesktop.org"
distfiles="${homepage}/src/${pkgname/1/}/${pkgname/1/}-${version}.tar.xz"
-checksum=8caa20789a09c304b49cf563d33cca9421b1875b84fcc187e4a385fa01d6aefd
+checksum=8f30f44db0bd063709bf6fbe55138e3a98af0abcb61c360f35582bbe10e80691
From 4d8166b1c5d85aad94e66ef2df272b80acf16cf8 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Sun, 30 Apr 2023 20:22:26 -0400
Subject: [PATCH 109/110] gst-rtsp-server: revbump for ffmpeg-6.0
---
srcpkgs/gst-rtsp-server/template | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/srcpkgs/gst-rtsp-server/template b/srcpkgs/gst-rtsp-server/template
index 8ceea8d34b4b..980fd72cdd4c 100644
--- a/srcpkgs/gst-rtsp-server/template
+++ b/srcpkgs/gst-rtsp-server/template
@@ -1,7 +1,7 @@
# Template file for 'gst-rtsp-server'
pkgname=gst-rtsp-server
-version=1.20.3
-revision=3
+version=1.22.2
+revision=2
build_style=meson
hostmakedepends="pkg-config python3"
makedepends="glib-devel gst-plugins-bad1-devel gobject-introspection
@@ -10,5 +10,5 @@ short_desc="GStreamer multimedia graph framework - rtsp server"
maintainer="1is7ac3 <isaac.qa13@gmail.com>"
license="LGPL-2.1-or-later"
homepage="https://gstreamer.freedesktop.org"
-distfiles="https://gstreamer.freedesktop.org/src/gst-rtsp-server/gst-rtsp-server-${version}.tar.xz"
-checksum=ee402718be9b127f0e5e66ca4c1b4f42e4926ec93ba307b7ccca5dc6cc9794ca
+distfiles="${homepage}/src/${pkgname}/${pkgname}-${version}.tar.xz"
+checksum=2be4aecfb88710100ea7115ed0216403e8094344ebf146094271b8d4d73828bf
From 64527953c6d70d820f222412e211a03c32043493 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Sun, 30 Apr 2023 20:22:26 -0400
Subject: [PATCH 110/110] gst-libav: revbump for ffmpeg-6.0
---
srcpkgs/gst-libav/template | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/srcpkgs/gst-libav/template b/srcpkgs/gst-libav/template
index f082bd211c65..04c39bff1489 100644
--- a/srcpkgs/gst-libav/template
+++ b/srcpkgs/gst-libav/template
@@ -1,6 +1,6 @@
# Template file for 'gst-libav'
pkgname=gst-libav
-version=1.20.3
+version=1.22.2
revision=2
build_style=meson
hostmakedepends="pkg-config yasm"
@@ -11,7 +11,7 @@ maintainer="Orphaned <orphan@voidlinux.org>"
license="LGPL-2.0-or-later"
homepage="https://gstreamer.freedesktop.org"
distfiles="${homepage}/src/${pkgname}/${pkgname}-${version}.tar.xz"
-checksum=3fedd10560fcdfaa1b6462cbf79a38c4e7b57d7f390359393fc0cef6dbf27dfe
+checksum=fcaaf9878fe8f3bc82317ef13a1558824cb68df1f8968c6797f556c5e33bcffd
case "$XBPS_TARGET_MACHINE" in
*-musl) # Required by musl for M_SQRT1_2
^ permalink raw reply [flat|nested] 175+ messages in thread
* Re: [PR PATCH] [Updated] ffmpeg6 split
2023-05-05 13:20 [PR PATCH] ffmpeg6 split zlice
` (5 preceding siblings ...)
2023-05-07 22:00 ` [PR PATCH] [Updated] " zlice
@ 2023-05-08 0:23 ` zlice
2023-05-29 1:43 ` zlice
` (166 subsequent siblings)
173 siblings, 0 replies; 175+ messages in thread
From: zlice @ 2023-05-08 0:23 UTC (permalink / raw)
To: ml
[-- Attachment #1: Type: text/plain, Size: 3256 bytes --]
There is an updated pull request by zlice against master on the void-packages repository
https://github.com/zlice/void-packages ffmpeg6-split
https://github.com/void-linux/void-packages/pull/43761
ffmpeg6 split
[ci skip]
#### Testing the changes
- I tested the changes in this PR: **YES**
main testing has been vaapi in Firefox Nightly and enc/dec in Shotcut on Intel A770
#### New package
- This new package conforms to the [package requirements](https://github.com/void-linux/void-packages/blob/master/CONTRIBUTING.md#package-requirements): **YES**
#### Local build testing
- I built this PR locally for my native architecture, **x86_64**
#### Discussion
Continuation of https://github.com/void-linux/void-packages/pull/36315
`libavresample` is deprecated, but marked as a dependency when trying to build other packages and install `ffmpeg`(6). I think the right way to handle this is make a meta package and the add to removals?
##### Commit naming / misc
~~Commits are 'dirty' right now, running with [gstreamer 1.22.1 updates](https://github.com/void-linux/void-packages/pull/42861) and [Intel OpenCL](https://github.com/void-linux/void-packages/pull/43084). This will also make [intel packages pr](https://github.com/void-linux/void-packages/pull/41132) obsolete.~~ (see Requirements below)
Maintainer for previous ffmpeg(4) was orphaned, I can put my name in there if that matters, though I don't exactly see myself keeping up on ffmpeg.
This updates QT5 which looks like it is usually hosted by Johnny. Not sure if there's any reason to stay there or these sources are fine.
##### STILL FFMPEG4
These are a mix of emulators, games and/or older packages.
- attract (multiple patches in master)
- audacity (3.2.x+ should work but requires wxWidgets dev 3.1.x)
- ccextractor (master patches? no release)
- vice
- kodi
- mlt (only dep left is flowblade)
- ~~synfig (mlt)~~ (work with mlt7, bump synfigstudio)
- tvheadend
- ssr
- spek-alternative
- ppsspp
- olive
- moc
- mediastreamer
- libextractor
- idjc
- hedgewars
- ~~ffmpegthumbnailer~~ (patches for moviedecoder.xxx files)
- ~~ffmpegthumbs~~ (latest compiles)
- deadbeef
- omxplayer
- qtav (fork has ffmpeg 5 patch - https://github.com/cmguo/QtAV)
- `vlc` (vlc4 will support ffmpeg5, there's a patch to build 3.x with ffmpeg5 but it will lack vaapi)
- `osg` (OpenSceneGraph plus `xine-lib`)
##### HAVE NOT BUILT YET
- omxplayer (rpi only? ffmpeg4)
- kodi (big, but ffmpeg4)
##### UPDATED (for ffmpeg6)
- blender: update to 3.5.1
- unpaper: update to 7.0.0.
- guvcview: update to 2.0.8.
- qt5: update to 5.15.8
- qt5-webengine: update to 5.18.13
- shiboken2: revbump for qt5.15.8 (patch)
- python3-pyside2: update to 5.15.8 (patch)
##### Requirements
- [gstreamer 1.22.2](https://github.com/void-linux/void-packages/pull/42861) - a few packages use ffmpeg-devel and require a revbump
- [Intel Packages](https://github.com/void-linux/void-packages/pull/41132) - ffmpeg4 uses different libraries than 6 (libmfx / Intel-MediaSDK vs only oneVPL that Intel is moving to), both are included here
A patch file from https://github.com/void-linux/void-packages/pull/43761.patch is attached
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: github-pr-ffmpeg6-split-43761.patch --]
[-- Type: text/x-diff, Size: 790913 bytes --]
From 25aec7f003c71ca658c00e37bc4707c391adc219 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 19:55:46 -0400
Subject: [PATCH 001/115] ffmpeg: update to 6.0.
---
common/shlibs | 26 +++++---
srcpkgs/ffmpeg/files/altivec.patch | 60 -------------------
.../patches/armv5tel-floating-point.patch | 18 ------
.../workaround-mesa-readeon-vaapi-bug.patch | 28 ---------
srcpkgs/ffmpeg/template | 31 +++++-----
5 files changed, 33 insertions(+), 130 deletions(-)
delete mode 100644 srcpkgs/ffmpeg/files/altivec.patch
delete mode 100644 srcpkgs/ffmpeg/patches/armv5tel-floating-point.patch
delete mode 100644 srcpkgs/ffmpeg/patches/workaround-mesa-readeon-vaapi-bug.patch
diff --git a/common/shlibs b/common/shlibs
index 89f7e53081f8..9497f6499aa2 100644
--- a/common/shlibs
+++ b/common/shlibs
@@ -390,15 +390,23 @@ libid3tag.so.0 libid3tag-0.15.1b_1
libgif.so.7 giflib-5.1.0_1
libImlib2.so.1 imlib2-1.4.2_1
libmp3lame.so.0 lame-3.98.2_1
-libavdevice.so.58 libavdevice-4.0_1
-libavformat.so.58 libavformat-4.0_1
-libswscale.so.5 libswscale-4.0_1
-libswresample.so.3 libswresample-4.0_1
-libavresample.so.4 libavresample-4.0_1
-libpostproc.so.55 libpostproc-4.0_1
-libavcodec.so.58 libavcodec-4.0_1
-libavutil.so.56 libavutil-4.0_1
-libavfilter.so.7 libavfilter-4.0_1
+libavdevice.so.60 libavdevice-6.0_1
+libavformat.so.60 libavformat-6.0_1
+libswscale.so.7 libswscale-6.0_1
+libswresample.so.4 libswresample-6.0_1
+libpostproc.so.57 libpostproc-6.0_1
+libavcodec.so.60 libavcodec-6.0_1
+libavutil.so.58 libavutil-6.0_1
+libavfilter.so.9 libavfilter-6.0_1
+libavdevice.so.58 libavdevice4-4.0_1
+libavformat.so.58 libavformat4-4.0_1
+libswscale.so.5 libswscale4-4.0_1
+libswresample.so.3 libswresample4-4.0_1
+libavresample.so.4 libavresample4-4.0_1
+libpostproc.so.55 libpostproc4-4.0_1
+libavcodec.so.58 libavcodec4-4.0_1
+libavutil.so.56 libavutil4-4.0_1
+libavfilter.so.7 libavfilter4-4.0_1
libSDL-1.2.so.0 SDL-1.2.14_1
libSDL_image-1.2.so.0 SDL_image-1.2.10_1
libx264.so.157 x264-20190507.2245_1
diff --git a/srcpkgs/ffmpeg/files/altivec.patch b/srcpkgs/ffmpeg/files/altivec.patch
deleted file mode 100644
index 9c5720046332..000000000000
--- a/srcpkgs/ffmpeg/files/altivec.patch
+++ /dev/null
@@ -1,60 +0,0 @@
-revert some altivec specific change on all ppc* except ppc64le*
-
-q66: "We should also throw in a revert of FFmpeg/FFmpeg@3a557c5 but only
-conditionally, for ppc* but not ppc64le* (the new code is valid for
-POWER8 VSX which LE targets as a baseline but not BE)"
-
-
-This reverts commit 3a557c5d88b7b15b5954ba2743febb055549b536.
----
- libswscale/ppc/yuv2rgb_altivec.c | 24 ++++++++++++++++++++----
- 1 file changed, 20 insertions(+), 4 deletions(-)
-
-diff --git a/libswscale/ppc/yuv2rgb_altivec.c b/libswscale/ppc/yuv2rgb_altivec.c
-index 536545293d..c1e2852adb 100644
---- a/libswscale/ppc/yuv2rgb_altivec.c
-+++ b/libswscale/ppc/yuv2rgb_altivec.c
-@@ -305,6 +305,9 @@ static int altivec_ ## name(SwsContext *c, const unsigned char **in, \
- vector signed short R1, G1, B1; \
- vector unsigned char R, G, B; \
- \
-+ const vector unsigned char *y1ivP, *y2ivP, *uivP, *vivP; \
-+ vector unsigned char align_perm; \
-+ \
- vector signed short lCY = c->CY; \
- vector signed short lOY = c->OY; \
- vector signed short lCRV = c->CRV; \
-@@ -335,13 +338,26 @@ static int altivec_ ## name(SwsContext *c, const unsigned char **in, \
- vec_dstst(oute, (0x02000002 | (((w * 3 + 32) / 32) << 16)), 1); \
- \
- for (j = 0; j < w / 16; j++) { \
-- y0 = vec_xl(0, y1i); \
-+ y1ivP = (const vector unsigned char *) y1i; \
-+ y2ivP = (const vector unsigned char *) y2i; \
-+ uivP = (const vector unsigned char *) ui; \
-+ vivP = (const vector unsigned char *) vi; \
-+ \
-+ align_perm = vec_lvsl(0, y1i); \
-+ y0 = (vector unsigned char) \
-+ vec_perm(y1ivP[0], y1ivP[1], align_perm); \
- \
-- y1 = vec_xl(0, y2i); \
-+ align_perm = vec_lvsl(0, y2i); \
-+ y1 = (vector unsigned char) \
-+ vec_perm(y2ivP[0], y2ivP[1], align_perm); \
- \
-- u = (vector signed char) vec_xl(0, ui); \
-+ align_perm = vec_lvsl(0, ui); \
-+ u = (vector signed char) \
-+ vec_perm(uivP[0], uivP[1], align_perm); \
- \
-- v = (vector signed char) vec_xl(0, vi); \
-+ align_perm = vec_lvsl(0, vi); \
-+ v = (vector signed char) \
-+ vec_perm(vivP[0], vivP[1], align_perm); \
- \
- u = (vector signed char) \
- vec_sub(u, \
---
-2.27.0
-
diff --git a/srcpkgs/ffmpeg/patches/armv5tel-floating-point.patch b/srcpkgs/ffmpeg/patches/armv5tel-floating-point.patch
deleted file mode 100644
index 9a55178c74f0..000000000000
--- a/srcpkgs/ffmpeg/patches/armv5tel-floating-point.patch
+++ /dev/null
@@ -1,18 +0,0 @@
---- a/libavfilter/vf_drawtext.c 2017-10-26 21:03:03.000000000 +0200
-+++ b/libavfilter/vf_drawtext.c 2017-11-21 11:06:49.602284422 +0100
-@@ -39,6 +39,15 @@
- #endif
- #include <fenv.h>
-
-+#if (FE_ALL_EXCEPT == 0)
-+/* E.g. ARM soft float does not define these */
-+#define FE_INVALID 0
-+#define FE_DIVBYZERO 0
-+#define FE_OVERFLOW 0
-+#define FE_UNDERFLOW 0
-+#define FE_INEXACT 0
-+#endif
-+
- #if CONFIG_LIBFONTCONFIG
- #include <fontconfig/fontconfig.h>
- #endif
diff --git a/srcpkgs/ffmpeg/patches/workaround-mesa-readeon-vaapi-bug.patch b/srcpkgs/ffmpeg/patches/workaround-mesa-readeon-vaapi-bug.patch
deleted file mode 100644
index 00e3f68a415b..000000000000
--- a/srcpkgs/ffmpeg/patches/workaround-mesa-readeon-vaapi-bug.patch
+++ /dev/null
@@ -1,28 +0,0 @@
-From 811d290844206fc73dc39c3e5b67d5d895baedf8 Mon Sep 17 00:00:00 2001
-From: Rainer Hochecker <fernetmenta@online.de>
-Date: Sat, 26 Jan 2019 19:48:35 +0100
-Subject: [PATCH] avcodec/vaapi_h264: skip decode if pic has no slices
-
-This fixes / workarounds https://bugs.freedesktop.org/show_bug.cgi?id=105368.
-It was hit frequently when watching h264 channels received via DVB-X.
-Corresponding kodi bug: https://github.com/xbmc/xbmc/issues/15704
----
- libavcodec/vaapi_h264.c | 5 +++++
- 1 file changed, 5 insertions(+)
-
-diff --git a/libavcodec/vaapi_h264.c b/libavcodec/vaapi_h264.c
-index 5854587a255..f12fdc457a4 100644
---- a/libavcodec/vaapi_h264.c
-+++ b/libavcodec/vaapi_h264.c
-@@ -317,6 +317,11 @@ static int vaapi_h264_end_frame(AVCodecContext *avctx)
- H264SliceContext *sl = &h->slice_ctx[0];
- int ret;
-
-+ if (pic->nb_slices == 0) {
-+ ret = AVERROR_INVALIDDATA;
-+ goto finish;
-+ }
-+
- ret = ff_vaapi_decode_issue(avctx, pic);
- if (ret < 0)
- goto finish;
diff --git a/srcpkgs/ffmpeg/template b/srcpkgs/ffmpeg/template
index 23a3d5c9967b..3d99e5173697 100644
--- a/srcpkgs/ffmpeg/template
+++ b/srcpkgs/ffmpeg/template
@@ -1,15 +1,15 @@
# Template file for 'ffmpeg'
# audacity also needs to be bumped when a new ffmpeg version bumps libavformat's soname!
pkgname=ffmpeg
-version=4.4.3
-revision=2
+version=6.0
+revision=1
short_desc="Decoding, encoding and streaming software"
maintainer="Orphaned <orphan@voidlinux.org>"
license="GPL-3.0-or-later"
homepage="https://www.ffmpeg.org"
changelog="https://raw.githubusercontent.com/FFmpeg/FFmpeg/master/Changelog"
distfiles="https://www.ffmpeg.org/releases/ffmpeg-${version}.tar.xz"
-checksum=6c5b6c195e61534766a0b5fe16acc919170c883362612816d0a1c7f4f947006e
+checksum=57be87c22d9b49c112b6d24bc67d42508660e6b718b3db89c44e47e289137082
hostmakedepends="pkg-config perl yasm"
makedepends="zlib-devel bzip2-devel freetype-devel alsa-lib-devel libXfixes-devel
@@ -26,12 +26,13 @@ makedepends="zlib-devel bzip2-devel freetype-devel alsa-lib-devel libXfixes-deve
$(vopt_if webp libwebp-devel) $(vopt_if sofa libmysofa-devel)
$(vopt_if drm libdrm-devel) $(vopt_if svtav1 libsvt-av1-devel)
$(vopt_if srt srt-devel) $(vopt_if rist librist-devel)
- $(vopt_if vulkan 'vulkan-loader Vulkan-Headers')
+ $(vopt_if vulkan 'vulkan-loader Vulkan-Headers Vulkan-Tools Vulkan-ValidationLayers')
+ $(vopt_if onevpl 'onevpl onevpl-devel')
$(vopt_if nvenc nv-codec-headers) $(vopt_if nvdec nv-codec-headers)"
depends="ffplay>=${version}_${revision}"
build_options="x265 v4l2 vaapi vdpau vpx fdk_aac aom nvenc sndio pulseaudio
- dav1d zimg webp sofa vulkan drm svtav1 srt rist nvdec"
+ dav1d zimg webp sofa vulkan drm svtav1 srt rist nvdec onevpl"
build_options_default="x265 v4l2 vpx aom sndio pulseaudio dav1d webp vulkan drm srt rist"
desc_option_srt="Enable support for SRT (Secure, Reliable, Transport)"
desc_option_rist="Enable support for RIST (Reliable Internet Stream Transport)"
@@ -39,7 +40,8 @@ desc_option_sofa="Enable support for AES SOFA"
desc_option_webp="Enable support for WebP"
case "$XBPS_TARGET_MACHINE" in
- i686*|x86_64*) build_options_default+=" vaapi vdpau nvenc nvdec";;
+ i686*) build_options_default+=" vaapi vdpau nvenc nvdec";;
+ x86_64*) build_options_default+=" vaapi vdpau nvenc nvdec onevpl";;
ppc64*) build_options_default+=" vaapi vdpau";;
mips*) CFLAGS="-mnan=legacy";;
esac
@@ -114,18 +116,19 @@ do_configure() {
$(vopt_enable x265 libx265) \
$(vopt_enable v4l2 libv4l2) \
$(vopt_enable aom libaom) $(vopt_enable vaapi) $(vopt_enable vdpau) \
- --enable-libbs2b --enable-avresample --enable-libvidstab \
+ --enable-libbs2b --enable-libvidstab \
$(vopt_enable dav1d libdav1d) \
$(vopt_enable zimg libzimg) \
$(vopt_enable webp libwebp) \
$(vopt_enable sofa libmysofa) \
$(vopt_enable vulkan) \
+ $(vopt_enable onevpl libvpl) \
$(vopt_enable drm libdrm) \
$(vopt_enable svtav1 libsvtav1) \
$(vopt_enable srt libsrt) \
$(vopt_enable rist librist) \
- $(vopt_if nvenc '--enable-nvenc') \
- $(vopt_if nvdec '--enable-nvdec')
+ $(vopt_enable nvenc nvenc) \
+ $(vopt_enable nvdec nvdec)
}
do_build() {
make ${makejobs}
@@ -148,10 +151,8 @@ libavdevice_package() {
}
}
libavresample_package() {
- short_desc="FFmpeg audio resampling library"
- pkg_install() {
- vmove "usr/lib/libavresample.so.*"
- }
+ short_desc="Package deprecated, removal needed"
+ build_style=meta
}
libavformat_package() {
short_desc="FFmpeg file format library"
@@ -198,9 +199,9 @@ ffmpeg-devel_package() {
libavfilter>=${version}_${revision}
libpostproc>=${version}_${revision}
libswscale>=${version}_${revision}
- libswresample>=${version}_${revision}
- libavresample>=${version}_${revision}"
+ libswresample>=${version}_${revision}"
short_desc+=" - development files"
+ conflicts="ffmpeg4-devel"
pkg_install() {
vmove usr/include
vmove usr/lib/pkgconfig
From 1ca2204fe9d5819d469ff21c06343018583837f8 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 19:56:22 -0400
Subject: [PATCH 002/115] New package: ffmpeg4-4.4.3.
---
srcpkgs/ffmpeg4-devel | 1 +
srcpkgs/ffmpeg4/files/altivec.patch | 60 +++++
.../patches/armv5tel-floating-point.patch | 18 ++
.../workaround-mesa-readeon-vaapi-bug.patch | 28 +++
srcpkgs/ffmpeg4/template | 217 ++++++++++++++++++
srcpkgs/libavcodec4 | 1 +
srcpkgs/libavdevice4 | 1 +
srcpkgs/libavfilter4 | 1 +
srcpkgs/libavformat4 | 1 +
srcpkgs/libavresample4 | 1 +
srcpkgs/libavutil4 | 1 +
srcpkgs/libpostproc4 | 1 +
srcpkgs/libswresample4 | 1 +
srcpkgs/libswscale4 | 1 +
14 files changed, 333 insertions(+)
create mode 120000 srcpkgs/ffmpeg4-devel
create mode 100644 srcpkgs/ffmpeg4/files/altivec.patch
create mode 100644 srcpkgs/ffmpeg4/patches/armv5tel-floating-point.patch
create mode 100644 srcpkgs/ffmpeg4/patches/workaround-mesa-readeon-vaapi-bug.patch
create mode 100644 srcpkgs/ffmpeg4/template
create mode 120000 srcpkgs/libavcodec4
create mode 120000 srcpkgs/libavdevice4
create mode 120000 srcpkgs/libavfilter4
create mode 120000 srcpkgs/libavformat4
create mode 120000 srcpkgs/libavresample4
create mode 120000 srcpkgs/libavutil4
create mode 120000 srcpkgs/libpostproc4
create mode 120000 srcpkgs/libswresample4
create mode 120000 srcpkgs/libswscale4
diff --git a/srcpkgs/ffmpeg4-devel b/srcpkgs/ffmpeg4-devel
new file mode 120000
index 000000000000..887f354e7c6b
--- /dev/null
+++ b/srcpkgs/ffmpeg4-devel
@@ -0,0 +1 @@
+ffmpeg4
\ No newline at end of file
diff --git a/srcpkgs/ffmpeg4/files/altivec.patch b/srcpkgs/ffmpeg4/files/altivec.patch
new file mode 100644
index 000000000000..9c5720046332
--- /dev/null
+++ b/srcpkgs/ffmpeg4/files/altivec.patch
@@ -0,0 +1,60 @@
+revert some altivec specific change on all ppc* except ppc64le*
+
+q66: "We should also throw in a revert of FFmpeg/FFmpeg@3a557c5 but only
+conditionally, for ppc* but not ppc64le* (the new code is valid for
+POWER8 VSX which LE targets as a baseline but not BE)"
+
+
+This reverts commit 3a557c5d88b7b15b5954ba2743febb055549b536.
+---
+ libswscale/ppc/yuv2rgb_altivec.c | 24 ++++++++++++++++++++----
+ 1 file changed, 20 insertions(+), 4 deletions(-)
+
+diff --git a/libswscale/ppc/yuv2rgb_altivec.c b/libswscale/ppc/yuv2rgb_altivec.c
+index 536545293d..c1e2852adb 100644
+--- a/libswscale/ppc/yuv2rgb_altivec.c
++++ b/libswscale/ppc/yuv2rgb_altivec.c
+@@ -305,6 +305,9 @@ static int altivec_ ## name(SwsContext *c, const unsigned char **in, \
+ vector signed short R1, G1, B1; \
+ vector unsigned char R, G, B; \
+ \
++ const vector unsigned char *y1ivP, *y2ivP, *uivP, *vivP; \
++ vector unsigned char align_perm; \
++ \
+ vector signed short lCY = c->CY; \
+ vector signed short lOY = c->OY; \
+ vector signed short lCRV = c->CRV; \
+@@ -335,13 +338,26 @@ static int altivec_ ## name(SwsContext *c, const unsigned char **in, \
+ vec_dstst(oute, (0x02000002 | (((w * 3 + 32) / 32) << 16)), 1); \
+ \
+ for (j = 0; j < w / 16; j++) { \
+- y0 = vec_xl(0, y1i); \
++ y1ivP = (const vector unsigned char *) y1i; \
++ y2ivP = (const vector unsigned char *) y2i; \
++ uivP = (const vector unsigned char *) ui; \
++ vivP = (const vector unsigned char *) vi; \
++ \
++ align_perm = vec_lvsl(0, y1i); \
++ y0 = (vector unsigned char) \
++ vec_perm(y1ivP[0], y1ivP[1], align_perm); \
+ \
+- y1 = vec_xl(0, y2i); \
++ align_perm = vec_lvsl(0, y2i); \
++ y1 = (vector unsigned char) \
++ vec_perm(y2ivP[0], y2ivP[1], align_perm); \
+ \
+- u = (vector signed char) vec_xl(0, ui); \
++ align_perm = vec_lvsl(0, ui); \
++ u = (vector signed char) \
++ vec_perm(uivP[0], uivP[1], align_perm); \
+ \
+- v = (vector signed char) vec_xl(0, vi); \
++ align_perm = vec_lvsl(0, vi); \
++ v = (vector signed char) \
++ vec_perm(vivP[0], vivP[1], align_perm); \
+ \
+ u = (vector signed char) \
+ vec_sub(u, \
+--
+2.27.0
+
diff --git a/srcpkgs/ffmpeg4/patches/armv5tel-floating-point.patch b/srcpkgs/ffmpeg4/patches/armv5tel-floating-point.patch
new file mode 100644
index 000000000000..9a55178c74f0
--- /dev/null
+++ b/srcpkgs/ffmpeg4/patches/armv5tel-floating-point.patch
@@ -0,0 +1,18 @@
+--- a/libavfilter/vf_drawtext.c 2017-10-26 21:03:03.000000000 +0200
++++ b/libavfilter/vf_drawtext.c 2017-11-21 11:06:49.602284422 +0100
+@@ -39,6 +39,15 @@
+ #endif
+ #include <fenv.h>
+
++#if (FE_ALL_EXCEPT == 0)
++/* E.g. ARM soft float does not define these */
++#define FE_INVALID 0
++#define FE_DIVBYZERO 0
++#define FE_OVERFLOW 0
++#define FE_UNDERFLOW 0
++#define FE_INEXACT 0
++#endif
++
+ #if CONFIG_LIBFONTCONFIG
+ #include <fontconfig/fontconfig.h>
+ #endif
diff --git a/srcpkgs/ffmpeg4/patches/workaround-mesa-readeon-vaapi-bug.patch b/srcpkgs/ffmpeg4/patches/workaround-mesa-readeon-vaapi-bug.patch
new file mode 100644
index 000000000000..00e3f68a415b
--- /dev/null
+++ b/srcpkgs/ffmpeg4/patches/workaround-mesa-readeon-vaapi-bug.patch
@@ -0,0 +1,28 @@
+From 811d290844206fc73dc39c3e5b67d5d895baedf8 Mon Sep 17 00:00:00 2001
+From: Rainer Hochecker <fernetmenta@online.de>
+Date: Sat, 26 Jan 2019 19:48:35 +0100
+Subject: [PATCH] avcodec/vaapi_h264: skip decode if pic has no slices
+
+This fixes / workarounds https://bugs.freedesktop.org/show_bug.cgi?id=105368.
+It was hit frequently when watching h264 channels received via DVB-X.
+Corresponding kodi bug: https://github.com/xbmc/xbmc/issues/15704
+---
+ libavcodec/vaapi_h264.c | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+diff --git a/libavcodec/vaapi_h264.c b/libavcodec/vaapi_h264.c
+index 5854587a255..f12fdc457a4 100644
+--- a/libavcodec/vaapi_h264.c
++++ b/libavcodec/vaapi_h264.c
+@@ -317,6 +317,11 @@ static int vaapi_h264_end_frame(AVCodecContext *avctx)
+ H264SliceContext *sl = &h->slice_ctx[0];
+ int ret;
+
++ if (pic->nb_slices == 0) {
++ ret = AVERROR_INVALIDDATA;
++ goto finish;
++ }
++
+ ret = ff_vaapi_decode_issue(avctx, pic);
+ if (ret < 0)
+ goto finish;
diff --git a/srcpkgs/ffmpeg4/template b/srcpkgs/ffmpeg4/template
new file mode 100644
index 000000000000..e736c205371d
--- /dev/null
+++ b/srcpkgs/ffmpeg4/template
@@ -0,0 +1,217 @@
+# Template file for 'ffmpeg4'
+# audacity also needs to be bumped when a new ffmpeg version bumps libavformat's soname!
+pkgname=ffmpeg4
+version=4.4.3
+revision=1
+short_desc="Decoding, encoding and streaming software - ffmpeg4 libraries only"
+maintainer="Orphaned <orphan@voidlinux.org>"
+license="GPL-3.0-or-later"
+homepage="https://www.ffmpeg.org"
+changelog="https://raw.githubusercontent.com/FFmpeg/FFmpeg/master/Changelog"
+distfiles="https://www.ffmpeg.org/releases/ffmpeg-${version}.tar.xz"
+checksum=6c5b6c195e61534766a0b5fe16acc919170c883362612816d0a1c7f4f947006e
+
+hostmakedepends="pkg-config perl yasm"
+makedepends="zlib-devel bzip2-devel freetype-devel alsa-lib-devel libXfixes-devel
+ libXext-devel libXvMC-devel libxcb-devel lame-devel libtheora-devel
+ libvorbis-devel x264-devel xvidcore-devel jack-devel SDL2-devel
+ libcdio-paranoia-devel librtmp-devel libmodplug-devel gnutls-devel
+ speex-devel celt-devel harfbuzz-devel libass-devel opus-devel ocl-icd-devel
+ libbs2b-devel libvidstab-devel $(vopt_if pulseaudio pulseaudio-devel)
+ $(vopt_if vaapi libva-devel) $(vopt_if vdpau libvdpau-devel)
+ $(vopt_if x265 x265-devel) $(vopt_if v4l2 v4l-utils-devel)
+ $(vopt_if fdk_aac fdk-aac-devel) $(vopt_if vpx libvpx-devel)
+ $(vopt_if aom libaom-devel) $(vopt_if sndio sndio-devel)
+ $(vopt_if dav1d libdav1d-devel) $(vopt_if zimg zimg-devel)
+ $(vopt_if webp libwebp-devel) $(vopt_if sofa libmysofa-devel)
+ $(vopt_if drm libdrm-devel) $(vopt_if svtav1 libsvt-av1-devel)
+ $(vopt_if srt srt-devel) $(vopt_if rist librist-devel)
+ $(vopt_if vulkan 'vulkan-loader Vulkan-Headers')
+ $(vopt_if mfx 'libmfx libmfx-devel')
+ $(vopt_if nvenc nv-codec-headers) $(vopt_if nvdec nv-codec-headers)"
+
+build_options="x265 v4l2 vaapi vdpau vpx fdk_aac aom nvenc sndio pulseaudio
+ dav1d zimg webp sofa vulkan drm svtav1 srt rist nvdec mfx"
+build_options_default="x265 v4l2 vpx aom sndio pulseaudio dav1d webp vulkan drm srt rist"
+
+desc_option_srt="Enable support for SRT (Secure, Reliable, Transport)"
+desc_option_rist="Enable support for RIST (Reliable Internet Stream Transport)"
+desc_option_sofa="Enable support for AES SOFA"
+desc_option_webp="Enable support for WebP"
+
+case "$XBPS_TARGET_MACHINE" in
+ i686*) build_options_default+=" vaapi vdpau nvenc nvdec";;
+ x86_64*) build_options_default+=" vaapi vdpau mfx nvenc nvdec";;
+ ppc64*) build_options_default+=" vaapi vdpau";;
+ mips*) CFLAGS="-mnan=legacy";;
+esac
+
+if [ "$XBPS_TARGET_WORDSIZE" != "32" ]; then
+ build_options_default+=" svtav1"
+fi
+
+if [ "$XBPS_TARGET_NO_ATOMIC8" ]; then
+ makedepends+=" libatomic-devel"
+fi
+
+_apply_patch() {
+ local args="$1" pname="$(basename $2)"
+
+ if [ ! -f ".${pname}_done" ]; then
+ patch -N $args -i $2
+ touch .${pname}_done
+ fi
+}
+
+post_patch() {
+ case "$XBPS_TARGET_MACHINE" in
+ ppc64le*) ;;
+ ppc*) _apply_patch -p1 ${FILESDIR}/altivec.patch ;;
+ esac
+}
+
+do_configure() {
+ # Fix gcc on x86_64-musl only
+ if [ "$XBPS_TARGET_MACHINE" = "x86_64-musl" ]; then
+ sed -i configure -e "s;_cflags_speed='-O3';_cflags_speed='-O2';"
+ fi
+
+ if [ "$CROSS_BUILD" ]; then
+ case "$XBPS_TARGET_MACHINE" in
+ arm*) _arch="arm";;
+ aarch64*) _arch="aarch64";;
+ mips*) _arch="mips";;
+ ppc64*) _arch="ppc64";;
+ ppc*) _arch="ppc";;
+ *) _arch="${XBPS_TARGET_MACHINE%%-musl}";;
+ esac
+
+ _args+=" --enable-cross-compile
+ --sysroot=$XBPS_CROSS_BASE
+ --cross-prefix=${XBPS_CROSS_TRIPLET}-
+ --target-os=linux --arch=${_arch}"
+ fi
+
+ case "$XBPS_TARGET_MACHINE" in
+ ppc|ppc-musl) _args+=" --disable-altivec";;
+ esac
+
+ if [ "$XBPS_TARGET_NO_ATOMIC8" ]; then
+ _args+=" --extra-libs=-latomic"
+ fi
+
+ ./configure --prefix=/usr --disable-debug --enable-gpl --enable-gnutls \
+ --disable-stripping \
+ --enable-libcdio --enable-version3 --enable-runtime-cpudetect \
+ --enable-libmp3lame --enable-libvorbis --enable-libxvid \
+ --enable-libx264 $(vopt_enable vpx libvpx) --enable-libtheora \
+ --enable-shared --enable-static --enable-libxcb \
+ $(vopt_enable pulseaudio libpulse) --enable-libfreetype --enable-libmodplug \
+ --enable-libspeex --enable-libcelt --enable-libass \
+ --enable-libopus --enable-librtmp --enable-libjack \
+ $(vopt_if fdk_aac '--enable-nonfree --enable-libfdk-aac') \
+ --disable-libopencore_amrnb --disable-libopencore_amrwb \
+ --disable-libopenjpeg \
+ --enable-postproc --enable-opencl ${_args} \
+ $(vopt_enable x265 libx265) \
+ $(vopt_enable v4l2 libv4l2) \
+ $(vopt_enable aom libaom) $(vopt_enable vaapi) $(vopt_enable vdpau) \
+ --enable-libbs2b --enable-avresample --enable-libvidstab \
+ $(vopt_enable dav1d libdav1d) \
+ $(vopt_enable zimg libzimg) \
+ $(vopt_enable webp libwebp) \
+ $(vopt_enable sofa libmysofa) \
+ $(vopt_enable vulkan) \
+ $(vopt_enable drm libdrm) \
+ $(vopt_enable svtav1 libsvtav1) \
+ $(vopt_enable srt libsrt) \
+ $(vopt_enable rist librist) \
+ $(vopt_enable mfx libmfx) \
+ $(vopt_if nvenc '--enable-nvenc') \
+ $(vopt_if nvdec '--enable-nvdec')
+}
+do_build() {
+ make ${makejobs}
+ make doc/ff{mpeg,play}.1
+}
+do_install() {
+ make DESTDIR=${DESTDIR} install install-man
+ rm -rf ${DESTDIR}/usr/bin
+}
+
+libavcodec4_package() {
+ short_desc="FFmpeg codec library"
+ pkg_install() {
+ vmove "usr/lib/libavcodec.so.*"
+ }
+}
+libavdevice4_package() {
+ short_desc="FFmpeg device handling library"
+ pkg_install() {
+ vmove "usr/lib/libavdevice.so.*"
+ }
+}
+libavresample4_package() {
+ short_desc="FFmpeg audio resampling library"
+ pkg_install() {
+ vmove "usr/lib/libavresample.so.*"
+ }
+}
+libavformat4_package() {
+ short_desc="FFmpeg file format library"
+ pkg_install() {
+ vmove "usr/lib/libavformat.so.*"
+ }
+}
+libavutil4_package() {
+ short_desc="FFmpeg utility library"
+ pkg_install() {
+ vmove "usr/lib/libavutil.so.*"
+ }
+}
+libavfilter4_package() {
+ short_desc="FFmpeg audio/video filter library"
+ pkg_install() {
+ vmove "usr/lib/libavfilter.so.*"
+ }
+}
+libpostproc4_package() {
+ short_desc="FFmpeg video postprocessing library"
+ pkg_install() {
+ vmove "usr/lib/libpostproc.so.*"
+ }
+}
+libswscale4_package() {
+ short_desc="FFmpeg video scaling library"
+ pkg_install() {
+ vmove "usr/lib/libswscale.so.*"
+ }
+}
+libswresample4_package() {
+ short_desc="FFmpeg video resampling library"
+ pkg_install() {
+ vmove "usr/lib/libswresample.so.*"
+ }
+}
+ffmpeg4-devel_package() {
+ depends="
+ libavcodec4>=${version}_${revision}
+ libavdevice4>=${version}_${revision}
+ libavformat4>=${version}_${revision}
+ libavutil4>=${version}_${revision}
+ libavfilter4>=${version}_${revision}
+ libpostproc4>=${version}_${revision}
+ libswscale4>=${version}_${revision}
+ libswresample4>=${version}_${revision}
+ libavresample4>=${version}_${revision}"
+ short_desc+=" - development files"
+ conflicts="ffmpeg-devel"
+ pkg_install() {
+ vmove usr/include
+ vmove usr/lib/pkgconfig
+ vmove usr/lib/*.a
+ vmove usr/lib/*.so
+ vmove usr/share/ffmpeg/examples
+ vmove usr/share/man/man3
+ }
+}
diff --git a/srcpkgs/libavcodec4 b/srcpkgs/libavcodec4
new file mode 120000
index 000000000000..887f354e7c6b
--- /dev/null
+++ b/srcpkgs/libavcodec4
@@ -0,0 +1 @@
+ffmpeg4
\ No newline at end of file
diff --git a/srcpkgs/libavdevice4 b/srcpkgs/libavdevice4
new file mode 120000
index 000000000000..887f354e7c6b
--- /dev/null
+++ b/srcpkgs/libavdevice4
@@ -0,0 +1 @@
+ffmpeg4
\ No newline at end of file
diff --git a/srcpkgs/libavfilter4 b/srcpkgs/libavfilter4
new file mode 120000
index 000000000000..887f354e7c6b
--- /dev/null
+++ b/srcpkgs/libavfilter4
@@ -0,0 +1 @@
+ffmpeg4
\ No newline at end of file
diff --git a/srcpkgs/libavformat4 b/srcpkgs/libavformat4
new file mode 120000
index 000000000000..887f354e7c6b
--- /dev/null
+++ b/srcpkgs/libavformat4
@@ -0,0 +1 @@
+ffmpeg4
\ No newline at end of file
diff --git a/srcpkgs/libavresample4 b/srcpkgs/libavresample4
new file mode 120000
index 000000000000..887f354e7c6b
--- /dev/null
+++ b/srcpkgs/libavresample4
@@ -0,0 +1 @@
+ffmpeg4
\ No newline at end of file
diff --git a/srcpkgs/libavutil4 b/srcpkgs/libavutil4
new file mode 120000
index 000000000000..887f354e7c6b
--- /dev/null
+++ b/srcpkgs/libavutil4
@@ -0,0 +1 @@
+ffmpeg4
\ No newline at end of file
diff --git a/srcpkgs/libpostproc4 b/srcpkgs/libpostproc4
new file mode 120000
index 000000000000..887f354e7c6b
--- /dev/null
+++ b/srcpkgs/libpostproc4
@@ -0,0 +1 @@
+ffmpeg4
\ No newline at end of file
diff --git a/srcpkgs/libswresample4 b/srcpkgs/libswresample4
new file mode 120000
index 000000000000..887f354e7c6b
--- /dev/null
+++ b/srcpkgs/libswresample4
@@ -0,0 +1 @@
+ffmpeg4
\ No newline at end of file
diff --git a/srcpkgs/libswscale4 b/srcpkgs/libswscale4
new file mode 120000
index 000000000000..887f354e7c6b
--- /dev/null
+++ b/srcpkgs/libswscale4
@@ -0,0 +1 @@
+ffmpeg4
\ No newline at end of file
From 9114267121dc20e29a132a07a7a6b39de8b3f7f3 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 19:59:04 -0400
Subject: [PATCH 003/115] opencv: update to 4.7.0.
---
common/shlibs | 104 ++++++++++++++++++++--------------------
srcpkgs/opencv/template | 8 ++--
2 files changed, 56 insertions(+), 56 deletions(-)
diff --git a/common/shlibs b/common/shlibs
index 9497f6499aa2..fcc7401be626 100644
--- a/common/shlibs
+++ b/common/shlibs
@@ -2137,58 +2137,58 @@ libcapstone.so.4 capstone-4.0_1
libhavege.so.2 libhaveged-1.9.11_1
libnih.so.1 libnih-1.0.3_1
libnih-dbus.so.1 libnih-1.0.3_1
-libopencv_quality.so.406 libopencv-4.6.0_1
-libopencv_reg.so.406 libopencv-4.6.0_1
-libopencv_surface_matching.so.406 libopencv-4.6.0_1
-libopencv_xphoto.so.406 libopencv-4.6.0_1
-libopencv_freetype.so.406 libopencv-4.6.0_1
-libopencv_fuzzy.so.406 libopencv-4.6.0_1
-libopencv_hfs.so.406 libopencv-4.6.0_1
-libopencv_img_hash.so.406 libopencv-4.6.0_1
-libopencv_line_descriptor.so.406 libopencv-4.6.0_1
-libopencv_saliency.so.406 libopencv-4.6.0_1
-libopencv_structured_light.so.406 libopencv-4.6.0_1
-libopencv_aruco.so.406 libopencv-4.6.0_1
-libopencv_bgsegm.so.406 libopencv-4.6.0_1
-libopencv_bioinspired.so.406 libopencv-4.6.0_1
-libopencv_ccalib.so.406 libopencv-4.6.0_1
-libopencv_face.so.406 libopencv-4.6.0_1
-libopencv_tracking.so.406 libopencv-4.6.0_1
-libopencv_xfeatures2d.so.406 libopencv-4.6.0_1
-libopencv_optflow.so.406 libopencv-4.6.0_1
-libopencv_ximgproc.so.406 libopencv-4.6.0_1
-libopencv_plot.so.406 libopencv-4.6.0_1
-libopencv_text.so.406 libopencv-4.6.0_1
-libopencv_ml.so.406 libopencv-4.6.0_1
-libopencv_objdetect.so.406 libopencv-4.6.0_1
-libopencv_dnn.so.406 libopencv-4.6.0_1
-libopencv_shape.so.406 libopencv-4.6.0_1
-libopencv_stitching.so.406 libopencv-4.6.0_1
-libopencv_photo.so.406 libopencv-4.6.0_1
-libopencv_video.so.406 libopencv-4.6.0_1
-libopencv_calib3d.so.406 libopencv-4.6.0_1
-libopencv_features2d.so.406 libopencv-4.6.0_1
-libopencv_flann.so.406 libopencv-4.6.0_1
-libopencv_highgui.so.406 libopencv-4.6.0_1
-libopencv_videoio.so.406 libopencv-4.6.0_1
-libopencv_imgcodecs.so.406 libopencv-4.6.0_1
-libopencv_imgproc.so.406 libopencv-4.6.0_1
-libopencv_core.so.406 libopencv-4.6.0_1
-libopencv_superres.so.406 libopencv-4.6.0_1
-libopencv_videostab.so.406 libopencv-4.6.0_1
-libopencv_gapi.so.406 libopencv-4.6.0_1
-libopencv_xobjdetect.so.406 libopencv-4.6.0_1
-libopencv_datasets.so.406 libopencv-4.6.0_1
-libopencv_dnn_objdetect.so.406 libopencv-4.6.0_1
-libopencv_dnn_superres.so.406 libopencv-4.6.0_1
-libopencv_dpm.so.406 libopencv-4.6.0_1
-libopencv_phase_unwrapping.so.406 libopencv-4.6.0_1
-libopencv_stereo.so.406 libopencv-4.6.0_1
-libopencv_rapid.so.406 libopencv-4.6.0_1
-libopencv_intensity_transform.so.406 libopencv-4.6.0_1
-libopencv_alphamat.so.406 libopencv-4.6.0_1
-libopencv_barcode.so.406 libopencv-4.6.0_1
-libopencv_mcc.so.406 libopencv-4.6.0_1
+libopencv_quality.so.407 libopencv-4.7.0_1
+libopencv_reg.so.407 libopencv-4.7.0_1
+libopencv_surface_matching.so.407 libopencv-4.7.0_1
+libopencv_xphoto.so.407 libopencv-4.7.0_1
+libopencv_freetype.so.407 libopencv-4.7.0_1
+libopencv_fuzzy.so.407 libopencv-4.7.0_1
+libopencv_hfs.so.407 libopencv-4.7.0_1
+libopencv_img_hash.so.407 libopencv-4.7.0_1
+libopencv_line_descriptor.so.407 libopencv-4.7.0_1
+libopencv_saliency.so.407 libopencv-4.7.0_1
+libopencv_structured_light.so.407 libopencv-4.7.0_1
+libopencv_aruco.so.407 libopencv-4.7.0_1
+libopencv_bgsegm.so.407 libopencv-4.7.0_1
+libopencv_bioinspired.so.407 libopencv-4.7.0_1
+libopencv_ccalib.so.407 libopencv-4.7.0_1
+libopencv_face.so.407 libopencv-4.7.0_1
+libopencv_tracking.so.407 libopencv-4.7.0_1
+libopencv_xfeatures2d.so.407 libopencv-4.7.0_1
+libopencv_optflow.so.407 libopencv-4.7.0_1
+libopencv_ximgproc.so.407 libopencv-4.7.0_1
+libopencv_plot.so.407 libopencv-4.7.0_1
+libopencv_text.so.407 libopencv-4.7.0_1
+libopencv_ml.so.407 libopencv-4.7.0_1
+libopencv_objdetect.so.407 libopencv-4.7.0_1
+libopencv_dnn.so.407 libopencv-4.7.0_1
+libopencv_shape.so.407 libopencv-4.7.0_1
+libopencv_stitching.so.407 libopencv-4.7.0_1
+libopencv_photo.so.407 libopencv-4.7.0_1
+libopencv_video.so.407 libopencv-4.7.0_1
+libopencv_calib3d.so.407 libopencv-4.7.0_1
+libopencv_features2d.so.407 libopencv-4.7.0_1
+libopencv_flann.so.407 libopencv-4.7.0_1
+libopencv_highgui.so.407 libopencv-4.7.0_1
+libopencv_videoio.so.407 libopencv-4.7.0_1
+libopencv_imgcodecs.so.407 libopencv-4.7.0_1
+libopencv_imgproc.so.407 libopencv-4.7.0_1
+libopencv_core.so.407 libopencv-4.7.0_1
+libopencv_superres.so.407 libopencv-4.7.0_1
+libopencv_videostab.so.407 libopencv-4.7.0_1
+libopencv_gapi.so.407 libopencv-4.7.0_1
+libopencv_xobjdetect.so.407 libopencv-4.7.0_1
+libopencv_datasets.so.407 libopencv-4.7.0_1
+libopencv_dnn_objdetect.so.407 libopencv-4.7.0_1
+libopencv_dnn_superres.so.407 libopencv-4.7.0_1
+libopencv_dpm.so.407 libopencv-4.7.0_1
+libopencv_phase_unwrapping.so.407 libopencv-4.7.0_1
+libopencv_stereo.so.407 libopencv-4.7.0_1
+libopencv_rapid.so.407 libopencv-4.7.0_1
+libopencv_intensity_transform.so.407 libopencv-4.7.0_1
+libopencv_alphamat.so.407 libopencv-4.7.0_1
+libopencv_barcode.so.407 libopencv-4.7.0_1
+libopencv_mcc.so.407 libopencv-4.7.0_1
libuniconf.so.4.6 wvstreams-4.6.1_20
libwvbase.so.4.6 wvstreams-4.6.1_20
libwvutils.so.4.6 wvstreams-4.6.1_20
diff --git a/srcpkgs/opencv/template b/srcpkgs/opencv/template
index 69c635b1ad2b..41f3183f1582 100644
--- a/srcpkgs/opencv/template
+++ b/srcpkgs/opencv/template
@@ -1,7 +1,7 @@
# Template file for 'opencv'
pkgname=opencv
-version=4.6.0
-revision=4
+version=4.7.0
+revision=1
create_wrksrc=yes
build_wrksrc=${pkgname}-${version}
build_style=cmake
@@ -24,8 +24,8 @@ homepage="https://opencv.org"
changelog="https://github.com/opencv/opencv/wiki/ChangeLog"
distfiles="https://github.com/opencv/opencv/archive/${version}.tar.gz
https://github.com/opencv/opencv_contrib/archive/${version}.tar.gz>contrib.tar.gz"
-checksum="1ec1cba65f9f20fe5a41fda1586e01c70ea0c9a6d7b67c9e13edf0cfe2239277
- 1777d5fd2b59029cf537e5fd6f8aa68d707075822f90bde683fcde086f85f7a7"
+checksum="8df0079cdbe179748a18d44731af62a245a45ebf5085223dc03133954c662973
+ 42df840cf9055e59d0e22c249cfb19f04743e1bdad113d31b1573d3934d62584"
patch_args="-Np1 -d ${build_wrksrc}"
# tests hang indenfinitely, even with test data included
make_check=no
From 6135f7a9607b47c60f4340b5d2736a024dc1c3e5 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 19:59:45 -0400
Subject: [PATCH 004/115] actiona: revbump for opencv-4.7.0
---
srcpkgs/actiona/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/actiona/template b/srcpkgs/actiona/template
index cf5f0b7a2ae6..0d899311e6df 100644
--- a/srcpkgs/actiona/template
+++ b/srcpkgs/actiona/template
@@ -1,7 +1,7 @@
# Template file for 'actiona'
pkgname=actiona
version=3.10.1
-revision=2
+revision=3
build_style=qmake
configure_args="PKGCONFIG_OPENCV=opencv4"
hostmakedepends="pkg-config qt5-plugin-mysql qt5-qmake qt5-host-tools"
From bb4405ae6656d539e721fb3dca56b80924167799 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 19:59:45 -0400
Subject: [PATCH 005/115] gmic: revbump for opencv-4.7.0
---
srcpkgs/gmic/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/gmic/template b/srcpkgs/gmic/template
index 24a9c7218fdf..0bb4034d5cc8 100644
--- a/srcpkgs/gmic/template
+++ b/srcpkgs/gmic/template
@@ -1,7 +1,7 @@
# Template file for 'gmic'
pkgname=gmic
version=3.1.6
-revision=3
+revision=4
_zart_hash=34ebf6cce0bafb98abe57cec83c4a02cd1abeca0
create_wrksrc=yes
build_wrksrc="src"
From 0c8688ca1d27b3c0ba8ce57a02281575959a2455 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 19:59:46 -0400
Subject: [PATCH 006/115] qimgv: revbump for opencv-4.7.0
---
srcpkgs/qimgv/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/qimgv/template b/srcpkgs/qimgv/template
index 7eb30db33992..dd341dfe1bfc 100644
--- a/srcpkgs/qimgv/template
+++ b/srcpkgs/qimgv/template
@@ -1,7 +1,7 @@
# Template file for 'qimgv'
pkgname=qimgv
version=1.0.2
-revision=2
+revision=3
build_style=cmake
configure_args="$(vopt_if video -DVIDEO_SUPPORT=ON -DVIDEO_SUPPORT=OFF)
$(vopt_if scale -DOPENCV_SUPPORT=ON -DOPENCV_SUPPORT=OFF)
From cc1cb7326876f5aeea947414fd7dbb62fc1f1593 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 19:59:46 -0400
Subject: [PATCH 007/115] retroshare: revbump for opencv-4.7.0
---
srcpkgs/retroshare/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/retroshare/template b/srcpkgs/retroshare/template
index 8a0786c21a08..72023fa98b75 100644
--- a/srcpkgs/retroshare/template
+++ b/srcpkgs/retroshare/template
@@ -1,7 +1,7 @@
# Template file for 'retroshare'
pkgname=retroshare
version=0.6.6
-revision=2
+revision=4
build_style=qmake
#XXX broadcast feature requires an ancient udp-discovery-cpp which either needs
# to be fetched+patched (FTBFS) here or packaged :/
From bf2f235fbe2d0344eb5f43f92e44cad3f35e0544 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 19:59:46 -0400
Subject: [PATCH 008/115] siril: revbump for opencv-4.7.0
---
srcpkgs/siril/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/siril/template b/srcpkgs/siril/template
index e88f30fb6178..84332f79d060 100644
--- a/srcpkgs/siril/template
+++ b/srcpkgs/siril/template
@@ -1,7 +1,7 @@
# Template file for 'siril'
pkgname=siril
version=0.9.12
-revision=9
+revision=10
build_style=gnu-configure
hostmakedepends="pkg-config intltool autoconf automake gettext-devel"
makedepends="fftw-devel libconfig-devel libopencv-devel libffms2-devel
From e80fe533b645ea6c5da57e894077e76f29c63c2f Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 19:59:46 -0400
Subject: [PATCH 009/115] waifu2x-converter-cpp: revbump for opencv-4.7.0
---
srcpkgs/waifu2x-converter-cpp/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/waifu2x-converter-cpp/template b/srcpkgs/waifu2x-converter-cpp/template
index 8c095d0d7bab..aa52d8c981a8 100644
--- a/srcpkgs/waifu2x-converter-cpp/template
+++ b/srcpkgs/waifu2x-converter-cpp/template
@@ -1,7 +1,7 @@
# Template file for 'waifu2x-converter-cpp'
pkgname=waifu2x-converter-cpp
version=5.2.4
-revision=2
+revision=3
build_style=cmake
configure_args="-DINSTALL_MODELS=ON"
hostmakedepends="pkg-config"
From 76f75fc7f7348a1450c2ae89bb44c545e8069902 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:00:38 -0400
Subject: [PATCH 010/115] vlc: revbump for ffmpeg4-4.4.3
---
srcpkgs/vlc/template | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/srcpkgs/vlc/template b/srcpkgs/vlc/template
index 210762b0a7e2..855ca5238662 100644
--- a/srcpkgs/vlc/template
+++ b/srcpkgs/vlc/template
@@ -1,7 +1,7 @@
# Template file for 'vlc'
pkgname=vlc
version=3.0.18
-revision=3
+revision=4
build_style=gnu-configure
configure_args="--disable-gme --disable-libtar --enable-jack
--enable-live555 --disable-fluidsynth --enable-dvdread
@@ -25,7 +25,7 @@ lib32disabled=yes
hostmakedepends="automake libtool pkg-config flex gettext libgcrypt-devel
live555-devel gettext-devel $(vopt_if lua lua52) $(vopt_if chromecast protobuf)"
makedepends="
- avahi-libs-devel dbus-glib-devel faad2-devel ffmpeg-devel freefont-ttf
+ avahi-libs-devel dbus-glib-devel faad2-devel ffmpeg4-devel freefont-ttf
gnutls-devel jack-devel liba52-devel libass-devel libbluray-devel
libcdio-devel libdca-devel libdvbpsi-devel libdvdnav-devel libmad-devel
libmatroska-devel libmodplug-devel libmpcdec-devel libmpeg2-devel
From 10a7f7d081d20388e213f2aabac2e04249e678ac Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:00:55 -0400
Subject: [PATCH 011/115] osg: revbump for ffmpeg4-4.4.3
---
srcpkgs/osg/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/osg/template b/srcpkgs/osg/template
index a9ebbd287933..755793f7e11b 100644
--- a/srcpkgs/osg/template
+++ b/srcpkgs/osg/template
@@ -8,7 +8,7 @@ build_helper="qemu"
configure_args="-DLIB_POSTFIX="
hostmakedepends="pkg-config xrandr"
makedepends="MesaLib-devel gtkglext-devel libcurl-devel giflib-devel librsvg-devel
- jasper-devel tiff-devel libgdal-devel libgta-devel ffmpeg-devel xine-lib-devel
+ jasper-devel tiff-devel libgdal-devel libgta-devel ffmpeg4-devel xine-lib-devel
SDL2-devel gst-plugins-base1-devel
$(vopt_if openexr libopenexr-devel)
$(vopt_if poppler poppler-glib-devel)
From 2889d5fa7ebdf7626c90698e914a8f574077e2e3 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:13 -0400
Subject: [PATCH 012/115] xine-lib: revbump for ffmpeg4-4.4.3
---
srcpkgs/xine-lib/template | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/srcpkgs/xine-lib/template b/srcpkgs/xine-lib/template
index f713eff49b07..ed6194c17d11 100644
--- a/srcpkgs/xine-lib/template
+++ b/srcpkgs/xine-lib/template
@@ -1,6 +1,6 @@
# Template file for 'xine-lib'
pkgname=xine-lib
-version=1.2.12
+version=1.2.13
revision=1
build_style=gnu-configure
configure_args="--disable-vcd --disable-gnomevfs --without-esound --disable-dxr3
@@ -8,7 +8,7 @@ configure_args="--disable-vcd --disable-gnomevfs --without-esound --disable-dxr3
hostmakedepends="automake gettext-devel libtool pkg-config perl"
makedepends="
zlib-devel alsa-lib-devel libxcb-devel libSM-devel libXext-devel libXv-devel
- libXvMC-devel liba52-devel libmad-devel ffmpeg-devel pulseaudio-devel
+ libXvMC-devel liba52-devel libmad-devel ffmpeg4-devel pulseaudio-devel
jack-devel samba-devel libflac-devel libmodplug-devel libmpcdec-devel
speex-devel libtheora-devel libvorbis-devel libdca-devel faad2-devel
libcdio-devel libbluray-devel aalib-devel libcaca-devel libXinerama-devel
@@ -19,7 +19,7 @@ license="GPL-2.0-or-later, LGPL-2.0-or-later"
homepage="http://www.xine-project.org"
changelog="https://sourceforge.net/projects/xine/files/xine-lib/${version}/README.txt/view"
distfiles="${SOURCEFORGE_SITE}/xine/${pkgname}-${version}.tar.xz"
-checksum=d606270468e1540c2a89c0d7f5fdf11e17ecc0c2698cc0bcb1065ff26abee098
+checksum=5f10d6d718a4a51c17ed1b32b031d4f9b80b061e8276535b2be31e5ac4b75e6f
case "$XBPS_TARGET_MACHINE" in
i686-musl)
From f090af258afe17d08b255a4f00ae4f52137f966f Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:45 -0400
Subject: [PATCH 013/115] QMPlay2: revbump for ffmpeg-6.0
---
srcpkgs/QMPlay2/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/QMPlay2/template b/srcpkgs/QMPlay2/template
index ad73cbb01bae..55284c051161 100644
--- a/srcpkgs/QMPlay2/template
+++ b/srcpkgs/QMPlay2/template
@@ -1,7 +1,7 @@
# Template file for 'QMPlay2'
pkgname=QMPlay2
version=23.02.05
-revision=1
+revision=2
build_style=cmake
hostmakedepends="pkg-config qt5-qmake qt5-host-tools"
makedepends="alsa-lib-devel ffmpeg-devel libass-devel libcdio-devel libgme-devel
From a4c49254105e3b89910b04c7b22add59592f77e5 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:45 -0400
Subject: [PATCH 014/115] alsa-plugins: revbump for ffmpeg-6.0
---
srcpkgs/alsa-plugins/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/alsa-plugins/template b/srcpkgs/alsa-plugins/template
index 0bfa6d9fd264..a5708a7d82a8 100644
--- a/srcpkgs/alsa-plugins/template
+++ b/srcpkgs/alsa-plugins/template
@@ -1,7 +1,7 @@
# Template file for 'alsa-plugins'
pkgname=alsa-plugins
version=1.2.7.1
-revision=1
+revision=2
build_style=gnu-configure
configure_args="--disable-maemo-plugin"
hostmakedepends="pkg-config"
From e55ecc75068286d87db2cbd96dece3dff612178f Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:45 -0400
Subject: [PATCH 015/115] arcan: revbump for ffmpeg-6.0
---
srcpkgs/arcan/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/arcan/template b/srcpkgs/arcan/template
index 7be9652eccf3..ccc7df11ceac 100644
--- a/srcpkgs/arcan/template
+++ b/srcpkgs/arcan/template
@@ -2,7 +2,7 @@
# !! keep synced with: acfgfs aclip aloadimage
pkgname=arcan
version=0.6.2.1
-revision=1
+revision=2
create_wrksrc=yes
build_wrksrc=arcan/src
build_style=cmake
From 1d3853b9d6c40618030e4d4aba6b07ccdd46d9a0 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:45 -0400
Subject: [PATCH 016/115] attract: revbump for ffmpeg4-4.4.3
---
srcpkgs/attract/template | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/srcpkgs/attract/template b/srcpkgs/attract/template
index 26144e931a3c..e760bf0d18ae 100644
--- a/srcpkgs/attract/template
+++ b/srcpkgs/attract/template
@@ -1,12 +1,12 @@
# Template file for 'attract'
pkgname=attract
version=2.6.2
-revision=1
+revision=2
build_style=gnu-makefile
make_build_args="VERBOSE=1"
make_use_env=yes
hostmakedepends="pkg-config"
-makedepends="SFML-devel ffmpeg-devel fontconfig-devel glu-devel libarchive-devel
+makedepends="SFML-devel ffmpeg4-devel fontconfig-devel glu-devel libarchive-devel
libcurl-devel libjpeg-turbo-devel xine-lib rapidjson libXrandr-devel"
depends="git"
short_desc="Attract-Mode is a graphical frontend for emulators"
From 36847e27f7d820302eb4ce70aa9d050a0bb70d86 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:45 -0400
Subject: [PATCH 017/115] aubio: revbump for ffmpeg-6.0
---
srcpkgs/aubio/patches/ffmpeg5.patch | 25 +++++++++++++++++++++++++
srcpkgs/aubio/template | 2 +-
2 files changed, 26 insertions(+), 1 deletion(-)
create mode 100644 srcpkgs/aubio/patches/ffmpeg5.patch
diff --git a/srcpkgs/aubio/patches/ffmpeg5.patch b/srcpkgs/aubio/patches/ffmpeg5.patch
new file mode 100644
index 000000000000..aace41a6e6d9
--- /dev/null
+++ b/srcpkgs/aubio/patches/ffmpeg5.patch
@@ -0,0 +1,25 @@
+From 8a05420e5dd8c7b8b2447f82dc919765876511b3 Mon Sep 17 00:00:00 2001
+From: Paul Brossier <piem@piem.org>
+Date: Tue, 25 Jan 2022 18:30:27 +0100
+Subject: [PATCH] [source_avcodec] define FF_API_LAVF_AVCTX for libavcodec >
+ 59, thx @berolinux (closes gh-353)
+
+---
+ src/io/source_avcodec.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/src/io/source_avcodec.c b/src/io/source_avcodec.c
+index e0ae93b5..1421bd9a 100644
+--- a/src/io/source_avcodec.c
++++ b/src/io/source_avcodec.c
+@@ -68,6 +68,10 @@
+ #define AUBIO_AVCODEC_MAX_BUFFER_SIZE AV_INPUT_BUFFER_MIN_SIZE
+ #endif
+
++#if LIBAVCODEC_VERSION_MAJOR >= 59
++#define FF_API_LAVF_AVCTX 1
++#endif
++
+ struct _aubio_source_avcodec_t {
+ uint_t hop_size;
+ uint_t samplerate;
diff --git a/srcpkgs/aubio/template b/srcpkgs/aubio/template
index ad1c4b256991..7d875cc02541 100644
--- a/srcpkgs/aubio/template
+++ b/srcpkgs/aubio/template
@@ -1,7 +1,7 @@
# Template file for 'aubio'
pkgname=aubio
version=0.4.9
-revision=1
+revision=2
build_style=waf3
# XXX lash, pure and swig support.
hostmakedepends="pkg-config txt2man"
From b698d4116032d9ba973025461f631a27282ae823 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:45 -0400
Subject: [PATCH 018/115] audacious-plugins: revbump for ffmpeg-6.0
---
.../audacious-plugins/patches/ffmpeg5.patch | 43 +++++++++++++++++++
srcpkgs/audacious-plugins/template | 2 +-
2 files changed, 44 insertions(+), 1 deletion(-)
create mode 100644 srcpkgs/audacious-plugins/patches/ffmpeg5.patch
diff --git a/srcpkgs/audacious-plugins/patches/ffmpeg5.patch b/srcpkgs/audacious-plugins/patches/ffmpeg5.patch
new file mode 100644
index 000000000000..4e5e34099d71
--- /dev/null
+++ b/srcpkgs/audacious-plugins/patches/ffmpeg5.patch
@@ -0,0 +1,43 @@
+commit 298aa371c56c2f52c25a33d9bdec4918b11cebdc
+Author: tibequadorian <tibequadorian@posteo.de>
+Date: Sat Mar 19 18:40:12 2022 +0100
+
+ audacious-plugins: rebuild against ffmpeg-5.0
+
+diff --git a/srcpkgs/audacious-plugins/patches/ffmpeg-5.0.patch b/srcpkgs/audacious-plugins/patches/ffmpeg-5.0.patch
+new file mode 100644
+index 0000000000..617c11215b
+--- /dev/null
++++ b/srcpkgs/audacious-plugins/patches/ffmpeg-5.0.patch
+@@ -0,0 +1,31 @@
++From f60beb400eeb1e4778bbfd738bc4a4ccef3de539 Mon Sep 17 00:00:00 2001
++From: John Lindgren <john@jlindgren.net>
++Date: Sat, 5 Mar 2022 12:05:34 -0500
++Subject: [PATCH] Fix build with FFmpeg 5.0
++
++---
++ src/ffaudio/ffaudio-core.cc | 4 ++--
++ 1 file changed, 2 insertions(+), 2 deletions(-)
++
++diff --git a/src/ffaudio/ffaudio-core.cc b/src/ffaudio/ffaudio-core.cc
++index 16dc63e3a..a2b95fd6c 100644
++--- a/src/ffaudio/ffaudio-core.cc
+++++ b/src/ffaudio/ffaudio-core.cc
++@@ -274,7 +274,7 @@ static AVInputFormat * get_format_by_content (const char * name, VFSFile & file)
++ AVProbeData d = {name, buf, filled};
++ score = target;
++
++- f = av_probe_input_format2 (& d, true, & score);
+++ f = (AVInputFormat *) av_probe_input_format2 (& d, true, & score);
++ if (f)
++ break;
++
++@@ -347,7 +347,7 @@ static bool find_codec (AVFormatContext * c, CodecInfo * cinfo)
++ #endif
++ if (stream && stream->codecpar && stream->codecpar->codec_type == AVMEDIA_TYPE_AUDIO)
++ {
++- AVCodec * codec = avcodec_find_decoder (stream->codecpar->codec_id);
+++ AVCodec * codec = (AVCodec *) avcodec_find_decoder (stream->codecpar->codec_id);
++
++ if (codec)
++ {
diff --git a/srcpkgs/audacious-plugins/template b/srcpkgs/audacious-plugins/template
index 88cbc1671fc6..beebfae59ed4 100644
--- a/srcpkgs/audacious-plugins/template
+++ b/srcpkgs/audacious-plugins/template
@@ -2,7 +2,7 @@
#Keep in sync with audacious!
pkgname=audacious-plugins
version=4.3.1
-revision=1
+revision=2
build_style=meson
configure_args="$(vopt_bool gtk3 gtk) $(vopt_bool gtk3)
$(vopt_bool qt) $(vopt_bool qt qt6)"
From 726d6008341e15e79027526fa134cff9ff60c03d Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:45 -0400
Subject: [PATCH 019/115] audacity: revbump for ffmpeg4-4.4.3
---
srcpkgs/audacity/template | 5 ++---
1 file changed, 2 insertions(+), 3 deletions(-)
diff --git a/srcpkgs/audacity/template b/srcpkgs/audacity/template
index d509c0a89407..11e20255685b 100644
--- a/srcpkgs/audacity/template
+++ b/srcpkgs/audacity/template
@@ -1,7 +1,7 @@
# Template file for 'audacity'
pkgname=audacity
version=2.4.1
-revision=2
+revision=3
build_style=gnu-configure
configure_args="--with-ffmpeg=system --with-libsndfile=system --with-expat=system
--with-libsoxr=system --with-lame=system --with-lv2=system ac_cv_path_WX_CONFIG=wx-config-gtk3"
@@ -9,7 +9,7 @@ hostmakedepends="pkg-config cmake gettext libtool m4 which"
makedepends="jack-devel wxWidgets-gtk3-devel gtk+3-devel
libmad-devel soundtouch-devel libsoxr-devel
vamp-plugin-sdk-devel lame-devel libid3tag-devel libflac-devel
- ffmpeg-devel twolame-devel serd-devel lv2 lilv-devel suil-devel"
+ ffmpeg4-devel twolame-devel serd-devel lv2 lilv-devel suil-devel"
depends="desktop-file-utils hicolor-icon-theme"
short_desc="Graphical cross-platform audio editor"
maintainer="Orphaned <orphan@voidlinux.org>"
@@ -33,5 +33,4 @@ post_install() {
vcopy plug-ins /usr/share/audacity
rm ${DESTDIR}/usr/share/doc/audacity/LICENSE.txt
- vlicense LICENSE.txt LICENSE
}
From 34cb1b58b2516b5994a58dbb9df10455e97950d4 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:45 -0400
Subject: [PATCH 020/115] avidemux: revbump for ffmpeg-6.0
---
srcpkgs/avidemux/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/avidemux/template b/srcpkgs/avidemux/template
index 253a0243e225..557285982d2b 100644
--- a/srcpkgs/avidemux/template
+++ b/srcpkgs/avidemux/template
@@ -1,7 +1,7 @@
# Template file for 'avidemux'
pkgname=avidemux
version=2.8.0
-revision=2
+revision=3
# Can't be compiled for aarch64, arm* or mips*
archs="x86_64* i686*"
hostmakedepends="cmake pkg-config qt5-host-tools qt5-devel tar yasm"
From da7c79c4eba97dd2f235318fd422506a62925bb3 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:45 -0400
Subject: [PATCH 021/115] baresip: revbump for ffmpeg-6.0
---
srcpkgs/baresip/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/baresip/template b/srcpkgs/baresip/template
index f1bd1817048b..b21e22334316 100644
--- a/srcpkgs/baresip/template
+++ b/srcpkgs/baresip/template
@@ -1,7 +1,7 @@
# Template file for 'baresip'
pkgname=baresip
version=2.10.0
-revision=1
+revision=2
build_style=cmake
hostmakedepends="pkg-config glib-devel"
makedepends="libgsm-devel libpng-devel openssl-devel libsndfile-devel
From 201bee8767aff1e59a176e37a8f6985afecd2dcd Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:46 -0400
Subject: [PATCH 022/115] blender: revbump for ffmpeg-6.0
---
.../patches/ffmpeg6-compat-blender.patch | 42 +++++++++++++++++++
srcpkgs/blender/template | 2 +-
2 files changed, 43 insertions(+), 1 deletion(-)
create mode 100644 srcpkgs/blender/patches/ffmpeg6-compat-blender.patch
diff --git a/srcpkgs/blender/patches/ffmpeg6-compat-blender.patch b/srcpkgs/blender/patches/ffmpeg6-compat-blender.patch
new file mode 100644
index 000000000000..d51a9c7710cc
--- /dev/null
+++ b/srcpkgs/blender/patches/ffmpeg6-compat-blender.patch
@@ -0,0 +1,42 @@
+--- a/source/blender/blenkernel/intern/writeffmpeg.c 2022-11-08 13:50:16 UTC
++++ b/source/blender/blenkernel/intern/writeffmpeg.c
+@@ -855,7 +855,7 @@ static AVStream *alloc_video_stream(FFMpegContext *con
+ 255);
+ st->avg_frame_rate = av_inv_q(c->time_base);
+
+- if (codec->capabilities & AV_CODEC_CAP_AUTO_THREADS) {
++ if (codec->capabilities & AV_CODEC_CAP_OTHER_THREADS) {
+ c->thread_count = 0;
+ }
+ else {
+--- a/source/blender/imbuf/intern/anim_movie.c 2022-11-04 00:33:07 UTC
++++ b/source/blender/imbuf/intern/anim_movie.c
+@@ -554,7 +554,7 @@ static int startffmpeg(struct anim *anim)
+ avcodec_parameters_to_context(pCodecCtx, video_stream->codecpar);
+ pCodecCtx->workaround_bugs = FF_BUG_AUTODETECT;
+
+- if (pCodec->capabilities & AV_CODEC_CAP_AUTO_THREADS) {
++ if (pCodec->capabilities & AV_CODEC_CAP_OTHER_THREADS) {
+ pCodecCtx->thread_count = 0;
+ }
+ else {
+--- a/source/blender/imbuf/intern/indexer.c 2022-11-04 00:33:07 UTC
++++ b/source/blender/imbuf/intern/indexer.c
+@@ -559,7 +559,7 @@ static struct proxy_output_ctx *alloc_proxy_output_ffm
+ av_dict_set(&codec_opts, "preset", "veryfast", 0);
+ av_dict_set(&codec_opts, "tune", "fastdecode", 0);
+
+- if (rv->codec->capabilities & AV_CODEC_CAP_AUTO_THREADS) {
++ if (rv->codec->capabilities & AV_CODEC_CAP_OTHER_THREADS) {
+ rv->c->thread_count = 0;
+ }
+ else {
+@@ -872,7 +872,7 @@ static IndexBuildContext *index_ffmpeg_create_context(
+ avcodec_parameters_to_context(context->iCodecCtx, context->iStream->codecpar);
+ context->iCodecCtx->workaround_bugs = FF_BUG_AUTODETECT;
+
+- if (context->iCodec->capabilities & AV_CODEC_CAP_AUTO_THREADS) {
++ if (context->iCodec->capabilities & AV_CODEC_CAP_OTHER_THREADS) {
+ context->iCodecCtx->thread_count = 0;
+ }
+ else {
diff --git a/srcpkgs/blender/template b/srcpkgs/blender/template
index 61b42eb2e51e..d18bc88838ff 100644
--- a/srcpkgs/blender/template
+++ b/srcpkgs/blender/template
@@ -1,7 +1,7 @@
# Template file for 'blender'
pkgname=blender
version=3.4.1
-revision=3
+revision=4
archs="x86_64* ppc64*"
build_style="cmake"
pycompile_dirs="/usr/share/blender/${version%.*}/scripts"
From d1beefb550f44520729886469d68e3055bb211c9 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:46 -0400
Subject: [PATCH 023/115] cantata: revbump for ffmpeg-6.0
---
srcpkgs/cantata/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/cantata/template b/srcpkgs/cantata/template
index 4b417d80d5c2..8a90aaa4c07a 100644
--- a/srcpkgs/cantata/template
+++ b/srcpkgs/cantata/template
@@ -1,7 +1,7 @@
# Template file for 'cantata'
pkgname=cantata
version=2.5.0
-revision=1
+revision=2
build_style=cmake
hostmakedepends="pkg-config qt5-qmake qt5-host-tools qt5-tools"
makedepends="qt5-devel qt5-tools-devel qt5-svg-devel qt5-xmlpatterns-devel
From a30aef40400d89e2f7eee4d7abd19cc4033f9e38 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:46 -0400
Subject: [PATCH 024/115] ccextractor: revbump for ffmpeg4-4.4.3
---
srcpkgs/ccextractor/template | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/srcpkgs/ccextractor/template b/srcpkgs/ccextractor/template
index 9abcd82852b2..6eccad5885af 100644
--- a/srcpkgs/ccextractor/template
+++ b/srcpkgs/ccextractor/template
@@ -1,12 +1,12 @@
# Template file for 'ccextractor'
pkgname=ccextractor
version=0.93
-revision=1
+revision=2
build_wrksrc="linux"
build_style=gnu-configure
configure_args="--enable-ocr --enable-hardsubx"
hostmakedepends="automake pkg-config"
-makedepends="leptonica-devel tesseract-ocr-devel ffmpeg-devel"
+makedepends="leptonica-devel tesseract-ocr-devel ffmpeg4-devel"
short_desc="Extract subtitles from video streams"
maintainer="newbluemoon <blaumolch@mailbox.org>"
license="GPL-2.0-or-later"
From f133fcd2c5ed3aba4d6d04665196de4c82d02718 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:46 -0400
Subject: [PATCH 025/115] chromaprint: revbump for ffmpeg-6.0
---
srcpkgs/chromaprint/patches/ffmpeg5.patch | 569 ++++++++++++++++++++++
srcpkgs/chromaprint/template | 2 +-
2 files changed, 570 insertions(+), 1 deletion(-)
create mode 100644 srcpkgs/chromaprint/patches/ffmpeg5.patch
diff --git a/srcpkgs/chromaprint/patches/ffmpeg5.patch b/srcpkgs/chromaprint/patches/ffmpeg5.patch
new file mode 100644
index 000000000000..a9fd307a23c8
--- /dev/null
+++ b/srcpkgs/chromaprint/patches/ffmpeg5.patch
@@ -0,0 +1,569 @@
+From 8ccad6937177b1b92e40ab8f4447ea27bac009a7 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Luk=C3=A1=C5=A1=20Lalinsk=C3=BD?= <lalinsky@gmail.com>
+Date: Fri, 4 Nov 2022 21:47:38 +0100
+Subject: [PATCH] Use FFmpeg 5.x (#120)
+
+* Use FFmpeg 5.1.2 for CI builds
+
+* Build on Ubuntu 20.04
+
+* Upgrade code to FFmpeg 5.x APIs
+
+* Only set FFmpeg include dirs if building tools
+
+* No longer needed
+
+* Use ubuntu 20.04
+---
+ .github/workflows/build.yml | 6 +-
+ CMakeLists.txt | 16 --
+ package/build.sh | 4 +-
+ src/audio/ffmpeg_audio_processor.h | 2 -
+ src/audio/ffmpeg_audio_processor_avresample.h | 72 -------
+ src/audio/ffmpeg_audio_processor_swresample.h | 18 +-
+ src/audio/ffmpeg_audio_reader.h | 197 +++++++++---------
+ tests/CMakeLists.txt | 6 +
+ 8 files changed, 122 insertions(+), 199 deletions(-)
+ delete mode 100644 src/audio/ffmpeg_audio_processor_avresample.h
+
+diff --git a/CMakeLists.txt b/CMakeLists.txt
+index f8d6a32..4da2405 100644
+--- a/CMakeLists.txt
++++ b/CMakeLists.txt
+@@ -84,9 +84,6 @@ find_package(FFmpeg)
+ if(FFMPEG_LIBRARIES)
+ cmake_push_check_state(RESET)
+ set(CMAKE_REQUIRED_LIBRARIES ${FFMPEG_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT} -lm)
+- check_function_exists(av_packet_unref HAVE_AV_PACKET_UNREF)
+- check_function_exists(av_frame_alloc HAVE_AV_FRAME_ALLOC)
+- check_function_exists(av_frame_free HAVE_AV_FRAME_FREE)
+ cmake_pop_check_state()
+ endif()
+
+@@ -163,14 +160,11 @@ message(STATUS "Using ${FFT_LIB} for FFT calculations")
+ if(NOT AUDIO_PROCESSOR_LIB)
+ if(FFMPEG_LIBSWRESAMPLE_FOUND)
+ set(AUDIO_PROCESSOR_LIB "swresample")
+- elseif(FFMPEG_LIBAVRESAMPLE_FOUND)
+- set(AUDIO_PROCESSOR_LIB "avresample")
+ endif()
+ endif()
+
+ if(AUDIO_PROCESSOR_LIB STREQUAL "swresample")
+ if(FFMPEG_LIBSWRESAMPLE_FOUND)
+- set(USE_AVRESAMPLE OFF)
+ set(USE_SWRESAMPLE ON)
+ set(AUDIO_PROCESSOR_LIBRARIES ${FFMPEG_LIBSWRESAMPLE_LIBRARIES})
+ set(AUDIO_PROCESSOR_INCLUDE_DIRS ${FFMPEG_LIBSWRESAMPLE_INCLUDE_DIRS})
+@@ -178,16 +172,6 @@ if(AUDIO_PROCESSOR_LIB STREQUAL "swresample")
+ message(FATAL_ERROR "Selected ${AUDIO_PROCESSOR_LIB} for audio processing, but the library is not found")
+ endif()
+ message(STATUS "Using ${AUDIO_PROCESSOR_LIB} for audio conversion")
+-elseif(AUDIO_PROCESSOR_LIB STREQUAL "avresample")
+- if(FFMPEG_LIBAVRESAMPLE_FOUND)
+- set(USE_AVRESAMPLE ON)
+- set(USE_SWRESAMPLE OFF)
+- set(AUDIO_PROCESSOR_LIBRARIES ${FFMPEG_LIBAVRESAMPLE_LIBRARIES})
+- set(AUDIO_PROCESSOR_INCLUDE_DIRS ${FFMPEG_LIBAVRESAMPLE_INCLUDE_DIRS})
+- else()
+- message(FATAL_ERROR "Selected ${AUDIO_PROCESSOR_LIB} for audio processing, but the library is not found")
+- endif()
+- message(STATUS "Using ${AUDIO_PROCESSOR_LIB} for audio conversion")
+ else()
+ message(STATUS "Building without audio conversion support, please install FFmpeg with libswresample")
+ endif()
+diff --git a/package/build.sh b/package/build.sh
+index da631ae..b41d36e 100755
+--- a/package/build.sh
++++ b/package/build.sh
+@@ -7,8 +7,8 @@ set -eux
+
+ BASE_DIR=$(cd $(dirname $0)/.. && pwd)
+
+-FFMPEG_VERSION=4.4.1
+-FFMPEG_BUILD_TAG=v4.4.1-1
++FFMPEG_VERSION=5.1.2
++FFMPEG_BUILD_TAG=v${FFMPEG_VERSION}-1
+
+ TMP_BUILD_DIR=$BASE_DIR/$(mktemp -d build.XXXXXXXX)
+ trap 'rm -rf $TMP_BUILD_DIR' EXIT
+diff --git a/src/audio/ffmpeg_audio_processor.h b/src/audio/ffmpeg_audio_processor.h
+index 7628fc7..39f4f6d 100644
+--- a/src/audio/ffmpeg_audio_processor.h
++++ b/src/audio/ffmpeg_audio_processor.h
+@@ -10,8 +10,6 @@
+
+ #if defined(USE_SWRESAMPLE)
+ #include "audio/ffmpeg_audio_processor_swresample.h"
+-#elif defined(USE_AVRESAMPLE)
+-#include "audio/ffmpeg_audio_processor_avresample.h"
+ #else
+ #error "no audio processing library"
+ #endif
+diff --git a/src/audio/ffmpeg_audio_processor_avresample.h b/src/audio/ffmpeg_audio_processor_avresample.h
+deleted file mode 100644
+index bd85f92..0000000
+--- a/src/audio/ffmpeg_audio_processor_avresample.h
++++ /dev/null
+@@ -1,72 +0,0 @@
+-// Copyright (C) 2016 Lukas Lalinsky
+-// Distributed under the MIT license, see the LICENSE file for details.
+-
+-#ifndef CHROMAPRINT_AUDIO_FFMPEG_AUDIO_PROCESSOR_AVRESAMPLE_H_
+-#define CHROMAPRINT_AUDIO_FFMPEG_AUDIO_PROCESSOR_AVRESAMPLE_H_
+-
+-extern "C" {
+-#include <libavresample/avresample.h>
+-}
+-
+-namespace chromaprint {
+-
+-class FFmpegAudioProcessor {
+-public:
+- FFmpegAudioProcessor() {
+- m_resample_ctx = avresample_alloc_context();
+- }
+-
+- ~FFmpegAudioProcessor() {
+- avresample_free(&m_resample_ctx);
+- }
+-
+- void SetCompatibleMode() {
+- av_opt_set_int(m_resample_ctx, "filter_size", 16, 0);
+- av_opt_set_int(m_resample_ctx, "phase_shift", 8, 0);
+- av_opt_set_int(m_resample_ctx, "linear_interp", 1, 0);
+- av_opt_set_double(m_resample_ctx, "cutoff", 0.8, 0);
+- }
+-
+- void SetInputChannelLayout(int64_t channel_layout) {
+- av_opt_set_int(m_resample_ctx, "in_channel_layout", channel_layout, 0);
+- }
+-
+- void SetInputSampleFormat(AVSampleFormat sample_format) {
+- av_opt_set_int(m_resample_ctx, "in_sample_fmt", sample_format, 0);
+- }
+-
+- void SetInputSampleRate(int sample_rate) {
+- av_opt_set_int(m_resample_ctx, "in_sample_rate", sample_rate, 0);
+- }
+-
+- void SetOutputChannelLayout(int64_t channel_layout) {
+- av_opt_set_int(m_resample_ctx, "out_channel_layout", channel_layout, 0);
+- }
+-
+- void SetOutputSampleFormat(AVSampleFormat sample_format) {
+- av_opt_set_int(m_resample_ctx, "out_sample_fmt", sample_format, 0);
+- }
+-
+- void SetOutputSampleRate(int sample_rate) {
+- av_opt_set_int(m_resample_ctx, "out_sample_fmt", sample_rate, 0);
+- }
+-
+- int Init() {
+- return avresample_open(m_resample_ctx);
+- }
+-
+- int Convert(uint8_t **out, int out_count, const uint8_t **in, int in_count) {
+- return avresample_convert(m_resample_ctx, out, 0, out_count, (uint8_t **) in, 0, in_count);
+- }
+-
+- int Flush(uint8_t **out, int out_count) {
+- return avresample_read(m_resample_ctx, out, out_count);
+- }
+-
+-private:
+- AVAudioResampleContext *m_resample_ctx = nullptr;
+-};
+-
+-}; // namespace chromaprint
+-
+-#endif
+diff --git a/src/audio/ffmpeg_audio_processor_swresample.h b/src/audio/ffmpeg_audio_processor_swresample.h
+index b86266b..b1d4bea 100644
+--- a/src/audio/ffmpeg_audio_processor_swresample.h
++++ b/src/audio/ffmpeg_audio_processor_swresample.h
+@@ -28,30 +28,28 @@ public:
+ av_opt_set_double(m_swr_ctx, "cutoff", 0.8, 0);
+ }
+
+- void SetInputChannelLayout(int64_t channel_layout) {
+- av_opt_set_int(m_swr_ctx, "icl", channel_layout, 0);
+- av_opt_set_int(m_swr_ctx, "ich", av_get_channel_layout_nb_channels(channel_layout), 0);
++ void SetInputChannelLayout(AVChannelLayout *channel_layout) {
++ av_opt_set_int(m_swr_ctx, "in_channel_layout", channel_layout->u.mask, 0);
+ }
+
+ void SetInputSampleFormat(AVSampleFormat sample_format) {
+- av_opt_set_int(m_swr_ctx, "isf", sample_format, 0);
++ av_opt_set_sample_fmt(m_swr_ctx, "in_sample_fmt", sample_format, 0);
+ }
+
+ void SetInputSampleRate(int sample_rate) {
+- av_opt_set_int(m_swr_ctx, "isr", sample_rate, 0);
++ av_opt_set_int(m_swr_ctx, "in_sample_rate", sample_rate, 0);
+ }
+
+- void SetOutputChannelLayout(int64_t channel_layout) {
+- av_opt_set_int(m_swr_ctx, "ocl", channel_layout, 0);
+- av_opt_set_int(m_swr_ctx, "och", av_get_channel_layout_nb_channels(channel_layout), 0);
++ void SetOutputChannelLayout(AVChannelLayout *channel_layout) {
++ av_opt_set_int(m_swr_ctx, "out_channel_layout", channel_layout->u.mask, 0);
+ }
+
+ void SetOutputSampleFormat(AVSampleFormat sample_format) {
+- av_opt_set_int(m_swr_ctx, "osf", sample_format, 0);
++ av_opt_set_sample_fmt(m_swr_ctx, "out_sample_fmt", sample_format, 0);
+ }
+
+ void SetOutputSampleRate(int sample_rate) {
+- av_opt_set_int(m_swr_ctx, "osr", sample_rate, 0);
++ av_opt_set_int(m_swr_ctx, "out_sample_rate", sample_rate, 0);
+ }
+
+ int Init() {
+diff --git a/src/audio/ffmpeg_audio_reader.h b/src/audio/ffmpeg_audio_reader.h
+index 5550164..1c6b346 100644
+--- a/src/audio/ffmpeg_audio_reader.h
++++ b/src/audio/ffmpeg_audio_reader.h
+@@ -62,7 +62,7 @@ public:
+ bool Read(const int16_t **data, size_t *size);
+
+ bool IsOpen() const { return m_opened; }
+- bool IsFinished() const { return m_finished && !m_got_frame; }
++ bool IsFinished() const { return !m_has_more_packets && !m_has_more_frames; }
+
+ std::string GetError() const { return m_error; }
+ int GetErrorCode() const { return m_error_code; }
+@@ -74,20 +74,19 @@ private:
+ uint8_t *m_convert_buffer[1] = { nullptr };
+ int m_convert_buffer_nb_samples = 0;
+
+- AVInputFormat *m_input_fmt = nullptr;
++ const AVInputFormat *m_input_fmt = nullptr;
+ AVDictionary *m_input_opts = nullptr;
+
+ AVFormatContext *m_format_ctx = nullptr;
+ AVCodecContext *m_codec_ctx = nullptr;
+- AVFrame *m_frame = nullptr;
+ int m_stream_index = -1;
+ std::string m_error;
+ int m_error_code = 0;
+- bool m_finished = false;
+ bool m_opened = false;
+- int m_got_frame = 0;
+- AVPacket m_packet;
+- AVPacket m_packet0;
++ bool m_has_more_packets = true;
++ bool m_has_more_frames = true;
++ AVPacket *m_packet = nullptr;
++ AVFrame *m_frame = nullptr;
+
+ int m_output_sample_rate = 0;
+ int m_output_channels = 0;
+@@ -98,19 +97,12 @@ private:
+
+ inline FFmpegAudioReader::FFmpegAudioReader() {
+ av_log_set_level(AV_LOG_QUIET);
+-
+- av_init_packet(&m_packet);
+- m_packet.data = nullptr;
+- m_packet.size = 0;
+-
+- m_packet0 = m_packet;
+ }
+
+ inline FFmpegAudioReader::~FFmpegAudioReader() {
+ Close();
+ av_dict_free(&m_input_opts);
+ av_freep(&m_convert_buffer[0]);
+- av_packet_unref(&m_packet0);
+ }
+
+ inline bool FFmpegAudioReader::SetInputFormat(const char *name) {
+@@ -135,11 +127,10 @@ inline bool FFmpegAudioReader::Open(const std::string &file_name) {
+
+ Close();
+
+- av_init_packet(&m_packet);
+- m_packet.data = nullptr;
+- m_packet.size = 0;
+-
+- m_packet0 = m_packet;
++ m_packet = av_packet_alloc();
++ if (!m_packet) {
++ return false;
++ }
+
+ ret = avformat_open_input(&m_format_ctx, file_name.c_str(), m_input_fmt, &m_input_opts);
+ if (ret < 0) {
+@@ -153,26 +144,31 @@ inline bool FFmpegAudioReader::Open(const std::string &file_name) {
+ return false;
+ }
+
+- AVCodec *codec;
++ const AVCodec *codec;
+ ret = av_find_best_stream(m_format_ctx, AVMEDIA_TYPE_AUDIO, -1, -1, &codec, 0);
+ if (ret < 0) {
+ SetError("Could not find any audio stream in the file", ret);
+ return false;
+ }
+ m_stream_index = ret;
++ auto stream = m_format_ctx->streams[m_stream_index];
+
+- m_codec_ctx = m_format_ctx->streams[m_stream_index]->codec;
++ m_codec_ctx = avcodec_alloc_context3(codec);
+ m_codec_ctx->request_sample_fmt = AV_SAMPLE_FMT_S16;
+
++ ret = avcodec_parameters_to_context(m_codec_ctx, stream->codecpar);
++ if (ret < 0) {
++ SetError("Could not copy the stream parameters", ret);
++ return false;
++ }
++
+ ret = avcodec_open2(m_codec_ctx, codec, nullptr);
+ if (ret < 0) {
+ SetError("Could not open the codec", ret);
+ return false;
+ }
+
+- if (!m_codec_ctx->channel_layout) {
+- m_codec_ctx->channel_layout = av_get_default_channel_layout(m_codec_ctx->channels);
+- }
++ av_dump_format(m_format_ctx, 0, "foo", 0);
+
+ m_frame = av_frame_alloc();
+ if (!m_frame) {
+@@ -183,19 +179,23 @@ inline bool FFmpegAudioReader::Open(const std::string &file_name) {
+ m_output_sample_rate = m_codec_ctx->sample_rate;
+ }
+
+- if (!m_output_channels) {
+- m_output_channels = m_codec_ctx->channels;
++ AVChannelLayout output_channel_layout;
++ if (m_output_channels) {
++ av_channel_layout_default(&output_channel_layout, m_output_channels);
++ } else {
++ m_output_channels = m_codec_ctx->ch_layout.nb_channels;
++ av_channel_layout_default(&output_channel_layout, m_output_channels);
+ }
+
+- if (m_codec_ctx->sample_fmt != AV_SAMPLE_FMT_S16 || m_codec_ctx->channels != m_output_channels || m_codec_ctx->sample_rate != m_output_sample_rate) {
++ if (m_codec_ctx->sample_fmt != AV_SAMPLE_FMT_S16 || m_codec_ctx->ch_layout.nb_channels != m_output_channels || m_codec_ctx->sample_rate != m_output_sample_rate) {
+ m_converter.reset(new FFmpegAudioProcessor());
+ m_converter->SetCompatibleMode();
+ m_converter->SetInputSampleFormat(m_codec_ctx->sample_fmt);
+ m_converter->SetInputSampleRate(m_codec_ctx->sample_rate);
+- m_converter->SetInputChannelLayout(m_codec_ctx->channel_layout);
++ m_converter->SetInputChannelLayout(&(m_codec_ctx->ch_layout));
+ m_converter->SetOutputSampleFormat(AV_SAMPLE_FMT_S16);
+ m_converter->SetOutputSampleRate(m_output_sample_rate);
+- m_converter->SetOutputChannelLayout(av_get_default_channel_layout(m_output_channels));
++ m_converter->SetOutputChannelLayout(&output_channel_layout);
+ auto ret = m_converter->Init();
+ if (ret != 0) {
+ SetError("Could not create an audio converter instance", ret);
+@@ -203,10 +203,11 @@ inline bool FFmpegAudioReader::Open(const std::string &file_name) {
+ }
+ }
+
++ av_channel_layout_uninit(&output_channel_layout);
++
+ m_opened = true;
+- m_finished = false;
+- m_got_frame = 0;
+- m_nb_packets = 0;
++ m_has_more_packets = true;
++ m_has_more_frames = true;
+ m_decode_error = 0;
+
+ return true;
+@@ -214,6 +215,7 @@ inline bool FFmpegAudioReader::Open(const std::string &file_name) {
+
+ inline void FFmpegAudioReader::Close() {
+ av_frame_free(&m_frame);
++ av_packet_free(&m_packet);
+
+ m_stream_index = -1;
+
+@@ -252,91 +254,98 @@ inline bool FFmpegAudioReader::Read(const int16_t **data, size_t *size) {
+ return false;
+ }
+
++ *data = nullptr;
++ *size = 0;
++
+ int ret;
++ bool needs_packet = false;
+ while (true) {
+- while (m_packet.size <= 0) {
+- av_packet_unref(&m_packet0);
+- av_init_packet(&m_packet);
+- m_packet.data = nullptr;
+- m_packet.size = 0;
+- ret = av_read_frame(m_format_ctx, &m_packet);
++ while (needs_packet && m_packet->size == 0) {
++ ret = av_read_frame(m_format_ctx, m_packet);
+ if (ret < 0) {
+ if (ret == AVERROR_EOF) {
+- m_finished = true;
++ needs_packet = false;
++ m_has_more_packets = false;
+ break;
+- } else {
++ }
++ SetError("Error reading from the audio source", ret);
++ return false;
++ }
++ if (m_packet->stream_index == m_stream_index) {
++ needs_packet = false;
++ } else {
++ av_packet_unref(m_packet);
++ }
++ }
++
++ if (m_packet->size != 0) {
++ ret = avcodec_send_packet(m_codec_ctx, m_packet);
++ if (ret < 0) {
++ if (ret != AVERROR(EAGAIN)) {
+ SetError("Error reading from the audio source", ret);
+ return false;
+ }
+- }
+- m_packet0 = m_packet;
+- if (m_packet.stream_index != m_stream_index) {
+- m_packet.data = nullptr;
+- m_packet.size = 0;
+ } else {
+- m_nb_packets++;
++ av_packet_unref(m_packet);
+ }
+ }
+
+- ret = avcodec_decode_audio4(m_codec_ctx, m_frame, &m_got_frame, &m_packet);
++ ret = avcodec_receive_frame(m_codec_ctx, m_frame);
+ if (ret < 0) {
+- if (m_decode_error) {
+- SetError("Error decoding audio frame", m_decode_error);
+- return false;
++ if (ret == AVERROR_EOF) {
++ m_has_more_frames = false;
++ } else if (ret == AVERROR(EAGAIN)) {
++ if (m_has_more_packets) {
++ needs_packet = true;
++ continue;
++ } else {
++ m_has_more_frames = false;
++ }
+ }
+- m_decode_error = ret;
+- m_packet.data = nullptr;
+- m_packet.size = 0;
+- continue;
++ SetError("Error decoding the audio source", ret);
++ return false;
+ }
+
+- break;
+- }
+-
+- m_decode_error = 0;
+-
+- const int decoded = std::min(ret, m_packet.size);
+- m_packet.data += decoded;
+- m_packet.size -= decoded;
+-
+- if (m_got_frame) {
+- if (m_converter) {
+- if (m_frame->nb_samples > m_convert_buffer_nb_samples) {
+- int linsize;
+- av_freep(&m_convert_buffer[0]);
+- m_convert_buffer_nb_samples = std::max(1024 * 8, m_frame->nb_samples);
+- ret = av_samples_alloc(m_convert_buffer, &linsize, m_codec_ctx->channels, m_convert_buffer_nb_samples, AV_SAMPLE_FMT_S16, 1);
+- if (ret < 0) {
+- SetError("Couldn't allocate audio converter buffer", ret);
++ if (m_frame->nb_samples > 0) {
++ if (m_converter) {
++ if (m_frame->nb_samples > m_convert_buffer_nb_samples) {
++ int linsize;
++ av_freep(&m_convert_buffer[0]);
++ m_convert_buffer_nb_samples = std::max(1024 * 8, m_frame->nb_samples);
++ ret = av_samples_alloc(m_convert_buffer, &linsize, m_codec_ctx->ch_layout.nb_channels, m_convert_buffer_nb_samples, AV_SAMPLE_FMT_S16, 1);
++ if (ret < 0) {
++ SetError("Couldn't allocate audio converter buffer", ret);
++ return false;
++ }
++ }
++ auto nb_samples = m_converter->Convert(m_convert_buffer, m_convert_buffer_nb_samples, (const uint8_t **) m_frame->data, m_frame->nb_samples);
++ if (nb_samples < 0) {
++ SetError("Couldn't convert audio", ret);
+ return false;
+ }
+- }
+- auto nb_samples = m_converter->Convert(m_convert_buffer, m_convert_buffer_nb_samples, (const uint8_t **) m_frame->data, m_frame->nb_samples);
+- if (nb_samples < 0) {
+- SetError("Couldn't convert audio", ret);
+- return false;
+- }
+- *data = (const int16_t *) m_convert_buffer[0];
+- *size = nb_samples;
+- } else {
+- *data = (const int16_t *) m_frame->data[0];
+- *size = m_frame->nb_samples;
+- }
+- } else {
+- if (m_finished && m_converter) {
+- auto nb_samples = m_converter->Flush(m_convert_buffer, m_convert_buffer_nb_samples);
+- if (nb_samples < 0) {
+- SetError("Couldn't convert audio", ret);
+- return false;
+- } else if (nb_samples > 0) {
+- m_got_frame = 1;
+ *data = (const int16_t *) m_convert_buffer[0];
+ *size = nb_samples;
++ } else {
++ *data = (const int16_t *) m_frame->data[0];
++ *size = m_frame->nb_samples;
++ }
++ } else {
++ if (m_converter) {
++ if (IsFinished()) {
++ auto nb_samples = m_converter->Flush(m_convert_buffer, m_convert_buffer_nb_samples);
++ if (nb_samples < 0) {
++ SetError("Couldn't convert audio", ret);
++ return false;
++ } else if (nb_samples > 0) {
++ *data = (const int16_t *) m_convert_buffer[0];
++ *size = nb_samples;
++ }
++ }
+ }
+ }
+- }
+
+- return true;
++ return true;
++ }
+ }
+
+ inline void FFmpegAudioReader::SetError(const char *message, int errnum) {
+diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt
+index a2b517b..123e643 100644
+--- a/tests/CMakeLists.txt
++++ b/tests/CMakeLists.txt
+@@ -38,6 +38,12 @@ set(SRCS
+
+ if(BUILD_TOOLS)
+ set(SRCS ${SRCS} ../src/audio/ffmpeg_audio_reader_test.cpp)
++ include_directories(
++ ${FFMPEG_LIBAVFORMAT_INCLUDE_DIRS}
++ ${FFMPEG_LIBAVCODEC_INCLUDE_DIRS}
++ ${FFMPEG_LIBAVUTIL_INCLUDE_DIRS}
++ ${AUDIO_PROCESSOR_INCLUDE_DIRS}
++ )
+ link_libraries(fpcalc_libs)
+ endif()
+
+--
+2.38.1
+
+
diff --git a/srcpkgs/chromaprint/template b/srcpkgs/chromaprint/template
index 7ef7838949f3..1f7bbc70a22c 100644
--- a/srcpkgs/chromaprint/template
+++ b/srcpkgs/chromaprint/template
@@ -1,7 +1,7 @@
# Template file for 'chromaprint'
pkgname=chromaprint
version=1.5.1
-revision=1
+revision=2
build_style=cmake
configure_args="-DBUILD_TOOLS=ON"
make_check_target="check"
From aed921f701932ce232bdcb1e5d9751098e56cc2e Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:46 -0400
Subject: [PATCH 026/115] chromium: revbump for ffmpeg-6.0
---
.../patches/chromium-93-ffmpeg-4.4.patch | 36 --------------
srcpkgs/chromium/patches/ffmpeg5.patch | 47 +++++++++++++++++++
srcpkgs/chromium/template | 2 +-
3 files changed, 48 insertions(+), 37 deletions(-)
delete mode 100644 srcpkgs/chromium/patches/chromium-93-ffmpeg-4.4.patch
create mode 100644 srcpkgs/chromium/patches/ffmpeg5.patch
diff --git a/srcpkgs/chromium/patches/chromium-93-ffmpeg-4.4.patch b/srcpkgs/chromium/patches/chromium-93-ffmpeg-4.4.patch
deleted file mode 100644
index f0ec736f98bc..000000000000
--- a/srcpkgs/chromium/patches/chromium-93-ffmpeg-4.4.patch
+++ /dev/null
@@ -1,36 +0,0 @@
-diff --git a/media/filters/ffmpeg_demuxer.cc b/media/filters/ffmpeg_demuxer.cc
-index ac4713b07268..492a9a37d096 100644
---- a/media/filters/ffmpeg_demuxer.cc
-+++ b/media/filters/ffmpeg_demuxer.cc
-@@ -427,11 +427,11 @@ void FFmpegDemuxerStream::EnqueuePacket(ScopedAVPacket packet) {
- scoped_refptr<DecoderBuffer> buffer;
-
- if (type() == DemuxerStream::TEXT) {
-- size_t id_size = 0;
-+ int id_size = 0;
- uint8_t* id_data = av_packet_get_side_data(
- packet.get(), AV_PKT_DATA_WEBVTT_IDENTIFIER, &id_size);
-
-- size_t settings_size = 0;
-+ int settings_size = 0;
- uint8_t* settings_data = av_packet_get_side_data(
- packet.get(), AV_PKT_DATA_WEBVTT_SETTINGS, &settings_size);
-
-@@ -443,7 +443,7 @@ void FFmpegDemuxerStream::EnqueuePacket(ScopedAVPacket packet) {
- buffer = DecoderBuffer::CopyFrom(packet->data, packet->size,
- side_data.data(), side_data.size());
- } else {
-- size_t side_data_size = 0;
-+ int side_data_size = 0;
- uint8_t* side_data = av_packet_get_side_data(
- packet.get(), AV_PKT_DATA_MATROSKA_BLOCKADDITIONAL, &side_data_size);
-
-@@ -504,7 +504,7 @@ void FFmpegDemuxerStream::EnqueuePacket(ScopedAVPacket packet) {
- packet->size - data_offset);
- }
-
-- size_t skip_samples_size = 0;
-+ int skip_samples_size = 0;
- const uint32_t* skip_samples_ptr =
- reinterpret_cast<const uint32_t*>(av_packet_get_side_data(
- packet.get(), AV_PKT_DATA_SKIP_SAMPLES, &skip_samples_size));
diff --git a/srcpkgs/chromium/patches/ffmpeg5.patch b/srcpkgs/chromium/patches/ffmpeg5.patch
new file mode 100644
index 000000000000..24e2da38e34c
--- /dev/null
+++ b/srcpkgs/chromium/patches/ffmpeg5.patch
@@ -0,0 +1,47 @@
+--- a/media/filters/ffmpeg_demuxer.cc 2023-01-23 17:33:57.366213805 +0200
++++ b/media/filters/ffmpeg_demuxer.cc 2023-01-23 17:43:09.283436983 +0200
+@@ -92,24 +92,12 @@
+
+ static base::TimeDelta ExtractStartTime(AVStream* stream) {
+ // The default start time is zero.
+- base::TimeDelta start_time;
++ base::TimeDelta start_time = kNoTimestamp;
+
+ // First try to use the |start_time| value as is.
+- if (stream->start_time != kNoFFmpegTimestamp)
++ if (stream->start_time != kNoFFmpegTimestamp) // AV_NOPTS_VALUE
+ start_time = ConvertFromTimeBase(stream->time_base, stream->start_time);
+
+- // Next try to use the first DTS value, for codecs where we know PTS == DTS
+- // (excludes all H26x codecs). The start time must be returned in PTS.
+- if (av_stream_get_first_dts(stream) != kNoFFmpegTimestamp &&
+- stream->codecpar->codec_id != AV_CODEC_ID_HEVC &&
+- stream->codecpar->codec_id != AV_CODEC_ID_H264 &&
+- stream->codecpar->codec_id != AV_CODEC_ID_MPEG4) {
+- const base::TimeDelta first_pts =
+- ConvertFromTimeBase(stream->time_base, av_stream_get_first_dts(stream));
+- if (first_pts < start_time)
+- start_time = first_pts;
+- }
+-
+ return start_time;
+ }
+
+@@ -1597,7 +1585,7 @@
+ for (const auto& stream : streams_) {
+ if (!stream || stream->IsEnabled() != enabled)
+ continue;
+- if (av_stream_get_first_dts(stream->av_stream()) == kInvalidPTSMarker)
++ if (stream->av_stream()->start_time == AV_NOPTS_VALUE)
+ continue;
+ if (!lowest_start_time_stream ||
+ stream->start_time() < lowest_start_time_stream->start_time()) {
+@@ -1618,7 +1606,7 @@
+ if (stream->type() != DemuxerStream::VIDEO)
+ continue;
+
+- if (av_stream_get_first_dts(stream->av_stream()) == kInvalidPTSMarker)
++ if (stream->av_stream()->start_time == AV_NOPTS_VALUE)
+ continue;
+
+ if (!stream->IsEnabled())
diff --git a/srcpkgs/chromium/template b/srcpkgs/chromium/template
index c3a1cd59eafe..5f4f6bd24d46 100644
--- a/srcpkgs/chromium/template
+++ b/srcpkgs/chromium/template
@@ -2,7 +2,7 @@
pkgname=chromium
# See https://chromiumdash.appspot.com/releases?platform=Linux for the latest version
version=113.0.5672.63
-revision=1
+revision=2
archs="i686* x86_64* aarch64* armv7l*"
hostmakedepends="
$(vopt_if clang "clang lld llvm15")
From 754ea7f90b2fe9f4c4de594e1228d43518b4e748 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:46 -0400
Subject: [PATCH 027/115] cmus: revbump for ffmpeg-6.0
---
srcpkgs/cmus/patches/ffmpeg6.patch | 12 ++++++++++++
srcpkgs/cmus/template | 2 +-
2 files changed, 13 insertions(+), 1 deletion(-)
create mode 100644 srcpkgs/cmus/patches/ffmpeg6.patch
diff --git a/srcpkgs/cmus/patches/ffmpeg6.patch b/srcpkgs/cmus/patches/ffmpeg6.patch
new file mode 100644
index 000000000000..ffa95ab81110
--- /dev/null
+++ b/srcpkgs/cmus/patches/ffmpeg6.patch
@@ -0,0 +1,12 @@
+--- a/ip/ffmpeg.c
++++ b/ip/ffmpeg.c
+@@ -202,9 +202,6 @@ static int ffmpeg_open(struct input_plugin_data *ip_data)
+ break;
+ }
+
+- if (codec->capabilities & AV_CODEC_CAP_TRUNCATED)
+- cc->flags |= AV_CODEC_FLAG_TRUNCATED;
+-
+ if (avcodec_open2(cc, codec, NULL) < 0) {
+ d_print("could not open codec: %d, %s\n", cc->codec_id, avcodec_get_name(cc->codec_id));
+ err = -IP_ERROR_UNSUPPORTED_FILE_TYPE;
diff --git a/srcpkgs/cmus/template b/srcpkgs/cmus/template
index 0fcb424ce336..05b77d0fecae 100644
--- a/srcpkgs/cmus/template
+++ b/srcpkgs/cmus/template
@@ -1,7 +1,7 @@
# Template file for 'cmus'
pkgname=cmus
version=2.10.0
-revision=1
+revision=2
build_style=configure
configure_args="prefix=/usr LD=$CC"
hostmakedepends="pkg-config"
From a25e3d74b7df189b9879bb153cdc8ca58d328d1b Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:46 -0400
Subject: [PATCH 028/115] cyanrip: revbump for ffmpeg-6.0
---
srcpkgs/cyanrip/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/cyanrip/template b/srcpkgs/cyanrip/template
index 9796e3461601..5db30e020d17 100644
--- a/srcpkgs/cyanrip/template
+++ b/srcpkgs/cyanrip/template
@@ -1,7 +1,7 @@
# Template file for 'cyanrip'
pkgname=cyanrip
version=0.9.0
-revision=1
+revision=2
build_style=meson
hostmakedepends="pkg-config"
makedepends="ffmpeg-devel libcdio-devel libcdio-paranoia-devel libcurl-devel libmusicbrainz5-devel"
From 0ab39cb0937e847d0df581b702e7b4319643b2b1 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:46 -0400
Subject: [PATCH 029/115] deadbeef: revbump for ffmpeg4-4.4.3
---
srcpkgs/deadbeef/template | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/srcpkgs/deadbeef/template b/srcpkgs/deadbeef/template
index b664bb1b9bd9..165b3c7b9cad 100644
--- a/srcpkgs/deadbeef/template
+++ b/srcpkgs/deadbeef/template
@@ -1,14 +1,14 @@
# Template file for 'deadbeef'
pkgname=deadbeef
version=1.8.8
-revision=1
+revision=2
create_wrksrc=yes
build_style=gnu-configure
configure_args="--disable-oss --disable-lfm --disable-notify --disable-gtk2"
hostmakedepends="automake libtool gettext gettext-devel intltool pkg-config
yasm clang glib-devel"
makedepends="
- alsa-lib-devel dbus-devel faad2-devel ffmpeg-devel gtk+3-devel imlib2-devel
+ alsa-lib-devel dbus-devel faad2-devel ffmpeg4-devel gtk+3-devel imlib2-devel
jansson-devel libcddb-devel libcdio-devel libcurl-devel libflac-devel
libmad-devel libpng-devel libsamplerate-devel libsndfile-devel libvorbis-devel
libzip-devel mpg123-devel opusfile-devel pulseaudio-devel wavpack-devel"
From 42beea4adfdb83f5eeadc8e69982b13cae32490a Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:46 -0400
Subject: [PATCH 030/115] dolphin-emu: revbump for ffmpeg-6.0
---
srcpkgs/dolphin-emu/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/dolphin-emu/template b/srcpkgs/dolphin-emu/template
index 7ea197ceb2a8..7aeb0a5b645e 100644
--- a/srcpkgs/dolphin-emu/template
+++ b/srcpkgs/dolphin-emu/template
@@ -1,7 +1,7 @@
# Template file for 'dolphin-emu'
pkgname=dolphin-emu
version=5.0.16101
-revision=1
+revision=2
_dolphin_commit=8ecfa537a242de74d2e372e30d9d79b14584b2fb
_mgba_commit=40d4c430fc36caeb7ea32fd39624947ed487d2f2
#Version/hash pair can be found at https://dolphin-emu.org/download/
From 37fcbe189246490434e522624500c79eaa06e41a Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:46 -0400
Subject: [PATCH 031/115] droidcam-obs-plugin: revbump for ffmpeg-6.0
---
srcpkgs/droidcam-obs-plugin/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/droidcam-obs-plugin/template b/srcpkgs/droidcam-obs-plugin/template
index fc9c9bf6b9d5..fb0480754df4 100644
--- a/srcpkgs/droidcam-obs-plugin/template
+++ b/srcpkgs/droidcam-obs-plugin/template
@@ -1,7 +1,7 @@
# Template file for 'droidcam-obs-plugin'
pkgname=droidcam-obs-plugin
version=2.0.1
-revision=1
+revision=2
build_style=gnu-makefile
make_use_env=yes
make_build_args="ALLOW_STATIC=no"
From 2102e4d728a5a80e01328d3946a68501d6bb047a Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:46 -0400
Subject: [PATCH 032/115] droidcam: revbump for ffmpeg-6.0
---
srcpkgs/droidcam/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/droidcam/template b/srcpkgs/droidcam/template
index 1c3f1b8b1fc6..32a9220b79a4 100644
--- a/srcpkgs/droidcam/template
+++ b/srcpkgs/droidcam/template
@@ -1,7 +1,7 @@
# Template file for 'droidcam'
pkgname=droidcam
version=1.8.2
-revision=2
+revision=3
build_style=gnu-makefile
make_build_args="USBMUXD=-lusbmuxd-2.0 JPEG=-lturbojpeg"
hostmakedepends="pkg-config"
From d3361215bff0ab2667fe972fa96d9e32a7972d6c Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:46 -0400
Subject: [PATCH 033/115] electron19: revbump for ffmpeg-6.0
---
srcpkgs/electron19/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/electron19/template b/srcpkgs/electron19/template
index 068136be7623..32ce301e730c 100644
--- a/srcpkgs/electron19/template
+++ b/srcpkgs/electron19/template
@@ -1,7 +1,7 @@
# Template file for 'electron19'
pkgname=electron19
version=19.0.8
-revision=2
+revision=3
_nodever=16.14.2
_chromiumver=102.0.5005.125
archs="x86_64* aarch64* ppc64le*"
From ebb2470bcabe4bec6edaa2292b38cb0ad999c85b Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:47 -0400
Subject: [PATCH 034/115] ffmpegthumbnailer: revbump for ffmpeg-6.0
---
.../ffmpegthumbnailer/patches/ffmpeg6.patch | 202 ++++++++++++++++++
srcpkgs/ffmpegthumbnailer/template | 6 +-
2 files changed, 205 insertions(+), 3 deletions(-)
create mode 100644 srcpkgs/ffmpegthumbnailer/patches/ffmpeg6.patch
diff --git a/srcpkgs/ffmpegthumbnailer/patches/ffmpeg6.patch b/srcpkgs/ffmpegthumbnailer/patches/ffmpeg6.patch
new file mode 100644
index 000000000000..363ff35a2841
--- /dev/null
+++ b/srcpkgs/ffmpegthumbnailer/patches/ffmpeg6.patch
@@ -0,0 +1,202 @@
+--- a/libffmpegthumbnailer/moviedecoder.cpp 2017-11-21 14:06:57.000000000 -0500
++++ b/libffmpegthumbnailer/moviedecoder.cpp 2023-05-05 13:14:47.946560668 -0400
+@@ -41,11 +41,6 @@
+ namespace ffmpegthumbnailer
+ {
+
+-struct SilenceLogLevel
+-{
+- SilenceLogLevel() { av_log_set_level(AV_LOG_QUIET); }
+-};
+-
+ MovieDecoder::MovieDecoder(AVFormatContext* pavContext)
+ : m_VideoStream(-1)
+ , m_pFormatContext(pavContext)
+@@ -70,8 +65,6 @@
+
+ void MovieDecoder::initialize(const string& filename, bool preferEmbeddedMetadata)
+ {
+- av_register_all();
+- avcodec_register_all();
+ avformat_network_init();
+
+ string inputFile = filename == "-" ? "pipe:" : filename;
+@@ -97,8 +90,7 @@
+ {
+ if (m_pVideoCodecContext)
+ {
+- avcodec_close(m_pVideoCodecContext);
+- m_pVideoCodecContext = nullptr;
++ avcodec_free_context(&m_pVideoCodecContext);
+ }
+
+ if ((!m_FormatContextWasGiven) && m_pFormatContext)
+@@ -152,10 +144,10 @@
+ for (unsigned int i = 0; i < m_pFormatContext->nb_streams; ++i)
+ {
+ AVStream *stream = m_pFormatContext->streams[i];
+- auto ctx = m_pFormatContext->streams[i]->codec;
+- if (ctx->codec_type == AVMEDIA_TYPE_VIDEO)
++ auto par = m_pFormatContext->streams[i]->codecpar;
++ if (par->codec_type == AVMEDIA_TYPE_VIDEO)
+ {
+- if (!preferEmbeddedMetadata || !isStillImageCodec(ctx->codec_id))
++ if (!preferEmbeddedMetadata || !isStillImageCodec(par->codec_id))
+ {
+ videoStreams.push_back(i);
+ continue;
+@@ -203,8 +195,7 @@
+ }
+
+ m_pVideoStream = m_pFormatContext->streams[m_VideoStream];
+- m_pVideoCodecContext = m_pVideoStream->codec;
+- m_pVideoCodec = avcodec_find_decoder(m_pVideoCodecContext->codec_id);
++ m_pVideoCodec = avcodec_find_decoder(m_pVideoStream->codecpar->codec_id);
+
+ if (m_pVideoCodec == nullptr)
+ {
+@@ -214,6 +205,20 @@
+ throw logic_error("Video Codec not found");
+ }
+
++ m_pVideoCodecContext = avcodec_alloc_context3(m_pVideoCodec);
++
++ if (m_pVideoCodecContext == nullptr)
++ {
++ destroy();
++ throw logic_error("Could not allocate video codec context");
++ }
++
++ if (avcodec_parameters_to_context(m_pVideoCodecContext, m_pVideoStream->codecpar) < 0)
++ {
++ destroy();
++ throw logic_error("Could not configure video codec context");
++ }
++
+ m_pVideoCodecContext->workaround_bugs = 1;
+
+ if (avcodec_open2(m_pVideoCodecContext, m_pVideoCodec, nullptr) < 0)
+@@ -386,13 +391,6 @@
+
+ void MovieDecoder::initializeFilterGraph(const AVRational& timeBase, const std::string& size, bool maintainAspectRatio)
+ {
+- static const AVPixelFormat pixelFormats[] = { AV_PIX_FMT_RGB24, AV_PIX_FMT_NONE };
+-
+- auto del = [] (AVBufferSinkParams* p) { av_freep(p); };
+- std::unique_ptr<AVBufferSinkParams, decltype(del)> buffersinkParams(av_buffersink_params_alloc(), del);
+-
+- avfilter_register_all();
+-
+ m_pFilterGraph = avfilter_graph_alloc();
+ assert(m_pFilterGraph);
+
+@@ -404,10 +402,8 @@
+
+ checkRc(avfilter_graph_create_filter(&m_pFilterSource, avfilter_get_by_name("buffer"), "thumb_buffer", ss.str().c_str(), nullptr, m_pFilterGraph),
+ "Failed to create filter source");
+- buffersinkParams->pixel_fmts = pixelFormats;
+- checkRc(avfilter_graph_create_filter(&m_pFilterSink, avfilter_get_by_name("buffersink"), "thumb_buffersink", nullptr, buffersinkParams.get(), m_pFilterGraph),
++ checkRc(avfilter_graph_create_filter(&m_pFilterSink, avfilter_get_by_name("buffersink"), "thumb_buffersink", nullptr, nullptr, m_pFilterGraph),
+ "Failed to create filter sink");
+- buffersinkParams.release();
+
+ AVFilterContext* yadifFilter = nullptr;
+ if (m_pFrame->interlaced_frame != 0)
+@@ -500,15 +496,15 @@
+ }
+
+ checkRc(av_seek_frame(m_pFormatContext, -1, timestamp, 0), "Seeking in video failed");
+- avcodec_flush_buffers(m_pFormatContext->streams[m_VideoStream]->codec);
++ avcodec_flush_buffers(m_pVideoCodecContext);
+
+ int keyFrameAttempts = 0;
+- bool gotFrame = 0;
++ bool gotFrame;
+
+ do
+ {
+ int count = 0;
+- gotFrame = 0;
++ gotFrame = false;
+
+ while (!gotFrame && count < 20)
+ {
+@@ -552,17 +548,33 @@
+ return false;
+ }
+
+- av_frame_unref(m_pFrame);
+-
+- int frameFinished;
++ int rc = avcodec_send_packet(m_pVideoCodecContext, m_pPacket);
++ if(rc == AVERROR(EAGAIN))
++ {
++ rc = 0;
++ }
+
+- int bytesDecoded = avcodec_decode_video2(m_pVideoCodecContext, m_pFrame, &frameFinished, m_pPacket);
+- if (bytesDecoded < 0)
++ if(rc == AVERROR_EOF)
++ {
++ return false;
++ }
++ else if(rc < 0)
+ {
+- throw logic_error("Failed to decode video frame: bytesDecoded < 0");
++ throw logic_error("Failed to decode video frame: avcodec_send_packet() < 0");
+ }
+
+- return frameFinished > 0;
++ rc = avcodec_receive_frame(m_pVideoCodecContext, m_pFrame);
++ switch(rc)
++ {
++ case 0:
++ return true;
++
++ case AVERROR(EAGAIN):
++ return false;
++
++ default:
++ throw logic_error("Failed to decode video frame: avcodec_receive_frame() < 0");
++ }
+ }
+
+ bool MovieDecoder::getVideoPacket()
+@@ -570,8 +582,6 @@
+ bool framesAvailable = true;
+ bool frameDecoded = false;
+
+- int attempts = 0;
+-
+ if (m_pPacket)
+ {
+ av_packet_unref(m_pPacket);
+@@ -580,6 +590,7 @@
+
+ m_pPacket = new AVPacket();
+
++
+ while (framesAvailable && !frameDecoded)
+ {
+ framesAvailable = av_read_frame(m_pFormatContext, m_pPacket) >= 0;
+@@ -644,7 +655,7 @@
+
+ int32_t MovieDecoder::getStreamRotation()
+ {
+- int32_t* matrix = reinterpret_cast<int32_t*>(av_stream_get_side_data(m_pVideoStream, AV_PKT_DATA_DISPLAYMATRIX, nullptr));
++ auto matrix = reinterpret_cast<int32_t*>(av_stream_get_side_data(m_pVideoStream, AV_PKT_DATA_DISPLAYMATRIX, nullptr));
+ if (matrix)
+ {
+ auto angle = lround(av_display_rotation_get(matrix));
+
+--- a/libffmpegthumbnailer/moviedecoder.h 2017-11-12 04:23:38.000000000 -0500
++++ b/libffmpegthumbnailer/moviedecoder.h 2023-05-05 13:26:07.095529911 -0400
+@@ -78,7 +78,7 @@
+ int m_VideoStream;
+ AVFormatContext* m_pFormatContext;
+ AVCodecContext* m_pVideoCodecContext;
+- AVCodec* m_pVideoCodec;
++ const AVCodec* m_pVideoCodec;
+ AVFilterGraph* m_pFilterGraph;
+ AVFilterContext* m_pFilterSource;
+ AVFilterContext* m_pFilterSink;
diff --git a/srcpkgs/ffmpegthumbnailer/template b/srcpkgs/ffmpegthumbnailer/template
index 039eea7622b3..35d546018d12 100644
--- a/srcpkgs/ffmpegthumbnailer/template
+++ b/srcpkgs/ffmpegthumbnailer/template
@@ -1,7 +1,7 @@
# Template file for 'ffmpegthumbnailer'
pkgname=ffmpegthumbnailer
version=2.2.2
-revision=1
+revision=2
build_style=cmake
hostmakedepends="pkg-config"
makedepends="libpng-devel libjpeg-turbo-devel ffmpeg-devel"
@@ -9,8 +9,8 @@ depends="ffmpeg"
short_desc="Lightweight video thumbnailer"
maintainer="Orphaned <orphan@voidlinux.org>"
license="GPL-2.0-or-later"
-homepage="https://github.com/dirkvdb/${pkgname}"
-distfiles="${homepage}/releases/download/${version}/${pkgname}-${version}.tar.bz2"
+homepage="https://github.com/dirkvdb"
+distfiles="${homepage}/${pkgname}/releases/download/${version}/${pkgname}-${version}.tar.bz2"
checksum=1cb24059c38223f657b300c84dd80491b7040d4b69471c4fea69be862bc99b5b
post_install() {
From e63c25096d3deb32562b2a0baffb618240f49519 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:47 -0400
Subject: [PATCH 035/115] ffmpegthumbs: revbump for ffmpeg-6.0
---
srcpkgs/ffmpegthumbs/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/ffmpegthumbs/template b/srcpkgs/ffmpegthumbs/template
index 5f0b9414dada..11b88193528f 100644
--- a/srcpkgs/ffmpegthumbs/template
+++ b/srcpkgs/ffmpegthumbs/template
@@ -1,7 +1,7 @@
# Template file for 'ffmpegthumbs'
pkgname=ffmpegthumbs
version=22.12.1
-revision=1
+revision=2
build_style=cmake
hostmakedepends="extra-cmake-modules kcoreaddons kconfig-devel
pkg-config qt5-host-tools qt5-qmake gettext"
From 4e9adba7994bd9d3140e577377f7a8c28ac403ad Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:47 -0400
Subject: [PATCH 036/115] ffms2: revbump for ffmpeg-6.0
---
srcpkgs/ffms2/patches/ffmpeg5.patch | 424 ++++++++++++++++++++++++++++
srcpkgs/ffms2/template | 2 +-
2 files changed, 425 insertions(+), 1 deletion(-)
create mode 100644 srcpkgs/ffms2/patches/ffmpeg5.patch
diff --git a/srcpkgs/ffms2/patches/ffmpeg5.patch b/srcpkgs/ffms2/patches/ffmpeg5.patch
new file mode 100644
index 000000000000..1479fabcafcb
--- /dev/null
+++ b/srcpkgs/ffms2/patches/ffmpeg5.patch
@@ -0,0 +1,424 @@
+From 45673149e9a2f5586855ad472e3059084eaa36b1 Mon Sep 17 00:00:00 2001
+From: Derek Buitenhuis <derek.buitenhuis@gmail.com>
+Date: Tue, 4 May 2021 14:41:21 +0100
+Subject: [PATCH] Use auto for AVCodec
+
+The geniuses over at FFmpeg decided to constify this API, so old
+versions of the library will return AVCodec *, while new versions
+of the libary will return const AVCodec *, which, in C++, are not
+OK to convert between.
+
+Rather than use some macro hell in ffmscompat.h, we can work around
+this by using auto.
+
+Gross.
+
+Signed-off-by: Derek Buitenhuis <derek.buitenhuis@gmail.com>
+---
+ src/core/audiosource.cpp | 2 +-
+ src/core/indexing.cpp | 6 +++---
+ src/core/videosource.cpp | 2 +-
+ 3 files changed, 5 insertions(+), 5 deletions(-)
+
+diff --git a/src/core/audiosource.cpp b/src/core/audiosource.cpp
+index e4ce97c..ac09666 100644
+--- a/src/core/audiosource.cpp
++++ b/src/core/audiosource.cpp
+@@ -469,7 +469,7 @@ void FFMS_AudioSource::OpenFile() {
+
+ LAVFOpenFile(SourceFile.c_str(), FormatContext, TrackNumber);
+
+- AVCodec *Codec = avcodec_find_decoder(FormatContext->streams[TrackNumber]->codecpar->codec_id);
++ auto *Codec = avcodec_find_decoder(FormatContext->streams[TrackNumber]->codecpar->codec_id);
+ if (Codec == nullptr)
+ throw FFMS_Exception(FFMS_ERROR_DECODING, FFMS_ERROR_CODEC,
+ "Audio codec not found");
+diff --git a/src/core/indexing.cpp b/src/core/indexing.cpp
+index e547c5a..59fb4e8 100644
+--- a/src/core/indexing.cpp
++++ b/src/core/indexing.cpp
+@@ -384,7 +384,7 @@ FFMS_TrackType FFMS_Indexer::GetTrackType(int Track) {
+ }
+
+ const char *FFMS_Indexer::GetTrackCodec(int Track) {
+- AVCodec *codec = avcodec_find_decoder(FormatContext->streams[Track]->codecpar->codec_id);
++ auto *codec = avcodec_find_decoder(FormatContext->streams[Track]->codecpar->codec_id);
+ return codec ? codec->name : nullptr;
+ }
+
+@@ -402,7 +402,7 @@ FFMS_Index *FFMS_Indexer::DoIndexing() {
+ UseDTS);
+
+ if (IndexMask.count(i) && FormatContext->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
+- AVCodec *VideoCodec = avcodec_find_decoder(FormatContext->streams[i]->codecpar->codec_id);
++ auto *VideoCodec = avcodec_find_decoder(FormatContext->streams[i]->codecpar->codec_id);
+ if (!VideoCodec) {
+ FormatContext->streams[i]->discard = AVDISCARD_ALL;
+ IndexMask.erase(i);
+@@ -433,7 +433,7 @@ FFMS_Index *FFMS_Indexer::DoIndexing() {
+ IndexMask.insert(i);
+ }
+ } else if (IndexMask.count(i) && FormatContext->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) {
+- AVCodec *AudioCodec = avcodec_find_decoder(FormatContext->streams[i]->codecpar->codec_id);
++ auto *AudioCodec = avcodec_find_decoder(FormatContext->streams[i]->codecpar->codec_id);
+ if (AudioCodec == nullptr)
+ throw FFMS_Exception(FFMS_ERROR_CODEC, FFMS_ERROR_UNSUPPORTED,
+ "Audio codec not found");
+diff --git a/src/core/videosource.cpp b/src/core/videosource.cpp
+index b889970..8956c22 100644
+--- a/src/core/videosource.cpp
++++ b/src/core/videosource.cpp
+@@ -171,7 +171,7 @@ FFMS_VideoSource::FFMS_VideoSource(const char *SourceFile, FFMS_Index &Index, in
+
+ LAVFOpenFile(SourceFile, FormatContext, VideoTrack);
+
+- AVCodec *Codec = avcodec_find_decoder(FormatContext->streams[VideoTrack]->codecpar->codec_id);
++ auto *Codec = avcodec_find_decoder(FormatContext->streams[VideoTrack]->codecpar->codec_id);
+ if (Codec == nullptr)
+ throw FFMS_Exception(FFMS_ERROR_DECODING, FFMS_ERROR_CODEC,
+ "Video codec not found");
+--
+2.40.0
+
+From 96cbf38ea9381829a1314f432a2c60495dcefaad Mon Sep 17 00:00:00 2001
+From: Derek Buitenhuis <derek.buitenhuis@gmail.com>
+Date: Tue, 4 May 2021 14:12:41 +0100
+Subject: [PATCH] all: Update AVPacket API usage
+
+AVPackets must all be on the heap now, since it is no longer
+part of the libav* ABI.
+
+Signed-off-by: Derek Buitenhuis <derek.buitenhuis@gmail.com>
+---
+ src/core/audiosource.cpp | 16 ++++++----
+ src/core/indexing.cpp | 63 ++++++++++++++++++++++------------------
+ src/core/indexing.h | 4 +--
+ src/core/utils.cpp | 6 ----
+ src/core/utils.h | 1 -
+ src/core/videosource.cpp | 30 ++++++++++---------
+ 6 files changed, 64 insertions(+), 56 deletions(-)
+
+diff --git a/src/core/audiosource.cpp b/src/core/audiosource.cpp
+index 37cf9ae..e4ce97c 100644
+--- a/src/core/audiosource.cpp
++++ b/src/core/audiosource.cpp
+@@ -285,10 +285,15 @@ FFMS_AudioSource::AudioBlock *FFMS_AudioSource::CacheBlock(CacheIterator &pos) {
+ int FFMS_AudioSource::DecodeNextBlock(CacheIterator *pos) {
+ CurrentFrame = &Frames[PacketNumber];
+
+- AVPacket Packet;
+- if (!ReadPacket(&Packet))
++ AVPacket *Packet = av_packet_alloc();
++ if (!Packet)
++ throw FFMS_Exception(FFMS_ERROR_PARSER, FFMS_ERROR_ALLOCATION_FAILED,
++ "Could not allocate packet.");
++ if (!ReadPacket(Packet)) {
++ av_packet_free(&Packet);
+ throw FFMS_Exception(FFMS_ERROR_PARSER, FFMS_ERROR_UNKNOWN,
+ "ReadPacket unexpectedly failed to read a packet");
++ }
+
+ // ReadPacket may have changed the packet number
+ CurrentFrame = &Frames[PacketNumber];
+@@ -297,8 +302,9 @@ int FFMS_AudioSource::DecodeNextBlock(CacheIterator *pos) {
+ int NumberOfSamples = 0;
+ AudioBlock *CachedBlock = nullptr;
+
+- int Ret = avcodec_send_packet(CodecContext, &Packet);
+- av_packet_unref(&Packet);
++ int Ret = avcodec_send_packet(CodecContext, Packet);
++ av_packet_unref(Packet);
++ av_packet_free(&Packet);
+
+ av_frame_unref(DecodeFrame);
+ Ret = avcodec_receive_frame(CodecContext, DecodeFrame);
+@@ -513,8 +519,6 @@ void FFMS_AudioSource::Seek() {
+ }
+
+ bool FFMS_AudioSource::ReadPacket(AVPacket *Packet) {
+- InitNullPacket(*Packet);
+-
+ while (av_read_frame(FormatContext, Packet) >= 0) {
+ if (Packet->stream_index == TrackNumber) {
+ // Required because not all audio packets, especially in ogg, have a pts. Use the previous valid packet's pts instead.
+diff --git a/src/core/indexing.cpp b/src/core/indexing.cpp
+index 23fb95b..e547c5a 100644
+--- a/src/core/indexing.cpp
++++ b/src/core/indexing.cpp
+@@ -320,7 +320,7 @@ void FFMS_Indexer::CheckAudioProperties(int Track, AVCodecContext *Context) {
+ }
+ }
+
+-void FFMS_Indexer::ParseVideoPacket(SharedAVContext &VideoContext, AVPacket &pkt, int *RepeatPict,
++void FFMS_Indexer::ParseVideoPacket(SharedAVContext &VideoContext, AVPacket *pkt, int *RepeatPict,
+ int *FrameType, bool *Invisible, enum AVPictureStructure *LastPicStruct) {
+ if (VideoContext.Parser) {
+ uint8_t *OB;
+@@ -330,8 +330,8 @@ void FFMS_Indexer::ParseVideoPacket(SharedAVContext &VideoContext, AVPacket &pkt
+ av_parser_parse2(VideoContext.Parser,
+ VideoContext.CodecContext,
+ &OB, &OBSize,
+- pkt.data, pkt.size,
+- pkt.pts, pkt.dts, pkt.pos);
++ pkt->data, pkt->size,
++ pkt->pts, pkt->dts, pkt->pos);
+
+ // H.264 (PAFF) and HEVC may have one field per packet, so we need to track
+ // when we have a full or half frame available, and mark one of them as
+@@ -351,15 +351,15 @@ void FFMS_Indexer::ParseVideoPacket(SharedAVContext &VideoContext, AVPacket &pkt
+
+ *RepeatPict = VideoContext.Parser->repeat_pict;
+ *FrameType = VideoContext.Parser->pict_type;
+- *Invisible = (IncompleteFrame || VideoContext.Parser->repeat_pict < 0 || (pkt.flags & AV_PKT_FLAG_DISCARD));
++ *Invisible = (IncompleteFrame || VideoContext.Parser->repeat_pict < 0 || (pkt->flags & AV_PKT_FLAG_DISCARD));
+ } else {
+- *Invisible = !!(pkt.flags & AV_PKT_FLAG_DISCARD);
++ *Invisible = !!(pkt->flags & AV_PKT_FLAG_DISCARD);
+ }
+
+ if (VideoContext.CodecContext->codec_id == AV_CODEC_ID_VP8)
+- ParseVP8(pkt.data[0], Invisible, FrameType);
++ ParseVP8(pkt->data[0], Invisible, FrameType);
+ else if (VideoContext.CodecContext->codec_id == AV_CODEC_ID_VP9)
+- ParseVP9(pkt.data[0], Invisible, FrameType);
++ ParseVP9(pkt->data[0], Invisible, FrameType);
+ }
+
+ void FFMS_Indexer::Free() {
+@@ -458,32 +458,36 @@ FFMS_Index *FFMS_Indexer::DoIndexing() {
+ }
+ }
+
+- AVPacket Packet;
+- InitNullPacket(Packet);
++ AVPacket *Packet = av_packet_alloc();
++ if (!Packet)
++ throw FFMS_Exception(FFMS_ERROR_CODEC, FFMS_ERROR_ALLOCATION_FAILED,
++ "Could not allocate packet.");
+ std::vector<int64_t> LastValidTS(FormatContext->nb_streams, AV_NOPTS_VALUE);
+
+ int64_t filesize = avio_size(FormatContext->pb);
+ enum AVPictureStructure LastPicStruct = AV_PICTURE_STRUCTURE_UNKNOWN;
+- while (av_read_frame(FormatContext, &Packet) >= 0) {
++ while (av_read_frame(FormatContext, Packet) >= 0) {
+ // Update progress
+ // FormatContext->pb can apparently be NULL when opening images.
+ if (IC && FormatContext->pb) {
+- if ((*IC)(FormatContext->pb->pos, filesize, ICPrivate))
++ if ((*IC)(FormatContext->pb->pos, filesize, ICPrivate)) {
++ av_packet_free(&Packet);
+ throw FFMS_Exception(FFMS_ERROR_CANCELLED, FFMS_ERROR_USER,
+ "Cancelled by user");
++ }
+ }
+- if (!IndexMask.count(Packet.stream_index)) {
+- av_packet_unref(&Packet);
++ if (!IndexMask.count(Packet->stream_index)) {
++ av_packet_unref(Packet);
+ continue;
+ }
+
+- int Track = Packet.stream_index;
++ int Track = Packet->stream_index;
+ FFMS_Track &TrackInfo = (*TrackIndices)[Track];
+- bool KeyFrame = !!(Packet.flags & AV_PKT_FLAG_KEY);
++ bool KeyFrame = !!(Packet->flags & AV_PKT_FLAG_KEY);
+ ReadTS(Packet, LastValidTS[Track], (*TrackIndices)[Track].UseDTS);
+
+ if (FormatContext->streams[Track]->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
+- int64_t PTS = TrackInfo.UseDTS ? Packet.dts : Packet.pts;
++ int64_t PTS = TrackInfo.UseDTS ? Packet->dts : Packet->pts;
+ if (PTS == AV_NOPTS_VALUE) {
+ // VPx alt-refs are output as packets which lack timestmps or durations, since
+ // they are invisible. Currently, the timestamp mangling code in libavformat
+@@ -495,9 +499,11 @@ FFMS_Index *FFMS_Indexer::DoIndexing() {
+ // FFMS2 currently sorts packets by PTS, which will break decoding, otherwise.
+ bool HasAltRefs = (FormatContext->streams[Track]->codecpar->codec_id == AV_CODEC_ID_VP8 ||
+ FormatContext->streams[Track]->codecpar->codec_id == AV_CODEC_ID_VP9);
+- if (Packet.duration == 0 && !HasAltRefs)
++ if (Packet->duration == 0 && !HasAltRefs) {
++ av_packet_free(&Packet);
+ throw FFMS_Exception(FFMS_ERROR_INDEXING, FFMS_ERROR_PARSER,
+ "Invalid packet pts, dts, and duration");
++ }
+
+ if (TrackInfo.empty())
+ PTS = 0;
+@@ -513,7 +519,7 @@ FFMS_Index *FFMS_Indexer::DoIndexing() {
+ ParseVideoPacket(AVContexts[Track], Packet, &RepeatPict, &FrameType, &Invisible, &LastPicStruct);
+
+ TrackInfo.AddVideoFrame(PTS, RepeatPict, KeyFrame,
+- FrameType, Packet.pos, Invisible);
++ FrameType, Packet->pos, Invisible);
+ } else if (FormatContext->streams[Track]->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) {
+ // For video seeking timestamps are used only if all packets have
+ // timestamps, while for audio they're used if any have timestamps,
+@@ -522,28 +528,29 @@ FFMS_Index *FFMS_Indexer::DoIndexing() {
+ TrackInfo.HasTS = true;
+
+ int64_t StartSample = AVContexts[Track].CurrentSample;
+- uint32_t SampleCount = IndexAudioPacket(Track, &Packet, AVContexts[Track], *TrackIndices);
++ uint32_t SampleCount = IndexAudioPacket(Track, Packet, AVContexts[Track], *TrackIndices);
+ TrackInfo.SampleRate = AVContexts[Track].CodecContext->sample_rate;
+
+ TrackInfo.AddAudioFrame(LastValidTS[Track],
+- StartSample, SampleCount, KeyFrame, Packet.pos, Packet.flags & AV_PKT_FLAG_DISCARD);
++ StartSample, SampleCount, KeyFrame, Packet->pos, Packet->flags & AV_PKT_FLAG_DISCARD);
+ }
+
+- if (!(Packet.flags & AV_PKT_FLAG_DISCARD))
+- TrackInfo.LastDuration = Packet.duration;
++ if (!(Packet->flags & AV_PKT_FLAG_DISCARD))
++ TrackInfo.LastDuration = Packet->duration;
+
+- av_packet_unref(&Packet);
++ av_packet_unref(Packet);
+ }
++ av_packet_free(&Packet);
+
+ TrackIndices->Finalize(AVContexts, FormatContext->iformat->name);
+ return TrackIndices.release();
+ }
+
+-void FFMS_Indexer::ReadTS(const AVPacket &Packet, int64_t &TS, bool &UseDTS) {
+- if (!UseDTS && Packet.pts != AV_NOPTS_VALUE)
+- TS = Packet.pts;
++void FFMS_Indexer::ReadTS(const AVPacket *Packet, int64_t &TS, bool &UseDTS) {
++ if (!UseDTS && Packet->pts != AV_NOPTS_VALUE)
++ TS = Packet->pts;
+ if (TS == AV_NOPTS_VALUE)
+ UseDTS = true;
+- if (UseDTS && Packet.dts != AV_NOPTS_VALUE)
+- TS = Packet.dts;
++ if (UseDTS && Packet->dts != AV_NOPTS_VALUE)
++ TS = Packet->dts;
+ }
+diff --git a/src/core/indexing.h b/src/core/indexing.h
+index 3cfc3c3..5c06868 100644
+--- a/src/core/indexing.h
++++ b/src/core/indexing.h
+@@ -80,10 +80,10 @@ private:
+ int64_t Filesize;
+ uint8_t Digest[20];
+
+- void ReadTS(const AVPacket &Packet, int64_t &TS, bool &UseDTS);
++ void ReadTS(const AVPacket *Packet, int64_t &TS, bool &UseDTS);
+ void CheckAudioProperties(int Track, AVCodecContext *Context);
+ uint32_t IndexAudioPacket(int Track, AVPacket *Packet, SharedAVContext &Context, FFMS_Index &TrackIndices);
+- void ParseVideoPacket(SharedAVContext &VideoContext, AVPacket &pkt, int *RepeatPict, int *FrameType, bool *Invisible, enum AVPictureStructure *LastPicStruct);
++ void ParseVideoPacket(SharedAVContext &VideoContext, AVPacket *pkt, int *RepeatPict, int *FrameType, bool *Invisible, enum AVPictureStructure *LastPicStruct);
+ void Free();
+ public:
+ FFMS_Indexer(const char *Filename);
+diff --git a/src/core/utils.cpp b/src/core/utils.cpp
+index ce67533..8a2e997 100644
+--- a/src/core/utils.cpp
++++ b/src/core/utils.cpp
+@@ -62,12 +62,6 @@ void ClearErrorInfo(FFMS_ErrorInfo *ErrorInfo) {
+ }
+ }
+
+-void InitNullPacket(AVPacket &pkt) {
+- av_init_packet(&pkt);
+- pkt.data = nullptr;
+- pkt.size = 0;
+-}
+-
+ void FillAP(FFMS_AudioProperties &AP, AVCodecContext *CTX, FFMS_Track &Frames) {
+ AP.SampleFormat = static_cast<FFMS_SampleFormat>(av_get_packed_sample_fmt(CTX->sample_fmt));
+ AP.BitsPerSample = av_get_bytes_per_sample(CTX->sample_fmt) * 8;
+diff --git a/src/core/utils.h b/src/core/utils.h
+index 9819dc7..003ab79 100644
+--- a/src/core/utils.h
++++ b/src/core/utils.h
+@@ -58,7 +58,6 @@ std::unique_ptr<T> make_unique(Args&&... args) {
+ }
+
+ void ClearErrorInfo(FFMS_ErrorInfo *ErrorInfo);
+-void InitNullPacket(AVPacket &pkt);
+ void FillAP(FFMS_AudioProperties &AP, AVCodecContext *CTX, FFMS_Track &Frames);
+
+ void LAVFOpenFile(const char *SourceFile, AVFormatContext *&FormatContext, int Track);
+diff --git a/src/core/videosource.cpp b/src/core/videosource.cpp
+index 06bd161..b889970 100644
+--- a/src/core/videosource.cpp
++++ b/src/core/videosource.cpp
+@@ -673,30 +673,34 @@ void FFMS_VideoSource::DecodeNextFrame(int64_t &AStartTime, int64_t &Pos) {
+ if (HasPendingDelayedFrames())
+ return;
+
+- AVPacket Packet;
+- InitNullPacket(Packet);
+-
+- while (ReadFrame(&Packet) >= 0) {
+- if (Packet.stream_index != VideoTrack) {
+- av_packet_unref(&Packet);
++ AVPacket *Packet = av_packet_alloc();
++ if (!Packet)
++ throw FFMS_Exception(FFMS_ERROR_DECODING, FFMS_ERROR_ALLOCATION_FAILED,
++ "Could not allocate packet.");
++
++ while (ReadFrame(Packet) >= 0) {
++ if (Packet->stream_index != VideoTrack) {
++ av_packet_unref(Packet);
+ continue;
+ }
+
+ if (AStartTime < 0)
+- AStartTime = Frames.UseDTS ? Packet.dts : Packet.pts;
++ AStartTime = Frames.UseDTS ? Packet->dts : Packet->pts;
+
+ if (Pos < 0)
+- Pos = Packet.pos;
++ Pos = Packet->pos;
+
+- bool FrameFinished = DecodePacket(&Packet);
+- av_packet_unref(&Packet);
+- if (FrameFinished)
++ bool FrameFinished = DecodePacket(Packet);
++ av_packet_unref(Packet);
++ if (FrameFinished) {
++ av_packet_free(&Packet);
+ return;
++ }
+ }
+
+ // Flush final frames
+- InitNullPacket(Packet);
+- DecodePacket(&Packet);
++ DecodePacket(Packet);
++ av_packet_free(&Packet);
+ }
+
+ bool FFMS_VideoSource::SeekTo(int n, int SeekOffset) {
+--
+2.40.0
+
+From bf9e03e9e08534c024e5a744a6437c4aac160201 Mon Sep 17 00:00:00 2001
+From: Derek Buitenhuis <derek.buitenhuis@gmail.com>
+Date: Tue, 4 May 2021 14:20:47 +0100
+Subject: [PATCH 2/3] configure: Remove deprecated API use
+
+Signed-off-by: Derek Buitenhuis <derek.buitenhuis@gmail.com>
+---
+ configure.ac | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/configure.ac b/configure.ac
+index b35ef80bc..d19714d0f 100644
+--- a/configure.ac
++++ b/configure.ac
+@@ -102,10 +102,10 @@ CFLAGS="$_CFLAGS $FFMPEG_CFLAGS"
+
+ AC_DEFUN([TEST_FFMPEG],
+ [AC_LINK_IFELSE([AC_LANG_PROGRAM([[
+- #include <libavcodec/avcodec.h>
++ #include <libavformat/avformat.h>
+ #include <libswscale/swscale.h>
+ ]],[[
+- avcodec_register_all();
++ avformat_network_init();
+ swscale_version();
+ ]])], [eval $1=yes], [eval $1=no])
+ ])
+
diff --git a/srcpkgs/ffms2/template b/srcpkgs/ffms2/template
index 68e8a0c14bce..2acfadac44b3 100644
--- a/srcpkgs/ffms2/template
+++ b/srcpkgs/ffms2/template
@@ -1,7 +1,7 @@
# Template file for 'ffms2'
pkgname=ffms2
version=2.40
-revision=1
+revision=2
build_style=gnu-configure
configure_args="--enable-shared --disable-static"
hostmakedepends="pkg-config autoconf automake libtool"
From 1222fe908d51f49828cf907c43269b774863a239 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:47 -0400
Subject: [PATCH 037/115] freerdp: revbump for ffmpeg-6.0
---
.../freerdp/patches/ffmpeg6_aa2cb9aa.patch | 42 +++++++++++++++++++
srcpkgs/freerdp/template | 2 +-
2 files changed, 43 insertions(+), 1 deletion(-)
create mode 100644 srcpkgs/freerdp/patches/ffmpeg6_aa2cb9aa.patch
diff --git a/srcpkgs/freerdp/patches/ffmpeg6_aa2cb9aa.patch b/srcpkgs/freerdp/patches/ffmpeg6_aa2cb9aa.patch
new file mode 100644
index 000000000000..a4324da3a882
--- /dev/null
+++ b/srcpkgs/freerdp/patches/ffmpeg6_aa2cb9aa.patch
@@ -0,0 +1,42 @@
+From aa2cb9aa5ff5562433598ba168a466e0752bca0e Mon Sep 17 00:00:00 2001
+From: akallabeth <akallabeth@posteo.net>
+Date: Tue, 14 Feb 2023 07:48:54 +0100
+Subject: [PATCH] Fixed #8686: Update h264 to use new FFMPEG API
+
+---
+ channels/tsmf/client/ffmpeg/tsmf_ffmpeg.c | 2 ++
+ libfreerdp/codec/h264_ffmpeg.c | 2 ++
+ 2 files changed, 4 insertions(+)
+
+diff --git a/channels/tsmf/client/ffmpeg/tsmf_ffmpeg.c b/channels/tsmf/client/ffmpeg/tsmf_ffmpeg.c
+index 339462d865f..beea80b7a1e 100644
+--- a/channels/tsmf/client/ffmpeg/tsmf_ffmpeg.c
++++ b/channels/tsmf/client/ffmpeg/tsmf_ffmpeg.c
+@@ -239,8 +239,10 @@ static BOOL tsmf_ffmpeg_init_stream(ITSMFDecoder* decoder, const TS_AM_MEDIA_TYP
+ }
+ }
+
++#if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(59, 18, 100)
+ if (mdecoder->codec->capabilities & AV_CODEC_CAP_TRUNCATED)
+ mdecoder->codec_context->flags |= AV_CODEC_FLAG_TRUNCATED;
++#endif
+
+ return TRUE;
+ }
+diff --git a/libfreerdp/codec/h264_ffmpeg.c b/libfreerdp/codec/h264_ffmpeg.c
+index 8a23db2473c..896a333019b 100644
+--- a/libfreerdp/codec/h264_ffmpeg.c
++++ b/libfreerdp/codec/h264_ffmpeg.c
+@@ -615,10 +615,12 @@ static BOOL libavcodec_init(H264_CONTEXT* h264)
+ goto EXCEPTION;
+ }
+
++#if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(59, 18, 100)
+ if (sys->codecDecoder->capabilities & AV_CODEC_CAP_TRUNCATED)
+ {
+ sys->codecDecoderContext->flags |= AV_CODEC_FLAG_TRUNCATED;
+ }
++#endif
+
+ #ifdef WITH_VAAPI
+
diff --git a/srcpkgs/freerdp/template b/srcpkgs/freerdp/template
index 25e8aa9677f0..4d51c8189902 100644
--- a/srcpkgs/freerdp/template
+++ b/srcpkgs/freerdp/template
@@ -1,7 +1,7 @@
# Template file for 'freerdp'
pkgname=freerdp
version=2.10.0
-revision=1
+revision=2
build_style=cmake
configure_args="-DWITH_ALSA=ON -DWITH_CUPS=OFF -DWITH_FFMPEG=ON
-DWITH_GSTREAMER_0_10=OFF -DWITH_GSTREAMER_1_0=OFF -DWITH_JPEG=ON
From f995b47cca685dd2b14dacc16ecc361acfac193d Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:47 -0400
Subject: [PATCH 038/115] gerbera: revbump for ffmpeg-6.0
---
srcpkgs/gerbera/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/gerbera/template b/srcpkgs/gerbera/template
index ae14f35c767c..2dc0ac0ce03b 100644
--- a/srcpkgs/gerbera/template
+++ b/srcpkgs/gerbera/template
@@ -1,7 +1,7 @@
# Template file for 'gerbera'
pkgname=gerbera
version=1.12.1
-revision=1
+revision=2
build_style=cmake
configure_args="-DWITH_SYSTEMD=0 -DWITH_AVCODEC=1"
hostmakedepends="pkg-config"
From 1ec1c2866aea383d4a6cb7ffa8eaae1fc81505d3 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:47 -0400
Subject: [PATCH 039/115] goldendict: revbump for ffmpeg-6.0
---
srcpkgs/goldendict/patches/ffmpeg4.patch | 21 --
srcpkgs/goldendict/patches/ffmpeg5.patch | 232 +++++++++++++++++++++++
srcpkgs/goldendict/template | 2 +-
3 files changed, 233 insertions(+), 22 deletions(-)
delete mode 100644 srcpkgs/goldendict/patches/ffmpeg4.patch
create mode 100644 srcpkgs/goldendict/patches/ffmpeg5.patch
diff --git a/srcpkgs/goldendict/patches/ffmpeg4.patch b/srcpkgs/goldendict/patches/ffmpeg4.patch
deleted file mode 100644
index f045fa27f54b..000000000000
--- a/srcpkgs/goldendict/patches/ffmpeg4.patch
+++ /dev/null
@@ -1,21 +0,0 @@
---- a/ffmpegaudio.cc.orig 2018-05-09 22:16:13.480659958 +0200
-+++ b/ffmpegaudio.cc 2018-05-09 22:16:50.748322790 +0200
-@@ -143,7 +143,7 @@
- return false;
- }
-
-- unsigned char * avioBuffer = ( unsigned char * )av_malloc( kBufferSize + FF_INPUT_BUFFER_PADDING_SIZE );
-+ unsigned char * avioBuffer = ( unsigned char * )av_malloc( kBufferSize + AV_INPUT_BUFFER_PADDING_SIZE );
- if ( !avioBuffer )
- {
- errorString = QObject::tr( "av_malloc() failed." );
-@@ -380,7 +380,7 @@
- }
-
- if ( !Qt4x5::AtomicInt::loadAcquire( isCancelled_ ) &&
-- codecContext_->codec->capabilities & CODEC_CAP_DELAY )
-+ codecContext_->codec->capabilities & AV_CODEC_CAP_DELAY )
- {
- av_init_packet( &packet );
- int gotFrame = 0;
-
diff --git a/srcpkgs/goldendict/patches/ffmpeg5.patch b/srcpkgs/goldendict/patches/ffmpeg5.patch
new file mode 100644
index 000000000000..7cfc98ada368
--- /dev/null
+++ b/srcpkgs/goldendict/patches/ffmpeg5.patch
@@ -0,0 +1,232 @@
+From 03bbe01b79a1f07a6780cb60f23a087104c5d77b Mon Sep 17 00:00:00 2001
+From: Abs62 <ottomann@yandex.ru>
+Date: Fri, 30 Mar 2018 22:53:24 +0300
+Subject: [PATCH] Fix warnings while compile with FFMpeg 3.4.2 (issue #978)
+
+---
+ ffmpegaudio.cc | 68 +++++++++++++++++++++++++++++++++++++++++++++-----
+ 1 file changed, 62 insertions(+), 6 deletions(-)
+
+diff --git a/ffmpegaudio.cc b/ffmpegaudio.cc
+index ed1172bdd..56e8f788e 100644
+--- a/ffmpegaudio.cc
++++ b/ffmpegaudio.cc
+@@ -91,6 +91,7 @@ struct DecoderContext
+ QByteArray audioData_;
+ QDataStream audioDataStream_;
+ AVFormatContext * formatContext_;
++ AVCodec * codec_;
+ AVCodecContext * codecContext_;
+ AVIOContext * avioContext_;
+ AVStream * audioStream_;
+@@ -114,6 +115,7 @@ DecoderContext::DecoderContext( QByteArray const & audioData, QAtomicInt & isCan
+ audioData_( audioData ),
+ audioDataStream_( audioData_ ),
+ formatContext_( NULL ),
++ codec_( NULL ),
+ codecContext_( NULL ),
+ avioContext_( NULL ),
+ audioStream_( NULL ),
+@@ -143,7 +145,11 @@ bool DecoderContext::openCodec( QString & errorString )
+ return false;
+ }
+
++#if LIBAVCODEC_VERSION_MAJOR < 56 || ( LIBAVCODEC_VERSION_MAJOR == 56 && LIBAVCODEC_VERSION_MINOR < 56 )
+ unsigned char * avioBuffer = ( unsigned char * )av_malloc( kBufferSize + FF_INPUT_BUFFER_PADDING_SIZE );
++#else
++ unsigned char * avioBuffer = ( unsigned char * )av_malloc( kBufferSize + AV_INPUT_BUFFER_PADDING_SIZE );
++#endif
+ if ( !avioBuffer )
+ {
+ errorString = QObject::tr( "av_malloc() failed." );
+@@ -186,7 +192,11 @@ bool DecoderContext::openCodec( QString & errorString )
+ // Find audio stream, use the first audio stream if available
+ for ( unsigned i = 0; i < formatContext_->nb_streams; i++ )
+ {
++#if LIBAVCODEC_VERSION_MAJOR < 57 || ( LIBAVCODEC_VERSION_MAJOR == 57 && LIBAVCODEC_VERSION_MINOR < 33 )
+ if ( formatContext_->streams[i]->codec->codec_type == AVMEDIA_TYPE_AUDIO )
++#else
++ if ( formatContext_->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_AUDIO )
++#endif
+ {
+ audioStream_ = formatContext_->streams[i];
+ break;
+@@ -198,22 +208,38 @@ bool DecoderContext::openCodec( QString & errorString )
+ return false;
+ }
+
++#if LIBAVCODEC_VERSION_MAJOR < 57 || ( LIBAVCODEC_VERSION_MAJOR == 57 && LIBAVCODEC_VERSION_MINOR < 33 )
+ codecContext_ = audioStream_->codec;
+- AVCodec * codec = avcodec_find_decoder( codecContext_->codec_id );
+- if ( !codec )
++ codec_ = avcodec_find_decoder( codecContext_->codec_id );
++ if ( !codec_ )
+ {
+ errorString = QObject::tr( "Codec [id: %1] not found." ).arg( codecContext_->codec_id );
+ return false;
+ }
++#else
++ codec_ = avcodec_find_decoder( audioStream_->codecpar->codec_id );
++ if ( !codec_ )
++ {
++ errorString = QObject::tr( "Codec [id: %1] not found." ).arg( audioStream_->codecpar->codec_id );
++ return false;
++ }
++ codecContext_ = avcodec_alloc_context3( codec_ );
++ if ( !codecContext_ )
++ {
++ errorString = QObject::tr( "avcodec_alloc_context3() failed." );
++ return false;
++ }
++ avcodec_parameters_to_context( codecContext_, audioStream_->codecpar );
++#endif
+
+- ret = avcodec_open2( codecContext_, codec, NULL );
++ ret = avcodec_open2( codecContext_, codec_, NULL );
+ if ( ret < 0 )
+ {
+ errorString = QObject::tr( "avcodec_open2() failed: %1." ).arg( avErrorString( ret ) );
+ return false;
+ }
+
+- av_log( NULL, AV_LOG_INFO, "Codec open: %s: channels: %d, rate: %d, format: %s\n", codec->long_name,
++ av_log( NULL, AV_LOG_INFO, "Codec open: %s: channels: %d, rate: %d, format: %s\n", codec_->long_name,
+ codecContext_->channels, codecContext_->sample_rate, av_get_sample_fmt_name( codecContext_->sample_fmt ) );
+ return true;
+ }
+@@ -252,10 +278,13 @@ void DecoderContext::closeCodec()
+
+ // Closing a codec context without prior avcodec_open2() will result in
+ // a crash in ffmpeg
+- if ( audioStream_ && audioStream_->codec && audioStream_->codec->codec )
++ if ( audioStream_ && codecContext_ && codec_ )
+ {
+ audioStream_->discard = AVDISCARD_ALL;
+- avcodec_close( audioStream_->codec );
++ avcodec_close( codecContext_ );
++#if LIBAVCODEC_VERSION_MAJOR > 57 || ( LIBAVCODEC_VERSION_MAJOR == 57 && LIBAVCODEC_VERSION_MINOR >= 33 )
++ avcodec_free_context( &codecContext_ );
++#endif
+ }
+
+ avformat_close_input( &formatContext_ );
+@@ -356,6 +385,7 @@ bool DecoderContext::play( QString & errorString )
+ if ( packet.stream_index == audioStream_->index )
+ {
+ AVPacket pack = packet;
++#if LIBAVCODEC_VERSION_MAJOR < 57 || ( LIBAVCODEC_VERSION_MAJOR == 57 && LIBAVCODEC_VERSION_MINOR < 37 )
+ int gotFrame = 0;
+ do
+ {
+@@ -370,6 +400,19 @@ bool DecoderContext::play( QString & errorString )
+ pack.data += len;
+ }
+ while( pack.size > 0 );
++#else
++ int ret = avcodec_send_packet( codecContext_, &pack );
++ /* read all the output frames (in general there may be any number of them) */
++ while( ret >= 0 )
++ {
++ ret = avcodec_receive_frame( codecContext_, frame);
++
++ if ( Qt4x5::AtomicInt::loadAcquire( isCancelled_ ) || ret < 0 )
++ break;
++
++ playFrame( frame );
++ }
++#endif
+ }
+ // av_free_packet() must be called after each call to av_read_frame()
+ #if LIBAVCODEC_VERSION_MAJOR < 57 || ( LIBAVCODEC_VERSION_MAJOR == 57 && LIBAVCODEC_VERSION_MINOR < 7 )
+@@ -379,6 +422,7 @@ bool DecoderContext::play( QString & errorString )
+ #endif
+ }
+
++#if LIBAVCODEC_VERSION_MAJOR < 57 || ( LIBAVCODEC_VERSION_MAJOR == 57 && LIBAVCODEC_VERSION_MINOR < 37 )
+ if ( !Qt4x5::AtomicInt::loadAcquire( isCancelled_ ) &&
+ codecContext_->codec->capabilities & CODEC_CAP_DELAY )
+ {
+@@ -391,6 +435,18 @@ bool DecoderContext::play( QString & errorString )
+ playFrame( frame );
+ }
+ }
++#else
++ /* flush the decoder */
++ av_init_packet( &packet );
++ int ret = avcodec_send_packet(codecContext_, &packet );
++ while( ret >= 0 )
++ {
++ ret = avcodec_receive_frame(codecContext_, frame);
++ if ( Qt4x5::AtomicInt::loadAcquire( isCancelled_ ) || ret < 0 )
++ break;
++ playFrame( frame );
++ }
++#endif
+
+ #if LIBAVCODEC_VERSION_MAJOR < 54
+ av_free( frame );
+32
+srcpkgs/goldendict/patches/ffmpeg5-2.patch
+Comment on this file
+@@ -0,0 +1,32 @@
+From 966f4a8b78e6324b930e5a50f2bb930bd87e565e Mon Sep 17 00:00:00 2001
+From: Abs62 <ottomann@yandex.ru>
+Date: Fri, 27 Sep 2019 17:00:52 +0300
+Subject: [PATCH] FFmpeg player: Fix some crashes on broken files
+
+---
+ ffmpegaudio.cc | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/ffmpegaudio.cc b/ffmpegaudio.cc
+index 56e8f788e..415fc79cb 100644
+--- a/ffmpegaudio.cc
++++ b/ffmpegaudio.cc
+@@ -51,7 +51,9 @@ AudioService & AudioService::instance()
+
+ AudioService::AudioService()
+ {
++#if LIBAVFORMAT_VERSION_MAJOR < 58 || ( LIBAVFORMAT_VERSION_MAJOR == 58 && LIBAVFORMAT_VERSION_MINOR < 9 )
+ av_register_all();
++#endif
+ ao_initialize();
+ }
+
+@@ -438,6 +440,8 @@ bool DecoderContext::play( QString & errorString )
+ #else
+ /* flush the decoder */
+ av_init_packet( &packet );
++ packet.data = NULL;
++ packet.size = 0;
+ int ret = avcodec_send_packet(codecContext_, &packet );
+ while( ret >= 0 )
+ {
+25
+srcpkgs/goldendict/patches/ffmpeg5-3.patch
+Comment on this file
+@@ -0,0 +1,25 @@
+From 8acb288c9e9bdb3c6bf2e803954dd3b6ac273c05 Mon Sep 17 00:00:00 2001
+From: Liao Junxuan <mikeljx@126.com>
+Date: Sun, 20 Feb 2022 12:28:05 +0800
+Subject: [PATCH] add support for ffmpeg 5.0
+
+---
+ ffmpegaudio.cc | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/ffmpegaudio.cc b/ffmpegaudio.cc
+index d550f4a77..7948d2187 100644
+--- a/ffmpegaudio.cc
++++ b/ffmpegaudio.cc
+@@ -94,7 +94,11 @@ struct DecoderContext
+ QByteArray audioData_;
+ QDataStream audioDataStream_;
+ AVFormatContext * formatContext_;
++#if LIBAVCODEC_VERSION_MAJOR < 59
+ AVCodec * codec_;
++#else
++ const AVCodec * codec_;
++#endif
+ AVCodecContext * codecContext_;
+ AVIOContext * avioContext_;
+ AVStream * audioStream_;
diff --git a/srcpkgs/goldendict/template b/srcpkgs/goldendict/template
index 4544ae710ee6..2ca4185e538a 100644
--- a/srcpkgs/goldendict/template
+++ b/srcpkgs/goldendict/template
@@ -9,7 +9,7 @@ makedepends="tiff-devel qt5-devel libvorbis-devel zlib-devel
libXtst-devel hunspell-devel qt5-tools-devel qt5-declarative-devel
qt5-webkit-devel lzo-devel bzip2-devel libao-devel qt5-svg-devel
libeb-devel qt5-x11extras-devel ffmpeg-devel liblzma-devel"
-short_desc="A feature-rich dictionary lookup program"
+short_desc="Feature-rich dictionary lookup program"
maintainer="John <me@johnnynator.dev>"
license="GPL-3.0-or-later"
homepage="http://goldendict.org/"
From 1aee6e8d96f9c4cfb76fb089b25f12cea5d37dde Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:47 -0400
Subject: [PATCH 040/115] gst-libav: revbump for ffmpeg-6.0
---
srcpkgs/gst-libav/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/gst-libav/template b/srcpkgs/gst-libav/template
index e9a79dc650a5..f082bd211c65 100644
--- a/srcpkgs/gst-libav/template
+++ b/srcpkgs/gst-libav/template
@@ -1,7 +1,7 @@
# Template file for 'gst-libav'
pkgname=gst-libav
version=1.20.3
-revision=1
+revision=2
build_style=meson
hostmakedepends="pkg-config yasm"
makedepends="orc-devel gst-plugins-base1-devel ffmpeg-devel"
From 9116fbba9005538f87198d08359bc9db3f16505a Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:47 -0400
Subject: [PATCH 041/115] gst-plugins-bad1: revbump for ffmpeg-6.0
---
srcpkgs/gst-plugins-bad1/template | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/srcpkgs/gst-plugins-bad1/template b/srcpkgs/gst-plugins-bad1/template
index f55f82fd4c77..dc9d389734e1 100644
--- a/srcpkgs/gst-plugins-bad1/template
+++ b/srcpkgs/gst-plugins-bad1/template
@@ -1,7 +1,7 @@
# Template file for 'gst-plugins-bad1'
pkgname=gst-plugins-bad1
-version=1.20.3
-revision=3
+version=1.22.2
+revision=2
build_helper="gir"
build_style=meson
configure_args="-Dpackage-origin=https://voidlinux.org -Ddoc=disabled
From 79d20087f60b715b7cfcb50b2b5a1d94cd4239a0 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:47 -0400
Subject: [PATCH 042/115] gst-rtsp-server: revbump for ffmpeg-6.0
---
srcpkgs/gst-rtsp-server/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/gst-rtsp-server/template b/srcpkgs/gst-rtsp-server/template
index 33cd64ceb95e..8ceea8d34b4b 100644
--- a/srcpkgs/gst-rtsp-server/template
+++ b/srcpkgs/gst-rtsp-server/template
@@ -1,7 +1,7 @@
# Template file for 'gst-rtsp-server'
pkgname=gst-rtsp-server
version=1.20.3
-revision=2
+revision=3
build_style=meson
hostmakedepends="pkg-config python3"
makedepends="glib-devel gst-plugins-bad1-devel gobject-introspection
From e7b5f401b71a5b37aa5ecfaa94decc429d6f29bf Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:47 -0400
Subject: [PATCH 043/115] guvcview: update to 2.0.8.
---
srcpkgs/guvcview/patches/fix-include.patch | 10 ++++++++++
srcpkgs/guvcview/template | 5 ++---
2 files changed, 12 insertions(+), 3 deletions(-)
create mode 100644 srcpkgs/guvcview/patches/fix-include.patch
diff --git a/srcpkgs/guvcview/patches/fix-include.patch b/srcpkgs/guvcview/patches/fix-include.patch
new file mode 100644
index 000000000000..503c2af3b78c
--- /dev/null
+++ b/srcpkgs/guvcview/patches/fix-include.patch
@@ -0,0 +1,10 @@
+--- a/guvcview/guvcview.c
++++ b/guvcview/guvcview.c
+@@ -28,6 +28,7 @@
+ #include <sys/stat.h>
+ #include <sys/resource.h>
+ #include <errno.h>
++#include <locale.h>
+
+ #include "gview.h"
+ #include "gviewv4l2core.h"
diff --git a/srcpkgs/guvcview/template b/srcpkgs/guvcview/template
index 345cf6006f24..86a7fd619612 100644
--- a/srcpkgs/guvcview/template
+++ b/srcpkgs/guvcview/template
@@ -1,8 +1,7 @@
# Template file for 'guvcview'
pkgname=guvcview
-version=2.0.7
+version=2.0.8
revision=1
-create_wrksrc=yes
build_style=gnu-configure
configure_args="--disable-static --disable-debian-menu"
hostmakedepends="pkg-config intltool autoconf automake libtool glib-devel"
@@ -14,7 +13,7 @@ maintainer="Orphaned <orphan@voidlinux.org>"
license="GPL-3.0-or-later"
homepage="http://guvcview.sourceforge.net/"
distfiles="${SOURCEFORGE_SITE}/${pkgname}/${pkgname}-src-${version}.tar.bz2"
-checksum=f47d51fbd06e44eeaa1a82f4a153c927527c90d94514197a70b2956028cc8ad4
+checksum=a21f4e448286666cf27bafef5290cc953a0a1796b752e5bbe521266dc1230c81
post_patch() {
sed '31a#include <locale.h>' -i guvcview/guvcview.c
From 1f613e34f36191ec5e5573f1ad54105426ca7b37 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:48 -0400
Subject: [PATCH 044/115] handbrake: update to 1.6.1
---
.../patches/fix-missing-x265-link-flag.patch | 11 ++++++-----
.../handbrake/patches/libhb-vpl-include.patch | 15 +++++++++++++++
srcpkgs/handbrake/template | 17 ++++++++++-------
3 files changed, 31 insertions(+), 12 deletions(-)
create mode 100644 srcpkgs/handbrake/patches/libhb-vpl-include.patch
diff --git a/srcpkgs/handbrake/patches/fix-missing-x265-link-flag.patch b/srcpkgs/handbrake/patches/fix-missing-x265-link-flag.patch
index 26db03867a0c..d6bb2eda627a 100644
--- a/srcpkgs/handbrake/patches/fix-missing-x265-link-flag.patch
+++ b/srcpkgs/handbrake/patches/fix-missing-x265-link-flag.patch
@@ -1,14 +1,15 @@
--- a/gtk/configure.ac
+++ b/gtk/configure.ac
@@ -203,7 +203,7 @@
-
+
AM_CONDITIONAL([MINGW], [test "x$mingw_flag" = "xyes"])
-
--HB_LIBS="$HB_LIBS -lhandbrake -lavformat -lavfilter -lavcodec -lavutil -ldav1d -lswresample -lpostproc -ldvdnav -ldvdread -lmp3lame -lvorbis -lvorbisenc -logg -lswscale -ltheoraenc -ltheoradec -lvpx -lz -lbz2 -lbluray -lass -lfontconfig -lfreetype -lxml2 -ljansson -lopus -lspeex -lturbojpeg -llzma -lzimg"
-+HB_LIBS="$HB_LIBS -lhandbrake -lavformat -lavfilter -lavcodec -lavutil -ldav1d -lswresample -lpostproc -ldvdnav -ldvdread -lmp3lame -lvorbis -lvorbisenc -logg -lswscale -ltheoraenc -ltheoradec -lvpx -lz -lbz2 -lbluray -lass -lfontconfig -lfreetype -lxml2 -ljansson -lopus -lspeex -lturbojpeg -llzma -lzimg -ldl"
+
+-HB_LIBS="$HB_LIBS -lhandbrake -lavformat -lavfilter -lavcodec -lavutil -ldav1d -lswresample -lpostproc -ldvdnav -ldvdread -lmp3lame -lvorbis -lvorbisenc -logg -lswscale -ltheoraenc -ltheoradec -lvpx -lz -lbz2 -lbluray -lass -lfontconfig -lfreetype -lxml2 -ljansson -lopus -lspeex -lturbojpeg -llzma -lzimg -lSvtAv1Enc"
++HB_LIBS="$HB_LIBS -lhandbrake -lavformat -lavfilter -lavcodec -lavutil -ldav1d -lswresample -lpostproc -ldvdnav -ldvdread -lmp3lame -lvorbis -lvorbisenc -logg -lswscale -ltheoraenc -ltheoradec -lvpx -lz -lbz2 -lbluray -lass -lfontconfig -lfreetype -lxml2 -ljansson -lopus -lspeex -lturbojpeg -llzma -lzimg -lSvtAv1Enc -ldl"
HB_CPPFLAGS="$HB_CPPFLAGS $HBINC"
-
+
PKG_CHECK_MODULES([x264], [x264], sys_x264=yes, sys_x264=no)
+
--- a/test/module.defs
+++ b/test/module.defs
@@ -69,6 +69,9 @@
diff --git a/srcpkgs/handbrake/patches/libhb-vpl-include.patch b/srcpkgs/handbrake/patches/libhb-vpl-include.patch
new file mode 100644
index 000000000000..298f9f4ab28f
--- /dev/null
+++ b/srcpkgs/handbrake/patches/libhb-vpl-include.patch
@@ -0,0 +1,15 @@
+--- a/libhb/module.defs 2023-01-22 11:36:49.000000000 -0500
++++ b/libhb/module.defs 2023-04-03 22:37:52.395467010 -0400
+@@ -46,11 +46,7 @@
+ LIBHB.GCC.I += $(LIBHB.build/) $(CONTRIB.build/)include
+
+ ifeq (1,$(FEATURE.qsv))
+- ifeq ($(HOST.system),freebsd))
+- LIBHB.GCC.I += $(LOCALBASE)/include/vpl
+- else
+- LIBHB.GCC.I += $(CONTRIB.build/)include/vpl
+- endif
++ LIBHB.GCC.I += /usr/include/vpl
+ endif
+
+ ifneq (,$(filter $(HOST.system),freebsd netbsd openbsd))
diff --git a/srcpkgs/handbrake/template b/srcpkgs/handbrake/template
index ca5e4571e49c..c32cb1bfa31f 100644
--- a/srcpkgs/handbrake/template
+++ b/srcpkgs/handbrake/template
@@ -1,10 +1,10 @@
# Template file for 'handbrake'
pkgname=handbrake
-version=1.5.1
+version=1.6.1
revision=1
build_style=gnu-configure
configure_args="--force --disable-gtk-update-checks --disable-df-fetch --harden
- $(vopt_enable fdk_aac fdk-aac) $(vopt_enable nvenc)"
+ $(vopt_enable fdk_aac fdk-aac) $(vopt_enable nvenc) $(vopt_enable qsv)"
make_build_args="-C ${XBPS_TRIPLET}"
make_install_args="-C ${XBPS_TRIPLET}"
hostmakedepends="automake cmake gettext-devel glib-devel intltool libtool m4 meson nasm pkg-config python3"
@@ -12,8 +12,11 @@ makedepends="bzip2-devel ffmpeg-devel gst-plugins-base1-devel gtk+3-devel
jansson-devel lame-devel libass-devel libbluray-devel libdav1d-devel
libdvdnav-devel libdvdread-devel libgudev-devel libnuma-devel
libsamplerate-devel libtheora-devel libvorbis-devel libvpx-devel libxml2-devel
- opus-devel speex-devel x264-devel x265-devel zimg-devel
+ opus-devel speex-devel x264-devel x265-devel zimg-devel libsvt-av1-devel
$(vopt_if fdk_aac fdk-aac-devel)
+ $(vopt_if qsv libva-devel)
+ $(vopt_if qsv libdrm-devel)
+ $(vopt_if qsv onevpl-devel)
$(vopt_if nvenc nv-codec-headers)"
depends="desktop-file-utils gst-plugins-good1 hicolor-icon-theme"
short_desc="Multithreaded video transcoder"
@@ -21,15 +24,15 @@ maintainer="Enno Boland <gottox@voidlinux.org>"
license="GPL-2.0-only"
homepage="https://handbrake.fr/"
distfiles="https://github.com/HandBrake/HandBrake/releases/download/${version}/HandBrake-${version}-source.tar.bz2"
-checksum=3999fe06d5309c819799a73a968a8ec3840e7840c2b64af8f5cdb7fd8c9430f0
+checksum=94ccfe03db917a91650000c510f7fd53f844da19f19ad4b4be1b8f6bc31a8d4c
nocross=yes
-build_options="fdk_aac nvenc"
+build_options="fdk_aac nvenc qsv"
case "$XBPS_TARGET_MACHINE" in
x86_64*|i686*)
CFLAGS="-msse"
- build_options_default="nvenc"
+ build_options_default="nvenc qsv"
;;
esac
@@ -37,7 +40,7 @@ pre_configure() {
# use system libraries, don't download them
rm -rf contrib/
for module in fdk-aac ffmpeg libbluray libdav1d libdvdnav libdvdread nvenc \
- x265 zimg; do
+ x265 zimg svt-av1 libvpl; do
vsed -i "/MODULES += contrib\/${module}/d" make/include/main.defs
done
}
From 23c775316676797c187faa386717ade8d480a4ab Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:48 -0400
Subject: [PATCH 045/115] hedgewars: revbump for ffmpeg4-4.4.3
---
srcpkgs/hedgewars/template | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/srcpkgs/hedgewars/template b/srcpkgs/hedgewars/template
index 419f29b98b44..926fe4fe3e68 100644
--- a/srcpkgs/hedgewars/template
+++ b/srcpkgs/hedgewars/template
@@ -1,13 +1,13 @@
# Template file for 'hedgewars'
pkgname=hedgewars
version=1.0.2
-revision=1
+revision=2
build_style=cmake
configure_args="-DNOSERVER=1 -DDATA_INSTALL_DIR=/usr/share/${pkgname}
-DPHYSFS_SYSTEM=1 -DMINIMAL_FLAGS=1"
make_cmd=make
hostmakedepends="lua51 pkg-config qt5-qmake qt5-host-tools"
-makedepends="ffmpeg-devel lua51-devel physfs-devel qt5-tools-devel SDL2_image-devel
+makedepends="ffmpeg4-devel lua51-devel physfs-devel qt5-tools-devel SDL2_image-devel
SDL2_mixer-devel SDL2_net-devel SDL2_ttf-devel"
depends="libfreeglut"
short_desc="Funny turn-based artillery game, featuring fighting Hedgehogs!"
From d65f579cd3dab169a42ea3680615cdbf524e499f Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:48 -0400
Subject: [PATCH 046/115] idjc: revbump for ffmpeg4-4.4.3
---
srcpkgs/idjc/template | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/srcpkgs/idjc/template b/srcpkgs/idjc/template
index df60318b3db9..36a75baf597c 100644
--- a/srcpkgs/idjc/template
+++ b/srcpkgs/idjc/template
@@ -1,11 +1,11 @@
# Template file for 'idjc'
pkgname=idjc
version=0.9.1
-revision=3
+revision=4
build_style=gnu-configure
hostmakedepends="pkg-config git python3 automake gettext-devel libtool"
makedepends="libvorbis-devel libogg-devel jack-devel libsamplerate-devel
- libflac-devel libsndfile-devel mpg123-devel ffmpeg-devel speex-devel
+ libflac-devel libsndfile-devel mpg123-devel ffmpeg4-devel speex-devel
glib-devel pixman-devel lame-devel python3-gobject-devel libshout-idjc-devel
opus-devel twolame-devel python3-mutagen python3-devel"
depends="python3-gobject python3-mutagen desktop-file-utils shared-mime-info python3-dbus jack"
From 72d8d52d2bfe083dc04d76f1bb56c4c4bfeb2f54 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:48 -0400
Subject: [PATCH 047/115] kfilemetadata5: revbump for ffmpeg-6.0
---
srcpkgs/kfilemetadata5/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/kfilemetadata5/template b/srcpkgs/kfilemetadata5/template
index 8980121fbc69..f662a2043f93 100644
--- a/srcpkgs/kfilemetadata5/template
+++ b/srcpkgs/kfilemetadata5/template
@@ -1,7 +1,7 @@
# Template file for 'kfilemetadata5'
pkgname=kfilemetadata5
version=5.105.0
-revision=1
+revision=2
build_style=cmake
hostmakedepends="kcoreaddons extra-cmake-modules pkg-config qt5-host-tools qt5-qmake
gettext kcoreaddons python3"
From 08a598b72e6c53b793aa155807a04785dea9abb3 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:48 -0400
Subject: [PATCH 048/115] kid3: revbump for ffmpeg-6.0
---
srcpkgs/kid3/patches/ffmpeg5.patch | 17 +++++++++++++++++
srcpkgs/kid3/template | 2 +-
2 files changed, 18 insertions(+), 1 deletion(-)
create mode 100644 srcpkgs/kid3/patches/ffmpeg5.patch
diff --git a/srcpkgs/kid3/patches/ffmpeg5.patch b/srcpkgs/kid3/patches/ffmpeg5.patch
new file mode 100644
index 000000000000..135fc50e07c9
--- /dev/null
+++ b/srcpkgs/kid3/patches/ffmpeg5.patch
@@ -0,0 +1,17 @@
+# https://aur.archlinux.org/cgit/aur.git/diff/ffmpeg5.patch?h=kid3-cli&id=12410a74906612e7efc0ec8fbce739b4a0fef7e7
+diff --git a/src/plugins/acoustidimport/ffmpegfingerprintdecoder.cpp b/src/plugins/acoustidimport/ffmpegfingerprintdecoder.cpp
+index e156d424..e12b9abd 100644
+--- a/src/plugins/acoustidimport/ffmpegfingerprintdecoder.cpp
++++ b/src/plugins/acoustidimport/ffmpegfingerprintdecoder.cpp
+@@ -232,7 +232,11 @@ private:
+ friend class Format;
+ friend class Converter;
+ AVCodecContext* m_ptr;
++#if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(59, 0, 0)
+ AVCodec* m_impl;
++#else
++ const AVCodec* m_impl;
++#endif
+ AVFrame* m_frame;
+ bool m_opened;
+ };
diff --git a/srcpkgs/kid3/template b/srcpkgs/kid3/template
index 456206d90e16..f32f9decb0e7 100644
--- a/srcpkgs/kid3/template
+++ b/srcpkgs/kid3/template
@@ -1,7 +1,7 @@
# Template file for 'kid3'
pkgname=kid3
version=3.9.1
-revision=2
+revision=3
build_style=cmake
configure_args="-DWITH_APPS='CLI;$(vopt_if KDE KDE Qt)'
-DWITH_DOCBOOKDIR=/usr/share/xsl/docbook -DWITH_FLAC=$(vopt_if flac ON OFF)
From 4253cbff60908b72c1a21047b66d49b9c471a8c5 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:48 -0400
Subject: [PATCH 049/115] kodi: revbump for ffmpeg4-4.4.3
---
srcpkgs/kodi/template | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/srcpkgs/kodi/template b/srcpkgs/kodi/template
index 8057964d78a3..6cc1874be7ba 100644
--- a/srcpkgs/kodi/template
+++ b/srcpkgs/kodi/template
@@ -1,7 +1,7 @@
# Template file for 'kodi'
pkgname=kodi
version=19.4
-revision=6
+revision=7
_codename="Matrix"
build_style=cmake
configure_args="-DWITH_FFMPEG=/usr -DENABLE_LDGOLD=OFF
@@ -54,7 +54,7 @@ makedepends="
libmad-devel fontconfig-devel libXinerama-devel libsamplerate-devel libmms-devel
enca-devel boost-devel libcurl-devel libva-devel libvdpau-devel libass-devel
libbluetooth-devel yajl-devel libplist-devel librtmp-devel tinyxml-devel
- taglib-devel libcap-devel lame-devel libbluray-devel libnfs-devel ffmpeg-devel
+ taglib-devel libcap-devel lame-devel libbluray-devel libnfs-devel ffmpeg4-devel
giflib-devel libxslt-devel gnutls-devel libssh-devel libmicrohttpd-devel
libcec-devel dcadec-devel flatbuffers-devel fmt-devel lcms2-devel
libfstrcmp-devel rapidjson libcdio-paranoia spdlog libwaylandpp-devel
From 0b4cd6b4017591086137a4c0239e4a46d30460fd Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:48 -0400
Subject: [PATCH 050/115] kpipewire: revbump for ffmpeg-6.0
---
srcpkgs/kpipewire/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/kpipewire/template b/srcpkgs/kpipewire/template
index 467ab823a5e1..51827f24db9e 100644
--- a/srcpkgs/kpipewire/template
+++ b/srcpkgs/kpipewire/template
@@ -1,7 +1,7 @@
# Template file for 'kpipewire'
pkgname=kpipewire
version=5.27.4
-revision=1
+revision=2
build_style=cmake
hostmakedepends="extra-cmake-modules plasma-wayland-protocols gettext
qt5-qmake qt5-host-tools pkg-config wayland-devel kcoreaddons
From 7fa28b2af916efea654a4f681b4de60e2a610382 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:48 -0400
Subject: [PATCH 051/115] libextractor: revbump for ffmpeg4-4.4.3
---
srcpkgs/libextractor/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/libextractor/template b/srcpkgs/libextractor/template
index ddd4790f93e8..1fb9ca56a96a 100644
--- a/srcpkgs/libextractor/template
+++ b/srcpkgs/libextractor/template
@@ -7,7 +7,7 @@ configure_args="--disable-static"
hostmakedepends="pkg-config"
makedepends="zlib-devel bzip2-devel exiv2-devel tiff-devel libpng-devel
libjpeg-turbo-devel libvorbis-devel libflac-devel giflib-devel libmpeg2-devel
- ffmpeg-devel gtk+3-devel libltdl-devel libarchive-devel file-devel libgsf-devel"
+ ffmpeg4-devel gtk+3-devel libltdl-devel libarchive-devel file-devel libgsf-devel"
short_desc="Library used to extract meta data from files"
maintainer="Martin Riese <grauehaare@gmx.de>"
license="GPL-3.0-or-later"
From 187931f718670dc74c879b408b32548f9656b205 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:48 -0400
Subject: [PATCH 052/115] libopenal: revbump for ffmpeg-6.0
---
srcpkgs/libopenal/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/libopenal/template b/srcpkgs/libopenal/template
index 77218f9e539d..3f49ed75a1fd 100644
--- a/srcpkgs/libopenal/template
+++ b/srcpkgs/libopenal/template
@@ -1,7 +1,7 @@
# Template file for 'libopenal'
pkgname=libopenal
version=1.22.2
-revision=1
+revision=2
build_style=cmake
configure_args="-DALSOFT_EXAMPLES=OFF"
hostmakedepends="pkg-config"
From 5815972357c594243a909666ace64a0dadcad050 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:48 -0400
Subject: [PATCH 053/115] libopenshot: revbump for ffmpeg-6.0
---
srcpkgs/libopenshot/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/libopenshot/template b/srcpkgs/libopenshot/template
index db831f69b474..81aa0d7136d9 100644
--- a/srcpkgs/libopenshot/template
+++ b/srcpkgs/libopenshot/template
@@ -1,7 +1,7 @@
# Template file for 'libopenshot'
pkgname=libopenshot
version=0.3.0
-revision=1
+revision=2
build_style=cmake
# Builds fail with Ruby-2.4.1
configure_args="-DENABLE_RUBY=OFF -DUSE_SYSTEM_JSONCPP=ON"
From 50d776c0dabbdd5bdd2f03627ada27443bbb173b Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:48 -0400
Subject: [PATCH 054/115] loudgain: revbump for ffmpeg-6.0
---
srcpkgs/loudgain/patches/ffmpeg5.patch | 11 +++++++++++
srcpkgs/loudgain/template | 2 +-
2 files changed, 12 insertions(+), 1 deletion(-)
create mode 100644 srcpkgs/loudgain/patches/ffmpeg5.patch
diff --git a/srcpkgs/loudgain/patches/ffmpeg5.patch b/srcpkgs/loudgain/patches/ffmpeg5.patch
new file mode 100644
index 000000000000..16d4510ee98f
--- /dev/null
+++ b/srcpkgs/loudgain/patches/ffmpeg5.patch
@@ -0,0 +1,11 @@
+--- a/src/scan.c 2019-09-06 11:31:19.000000000 -0400
++++ b/src/scan.c 2023-03-23 11:15:40.867968521 -0400
+@@ -69,8 +69,6 @@
+ * It is now useless
+ * https://github.com/FFmpeg/FFmpeg/blob/70d25268c21cbee5f08304da95be1f647c630c15/doc/APIchanges#L86
+ */
+- if (avformat_version() < AV_VERSION_INT(58,9,100))
+- av_register_all();
+
+ av_log_set_callback(scan_av_log);
+
diff --git a/srcpkgs/loudgain/template b/srcpkgs/loudgain/template
index da4f2d56e94c..4d6bf29efb4f 100644
--- a/srcpkgs/loudgain/template
+++ b/srcpkgs/loudgain/template
@@ -1,7 +1,7 @@
# Template file for 'loudgain'
pkgname=loudgain
version=0.6.8
-revision=2
+revision=3
build_style=cmake
hostmakedepends="pkg-config"
makedepends="libebur128-devel taglib-devel ffmpeg-devel"
From f8cda18c46eab51c4e005d53439627a8343a8c88 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:48 -0400
Subject: [PATCH 055/115] mediastreamer: revbump for ffmpeg4-4.4.3
---
srcpkgs/mediastreamer/template | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/srcpkgs/mediastreamer/template b/srcpkgs/mediastreamer/template
index d0e97e858e29..1bde031443a5 100644
--- a/srcpkgs/mediastreamer/template
+++ b/srcpkgs/mediastreamer/template
@@ -1,11 +1,11 @@
# Template file for 'mediastreamer'
pkgname=mediastreamer
version=5.2.6
-revision=1
+revision=2
build_style=cmake
configure_args="-DENABLE_STRICT=0 -DENABLE_UNIT_TESTS=0"
hostmakedepends="python3"
-makedepends="bzrtp-devel ffmpeg-devel glew-devel libXv-devel libsrtp-devel
+makedepends="bzrtp-devel ffmpeg4-devel glew-devel libXv-devel libsrtp-devel
libupnp-devel libvpx-devel mbedtls-devel opus-devel ortp-devel pulseaudio-devel
libtheora-devel speex-devel v4l-utils-devel bcg729-devel bcmatroska2-devel libgsm-devel"
# zxing-cpp-devel (1.2.0 probably not compatible, check again after updaing xzing)
From 8f233333909c232570b4073560075f96e7df04df Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:48 -0400
Subject: [PATCH 056/115] mgba: revbump for ffmpeg-6.0
---
srcpkgs/mgba/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/mgba/template b/srcpkgs/mgba/template
index ae0504311eee..d31295a0cd3d 100644
--- a/srcpkgs/mgba/template
+++ b/srcpkgs/mgba/template
@@ -1,7 +1,7 @@
# Template file for 'mgba'
pkgname=mgba
version=0.10.2
-revision=1
+revision=2
build_style=cmake
hostmakedepends="pkg-config qt5-host-tools qt5-qmake desktop-file-utils"
makedepends="SDL2-devel ffmpeg-devel libedit-devel libepoxy-devel libmagick-devel
From cdce2b526a5cb555ed95aeac0d898bafd0e1a1f4 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:48 -0400
Subject: [PATCH 057/115] minidlna: revbump for ffmpeg-6.0
---
srcpkgs/minidlna/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/minidlna/template b/srcpkgs/minidlna/template
index e8081b1cbc67..9ee9714861fd 100644
--- a/srcpkgs/minidlna/template
+++ b/srcpkgs/minidlna/template
@@ -1,7 +1,7 @@
# Template file for 'minidlna'
pkgname=minidlna
version=1.3.2
-revision=1
+revision=2
build_style=gnu-configure
configure_args="
--sbindir=/usr/bin
From 8be3ee09f8e0d0f48443aded7dd171480e80adb8 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:49 -0400
Subject: [PATCH 058/115] mixxx: revbump for ffmpeg-6.0
---
srcpkgs/mixxx/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/mixxx/template b/srcpkgs/mixxx/template
index 619ddca0d332..4b9ea00d3fb3 100644
--- a/srcpkgs/mixxx/template
+++ b/srcpkgs/mixxx/template
@@ -1,7 +1,7 @@
# Template file for 'mixxx'
pkgname=mixxx
version=2.3.3
-revision=1
+revision=2
build_style=cmake
configure_args="-DCMAKE_BUILD_TYPE=Release"
hostmakedepends="extra-cmake-modules pkg-config protobuf qt5-host-tools qt5-devel"
From 367870c32065dc29ca1c061dd3184425f4806323 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:49 -0400
Subject: [PATCH 059/115] mlt: revbump for ffmpeg4-4.4.3
---
srcpkgs/mlt/template | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/srcpkgs/mlt/template b/srcpkgs/mlt/template
index 8933eb4e7bb9..73353fedafb5 100644
--- a/srcpkgs/mlt/template
+++ b/srcpkgs/mlt/template
@@ -1,14 +1,14 @@
# Template file for 'mlt'
pkgname=mlt
version=6.26.1
-revision=1
+revision=2
build_style=configure
configure_args="--prefix=/usr --libdir=/usr/lib$XBPS_TARGET_WORDSIZE
--enable-gpl --enable-gpl3 --disable-swfdec --without-kde
--swig-languages=python"
hostmakedepends="doxygen pkg-config ladspa-sdk swig python3 which"
# XXX: movit vid.stab
-makedepends="alsa-lib-devel ffmpeg-devel gtk+-devel jack-devel ladspa-sdk
+makedepends="alsa-lib-devel ffmpeg4-devel gtk+-devel jack-devel ladspa-sdk
libexif-devel libsamplerate-devel libxml2-devel sox-devel SDL_image-devel
fftw-devel frei0r-plugins python3-devel pulseaudio-devel movit-devel
libvidstab-devel libatomic-devel"
From b1c4aafcb4733b922233b3f1a7f7ce22ff90888c Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:49 -0400
Subject: [PATCH 060/115] moc: revbump for ffmpeg4-4.4.3
---
srcpkgs/moc/template | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/srcpkgs/moc/template b/srcpkgs/moc/template
index c42be650a1d2..d4f0eefbad52 100644
--- a/srcpkgs/moc/template
+++ b/srcpkgs/moc/template
@@ -1,10 +1,10 @@
# Template file for 'moc'
pkgname=moc
version=2.5.2
-revision=6
+revision=7
build_style=gnu-configure
hostmakedepends="pkg-config"
-makedepends="db-devel ncurses-devel libcurl-devel popt-devel ffmpeg-devel
+makedepends="db-devel ncurses-devel libcurl-devel popt-devel ffmpeg4-devel
jack-devel alsa-lib-devel libltdl-devel libflac-devel libvorbis-devel
libmad-devel libmpcdec-devel libmodplug-devel libid3tag-devel faad2-devel
taglib-devel libsndfile-devel wavpack-devel speex-devel libsamplerate-devel
From 1eff1b52487efd649fcd394cc985bc518805e580 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:49 -0400
Subject: [PATCH 061/115] motion: revbump for ffmpeg-6.0
---
srcpkgs/motion/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/motion/template b/srcpkgs/motion/template
index 3cf3c3035c5b..7dca12d851e3 100644
--- a/srcpkgs/motion/template
+++ b/srcpkgs/motion/template
@@ -1,7 +1,7 @@
# Template file for 'motion'
pkgname=motion
version=4.5.1
-revision=1
+revision=2
build_style=gnu-configure
hostmakedepends="automake pkg-config gettext-devel tar"
makedepends="ffmpeg-devel libmicrohttpd-devel v4l-utils-devel gettext-devel"
From 32eb49a3aaa1d2865ccadda81db7a4c76cdae901 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:49 -0400
Subject: [PATCH 062/115] mpv: revbump for ffmpeg-6.0
---
srcpkgs/mpv/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/mpv/template b/srcpkgs/mpv/template
index e163c496c6eb..d4fefbf5e3c7 100644
--- a/srcpkgs/mpv/template
+++ b/srcpkgs/mpv/template
@@ -1,7 +1,7 @@
# Template file for 'mpv'
pkgname=mpv
version=0.35.1
-revision=2
+revision=3
build_style=meson
configure_args="-Dcdda=enabled -Ddvbin=enabled -Ddvdnav=enabled
-Dlibmpv=true -Dcplugins=enabled
From 8c9690d2905383ed28e649af2f10e8cd267f07e8 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:49 -0400
Subject: [PATCH 063/115] musikcube: revbump for ffmpeg-6.0
---
srcpkgs/musikcube/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/musikcube/template b/srcpkgs/musikcube/template
index 4b7930041126..7cd65cf76b77 100644
--- a/srcpkgs/musikcube/template
+++ b/srcpkgs/musikcube/template
@@ -1,7 +1,7 @@
# Template file for 'musikcube'
pkgname=musikcube
version=0.99.4
-revision=1
+revision=2
build_style=cmake
make_cmd=make
configure_args="-DNO_NCURSESW=1"
From 2625715963d686174a62465f0bce4257916f0d35 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:49 -0400
Subject: [PATCH 064/115] notcurses: revbump for ffmpeg-6.0
---
srcpkgs/notcurses/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/notcurses/template b/srcpkgs/notcurses/template
index 6dd8a091319f..3110c30c9aff 100644
--- a/srcpkgs/notcurses/template
+++ b/srcpkgs/notcurses/template
@@ -1,7 +1,7 @@
# Template file for 'notcurses'
pkgname=notcurses
version=3.0.9
-revision=1
+revision=2
build_style=cmake
configure_args="-DUSE_STATIC=ON $(vopt_bool man USE_PANDOC)"
hostmakedepends="pkg-config $(vopt_if man pandoc)"
From 664e7bde66882fb5f8c6b0017bde4c2cc2e8c41a Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:49 -0400
Subject: [PATCH 065/115] obs: revbump for ffmpeg-6.0
---
srcpkgs/obs/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/obs/template b/srcpkgs/obs/template
index 89fd11297c3f..3cf49e414bf3 100644
--- a/srcpkgs/obs/template
+++ b/srcpkgs/obs/template
@@ -1,7 +1,7 @@
# Template file for 'obs'
pkgname=obs
version=29.1.0
-revision=1
+revision=2
archs="i686* x86_64* ppc64le* aarch64*"
build_style=cmake
configure_args="-DOBS_VERSION_OVERRIDE=${version} -DENABLE_JACK=ON
From 893fb73b0b047e5fa8e33a0de91bfdb1ef1296bd Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:49 -0400
Subject: [PATCH 066/115] olive: revbump for ffmpeg4-4.4.3
---
srcpkgs/olive/template | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/srcpkgs/olive/template b/srcpkgs/olive/template
index 12a46936c990..5c2917b9c512 100644
--- a/srcpkgs/olive/template
+++ b/srcpkgs/olive/template
@@ -1,10 +1,10 @@
# Template file for 'olive'
pkgname=olive
version=0.1.2
-revision=2
+revision=3
build_style=qmake
hostmakedepends="qt5-qmake qt5-host-tools pkg-config"
-makedepends="qt5-devel qt5-multimedia-devel qt5-svg-devel ffmpeg-devel frei0r-plugins"
+makedepends="qt5-devel qt5-multimedia-devel qt5-svg-devel ffmpeg4-devel frei0r-plugins"
short_desc="Non-linear video editor"
maintainer="Orphaned <orphan@voidlinux.org>"
license="GPL-3.0-or-later"
From de56fe4d55bddaa978c0fe094fc04d242085401c Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:49 -0400
Subject: [PATCH 067/115] omxplayer: revbump for ffmpeg4-4.4.3
---
srcpkgs/omxplayer/template | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/srcpkgs/omxplayer/template b/srcpkgs/omxplayer/template
index e70bf7873d4d..0e9bc70e7c8e 100644
--- a/srcpkgs/omxplayer/template
+++ b/srcpkgs/omxplayer/template
@@ -1,10 +1,10 @@
# Template file for 'omxplayer'
pkgname=omxplayer
version=20190102
-revision=1
+revision=2
short_desc="Commandline OMX player for the Raspberry Pi"
maintainer="Orphaned <orphan@voidlinux.org>"
-license="GPL-2"
+license="GPL-2.0-or-later"
homepage="https://github.com/popcornmix/omxplayer"
_commit="f06235cc9690a6d58187514452df8cf8fcdaacec"
@@ -15,7 +15,7 @@ checksum=af2d9450f8947842ea8c401fe9f71eec444013ebbdee29f2ac828c9c493c1329
archs="armv6l* armv7l*"
build_style=gnu-makefile
hostmakedepends="curl pkg-config"
-makedepends="alsa-lib-devel rpi-userland-devel pcre-devel boost-devel freetype-devel ffmpeg-devel dbus-devel"
+makedepends="alsa-lib-devel rpi-userland-devel pcre-devel boost-devel freetype-devel ffmpeg4-devel dbus-devel"
depends="freefont-ttf"
do_build() {
From ef9f8927d630d02ae1e3c990ee2bbbe3bab6fc5a Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:50 -0400
Subject: [PATCH 068/115] openimageio: revbump for ffmpeg-6.0
---
common/shlibs | 2 ++
srcpkgs/openimageio/template | 2 +-
2 files changed, 3 insertions(+), 1 deletion(-)
diff --git a/common/shlibs b/common/shlibs
index fcc7401be626..5f05896ba1d1 100644
--- a/common/shlibs
+++ b/common/shlibs
@@ -2262,6 +2262,8 @@ libxmp.so.4 libxmp-4.3.7_1
libKF5ThreadWeaver.so.5 threadweaver-5.26.0_1
libOpenImageIO_Util.so.2.4 openimageio-2.4.9.0_1
libOpenImageIO.so.2.4 openimageio-2.4.9.0_1
+libOpenImageIO_Util.so.2.4 openimageio-2.4.8.1_1
+libOpenImageIO.so.2.4 openimageio-2.4.8.1_1
libOpenColorIO.so.2.1 opencolorio-2.1.2_1
libpystring.so.1 pystring-1.1.3_1
libyaml-cpp.so.0.7 yaml-cpp-0.7.0_1
diff --git a/srcpkgs/openimageio/template b/srcpkgs/openimageio/template
index b661bbf7ba57..9b38ace50f7e 100644
--- a/srcpkgs/openimageio/template
+++ b/srcpkgs/openimageio/template
@@ -1,7 +1,7 @@
# Template file for 'openimageio'
pkgname=openimageio
version=2.4.9.0
-revision=2
+revision=3
build_style=cmake
build_helper=qemu
configure_args="-DUSE_QT=0 -DUSE_PYTHON=0 -DOIIO_BUILD_TESTS=0
From 811c70c6496f6ee84ea727e00613131d573c0eb0 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:50 -0400
Subject: [PATCH 069/115] openmw: revbump for ffmpeg-6.0
---
srcpkgs/openmw/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/openmw/template b/srcpkgs/openmw/template
index 5251a0283dc1..e3771c7aaf1a 100644
--- a/srcpkgs/openmw/template
+++ b/srcpkgs/openmw/template
@@ -1,7 +1,7 @@
# Template file for 'openmw'
pkgname=openmw
version=0.47.0
-revision=4
+revision=5
build_style=cmake
_recast_commit=e75adf86f91eb3082220085e42dda62679f9a3ea
_bullet_tag=3.17
From 2f2ba3fcd1c541342e4cc5d0c5d40bd7404ec9a5 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:50 -0400
Subject: [PATCH 070/115] openshot: revbump for ffmpeg-6.0
---
srcpkgs/openshot/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/openshot/template b/srcpkgs/openshot/template
index 322717d40abc..c074e0338773 100644
--- a/srcpkgs/openshot/template
+++ b/srcpkgs/openshot/template
@@ -1,7 +1,7 @@
# Template file for 'openshot'
pkgname=openshot
version=3.0.0
-revision=1
+revision=2
build_style=python3-module
hostmakedepends="python3 python3-setuptools"
makedepends="ffmpeg-devel python3-PyQt5"
From 9488a765692629eddc8944341de8267bc4461b90 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:50 -0400
Subject: [PATCH 071/115] opentoonz: revbump for ffmpeg-6.0
---
srcpkgs/opentoonz/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/opentoonz/template b/srcpkgs/opentoonz/template
index ee9f7603f55f..3e81834ca0ed 100644
--- a/srcpkgs/opentoonz/template
+++ b/srcpkgs/opentoonz/template
@@ -1,7 +1,7 @@
# Template file for 'opentoonz'
pkgname=opentoonz
version=1.6.0
-revision=2
+revision=3
build_wrksrc="toonz/sources"
build_style=cmake
make_cmd=make
From d803d9a848206b9d59967576ef4febbc0d537d58 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:50 -0400
Subject: [PATCH 072/115] pianobar: revbump for ffmpeg-6.0
---
srcpkgs/pianobar/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/pianobar/template b/srcpkgs/pianobar/template
index a9b29e91993f..81efcd122c4d 100644
--- a/srcpkgs/pianobar/template
+++ b/srcpkgs/pianobar/template
@@ -1,7 +1,7 @@
# Template file for 'pianobar'
pkgname=pianobar
version=2022.04.01
-revision=1
+revision=2
build_style=gnu-makefile
make_build_args="V=1"
hostmakedepends="pkg-config"
From ebf95e2d004bd3156ff436d6bea236fd18fdac5f Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:50 -0400
Subject: [PATCH 073/115] ppsspp: revbump for ffmpeg4-4.4.3
---
srcpkgs/ppsspp/template | 7 +++----
1 file changed, 3 insertions(+), 4 deletions(-)
diff --git a/srcpkgs/ppsspp/template b/srcpkgs/ppsspp/template
index 7984a733d4be..15a42fd2c993 100644
--- a/srcpkgs/ppsspp/template
+++ b/srcpkgs/ppsspp/template
@@ -1,7 +1,7 @@
# Template file for 'ppsspp'
pkgname=ppsspp
version=1.14.4
-revision=1
+revision=2
_glslang_commit=dc11adde23c455a24e13dd54de9b4ede8bdd7db8
_SPIRV_Cross_commit=9acb9ec31f5a8ef80ea6b994bb77be787b08d3d1
_armips_commit=6719edebaae03330ee5441d9b28280672edf00d5
@@ -13,7 +13,7 @@ configure_args="-DHEADLESS=1 -DUSE_SYSTEM_FFMPEG=1 -DUNITTEST=ON
-DUSING_QT_UI=$(vopt_if qt ON OFF) -DUSE_SYSTEM_ZSTD=ON
-DARMIPS_USE_STD_FILESYSTEM=ON"
hostmakedepends="pkg-config python3 $(vopt_if qt qt5-host-tools)"
-makedepends="zlib-devel glew-devel ffmpeg-devel libzip-devel
+makedepends="zlib-devel glew-devel ffmpeg4-devel libzip-devel
snappy-devel rapidjson libpng-devel libzstd-devel
$(vopt_if sdl2 SDL2-devel) $(vopt_if wayland wayland-devel)
$(vopt_if qt 'qt5-devel qt5-multimedia-devel')"
@@ -62,13 +62,12 @@ post_extract() {
mv ${wrksrc}/miniupnp-${_miniupnp_commit} ${wrksrc}/ext/miniupnp
}
-post_patch(){
+post_patch() {
# disable git versioning
vsed -e 's|find_package(Git)|# &|' -i git-version.cmake
}
do_install() {
- vlicense LICENSE.TXT
vinstall icons/icon.svg 644 usr/share/pixmaps ppsspp.svg
vinstall Qt/PPSSPP.desktop 644 usr/share/applications
vbin build/PPSSPPHeadless ppsspp-headless
From d9457ef5ad55b755ce49c6f10f5ed721871043cc Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:50 -0400
Subject: [PATCH 074/115] pqiv: revbump for ffmpeg-6.0
---
srcpkgs/pqiv/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/pqiv/template b/srcpkgs/pqiv/template
index 542fc27a2d32..9308d949b6a1 100644
--- a/srcpkgs/pqiv/template
+++ b/srcpkgs/pqiv/template
@@ -1,7 +1,7 @@
# Template file for 'pqiv'
pkgname=pqiv
version=2.12
-revision=1
+revision=2
build_style=gnu-makefile
hostmakedepends="pkg-config"
makedepends="glib-devel gtk+3-devel $(vopt_if ffmpeg ffmpeg-devel)
From 70a28738048f99eea3ea55c412300ad4a7f3baa5 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:50 -0400
Subject: [PATCH 075/115] qmmp: revbump for ffmpeg-6.0
---
srcpkgs/qmmp/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/qmmp/template b/srcpkgs/qmmp/template
index 26c661ed16be..a150d7441c7a 100644
--- a/srcpkgs/qmmp/template
+++ b/srcpkgs/qmmp/template
@@ -1,7 +1,7 @@
# Template file for 'qmmp'
pkgname=qmmp
version=1.6.1
-revision=1
+revision=2
build_style=cmake
configure_args="-DUSE_HAL:BOOL=FALSE -DQMMP_DEFAULT_UI:STRING=simple"
hostmakedepends="pkg-config qt5-host-tools qt5-qmake"
From 7122ecfe1aac0dffb9796d19abb03b5db7b0f121 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:50 -0400
Subject: [PATCH 076/115] qt5-webengine: update to 5.15.13
---
.../chromium-media-filters-cpp14.patch | 11 ++
srcpkgs/qt5-webengine/patches/ffmpeg5.patch | 179 ++++++++++++++++++
srcpkgs/qt5-webengine/template | 10 +-
3 files changed, 195 insertions(+), 5 deletions(-)
create mode 100644 srcpkgs/qt5-webengine/patches/chromium-media-filters-cpp14.patch
create mode 100644 srcpkgs/qt5-webengine/patches/ffmpeg5.patch
diff --git a/srcpkgs/qt5-webengine/patches/chromium-media-filters-cpp14.patch b/srcpkgs/qt5-webengine/patches/chromium-media-filters-cpp14.patch
new file mode 100644
index 000000000000..04adc540f2cb
--- /dev/null
+++ b/srcpkgs/qt5-webengine/patches/chromium-media-filters-cpp14.patch
@@ -0,0 +1,11 @@
+--- a/src/3rdparty/chromium/media/filters/BUILD.gn 2023-02-27 13:32:59.000000000 -0500
++++ b/src/3rdparty/chromium/media/filters/BUILD.gn 2023-04-02 17:21:39.204066384 -0400
+@@ -96,6 +96,8 @@
+ "//ui/gfx/geometry:geometry",
+ ]
+
++ cflags_cc = [ "-std=c++14" ]
++
+ libs = []
+
+ if (proprietary_codecs) {
diff --git a/srcpkgs/qt5-webengine/patches/ffmpeg5.patch b/srcpkgs/qt5-webengine/patches/ffmpeg5.patch
new file mode 100644
index 000000000000..ac55e1634423
--- /dev/null
+++ b/srcpkgs/qt5-webengine/patches/ffmpeg5.patch
@@ -0,0 +1,179 @@
+--- a/src/3rdparty/chromium/media/filters/ffmpeg_demuxer.cc 2023-04-02 16:50:57.732547446 -0400
++++ b/src/3rdparty/chromium/media/filters/ffmpeg_demuxer.cc 2023-04-02 16:50:09.486478995 -0400
+@@ -57,6 +57,8 @@
+
+ namespace {
+
++constexpr int64_t kRelativeTsBase = static_cast<int64_t>(0x7ffeffffffffffff);
++
+ void SetAVStreamDiscard(AVStream* stream, AVDiscard discard) {
+ DCHECK(stream);
+ stream->discard = discard;
+@@ -90,24 +92,12 @@
+
+ static base::TimeDelta ExtractStartTime(AVStream* stream) {
+ // The default start time is zero.
+- base::TimeDelta start_time;
++ base::TimeDelta start_time = kNoTimestamp;
+
+ // First try to use the |start_time| value as is.
+ if (stream->start_time != kNoFFmpegTimestamp)
+ start_time = ConvertFromTimeBase(stream->time_base, stream->start_time);
+
+- // Next try to use the first DTS value, for codecs where we know PTS == DTS
+- // (excludes all H26x codecs). The start time must be returned in PTS.
+- if (stream->first_dts != kNoFFmpegTimestamp &&
+- stream->codecpar->codec_id != AV_CODEC_ID_HEVC &&
+- stream->codecpar->codec_id != AV_CODEC_ID_H264 &&
+- stream->codecpar->codec_id != AV_CODEC_ID_MPEG4) {
+- const base::TimeDelta first_pts =
+- ConvertFromTimeBase(stream->time_base, stream->first_dts);
+- if (first_pts < start_time)
+- start_time = first_pts;
+- }
+-
+ return start_time;
+ }
+
+@@ -408,11 +398,11 @@
+ scoped_refptr<DecoderBuffer> buffer;
+
+ if (type() == DemuxerStream::TEXT) {
+- int id_size = 0;
++ size_t id_size = 0;
+ uint8_t* id_data = av_packet_get_side_data(
+ packet.get(), AV_PKT_DATA_WEBVTT_IDENTIFIER, &id_size);
+
+- int settings_size = 0;
++ size_t settings_size = 0;
+ uint8_t* settings_data = av_packet_get_side_data(
+ packet.get(), AV_PKT_DATA_WEBVTT_SETTINGS, &settings_size);
+
+@@ -424,7 +414,7 @@
+ buffer = DecoderBuffer::CopyFrom(packet->data, packet->size,
+ side_data.data(), side_data.size());
+ } else {
+- int side_data_size = 0;
++ size_t side_data_size = 0;
+ uint8_t* side_data = av_packet_get_side_data(
+ packet.get(), AV_PKT_DATA_MATROSKA_BLOCKADDITIONAL, &side_data_size);
+
+@@ -485,7 +475,7 @@
+ packet->size - data_offset);
+ }
+
+- int skip_samples_size = 0;
++ size_t skip_samples_size = 0;
+ const uint32_t* skip_samples_ptr =
+ reinterpret_cast<const uint32_t*>(av_packet_get_side_data(
+ packet.get(), AV_PKT_DATA_SKIP_SAMPLES, &skip_samples_size));
+@@ -1587,6 +1577,8 @@
+ for (const auto& stream : streams_) {
+ if (!stream || stream->IsEnabled() != enabled)
+ continue;
++ if (stream->av_stream()->start_time == AV_NOPTS_VALUE)
++ continue;
+ if (!lowest_start_time_stream ||
+ stream->start_time() < lowest_start_time_stream->start_time()) {
+ lowest_start_time_stream = stream.get();
+@@ -1604,6 +1596,8 @@
+ if (stream && stream->type() == DemuxerStream::VIDEO &&
+ stream->IsEnabled()) {
+ video_stream = stream.get();
++ if (stream->av_stream()->start_time == AV_NOPTS_VALUE)
++ continue;
+ if (video_stream->start_time() <= seek_time) {
+ return video_stream;
+ }
+diff -Naurp qtwebengine-5.15.10.orig/src/3rdparty/chromium/media/ffmpeg/ffmpeg_common.h qtwebengine-5.15.10/src/3rdparty/chromium/media/ffmpeg/ffmpeg_common.h
+--- a/src/3rdparty/chromium/media/ffmpeg/ffmpeg_common.h 2022-05-23 06:38:40.000000000 -0500
++++ b/src/3rdparty/chromium/media/ffmpeg/ffmpeg_common.h 2022-07-11 22:12:47.917192788 -0500
+@@ -29,6 +29,7 @@ extern "C" {
+ #include <libavformat/avformat.h>
+ #include <libavformat/avio.h>
+ #include <libavutil/avutil.h>
++#include <libavutil/channel_layout.h>
+ #include <libavutil/imgutils.h>
+ #include <libavutil/log.h>
+ #include <libavutil/mastering_display_metadata.h>
+diff -Naurp qtwebengine-5.15.10.orig/src/3rdparty/chromium/media/filters/audio_file_reader.cc qtwebengine-5.15.10/src/3rdparty/chromium/media/filters/audio_file_reader.cc
+--- a/src/3rdparty/chromium/media/filters/audio_file_reader.cc 2022-05-23 06:38:40.000000000 -0500
++++ b/src/3rdparty/chromium/media/filters/audio_file_reader.cc 2022-07-11 22:12:47.917192788 -0500
+@@ -85,7 +85,7 @@ bool AudioFileReader::OpenDemuxer() {
+ }
+
+ bool AudioFileReader::OpenDecoder() {
+- AVCodec* codec = avcodec_find_decoder(codec_context_->codec_id);
++ const AVCodec* codec = avcodec_find_decoder(codec_context_->codec_id);
+ if (codec) {
+ // MP3 decodes to S16P which we don't support, tell it to use S16 instead.
+ if (codec_context_->sample_fmt == AV_SAMPLE_FMT_S16P)
+diff -Naurp qtwebengine-5.15.10.orig/src/3rdparty/chromium/media/filters/ffmpeg_audio_decoder.cc qtwebengine-5.15.10/src/3rdparty/chromium/media/filters/ffmpeg_audio_decoder.cc
+--- a/src/3rdparty/chromium/media/filters/ffmpeg_audio_decoder.cc 2022-05-23 06:38:40.000000000 -0500
++++ b/src/3rdparty/chromium/media/filters/ffmpeg_audio_decoder.cc 2022-07-11 22:12:47.917192788 -0500
+@@ -329,7 +329,7 @@ bool FFmpegAudioDecoder::ConfigureDecode
+ }
+ }
+
+- AVCodec* codec = avcodec_find_decoder(codec_context_->codec_id);
++ const AVCodec* codec = avcodec_find_decoder(codec_context_->codec_id);
+ if (!codec ||
+ avcodec_open2(codec_context_.get(), codec, &codec_options) < 0) {
+ DLOG(ERROR) << "Could not initialize audio decoder: "
+diff -Naurp qtwebengine-5.15.10.orig/src/3rdparty/chromium/media/filters/ffmpeg_glue.cc qtwebengine-5.15.10/src/3rdparty/chromium/media/filters/ffmpeg_glue.cc
+--- a/src/3rdparty/chromium/media/filters/ffmpeg_glue.cc 2022-05-23 06:38:40.000000000 -0500
++++ b/src/3rdparty/chromium/media/filters/ffmpeg_glue.cc 2022-07-11 22:12:47.918192779 -0500
+@@ -59,7 +59,6 @@ static int64_t AVIOSeekOperation(void* o
+ }
+
+ void FFmpegGlue::InitializeFFmpeg() {
+- av_register_all();
+ }
+
+ static void LogContainer(bool is_local_file,
+@@ -95,9 +94,6 @@ FFmpegGlue::FFmpegGlue(FFmpegURLProtocol
+ // Enable fast, but inaccurate seeks for MP3.
+ format_context_->flags |= AVFMT_FLAG_FAST_SEEK;
+
+- // Ensures we can read out various metadata bits like vp8 alpha.
+- format_context_->flags |= AVFMT_FLAG_KEEP_SIDE_DATA;
+-
+ // Ensures format parsing errors will bail out. From an audit on 11/2017, all
+ // instances were real failures. Solves bugs like http://crbug.com/710791.
+ format_context_->error_recognition |= AV_EF_EXPLODE;
+diff -Naurp qtwebengine-5.15.10.orig/src/3rdparty/chromium/media/filters/ffmpeg_video_decoder.cc qtwebengine-5.15.10/src/3rdparty/chromium/media/filters/ffmpeg_video_decoder.cc
+--- a/src/3rdparty/chromium/media/filters/ffmpeg_video_decoder.cc 2022-05-23 06:38:40.000000000 -0500
++++ b/src/3rdparty/chromium/media/filters/ffmpeg_video_decoder.cc 2022-07-11 22:12:47.918192779 -0500
+@@ -391,7 +391,7 @@ bool FFmpegVideoDecoder::ConfigureDecode
+ if (decode_nalus_)
+ codec_context_->flags2 |= AV_CODEC_FLAG2_CHUNKS;
+
+- AVCodec* codec = avcodec_find_decoder(codec_context_->codec_id);
++ const AVCodec* codec = avcodec_find_decoder(codec_context_->codec_id);
+ if (!codec || avcodec_open2(codec_context_.get(), codec, NULL) < 0) {
+ ReleaseFFmpegResources();
+ return false;
+diff -Naurp qtwebengine-5.15.10.orig/src/3rdparty/chromium/media/filters/media_file_checker.cc qtwebengine-5.15.10/src/3rdparty/chromium/media/filters/media_file_checker.cc
+--- a/src/3rdparty/chromium/media/filters/media_file_checker.cc 2022-05-23 06:38:40.000000000 -0500
++++ b/src/3rdparty/chromium/media/filters/media_file_checker.cc 2022-07-11 22:12:47.918192779 -0500
+@@ -68,7 +68,7 @@ bool MediaFileChecker::Start(base::TimeD
+ auto context = AVStreamToAVCodecContext(format_context->streams[i]);
+ if (!context)
+ continue;
+- AVCodec* codec = avcodec_find_decoder(cp->codec_id);
++ const AVCodec* codec = avcodec_find_decoder(cp->codec_id);
+ if (codec && avcodec_open2(context.get(), codec, nullptr) >= 0) {
+ auto loop = std::make_unique<FFmpegDecodingLoop>(context.get());
+ stream_contexts[i] = {std::move(context), std::move(loop)};
+diff -Naurp qtwebengine-5.15.10.orig/src/3rdparty/chromium/third_party/webrtc/modules/video_coding/codecs/h264/h264_decoder_impl.cc qtwebengine-5.15.10/src/3rdparty/chromium/third_party/webrtc/modules/video_coding/codecs/h264/h264_decoder_impl.cc
+--- a/src/3rdparty/chromium/third_party/webrtc/modules/video_coding/codecs/h264/h264_decoder_impl.cc 2022-05-23 06:38:40.000000000 -0500
++++ b/src/3rdparty/chromium/third_party/webrtc/modules/video_coding/codecs/h264/h264_decoder_impl.cc 2022-07-11 22:12:47.918192779 -0500
+@@ -203,7 +203,7 @@ int32_t H264DecoderImpl::InitDecode(cons
+ // a pointer |this|.
+ av_context_->opaque = this;
+
+- AVCodec* codec = avcodec_find_decoder(av_context_->codec_id);
++ const AVCodec* codec = avcodec_find_decoder(av_context_->codec_id);
+ if (!codec) {
+ // This is an indication that FFmpeg has not been initialized or it has not
+ // been compiled/initialized with the correct set of codecs.
diff --git a/srcpkgs/qt5-webengine/template b/srcpkgs/qt5-webengine/template
index 0a71484208bc..095ab67701e4 100644
--- a/srcpkgs/qt5-webengine/template
+++ b/srcpkgs/qt5-webengine/template
@@ -1,9 +1,9 @@
# Template file for 'qt5-webengine'
pkgname=qt5-webengine
-version=5.15.11
-revision=2
+version=5.15.13
+revision=1
_version="${version}-lts"
-_chromium_commit=be349eaf62e77955791d7bf29f893f1e8a37daf4
+_chromium_commit=e48df7803c7c98b0b2471c94057d32e44a301ad5
archs="x86_64* i686* armv[67]* ppc64* aarch64*"
create_wrksrc=yes
build_style=qmake
@@ -32,8 +32,8 @@ license="GPL-3.0-or-later, LGPL-3.0-or-later"
homepage="https://qt.io/"
distfiles="https://github.com/qt/qtwebengine/archive/v${_version}.tar.gz
https://github.com/qt/qtwebengine-chromium/archive/${_chromium_commit}.tar.gz"
-checksum="aa7466356c450c5f5870f979b93cd7e7e62da1165c328ffcab1a9928db18ad67
- 6f47ed8ab8cc062411f6f206da6353bc8263d6ed6d6290c689a05c01d91f646b"
+checksum="4b59838ed75ef788b59e1e412535a0e42dd9d311661fdeadb191b581ba815c63
+ a91686562b1d4e8b220e0bbcbab5feb64630e2de974b35ac034bf388af771a6c"
no_generic_pkgconfig_link=yes
build_options="sndio pipewire"
From 9b9ff4e130db5e70ce55e050939c607a779408f5 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:51 -0400
Subject: [PATCH 077/115] qt5: update to 5.15.8
---
...erywhere-opensource-src-5.15.8-kf5-1.patch | 12913 ++++++++++++++++
srcpkgs/qt5/template | 12 +-
2 files changed, 12919 insertions(+), 6 deletions(-)
create mode 100644 srcpkgs/qt5/patches/qt-everywhere-opensource-src-5.15.8-kf5-1.patch
diff --git a/srcpkgs/qt5/patches/qt-everywhere-opensource-src-5.15.8-kf5-1.patch b/srcpkgs/qt5/patches/qt-everywhere-opensource-src-5.15.8-kf5-1.patch
new file mode 100644
index 000000000000..966c98bcd3bb
--- /dev/null
+++ b/srcpkgs/qt5/patches/qt-everywhere-opensource-src-5.15.8-kf5-1.patch
@@ -0,0 +1,12913 @@
+Submitted By: Pierre Labastie <pierre_dot_labastie_at_neuf_dot_fr>
+Date: 2023-01-05
+Initial Package Version: 5.15.8
+Upstream Status: Applied (according to KDE)
+Origin: KDE patch set
+Description: Patch set maintained by the KDE folks
+see https://dot.kde.org/2021/04/06/announcing-kdes-qt-5-patch-collection
+Patch generated using the procedure in
+https://wiki.linuxfromscratch.org/blfs/ticket/17476#comment:3
+
+Submodule qtbase 4ee4fc18..9cf586d6:
+diff --git a/qtbase/mkspecs/common/android/qplatformdefs.h b/qtbase/mkspecs/common/android/qplatformdefs.h
+index f75bc4093b..2bd59410d4 100644
+--- a/qtbase/mkspecs/common/android/qplatformdefs.h
++++ b/qtbase/mkspecs/common/android/qplatformdefs.h
+@@ -144,11 +144,7 @@
+ #define QT_SIGNAL_ARGS int
+ #define QT_SIGNAL_IGNORE SIG_IGN
+
+-#if defined(__GLIBC__) && (__GLIBC__ >= 2)
+ #define QT_SOCKLEN_T socklen_t
+-#else
+-#define QT_SOCKLEN_T int
+-#endif
+
+ #if defined(_XOPEN_SOURCE) && (_XOPEN_SOURCE >= 500)
+ #define QT_SNPRINTF ::snprintf
+diff --git a/qtbase/mkspecs/features/mac/sdk.mk b/qtbase/mkspecs/features/mac/sdk.mk
+index f30b5830b4..a32ceacb6c 100644
+--- a/qtbase/mkspecs/features/mac/sdk.mk
++++ b/qtbase/mkspecs/features/mac/sdk.mk
+@@ -1,6 +1,6 @@
+
+ ifeq ($(QT_MAC_SDK_NO_VERSION_CHECK),)
+- CHECK_SDK_COMMAND = /usr/bin/xcrun --sdk $(EXPORT_QMAKE_MAC_SDK) -show-sdk-version 2>&1
++ CHECK_SDK_COMMAND = /usr/bin/xcrun --sdk $(EXPORT_QMAKE_MAC_SDK) -show-sdk-version 2>/dev/null
+ CURRENT_MAC_SDK_VERSION := $(shell DEVELOPER_DIR=$(EXPORT_QMAKE_XCODE_DEVELOPER_PATH) $(CHECK_SDK_COMMAND))
+ ifneq ($(CURRENT_MAC_SDK_VERSION),$(EXPORT_QMAKE_MAC_SDK_VERSION))
+ # We don't want to complain about out of date SDK unless the target needs to be remade.
+diff --git a/qtbase/mkspecs/linux-clang/qplatformdefs.h b/qtbase/mkspecs/linux-clang/qplatformdefs.h
+index a818d973f0..c1ab72fbc6 100644
+--- a/qtbase/mkspecs/linux-clang/qplatformdefs.h
++++ b/qtbase/mkspecs/linux-clang/qplatformdefs.h
+@@ -79,14 +79,6 @@
+ #define QT_USE_XOPEN_LFS_EXTENSIONS
+ #include "../common/posix/qplatformdefs.h"
+
+-#undef QT_SOCKLEN_T
+-
+-#if defined(__GLIBC__) && (__GLIBC__ >= 2)
+-#define QT_SOCKLEN_T socklen_t
+-#else
+-#define QT_SOCKLEN_T int
+-#endif
+-
+ #if defined(_XOPEN_SOURCE) && (_XOPEN_SOURCE >= 500)
+ #define QT_SNPRINTF ::snprintf
+ #define QT_VSNPRINTF ::vsnprintf
+diff --git a/qtbase/mkspecs/linux-g++/qplatformdefs.h b/qtbase/mkspecs/linux-g++/qplatformdefs.h
+index 13523f0702..4d2750d9ec 100644
+--- a/qtbase/mkspecs/linux-g++/qplatformdefs.h
++++ b/qtbase/mkspecs/linux-g++/qplatformdefs.h
+@@ -79,14 +79,6 @@
+ #define QT_USE_XOPEN_LFS_EXTENSIONS
+ #include "../common/posix/qplatformdefs.h"
+
+-#undef QT_SOCKLEN_T
+-
+-#if defined(__GLIBC__) && (__GLIBC__ < 2)
+-#define QT_SOCKLEN_T int
+-#else
+-#define QT_SOCKLEN_T socklen_t
+-#endif
+-
+ #if defined(_XOPEN_SOURCE) && (_XOPEN_SOURCE >= 500)
+ #define QT_SNPRINTF ::snprintf
+ #define QT_VSNPRINTF ::vsnprintf
+diff --git a/qtbase/mkspecs/linux-llvm/qplatformdefs.h b/qtbase/mkspecs/linux-llvm/qplatformdefs.h
+index dc750ab1ef..d3cc39b47f 100644
+--- a/qtbase/mkspecs/linux-llvm/qplatformdefs.h
++++ b/qtbase/mkspecs/linux-llvm/qplatformdefs.h
+@@ -80,14 +80,6 @@
+ #define QT_USE_XOPEN_LFS_EXTENSIONS
+ #include "../common/posix/qplatformdefs.h"
+
+-#undef QT_SOCKLEN_T
+-
+-#if defined(__GLIBC__) && (__GLIBC__ >= 2)
+-#define QT_SOCKLEN_T socklen_t
+-#else
+-#define QT_SOCKLEN_T int
+-#endif
+-
+ #if defined(_XOPEN_SOURCE) && (_XOPEN_SOURCE >= 500)
+ #define QT_SNPRINTF ::snprintf
+ #define QT_VSNPRINTF ::vsnprintf
+diff --git a/qtbase/mkspecs/linux-lsb-g++/qplatformdefs.h b/qtbase/mkspecs/linux-lsb-g++/qplatformdefs.h
+index 4c4e53da2a..83baffb3e3 100644
+--- a/qtbase/mkspecs/linux-lsb-g++/qplatformdefs.h
++++ b/qtbase/mkspecs/linux-lsb-g++/qplatformdefs.h
+@@ -85,16 +85,9 @@
+ #include "../common/posix/qplatformdefs.h"
+
+ #undef QT_OPEN_LARGEFILE
+-#undef QT_SOCKLEN_T
+
+ #define QT_OPEN_LARGEFILE 0
+
+-#if defined(__GLIBC__) && (__GLIBC__ >= 2)
+-#define QT_SOCKLEN_T socklen_t
+-#else
+-#define QT_SOCKLEN_T int
+-#endif
+-
+ #ifndef SIOCGIFBRDADDR
+ # define SIOCGIFBRDADDR 0x8919
+ #endif
+diff --git a/qtbase/mkspecs/lynxos-g++/qplatformdefs.h b/qtbase/mkspecs/lynxos-g++/qplatformdefs.h
+index 4339ea2b23..6007af0055 100644
+--- a/qtbase/mkspecs/lynxos-g++/qplatformdefs.h
++++ b/qtbase/mkspecs/lynxos-g++/qplatformdefs.h
+@@ -72,14 +72,6 @@
+
+ #include "../common/posix/qplatformdefs.h"
+
+-#undef QT_SOCKLEN_T
+-
+-#if defined(__GLIBC__) && (__GLIBC__ >= 2)
+-#define QT_SOCKLEN_T socklen_t
+-#else
+-#define QT_SOCKLEN_T int
+-#endif
+-
+ #if defined(_XOPEN_SOURCE) && (_XOPEN_SOURCE >= 500)
+ #define QT_SNPRINTF ::snprintf
+ #define QT_VSNPRINTF ::vsnprintf
+diff --git a/qtbase/src/3rdparty/angle/src/libANGLE/HandleAllocator.cpp b/qtbase/src/3rdparty/angle/src/libANGLE/HandleAllocator.cpp
+index c3c184258f..32af3f8f29 100644
+--- a/qtbase/src/3rdparty/angle/src/libANGLE/HandleAllocator.cpp
++++ b/qtbase/src/3rdparty/angle/src/libANGLE/HandleAllocator.cpp
+@@ -10,6 +10,7 @@
+ #include "libANGLE/HandleAllocator.h"
+
+ #include <algorithm>
++#include <limits>
+
+ #include "common/debug.h"
+
+diff --git a/qtbase/src/3rdparty/forkfd/forkfd_linux.c b/qtbase/src/3rdparty/forkfd/forkfd_linux.c
+index ffe0e9a5e2..b1f5408d11 100644
+--- a/qtbase/src/3rdparty/forkfd/forkfd_linux.c
++++ b/qtbase/src/3rdparty/forkfd/forkfd_linux.c
+@@ -82,7 +82,8 @@ static int sys_clone(unsigned long cloneflags, int *ptid)
+ return syscall(__NR_clone, cloneflags, child_stack, stack_size, ptid, newtls, ctid);
+ #elif defined(__arc__) || defined(__arm__) || defined(__aarch64__) || defined(__mips__) || \
+ defined(__nds32__) || defined(__hppa__) || defined(__powerpc__) || defined(__i386__) || \
+- defined(__x86_64__) || defined(__xtensa__) || defined(__alpha__) || defined(__riscv)
++ defined(__x86_64__) || defined(__xtensa__) || defined(__alpha__) || defined(__riscv) || \
++ defined(__loongarch__)
+ /* ctid and newtls are inverted on CONFIG_CLONE_BACKWARDS architectures,
+ * but since both values are 0, there's no harm. */
+ return syscall(__NR_clone, cloneflags, child_stack, ptid, ctid, newtls);
+diff --git a/qtbase/src/android/jar/src/org/qtproject/qt5/android/QtNative.java b/qtbase/src/android/jar/src/org/qtproject/qt5/android/QtNative.java
+index 5792b5b2f5..2f74750fcf 100644
+--- a/qtbase/src/android/jar/src/org/qtproject/qt5/android/QtNative.java
++++ b/qtbase/src/android/jar/src/org/qtproject/qt5/android/QtNative.java
+@@ -116,6 +116,7 @@ public class QtNative
+ public static QtThread m_qtThread = new QtThread();
+ private static HashMap<String, Uri> m_cachedUris = new HashMap<String, Uri>();
+ private static ArrayList<String> m_knownDirs = new ArrayList<String>();
++ private static final String NoPermissionErrorMessage = "No permissions to open Uri";
+
+ private static final Runnable runPendingCppRunnablesRunnable = new Runnable() {
+ @Override
+@@ -193,11 +194,10 @@ public class QtNative
+ return iterUri;
+ }
+
+- // Android 6 and earlier could still manage to open the file so we can return the
+- // parsed uri here
+- if (Build.VERSION.SDK_INT < 24)
+- return parsedUri;
+- return null;
++ // if we only have transient permissions on uri all the above will fail,
++ // but we will be able to read the file anyway, so continue with uri here anyway
++ // and check for SecurityExceptions later
++ return parsedUri;
+ } catch (SecurityException e) {
+ e.printStackTrace();
+ return null;
+@@ -244,7 +244,7 @@ public class QtNative
+ int error = -1;
+
+ if (uri == null) {
+- Log.e(QtTAG, "openFdForContentUrl(): No permissions to open Uri");
++ Log.e(QtTAG, "openFdForContentUrl(): " + NoPermissionErrorMessage);
+ return error;
+ }
+
+@@ -254,12 +254,13 @@ public class QtNative
+ return fdDesc.detachFd();
+ } catch (FileNotFoundException e) {
+ e.printStackTrace();
+- return error;
+ } catch (IllegalArgumentException e) {
+ Log.e(QtTAG, "openFdForContentUrl(): Invalid Uri");
+ e.printStackTrace();
+- return error;
++ } catch (SecurityException e) {
++ Log.e(QtTAG, NoPermissionErrorMessage);
+ }
++ return error;
+ }
+
+ public static long getSize(Context context, String contentUrl)
+@@ -270,7 +271,7 @@ public class QtNative
+ uri = getUriWithValidPermission(context, contentUrl, "r");
+
+ if (uri == null) {
+- Log.e(QtTAG, "getSize(): No permissions to open Uri");
++ Log.e(QtTAG, NoPermissionErrorMessage);
+ return size;
+ } else if (!m_cachedUris.containsKey(contentUrl)) {
+ m_cachedUris.put(contentUrl, uri);
+@@ -288,12 +289,13 @@ public class QtNative
+ } catch (IllegalArgumentException e) {
+ Log.e(QtTAG, "getSize(): Invalid Uri");
+ e.printStackTrace();
+- return size;
+ } catch (UnsupportedOperationException e) {
+ Log.e(QtTAG, "getSize(): Unsupported operation for given Uri");
+ e.printStackTrace();
+- return size;
++ } catch (SecurityException e) {
++ Log.e(QtTAG, NoPermissionErrorMessage);
+ }
++ return size;
+ }
+
+ public static boolean checkFileExists(Context context, String contentUrl)
+@@ -303,7 +305,7 @@ public class QtNative
+ if (uri == null)
+ uri = getUriWithValidPermission(context, contentUrl, "r");
+ if (uri == null) {
+- Log.e(QtTAG, "checkFileExists(): No permissions to open Uri");
++ Log.e(QtTAG, NoPermissionErrorMessage);
+ return exists;
+ } else {
+ if (!m_cachedUris.containsKey(contentUrl))
+@@ -321,12 +323,13 @@ public class QtNative
+ } catch (IllegalArgumentException e) {
+ Log.e(QtTAG, "checkFileExists(): Invalid Uri");
+ e.printStackTrace();
+- return exists;
+ } catch (UnsupportedOperationException e) {
+ Log.e(QtTAG, "checkFileExists(): Unsupported operation for given Uri");
+ e.printStackTrace();
+- return false;
++ } catch (SecurityException e) {
++ Log.e(QtTAG, NoPermissionErrorMessage);
+ }
++ return exists;
+ }
+
+ public static boolean checkIfWritable(Context context, String contentUrl)
+@@ -344,7 +347,7 @@ public class QtNative
+ uri = getUriWithValidPermission(context, contentUrl, "r");
+ }
+ if (uri == null) {
+- Log.e(QtTAG, "isDir(): No permissions to open Uri");
++ Log.e(QtTAG, NoPermissionErrorMessage);
+ return isDir;
+ } else {
+ if (!m_cachedUris.containsKey(contentUrl))
+@@ -374,12 +377,13 @@ public class QtNative
+ } catch (IllegalArgumentException e) {
+ Log.e(QtTAG, "checkIfDir(): Invalid Uri");
+ e.printStackTrace();
+- return false;
+ } catch (UnsupportedOperationException e) {
+ Log.e(QtTAG, "checkIfDir(): Unsupported operation for given Uri");
+ e.printStackTrace();
+- return false;
++ } catch (SecurityException e) {
++ Log.e(QtTAG, NoPermissionErrorMessage);
+ }
++ return false;
+ }
+ public static String[] listContentsFromTreeUri(Context context, String contentUrl)
+ {
+diff --git a/qtbase/src/concurrent/qtconcurrentreducekernel.h b/qtbase/src/concurrent/qtconcurrentreducekernel.h
+index 8f9a938952..a98dedef2e 100644
+--- a/qtbase/src/concurrent/qtconcurrentreducekernel.h
++++ b/qtbase/src/concurrent/qtconcurrentreducekernel.h
+@@ -212,11 +212,13 @@ public:
+
+ inline bool shouldThrottle()
+ {
++ std::lock_guard<QMutex> locker(mutex);
+ return (resultsMapSize > (ReduceQueueThrottleLimit * threadCount));
+ }
+
+ inline bool shouldStartThread()
+ {
++ std::lock_guard<QMutex> locker(mutex);
+ return (resultsMapSize <= (ReduceQueueStartLimit * threadCount));
+ }
+ };
+diff --git a/qtbase/src/concurrent/qtconcurrentthreadengine.cpp b/qtbase/src/concurrent/qtconcurrentthreadengine.cpp
+index ea6ce3ac42..7f91a2ba68 100644
+--- a/qtbase/src/concurrent/qtconcurrentthreadengine.cpp
++++ b/qtbase/src/concurrent/qtconcurrentthreadengine.cpp
+@@ -176,6 +176,39 @@ void ThreadEngineBase::startSingleThreaded()
+ finish();
+ }
+
++void ThreadEngineBase::startBlocking()
++{
++ start();
++ barrier.acquire();
++ startThreads();
++
++ bool throttled = false;
++#ifndef QT_NO_EXCEPTIONS
++ try {
++#endif
++ while (threadFunction() == ThrottleThread) {
++ if (threadThrottleExit()) {
++ throttled = true;
++ break;
++ }
++ }
++#ifndef QT_NO_EXCEPTIONS
++ } catch (QException &e) {
++ handleException(e);
++ } catch (...) {
++ handleException(QUnhandledException());
++ }
++#endif
++
++ if (throttled == false) {
++ barrier.release();
++ }
++
++ barrier.wait();
++ finish();
++ exceptionStore.throwPossibleException();
++}
++
+ void ThreadEngineBase::startThread()
+ {
+ startThreadInternal();
+diff --git a/qtbase/src/concurrent/qtconcurrentthreadengine.h b/qtbase/src/concurrent/qtconcurrentthreadengine.h
+index 7c30cebdbc..a4c8548cc4 100644
+--- a/qtbase/src/concurrent/qtconcurrentthreadengine.h
++++ b/qtbase/src/concurrent/qtconcurrentthreadengine.h
+@@ -91,6 +91,7 @@ public:
+ ThreadEngineBase();
+ virtual ~ThreadEngineBase();
+ void startSingleThreaded();
++ void startBlocking();
+ void startThread();
+ bool isCanceled();
+ void waitForResume();
+@@ -143,6 +144,15 @@ public:
+ return result();
+ }
+
++ // Runs the user algorithm using multiple threads.
++ // This function blocks until the algorithm is finished,
++ // and then returns the result.
++ T *startBlocking()
++ {
++ ThreadEngineBase::startBlocking();
++ return result();
++ }
++
+ // Runs the user algorithm using multiple threads.
+ // Does not block, returns a future.
+ QFuture<T> startAsynchronously()
+@@ -223,6 +233,13 @@ class ThreadEngineStarter : public ThreadEngineStarterBase<T>
+ public:
+ ThreadEngineStarter(TypedThreadEngine *eng)
+ : Base(eng) { }
++
++ T startBlocking()
++ {
++ T t = *this->threadEngine->startBlocking();
++ delete this->threadEngine;
++ return t;
++ }
+ };
+
+ // Full template specialization where T is void.
+@@ -232,6 +249,12 @@ class ThreadEngineStarter<void> : public ThreadEngineStarterBase<void>
+ public:
+ ThreadEngineStarter(ThreadEngine<void> *_threadEngine)
+ : ThreadEngineStarterBase<void>(_threadEngine) {}
++
++ void startBlocking()
++ {
++ this->threadEngine->startBlocking();
++ delete this->threadEngine;
++ }
+ };
+
+ //! [qtconcurrentthreadengine-1]
+diff --git a/qtbase/src/corelib/animation/qvariantanimation.cpp b/qtbase/src/corelib/animation/qvariantanimation.cpp
+index 98b02f0202..eac1524107 100644
+--- a/qtbase/src/corelib/animation/qvariantanimation.cpp
++++ b/qtbase/src/corelib/animation/qvariantanimation.cpp
+@@ -276,7 +276,9 @@ void QVariantAnimationPrivate::setCurrentValueForProgress(const qreal progress)
+
+ const qreal startProgress = currentInterval.start.first;
+ const qreal endProgress = currentInterval.end.first;
+- const qreal localProgress = (progress - startProgress) / (endProgress - startProgress);
++ const qreal localProgress =
++ qIsNull(progress - startProgress) ? 0.0 // avoid 0/0 below
++ /* else */ : (progress - startProgress) / (endProgress - startProgress);
+
+ QVariant ret = q->interpolated(currentInterval.start.second,
+ currentInterval.end.second,
+diff --git a/qtbase/src/corelib/global/qnamespace.h b/qtbase/src/corelib/global/qnamespace.h
+index ad4150b317..bf19b1627b 100644
+--- a/qtbase/src/corelib/global/qnamespace.h
++++ b/qtbase/src/corelib/global/qnamespace.h
+@@ -1864,7 +1864,7 @@ public:
+ QT_Q_ENUM(TimerType)
+ QT_Q_ENUM(ScrollPhase)
+ QT_Q_ENUM(MouseEventSource)
+- QT_Q_FLAG(MouseEventFlag)
++ QT_Q_FLAG(MouseEventFlags)
+ QT_Q_ENUM(ChecksumType)
+ QT_Q_ENUM(HighDpiScaleFactorRoundingPolicy)
+ QT_Q_ENUM(TabFocusBehavior)
+diff --git a/qtbase/src/corelib/global/qrandom.cpp b/qtbase/src/corelib/global/qrandom.cpp
+index 10672c1f92..25f87c7e6a 100644
+--- a/qtbase/src/corelib/global/qrandom.cpp
++++ b/qtbase/src/corelib/global/qrandom.cpp
+@@ -383,7 +383,6 @@ struct QRandomGenerator::SystemAndGlobalGenerators
+
+ constexpr SystemAndGlobalGenerators g = {};
+ Q_UNUSED(g);
+- Q_STATIC_ASSERT(std::is_literal_type<SystemAndGlobalGenerators>::value);
+ #endif
+ }
+
+diff --git a/qtbase/src/corelib/io/qbuffer.cpp b/qtbase/src/corelib/io/qbuffer.cpp
+index 595fcd2724..032c0ddd4b 100644
+--- a/qtbase/src/corelib/io/qbuffer.cpp
++++ b/qtbase/src/corelib/io/qbuffer.cpp
+@@ -41,6 +41,8 @@
+ #include <QtCore/qmetaobject.h>
+ #include "private/qiodevice_p.h"
+
++#include <limits>
++
+ QT_BEGIN_NAMESPACE
+
+ /** QBufferPrivate **/
+@@ -366,7 +368,9 @@ qint64 QBuffer::size() const
+ bool QBuffer::seek(qint64 pos)
+ {
+ Q_D(QBuffer);
+- if (pos > d->buf->size() && isWritable()) {
++ const auto oldBufSize = d->buf->size();
++ constexpr qint64 MaxSeekPos = (std::numeric_limits<decltype(oldBufSize)>::max)();
++ if (pos <= MaxSeekPos && pos > oldBufSize && isWritable()) {
+ if (seek(d->buf->size())) {
+ const qint64 gapSize = pos - d->buf->size();
+ if (write(QByteArray(gapSize, 0)) != gapSize) {
+@@ -377,7 +381,7 @@ bool QBuffer::seek(qint64 pos)
+ return false;
+ }
+ } else if (pos > d->buf->size() || pos < 0) {
+- qWarning("QBuffer::seek: Invalid pos: %d", int(pos));
++ qWarning("QBuffer::seek: Invalid pos: %lld", pos);
+ return false;
+ }
+ return QIODevice::seek(pos);
+diff --git a/qtbase/src/corelib/io/qfilesystemengine_win.cpp b/qtbase/src/corelib/io/qfilesystemengine_win.cpp
+index 81d3a71986..c86ed1f9b0 100644
+--- a/qtbase/src/corelib/io/qfilesystemengine_win.cpp
++++ b/qtbase/src/corelib/io/qfilesystemengine_win.cpp
+@@ -664,14 +664,14 @@ QFileSystemEntry QFileSystemEngine::absoluteName(const QFileSystemEntry &entry)
+ return QFileSystemEntry(ret, QFileSystemEntry::FromInternalPath());
+ }
+
+-#if defined(Q_CC_MINGW) && WINVER < 0x0602 // Windows 8 onwards
++#if defined(Q_CC_MINGW) && WINVER < 0x0602 && _WIN32_WINNT < _WIN32_WINNT_WIN8 // Windows 8 onwards
+
+ typedef struct _FILE_ID_INFO {
+ ULONGLONG VolumeSerialNumber;
+ FILE_ID_128 FileId;
+ } FILE_ID_INFO, *PFILE_ID_INFO;
+
+-#endif // if defined (Q_CC_MINGW) && WINVER < 0x0602
++#endif // if defined(Q_CC_MINGW) && WINVER < 0x0602 && _WIN32_WINNT < _WIN32_WINNT_WIN8
+
+ // File ID for Windows up to version 7 and FAT32 drives
+ static inline QByteArray fileId(HANDLE handle)
+diff --git a/qtbase/src/corelib/io/qfilesystemwatcher_inotify.cpp b/qtbase/src/corelib/io/qfilesystemwatcher_inotify.cpp
+index 94d9d06bcb..27e0b13b0b 100644
+--- a/qtbase/src/corelib/io/qfilesystemwatcher_inotify.cpp
++++ b/qtbase/src/corelib/io/qfilesystemwatcher_inotify.cpp
+@@ -366,7 +366,9 @@ void QInotifyFileSystemWatcherEngine::readFromInotify()
+ // qDebug("QInotifyFileSystemWatcherEngine::readFromInotify");
+
+ int buffSize = 0;
+- ioctl(inotifyFd, FIONREAD, (char *) &buffSize);
++ if (ioctl(inotifyFd, FIONREAD, (char *) &buffSize) == -1 || buffSize == 0)
++ return;
++
+ QVarLengthArray<char, 4096> buffer(buffSize);
+ buffSize = read(inotifyFd, buffer.data(), buffSize);
+ char *at = buffer.data();
+diff --git a/qtbase/src/corelib/io/qlockfile_win.cpp b/qtbase/src/corelib/io/qlockfile_win.cpp
+index 277f8d4230..38ecef5550 100644
+--- a/qtbase/src/corelib/io/qlockfile_win.cpp
++++ b/qtbase/src/corelib/io/qlockfile_win.cpp
+@@ -48,6 +48,8 @@
+ #include "QtCore/qdebug.h"
+ #include "QtCore/qthread.h"
+
++#include "private/qsystemlibrary_p.h"
++
+ QT_BEGIN_NAMESPACE
+
+ static inline bool fileExists(const wchar_t *fileName)
+@@ -150,7 +152,7 @@ QString QLockFilePrivate::processNameByPid(qint64 pid)
+ #if !defined(Q_OS_WINRT)
+ typedef DWORD (WINAPI *GetModuleFileNameExFunc)(HANDLE, HMODULE, LPTSTR, DWORD);
+
+- HMODULE hPsapi = LoadLibraryA("psapi");
++ HMODULE hPsapi = QSystemLibrary::load(L"psapi");
+ if (!hPsapi)
+ return QString();
+ GetModuleFileNameExFunc qGetModuleFileNameEx = reinterpret_cast<GetModuleFileNameExFunc>(
+diff --git a/qtbase/src/corelib/io/qprocess_unix.cpp b/qtbase/src/corelib/io/qprocess_unix.cpp
+index 50390e57f5..15c8f30745 100644
+--- a/qtbase/src/corelib/io/qprocess_unix.cpp
++++ b/qtbase/src/corelib/io/qprocess_unix.cpp
+@@ -1,7 +1,7 @@
+ /****************************************************************************
+ **
+ ** Copyright (C) 2016 The Qt Company Ltd.
+-** Copyright (C) 2016 Intel Corporation.
++** Copyright (C) 2022 Intel Corporation.
+ ** Contact: https://www.qt.io/licensing/
+ **
+ ** This file is part of the QtCore module of the Qt Toolkit.
+@@ -422,14 +422,15 @@ void QProcessPrivate::startProcess()
+ // Add the program name to the argument list.
+ argv[0] = nullptr;
+ if (!program.contains(QLatin1Char('/'))) {
++ // findExecutable() returns its argument if it's an absolute path,
++ // otherwise it searches $PATH; returns empty if not found (we handle
++ // that case much later)
+ const QString &exeFilePath = QStandardPaths::findExecutable(program);
+- if (!exeFilePath.isEmpty()) {
+- const QByteArray &tmp = QFile::encodeName(exeFilePath);
+- argv[0] = ::strdup(tmp.constData());
+- }
+- }
+- if (!argv[0])
++ const QByteArray &tmp = QFile::encodeName(exeFilePath);
++ argv[0] = ::strdup(tmp.constData());
++ } else {
+ argv[0] = ::strdup(encodedProgramName.constData());
++ }
+
+ // Add every argument to the list
+ for (int i = 0; i < arguments.count(); ++i)
+@@ -983,15 +984,16 @@ bool QProcessPrivate::startDetached(qint64 *pid)
+ envp = _q_dupEnvironment(environment.d.constData()->vars, &envc);
+ }
+
+- QByteArray tmp;
+ if (!program.contains(QLatin1Char('/'))) {
++ // findExecutable() returns its argument if it's an absolute path,
++ // otherwise it searches $PATH; returns empty if not found (we handle
++ // that case much later)
+ const QString &exeFilePath = QStandardPaths::findExecutable(program);
+- if (!exeFilePath.isEmpty())
+- tmp = QFile::encodeName(exeFilePath);
++ const QByteArray &tmp = QFile::encodeName(exeFilePath);
++ argv[0] = ::strdup(tmp.constData());
++ } else {
++ argv[0] = ::strdup(QFile::encodeName(program));
+ }
+- if (tmp.isEmpty())
+- tmp = QFile::encodeName(program);
+- argv[0] = tmp.data();
+
+ if (envp)
+ qt_safe_execve(argv[0], argv, envp);
+diff --git a/qtbase/src/corelib/itemmodels/qabstractitemmodel.cpp b/qtbase/src/corelib/itemmodels/qabstractitemmodel.cpp
+index 3a79c502af..997a634e76 100644
+--- a/qtbase/src/corelib/itemmodels/qabstractitemmodel.cpp
++++ b/qtbase/src/corelib/itemmodels/qabstractitemmodel.cpp
+@@ -3196,9 +3196,8 @@ bool QAbstractItemModel::beginMoveColumns(const QModelIndex &sourceParent, int s
+ destinationChange.needsAdjust = destinationParent.isValid() && destinationParent.row() >= sourceLast && destinationParent.parent() == sourceParent;
+ d->changes.push(destinationChange);
+
+- d->itemsAboutToBeMoved(sourceParent, sourceFirst, sourceLast, destinationParent, destinationChild, Qt::Horizontal);
+-
+ emit columnsAboutToBeMoved(sourceParent, sourceFirst, sourceLast, destinationParent, destinationChild, QPrivateSignal());
++ d->itemsAboutToBeMoved(sourceParent, sourceFirst, sourceLast, destinationParent, destinationChild, Qt::Horizontal);
+ return true;
+ }
+
+@@ -3231,7 +3230,6 @@ void QAbstractItemModel::endMoveColumns()
+ adjustedSource = createIndex(adjustedSource.row(), adjustedSource.column() + numMoved, adjustedSource.internalPointer());
+
+ d->itemsMoved(adjustedSource, removeChange.first, removeChange.last, adjustedDestination, insertChange.first, Qt::Horizontal);
+-
+ emit columnsMoved(adjustedSource, removeChange.first, removeChange.last, adjustedDestination, insertChange.first, QPrivateSignal());
+ }
+
+diff --git a/qtbase/src/corelib/itemmodels/qsortfilterproxymodel.cpp b/qtbase/src/corelib/itemmodels/qsortfilterproxymodel.cpp
+index dc6379d9fb..c5e287ee84 100644
+--- a/qtbase/src/corelib/itemmodels/qsortfilterproxymodel.cpp
++++ b/qtbase/src/corelib/itemmodels/qsortfilterproxymodel.cpp
+@@ -939,8 +939,9 @@ void QSortFilterProxyModelPrivate::insert_source_items(
+ q->beginInsertColumns(proxy_parent, proxy_start, proxy_end);
+ }
+
+- for (int i = 0; i < source_items.size(); ++i)
+- proxy_to_source.insert(proxy_start + i, source_items.at(i));
++ // TODO: use the range QList::insert() overload once it is implemented (QTBUG-58633).
++ proxy_to_source.insert(proxy_start, source_items.size(), 0);
++ std::copy(source_items.cbegin(), source_items.cend(), proxy_to_source.begin() + proxy_start);
+
+ build_source_to_proxy_mapping(proxy_to_source, source_to_proxy);
+
+@@ -3123,8 +3124,9 @@ bool QSortFilterProxyModel::filterAcceptsRow(int source_row, const QModelIndex &
+
+ if (d->filter_data.isEmpty())
+ return true;
++
++ int column_count = d->model->columnCount(source_parent);
+ if (d->filter_column == -1) {
+- int column_count = d->model->columnCount(source_parent);
+ for (int column = 0; column < column_count; ++column) {
+ QModelIndex source_index = d->model->index(source_row, column, source_parent);
+ QString key = d->model->data(source_index, d->filter_role).toString();
+@@ -3133,9 +3135,10 @@ bool QSortFilterProxyModel::filterAcceptsRow(int source_row, const QModelIndex &
+ }
+ return false;
+ }
+- QModelIndex source_index = d->model->index(source_row, d->filter_column, source_parent);
+- if (!source_index.isValid()) // the column may not exist
++
++ if (d->filter_column >= column_count) // the column may not exist
+ return true;
++ QModelIndex source_index = d->model->index(source_row, d->filter_column, source_parent);
+ QString key = d->model->data(source_index, d->filter_role).toString();
+ return d->filter_data.hasMatch(key);
+ }
+diff --git a/qtbase/src/corelib/kernel/qcoreapplication.cpp b/qtbase/src/corelib/kernel/qcoreapplication.cpp
+index ca2864df83..132b2eae52 100644
+--- a/qtbase/src/corelib/kernel/qcoreapplication.cpp
++++ b/qtbase/src/corelib/kernel/qcoreapplication.cpp
+@@ -1157,7 +1157,7 @@ static bool doNotify(QObject *receiver, QEvent *event)
+ bool QCoreApplicationPrivate::sendThroughApplicationEventFilters(QObject *receiver, QEvent *event)
+ {
+ // We can't access the application event filters outside of the main thread (race conditions)
+- Q_ASSERT(receiver->d_func()->threadData.loadRelaxed()->thread.loadAcquire() == mainThread());
++ Q_ASSERT(receiver->d_func()->threadData.loadAcquire()->thread.loadRelaxed() == mainThread());
+
+ if (extraData) {
+ // application event filters are only called for objects in the GUI thread
+diff --git a/qtbase/src/corelib/kernel/qobject.cpp b/qtbase/src/corelib/kernel/qobject.cpp
+index 1eb79138d9..36cd780ee1 100644
+--- a/qtbase/src/corelib/kernel/qobject.cpp
++++ b/qtbase/src/corelib/kernel/qobject.cpp
+@@ -1010,7 +1010,7 @@ QObject::~QObject()
+ emit destroyed(this);
+ }
+
+- if (d->declarativeData) {
++ if (!d->isDeletingChildren && d->declarativeData) {
+ if (static_cast<QAbstractDeclarativeDataImpl*>(d->declarativeData)->ownedByQml1) {
+ if (QAbstractDeclarativeData::destroyed_qml1)
+ QAbstractDeclarativeData::destroyed_qml1(d->declarativeData, this);
+@@ -1580,7 +1580,7 @@ void QObject::moveToThread(QThread *targetThread)
+
+ QThreadData *currentData = QThreadData::current();
+ QThreadData *targetData = targetThread ? QThreadData::get2(targetThread) : nullptr;
+- QThreadData *thisThreadData = d->threadData.loadRelaxed();
++ QThreadData *thisThreadData = d->threadData.loadAcquire();
+ if (!thisThreadData->thread.loadAcquire() && currentData == targetData) {
+ // one exception to the rule: we allow moving objects with no thread affinity to the current thread
+ currentData = d->threadData;
+@@ -2620,7 +2620,7 @@ int QObject::receivers(const char *signal) const
+ if (!d->isSignalConnected(signal_index))
+ return receivers;
+
+- if (d->declarativeData && QAbstractDeclarativeData::receivers) {
++ if (!d->isDeletingChildren && d->declarativeData && QAbstractDeclarativeData::receivers) {
+ receivers += QAbstractDeclarativeData::receivers(d->declarativeData, this,
+ signal_index);
+ }
+diff --git a/qtbase/src/corelib/kernel/qobject_p.h b/qtbase/src/corelib/kernel/qobject_p.h
+index 0b827a52ca..13ffb88999 100644
+--- a/qtbase/src/corelib/kernel/qobject_p.h
++++ b/qtbase/src/corelib/kernel/qobject_p.h
+@@ -444,7 +444,7 @@ inline void QObjectPrivate::checkForIncompatibleLibraryVersion(int version) cons
+
+ inline bool QObjectPrivate::isDeclarativeSignalConnected(uint signal_index) const
+ {
+- return declarativeData && QAbstractDeclarativeData::isSignalConnected
++ return !isDeletingChildren && declarativeData && QAbstractDeclarativeData::isSignalConnected
+ && QAbstractDeclarativeData::isSignalConnected(declarativeData, q_func(), signal_index);
+ }
+
+diff --git a/qtbase/src/corelib/kernel/qtranslator.cpp b/qtbase/src/corelib/kernel/qtranslator.cpp
+index 2812ffb7ea..bc0177c5ec 100644
+--- a/qtbase/src/corelib/kernel/qtranslator.cpp
++++ b/qtbase/src/corelib/kernel/qtranslator.cpp
+@@ -902,7 +902,7 @@ static QString getMessage(const uchar *m, const uchar *end, const char *context,
+ goto end;
+ case Tag_Translation: {
+ int len = read32(m);
+- if (len % 1)
++ if (len & 1)
+ return QString();
+ m += 4;
+ if (!numerus--) {
+diff --git a/qtbase/src/corelib/mimetypes/qmimedatabase.cpp b/qtbase/src/corelib/mimetypes/qmimedatabase.cpp
+index 9de22cef33..ff868a3268 100644
+--- a/qtbase/src/corelib/mimetypes/qmimedatabase.cpp
++++ b/qtbase/src/corelib/mimetypes/qmimedatabase.cpp
+@@ -389,20 +389,23 @@ QMimeType QMimeDatabasePrivate::mimeTypeForFileNameAndData(const QString &fileNa
+ // Disambiguate conflicting extensions (if magic matching found something)
+ if (candidateByData.isValid() && magicAccuracy > 0) {
+ const QString sniffedMime = candidateByData.name();
+- // If the sniffedMime matches a glob match, use it
++ // If the sniffedMime matches a highest-weight glob match, use it
+ if (candidatesByName.m_matchingMimeTypes.contains(sniffedMime)) {
+ *accuracyPtr = 100;
+ return candidateByData;
+ }
+- for (const QString &m : qAsConst(candidatesByName.m_matchingMimeTypes)) {
++ for (const QString &m : qAsConst(candidatesByName.m_allMatchingMimeTypes)) {
+ if (inherits(m, sniffedMime)) {
+ // We have magic + pattern pointing to this, so it's a pretty good match
+ *accuracyPtr = 100;
+ return mimeTypeForName(m);
+ }
+ }
+- *accuracyPtr = magicAccuracy;
+- return candidateByData;
++ if (candidatesByName.m_allMatchingMimeTypes.isEmpty()) {
++ // No glob, use magic
++ *accuracyPtr = magicAccuracy;
++ return candidateByData;
++ }
+ }
+ }
+
+diff --git a/qtbase/src/corelib/mimetypes/qmimeglobpattern.cpp b/qtbase/src/corelib/mimetypes/qmimeglobpattern.cpp
+index a81112d227..fa8f4c545d 100644
+--- a/qtbase/src/corelib/mimetypes/qmimeglobpattern.cpp
++++ b/qtbase/src/corelib/mimetypes/qmimeglobpattern.cpp
+@@ -83,7 +83,10 @@ void QMimeGlobMatchResult::addMatch(const QString &mimeType, int weight, const Q
+ }
+ if (!m_matchingMimeTypes.contains(mimeType)) {
+ m_matchingMimeTypes.append(mimeType);
+- m_allMatchingMimeTypes.append(mimeType);
++ if (replace)
++ m_allMatchingMimeTypes.prepend(mimeType); // highest-weight first
++ else
++ m_allMatchingMimeTypes.append(mimeType);
+ m_knownSuffixLength = knownSuffixLength;
+ }
+ }
+@@ -94,7 +97,7 @@ QMimeGlobPattern::PatternType QMimeGlobPattern::detectPatternType(const QString
+ if (!patternLength)
+ return OtherPattern;
+
+- const bool starCount = pattern.count(QLatin1Char('*')) == 1;
++ const int starCount = pattern.count(QLatin1Char('*'));
+ const bool hasSquareBracket = pattern.indexOf(QLatin1Char('[')) != -1;
+ const bool hasQuestionMark = pattern.indexOf(QLatin1Char('?')) != -1;
+
+@@ -106,10 +109,10 @@ QMimeGlobPattern::PatternType QMimeGlobPattern::detectPatternType(const QString
+ // Patterns like "README*" (well this is currently the only one like that...)
+ if (pattern.at(patternLength - 1) == QLatin1Char('*'))
+ return PrefixPattern;
+- }
+- // Names without any wildcards like "README"
+- if (starCount == 0)
++ } else if (starCount == 0) {
++ // Names without any wildcards like "README"
+ return LiteralPattern;
++ }
+ }
+
+ if (pattern == QLatin1String("[0-9][0-9][0-9].vdr"))
+diff --git a/qtbase/src/corelib/mimetypes/qmimeprovider.cpp b/qtbase/src/corelib/mimetypes/qmimeprovider.cpp
+index 258dddf8cb..4642d0f2d0 100644
+--- a/qtbase/src/corelib/mimetypes/qmimeprovider.cpp
++++ b/qtbase/src/corelib/mimetypes/qmimeprovider.cpp
+@@ -244,15 +244,18 @@ void QMimeBinaryProvider::addFileNameMatches(const QString &fileName, QMimeGlobM
+ const QString lowerFileName = fileName.toLower();
+ // Check literals (e.g. "Makefile")
+ matchGlobList(result, m_cacheFile, m_cacheFile->getUint32(PosLiteralListOffset), fileName);
+- // Check complex globs (e.g. "callgrind.out[0-9]*")
+- matchGlobList(result, m_cacheFile, m_cacheFile->getUint32(PosGlobListOffset), fileName);
+ // Check the very common *.txt cases with the suffix tree
+- const int reverseSuffixTreeOffset = m_cacheFile->getUint32(PosReverseSuffixTreeOffset);
+- const int numRoots = m_cacheFile->getUint32(reverseSuffixTreeOffset);
+- const int firstRootOffset = m_cacheFile->getUint32(reverseSuffixTreeOffset + 4);
+- matchSuffixTree(result, m_cacheFile, numRoots, firstRootOffset, lowerFileName, lowerFileName.length() - 1, false);
++ if (result.m_matchingMimeTypes.isEmpty()) {
++ const int reverseSuffixTreeOffset = m_cacheFile->getUint32(PosReverseSuffixTreeOffset);
++ const int numRoots = m_cacheFile->getUint32(reverseSuffixTreeOffset);
++ const int firstRootOffset = m_cacheFile->getUint32(reverseSuffixTreeOffset + 4);
++ matchSuffixTree(result, m_cacheFile, numRoots, firstRootOffset, lowerFileName, lowerFileName.length() - 1, false);
++ if (result.m_matchingMimeTypes.isEmpty())
++ matchSuffixTree(result, m_cacheFile, numRoots, firstRootOffset, fileName, fileName.length() - 1, true);
++ }
++ // Check complex globs (e.g. "callgrind.out[0-9]*" or "README*")
+ if (result.m_matchingMimeTypes.isEmpty())
+- matchSuffixTree(result, m_cacheFile, numRoots, firstRootOffset, fileName, fileName.length() - 1, true);
++ matchGlobList(result, m_cacheFile, m_cacheFile->getUint32(PosGlobListOffset), fileName);
+ }
+
+ void QMimeBinaryProvider::matchGlobList(QMimeGlobMatchResult &result, CacheFile *cacheFile, int off, const QString &fileName)
+diff --git a/qtbase/src/corelib/serialization/qjsonparser.cpp b/qtbase/src/corelib/serialization/qjsonparser.cpp
+index 17e6f111ab..2e40b6c8fb 100644
+--- a/qtbase/src/corelib/serialization/qjsonparser.cpp
++++ b/qtbase/src/corelib/serialization/qjsonparser.cpp
+@@ -379,10 +379,30 @@ error:
+ return QCborValue();
+ }
+
++// We need to retain the _last_ value for any duplicate keys and we need to deref containers.
++// Therefore the manual implementation of std::unique().
++template<typename Iterator, typename Compare, typename Assign>
++static Iterator customAssigningUniqueLast(Iterator first, Iterator last,
++ Compare compare, Assign assign)
++{
++ first = std::adjacent_find(first, last, compare);
++ if (first == last)
++ return last;
++
++ Iterator result = first;
++ while (++first != last) {
++ if (!compare(*result, *first))
++ ++result;
++ if (result != first)
++ assign(*result, *first);
++ }
++
++ return ++result;
++}
++
+ static void sortContainer(QCborContainerPrivate *container)
+ {
+ using Forward = QJsonPrivate::KeyIterator;
+- using Reverse = std::reverse_iterator<Forward>;
+ using Value = Forward::value_type;
+
+ auto compare = [container](const Value &a, const Value &b)
+@@ -420,17 +440,31 @@ static void sortContainer(QCborContainerPrivate *container)
+ }
+ };
+
+- std::sort(Forward(container->elements.begin()), Forward(container->elements.end()),
+- [&compare](const Value &a, const Value &b) { return compare(a, b) < 0; });
++ // The elements' containers are owned by the outer container, not by the elements themselves.
++ auto move = [](Forward::reference target, Forward::reference source)
++ {
++ QtCbor::Element &targetValue = target.value();
++
++ // If the target has a container, deref it before overwriting, so that we don't leak.
++ if (targetValue.flags & QtCbor::Element::IsContainer)
++ targetValue.container->deref();
++
++ // Do not move, so that we can clear the value afterwards.
++ target = source;
++
++ // Clear the source value, so that we don't store the same container twice.
++ source.value() = QtCbor::Element();
++ };
++
++ std::stable_sort(
++ Forward(container->elements.begin()), Forward(container->elements.end()),
++ [&compare](const Value &a, const Value &b) { return compare(a, b) < 0; });
+
+- // We need to retain the _last_ value for any duplicate keys. Therefore the reverse dance here.
+- auto it = std::unique(Reverse(container->elements.end()), Reverse(container->elements.begin()),
+- [&compare](const Value &a, const Value &b) {
+- return compare(a, b) == 0;
+- }).base().elementsIterator();
++ Forward result = customAssigningUniqueLast(
++ Forward(container->elements.begin()), Forward(container->elements.end()),
++ [&compare](const Value &a, const Value &b) { return compare(a, b) == 0; }, move);
+
+- // The erase from beginning is expensive but hopefully rare.
+- container->elements.erase(container->elements.begin(), it);
++ container->elements.erase(result.elementsIterator(), container->elements.end());
+ }
+
+
+diff --git a/qtbase/src/corelib/serialization/qxmlstream.cpp b/qtbase/src/corelib/serialization/qxmlstream.cpp
+index b2f846544d..7cd457ba3a 100644
+--- a/qtbase/src/corelib/serialization/qxmlstream.cpp
++++ b/qtbase/src/corelib/serialization/qxmlstream.cpp
+@@ -980,7 +980,7 @@ inline uint QXmlStreamReaderPrivate::peekChar()
+ bool QXmlStreamReaderPrivate::scanUntil(const char *str, short tokenToInject)
+ {
+ int pos = textBuffer.size();
+- int oldLineNumber = lineNumber;
++ const auto oldLineNumber = lineNumber;
+
+ uint c;
+ while ((c = getChar()) != StreamEOF) {
+diff --git a/qtbase/src/corelib/text/qstring.cpp b/qtbase/src/corelib/text/qstring.cpp
+index 3e88ab4859..8deeae47bb 100644
+--- a/qtbase/src/corelib/text/qstring.cpp
++++ b/qtbase/src/corelib/text/qstring.cpp
+@@ -12312,7 +12312,7 @@ static qsizetype qLastIndexOf(Haystack haystack0, qsizetype from,
+ const auto needle = needle0.data();
+ const auto *end = haystack;
+ haystack += from;
+- const std::size_t sl_minus_1 = sl - 1;
++ const std::size_t sl_minus_1 = sl ? sl - 1 : 0;
+ const auto *n = needle + sl_minus_1;
+ const auto *h = haystack + sl_minus_1;
+ std::size_t hashNeedle = 0, hashHaystack = 0;
+diff --git a/qtbase/src/corelib/text/qstringiterator_p.h b/qtbase/src/corelib/text/qstringiterator_p.h
+index 219589b6e4..1d0c66cc78 100644
+--- a/qtbase/src/corelib/text/qstringiterator_p.h
++++ b/qtbase/src/corelib/text/qstringiterator_p.h
+@@ -61,6 +61,8 @@ class QStringIterator
+ {
+ QString::const_iterator i, pos, e;
+ Q_STATIC_ASSERT((std::is_same<QString::const_iterator, const QChar *>::value));
++ static bool less(const QChar *lhs, const QChar *rhs) noexcept
++ { return std::less<QString::const_iterator>{}(lhs, rhs); }
+ public:
+ explicit QStringIterator(QStringView string, qsizetype idx = 0)
+ : i(string.begin()),
+@@ -95,7 +97,8 @@ public:
+
+ inline void setPosition(QString::const_iterator position)
+ {
+- Q_ASSERT_X(i <= position && position <= e, Q_FUNC_INFO, "position out of bounds");
++ Q_ASSERT_X(!less(position, i) && !less(e, position),
++ Q_FUNC_INFO, "position out of bounds");
+ pos = position;
+ }
+
+@@ -103,7 +106,7 @@ public:
+
+ inline bool hasNext() const
+ {
+- return pos < e;
++ return less(pos, e);
+ }
+
+ inline void advance()
+@@ -120,16 +123,20 @@ public:
+ {
+ Q_ASSERT_X(hasNext(), Q_FUNC_INFO, "iterator hasn't a next item");
+
+- if (Q_UNLIKELY((pos++)->isHighSurrogate()))
++ if (Q_UNLIKELY((pos++)->isHighSurrogate())) {
++ Q_ASSERT(hasNext() && pos->isLowSurrogate());
+ ++pos;
++ }
+ }
+
+ inline uint peekNextUnchecked() const
+ {
+ Q_ASSERT_X(hasNext(), Q_FUNC_INFO, "iterator hasn't a next item");
+
+- if (Q_UNLIKELY(pos->isHighSurrogate()))
++ if (Q_UNLIKELY(pos->isHighSurrogate())) {
++ Q_ASSERT(less(pos + 1, e) && pos[1].isLowSurrogate());
+ return QChar::surrogateToUcs4(pos[0], pos[1]);
++ }
+
+ return pos->unicode();
+ }
+@@ -155,8 +162,10 @@ public:
+ Q_ASSERT_X(hasNext(), Q_FUNC_INFO, "iterator hasn't a next item");
+
+ const QChar cur = *pos++;
+- if (Q_UNLIKELY(cur.isHighSurrogate()))
++ if (Q_UNLIKELY(cur.isHighSurrogate())) {
++ Q_ASSERT(hasNext() && pos->isLowSurrogate());
+ return QChar::surrogateToUcs4(cur, *pos++);
++ }
+ return cur.unicode();
+ }
+
+@@ -166,7 +175,7 @@ public:
+
+ const QChar uc = *pos++;
+ if (Q_UNLIKELY(uc.isSurrogate())) {
+- if (Q_LIKELY(uc.isHighSurrogate() && pos < e && pos->isLowSurrogate()))
++ if (Q_LIKELY(uc.isHighSurrogate() && hasNext() && pos->isLowSurrogate()))
+ return QChar::surrogateToUcs4(uc, *pos++);
+ return invalidAs;
+ }
+@@ -178,7 +187,7 @@ public:
+
+ inline bool hasPrevious() const
+ {
+- return pos > i;
++ return less(i, pos);
+ }
+
+ inline void recede()
+@@ -196,16 +205,20 @@ public:
+ {
+ Q_ASSERT_X(hasPrevious(), Q_FUNC_INFO, "iterator hasn't a previous item");
+
+- if (Q_UNLIKELY((--pos)->isLowSurrogate()))
++ if (Q_UNLIKELY((--pos)->isLowSurrogate())) {
++ Q_ASSERT(hasPrevious() && pos[-1].isHighSurrogate());
+ --pos;
++ }
+ }
+
+ inline uint peekPreviousUnchecked() const
+ {
+ Q_ASSERT_X(hasPrevious(), Q_FUNC_INFO, "iterator hasn't a previous item");
+
+- if (Q_UNLIKELY(pos[-1].isLowSurrogate()))
++ if (Q_UNLIKELY(pos[-1].isLowSurrogate())) {
++ Q_ASSERT(less(i + 1, pos) && pos[-2].isHighSurrogate());
+ return QChar::surrogateToUcs4(pos[-2], pos[-1]);
++ }
+ return pos[-1].unicode();
+ }
+
+@@ -230,8 +243,10 @@ public:
+ Q_ASSERT_X(hasPrevious(), Q_FUNC_INFO, "iterator hasn't a previous item");
+
+ const QChar cur = *--pos;
+- if (Q_UNLIKELY(cur.isLowSurrogate()))
++ if (Q_UNLIKELY(cur.isLowSurrogate())) {
++ Q_ASSERT(hasPrevious() && pos[-1].isHighSurrogate());
+ return QChar::surrogateToUcs4(*--pos, cur);
++ }
+ return cur.unicode();
+ }
+
+@@ -241,7 +256,7 @@ public:
+
+ const QChar uc = *--pos;
+ if (Q_UNLIKELY(uc.isSurrogate())) {
+- if (Q_LIKELY(uc.isLowSurrogate() && pos > i && pos[-1].isHighSurrogate()))
++ if (Q_LIKELY(uc.isLowSurrogate() && hasPrevious() && pos[-1].isHighSurrogate()))
+ return QChar::surrogateToUcs4(*--pos, uc);
+ return invalidAs;
+ }
+diff --git a/qtbase/src/corelib/thread/qfutex_p.h b/qtbase/src/corelib/thread/qfutex_p.h
+index f287b752d7..e294537787 100644
+--- a/qtbase/src/corelib/thread/qfutex_p.h
++++ b/qtbase/src/corelib/thread/qfutex_p.h
+@@ -52,6 +52,7 @@
+ //
+
+ #include <qglobal.h>
++#include <QtCore/qtsan_impl.h>
+
+ QT_BEGIN_NAMESPACE
+
+@@ -106,16 +107,13 @@ namespace QtLinuxFutex {
+ inline int _q_futex(int *addr, int op, int val, quintptr val2 = 0,
+ int *addr2 = nullptr, int val3 = 0) noexcept
+ {
+- // A futex call ensures total ordering on the futex words
+- // (in either success or failure of the call). Instruct TSAN accordingly,
+- // as TSAN does not understand the futex(2) syscall.
+- _q_tsan_release(addr, addr2);
++ QtTsan::futexRelease(addr, addr2);
+
+ // we use __NR_futex because some libcs (like Android's bionic) don't
+ // provide SYS_futex etc.
+ int result = syscall(__NR_futex, addr, op | FUTEX_PRIVATE_FLAG, val, val2, addr2, val3);
+
+- _q_tsan_acquire(addr, addr2);
++ QtTsan::futexAcquire(addr, addr2);
+
+ return result;
+ }
+diff --git a/qtbase/src/corelib/thread/qmutex.cpp b/qtbase/src/corelib/thread/qmutex.cpp
+index 310d1cb14f..7097122d8e 100644
+--- a/qtbase/src/corelib/thread/qmutex.cpp
++++ b/qtbase/src/corelib/thread/qmutex.cpp
+@@ -152,6 +152,7 @@ public:
+
+ /*!
+ \enum QMutex::RecursionMode
++ \obsolete Use QRecursiveMutex to create a recursive mutex.
+
+ \value Recursive In this mode, a thread can lock the same mutex
+ multiple times and the mutex won't be unlocked
+@@ -173,6 +174,7 @@ public:
+
+ /*!
+ Constructs a new mutex. The mutex is created in an unlocked state.
++ \obsolete Use QRecursiveMutex to create a recursive mutex.
+
+ If \a mode is QMutex::Recursive, a thread can lock the same mutex
+ multiple times and the mutex won't be unlocked until a
+@@ -197,7 +199,7 @@ QMutex::QMutex(RecursionMode mode)
+ QMutex::~QMutex()
+ {
+ QMutexData *d = d_ptr.loadRelaxed();
+- if (isRecursive()) {
++ if (QBasicMutex::isRecursive()) {
+ delete static_cast<QRecursiveMutexPrivate *>(d);
+ } else if (d) {
+ #ifndef QT_LINUX_FUTEX
+diff --git a/qtbase/src/corelib/thread/qmutex.h b/qtbase/src/corelib/thread/qmutex.h
+index 73c9e00663..1bae573a03 100644
+--- a/qtbase/src/corelib/thread/qmutex.h
++++ b/qtbase/src/corelib/thread/qmutex.h
+@@ -42,6 +42,7 @@
+
+ #include <QtCore/qglobal.h>
+ #include <QtCore/qatomic.h>
++#include <QtCore/qtsan_impl.h>
+ #include <new>
+
+ #if __has_include(<chrono>)
+@@ -77,19 +78,37 @@ public:
+
+ // BasicLockable concept
+ inline void lock() QT_MUTEX_LOCK_NOEXCEPT {
++ QtTsan::mutexPreLock(this, 0u);
++
+ if (!fastTryLock())
+ lockInternal();
++
++ QtTsan::mutexPostLock(this, 0u, 0);
+ }
+
+ // BasicLockable concept
+ inline void unlock() noexcept {
+ Q_ASSERT(d_ptr.loadRelaxed()); //mutex must be locked
++
++ QtTsan::mutexPreUnlock(this, 0u);
++
+ if (!fastTryUnlock())
+ unlockInternal();
++
++ QtTsan::mutexPostUnlock(this, 0u);
+ }
+
+ bool tryLock() noexcept {
+- return fastTryLock();
++ unsigned tsanFlags = QtTsan::TryLock;
++ QtTsan::mutexPreLock(this, tsanFlags);
++
++ const bool success = fastTryLock();
++
++ if (!success)
++ tsanFlags |= QtTsan::TryLockFailed;
++ QtTsan::mutexPostLock(this, tsanFlags, 0);
++
++ return success;
+ }
+
+ // Lockable concept
+@@ -134,8 +153,16 @@ public:
+ #else
+ QMutex() { d_ptr.storeRelaxed(nullptr); }
+ #endif
++#if QT_DEPRECATED_SINCE(5,15)
+ enum RecursionMode { NonRecursive, Recursive };
++ QT_DEPRECATED_VERSION_X(5, 15, "Use QRecursiveMutex instead of a recursive QMutex")
+ explicit QMutex(RecursionMode mode);
++
++ QT_DEPRECATED_VERSION_X(5, 15, "Use QRecursiveMutex instead of a recursive QMutex")
++ bool isRecursive() const noexcept
++ { return QBasicMutex::isRecursive(); }
++#endif
++
+ ~QMutex();
+
+ // BasicLockable concept
+@@ -166,9 +193,6 @@ public:
+ }
+ #endif
+
+- bool isRecursive() const noexcept
+- { return QBasicMutex::isRecursive(); }
+-
+ private:
+ Q_DISABLE_COPY(QMutex)
+ friend class QMutexLocker;
+diff --git a/qtbase/src/corelib/thread/qreadwritelock.cpp b/qtbase/src/corelib/thread/qreadwritelock.cpp
+index 8c28507d5a..9dd8503116 100644
+--- a/qtbase/src/corelib/thread/qreadwritelock.cpp
++++ b/qtbase/src/corelib/thread/qreadwritelock.cpp
+@@ -155,7 +155,7 @@ QReadWriteLock::QReadWriteLock(RecursionMode recursionMode)
+ */
+ QReadWriteLock::~QReadWriteLock()
+ {
+- auto d = d_ptr.loadRelaxed();
++ auto d = d_ptr.loadAcquire();
+ if (isUncontendedLocked(d)) {
+ qWarning("QReadWriteLock: destroying locked QReadWriteLock");
+ return;
+@@ -445,7 +445,7 @@ void QReadWriteLock::unlock()
+ /*! \internal Helper for QWaitCondition::wait */
+ QReadWriteLock::StateForWaitCondition QReadWriteLock::stateForWaitCondition() const
+ {
+- QReadWriteLockPrivate *d = d_ptr.loadRelaxed();
++ QReadWriteLockPrivate *d = d_ptr.loadAcquire();
+ switch (quintptr(d) & StateMask) {
+ case StateLockedForRead: return LockedForRead;
+ case StateLockedForWrite: return LockedForWrite;
+@@ -453,6 +453,7 @@ QReadWriteLock::StateForWaitCondition QReadWriteLock::stateForWaitCondition() co
+
+ if (!d)
+ return Unlocked;
++ const auto lock = qt_scoped_lock(d->mutex);
+ if (d->writerCount > 1)
+ return RecursivelyLocked;
+ else if (d->writerCount == 1)
+diff --git a/qtbase/src/corelib/thread/qsemaphore.cpp b/qtbase/src/corelib/thread/qsemaphore.cpp
+index 1d01fc1b28..3ecdee3747 100644
+--- a/qtbase/src/corelib/thread/qsemaphore.cpp
++++ b/qtbase/src/corelib/thread/qsemaphore.cpp
+@@ -354,7 +354,12 @@ void QSemaphore::release(int n)
+ quintptr nn = unsigned(n);
+ if (futexHasWaiterCount)
+ nn |= quint64(nn) << 32; // token count replicated in high word
+- quintptr prevValue = u.fetchAndAddRelease(nn);
++ quintptr prevValue = u.loadRelaxed();
++ quintptr newValue;
++ do { // loop just to ensure the operations are done atomically
++ newValue = prevValue + nn;
++ newValue &= (futexNeedsWakeAllBit - 1);
++ } while (!u.testAndSetRelease(prevValue, newValue, prevValue));
+ if (futexNeedsWake(prevValue)) {
+ #ifdef FUTEX_OP
+ if (futexHasWaiterCount) {
+@@ -376,7 +381,6 @@ void QSemaphore::release(int n)
+ quint32 oparg = 0;
+ quint32 cmp = FUTEX_OP_CMP_NE;
+ quint32 cmparg = 0;
+- u.fetchAndAndRelease(futexNeedsWakeAllBit - 1);
+ futexWakeOp(*futexLow32(&u), n, INT_MAX, *futexHigh32(&u), FUTEX_OP(op, oparg, cmp, cmparg));
+ return;
+ }
+@@ -388,7 +392,6 @@ void QSemaphore::release(int n)
+ // its acquisition anyway, so it has to wait;
+ // 2) it did not see the new counter value, in which case its
+ // futexWait will fail.
+- u.fetchAndAndRelease(futexNeedsWakeAllBit - 1);
+ if (futexHasWaiterCount) {
+ futexWakeAll(*futexLow32(&u));
+ futexWakeAll(*futexHigh32(&u));
+diff --git a/qtbase/src/corelib/thread/qthread_p.h b/qtbase/src/corelib/thread/qthread_p.h
+index b2d1628e6e..f32f6f0460 100644
+--- a/qtbase/src/corelib/thread/qthread_p.h
++++ b/qtbase/src/corelib/thread/qthread_p.h
+@@ -174,7 +174,7 @@ public:
+ int returnCode;
+
+ uint stackSize;
+- QThread::Priority priority;
++ std::underlying_type<QThread::Priority>::type priority;
+
+ static QThread *threadForId(int id);
+
+@@ -213,6 +213,13 @@ public:
+ QCoreApplication::instance()->postEvent(q_ptr, new QEvent(QEvent::Quit));
+ }
+ }
++
++#ifndef Q_OS_INTEGRITY
++private:
++ // Used in QThread(Private)::start to avoid racy access to QObject::objectName,
++ // unset afterwards. On INTEGRITY we set the thread name before starting it.
++ QString objectName;
++#endif
+ };
+
+ #else // QT_CONFIG(thread)
+diff --git a/qtbase/src/corelib/thread/qthread_unix.cpp b/qtbase/src/corelib/thread/qthread_unix.cpp
+index 56a8e0a038..610117a640 100644
+--- a/qtbase/src/corelib/thread/qthread_unix.cpp
++++ b/qtbase/src/corelib/thread/qthread_unix.cpp
+@@ -169,8 +169,7 @@ static void set_thread_data(QThreadData *data)
+
+ static void clear_thread_data()
+ {
+- currentThreadData = nullptr;
+- pthread_setspecific(current_thread_data_key, nullptr);
++ set_thread_data(nullptr);
+ }
+
+ template <typename T>
+@@ -296,7 +295,7 @@ void *QThreadPrivate::start(void *arg)
+ QMutexLocker locker(&thr->d_func()->mutex);
+
+ // do we need to reset the thread priority?
+- if (int(thr->d_func()->priority) & ThreadPriorityResetFlag) {
++ if (thr->d_func()->priority & ThreadPriorityResetFlag) {
+ thr->d_func()->setPriority(QThread::Priority(thr->d_func()->priority & ~ThreadPriorityResetFlag));
+ }
+
+@@ -316,10 +315,10 @@ void *QThreadPrivate::start(void *arg)
+ // Sets the name of the current thread. We can only do this
+ // when the thread is starting, as we don't have a cross
+ // platform way of setting the name of an arbitrary thread.
+- if (Q_LIKELY(thr->objectName().isEmpty()))
++ if (Q_LIKELY(thr->d_func()->objectName.isEmpty()))
+ setCurrentThreadName(thr->metaObject()->className());
+ else
+- setCurrentThreadName(thr->objectName().toLocal8Bit());
++ setCurrentThreadName(std::exchange(thr->d_func()->objectName, {}).toLocal8Bit());
+ }
+ #endif
+
+@@ -671,7 +670,7 @@ void QThread::start(Priority priority)
+ // could not set scheduling hints, fallback to inheriting them
+ // we'll try again from inside the thread
+ pthread_attr_setinheritsched(&attr, PTHREAD_INHERIT_SCHED);
+- d->priority = Priority(priority | ThreadPriorityResetFlag);
++ d->priority = static_cast<std::underlying_type<QThread::Priority>::type>(priority) | ThreadPriorityResetFlag;
+ }
+ break;
+ }
+@@ -702,7 +701,10 @@ void QThread::start(Priority priority)
+ pthread_attr_setthreadname(&attr, metaObject()->className());
+ else
+ pthread_attr_setthreadname(&attr, objectName().toLocal8Bit());
++#else
++ d->objectName = objectName();
+ #endif
++
+ pthread_t threadId;
+ int code = pthread_create(&threadId, &attr, QThreadPrivate::start, this);
+ if (code == EPERM) {
+diff --git a/qtbase/src/corelib/thread/qthread_win.cpp b/qtbase/src/corelib/thread/qthread_win.cpp
+index bc70e3178a..4e76972498 100644
+--- a/qtbase/src/corelib/thread/qthread_win.cpp
++++ b/qtbase/src/corelib/thread/qthread_win.cpp
+@@ -394,10 +394,9 @@ unsigned int __stdcall QT_ENSURE_STACK_ALIGNED_FOR_SSE QThreadPrivate::start(voi
+
+ #if !defined(QT_NO_DEBUG) && defined(Q_CC_MSVC) && !defined(Q_OS_WINRT)
+ // sets the name of the current thread.
+- QByteArray objectName = thr->objectName().toLocal8Bit();
+- qt_set_thread_name(HANDLE(-1),
+- objectName.isEmpty() ?
+- thr->metaObject()->className() : objectName.constData());
++ qt_set_thread_name(HANDLE(-1), thr->d_func()->objectName.isEmpty()
++ ? thr->metaObject()->className()
++ : std::exchange(thr->d_func()->objectName, {}).toLocal8Bit().constData());
+ #endif
+
+ emit thr->started(QThread::QPrivateSignal());
+@@ -503,6 +502,7 @@ void QThread::start(Priority priority)
+ if (d->running)
+ return;
+
++ d->objectName = objectName();
+ d->running = true;
+ d->finished = false;
+ d->exited = false;
+@@ -548,7 +548,7 @@ void QThread::start(Priority priority)
+
+ int prio;
+ d->priority = priority;
+- switch (d->priority) {
++ switch (priority) {
+ case IdlePriority:
+ prio = THREAD_PRIORITY_IDLE;
+ break;
+@@ -686,7 +686,7 @@ void QThreadPrivate::setPriority(QThread::Priority threadPriority)
+
+ int prio;
+ priority = threadPriority;
+- switch (priority) {
++ switch (threadPriority) {
+ case QThread::IdlePriority:
+ prio = THREAD_PRIORITY_IDLE;
+ break;
+diff --git a/qtbase/src/corelib/thread/qtsan_impl.h b/qtbase/src/corelib/thread/qtsan_impl.h
+new file mode 100644
+index 0000000000..580a738b91
+--- /dev/null
++++ b/qtbase/src/corelib/thread/qtsan_impl.h
+@@ -0,0 +1,115 @@
++/****************************************************************************
++**
++** Copyright (C) 2017 Intel Corporation.
++** Copyright (C) 2022 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Giuseppe D'Angelo <giuseppe.dangelo@kdab.com>
++** Contact: https://www.qt.io/licensing/
++**
++** This file is part of the QtCore module of the Qt Toolkit.
++**
++** $QT_BEGIN_LICENSE:LGPL$
++** Commercial License Usage
++** Licensees holding valid commercial Qt licenses may use this file in
++** accordance with the commercial license agreement provided with the
++** Software or, alternatively, in accordance with the terms contained in
++** a written agreement between you and The Qt Company. For licensing terms
++** and conditions see https://www.qt.io/terms-conditions. For further
++** information use the contact form at https://www.qt.io/contact-us.
++**
++** GNU Lesser General Public License Usage
++** Alternatively, this file may be used under the terms of the GNU Lesser
++** General Public License version 3 as published by the Free Software
++** Foundation and appearing in the file LICENSE.LGPL3 included in the
++** packaging of this file. Please review the following information to
++** ensure the GNU Lesser General Public License version 3 requirements
++** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
++**
++** GNU General Public License Usage
++** Alternatively, this file may be used under the terms of the GNU
++** General Public License version 2.0 or (at your option) the GNU General
++** Public license version 3 or any later version approved by the KDE Free
++** Qt Foundation. The licenses are as published by the Free Software
++** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
++** included in the packaging of this file. Please review the following
++** information to ensure the GNU General Public License requirements will
++** be met: https://www.gnu.org/licenses/gpl-2.0.html and
++** https://www.gnu.org/licenses/gpl-3.0.html.
++**
++** $QT_END_LICENSE$
++**
++****************************************************************************/
++
++#ifndef QTSAN_IMPL_H
++#define QTSAN_IMPL_H
++
++#include <QtCore/qglobal.h>
++
++#if (__has_feature(thread_sanitizer) || defined(__SANITIZE_THREAD__)) && __has_include(<sanitizer/tsan_interface.h>)
++# define QT_BUILDING_UNDER_TSAN
++# include <sanitizer/tsan_interface.h>
++#endif
++
++QT_BEGIN_NAMESPACE
++
++namespace QtTsan {
++#ifdef QT_BUILDING_UNDER_TSAN
++inline void futexAcquire(void *addr, void *addr2 = nullptr)
++{
++ // A futex call ensures total ordering on the futex words
++ // (in either success or failure of the call). Instruct TSAN accordingly,
++ // as TSAN does not understand the futex(2) syscall (or equivalent).
++ ::__tsan_acquire(addr);
++ if (addr2)
++ ::__tsan_acquire(addr2);
++}
++
++inline void futexRelease(void *addr, void *addr2 = nullptr)
++{
++ if (addr2)
++ ::__tsan_release(addr2);
++ ::__tsan_release(addr);
++}
++
++inline void mutexPreLock(void *addr, unsigned flags)
++{
++ ::__tsan_mutex_pre_lock(addr, flags);
++}
++
++inline void mutexPostLock(void *addr, unsigned flags, int recursion)
++{
++ ::__tsan_mutex_post_lock(addr, flags, recursion);
++}
++
++inline void mutexPreUnlock(void *addr, unsigned flags)
++{
++ ::__tsan_mutex_pre_unlock(addr, flags);
++}
++
++inline void mutexPostUnlock(void *addr, unsigned flags)
++{
++ ::__tsan_mutex_post_unlock(addr, flags);
++}
++
++enum : unsigned {
++ MutexWriteReentrant = ::__tsan_mutex_write_reentrant,
++ TryLock = ::__tsan_mutex_try_lock,
++ TryLockFailed = ::__tsan_mutex_try_lock_failed,
++};
++#else
++inline void futexAcquire(void *, void * = nullptr) {}
++inline void futexRelease(void *, void * = nullptr) {}
++
++enum : unsigned {
++ MutexWriteReentrant,
++ TryLock,
++ TryLockFailed,
++};
++inline void mutexPreLock(void *, unsigned) {}
++inline void mutexPostLock(void *, unsigned, int) {}
++inline void mutexPreUnlock(void *, unsigned) {}
++inline void mutexPostUnlock(void *, unsigned) {}
++#endif // QT_BUILDING_UNDER_TSAN
++} // namespace QtTsan
++
++QT_END_NAMESPACE
++
++#endif // QTSAN_IMPL_H
+diff --git a/qtbase/src/corelib/thread/qwaitcondition_unix.cpp b/qtbase/src/corelib/thread/qwaitcondition_unix.cpp
+index 88b058f410..0f1da4dc9b 100644
+--- a/qtbase/src/corelib/thread/qwaitcondition_unix.cpp
++++ b/qtbase/src/corelib/thread/qwaitcondition_unix.cpp
+@@ -213,7 +213,7 @@ bool QWaitCondition::wait(QMutex *mutex, QDeadlineTimer deadline)
+ {
+ if (! mutex)
+ return false;
+- if (mutex->isRecursive()) {
++ if (static_cast<QBasicMutex *>(mutex)->isRecursive()) {
+ qWarning("QWaitCondition: cannot wait on recursive mutexes");
+ return false;
+ }
+diff --git a/qtbase/src/corelib/time/qdatetime.cpp b/qtbase/src/corelib/time/qdatetime.cpp
+index ec12569e3f..2c0b098079 100644
+--- a/qtbase/src/corelib/time/qdatetime.cpp
++++ b/qtbase/src/corelib/time/qdatetime.cpp
+@@ -43,6 +43,7 @@
+ #if QT_CONFIG(datetimeparser)
+ #include "private/qdatetimeparser_p.h"
+ #endif
++#include <private/qnumeric_p.h>
+
+ #include "qdatastream.h"
+ #include "qset.h"
+@@ -1429,9 +1430,11 @@ QDate QDate::addDays(qint64 ndays) const
+ if (isNull())
+ return QDate();
+
+- // Due to limits on minJd() and maxJd() we know that any overflow
+- // will be invalid and caught by fromJulianDay().
+- return fromJulianDay(jd + ndays);
++ qint64 r;
++ if (Q_UNLIKELY(add_overflow(jd, ndays, &r)))
++ return QDate();
++ else
++ return fromJulianDay(r);
+ }
+
+ /*!
+diff --git a/qtbase/src/corelib/time/qtimezone.cpp b/qtbase/src/corelib/time/qtimezone.cpp
+index 0309e43e52..3d451696a1 100644
+--- a/qtbase/src/corelib/time/qtimezone.cpp
++++ b/qtbase/src/corelib/time/qtimezone.cpp
+@@ -1,6 +1,6 @@
+ /****************************************************************************
+ **
+-** Copyright (C) 2013 John Layt <jlayt@kde.org>
++** Copyright (C) 2020 John Layt <jlayt@kde.org>
+ ** Contact: https://www.qt.io/licensing/
+ **
+ ** This file is part of the QtCore module of the Qt Toolkit.
+@@ -975,9 +975,15 @@ QList<QByteArray> QTimeZone::windowsIdToIanaIds(const QByteArray &windowsId,
+ }
+
+ #ifndef QT_NO_DATASTREAM
++// Invalid, as an IANA ID: too long, starts with - and has other invalid characters in it
++static inline QString invalidId() { return QStringLiteral("-No Time Zone Specified!"); }
++
+ QDataStream &operator<<(QDataStream &ds, const QTimeZone &tz)
+ {
+- tz.d->serialize(ds);
++ if (tz.isValid())
++ tz.d->serialize(ds);
++ else
++ ds << invalidId();
+ return ds;
+ }
+
+@@ -985,7 +991,9 @@ QDataStream &operator>>(QDataStream &ds, QTimeZone &tz)
+ {
+ QString ianaId;
+ ds >> ianaId;
+- if (ianaId == QLatin1String("OffsetFromUtc")) {
++ if (ianaId == invalidId()) {
++ tz = QTimeZone();
++ } else if (ianaId == QLatin1String("OffsetFromUtc")) {
+ int utcOffset;
+ QString name;
+ QString abbreviation;
+diff --git a/qtbase/src/corelib/time/qtimezoneprivate_tz.cpp b/qtbase/src/corelib/time/qtimezoneprivate_tz.cpp
+index b1611d7ddb..a7a6a72ccf 100644
+--- a/qtbase/src/corelib/time/qtimezoneprivate_tz.cpp
++++ b/qtbase/src/corelib/time/qtimezoneprivate_tz.cpp
+@@ -42,6 +42,7 @@
+ #include "qtimezone.h"
+ #include "qtimezoneprivate_p.h"
+ #include "private/qlocale_tools_p.h"
++#include "private/qlocking_p.h"
+
+ #include <QtCore/QDataStream>
+ #include <QtCore/QDateTime>
+@@ -62,6 +63,10 @@
+
+ QT_BEGIN_NAMESPACE
+
++#if QT_CONFIG(icu)
++static QBasicMutex s_icu_mutex;
++#endif
++
+ /*
+ Private
+
+@@ -670,6 +675,9 @@ QTzTimeZonePrivate::~QTzTimeZonePrivate()
+
+ QTzTimeZonePrivate *QTzTimeZonePrivate::clone() const
+ {
++#if QT_CONFIG(icu)
++ const auto lock = qt_scoped_lock(s_icu_mutex);
++#endif
+ return new QTzTimeZonePrivate(*this);
+ }
+
+@@ -913,12 +921,14 @@ QString QTzTimeZonePrivate::displayName(qint64 atMSecsSinceEpoch,
+ const QLocale &locale) const
+ {
+ #if QT_CONFIG(icu)
++ auto lock = qt_unique_lock(s_icu_mutex);
+ if (!m_icu)
+ m_icu = new QIcuTimeZonePrivate(m_id);
+ // TODO small risk may not match if tran times differ due to outdated files
+ // TODO Some valid TZ names are not valid ICU names, use translation table?
+ if (m_icu->isValid())
+ return m_icu->displayName(atMSecsSinceEpoch, nameType, locale);
++ lock.unlock();
+ #else
+ Q_UNUSED(nameType)
+ Q_UNUSED(locale)
+@@ -932,12 +942,14 @@ QString QTzTimeZonePrivate::displayName(QTimeZone::TimeType timeType,
+ const QLocale &locale) const
+ {
+ #if QT_CONFIG(icu)
++ auto lock = qt_unique_lock(s_icu_mutex);
+ if (!m_icu)
+ m_icu = new QIcuTimeZonePrivate(m_id);
+ // TODO small risk may not match if tran times differ due to outdated files
+ // TODO Some valid TZ names are not valid ICU names, use translation table?
+ if (m_icu->isValid())
+ return m_icu->displayName(timeType, nameType, locale);
++ lock.unlock();
+ #else
+ Q_UNUSED(timeType)
+ Q_UNUSED(nameType)
+diff --git a/qtbase/src/corelib/tools/qarraydata.h b/qtbase/src/corelib/tools/qarraydata.h
+index dcd95924c1..d01739e7e6 100644
+--- a/qtbase/src/corelib/tools/qarraydata.h
++++ b/qtbase/src/corelib/tools/qarraydata.h
+@@ -42,6 +42,7 @@
+
+ #include <QtCore/qrefcount.h>
+ #include <string.h>
++#include <cstdint>
+
+ QT_BEGIN_NAMESPACE
+
+@@ -58,14 +59,14 @@ struct Q_CORE_EXPORT QArrayData
+ {
+ Q_ASSERT(size == 0
+ || offset < 0 || size_t(offset) >= sizeof(QArrayData));
+- return reinterpret_cast<char *>(this) + offset;
++ return reinterpret_cast<void *> (reinterpret_cast<uintptr_t>(this) + offset);
+ }
+
+ const void *data() const
+ {
+ Q_ASSERT(size == 0
+ || offset < 0 || size_t(offset) >= sizeof(QArrayData));
+- return reinterpret_cast<const char *>(this) + offset;
++ return reinterpret_cast<void *> (reinterpret_cast<uintptr_t>(this) + offset);
+ }
+
+ // This refers to array data mutability, not "header data" represented by
+diff --git a/qtbase/src/corelib/tools/qfreelist_p.h b/qtbase/src/corelib/tools/qfreelist_p.h
+index 5ba23b344b..9974102136 100644
+--- a/qtbase/src/corelib/tools/qfreelist_p.h
++++ b/qtbase/src/corelib/tools/qfreelist_p.h
+@@ -161,7 +161,7 @@ class QFreeList
+ return i;
+ x -= size;
+ }
+- Q_ASSERT(false);
++ Q_UNREACHABLE();
+ return -1;
+ }
+
+diff --git a/qtbase/src/corelib/tools/qversionnumber.h b/qtbase/src/corelib/tools/qversionnumber.h
+index d43b86ba51..2843f2b043 100644
+--- a/qtbase/src/corelib/tools/qversionnumber.h
++++ b/qtbase/src/corelib/tools/qversionnumber.h
+@@ -273,10 +273,10 @@ public:
+
+ Q_REQUIRED_RESULT Q_CORE_EXPORT QString toString() const;
+ #if QT_STRINGVIEW_LEVEL < 2
+- Q_REQUIRED_RESULT Q_CORE_EXPORT static Q_DECL_PURE_FUNCTION QVersionNumber fromString(const QString &string, int *suffixIndex = nullptr);
++ Q_REQUIRED_RESULT Q_CORE_EXPORT static QVersionNumber fromString(const QString &string, int *suffixIndex = nullptr);
+ #endif
+- Q_REQUIRED_RESULT Q_CORE_EXPORT static Q_DECL_PURE_FUNCTION QVersionNumber fromString(QLatin1String string, int *suffixIndex = nullptr);
+- Q_REQUIRED_RESULT Q_CORE_EXPORT static Q_DECL_PURE_FUNCTION QVersionNumber fromString(QStringView string, int *suffixIndex = nullptr);
++ Q_REQUIRED_RESULT Q_CORE_EXPORT static QVersionNumber fromString(QLatin1String string, int *suffixIndex = nullptr);
++ Q_REQUIRED_RESULT Q_CORE_EXPORT static QVersionNumber fromString(QStringView string, int *suffixIndex = nullptr);
+
+ private:
+ #ifndef QT_NO_DATASTREAM
+diff --git a/qtbase/src/dbus/qdbusintegrator.cpp b/qtbase/src/dbus/qdbusintegrator.cpp
+index 5b66ce971b..28a3b0ffea 100644
+--- a/qtbase/src/dbus/qdbusintegrator.cpp
++++ b/qtbase/src/dbus/qdbusintegrator.cpp
+@@ -1135,7 +1135,13 @@ void QDBusConnectionPrivate::closeConnection()
+ }
+ }
+
+- qDeleteAll(pendingCalls);
++ for (auto it = pendingCalls.begin(); it != pendingCalls.end(); ++it) {
++ auto call = *it;
++ if (!call->ref.deref()) {
++ delete call;
++ }
++ }
++ pendingCalls.clear();
+
+ // Disconnect all signals from signal hooks and from the object tree to
+ // avoid QObject::destroyed being sent to dbus daemon thread which has
+@@ -2584,6 +2590,11 @@ QDBusConnectionPrivate::findMetaObject(const QString &service, const QString &pa
+ if (mo)
+ return mo;
+ }
++ if (path.isEmpty()) {
++ error = QDBusError(QDBusError::InvalidObjectPath, QLatin1String("Object path cannot be empty"));
++ lastError = error;
++ return nullptr;
++ }
+
+ // introspect the target object
+ QDBusMessage msg = QDBusMessage::createMethodCall(service, path,
+diff --git a/qtbase/src/dbus/qdbusmetaobject.cpp b/qtbase/src/dbus/qdbusmetaobject.cpp
+index 5265568f42..7e9f0f1acc 100644
+--- a/qtbase/src/dbus/qdbusmetaobject.cpp
++++ b/qtbase/src/dbus/qdbusmetaobject.cpp
+@@ -210,6 +210,9 @@ QDBusMetaObjectGenerator::findType(const QByteArray &signature,
+ } else if (signature == "a{ss}") {
+ result.name = "QMap<QString,QString>";
+ type = qMetaTypeId<QMap<QString, QString> >();
++ } else if (signature == "aay") {
++ result.name = "QByteArrayList";
++ type = qMetaTypeId<QByteArrayList>();
+ } else {
+ result.name = "{D-Bus type \"" + signature + "\"}";
+ type = registerComplexDBusType(result.name);
+diff --git a/qtbase/src/gui/accessible/qaccessible.cpp b/qtbase/src/gui/accessible/qaccessible.cpp
+index d705bfccb5..0caf3c808c 100644
+--- a/qtbase/src/gui/accessible/qaccessible.cpp
++++ b/qtbase/src/gui/accessible/qaccessible.cpp
+@@ -54,6 +54,7 @@
+ #include <QtCore/qdebug.h>
+ #include <QtCore/qloggingcategory.h>
+ #include <QtCore/qmetaobject.h>
++#include <QtCore/private/qmetaobject_p.h>
+ #include <QtCore/qhash.h>
+ #include <private/qfactoryloader_p.h>
+
+@@ -681,6 +682,25 @@ QAccessibleInterface *QAccessible::queryAccessibleInterface(QObject *object)
+ // Create a QAccessibleInterface for the object class. Start by the most
+ // derived class and walk up the class hierarchy.
+ const QMetaObject *mo = object->metaObject();
++ const auto *objectPriv = QObjectPrivate::get(object);
++ /*
++ We do not want to cache each and every QML metaobject (Button_QMLTYPE_124,
++ Button_QMLTYPE_125, etc.). Those dynamic metaobjects shouldn't have an
++ accessible interface in any case. Instead, we start the whole checking
++ with the first non-dynamic meta-object. To avoid potential regressions
++ in other areas of Qt that also use dynamic metaobjects, we only do this
++ for objects that are QML-related (approximated by checking whether they
++ have ddata set).
++ */
++ const bool qmlRelated = !objectPriv->isDeletingChildren &&
++ objectPriv->declarativeData;
++ while (qmlRelated && mo) {
++ auto mop = QMetaObjectPrivate::get(mo);
++ if (!mop || !(mop->flags & DynamicMetaObject))
++ break;
++
++ mo = mo->superClass();
++ };
+ while (mo) {
+ const QString cn = QLatin1String(mo->className());
+
+@@ -696,14 +716,15 @@ QAccessibleInterface *QAccessible::queryAccessibleInterface(QObject *object)
+ // Find a QAccessiblePlugin (factory) for the class name. If there's
+ // no entry in the cache try to create it using the plugin loader.
+ if (!qAccessiblePlugins()->contains(cn)) {
++ QAccessiblePlugin *factory = nullptr; // 0 means "no plugin found". This is cached as well.
+ const int index = loader()->indexOf(cn);
+- if (index != -1) {
+- QAccessiblePlugin *factory = qobject_cast<QAccessiblePlugin *>(loader()->instance(index));
+- qAccessiblePlugins()->insert(cn, factory);
+- }
++ if (index != -1)
++ factory = qobject_cast<QAccessiblePlugin *>(loader()->instance(index));
++ qAccessiblePlugins()->insert(cn, factory);
+ }
+
+ // At this point the cache should contain a valid factory pointer or 0:
++ Q_ASSERT(qAccessiblePlugins()->contains(cn));
+ QAccessiblePlugin *factory = qAccessiblePlugins()->value(cn);
+ if (factory) {
+ QAccessibleInterface *result = factory->create(cn, object);
+diff --git a/qtbase/src/gui/configure.json b/qtbase/src/gui/configure.json
+index 1f08795c57..12c95742d2 100644
+--- a/qtbase/src/gui/configure.json
++++ b/qtbase/src/gui/configure.json
+@@ -834,7 +834,8 @@
+ "// embedded devices, are not intended to be used together with X. EGL support",
+ "// has to be disabled in plugins like xcb in this case since the native display,",
+ "// window and pixmap types will be different than what an X-based platform",
+- "// plugin would expect."
++ "// plugin would expect.",
++ "#define USE_X11"
+ ],
+ "include": [ "EGL/egl.h", "X11/Xlib.h" ],
+ "main": [
+diff --git a/qtbase/src/gui/image/qbmphandler.cpp b/qtbase/src/gui/image/qbmphandler.cpp
+index 96f1e8cb1d..0e73bbbdb0 100644
+--- a/qtbase/src/gui/image/qbmphandler.cpp
++++ b/qtbase/src/gui/image/qbmphandler.cpp
+@@ -150,16 +150,42 @@ static QDataStream &operator<<(QDataStream &s, const BMP_INFOHDR &bi)
+ return s;
+ }
+
+-static int calc_shift(uint mask)
++static uint calc_shift(uint mask)
+ {
+- int result = 0;
+- while (mask && !(mask & 1)) {
++ uint result = 0;
++ while ((mask >= 0x100) || (!(mask & 1) && mask)) {
+ result++;
+ mask >>= 1;
+ }
+ return result;
+ }
+
++static uint calc_scale(uint low_mask)
++{
++ uint result = 8;
++ while (low_mask && result) {
++ result--;
++ low_mask >>= 1;
++ }
++ return result;
++}
++
++static inline uint apply_scale(uint value, uint scale)
++{
++ if (!(scale & 0x07)) // return immediately if scale == 8 or 0
++ return value;
++
++ uint filled = 8 - scale;
++ uint result = value << scale;
++
++ do {
++ result |= result >> filled;
++ filled <<= 1;
++ } while (filled < 8);
++
++ return result;
++}
++
+ static bool read_dib_fileheader(QDataStream &s, BMP_FILEHDR &bf)
+ {
+ // read BMP file header
+@@ -222,14 +248,14 @@ static bool read_dib_body(QDataStream &s, const BMP_INFOHDR &bi, qint64 offset,
+ uint green_mask = 0;
+ uint blue_mask = 0;
+ uint alpha_mask = 0;
+- int red_shift = 0;
+- int green_shift = 0;
+- int blue_shift = 0;
+- int alpha_shift = 0;
+- int red_scale = 0;
+- int green_scale = 0;
+- int blue_scale = 0;
+- int alpha_scale = 0;
++ uint red_shift = 0;
++ uint green_shift = 0;
++ uint blue_shift = 0;
++ uint alpha_shift = 0;
++ uint red_scale = 0;
++ uint green_scale = 0;
++ uint blue_scale = 0;
++ uint alpha_scale = 0;
+
+ if (!d->isSequential())
+ d->seek(startpos + BMP_FILEHDR_SIZE + bi.biSize); // goto start of colormap or masks
+@@ -308,19 +334,19 @@ static bool read_dib_body(QDataStream &s, const BMP_INFOHDR &bi, qint64 offset,
+ red_shift = calc_shift(red_mask);
+ if (((red_mask >> red_shift) + 1) == 0)
+ return false;
+- red_scale = 256 / ((red_mask >> red_shift) + 1);
++ red_scale = calc_scale(red_mask >> red_shift);
+ green_shift = calc_shift(green_mask);
+ if (((green_mask >> green_shift) + 1) == 0)
+ return false;
+- green_scale = 256 / ((green_mask >> green_shift) + 1);
++ green_scale = calc_scale(green_mask >> green_shift);
+ blue_shift = calc_shift(blue_mask);
+ if (((blue_mask >> blue_shift) + 1) == 0)
+ return false;
+- blue_scale = 256 / ((blue_mask >> blue_shift) + 1);
++ blue_scale = calc_scale(blue_mask >> blue_shift);
+ alpha_shift = calc_shift(alpha_mask);
+ if (((alpha_mask >> alpha_shift) + 1) == 0)
+ return false;
+- alpha_scale = 256 / ((alpha_mask >> alpha_shift) + 1);
++ alpha_scale = calc_scale(alpha_mask >> alpha_shift);
+ } else if (comp == BMP_RGB && (nbits == 24 || nbits == 32)) {
+ blue_mask = 0x000000ff;
+ green_mask = 0x0000ff00;
+@@ -328,17 +354,15 @@ static bool read_dib_body(QDataStream &s, const BMP_INFOHDR &bi, qint64 offset,
+ blue_shift = 0;
+ green_shift = 8;
+ red_shift = 16;
+- blue_scale = green_scale = red_scale = 1;
++ blue_scale = green_scale = red_scale = 0;
+ } else if (comp == BMP_RGB && nbits == 16) {
+ blue_mask = 0x001f;
+ green_mask = 0x03e0;
+ red_mask = 0x7c00;
+ blue_shift = 0;
+- green_shift = 2;
+- red_shift = 7;
+- red_scale = 1;
+- green_scale = 1;
+- blue_scale = 8;
++ green_shift = 5;
++ red_shift = 10;
++ blue_scale = green_scale = red_scale = 3;
+ }
+
+ #if 0
+@@ -544,10 +568,10 @@ static bool read_dib_body(QDataStream &s, const BMP_INFOHDR &bi, qint64 offset,
+ c |= *(uchar*)(b+2)<<16;
+ if (nbits > 24)
+ c |= *(uchar*)(b+3)<<24;
+- *p++ = qRgba(((c & red_mask) >> red_shift) * red_scale,
+- ((c & green_mask) >> green_shift) * green_scale,
+- ((c & blue_mask) >> blue_shift) * blue_scale,
+- transp ? ((c & alpha_mask) >> alpha_shift) * alpha_scale : 0xff);
++ *p++ = qRgba(apply_scale((c & red_mask) >> red_shift, red_scale),
++ apply_scale((c & green_mask) >> green_shift, green_scale),
++ apply_scale((c & blue_mask) >> blue_shift, blue_scale),
++ transp ? apply_scale((c & alpha_mask) >> alpha_shift, alpha_scale) : 0xff);
+ b += nbits/8;
+ }
+ }
+diff --git a/qtbase/src/gui/image/qimage.cpp b/qtbase/src/gui/image/qimage.cpp
+index 7152ac1607..0df772564c 100644
+--- a/qtbase/src/gui/image/qimage.cpp
++++ b/qtbase/src/gui/image/qimage.cpp
+@@ -4694,6 +4694,8 @@ QImage QImage::smoothScaled(int w, int h) const {
+ static QImage rotated90(const QImage &image)
+ {
+ QImage out(image.height(), image.width(), image.format());
++ if (out.isNull())
++ return out;
+ copyMetadata(&out, image);
+ if (image.colorCount() > 0)
+ out.setColorTable(image.colorTable());
+@@ -4722,6 +4724,8 @@ static QImage rotated180(const QImage &image)
+ return image.mirrored(true, true);
+
+ QImage out(image.width(), image.height(), image.format());
++ if (out.isNull())
++ return out;
+ copyMetadata(&out, image);
+ if (image.colorCount() > 0)
+ out.setColorTable(image.colorTable());
+@@ -4734,6 +4738,8 @@ static QImage rotated180(const QImage &image)
+ static QImage rotated270(const QImage &image)
+ {
+ QImage out(image.height(), image.width(), image.format());
++ if (out.isNull())
++ return out;
+ copyMetadata(&out, image);
+ if (image.colorCount() > 0)
+ out.setColorTable(image.colorTable());
+diff --git a/qtbase/src/gui/kernel/qcursor.cpp b/qtbase/src/gui/kernel/qcursor.cpp
+index d6ccaff8ed..455088241c 100644
+--- a/qtbase/src/gui/kernel/qcursor.cpp
++++ b/qtbase/src/gui/kernel/qcursor.cpp
+@@ -251,7 +251,8 @@ void QCursor::setPos(QScreen *screen, int x, int y)
+ {
+ if (screen) {
+ if (QPlatformCursor *cursor = screen->handle()->cursor()) {
+- const QPoint devicePos = QHighDpi::toNativePixels(QPoint(x, y), screen);
++ const QPoint pos(x, y);
++ const QPoint devicePos = QHighDpi::toNativePixels(pos, screen->virtualSiblingAt(pos));
+ // Need to check, since some X servers generate null mouse move
+ // events, causing looping in applications which call setPos() on
+ // every mouse move event.
+diff --git a/qtbase/src/gui/kernel/qhighdpiscaling.cpp b/qtbase/src/gui/kernel/qhighdpiscaling.cpp
+index 9bbf2773a9..3ac4a4d8b6 100644
+--- a/qtbase/src/gui/kernel/qhighdpiscaling.cpp
++++ b/qtbase/src/gui/kernel/qhighdpiscaling.cpp
+@@ -580,9 +580,8 @@ void QHighDpiScaling::setScreenFactor(QScreen *screen, qreal factor)
+ else
+ qNamedScreenScaleFactors()->insert(name, factor);
+
+- // hack to force re-evaluation of screen geometry
+ if (screen->handle())
+- screen->d_func()->setPlatformScreen(screen->handle()); // updates geometries based on scale factor
++ screen->d_func()->updateLogicalDpi();
+ }
+
+ QPoint QHighDpiScaling::mapPositionToNative(const QPoint &pos, const QPlatformScreen *platformScreen)
+diff --git a/qtbase/src/gui/kernel/qkeysequence.cpp b/qtbase/src/gui/kernel/qkeysequence.cpp
+index a75b8ef920..4f2d294739 100644
+--- a/qtbase/src/gui/kernel/qkeysequence.cpp
++++ b/qtbase/src/gui/kernel/qkeysequence.cpp
+@@ -701,6 +701,10 @@ static const struct {
+ { Qt::Key_TouchpadToggle, QT_TRANSLATE_NOOP("QShortcut", "Touchpad Toggle") },
+ { Qt::Key_TouchpadOn, QT_TRANSLATE_NOOP("QShortcut", "Touchpad On") },
+ { Qt::Key_TouchpadOff, QT_TRANSLATE_NOOP("QShortcut", "Touchpad Off") },
++ { Qt::Key_Shift, QT_TRANSLATE_NOOP("QShortcut", "Shift") },
++ { Qt::Key_Control, QT_TRANSLATE_NOOP("QShortcut", "Control") },
++ { Qt::Key_Alt, QT_TRANSLATE_NOOP("QShortcut", "Alt") },
++ { Qt::Key_Meta, QT_TRANSLATE_NOOP("QShortcut", "Meta") },
+
+ };
+ static Q_CONSTEXPR int numKeyNames = sizeof keyname / sizeof *keyname;
+diff --git a/qtbase/src/gui/kernel/qplatformservices.cpp b/qtbase/src/gui/kernel/qplatformservices.cpp
+index fdc6a6c4aa..ac47f98c5d 100644
+--- a/qtbase/src/gui/kernel/qplatformservices.cpp
++++ b/qtbase/src/gui/kernel/qplatformservices.cpp
+@@ -55,6 +55,19 @@ QT_BEGIN_NAMESPACE
+ \brief The QPlatformServices provides the backend for desktop-related functionality.
+ */
+
++/*!
++ \enum QPlatformServices::Capability
++
++ Capabilities are used to determine a specific platform service's availability.
++
++ \value ColorPickingFromScreen The platform natively supports color picking from screen.
++ This capability indicates that the platform supports "opaque" color picking, where the
++ platform implements a complete user experience for color picking and outputs a color.
++ This is in contrast to the application implementing the color picking user experience
++ (taking care of showing a cross hair, instructing the platform integration to obtain
++ the color at a given pixel, etc.). The related service function is pickColor().
++ */
++
+ QPlatformServices::QPlatformServices()
+ { }
+
+@@ -85,5 +98,16 @@ QByteArray QPlatformServices::desktopEnvironment() const
+ return QByteArray("UNKNOWN");
+ }
+
++QPlatformServiceColorPicker *QPlatformServices::colorPicker(QWindow *parent)
++{
++ Q_UNUSED(parent);
++ return nullptr;
++}
++
++bool QPlatformServices::hasCapability(Capability capability) const
++{
++ Q_UNUSED(capability)
++ return false;
++}
+
+ QT_END_NAMESPACE
+diff --git a/qtbase/src/gui/kernel/qplatformservices.h b/qtbase/src/gui/kernel/qplatformservices.h
+index 5de96cfa7d..a8b2a4ce71 100644
+--- a/qtbase/src/gui/kernel/qplatformservices.h
++++ b/qtbase/src/gui/kernel/qplatformservices.h
+@@ -50,16 +50,32 @@
+ //
+
+ #include <QtGui/qtguiglobal.h>
++#include <QtCore/qobject.h>
+
+ QT_BEGIN_NAMESPACE
+
+ class QUrl;
++class QWindow;
++
++class Q_GUI_EXPORT QPlatformServiceColorPicker : public QObject
++{
++ Q_OBJECT
++public:
++ using QObject::QObject;
++ virtual void pickColor() = 0;
++Q_SIGNALS:
++ void colorPicked(const QColor &color);
++};
+
+ class Q_GUI_EXPORT QPlatformServices
+ {
+ public:
+ Q_DISABLE_COPY_MOVE(QPlatformServices)
+
++ enum Capability {
++ ColorPicking,
++ };
++
+ QPlatformServices();
+ virtual ~QPlatformServices() { }
+
+@@ -67,6 +83,10 @@ public:
+ virtual bool openDocument(const QUrl &url);
+
+ virtual QByteArray desktopEnvironment() const;
++
++ virtual bool hasCapability(Capability capability) const;
++
++ virtual QPlatformServiceColorPicker *colorPicker(QWindow *parent = nullptr);
+ };
+
+ QT_END_NAMESPACE
+diff --git a/qtbase/src/gui/kernel/qplatformtheme.cpp b/qtbase/src/gui/kernel/qplatformtheme.cpp
+index 71521c0339..2325873245 100644
+--- a/qtbase/src/gui/kernel/qplatformtheme.cpp
++++ b/qtbase/src/gui/kernel/qplatformtheme.cpp
+@@ -163,6 +163,8 @@ QT_BEGIN_NAMESPACE
+
+ \value ShowShortcutsInContextMenus (bool) Whether to display shortcut key sequences in context menus.
+
++ \value ButtonPressKeys (QList<Qt::Key>) A list of keys that can be used to press buttons via keyboard input.
++
+ \sa themeHint(), QStyle::pixelMetric()
+ */
+
+@@ -563,6 +565,8 @@ QVariant QPlatformTheme::defaultThemeHint(ThemeHint hint)
+ }
+ case MouseQuickSelectionThreshold:
+ return QVariant(10);
++ case ButtonPressKeys:
++ return QVariant::fromValue(QList<Qt::Key>({ Qt::Key_Space, Qt::Key_Select }));
+ }
+ return QVariant();
+ }
+diff --git a/qtbase/src/gui/kernel/qplatformtheme.h b/qtbase/src/gui/kernel/qplatformtheme.h
+index 3185fc4541..7e6c9d5740 100644
+--- a/qtbase/src/gui/kernel/qplatformtheme.h
++++ b/qtbase/src/gui/kernel/qplatformtheme.h
+@@ -120,7 +120,8 @@ public:
+ TouchDoubleTapDistance,
+ ShowShortcutsInContextMenus,
+ IconFallbackSearchPaths,
+- MouseQuickSelectionThreshold
++ MouseQuickSelectionThreshold,
++ ButtonPressKeys
+ };
+
+ enum DialogType {
+diff --git a/qtbase/src/gui/kernel/qscreen.cpp b/qtbase/src/gui/kernel/qscreen.cpp
+index 8e0eb35116..5d172a58dd 100644
+--- a/qtbase/src/gui/kernel/qscreen.cpp
++++ b/qtbase/src/gui/kernel/qscreen.cpp
+@@ -77,6 +77,12 @@ QScreen::QScreen(QPlatformScreen *screen)
+ d->setPlatformScreen(screen);
+ }
+
++void QScreenPrivate::updateLogicalDpi()
++{
++ logicalDpi = QPlatformScreen::overrideDpi(platformScreen->logicalDpi());
++ updateGeometriesWithSignals(); // updates geometries based on scale factor
++}
++
+ void QScreenPrivate::updateGeometriesWithSignals()
+ {
+ const QRect oldGeometry = geometry;
+diff --git a/qtbase/src/gui/kernel/qscreen_p.h b/qtbase/src/gui/kernel/qscreen_p.h
+index 7da542c25e..e50fc3190b 100644
+--- a/qtbase/src/gui/kernel/qscreen_p.h
++++ b/qtbase/src/gui/kernel/qscreen_p.h
+@@ -70,6 +70,7 @@ public:
+ geometry = platformScreen->deviceIndependentGeometry();
+ availableGeometry = QHighDpi::fromNative(platformScreen->availableGeometry(), QHighDpiScaling::factor(platformScreen), geometry.topLeft());
+ }
++ void updateLogicalDpi();
+
+ void updatePrimaryOrientation();
+ void updateGeometriesWithSignals();
+diff --git a/qtbase/src/gui/painting/qblendfunctions_p.h b/qtbase/src/gui/painting/qblendfunctions_p.h
+index 080da98ec4..6997d62b3c 100644
+--- a/qtbase/src/gui/painting/qblendfunctions_p.h
++++ b/qtbase/src/gui/painting/qblendfunctions_p.h
+@@ -246,25 +246,32 @@ void qt_transform_image_rasterize(DestT *destPixels, int dbpl,
+ int dudx, int dvdx, int dudy, int dvdy, int u0, int v0,
+ Blender blender)
+ {
+- int fromY = qMax(qRound(topY), clip.top());
+- int toY = qMin(qRound(bottomY), clip.top() + clip.height());
++ qint64 fromY = qMax(qRound(topY), clip.top());
++ qint64 toY = qMin(qRound(bottomY), clip.top() + clip.height());
+ if (fromY >= toY)
+ return;
+
+ qreal leftSlope = (bottomLeft.x - topLeft.x) / (bottomLeft.y - topLeft.y);
+ qreal rightSlope = (bottomRight.x - topRight.x) / (bottomRight.y - topRight.y);
+- int dx_l = int(leftSlope * 0x10000);
+- int dx_r = int(rightSlope * 0x10000);
+- int x_l = int((topLeft.x + (qreal(0.5) + fromY - topLeft.y) * leftSlope + qreal(0.5)) * 0x10000);
+- int x_r = int((topRight.x + (qreal(0.5) + fromY - topRight.y) * rightSlope + qreal(0.5)) * 0x10000);
+-
+- int fromX, toX, x1, x2, u, v, i, ii;
++ qint64 dx_l = qint64(leftSlope * 0x10000);
++ qint64 dx_r = qint64(rightSlope * 0x10000);
++ qint64 x_l = qint64((topLeft.x + (qreal(0.5) + fromY - topLeft.y) * leftSlope + qreal(0.5)) * 0x10000);
++ qint64 x_r = qint64((topRight.x + (qreal(0.5) + fromY - topRight.y) * rightSlope + qreal(0.5)) * 0x10000);
++
++ qint64 sourceRectTop = qint64(sourceRect.top());
++ qint64 sourceRectLeft = qint64(sourceRect.left());
++ qint64 sourceRectWidth = qint64(sourceRect.width());
++ qint64 sourceRectHeight = qint64(sourceRect.height());
++ qint64 clipLeft = qint64(clip.left());
++ qint64 clipWidth = qint64(clip.width());
++
++ qint64 fromX, toX, x1, x2, u, v, i, ii;
+ DestT *line;
+- for (int y = fromY; y < toY; ++y) {
++ for (qint64 y = fromY; y < toY; ++y) {
+ line = reinterpret_cast<DestT *>(reinterpret_cast<uchar *>(destPixels) + y * dbpl);
+
+- fromX = qMax(x_l >> 16, clip.left());
+- toX = qMin(x_r >> 16, clip.left() + clip.width());
++ fromX = qMax(x_l >> 16, clipLeft);
++ toX = qMin(x_r >> 16, clipLeft + clipWidth);
+ if (fromX < toX) {
+ // Because of rounding, we can get source coordinates outside the source image.
+ // Clamp these coordinates to the source rect to avoid segmentation fault and
+@@ -275,10 +282,10 @@ void qt_transform_image_rasterize(DestT *destPixels, int dbpl,
+ u = x1 * dudx + y * dudy + u0;
+ v = x1 * dvdx + y * dvdy + v0;
+ for (; x1 < toX; ++x1) {
+- int uu = u >> 16;
+- int vv = v >> 16;
+- if (uu >= sourceRect.left() && uu < sourceRect.left() + sourceRect.width()
+- && vv >= sourceRect.top() && vv < sourceRect.top() + sourceRect.height()) {
++ qint64 uu = u >> 16;
++ qint64 vv = v >> 16;
++ if (uu >= sourceRectLeft && uu < sourceRectLeft + sourceRectWidth
++ && vv >= sourceRectTop && vv < sourceRectTop + sourceRectHeight) {
+ break;
+ }
+ u += dudx;
+@@ -290,10 +297,10 @@ void qt_transform_image_rasterize(DestT *destPixels, int dbpl,
+ u = (x2 - 1) * dudx + y * dudy + u0;
+ v = (x2 - 1) * dvdx + y * dvdy + v0;
+ for (; x2 > x1; --x2) {
+- int uu = u >> 16;
+- int vv = v >> 16;
+- if (uu >= sourceRect.left() && uu < sourceRect.left() + sourceRect.width()
+- && vv >= sourceRect.top() && vv < sourceRect.top() + sourceRect.height()) {
++ qint64 uu = u >> 16;
++ qint64 vv = v >> 16;
++ if (uu >= sourceRectLeft && uu < sourceRectLeft + sourceRectWidth
++ && vv >= sourceRectTop && vv < sourceRectTop + sourceRectHeight) {
+ break;
+ }
+ u -= dudx;
+@@ -308,8 +315,8 @@ void qt_transform_image_rasterize(DestT *destPixels, int dbpl,
+ // Beginning of the scan line, with per-pixel checks.
+ i = x1 - fromX;
+ while (i) {
+- int uu = qBound(sourceRect.left(), u >> 16, sourceRect.left() + sourceRect.width() - 1);
+- int vv = qBound(sourceRect.top(), v >> 16, sourceRect.top() + sourceRect.height() - 1);
++ qint64 uu = qBound(sourceRectLeft, u >> 16, sourceRectLeft + sourceRectWidth - 1);
++ qint64 vv = qBound(sourceRectTop, v >> 16, sourceRectTop + sourceRectHeight - 1);
+ blender.write(line, reinterpret_cast<const SrcT *>(reinterpret_cast<const uchar *>(srcPixels) + vv * sbpl)[uu]);
+ u += dudx;
+ v += dvdx;
+@@ -348,8 +355,8 @@ void qt_transform_image_rasterize(DestT *destPixels, int dbpl,
+ // End of the scan line, with per-pixel checks.
+ i = toX - x2;
+ while (i) {
+- int uu = qBound(sourceRect.left(), u >> 16, sourceRect.left() + sourceRect.width() - 1);
+- int vv = qBound(sourceRect.top(), v >> 16, sourceRect.top() + sourceRect.height() - 1);
++ qint64 uu = qBound(sourceRectLeft, u >> 16, sourceRectLeft + sourceRectWidth - 1);
++ qint64 vv = qBound(sourceRectTop, v >> 16, sourceRectTop + sourceRectHeight - 1);
+ blender.write(line, reinterpret_cast<const SrcT *>(reinterpret_cast<const uchar *>(srcPixels) + vv * sbpl)[uu]);
+ u += dudx;
+ v += dvdx;
+diff --git a/qtbase/src/gui/painting/qcolortrclut_p.h b/qtbase/src/gui/painting/qcolortrclut_p.h
+index 76a6a60803..24fd522e6c 100644
+--- a/qtbase/src/gui/painting/qcolortrclut_p.h
++++ b/qtbase/src/gui/painting/qcolortrclut_p.h
+@@ -118,6 +118,7 @@ public:
+ return QRgba64::fromRgba64(r, g, b, qAlpha(rgb32) * 257);
+ #endif
+ }
++ QRgba64 toLinear64(QRgba64) const = delete;
+
+ QRgb toLinear(QRgb rgb32) const
+ {
+diff --git a/qtbase/src/gui/painting/qdrawhelper.cpp b/qtbase/src/gui/painting/qdrawhelper.cpp
+index a61793508a..5ba2d277b7 100644
+--- a/qtbase/src/gui/painting/qdrawhelper.cpp
++++ b/qtbase/src/gui/painting/qdrawhelper.cpp
+@@ -6091,7 +6091,7 @@ static inline void alphargbblend_argb32(quint32 *dst, uint coverage, const QRgba
+ static inline void rgbBlendPixel(QRgba64 &dst, int coverage, QRgba64 slinear, const QColorTrcLut *colorProfile)
+ {
+ // Do a gammacorrected RGB alphablend...
+- const QRgba64 dlinear = colorProfile ? colorProfile->toLinear64(dst) : dst;
++ const QRgba64 dlinear = colorProfile ? colorProfile->toLinear(dst) : dst;
+
+ QRgba64 blend = rgbBlend(dlinear, slinear, coverage);
+
+diff --git a/qtbase/src/gui/painting/qpaintengine_raster.cpp b/qtbase/src/gui/painting/qpaintengine_raster.cpp
+index 283923de52..f08eb9cbee 100644
+--- a/qtbase/src/gui/painting/qpaintengine_raster.cpp
++++ b/qtbase/src/gui/painting/qpaintengine_raster.cpp
+@@ -560,31 +560,6 @@ void QRasterPaintEngine::updateMatrix(const QTransform &matrix)
+ QRasterPaintEngineState *s = state();
+ // FALCON: get rid of this line, see drawImage call below.
+ s->matrix = matrix;
+- QTransform::TransformationType txop = s->matrix.type();
+-
+- switch (txop) {
+-
+- case QTransform::TxNone:
+- s->flags.int_xform = true;
+- break;
+-
+- case QTransform::TxTranslate:
+- s->flags.int_xform = qreal(int(s->matrix.dx())) == s->matrix.dx()
+- && qreal(int(s->matrix.dy())) == s->matrix.dy();
+- break;
+-
+- case QTransform::TxScale:
+- s->flags.int_xform = qreal(int(s->matrix.dx())) == s->matrix.dx()
+- && qreal(int(s->matrix.dy())) == s->matrix.dy()
+- && qreal(int(s->matrix.m11())) == s->matrix.m11()
+- && qreal(int(s->matrix.m22())) == s->matrix.m22();
+- break;
+-
+- default: // shear / perspective...
+- s->flags.int_xform = false;
+- break;
+- }
+-
+ s->flags.tx_noshear = qt_scaleForTransform(s->matrix, &s->txscale);
+
+ ensureOutlineMapper();
+@@ -617,7 +592,6 @@ QRasterPaintEngineState::QRasterPaintEngineState()
+ flags.bilinear = false;
+ flags.legacy_rounding = false;
+ flags.fast_text = true;
+- flags.int_xform = true;
+ flags.tx_noshear = true;
+ flags.fast_images = true;
+
+@@ -1793,7 +1767,7 @@ void QRasterPaintEngine::fill(const QVectorPath &path, const QBrush &brush)
+ QRectF cpRect = path.controlPointRect();
+ const QRectF pathDeviceRect = s->matrix.mapRect(cpRect);
+ // Skip paths that by conservative estimates are completely outside the paint device.
+- if (!pathDeviceRect.intersects(QRectF(d->deviceRect)))
++ if (!pathDeviceRect.intersects(QRectF(d->deviceRect)) || !pathDeviceRect.isValid())
+ return;
+
+ ProcessSpans blend = d->getBrushFunc(pathDeviceRect, &s->brushData);
+diff --git a/qtbase/src/gui/painting/qpaintengine_raster_p.h b/qtbase/src/gui/painting/qpaintengine_raster_p.h
+index 089aadc3f7..bf7363d5aa 100644
+--- a/qtbase/src/gui/painting/qpaintengine_raster_p.h
++++ b/qtbase/src/gui/painting/qpaintengine_raster_p.h
+@@ -111,7 +111,6 @@ public:
+ uint bilinear : 1;
+ uint legacy_rounding : 1;
+ uint fast_text : 1;
+- uint int_xform : 1;
+ uint tx_noshear : 1;
+ uint fast_images : 1;
+ };
+diff --git a/qtbase/src/gui/painting/qpainterpath.cpp b/qtbase/src/gui/painting/qpainterpath.cpp
+index f9544a3241..d80fafeaf1 100644
+--- a/qtbase/src/gui/painting/qpainterpath.cpp
++++ b/qtbase/src/gui/painting/qpainterpath.cpp
+@@ -1253,7 +1253,7 @@ void QPainterPath::addText(const QPointF &point, const QFont &f, const QString &
+
+ if (si.analysis.flags < QScriptAnalysis::TabOrObject) {
+ QGlyphLayout glyphs = eng->shapedGlyphs(&si);
+- QFontEngine *fe = f.d->engineForScript(si.analysis.script);
++ QFontEngine *fe = eng->fontEngine(si);
+ Q_ASSERT(fe);
+ fe->addOutlineToPath(x, y, glyphs, this,
+ si.analysis.bidiLevel % 2
+diff --git a/qtbase/src/gui/painting/qpathclipper_p.h b/qtbase/src/gui/painting/qpathclipper_p.h
+index 9444a87b71..18f64c5e8c 100644
+--- a/qtbase/src/gui/painting/qpathclipper_p.h
++++ b/qtbase/src/gui/painting/qpathclipper_p.h
+@@ -156,7 +156,7 @@ public:
+ int vertex(Direction direction) const;
+
+ private:
+- int m_next[2][2];
++ int m_next[2][2] = { { -1, -1 }, { -1, -1 } };
+ };
+
+ class QPathSegments
+@@ -296,10 +296,6 @@ inline QPathEdge::QPathEdge(int a, int b)
+ , angle(0)
+ , invAngle(0)
+ {
+- m_next[0][0] = -1;
+- m_next[1][0] = -1;
+- m_next[0][0] = -1;
+- m_next[1][0] = -1;
+ }
+
+ inline int QPathEdge::next(Traversal traversal, Direction direction) const
+diff --git a/qtbase/src/gui/painting/qpdf.cpp b/qtbase/src/gui/painting/qpdf.cpp
+index 3066744f1b..2c8d3c3b53 100644
+--- a/qtbase/src/gui/painting/qpdf.cpp
++++ b/qtbase/src/gui/painting/qpdf.cpp
+@@ -2760,6 +2760,8 @@ int QPdfEnginePrivate::addBrushPattern(const QTransform &m, bool *specifyColor,
+ return gradientBrush(brush, matrix, gStateObject);
+ }
+
++ matrix = brush.transform() * matrix;
++
+ if ((!brush.isOpaque() && brush.style() < Qt::LinearGradientPattern) || opacity != 1.0)
+ *gStateObject = addConstantAlphaObject(qRound(brush.color().alpha() * opacity),
+ qRound(pen.color().alpha() * opacity));
+diff --git a/qtbase/src/gui/painting/qstroker.cpp b/qtbase/src/gui/painting/qstroker.cpp
+index cb5d395e80..3b6357a893 100644
+--- a/qtbase/src/gui/painting/qstroker.cpp
++++ b/qtbase/src/gui/painting/qstroker.cpp
+@@ -1182,6 +1182,7 @@ void QDashStroker::processCurrentSubpath()
+ // Check if the entire line should be clipped away or simplified
+ bool clipIt = clipping && !lineIntersectsRect(prev, e, clip_tl, clip_br);
+ bool skipDashing = elen * invSumLength > repetitionLimit();
++ int maxDashes = dashCount;
+ if (skipDashing || clipIt) {
+ // Cut away full dash sequences.
+ elen -= std::floor(elen * invSumLength) * sumLength;
+@@ -1196,7 +1197,7 @@ void QDashStroker::processCurrentSubpath()
+ pos = estop; // move pos to next path element
+ done = true;
+ } else { // Dash is on this line
+- pos = dpos + estart;
++ pos = --maxDashes > 0 ? dpos + estart : estop;
+ done = pos >= estop;
+ if (++idash >= dashCount)
+ idash = 0;
+diff --git a/qtbase/src/gui/painting/qt_attribution.json b/qtbase/src/gui/painting/qt_attribution.json
+index 7b16e8c211..0e87d30aa2 100644
+--- a/qtbase/src/gui/painting/qt_attribution.json
++++ b/qtbase/src/gui/painting/qt_attribution.json
+@@ -10,7 +10,7 @@
+ "Homepage": "http://www.freetype.org",
+ "License": "Freetype Project License or GNU General Public License v2.0 only",
+ "LicenseId": "FTL or GPL-2.0",
+- "LicenseFile": "../../3rdparty/freetype/docs/LICENSE.TXT",
++ "LicenseFile": "../../3rdparty/freetype/LICENSE.TXT",
+ "Copyright": "Copyright 2000-2016 by David Turner, Robert Wilhelm, and Werner Lemberg."
+ },
+ {
+diff --git a/qtbase/src/gui/rhi/qshader_p_p.h b/qtbase/src/gui/rhi/qshader_p_p.h
+index ec9d25971f..4a5a7a6d51 100644
+--- a/qtbase/src/gui/rhi/qshader_p_p.h
++++ b/qtbase/src/gui/rhi/qshader_p_p.h
+@@ -68,13 +68,13 @@ struct Q_GUI_EXPORT QShaderPrivate
+ {
+ }
+
+- QShaderPrivate(const QShaderPrivate *other)
++ QShaderPrivate(const QShaderPrivate &other)
+ : ref(1),
+- qsbVersion(other->qsbVersion),
+- stage(other->stage),
+- desc(other->desc),
+- shaders(other->shaders),
+- bindings(other->bindings)
++ qsbVersion(other.qsbVersion),
++ stage(other.stage),
++ desc(other.desc),
++ shaders(other.shaders),
++ bindings(other.bindings)
+ {
+ }
+
+diff --git a/qtbase/src/gui/rhi/qshaderdescription_p_p.h b/qtbase/src/gui/rhi/qshaderdescription_p_p.h
+index ec2b0b6b4c..3da33a8a2b 100644
+--- a/qtbase/src/gui/rhi/qshaderdescription_p_p.h
++++ b/qtbase/src/gui/rhi/qshaderdescription_p_p.h
+@@ -63,16 +63,16 @@ struct Q_GUI_EXPORT QShaderDescriptionPrivate
+ localSize[0] = localSize[1] = localSize[2] = 0;
+ }
+
+- QShaderDescriptionPrivate(const QShaderDescriptionPrivate *other)
++ QShaderDescriptionPrivate(const QShaderDescriptionPrivate &other)
+ : ref(1),
+- inVars(other->inVars),
+- outVars(other->outVars),
+- uniformBlocks(other->uniformBlocks),
+- pushConstantBlocks(other->pushConstantBlocks),
+- storageBlocks(other->storageBlocks),
+- combinedImageSamplers(other->combinedImageSamplers),
+- storageImages(other->storageImages),
+- localSize(other->localSize)
++ inVars(other.inVars),
++ outVars(other.outVars),
++ uniformBlocks(other.uniformBlocks),
++ pushConstantBlocks(other.pushConstantBlocks),
++ storageBlocks(other.storageBlocks),
++ combinedImageSamplers(other.combinedImageSamplers),
++ storageImages(other.storageImages),
++ localSize(other.localSize)
+ {
+ }
+
+diff --git a/qtbase/src/gui/text/qfontdatabase.cpp b/qtbase/src/gui/text/qfontdatabase.cpp
+index a657a8c516..4fc0100958 100644
+--- a/qtbase/src/gui/text/qfontdatabase.cpp
++++ b/qtbase/src/gui/text/qfontdatabase.cpp
+@@ -983,7 +983,7 @@ QFontEngine *loadSingleEngine(int script,
+ if (style->key.stretch != 0 && request.stretch != 0
+ && (request.styleName.isEmpty() || request.styleName != style->styleName)) {
+ def.stretch = (request.stretch * 100 + style->key.stretch / 2) / style->key.stretch;
+- } else {
++ } else if (request.stretch == QFont::AnyStretch) {
+ def.stretch = 100;
+ }
+
+diff --git a/qtbase/src/gui/text/qtextdocumentlayout.cpp b/qtbase/src/gui/text/qtextdocumentlayout.cpp
+index f3e6ea2100..72267e9380 100644
+--- a/qtbase/src/gui/text/qtextdocumentlayout.cpp
++++ b/qtbase/src/gui/text/qtextdocumentlayout.cpp
+@@ -2123,7 +2123,7 @@ void QTextDocumentLayoutPrivate::drawListItem(const QPointF &offset, QPainter *p
+ {
+ Q_Q(const QTextDocumentLayout);
+ const QTextBlockFormat blockFormat = bl.blockFormat();
+- const QTextCharFormat charFormat = QTextCursor(bl).charFormat();
++ const QTextCharFormat charFormat = bl.charFormat();
+ QFont font(charFormat.font());
+ if (q->paintDevice())
+ font = QFont(font, q->paintDevice());
+diff --git a/qtbase/src/gui/text/qtextengine.cpp b/qtbase/src/gui/text/qtextengine.cpp
+index ce4abac472..a6c66e5d2d 100644
+--- a/qtbase/src/gui/text/qtextengine.cpp
++++ b/qtbase/src/gui/text/qtextengine.cpp
+@@ -1,6 +1,6 @@
+ /****************************************************************************
+ **
+-** Copyright (C) 2016 The Qt Company Ltd.
++** Copyright (C) 2021 The Qt Company Ltd.
+ ** Contact: https://www.qt.io/licensing/
+ **
+ ** This file is part of the QtGui module of the Qt Toolkit.
+@@ -1565,6 +1565,12 @@ void QTextEngine::shapeText(int item) const
+ // Overwrite with 0 token to indicate failure
+ QGlyphLayout g = availableGlyphs(&si);
+ g.glyphs[0] = 0;
++ g.attributes[0].clusterStart = true;
++
++ ushort *log_clusters = logClusters(&si);
++ for (int i = 0; i < itemLength; ++i)
++ log_clusters[i] = 0;
++
+ return;
+ }
+
+diff --git a/qtbase/src/gui/util/qdesktopservices.cpp b/qtbase/src/gui/util/qdesktopservices.cpp
+index fbb63a9408..4d5fafaaa7 100644
+--- a/qtbase/src/gui/util/qdesktopservices.cpp
++++ b/qtbase/src/gui/util/qdesktopservices.cpp
+@@ -54,6 +54,8 @@
+ #include <qpa/qplatformintegration.h>
+ #include <qdir.h>
+
++#include <QtCore/private/qlocking_p.h>
++
+ QT_BEGIN_NAMESPACE
+
+ class QOpenUrlHandlerRegistry : public QObject
+@@ -81,6 +83,7 @@ Q_GLOBAL_STATIC(QOpenUrlHandlerRegistry, handlerRegistry)
+
+ void QOpenUrlHandlerRegistry::handlerDestroyed(QObject *handler)
+ {
++ const auto lock = qt_scoped_lock(mutex);
+ HandlerHash::Iterator it = handlers.begin();
+ while (it != handlers.end()) {
+ if (it->receiver == handler) {
+@@ -294,7 +297,8 @@ void QDesktopServices::setUrlHandler(const QString &scheme, QObject *receiver, c
+ h.name = method;
+ registry->handlers.insert(scheme.toLower(), h);
+ QObject::connect(receiver, SIGNAL(destroyed(QObject*)),
+- registry, SLOT(handlerDestroyed(QObject*)));
++ registry, SLOT(handlerDestroyed(QObject*)),
++ Qt::DirectConnection);
+ }
+
+ /*!
+diff --git a/qtbase/src/gui/util/qpkmhandler.cpp b/qtbase/src/gui/util/qpkmhandler.cpp
+index e0c3b75efe..3414f9d8ba 100644
+--- a/qtbase/src/gui/util/qpkmhandler.cpp
++++ b/qtbase/src/gui/util/qpkmhandler.cpp
+@@ -57,7 +57,7 @@ struct PkmType
+ quint32 bytesPerBlock;
+ };
+
+-static PkmType typeMap[5] = {
++static constexpr PkmType typeMap[5] = {
+ { 0x8D64, 8 }, // GL_ETC1_RGB8_OES
+ { 0x9274, 8 }, // GL_COMPRESSED_RGB8_ETC2
+ { 0, 0 }, // unused (obsolete)
+diff --git a/qtbase/src/network/access/qnetworkreplyfileimpl.cpp b/qtbase/src/network/access/qnetworkreplyfileimpl.cpp
+index b6be93147a..6e69b4c4d3 100644
+--- a/qtbase/src/network/access/qnetworkreplyfileimpl.cpp
++++ b/qtbase/src/network/access/qnetworkreplyfileimpl.cpp
+@@ -89,9 +89,10 @@ QNetworkReplyFileImpl::QNetworkReplyFileImpl(QNetworkAccessManager *manager, con
+ // we handle only local files
+ QString msg = QCoreApplication::translate("QNetworkAccessFileBackend", "Request for opening non-local file %1").arg(url.toString());
+ setError(QNetworkReply::ProtocolInvalidOperationError, msg);
++ setFinished(true); // We're finished, will emit finished() after ctor is done.
+ QMetaObject::invokeMethod(this, "errorOccurred", Qt::QueuedConnection,
+ Q_ARG(QNetworkReply::NetworkError, QNetworkReply::ProtocolInvalidOperationError));
+- fileOpenFinished(false);
++ QMetaObject::invokeMethod(this, [this](){ fileOpenFinished(false); }, Qt::QueuedConnection);
+ return;
+ }
+ #endif
+diff --git a/qtbase/src/network/access/qnetworkreplyimpl.cpp b/qtbase/src/network/access/qnetworkreplyimpl.cpp
+index bcdf6ee2f1..3b6deb82bd 100644
+--- a/qtbase/src/network/access/qnetworkreplyimpl.cpp
++++ b/qtbase/src/network/access/qnetworkreplyimpl.cpp
+@@ -680,7 +680,7 @@ void QNetworkReplyImplPrivate::appendDownstreamData(QIODevice *data)
+ // read until EOF from data
+ if (Q_UNLIKELY(copyDevice)) {
+ qCritical("QNetworkReplyImpl: copy from QIODevice already in progress -- "
+- "backend probly needs to be fixed");
++ "backend probably needs to be fixed");
+ return;
+ }
+
+diff --git a/qtbase/src/network/kernel/qauthenticator.cpp b/qtbase/src/network/kernel/qauthenticator.cpp
+index d9fe7bc47b..ccd04b294a 100644
+--- a/qtbase/src/network/kernel/qauthenticator.cpp
++++ b/qtbase/src/network/kernel/qauthenticator.cpp
+@@ -50,6 +50,7 @@
+ #include <qstring.h>
+ #include <qdatetime.h>
+ #include <qrandom.h>
++#include "private/qsystemlibrary_p.h"
+
+ #ifdef Q_OS_WIN
+ #include <qmutex.h>
+@@ -1563,7 +1564,7 @@ static bool q_SSPI_library_load()
+
+ // Initialize security interface
+ if (pSecurityFunctionTable == nullptr) {
+- securityDLLHandle = LoadLibrary(L"secur32.dll");
++ securityDLLHandle = QSystemLibrary::load(L"secur32");
+ if (securityDLLHandle != nullptr) {
+ INIT_SECURITY_INTERFACE pInitSecurityInterface =
+ reinterpret_cast<INIT_SECURITY_INTERFACE>(
+diff --git a/qtbase/src/network/kernel/qhostinfo_unix.cpp b/qtbase/src/network/kernel/qhostinfo_unix.cpp
+index 9b0a2ee669..73679c9ef1 100644
+--- a/qtbase/src/network/kernel/qhostinfo_unix.cpp
++++ b/qtbase/src/network/kernel/qhostinfo_unix.cpp
+@@ -122,7 +122,6 @@ static QFunctionPointer resolveSymbol(QLibrary &lib, const char *sym)
+
+ LibResolv::LibResolv()
+ {
+- QLibrary lib;
+ #ifdef LIBRESOLV_SO
+ lib.setFileName(QStringLiteral(LIBRESOLV_SO));
+ if (!lib.load())
+diff --git a/qtbase/src/network/socket/qsocks5socketengine.cpp b/qtbase/src/network/socket/qsocks5socketengine.cpp
+index 3a046fd116..97fadca0b3 100644
+--- a/qtbase/src/network/socket/qsocks5socketengine.cpp
++++ b/qtbase/src/network/socket/qsocks5socketengine.cpp
+@@ -1296,7 +1296,7 @@ void QSocks5SocketEnginePrivate::_q_udpSocketReadNotification()
+ int pos = 0;
+ const char *buf = inBuf.constData();
+ if (inBuf.size() < 4) {
+- QSOCKS5_D_DEBUG << "bugus udp data, discarding";
++ QSOCKS5_D_DEBUG << "bogus udp data, discarding";
+ return;
+ }
+ QSocks5RevivedDatagram datagram;
+diff --git a/qtbase/src/network/ssl/qsslcontext_openssl.cpp b/qtbase/src/network/ssl/qsslcontext_openssl.cpp
+index c9f202f573..c992da9d8e 100644
+--- a/qtbase/src/network/ssl/qsslcontext_openssl.cpp
++++ b/qtbase/src/network/ssl/qsslcontext_openssl.cpp
+@@ -409,7 +409,7 @@ init_context:
+ break;
+ case QSsl::DtlsV1_0OrLater:
+ minVersion = DTLS1_VERSION;
+- maxVersion = DTLS_MAX_VERSION;
++ maxVersion = 0;
+ break;
+ case QSsl::DtlsV1_2:
+ minVersion = DTLS1_2_VERSION;
+@@ -417,7 +417,7 @@ init_context:
+ break;
+ case QSsl::DtlsV1_2OrLater:
+ minVersion = DTLS1_2_VERSION;
+- maxVersion = DTLS_MAX_VERSION;
++ maxVersion = 0;
+ break;
+ case QSsl::TlsV1_3OrLater:
+ #ifdef TLS1_3_VERSION
+@@ -455,7 +455,7 @@ init_context:
+ }
+
+ // Enable bug workarounds.
+- long options = QSslSocketBackendPrivate::setupOpenSslOptions(configuration.protocol(), configuration.d->sslOptions);
++ qssloptions options = QSslSocketBackendPrivate::setupOpenSslOptions(configuration.protocol(), configuration.d->sslOptions);
+ q_SSL_CTX_set_options(sslContext->ctx, options);
+
+ // Tell OpenSSL to release memory early
+diff --git a/qtbase/src/network/ssl/qssldiffiehellmanparameters_openssl.cpp b/qtbase/src/network/ssl/qssldiffiehellmanparameters_openssl.cpp
+index aaf8741130..b58935372c 100644
+--- a/qtbase/src/network/ssl/qssldiffiehellmanparameters_openssl.cpp
++++ b/qtbase/src/network/ssl/qssldiffiehellmanparameters_openssl.cpp
+@@ -59,57 +59,6 @@
+
+ QT_BEGIN_NAMESPACE
+
+-#ifdef OPENSSL_NO_DEPRECATED_3_0
+-
+-static int q_DH_check(DH *dh, int *status)
+-{
+- // DH_check was first deprecated in OpenSSL 3.0.0, as low-level
+- // API; the EVP_PKEY family of functions was advised as an alternative.
+- // As of now EVP_PKEY_params_check ends up calling ... DH_check,
+- // which is good enough.
+-
+- Q_ASSERT(dh);
+- Q_ASSERT(status);
+-
+- EVP_PKEY *key = q_EVP_PKEY_new();
+- if (!key) {
+- qCWarning(lcSsl, "EVP_PKEY_new failed");
+- QSslSocketBackendPrivate::logAndClearErrorQueue();
+- return 0;
+- }
+- const auto keyDeleter = qScopeGuard([key](){
+- q_EVP_PKEY_free(key);
+- });
+- if (!q_EVP_PKEY_set1_DH(key, dh)) {
+- qCWarning(lcSsl, "EVP_PKEY_set1_DH failed");
+- QSslSocketBackendPrivate::logAndClearErrorQueue();
+- return 0;
+- }
+-
+- EVP_PKEY_CTX *keyCtx = q_EVP_PKEY_CTX_new(key, nullptr);
+- if (!keyCtx) {
+- qCWarning(lcSsl, "EVP_PKEY_CTX_new failed");
+- QSslSocketBackendPrivate::logAndClearErrorQueue();
+- return 0;
+- }
+- const auto ctxDeleter = qScopeGuard([keyCtx]{
+- q_EVP_PKEY_CTX_free(keyCtx);
+- });
+-
+- const int result = q_EVP_PKEY_param_check(keyCtx);
+- QSslSocketBackendPrivate::logAndClearErrorQueue();
+- // Note: unlike DH_check, we cannot obtain the 'status',
+- // if the 'result' is 0 (actually the result is 1 only
+- // if this 'status' was 0). We could probably check the
+- // errors from the error queue, but it's not needed anyway
+- // - see the 'isSafeDH' below, how it returns immediately
+- // on 0.
+- Q_UNUSED(status)
+-
+- return result;
+-}
+-#endif // OPENSSL_NO_DEPRECATED_3_0
+-
+ static bool isSafeDH(DH *dh)
+ {
+ int status = 0;
+diff --git a/qtbase/src/network/ssl/qsslsocket_openssl.cpp b/qtbase/src/network/ssl/qsslsocket_openssl.cpp
+index 37fad2a68f..8f6858c867 100644
+--- a/qtbase/src/network/ssl/qsslsocket_openssl.cpp
++++ b/qtbase/src/network/ssl/qsslsocket_openssl.cpp
+@@ -550,9 +550,9 @@ static void q_loadCiphersForConnection(SSL *connection, QList<QSslCipher> &ciphe
+ // Defined in qsslsocket.cpp
+ void q_setDefaultDtlsCiphers(const QList<QSslCipher> &ciphers);
+
+-long QSslSocketBackendPrivate::setupOpenSslOptions(QSsl::SslProtocol protocol, QSsl::SslOptions sslOptions)
++qssloptions QSslSocketBackendPrivate::setupOpenSslOptions(QSsl::SslProtocol protocol, QSsl::SslOptions sslOptions)
+ {
+- long options;
++ qssloptions options;
+ if (protocol == QSsl::TlsV1SslV3)
+ options = SSL_OP_ALL|SSL_OP_NO_SSLv2|SSL_OP_NO_SSLv3;
+ else if (protocol == QSsl::SecureProtocols)
+diff --git a/qtbase/src/network/ssl/qsslsocket_openssl_p.h b/qtbase/src/network/ssl/qsslsocket_openssl_p.h
+index 4103de23e8..5547589256 100644
+--- a/qtbase/src/network/ssl/qsslsocket_openssl_p.h
++++ b/qtbase/src/network/ssl/qsslsocket_openssl_p.h
+@@ -107,6 +107,12 @@
+
+ QT_BEGIN_NAMESPACE
+
++#if defined(OPENSSL_VERSION_MAJOR) && OPENSSL_VERSION_MAJOR >= 3
++typedef uint64_t qssloptions;
++#else
++typedef unsigned long qssloptions;
++#endif
++
+ struct QSslErrorEntry {
+ int code;
+ int depth;
+@@ -171,7 +177,7 @@ public:
+ QVector<QSslError> ocspErrors;
+ QByteArray ocspResponseDer;
+
+- Q_AUTOTEST_EXPORT static long setupOpenSslOptions(QSsl::SslProtocol protocol, QSsl::SslOptions sslOptions);
++ Q_AUTOTEST_EXPORT static qssloptions setupOpenSslOptions(QSsl::SslProtocol protocol, QSsl::SslOptions sslOptions);
+ static QSslCipher QSslCipher_from_SSL_CIPHER(const SSL_CIPHER *cipher);
+ static QList<QSslCertificate> STACKOFX509_to_QSslCertificates(STACK_OF(X509) *x509);
+ static QList<QSslError> verify(const QList<QSslCertificate> &certificateChain, const QString &hostName);
+diff --git a/qtbase/src/network/ssl/qsslsocket_openssl_symbols.cpp b/qtbase/src/network/ssl/qsslsocket_openssl_symbols.cpp
+index e53fb279f0..459ccd0b19 100644
+--- a/qtbase/src/network/ssl/qsslsocket_openssl_symbols.cpp
++++ b/qtbase/src/network/ssl/qsslsocket_openssl_symbols.cpp
+@@ -148,7 +148,6 @@ DEFINEFUNC(int, EVP_PKEY_up_ref, EVP_PKEY *a, a, return 0, return)
+ DEFINEFUNC2(EVP_PKEY_CTX *, EVP_PKEY_CTX_new, EVP_PKEY *pkey, pkey, ENGINE *e, e, return nullptr, return)
+ DEFINEFUNC(int, EVP_PKEY_param_check, EVP_PKEY_CTX *ctx, ctx, return 0, return)
+ DEFINEFUNC(void, EVP_PKEY_CTX_free, EVP_PKEY_CTX *ctx, ctx, return, return)
+-DEFINEFUNC(int, EVP_PKEY_base_id, EVP_PKEY *a, a, return NID_undef, return)
+ DEFINEFUNC(int, RSA_bits, RSA *a, a, return 0, return)
+ DEFINEFUNC(int, DSA_bits, DSA *a, a, return 0, return)
+ DEFINEFUNC(int, OPENSSL_sk_num, OPENSSL_STACK *a, a, return -1, return)
+@@ -158,7 +157,7 @@ DEFINEFUNC2(void, OPENSSL_sk_push, OPENSSL_STACK *a, a, void *b, b, return, DUMM
+ DEFINEFUNC(void, OPENSSL_sk_free, OPENSSL_STACK *a, a, return, DUMMYARG)
+ DEFINEFUNC2(void *, OPENSSL_sk_value, OPENSSL_STACK *a, a, int b, b, return nullptr, return)
+ DEFINEFUNC(int, SSL_session_reused, SSL *a, a, return 0, return)
+-DEFINEFUNC2(unsigned long, SSL_CTX_set_options, SSL_CTX *ctx, ctx, unsigned long op, op, return 0, return)
++DEFINEFUNC2(qssloptions, SSL_CTX_set_options, SSL_CTX *ctx, ctx, qssloptions op, op, return 0, return)
+ DEFINEFUNC(int, SSL_CTX_get_security_level, const SSL_CTX *ctx, ctx, return -1, return)
+ DEFINEFUNC2(void, SSL_CTX_set_security_level, SSL_CTX *ctx, ctx, int level, level, return, return)
+ #ifdef TLS1_3_VERSION
+@@ -371,7 +370,15 @@ DEFINEFUNC(const SSL_CIPHER *, SSL_get_current_cipher, SSL *a, a, return nullptr
+ DEFINEFUNC(int, SSL_version, const SSL *a, a, return 0, return)
+ DEFINEFUNC2(int, SSL_get_error, SSL *a, a, int b, b, return -1, return)
+ DEFINEFUNC(STACK_OF(X509) *, SSL_get_peer_cert_chain, SSL *a, a, return nullptr, return)
++
++#if defined(OPENSSL_VERSION_MAJOR) && OPENSSL_VERSION_MAJOR >= 3
++DEFINEFUNC(X509 *, SSL_get1_peer_certificate, SSL *a, a, return nullptr, return)
++DEFINEFUNC(int, EVP_PKEY_get_base_id, const EVP_PKEY *pkey, pkey, return -1, return)
++#else
+ DEFINEFUNC(X509 *, SSL_get_peer_certificate, SSL *a, a, return nullptr, return)
++DEFINEFUNC(int, EVP_PKEY_base_id, EVP_PKEY *a, a, return NID_undef, return)
++#endif // OPENSSL_VERSION_MAJOR >= 3
++
+ DEFINEFUNC(long, SSL_get_verify_result, const SSL *a, a, return -1, return)
+ DEFINEFUNC(SSL *, SSL_new, SSL_CTX *a, a, return nullptr, return)
+ DEFINEFUNC(SSL_CTX *, SSL_get_SSL_CTX, SSL *a, a, return nullptr, return)
+@@ -492,9 +499,7 @@ DEFINEFUNC(DH *, DH_new, DUMMYARG, DUMMYARG, return nullptr, return)
+ DEFINEFUNC(void, DH_free, DH *dh, dh, return, DUMMYARG)
+ DEFINEFUNC3(DH *, d2i_DHparams, DH**a, a, const unsigned char **pp, pp, long length, length, return nullptr, return)
+ DEFINEFUNC2(int, i2d_DHparams, DH *a, a, unsigned char **p, p, return -1, return)
+-#ifndef OPENSSL_NO_DEPRECATED_3_0
+ DEFINEFUNC2(int, DH_check, DH *dh, dh, int *codes, codes, return 0, return)
+-#endif // OPENSSL_NO_DEPRECATED_3_0
+ DEFINEFUNC3(BIGNUM *, BN_bin2bn, const unsigned char *s, s, int len, len, BIGNUM *ret, ret, return nullptr, return)
+
+ #ifndef OPENSSL_NO_EC
+@@ -868,7 +873,6 @@ bool q_resolveOpenSslSymbols()
+ RESOLVEFUNC(EVP_PKEY_CTX_new)
+ RESOLVEFUNC(EVP_PKEY_param_check)
+ RESOLVEFUNC(EVP_PKEY_CTX_free)
+- RESOLVEFUNC(EVP_PKEY_base_id)
+ RESOLVEFUNC(RSA_bits)
+ RESOLVEFUNC(OPENSSL_sk_new_null)
+ RESOLVEFUNC(OPENSSL_sk_push)
+@@ -1107,7 +1111,15 @@ bool q_resolveOpenSslSymbols()
+ RESOLVEFUNC(SSL_version)
+ RESOLVEFUNC(SSL_get_error)
+ RESOLVEFUNC(SSL_get_peer_cert_chain)
++
++#if defined(OPENSSL_VERSION_MAJOR) && OPENSSL_VERSION_MAJOR >= 3
++ RESOLVEFUNC(SSL_get1_peer_certificate)
++ RESOLVEFUNC(EVP_PKEY_get_base_id)
++#else
+ RESOLVEFUNC(SSL_get_peer_certificate)
++ RESOLVEFUNC(EVP_PKEY_base_id)
++#endif // OPENSSL_VERSION_MAJOR >= 3
++
+ RESOLVEFUNC(SSL_get_verify_result)
+ RESOLVEFUNC(SSL_new)
+ RESOLVEFUNC(SSL_get_SSL_CTX)
+@@ -1206,9 +1218,7 @@ bool q_resolveOpenSslSymbols()
+ RESOLVEFUNC(DH_free)
+ RESOLVEFUNC(d2i_DHparams)
+ RESOLVEFUNC(i2d_DHparams)
+-#ifndef OPENSSL_NO_DEPRECATED_3_0
+ RESOLVEFUNC(DH_check)
+-#endif // OPENSSL_NO_DEPRECATED_3_0
+ RESOLVEFUNC(BN_bin2bn)
+
+ #ifndef OPENSSL_NO_EC
+diff --git a/qtbase/src/network/ssl/qsslsocket_openssl_symbols_p.h b/qtbase/src/network/ssl/qsslsocket_openssl_symbols_p.h
+index 95e8897a3b..27aeffa18a 100644
+--- a/qtbase/src/network/ssl/qsslsocket_openssl_symbols_p.h
++++ b/qtbase/src/network/ssl/qsslsocket_openssl_symbols_p.h
+@@ -237,7 +237,6 @@ Q_AUTOTEST_EXPORT int q_EVP_PKEY_up_ref(EVP_PKEY *a);
+ EVP_PKEY_CTX *q_EVP_PKEY_CTX_new(EVP_PKEY *pkey, ENGINE *e);
+ void q_EVP_PKEY_CTX_free(EVP_PKEY_CTX *ctx);
+ int q_EVP_PKEY_param_check(EVP_PKEY_CTX *ctx);
+-int q_EVP_PKEY_base_id(EVP_PKEY *a);
+ int q_RSA_bits(RSA *a);
+ Q_AUTOTEST_EXPORT int q_OPENSSL_sk_num(OPENSSL_STACK *a);
+ Q_AUTOTEST_EXPORT void q_OPENSSL_sk_pop_free(OPENSSL_STACK *a, void (*b)(void *));
+@@ -246,7 +245,7 @@ Q_AUTOTEST_EXPORT void q_OPENSSL_sk_push(OPENSSL_STACK *st, void *data);
+ Q_AUTOTEST_EXPORT void q_OPENSSL_sk_free(OPENSSL_STACK *a);
+ Q_AUTOTEST_EXPORT void * q_OPENSSL_sk_value(OPENSSL_STACK *a, int b);
+ int q_SSL_session_reused(SSL *a);
+-unsigned long q_SSL_CTX_set_options(SSL_CTX *ctx, unsigned long op);
++qssloptions q_SSL_CTX_set_options(SSL_CTX *ctx, qssloptions op);
+ int q_OPENSSL_init_ssl(uint64_t opts, const OPENSSL_INIT_SETTINGS *settings);
+ size_t q_SSL_get_client_random(SSL *a, unsigned char *out, size_t outlen);
+ size_t q_SSL_SESSION_get_master_key(const SSL_SESSION *session, unsigned char *out, size_t outlen);
+@@ -510,7 +509,6 @@ const SSL_CIPHER *q_SSL_get_current_cipher(SSL *a);
+ int q_SSL_version(const SSL *a);
+ int q_SSL_get_error(SSL *a, int b);
+ STACK_OF(X509) *q_SSL_get_peer_cert_chain(SSL *a);
+-X509 *q_SSL_get_peer_certificate(SSL *a);
+ long q_SSL_get_verify_result(const SSL *a);
+ SSL *q_SSL_new(SSL_CTX *a);
+ SSL_CTX *q_SSL_get_SSL_CTX(SSL *a);
+@@ -582,10 +580,7 @@ DH *q_DH_new();
+ void q_DH_free(DH *dh);
+ DH *q_d2i_DHparams(DH **a, const unsigned char **pp, long length);
+ int q_i2d_DHparams(DH *a, unsigned char **p);
+-
+-#ifndef OPENSSL_NO_DEPRECATED_3_0
+ int q_DH_check(DH *dh, int *codes);
+-#endif // OPENSSL_NO_DEPRECATED_3_0
+
+ BIGNUM *q_BN_bin2bn(const unsigned char *s, int len, BIGNUM *ret);
+ #define q_SSL_CTX_set_tmp_dh(ctx, dh) q_SSL_CTX_ctrl((ctx), SSL_CTRL_SET_TMP_DH, 0, (char *)dh)
+@@ -754,6 +749,17 @@ void q_CRYPTO_free(void *str, const char *file, int line);
+ int q_SSL_CTX_get_security_level(const SSL_CTX *ctx);
+ void q_SSL_CTX_set_security_level(SSL_CTX *ctx, int level);
+
++// Here we have the ones that make difference between OpenSSL pre/post v3:
++#if defined(OPENSSL_VERSION_MAJOR) && OPENSSL_VERSION_MAJOR >= 3
++X509 *q_SSL_get1_peer_certificate(SSL *a);
++#define q_SSL_get_peer_certificate q_SSL_get1_peer_certificate
++int q_EVP_PKEY_get_base_id(const EVP_PKEY *pkey);
++#define q_EVP_PKEY_base_id q_EVP_PKEY_get_base_id
++#else
++X509 *q_SSL_get_peer_certificate(SSL *a);
++int q_EVP_PKEY_base_id(EVP_PKEY *a);
++#endif // OPENSSL_VERSION_MAJOR >= 3
++
+ QT_END_NAMESPACE
+
+ #endif
+diff --git a/qtbase/src/platformsupport/eglconvenience/qt_egl_p.h b/qtbase/src/platformsupport/eglconvenience/qt_egl_p.h
+index bf37d07fd8..dbd42fb799 100644
+--- a/qtbase/src/platformsupport/eglconvenience/qt_egl_p.h
++++ b/qtbase/src/platformsupport/eglconvenience/qt_egl_p.h
+@@ -61,7 +61,11 @@
+ # if !defined(Q_OS_INTEGRITY)
+ # define WIN_INTERFACE_CUSTOM // NV
+ # endif // Q_OS_INTEGRITY
+-#endif // QT_EGL_NO_X11
++#else // QT_EGL_NO_X11
++// If one has an eglplatform.h with https://github.com/KhronosGroup/EGL-Registry/pull/130
++// that needs USE_X11 to be defined.
++# define USE_X11
++#endif
+
+ #ifdef QT_EGL_WAYLAND
+ # define WAYLAND // NV
+diff --git a/qtbase/src/platformsupport/fontdatabases/fontconfig/qfontconfigdatabase.cpp b/qtbase/src/platformsupport/fontdatabases/fontconfig/qfontconfigdatabase.cpp
+index 159b490ce0..00aa80cd58 100644
+--- a/qtbase/src/platformsupport/fontdatabases/fontconfig/qfontconfigdatabase.cpp
++++ b/qtbase/src/platformsupport/fontdatabases/fontconfig/qfontconfigdatabase.cpp
+@@ -567,6 +567,8 @@ void QFontconfigDatabase::populateFontDatabase()
+ fonts = FcFontList(nullptr, pattern, os);
+ FcObjectSetDestroy(os);
+ FcPatternDestroy(pattern);
++ if (!fonts)
++ return;
+ }
+
+ for (int i = 0; i < fonts->nfont; i++)
+diff --git a/qtbase/src/platformsupport/input/xkbcommon/qxkbcommon.cpp b/qtbase/src/platformsupport/input/xkbcommon/qxkbcommon.cpp
+index b713c19447..7cb9a8c79a 100644
+--- a/qtbase/src/platformsupport/input/xkbcommon/qxkbcommon.cpp
++++ b/qtbase/src/platformsupport/input/xkbcommon/qxkbcommon.cpp
+@@ -95,6 +95,7 @@ static constexpr const auto KeyTbl = qMakeArray(
+ Xkb2Qt<XKB_KEY_Clear, Qt::Key_Delete>,
+ Xkb2Qt<XKB_KEY_Pause, Qt::Key_Pause>,
+ Xkb2Qt<XKB_KEY_Print, Qt::Key_Print>,
++ Xkb2Qt<XKB_KEY_Sys_Req, Qt::Key_SysReq>,
+ Xkb2Qt<0x1005FF60, Qt::Key_SysReq>, // hardcoded Sun SysReq
+ Xkb2Qt<0x1007ff00, Qt::Key_SysReq>, // hardcoded X386 SysReq
+
+@@ -471,7 +472,7 @@ QVector<xkb_keysym_t> QXkbCommon::toKeysym(QKeyEvent *event)
+ } else if (event->modifiers() & Qt::KeypadModifier) {
+ if (qtKey >= Qt::Key_0 && qtKey <= Qt::Key_9)
+ keysyms.append(XKB_KEY_KP_0 + (qtKey - Qt::Key_0));
+- } else if (isLatin(qtKey) && event->text().isUpper()) {
++ } else if (isLatin1(qtKey) && event->text().isUpper()) {
+ keysyms.append(qtKey);
+ }
+
+@@ -523,7 +524,7 @@ int QXkbCommon::keysymToQtKey(xkb_keysym_t keysym, Qt::KeyboardModifiers modifie
+ // With standard shortcuts we should prefer a latin character, this is
+ // for checks like "some qkeyevent == QKeySequence::Copy" to work even
+ // when using for example 'russian' keyboard layout.
+- if (!QXkbCommon::isLatin(keysym)) {
++ if (!QXkbCommon::isLatin1(keysym)) {
+ xkb_keysym_t latinKeysym = QXkbCommon::lookupLatinKeysym(state, code);
+ if (latinKeysym != XKB_KEY_NoSymbol)
+ keysym = latinKeysym;
+@@ -546,7 +547,7 @@ static int keysymToQtKey_internal(xkb_keysym_t keysym, Qt::KeyboardModifiers mod
+ } else if (keysym >= XKB_KEY_KP_0 && keysym <= XKB_KEY_KP_9) {
+ // numeric keypad keys
+ qtKey = Qt::Key_0 + (keysym - XKB_KEY_KP_0);
+- } else if (QXkbCommon::isLatin(keysym)) {
++ } else if (QXkbCommon::isLatin1(keysym)) {
+ qtKey = QXkbCommon::qxkbcommon_xkb_keysym_to_upper(keysym);
+ } else {
+ // check if we have a direct mapping
+@@ -678,7 +679,7 @@ QList<int> QXkbCommon::possibleKeys(xkb_state *state, const QKeyEvent *event,
+ Qt::KeyboardModifiers neededMods = ModsTbl[i];
+ if ((modifiers & neededMods) == neededMods) {
+ if (i == 8) {
+- if (isLatin(baseQtKey))
++ if (isLatin1(baseQtKey))
+ continue;
+ // add a latin key as a fall back key
+ sym = lookupLatinKeysym(state, keycode);
+@@ -733,7 +734,7 @@ void QXkbCommon::verifyHasLatinLayout(xkb_keymap *keymap)
+ for (xkb_layout_index_t layout = 0; layout < layoutCount; ++layout) {
+ for (xkb_keycode_t code = minKeycode; code < maxKeycode; ++code) {
+ xkb_keymap_key_get_syms_by_level(keymap, code, layout, 0, &keysyms);
+- if (keysyms && isLatin(keysyms[0]))
++ if (keysyms && isLatin1(keysyms[0]))
+ nrLatinKeys++;
+ if (nrLatinKeys > 10) // arbitrarily chosen threshold
+ return;
+@@ -766,7 +767,7 @@ xkb_keysym_t QXkbCommon::lookupLatinKeysym(xkb_state *state, xkb_keycode_t keyco
+ xkb_level_index_t level = xkb_state_key_get_level(state, keycode, layout);
+ if (xkb_keymap_key_get_syms_by_level(keymap, keycode, layout, level, &syms) != 1)
+ continue;
+- if (isLatin(syms[0])) {
++ if (isLatin1(syms[0])) {
+ sym = syms[0];
+ break;
+ }
+diff --git a/qtbase/src/platformsupport/input/xkbcommon/qxkbcommon_p.h b/qtbase/src/platformsupport/input/xkbcommon/qxkbcommon_p.h
+index 561eae03db..8389bd8f5a 100644
+--- a/qtbase/src/platformsupport/input/xkbcommon/qxkbcommon_p.h
++++ b/qtbase/src/platformsupport/input/xkbcommon/qxkbcommon_p.h
+@@ -94,8 +94,8 @@ public:
+ static void verifyHasLatinLayout(xkb_keymap *keymap);
+ static xkb_keysym_t lookupLatinKeysym(xkb_state *state, xkb_keycode_t keycode);
+
+- static bool isLatin(xkb_keysym_t sym) {
+- return ((sym >= 'a' && sym <= 'z') || (sym >= 'A' && sym <= 'Z'));
++ static bool isLatin1(xkb_keysym_t sym) {
++ return sym <= 0xff;
+ }
+ static bool isKeypad(xkb_keysym_t sym) {
+ return sym >= XKB_KEY_KP_Space && sym <= XKB_KEY_KP_9;
+diff --git a/qtbase/src/platformsupport/kmsconvenience/qkmsdevice.cpp b/qtbase/src/platformsupport/kmsconvenience/qkmsdevice.cpp
+index 8cd7f9b368..406f84663f 100644
+--- a/qtbase/src/platformsupport/kmsconvenience/qkmsdevice.cpp
++++ b/qtbase/src/platformsupport/kmsconvenience/qkmsdevice.cpp
+@@ -318,7 +318,7 @@ QPlatformScreen *QKmsDevice::createScreenForConnector(drmModeResPtr resources,
+
+ if (current < 0 && crtc_mode.clock != 0) {
+ modes << crtc_mode;
+- current = mode.size() - 1;
++ current = modes.size() - 1;
+ }
+
+ if (configuration == OutputConfigCurrent)
+diff --git a/qtbase/src/platformsupport/linuxaccessibility/atspiadaptor.cpp b/qtbase/src/platformsupport/linuxaccessibility/atspiadaptor.cpp
+index 9153fd20bb..255ea5e33e 100644
+--- a/qtbase/src/platformsupport/linuxaccessibility/atspiadaptor.cpp
++++ b/qtbase/src/platformsupport/linuxaccessibility/atspiadaptor.cpp
+@@ -194,6 +194,9 @@ QString AtSpiAdaptor::introspect(const QString &path) const
+ " <arg direction=\"out\" type=\"(so)\"/>\n"
+ " <annotation value=\"QSpiObjectReference\" name=\"org.qtproject.QtDBus.QtTypeName.Out0\"/>\n"
+ " </method>\n"
++ " <method name=\"GetAccessibleId\">\n"
++ " <arg direction=\"out\" type=\"s\"/>\n"
++ " </method>\n"
+ " </interface>\n"
+ );
+
+@@ -913,8 +916,17 @@ void AtSpiAdaptor::notify(QAccessibleEvent *event)
+ }
+ case QAccessible::NameChanged: {
+ if (sendObject || sendObject_property_change || sendObject_property_change_accessible_name) {
+- QString path = pathForInterface(event->accessibleInterface());
+- QVariantList args = packDBusSignalArguments(QLatin1String("accessible-name"), 0, 0, variantForPath(path));
++ QAccessibleInterface *iface = event->accessibleInterface();
++ if (!iface) {
++ qCDebug(lcAccessibilityAtspi,
++ "NameChanged event from invalid accessible.");
++ return;
++ }
++
++ QString path = pathForInterface(iface);
++ QVariantList args = packDBusSignalArguments(
++ QLatin1String("accessible-name"), 0, 0,
++ QVariant::fromValue(QDBusVariant(iface->text(QAccessible::Name))));
+ sendDBusSignal(path, QLatin1String(ATSPI_DBUS_INTERFACE_EVENT_OBJECT),
+ QLatin1String("PropertyChange"), args);
+ }
+@@ -922,8 +934,17 @@ void AtSpiAdaptor::notify(QAccessibleEvent *event)
+ }
+ case QAccessible::DescriptionChanged: {
+ if (sendObject || sendObject_property_change || sendObject_property_change_accessible_description) {
+- QString path = pathForInterface(event->accessibleInterface());
+- QVariantList args = packDBusSignalArguments(QLatin1String("accessible-description"), 0, 0, variantForPath(path));
++ QAccessibleInterface *iface = event->accessibleInterface();
++ if (!iface) {
++ qCDebug(lcAccessibilityAtspi,
++ "DescriptionChanged event from invalid accessible.");
++ return;
++ }
++
++ QString path = pathForInterface(iface);
++ QVariantList args = packDBusSignalArguments(
++ QLatin1String("accessible-description"), 0, 0,
++ QVariant::fromValue(QDBusVariant(iface->text(QAccessible::Description))));
+ sendDBusSignal(path, QLatin1String(ATSPI_DBUS_INTERFACE_EVENT_OBJECT),
+ QLatin1String("PropertyChange"), args);
+ }
+@@ -1038,7 +1059,9 @@ void AtSpiAdaptor::notify(QAccessibleEvent *event)
+ // Combo Box with AT-SPI likes to be special
+ // It requires a name-change to update caches and then selection-changed
+ QString path = pathForInterface(iface);
+- QVariantList args1 = packDBusSignalArguments(QLatin1String("accessible-name"), 0, 0, variantForPath(path));
++ QVariantList args1 = packDBusSignalArguments(
++ QLatin1String("accessible-name"), 0, 0,
++ QVariant::fromValue(QDBusVariant(iface->text(QAccessible::Name))));
+ sendDBusSignal(path, QLatin1String(ATSPI_DBUS_INTERFACE_EVENT_OBJECT),
+ QLatin1String("PropertyChange"), args1);
+ QVariantList args2 = packDBusSignalArguments(QString(), 0, 0, QVariant::fromValue(QDBusVariant(QVariant(0))));
+@@ -1358,6 +1381,26 @@ void AtSpiAdaptor::registerApplication()
+ delete registry;
+ }
+
++namespace {
++QString accessibleIdForAccessible(QAccessibleInterface *accessible)
++{
++ QString result;
++ while (accessible) {
++ if (!result.isEmpty())
++ result.prepend(QLatin1Char('.'));
++ if (auto obj = accessible->object()) {
++ const QString name = obj->objectName();
++ if (!name.isEmpty())
++ result.prepend(name);
++ else
++ result.prepend(QString::fromUtf8(obj->metaObject()->className()));
++ }
++ accessible = accessible->parent();
++ }
++ return result;
++}
++} // namespace
++
+ // Accessible
+ bool AtSpiAdaptor::accessibleInterface(QAccessibleInterface *interface, const QString &function, const QDBusMessage &message, const QDBusConnection &connection)
+ {
+@@ -1441,6 +1484,9 @@ bool AtSpiAdaptor::accessibleInterface(QAccessibleInterface *interface, const QS
+ children << ref;
+ }
+ connection.send(message.createReply(QVariant::fromValue(children)));
++ } else if (function == QLatin1String("GetAccessibleId")) {
++ sendReply(connection, message,
++ QVariant::fromValue(QDBusVariant(accessibleIdForAccessible(interface))));
+ } else {
+ qCDebug(lcAccessibilityAtspi) << "WARNING: AtSpiAdaptor::accessibleInterface does not implement " << function << message.path();
+ return false;
+diff --git a/qtbase/src/platformsupport/linuxaccessibility/dbusconnection.cpp b/qtbase/src/platformsupport/linuxaccessibility/dbusconnection.cpp
+index 45ddc8e496..cc734abc63 100644
+--- a/qtbase/src/platformsupport/linuxaccessibility/dbusconnection.cpp
++++ b/qtbase/src/platformsupport/linuxaccessibility/dbusconnection.cpp
+@@ -69,6 +69,21 @@ QT_BEGIN_NAMESPACE
+ DBusConnection::DBusConnection(QObject *parent)
+ : QObject(parent), m_a11yConnection(QString()), m_enabled(false)
+ {
++ // If the bus is explicitly set via env var it overrides everything else.
++ QByteArray addressEnv = qgetenv("AT_SPI_BUS_ADDRESS");
++ if (!addressEnv.isEmpty()) {
++ // Only connect on next loop run, connections to our enabled signal are
++ // only established after the ctor returns.
++ QMetaObject::invokeMethod(
++ this,
++ [this, addressEnv] {
++ m_enabled = true;
++ connectA11yBus(QString::fromLocal8Bit(addressEnv));
++ },
++ Qt::QueuedConnection);
++ return;
++ }
++
+ // Start monitoring if "org.a11y.Bus" is registered as DBus service.
+ QDBusConnection c = QDBusConnection::sessionBus();
+ if (!c.isConnected()) {
+diff --git a/qtbase/src/platformsupport/services/genericunix/qgenericunixservices.cpp b/qtbase/src/platformsupport/services/genericunix/qgenericunixservices.cpp
+index 1a3cab275d..2abe039126 100644
+--- a/qtbase/src/platformsupport/services/genericunix/qgenericunixservices.cpp
++++ b/qtbase/src/platformsupport/services/genericunix/qgenericunixservices.cpp
+@@ -51,6 +51,9 @@
+ #include <QtCore/QStandardPaths>
+ #include <QtCore/QUrl>
+
++#include <QtGui/QGuiApplication>
++#include <QtGui/QWindow>
++
+ #if QT_CONFIG(dbus)
+ // These QtCore includes are needed for xdg-desktop-portal support
+ #include <QtCore/private/qcore_unix_p.h>
+@@ -58,6 +61,8 @@
+ #include <QtCore/QFileInfo>
+ #include <QtCore/QUrlQuery>
+
++#include <QtGui/QColor>
++
+ #include <QtDBus/QDBusConnection>
+ #include <QtDBus/QDBusMessage>
+ #include <QtDBus/QDBusPendingCall>
+@@ -142,6 +147,8 @@ static inline bool detectWebBrowser(const QByteArray &desktop,
+ }
+
+ if (desktop == QByteArray("KDE")) {
++ if (checkExecutable(QStringLiteral("kde-open5"), browser))
++ return true;
+ // Konqueror launcher
+ if (checkExecutable(QStringLiteral("kfmclient"), browser)) {
+ browser->append(QLatin1String(" exec"));
+@@ -296,8 +303,135 @@ static inline QDBusMessage xdgDesktopPortalSendEmail(const QUrl &url)
+
+ return QDBusConnection::sessionBus().call(message);
+ }
++
++namespace {
++struct XDGDesktopColor
++{
++ double r = 0;
++ double g = 0;
++ double b = 0;
++
++ QColor toQColor() const
++ {
++ constexpr auto rgbMax = 255;
++ return { static_cast<int>(r * rgbMax), static_cast<int>(g * rgbMax),
++ static_cast<int>(b * rgbMax) };
++ }
++};
++
++const QDBusArgument &operator>>(const QDBusArgument &argument, XDGDesktopColor &myStruct)
++{
++ argument.beginStructure();
++ argument >> myStruct.r >> myStruct.g >> myStruct.b;
++ argument.endStructure();
++ return argument;
++}
++
++class XdgDesktopPortalColorPicker : public QPlatformServiceColorPicker
++{
++ Q_OBJECT
++public:
++ XdgDesktopPortalColorPicker(const QString &parentWindowId, QWindow *parent)
++ : QPlatformServiceColorPicker(parent), m_parentWindowId(parentWindowId)
++ {
++ }
++
++ void pickColor() override
++ {
++ // DBus signature:
++ // PickColor (IN s parent_window,
++ // IN a{sv} options
++ // OUT o handle)
++ // Options:
++ // handle_token (s) - A string that will be used as the last element of the @handle.
++
++ QDBusMessage message = QDBusMessage::createMethodCall(
++ QStringLiteral("org.freedesktop.portal.Desktop"), QStringLiteral("/org/freedesktop/portal/desktop"),
++ QStringLiteral("org.freedesktop.portal.Screenshot"), QStringLiteral("PickColor"));
++ message << m_parentWindowId << QVariantMap();
++
++ QDBusPendingCall pendingCall = QDBusConnection::sessionBus().asyncCall(message);
++ auto watcher = new QDBusPendingCallWatcher(pendingCall, this);
++ connect(watcher, &QDBusPendingCallWatcher::finished, this,
++ [this](QDBusPendingCallWatcher *watcher) {
++ watcher->deleteLater();
++ QDBusPendingReply<QDBusObjectPath> reply = *watcher;
++ if (reply.isError()) {
++ qWarning("DBus call to pick color failed: %s",
++ qPrintable(reply.error().message()));
++ Q_EMIT colorPicked({});
++ } else {
++ QDBusConnection::sessionBus().connect(
++ QStringLiteral("org.freedesktop.portal.Desktop"), reply.value().path(),
++ QStringLiteral("org.freedesktop.portal.Request"), QStringLiteral("Response"), this,
++ // clang-format off
++ SLOT(gotColorResponse(uint,QVariantMap))
++ // clang-format on
++ );
++ }
++ });
++ }
++
++private Q_SLOTS:
++ void gotColorResponse(uint result, const QVariantMap &map)
++ {
++ if (result != 0)
++ return;
++ XDGDesktopColor color{};
++ map.value(QStringLiteral("color")).value<QDBusArgument>() >> color;
++ Q_EMIT colorPicked(color.toQColor());
++ deleteLater();
++ }
++
++private:
++ const QString m_parentWindowId;
++};
++} // namespace
++
+ #endif // QT_CONFIG(dbus)
+
++QGenericUnixServices::QGenericUnixServices()
++{
++#if QT_CONFIG(dbus)
++ if (qEnvironmentVariableIntValue("QT_NO_XDG_DESKTOP_PORTAL") > 0) {
++ return;
++ }
++ QDBusMessage message = QDBusMessage::createMethodCall(
++ QStringLiteral("org.freedesktop.portal.Desktop"), QStringLiteral("/org/freedesktop/portal/desktop"),
++ QStringLiteral("org.freedesktop.DBus.Properties"), QStringLiteral("Get"));
++ message << QStringLiteral("org.freedesktop.portal.Screenshot")
++ << QStringLiteral("version");
++
++ QDBusPendingCall pendingCall = QDBusConnection::sessionBus().asyncCall(message);
++ auto watcher = new QDBusPendingCallWatcher(pendingCall);
++ QObject::connect(watcher, &QDBusPendingCallWatcher::finished, watcher,
++ [this](QDBusPendingCallWatcher *watcher) {
++ watcher->deleteLater();
++ QDBusPendingReply<QVariant> reply = *watcher;
++ if (!reply.isError() && reply.value().toUInt() >= 2)
++ m_hasScreenshotPortalWithColorPicking = true;
++ });
++
++#endif
++}
++
++QPlatformServiceColorPicker *QGenericUnixServices::colorPicker(QWindow *parent)
++{
++#if QT_CONFIG(dbus)
++ // Make double sure that we are in a wayland environment. In particular check
++ // WAYLAND_DISPLAY so also XWayland apps benefit from portal-based color picking.
++ // Outside wayland we'll rather rely on other means than the XDG desktop portal.
++ if (!qEnvironmentVariableIsEmpty("WAYLAND_DISPLAY")
++ || QGuiApplication::platformName().startsWith(QLatin1String("wayland"))) {
++ return new XdgDesktopPortalColorPicker(portalWindowIdentifier(parent), parent);
++ }
++ return nullptr;
++#else
++ Q_UNUSED(parent);
++ return nullptr;
++#endif
++}
++
+ QByteArray QGenericUnixServices::desktopEnvironment() const
+ {
+ static const QByteArray result = detectDesktopEnvironment();
+@@ -352,6 +486,8 @@ bool QGenericUnixServices::openDocument(const QUrl &url)
+ }
+
+ #else
++QGenericUnixServices::QGenericUnixServices() = default;
++
+ QByteArray QGenericUnixServices::desktopEnvironment() const
+ {
+ return QByteArrayLiteral("UNKNOWN");
+@@ -371,6 +507,30 @@ bool QGenericUnixServices::openDocument(const QUrl &url)
+ return false;
+ }
+
++QPlatformServiceColorPicker *QGenericUnixServices::colorPicker(QWindow *parent)
++{
++ Q_UNUSED(parent);
++ return nullptr;
++}
++
+ #endif // QT_NO_MULTIPROCESS
+
++QString QGenericUnixServices::portalWindowIdentifier(QWindow *window)
++{
++ if (QGuiApplication::platformName() == QLatin1String("xcb"))
++ return QStringLiteral("x11:") + QString::number(window->winId(), 16);
++ return QString();
++}
++
++bool QGenericUnixServices::hasCapability(Capability capability) const
++{
++ switch (capability) {
++ case Capability::ColorPicking:
++ return m_hasScreenshotPortalWithColorPicking;
++ }
++ return false;
++}
++
+ QT_END_NAMESPACE
++
++#include "qgenericunixservices.moc"
+diff --git a/qtbase/src/platformsupport/services/genericunix/qgenericunixservices_p.h b/qtbase/src/platformsupport/services/genericunix/qgenericunixservices_p.h
+index 8ac3de6f03..30924e64bd 100644
+--- a/qtbase/src/platformsupport/services/genericunix/qgenericunixservices_p.h
++++ b/qtbase/src/platformsupport/services/genericunix/qgenericunixservices_p.h
+@@ -59,16 +59,21 @@ QT_BEGIN_NAMESPACE
+ class QGenericUnixServices : public QPlatformServices
+ {
+ public:
+- QGenericUnixServices() {}
++ QGenericUnixServices();
+
+ QByteArray desktopEnvironment() const override;
+
++ bool hasCapability(Capability capability) const override;
+ bool openUrl(const QUrl &url) override;
+ bool openDocument(const QUrl &url) override;
++ QPlatformServiceColorPicker *colorPicker(QWindow *parent = nullptr) override;
++
++ virtual QString portalWindowIdentifier(QWindow *window);
+
+ private:
+ QString m_webBrowser;
+ QString m_documentLauncher;
++ bool m_hasScreenshotPortalWithColorPicking = false;
+ };
+
+ QT_END_NAMESPACE
+diff --git a/qtbase/src/platformsupport/themes/genericunix/dbusmenu/qdbusmenuconnection.cpp b/qtbase/src/platformsupport/themes/genericunix/dbusmenu/qdbusmenuconnection.cpp
+index 09470bccc6..cc7c7d4d8a 100644
+--- a/qtbase/src/platformsupport/themes/genericunix/dbusmenu/qdbusmenuconnection.cpp
++++ b/qtbase/src/platformsupport/themes/genericunix/dbusmenu/qdbusmenuconnection.cpp
+@@ -69,6 +69,7 @@ const QString MenuBarPath = QLatin1String("/MenuBar");
+ */
+ QDBusMenuConnection::QDBusMenuConnection(QObject *parent, const QString &serviceName)
+ : QObject(parent)
++ , m_serviceName(serviceName)
+ , m_connection(serviceName.isNull() ? QDBusConnection::sessionBus()
+ : QDBusConnection::connectToBus(QDBusConnection::SessionBus, serviceName))
+ , m_dbusWatcher(new QDBusServiceWatcher(StatusNotifierWatcherService, m_connection, QDBusServiceWatcher::WatchForRegistration, this))
+@@ -83,6 +84,12 @@ QDBusMenuConnection::QDBusMenuConnection(QObject *parent, const QString &service
+ #endif
+ }
+
++QDBusMenuConnection::~QDBusMenuConnection()
++{
++ if (!m_serviceName.isEmpty() && m_connection.isConnected())
++ QDBusConnection::disconnectFromBus(m_serviceName);
++}
++
+ void QDBusMenuConnection::dbusError(const QDBusError &error)
+ {
+ qWarning() << "QDBusTrayIcon encountered a D-Bus error:" << error;
+@@ -105,13 +112,7 @@ void QDBusMenuConnection::unregisterTrayIconMenu(QDBusTrayIcon *item)
+
+ bool QDBusMenuConnection::registerTrayIcon(QDBusTrayIcon *item)
+ {
+- bool success = connection().registerService(item->instanceId());
+- if (!success) {
+- qWarning() << "failed to register service" << item->instanceId();
+- return false;
+- }
+-
+- success = connection().registerObject(StatusNotifierItemPath, item);
++ bool success = connection().registerObject(StatusNotifierItemPath, item);
+ if (!success) {
+ unregisterTrayIcon(item);
+ qWarning() << "failed to register" << item->instanceId() << StatusNotifierItemPath;
+@@ -126,21 +127,18 @@ bool QDBusMenuConnection::registerTrayIcon(QDBusTrayIcon *item)
+
+ bool QDBusMenuConnection::registerTrayIconWithWatcher(QDBusTrayIcon *item)
+ {
++ Q_UNUSED(item);
+ QDBusMessage registerMethod = QDBusMessage::createMethodCall(
+ StatusNotifierWatcherService, StatusNotifierWatcherPath, StatusNotifierWatcherService,
+ QLatin1String("RegisterStatusNotifierItem"));
+- registerMethod.setArguments(QVariantList() << item->instanceId());
++ registerMethod.setArguments(QVariantList() << m_connection.baseService());
+ return m_connection.callWithCallback(registerMethod, this, SIGNAL(trayIconRegistered()), SLOT(dbusError(QDBusError)));
+ }
+
+-bool QDBusMenuConnection::unregisterTrayIcon(QDBusTrayIcon *item)
++void QDBusMenuConnection::unregisterTrayIcon(QDBusTrayIcon *item)
+ {
+ unregisterTrayIconMenu(item);
+ connection().unregisterObject(StatusNotifierItemPath);
+- bool success = connection().unregisterService(item->instanceId());
+- if (!success)
+- qWarning() << "failed to unregister service" << item->instanceId();
+- return success;
+ }
+ #endif // QT_NO_SYSTEMTRAYICON
+
+diff --git a/qtbase/src/platformsupport/themes/genericunix/dbusmenu/qdbusmenuconnection_p.h b/qtbase/src/platformsupport/themes/genericunix/dbusmenu/qdbusmenuconnection_p.h
+index f484795fbb..97bdfabb85 100644
+--- a/qtbase/src/platformsupport/themes/genericunix/dbusmenu/qdbusmenuconnection_p.h
++++ b/qtbase/src/platformsupport/themes/genericunix/dbusmenu/qdbusmenuconnection_p.h
+@@ -70,6 +70,7 @@ class QDBusMenuConnection : public QObject
+
+ public:
+ QDBusMenuConnection(QObject *parent = nullptr, const QString &serviceName = QString());
++ ~QDBusMenuConnection();
+ QDBusConnection connection() const { return m_connection; }
+ QDBusServiceWatcher *dbusWatcher() const { return m_dbusWatcher; }
+ bool isStatusNotifierHostRegistered() const { return m_statusNotifierHostRegistered; }
+@@ -78,7 +79,7 @@ public:
+ void unregisterTrayIconMenu(QDBusTrayIcon *item);
+ bool registerTrayIcon(QDBusTrayIcon *item);
+ bool registerTrayIconWithWatcher(QDBusTrayIcon *item);
+- bool unregisterTrayIcon(QDBusTrayIcon *item);
++ void unregisterTrayIcon(QDBusTrayIcon *item);
+ #endif // QT_NO_SYSTEMTRAYICON
+
+ Q_SIGNALS:
+@@ -90,6 +91,7 @@ private Q_SLOTS:
+ void dbusError(const QDBusError &error);
+
+ private:
++ QString m_serviceName;
+ QDBusConnection m_connection;
+ QDBusServiceWatcher *m_dbusWatcher;
+ bool m_statusNotifierHostRegistered;
+diff --git a/qtbase/src/platformsupport/themes/genericunix/dbustray/qdbustrayicon.cpp b/qtbase/src/platformsupport/themes/genericunix/dbustray/qdbustrayicon.cpp
+index bede70975a..76bfec5e5a 100644
+--- a/qtbase/src/platformsupport/themes/genericunix/dbustray/qdbustrayicon.cpp
++++ b/qtbase/src/platformsupport/themes/genericunix/dbustray/qdbustrayicon.cpp
+@@ -71,8 +71,12 @@ Q_LOGGING_CATEGORY(qLcTray, "qt.qpa.tray")
+ static QString iconTempPath()
+ {
+ QString tempPath = QStandardPaths::writableLocation(QStandardPaths::RuntimeLocation);
+- if (!tempPath.isEmpty())
++ if (!tempPath.isEmpty()) {
++ QString flatpakId = qEnvironmentVariable("FLATPAK_ID");
++ if (!flatpakId.isEmpty() && QFileInfo::exists(QLatin1String("/.flatpak-info")))
++ tempPath += QLatin1String("/app/") + flatpakId;
+ return tempPath;
++ }
+
+ tempPath = QStandardPaths::writableLocation(QStandardPaths::GenericCacheLocation);
+
+diff --git a/qtbase/src/platformsupport/themes/genericunix/qgenericunixthemes.cpp b/qtbase/src/platformsupport/themes/genericunix/qgenericunixthemes.cpp
+index cb1b39db64..6e01af052c 100644
+--- a/qtbase/src/platformsupport/themes/genericunix/qgenericunixthemes.cpp
++++ b/qtbase/src/platformsupport/themes/genericunix/qgenericunixthemes.cpp
+@@ -755,6 +755,9 @@ QVariant QGnomeTheme::themeHint(QPlatformTheme::ThemeHint hint) const
+ return QVariant(QChar(0x2022));
+ case QPlatformTheme::UiEffects:
+ return QVariant(int(HoverEffect));
++ case QPlatformTheme::ButtonPressKeys:
++ return QVariant::fromValue(
++ QList<Qt::Key>({ Qt::Key_Space, Qt::Key_Return, Qt::Key_Enter, Qt::Key_Select }));
+ default:
+ break;
+ }
+diff --git a/qtbase/src/plugins/platforms/eglfs/api/qeglfscursor.cpp b/qtbase/src/plugins/platforms/eglfs/api/qeglfscursor.cpp
+index 98e05195ee..1e92f43dec 100644
+--- a/qtbase/src/plugins/platforms/eglfs/api/qeglfscursor.cpp
++++ b/qtbase/src/plugins/platforms/eglfs/api/qeglfscursor.cpp
+@@ -343,8 +343,7 @@ void QEglFSCursor::paintOnScreen()
+ // screens are siblings of each other. When not enabled, the sibling list
+ // only contains m_screen itself.
+ for (QPlatformScreen *screen : m_screen->virtualSiblings()) {
+- if (screen->geometry().contains(cr.topLeft().toPoint() + m_cursor.hotSpot)
+- && QOpenGLContext::currentContext()->screen() == screen->screen())
++ if (screen->geometry().contains(cr.topLeft().toPoint() + m_cursor.hotSpot))
+ {
+ cr.translate(-screen->geometry().topLeft());
+ const QSize screenSize = screen->geometry().size();
+@@ -468,11 +467,12 @@ void QEglFSCursor::draw(const QRectF &r)
+ {
+ StateSaver stateSaver;
+
+- QEglFSCursorData &gfx = static_cast<QEglFSContext*>(QOpenGLContext::currentContext()->handle())->cursorData;
+- if (!gfx.program) {
+- // one time initialization
++ // one time initialization
++ if (!QOpenGLFunctions::d_ptr)
+ initializeOpenGLFunctions();
+
++ QEglFSCursorData &gfx = static_cast<QEglFSContext*>(QOpenGLContext::currentContext()->handle())->cursorData;
++ if (!gfx.program) {
+ createShaderPrograms();
+
+ if (!gfx.atlasTexture) {
+diff --git a/qtbase/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmseventreader.cpp b/qtbase/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmseventreader.cpp
+index 645a0ae2e9..3e0e406f1a 100644
+--- a/qtbase/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmseventreader.cpp
++++ b/qtbase/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmseventreader.cpp
+@@ -179,7 +179,7 @@ void QEglFSKmsEventReader::create(QEglFSKmsDevice *device)
+
+ m_device = device;
+
+- qCDebug(qLcEglfsKmsDebug, "Initalizing event reader for device %p fd %d",
++ qCDebug(qLcEglfsKmsDebug, "Initializing event reader for device %p fd %d",
+ m_device, m_device->fd());
+
+ m_thread = new QEglFSKmsEventReaderThread(m_device->fd());
+diff --git a/qtbase/src/plugins/platforms/offscreen/qoffscreenintegration.cpp b/qtbase/src/plugins/platforms/offscreen/qoffscreenintegration.cpp
+index 141fb68a23..d4294d425a 100644
+--- a/qtbase/src/plugins/platforms/offscreen/qoffscreenintegration.cpp
++++ b/qtbase/src/plugins/platforms/offscreen/qoffscreenintegration.cpp
+@@ -122,11 +122,13 @@ QOffscreenIntegration::QOffscreenIntegration()
+ #endif
+ m_services.reset(new QPlatformServices);
+
+- QWindowSystemInterface::handleScreenAdded(new QOffscreenScreen);
++ m_screen = new QOffscreenScreen;
++ QWindowSystemInterface::handleScreenAdded(m_screen);
+ }
+
+ QOffscreenIntegration::~QOffscreenIntegration()
+ {
++ QWindowSystemInterface::handleScreenRemoved(m_screen);
+ }
+
+ void QOffscreenIntegration::initialize()
+diff --git a/qtbase/src/plugins/platforms/offscreen/qoffscreenintegration.h b/qtbase/src/plugins/platforms/offscreen/qoffscreenintegration.h
+index 0ea90f6c2f..fe00fde07c 100644
+--- a/qtbase/src/plugins/platforms/offscreen/qoffscreenintegration.h
++++ b/qtbase/src/plugins/platforms/offscreen/qoffscreenintegration.h
+@@ -84,6 +84,7 @@ protected:
+ #endif
+ QScopedPointer<QPlatformInputContext> m_inputContext;
+ QScopedPointer<QPlatformServices> m_services;
++ QPlatformScreen *m_screen;
+ mutable QScopedPointer<QPlatformNativeInterface> m_nativeInterface;
+ };
+
+diff --git a/qtbase/src/plugins/platforms/windows/qwindowsglcontext.cpp b/qtbase/src/plugins/platforms/windows/qwindowsglcontext.cpp
+index 6fa5a8a2b3..1f49f0aefd 100644
+--- a/qtbase/src/plugins/platforms/windows/qwindowsglcontext.cpp
++++ b/qtbase/src/plugins/platforms/windows/qwindowsglcontext.cpp
+@@ -48,6 +48,7 @@
+ #include <qpa/qplatformnativeinterface.h>
+ #include <QtPlatformHeaders/qwglnativecontext.h>
+
++#include <private/qsystemlibrary_p.h>
+ #include <algorithm>
+
+ #include <wingdi.h>
+@@ -162,19 +163,25 @@ QFunctionPointer QWindowsOpengl32DLL::resolve(const char *name)
+
+ bool QWindowsOpengl32DLL::init(bool softwareRendering)
+ {
+- const QByteArray opengl32 = QByteArrayLiteral("opengl32.dll");
+- const QByteArray swopengl = QByteArrayLiteral("opengl32sw.dll");
++ const QByteArray opengl32 = QByteArrayLiteral("opengl32");
++ const QByteArray swopengl = QByteArrayLiteral("opengl32sw");
++ bool useSystemLib = false;
+
+ QByteArray openglDll = qgetenv("QT_OPENGL_DLL");
+- if (openglDll.isEmpty())
++ if (openglDll.isEmpty()) {
+ openglDll = softwareRendering ? swopengl : opengl32;
++ useSystemLib = !softwareRendering;
++ }
+
+ openglDll = openglDll.toLower();
+ m_nonOpengl32 = openglDll != opengl32;
+
+ qCDebug(lcQpaGl) << "Qt: Using WGL and OpenGL from" << openglDll;
+
+- m_lib = ::LoadLibraryA(openglDll.constData());
++ if (useSystemLib)
++ m_lib = QSystemLibrary::load((wchar_t*)(QString::fromLatin1(openglDll).utf16()));
++ else
++ m_lib = LoadLibraryA(openglDll.constData());
+ if (!m_lib) {
+ qErrnoWarning(::GetLastError(), "Failed to load %s", openglDll.constData());
+ return false;
+@@ -184,7 +191,7 @@ bool QWindowsOpengl32DLL::init(bool softwareRendering)
+ // Load opengl32.dll always. GDI functions like ChoosePixelFormat do
+ // GetModuleHandle for opengl32.dll and behave differently (and call back into
+ // opengl32) when the module is present. This is fine for dummy contexts and windows.
+- ::LoadLibraryA("opengl32.dll");
++ QSystemLibrary::load(L"opengl32");
+ }
+
+ wglCreateContext = reinterpret_cast<HGLRC (WINAPI *)(HDC)>(resolve("wglCreateContext"));
+diff --git a/qtbase/src/plugins/platforms/windows/qwindowsopengltester.cpp b/qtbase/src/plugins/platforms/windows/qwindowsopengltester.cpp
+index d7d186e804..9eb4011bf2 100644
+--- a/qtbase/src/plugins/platforms/windows/qwindowsopengltester.cpp
++++ b/qtbase/src/plugins/platforms/windows/qwindowsopengltester.cpp
+@@ -49,6 +49,7 @@
+ #include <QtCore/qstandardpaths.h>
+ #include <QtCore/qlibraryinfo.h>
+ #include <QtCore/qhash.h>
++#include <private/qsystemlibrary_p.h>
+
+ #ifndef QT_NO_OPENGL
+ #include <private/qopengl_p.h>
+@@ -396,7 +397,7 @@ bool QWindowsOpenGLTester::testDesktopGL()
+
+ // Test #1: Load opengl32.dll and try to resolve an OpenGL 2 function.
+ // This will typically fail on systems that do not have a real OpenGL driver.
+- lib = LoadLibraryA("opengl32.dll");
++ lib = QSystemLibrary::load(L"opengl32");
+ if (lib) {
+ CreateContext = reinterpret_cast<CreateContextType>(
+ reinterpret_cast<QFunctionPointer>(::GetProcAddress(lib, "wglCreateContext")));
+diff --git a/qtbase/src/plugins/platforms/xcb/nativepainting/qtessellator.cpp b/qtbase/src/plugins/platforms/xcb/nativepainting/qtessellator.cpp
+index 1afa00cfc9..118af6ce73 100644
+--- a/qtbase/src/plugins/platforms/xcb/nativepainting/qtessellator.cpp
++++ b/qtbase/src/plugins/platforms/xcb/nativepainting/qtessellator.cpp
+@@ -41,6 +41,7 @@
+
+ #include <QRect>
+ #include <QList>
++#include <QMap>
+ #include <QDebug>
+
+ #include <qmath.h>
+diff --git a/qtbase/src/plugins/platforms/xcb/qxcbconnection.cpp b/qtbase/src/plugins/platforms/xcb/qxcbconnection.cpp
+index 9e2a37a6a1..e6e175a118 100644
+--- a/qtbase/src/plugins/platforms/xcb/qxcbconnection.cpp
++++ b/qtbase/src/plugins/platforms/xcb/qxcbconnection.cpp
+@@ -488,12 +488,12 @@ void QXcbConnection::printXcbError(const char *message, xcb_generic_error_t *err
+ uint clamped_error_code = qMin<uint>(error->error_code, (sizeof(xcb_errors) / sizeof(xcb_errors[0])) - 1);
+ uint clamped_major_code = qMin<uint>(error->major_code, (sizeof(xcb_protocol_request_codes) / sizeof(xcb_protocol_request_codes[0])) - 1);
+
+- qCWarning(lcQpaXcb, "%s: %d (%s), sequence: %d, resource id: %d, major code: %d (%s), minor code: %d",
+- message,
+- int(error->error_code), xcb_errors[clamped_error_code],
+- int(error->sequence), int(error->resource_id),
+- int(error->major_code), xcb_protocol_request_codes[clamped_major_code],
+- int(error->minor_code));
++ qCDebug(lcQpaXcb, "%s: %d (%s), sequence: %d, resource id: %d, major code: %d (%s), minor code: %d",
++ message,
++ int(error->error_code), xcb_errors[clamped_error_code],
++ int(error->sequence), int(error->resource_id),
++ int(error->major_code), xcb_protocol_request_codes[clamped_major_code],
++ int(error->minor_code));
+ }
+
+ static Qt::MouseButtons translateMouseButtons(int s)
+@@ -702,6 +702,8 @@ void QXcbConnection::handleXcbEvent(xcb_generic_event_t *event)
+ QXcbVirtualDesktop *virtualDesktop = virtualDesktopForRootWindow(propertyNotify->window);
+ if (virtualDesktop)
+ virtualDesktop->updateWorkArea();
++ } else if (propertyNotify->atom == atom(QXcbAtom::_NET_SUPPORTED)) {
++ m_wmSupport->updateNetWMAtoms();
+ } else {
+ HANDLE_PLATFORM_WINDOW_EVENT(xcb_property_notify_event_t, window, handlePropertyNotifyEvent);
+ }
+@@ -750,7 +752,7 @@ void QXcbConnection::handleXcbEvent(xcb_generic_event_t *event)
+ case XCB_XKB_NEW_KEYBOARD_NOTIFY: {
+ xcb_xkb_new_keyboard_notify_event_t *ev = &xkb_event->new_keyboard_notify;
+ if (ev->changed & XCB_XKB_NKN_DETAIL_KEYCODES)
+- m_keyboard->updateKeymap(ev);
++ m_keyboard->updateKeymap();
+ break;
+ }
+ default:
+diff --git a/qtbase/src/plugins/platforms/xcb/qxcbintegration.cpp b/qtbase/src/plugins/platforms/xcb/qxcbintegration.cpp
+index 76869ced60..02d2eebb56 100644
+--- a/qtbase/src/plugins/platforms/xcb/qxcbintegration.cpp
++++ b/qtbase/src/plugins/platforms/xcb/qxcbintegration.cpp
+@@ -274,8 +274,7 @@ QPlatformWindow *QXcbIntegration::createForeignWindow(QWindow *window, WId nativ
+ #ifndef QT_NO_OPENGL
+ QPlatformOpenGLContext *QXcbIntegration::createPlatformOpenGLContext(QOpenGLContext *context) const
+ {
+- QXcbScreen *screen = static_cast<QXcbScreen *>(context->screen()->handle());
+- QXcbGlIntegration *glIntegration = screen->connection()->glIntegration();
++ QXcbGlIntegration *glIntegration = defaultConnection()->glIntegration();
+ if (!glIntegration) {
+ qWarning("QXcbIntegration: Cannot create platform OpenGL context, neither GLX nor EGL are enabled");
+ return nullptr;
+diff --git a/qtbase/src/plugins/platforms/xcb/qxcbkeyboard.cpp b/qtbase/src/plugins/platforms/xcb/qxcbkeyboard.cpp
+index efecd7e2d1..e8286381a2 100644
+--- a/qtbase/src/plugins/platforms/xcb/qxcbkeyboard.cpp
++++ b/qtbase/src/plugins/platforms/xcb/qxcbkeyboard.cpp
+@@ -365,17 +365,6 @@ void QXcbKeyboard::updateKeymap(xcb_mapping_notify_event_t *event)
+ updateKeymap();
+ }
+
+-void QXcbKeyboard::updateKeymap(xcb_xkb_new_keyboard_notify_event_t *event)
+-{
+- if (!event)
+- return;
+-
+- if (event->deviceID != event->oldDeviceID)
+- m_config = false;
+-
+- updateKeymap();
+-}
+-
+ void QXcbKeyboard::updateKeymap()
+ {
+ KeysymModifierMap keysymMods;
+@@ -383,6 +372,8 @@ void QXcbKeyboard::updateKeymap()
+ keysymMods = keysymsToModifiers();
+ updateModifiers(keysymMods);
+
++ m_config = true;
++
+ if (!m_xkbContext) {
+ m_xkbContext.reset(xkb_context_new(XKB_CONTEXT_NO_DEFAULT_INCLUDES));
+ if (!m_xkbContext) {
+@@ -398,13 +389,8 @@ void QXcbKeyboard::updateKeymap()
+ if (connection()->hasXKB()) {
+ m_xkbKeymap.reset(xkb_x11_keymap_new_from_device(m_xkbContext.get(), xcb_connection(),
+ core_device_id, XKB_KEYMAP_COMPILE_NO_FLAGS));
+- if (m_xkbKeymap) {
+- if (m_config)
+- m_xkbState.reset(xkb_state_new(m_xkbKeymap.get()));
+- else
+- m_xkbState.reset(xkb_x11_state_new_from_device(m_xkbKeymap.get(), xcb_connection(), core_device_id));
+-
+- }
++ if (m_xkbKeymap)
++ m_xkbState.reset(xkb_x11_state_new_from_device(m_xkbKeymap.get(), xcb_connection(), core_device_id));
+ } else {
+ m_xkbKeymap.reset(keymapFromCore(keysymMods));
+ if (m_xkbKeymap)
+@@ -425,8 +411,6 @@ void QXcbKeyboard::updateKeymap()
+ updateXKBMods();
+
+ QXkbCommon::verifyHasLatinLayout(m_xkbKeymap.get());
+-
+- m_config = true;
+ }
+
+ QList<int> QXcbKeyboard::possibleKeys(const QKeyEvent *event) const
+diff --git a/qtbase/src/plugins/platforms/xcb/qxcbkeyboard.h b/qtbase/src/plugins/platforms/xcb/qxcbkeyboard.h
+index b652c85fe3..0ee08aeff2 100644
+--- a/qtbase/src/plugins/platforms/xcb/qxcbkeyboard.h
++++ b/qtbase/src/plugins/platforms/xcb/qxcbkeyboard.h
+@@ -69,7 +69,6 @@ public:
+
+ Qt::KeyboardModifiers translateModifiers(int s) const;
+ void updateKeymap(xcb_mapping_notify_event_t *event);
+- void updateKeymap(xcb_xkb_new_keyboard_notify_event_t *event);
+ void updateKeymap();
+ QList<int> possibleKeys(const QKeyEvent *event) const;
+
+diff --git a/qtbase/src/plugins/platforms/xcb/qxcbwindow.cpp b/qtbase/src/plugins/platforms/xcb/qxcbwindow.cpp
+index ffda7b6a57..863e961f4c 100644
+--- a/qtbase/src/plugins/platforms/xcb/qxcbwindow.cpp
++++ b/qtbase/src/plugins/platforms/xcb/qxcbwindow.cpp
+@@ -564,11 +564,6 @@ void QXcbWindow::setGeometry(const QRect &rect)
+ {
+ QPlatformWindow::setGeometry(rect);
+
+- if (shouldDeferTask(Task::SetGeometry)) {
+- m_deferredGeometry = rect;
+- return;
+- }
+-
+ propagateSizeHints();
+
+ QXcbScreen *currentScreen = xcbScreen();
+@@ -693,9 +688,6 @@ void QXcbWindow::setVisible(bool visible)
+
+ void QXcbWindow::show()
+ {
+- if (shouldDeferTask(Task::Map))
+- return;
+-
+ if (window()->isTopLevel()) {
+
+ // update WM_NORMAL_HINTS
+@@ -706,7 +698,7 @@ void QXcbWindow::show()
+ if (isTransient(window())) {
+ const QWindow *tp = window()->transientParent();
+ if (tp && tp->handle())
+- transientXcbParent = static_cast<const QXcbWindow *>(tp->handle())->winId();
++ transientXcbParent = tp->handle()->winId();
+ // Default to client leader if there is no transient parent, else modal dialogs can
+ // be hidden by their parents.
+ if (!transientXcbParent)
+@@ -746,10 +738,6 @@ void QXcbWindow::show()
+
+ void QXcbWindow::hide()
+ {
+- if (shouldDeferTask(Task::Unmap))
+- return;
+-
+- m_wmStateValid = false;
+ xcb_unmap_window(xcb_connection(), m_window);
+
+ // send synthetic UnmapNotify event according to icccm 4.1.4
+@@ -909,9 +897,6 @@ QXcbWindow::NetWmStates QXcbWindow::netWmStates()
+
+ void QXcbWindow::setWindowFlags(Qt::WindowFlags flags)
+ {
+- if (shouldDeferTask(Task::SetWindowFlags))
+- return;
+-
+ Qt::WindowType type = static_cast<Qt::WindowType>(int(flags & Qt::WindowType_Mask));
+
+ if (type == Qt::ToolTip)
+@@ -941,8 +926,6 @@ void QXcbWindow::setWindowFlags(Qt::WindowFlags flags)
+
+ setTransparentForMouseEvents(flags & Qt::WindowTransparentForInput);
+ updateDoesNotAcceptFocus(flags & Qt::WindowDoesNotAcceptFocus);
+-
+- m_isWmManagedWindow = !(flags & Qt::X11BypassWindowManagerHint);
+ }
+
+ void QXcbWindow::setMotifWmHints(Qt::WindowFlags flags)
+@@ -1142,9 +1125,6 @@ void QXcbWindow::setWindowState(Qt::WindowStates state)
+ if (state == m_windowState)
+ return;
+
+- if (shouldDeferTask(Task::SetWindowState))
+- return;
+-
+ // unset old state
+ if (m_windowState & Qt::WindowMinimized)
+ xcb_map_window(xcb_connection(), m_window);
+@@ -1350,6 +1330,12 @@ void QXcbWindow::setWindowIcon(const QIcon &icon)
+ }
+
+ if (!icon_data.isEmpty()) {
++ // Ignore icon exceeding maximum xcb request length
++ if (icon_data.size() > xcb_get_maximum_request_length(xcb_connection())) {
++ qWarning("Ignoring window icon: Size %llu exceeds maximum xcb request length %u.",
++ icon_data.size(), xcb_get_maximum_request_length(xcb_connection()));
++ return;
++ }
+ xcb_change_property(xcb_connection(),
+ XCB_PROP_MODE_REPLACE,
+ m_window,
+@@ -1639,7 +1625,7 @@ void QXcbWindow::setWmWindowType(QXcbWindowFunctions::WmWindowTypes types, Qt::W
+ break;
+ }
+
+- if ((flags & Qt::FramelessWindowHint) && !(type & QXcbWindowFunctions::KdeOverride)) {
++ if ((flags & Qt::FramelessWindowHint) && !(types & QXcbWindowFunctions::KdeOverride)) {
+ // override netwm type - quick and easy for KDE noborder
+ atoms.append(atom(QXcbAtom::_KDE_NET_WM_WINDOW_TYPE_OVERRIDE));
+ }
+@@ -1894,10 +1880,6 @@ void QXcbWindow::handleUnmapNotifyEvent(const xcb_unmap_notify_event_t *event)
+ if (event->window == m_window) {
+ m_mapped = false;
+ QWindowSystemInterface::handleExposeEvent(window(), QRegion());
+- if (!m_isWmManagedWindow || parent()) {
+- m_wmStateValid = true;
+- handleDeferredTasks();
+- }
+ }
+ }
+
+@@ -2212,98 +2194,30 @@ void QXcbWindow::handleLeaveNotifyEvent(const xcb_leave_notify_event_t *event)
+ handleLeaveNotifyEvent(event->root_x, event->root_y, event->mode, event->detail, event->time);
+ }
+
+-bool QXcbWindow::shouldDeferTask(Task task)
+-{
+- if (m_wmStateValid)
+- return false;
+-
+- m_deferredTasks.append(task);
+- return true;
+-}
+-
+-void QXcbWindow::handleDeferredTasks()
+-{
+- Q_ASSERT(m_wmStateValid == true);
+- if (m_deferredTasks.isEmpty())
+- return;
+-
+- bool map = false;
+- bool unmap = false;
+-
+- QVector<Task> tasks;
+- for (auto taskIt = m_deferredTasks.rbegin(); taskIt != m_deferredTasks.rend(); ++taskIt) {
+- if (!tasks.contains(*taskIt))
+- tasks.prepend(*taskIt);
+- }
+-
+- for (Task task : tasks) {
+- switch (task) {
+- case Task::Map:
+- map = true;
+- unmap = false;
+- break;
+- case Task::Unmap:
+- unmap = true;
+- map = false;
+- break;
+- case Task::SetGeometry:
+- setGeometry(m_deferredGeometry);
+- break;
+- case Task::SetWindowFlags:
+- setWindowFlags(window()->flags());
+- break;
+- case Task::SetWindowState:
+- setWindowState(window()->windowState());
+- break;
+- }
+- }
+- m_deferredTasks.clear();
+-
+- if (map) {
+- Q_ASSERT(unmap == false);
+- show();
+- }
+- if (unmap) {
+- Q_ASSERT(map == false);
+- hide();
+- }
+-}
+-
+ void QXcbWindow::handlePropertyNotifyEvent(const xcb_property_notify_event_t *event)
+ {
+ connection()->setTime(event->time);
+
+- const bool wmStateChanged = event->atom == atom(QXcbAtom::WM_STATE);
+- const bool netWmStateChanged = event->atom == atom(QXcbAtom::_NET_WM_STATE);
+- if (netWmStateChanged || wmStateChanged) {
+- if (wmStateChanged && !m_wmStateValid && m_isWmManagedWindow) {
+- // ICCCM 4.1.4
+- // Clients that want to re-use a client window (e.g. by mapping it again)
+- // after withdrawing it must wait for the withdrawal to be complete before
+- // proceeding. The preferred method for doing this is for clients to wait for
+- // a window manager to update or remove the WM_STATE property.
+- m_wmStateValid = true;
+- handleDeferredTasks();
+- }
+- if (event->state == XCB_PROPERTY_DELETE)
++ const bool propertyDeleted = event->state == XCB_PROPERTY_DELETE;
++
++ if (event->atom == atom(QXcbAtom::_NET_WM_STATE) || event->atom == atom(QXcbAtom::WM_STATE)) {
++ if (propertyDeleted)
+ return;
+
+- if (wmStateChanged) {
++ Qt::WindowStates newState = Qt::WindowNoState;
++
++ if (event->atom == atom(QXcbAtom::WM_STATE)) { // WM_STATE: Quick check for 'Minimize'.
+ auto reply = Q_XCB_REPLY(xcb_get_property, xcb_connection(),
+ 0, m_window, atom(QXcbAtom::WM_STATE),
+ XCB_ATOM_ANY, 0, 1024);
+ if (reply && reply->format == 32 && reply->type == atom(QXcbAtom::WM_STATE)) {
+- auto data = static_cast<const quint32 *>(xcb_get_property_value(reply.get()));
+- if (reply->length != 0) {
+- const bool changedToWithdrawn = data[0] == XCB_ICCCM_WM_STATE_WITHDRAWN;
+- const bool changedToIconic = data[0] == XCB_ICCCM_WM_STATE_ICONIC;
+- m_minimized = changedToIconic || (changedToWithdrawn && m_minimized);
+- }
++ const quint32 *data = (const quint32 *)xcb_get_property_value(reply.get());
++ if (reply->length != 0)
++ m_minimized = (data[0] == XCB_ICCCM_WM_STATE_ICONIC
++ || (data[0] == XCB_ICCCM_WM_STATE_WITHDRAWN && m_minimized));
+ }
+ }
+
+- // _NET_WM_STATE handling
+- Qt::WindowStates newState = Qt::WindowNoState;
+ const NetWmStates states = netWmStates();
+ // _NET_WM_STATE_HIDDEN should be set by the Window Manager to indicate that a window would
+ // not be visible on the screen if its desktop/viewport were active and its coordinates were
+@@ -2325,6 +2239,7 @@ void QXcbWindow::handlePropertyNotifyEvent(const xcb_property_notify_event_t *ev
+ if ((m_windowState & Qt::WindowMinimized) && connection()->mouseGrabber() == this)
+ connection()->setMouseGrabber(nullptr);
+ }
++ return;
+ } else if (event->atom == atom(QXcbAtom::_NET_FRAME_EXTENTS)) {
+ m_dirtyFrameMargins = true;
+ }
+diff --git a/qtbase/src/plugins/platforms/xcb/qxcbwindow.h b/qtbase/src/plugins/platforms/xcb/qxcbwindow.h
+index 55af9279b1..6f5c1f5ed9 100644
+--- a/qtbase/src/plugins/platforms/xcb/qxcbwindow.h
++++ b/qtbase/src/plugins/platforms/xcb/qxcbwindow.h
+@@ -74,14 +74,6 @@ public:
+
+ Q_DECLARE_FLAGS(NetWmStates, NetWmState)
+
+- enum Task {
+- Map,
+- Unmap,
+- SetGeometry,
+- SetWindowFlags,
+- SetWindowState
+- };
+-
+ QXcbWindow(QWindow *window);
+ ~QXcbWindow();
+
+@@ -151,9 +143,6 @@ public:
+
+ QXcbWindow *toWindow() override;
+
+- bool shouldDeferTask(Task task);
+- void handleDeferredTasks();
+-
+ void handleMouseEvent(xcb_timestamp_t time, const QPoint &local, const QPoint &global,
+ Qt::KeyboardModifiers modifiers, QEvent::Type type, Qt::MouseEventSource source);
+
+@@ -292,11 +281,6 @@ protected:
+ int m_swapInterval = -1;
+
+ qreal m_sizeHintsScaleFactor = 1.0;
+-
+- bool m_wmStateValid = true;
+- QVector<Task> m_deferredTasks;
+- bool m_isWmManagedWindow = true;
+- QRect m_deferredGeometry;
+ };
+
+ class QXcbForeignWindow : public QXcbWindow
+diff --git a/qtbase/src/plugins/platformthemes/gtk3/qgtk3menu.cpp b/qtbase/src/plugins/platformthemes/gtk3/qgtk3menu.cpp
+index d9d117faeb..640b49daa0 100644
+--- a/qtbase/src/plugins/platformthemes/gtk3/qgtk3menu.cpp
++++ b/qtbase/src/plugins/platformthemes/gtk3/qgtk3menu.cpp
+@@ -85,6 +85,7 @@ QGtk3MenuItem::QGtk3MenuItem()
+ m_checkable(false),
+ m_checked(false),
+ m_enabled(true),
++ m_exclusive(false),
+ m_underline(false),
+ m_invalid(true),
+ m_menu(nullptr),
+diff --git a/qtbase/src/plugins/platformthemes/xdgdesktopportal/qxdgdesktopportalfiledialog.cpp b/qtbase/src/plugins/platformthemes/xdgdesktopportal/qxdgdesktopportalfiledialog.cpp
+index 0048bbc1e6..396e7f6d1c 100644
+--- a/qtbase/src/plugins/platformthemes/xdgdesktopportal/qxdgdesktopportalfiledialog.cpp
++++ b/qtbase/src/plugins/platformthemes/xdgdesktopportal/qxdgdesktopportalfiledialog.cpp
+@@ -102,15 +102,12 @@ const QDBusArgument &operator >>(const QDBusArgument &arg, QXdgDesktopPortalFile
+ class QXdgDesktopPortalFileDialogPrivate
+ {
+ public:
+- QXdgDesktopPortalFileDialogPrivate(QPlatformFileDialogHelper *nativeFileDialog)
++ QXdgDesktopPortalFileDialogPrivate(QPlatformFileDialogHelper *nativeFileDialog, uint fileChooserPortalVersion)
+ : nativeFileDialog(nativeFileDialog)
++ , fileChooserPortalVersion(fileChooserPortalVersion)
+ { }
+
+- WId winId = 0;
+- bool directoryMode = false;
+- bool modal = false;
+- bool multipleFiles = false;
+- bool saveFile = false;
++ QEventLoop loop;
+ QString acceptLabel;
+ QString directory;
+ QString title;
+@@ -121,19 +118,27 @@ public:
+ QString selectedMimeTypeFilter;
+ QString selectedNameFilter;
+ QStringList selectedFiles;
+- QPlatformFileDialogHelper *nativeFileDialog = nullptr;
++ std::unique_ptr<QPlatformFileDialogHelper> nativeFileDialog;
++ uint fileChooserPortalVersion = 0;
++ bool failedToOpen = false;
++ bool directoryMode = false;
++ bool multipleFiles = false;
++ bool saveFile = false;
+ };
+
+-QXdgDesktopPortalFileDialog::QXdgDesktopPortalFileDialog(QPlatformFileDialogHelper *nativeFileDialog)
++QXdgDesktopPortalFileDialog::QXdgDesktopPortalFileDialog(QPlatformFileDialogHelper *nativeFileDialog, uint fileChooserPortalVersion)
+ : QPlatformFileDialogHelper()
+- , d_ptr(new QXdgDesktopPortalFileDialogPrivate(nativeFileDialog))
++ , d_ptr(new QXdgDesktopPortalFileDialogPrivate(nativeFileDialog, fileChooserPortalVersion))
+ {
+ Q_D(QXdgDesktopPortalFileDialog);
+
+ if (d->nativeFileDialog) {
+- connect(d->nativeFileDialog, SIGNAL(accept()), this, SIGNAL(accept()));
+- connect(d->nativeFileDialog, SIGNAL(reject()), this, SIGNAL(reject()));
++ connect(d->nativeFileDialog.get(), SIGNAL(accept()), this, SIGNAL(accept()));
++ connect(d->nativeFileDialog.get(), SIGNAL(reject()), this, SIGNAL(reject()));
+ }
++
++ d->loop.connect(this, SIGNAL(accept()), SLOT(quit()));
++ d->loop.connect(this, SIGNAL(reject()), SLOT(quit()));
+ }
+
+ QXdgDesktopPortalFileDialog::~QXdgDesktopPortalFileDialog()
+@@ -177,7 +182,7 @@ void QXdgDesktopPortalFileDialog::initializeDialog()
+ setDirectory(options()->initialDirectory());
+ }
+
+-void QXdgDesktopPortalFileDialog::openPortal()
++void QXdgDesktopPortalFileDialog::openPortal(Qt::WindowFlags windowFlags, Qt::WindowModality windowModality, QWindow *parent)
+ {
+ Q_D(QXdgDesktopPortalFileDialog);
+
+@@ -185,13 +190,13 @@ void QXdgDesktopPortalFileDialog::openPortal()
+ QLatin1String("/org/freedesktop/portal/desktop"),
+ QLatin1String("org.freedesktop.portal.FileChooser"),
+ d->saveFile ? QLatin1String("SaveFile") : QLatin1String("OpenFile"));
+- QString parentWindowId = QLatin1String("x11:") + QString::number(d->winId, 16);
++ QString parentWindowId = QLatin1String("x11:") + QString::number(parent ? parent->winId() : 0, 16);
+
+ QVariantMap options;
+ if (!d->acceptLabel.isEmpty())
+ options.insert(QLatin1String("accept_label"), d->acceptLabel);
+
+- options.insert(QLatin1String("modal"), d->modal);
++ options.insert(QLatin1String("modal"), windowModality != Qt::NonModal);
+ options.insert(QLatin1String("multiple"), d->multipleFiles);
+ options.insert(QLatin1String("directory"), d->directoryMode);
+
+@@ -290,10 +295,18 @@ void QXdgDesktopPortalFileDialog::openPortal()
+
+ QDBusPendingCall pendingCall = QDBusConnection::sessionBus().asyncCall(message);
+ QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(pendingCall);
+- connect(watcher, &QDBusPendingCallWatcher::finished, this, [this] (QDBusPendingCallWatcher *watcher) {
++ connect(watcher, &QDBusPendingCallWatcher::finished, this, [=] (QDBusPendingCallWatcher *watcher) {
+ QDBusPendingReply<QDBusObjectPath> reply = *watcher;
+- if (reply.isError()) {
+- Q_EMIT reject();
++ // Any error means the dialog is not shown and we need to fallback
++ d->failedToOpen = reply.isError();
++ if (d->failedToOpen) {
++ if (d->nativeFileDialog) {
++ d->nativeFileDialog->show(windowFlags, windowModality, parent);
++ if (d->loop.isRunning())
++ d->nativeFileDialog->exec();
++ } else {
++ Q_EMIT reject();
++ }
+ } else {
+ QDBusConnection::sessionBus().connect(nullptr,
+ reply.value().path(),
+@@ -302,6 +315,7 @@ void QXdgDesktopPortalFileDialog::openPortal()
+ this,
+ SLOT(gotResponse(uint,QVariantMap)));
+ }
++ watcher->deleteLater();
+ });
+ }
+
+@@ -326,7 +340,7 @@ QUrl QXdgDesktopPortalFileDialog::directory() const
+ {
+ Q_D(const QXdgDesktopPortalFileDialog);
+
+- if (d->nativeFileDialog && (options()->fileMode() == QFileDialogOptions::Directory || options()->fileMode() == QFileDialogOptions::DirectoryOnly))
++ if (d->nativeFileDialog && useNativeFileDialog())
+ return d->nativeFileDialog->directory();
+
+ return d->directory;
+@@ -348,7 +362,7 @@ QList<QUrl> QXdgDesktopPortalFileDialog::selectedFiles() const
+ {
+ Q_D(const QXdgDesktopPortalFileDialog);
+
+- if (d->nativeFileDialog && (options()->fileMode() == QFileDialogOptions::Directory || options()->fileMode() == QFileDialogOptions::DirectoryOnly))
++ if (d->nativeFileDialog && useNativeFileDialog())
+ return d->nativeFileDialog->selectedFiles();
+
+ QList<QUrl> files;
+@@ -403,16 +417,13 @@ void QXdgDesktopPortalFileDialog::exec()
+ {
+ Q_D(QXdgDesktopPortalFileDialog);
+
+- if (d->nativeFileDialog && (options()->fileMode() == QFileDialogOptions::Directory || options()->fileMode() == QFileDialogOptions::DirectoryOnly)) {
++ if (d->nativeFileDialog && useNativeFileDialog()) {
+ d->nativeFileDialog->exec();
+ return;
+ }
+
+ // HACK we have to avoid returning until we emit that the dialog was accepted or rejected
+- QEventLoop loop;
+- loop.connect(this, SIGNAL(accept()), SLOT(quit()));
+- loop.connect(this, SIGNAL(reject()), SLOT(quit()));
+- loop.exec();
++ d->loop.exec();
+ }
+
+ void QXdgDesktopPortalFileDialog::hide()
+@@ -429,13 +440,10 @@ bool QXdgDesktopPortalFileDialog::show(Qt::WindowFlags windowFlags, Qt::WindowMo
+
+ initializeDialog();
+
+- d->modal = windowModality != Qt::NonModal;
+- d->winId = parent ? parent->winId() : 0;
+-
+- if (d->nativeFileDialog && (options()->fileMode() == QFileDialogOptions::Directory || options()->fileMode() == QFileDialogOptions::DirectoryOnly))
++ if (d->nativeFileDialog && useNativeFileDialog(OpenFallback))
+ return d->nativeFileDialog->show(windowFlags, windowModality, parent);
+
+- openPortal();
++ openPortal(windowFlags, windowModality, parent);
+
+ return true;
+ }
+@@ -465,4 +473,21 @@ void QXdgDesktopPortalFileDialog::gotResponse(uint response, const QVariantMap &
+ }
+ }
+
++bool QXdgDesktopPortalFileDialog::useNativeFileDialog(QXdgDesktopPortalFileDialog::FallbackType fallbackType) const
++{
++ Q_D(const QXdgDesktopPortalFileDialog);
++
++ if (d->failedToOpen && fallbackType != OpenFallback)
++ return true;
++
++ if (d->fileChooserPortalVersion < 3) {
++ if (options()->fileMode() == QFileDialogOptions::Directory)
++ return true;
++ else if (options()->fileMode() == QFileDialogOptions::DirectoryOnly)
++ return true;
++ }
++
++ return false;
++}
++
+ QT_END_NAMESPACE
+diff --git a/qtbase/src/plugins/platformthemes/xdgdesktopportal/qxdgdesktopportalfiledialog_p.h b/qtbase/src/plugins/platformthemes/xdgdesktopportal/qxdgdesktopportalfiledialog_p.h
+index 4f4de96ecf..65e22a5cf2 100644
+--- a/qtbase/src/plugins/platformthemes/xdgdesktopportal/qxdgdesktopportalfiledialog_p.h
++++ b/qtbase/src/plugins/platformthemes/xdgdesktopportal/qxdgdesktopportalfiledialog_p.h
+@@ -51,6 +51,11 @@ class QXdgDesktopPortalFileDialog : public QPlatformFileDialogHelper
+ Q_OBJECT
+ Q_DECLARE_PRIVATE(QXdgDesktopPortalFileDialog)
+ public:
++ enum FallbackType {
++ GenericFallback,
++ OpenFallback
++ };
++
+ enum ConditionType : uint {
+ GlobalPattern = 0,
+ MimeType = 1
+@@ -69,7 +74,7 @@ public:
+ };
+ typedef QVector<Filter> FilterList;
+
+- QXdgDesktopPortalFileDialog(QPlatformFileDialogHelper *nativeFileDialog = nullptr);
++ QXdgDesktopPortalFileDialog(QPlatformFileDialogHelper *nativeFileDialog = nullptr, uint fileChooserPortalVersion = 0);
+ ~QXdgDesktopPortalFileDialog();
+
+ bool defaultNameFilterDisables() const override;
+@@ -92,7 +97,8 @@ private Q_SLOTS:
+
+ private:
+ void initializeDialog();
+- void openPortal();
++ void openPortal(Qt::WindowFlags windowFlags, Qt::WindowModality windowModality, QWindow *parent);
++ bool useNativeFileDialog(FallbackType fallbackType = GenericFallback) const;
+
+ QScopedPointer<QXdgDesktopPortalFileDialogPrivate> d_ptr;
+ };
+diff --git a/qtbase/src/plugins/platformthemes/xdgdesktopportal/qxdgdesktopportaltheme.cpp b/qtbase/src/plugins/platformthemes/xdgdesktopportal/qxdgdesktopportaltheme.cpp
+index fb324afbd8..b809503122 100644
+--- a/qtbase/src/plugins/platformthemes/xdgdesktopportal/qxdgdesktopportaltheme.cpp
++++ b/qtbase/src/plugins/platformthemes/xdgdesktopportal/qxdgdesktopportaltheme.cpp
+@@ -111,6 +111,7 @@ QXdgDesktopPortalTheme::QXdgDesktopPortalTheme()
+ if (reply.isValid()) {
+ d->fileChooserPortalVersion = reply.value().toUInt();
+ }
++ watcher->deleteLater();
+ });
+ }
+
+@@ -152,11 +153,12 @@ QPlatformDialogHelper* QXdgDesktopPortalTheme::createPlatformDialogHelper(Dialog
+ {
+ Q_D(const QXdgDesktopPortalTheme);
+
+- if (type == FileDialog) {
++ if (type == FileDialog && d->fileChooserPortalVersion) {
+ // Older versions of FileChooser portal don't support opening directories, therefore we fallback
+ // to native file dialog opened inside the sandbox to open a directory.
+- if (d->fileChooserPortalVersion < 3 && d->baseTheme->usePlatformNativeDialog(type))
+- return new QXdgDesktopPortalFileDialog(static_cast<QPlatformFileDialogHelper*>(d->baseTheme->createPlatformDialogHelper(type)));
++ if (d->baseTheme->usePlatformNativeDialog(type))
++ return new QXdgDesktopPortalFileDialog(static_cast<QPlatformFileDialogHelper*>(d->baseTheme->createPlatformDialogHelper(type)),
++ d->fileChooserPortalVersion);
+
+ return new QXdgDesktopPortalFileDialog;
+ }
+diff --git a/qtbase/src/plugins/printsupport/cups/qcupsprintengine.cpp b/qtbase/src/plugins/printsupport/cups/qcupsprintengine.cpp
+index 43d5e119ad..1f9cbc4565 100644
+--- a/qtbase/src/plugins/printsupport/cups/qcupsprintengine.cpp
++++ b/qtbase/src/plugins/printsupport/cups/qcupsprintengine.cpp
+@@ -89,8 +89,10 @@ void QCupsPrintEngine::setProperty(PrintEnginePropertyKey key, const QVariant &v
+ break;
+ case PPK_Duplex: {
+ QPrint::DuplexMode mode = QPrint::DuplexMode(value.toInt());
+- if (mode != d->duplex && d->m_printDevice.supportedDuplexModes().contains(mode))
++ if (d->m_printDevice.supportedDuplexModes().contains(mode)) {
+ d->duplex = mode;
++ d->duplexRequestedExplicitly = true;
++ }
+ break;
+ }
+ case PPK_PrinterName:
+@@ -277,9 +279,12 @@ void QCupsPrintEnginePrivate::changePrinter(const QString &newPrinter)
+ m_printDevice.swap(printDevice);
+ printerName = m_printDevice.id();
+
+- // Check if new printer supports current settings, otherwise us defaults
+- if (duplex != QPrint::DuplexAuto && !m_printDevice.supportedDuplexModes().contains(duplex))
++ // in case a duplex value was explicitly set, check if new printer supports current value,
++ // otherwise use device default
++ if (!duplexRequestedExplicitly || !m_printDevice.supportedDuplexModes().contains(duplex)) {
+ duplex = m_printDevice.defaultDuplexMode();
++ duplexRequestedExplicitly = false;
++ }
+ QPrint::ColorMode colorMode = grayscale ? QPrint::GrayScale : QPrint::Color;
+ if (!m_printDevice.supportedColorModes().contains(colorMode))
+ grayscale = m_printDevice.defaultColorMode() == QPrint::GrayScale;
+diff --git a/qtbase/src/plugins/printsupport/cups/qcupsprintengine_p.h b/qtbase/src/plugins/printsupport/cups/qcupsprintengine_p.h
+index c021b0c643..8f81fe478d 100644
+--- a/qtbase/src/plugins/printsupport/cups/qcupsprintengine_p.h
++++ b/qtbase/src/plugins/printsupport/cups/qcupsprintengine_p.h
+@@ -100,6 +100,7 @@ private:
+ QStringList cupsOptions;
+ QString cupsTempFile;
+ QPrint::DuplexMode duplex;
++ bool duplexRequestedExplicitly = false;
+ };
+
+ QT_END_NAMESPACE
+diff --git a/qtbase/src/plugins/sqldrivers/ibase/qsql_ibase.cpp b/qtbase/src/plugins/sqldrivers/ibase/qsql_ibase.cpp
+index 67e7154fa6..40876152e5 100644
+--- a/qtbase/src/plugins/sqldrivers/ibase/qsql_ibase.cpp
++++ b/qtbase/src/plugins/sqldrivers/ibase/qsql_ibase.cpp
+@@ -817,7 +817,7 @@ bool QIBaseResultPrivate::writeArray(int column, const QList<QVariant> &list)
+ ba.resize(int(bufLen));
+
+ if (list.size() > arraySize) {
+- error = QLatin1String("Array size missmatch: size of %1 is %2, size of provided list is %3");
++ error = QLatin1String("Array size mismatch: size of %1 is %2, size of provided list is %3");
+ error = error.arg(QLatin1String(sqlname)).arg(arraySize).arg(list.size());
+ q->setLastError(QSqlError(error, QLatin1String(""), QSqlError::StatementError));
+ return false;
+diff --git a/qtbase/src/plugins/sqldrivers/mysql/qsql_mysql.cpp b/qtbase/src/plugins/sqldrivers/mysql/qsql_mysql.cpp
+index 7ca055eea2..6bc9d46755 100644
+--- a/qtbase/src/plugins/sqldrivers/mysql/qsql_mysql.cpp
++++ b/qtbase/src/plugins/sqldrivers/mysql/qsql_mysql.cpp
+@@ -223,7 +223,7 @@ public:
+ struct QMyField
+ {
+ char *outField = nullptr;
+- MYSQL_FIELD *myField = nullptr;
++ const MYSQL_FIELD *myField = nullptr;
+ QMetaType::Type type = QMetaType::UnknownType;
+ my_bool nullIndicator = false;
+ ulong bufLength = 0ul;
+@@ -361,7 +361,7 @@ static bool qIsInteger(int t)
+ void QMYSQLResultPrivate::bindBlobs()
+ {
+ int i;
+- MYSQL_FIELD *fieldInfo;
++ const MYSQL_FIELD *fieldInfo;
+ MYSQL_BIND *bind;
+
+ for(i = 0; i < fields.count(); ++i) {
+@@ -379,7 +379,6 @@ void QMYSQLResultPrivate::bindBlobs()
+ bool QMYSQLResultPrivate::bindInValues()
+ {
+ MYSQL_BIND *bind;
+- char *field;
+ int i = 0;
+
+ if (!meta)
+@@ -392,35 +391,34 @@ bool QMYSQLResultPrivate::bindInValues()
+ inBinds = new MYSQL_BIND[fields.size()];
+ memset(inBinds, 0, fields.size() * sizeof(MYSQL_BIND));
+
+- MYSQL_FIELD *fieldInfo;
++ const MYSQL_FIELD *fieldInfo;
+
+ while((fieldInfo = mysql_fetch_field(meta))) {
++ bind = &inBinds[i];
++
+ QMyField &f = fields[i];
+ f.myField = fieldInfo;
+-
++ bind->buffer_length = f.bufLength = fieldInfo->length + 1;
++ bind->buffer_type = fieldInfo->type;
+ f.type = qDecodeMYSQLType(fieldInfo->type, fieldInfo->flags);
+ if (qIsBlob(fieldInfo->type)) {
+ // the size of a blob-field is available as soon as we call
+ // mysql_stmt_store_result()
+ // after mysql_stmt_exec() in QMYSQLResult::exec()
+- fieldInfo->length = 0;
++ bind->buffer_length = f.bufLength = 0;
+ hasBlobs = true;
+ } else if (qIsInteger(f.type)) {
+- fieldInfo->length = 8;
++ bind->buffer_length = f.bufLength = 8;
+ } else {
+- fieldInfo->type = MYSQL_TYPE_STRING;
++ bind->buffer_type = MYSQL_TYPE_STRING;
+ }
+- bind = &inBinds[i];
+- field = new char[fieldInfo->length + 1];
+- memset(field, 0, fieldInfo->length + 1);
+
+- bind->buffer_type = fieldInfo->type;
+- bind->buffer = field;
+- bind->buffer_length = f.bufLength = fieldInfo->length + 1;
+ bind->is_null = &f.nullIndicator;
+ bind->length = &f.bufLength;
+ bind->is_unsigned = fieldInfo->flags & UNSIGNED_FLAG ? 1 : 0;
+- f.outField=field;
++
++ char *field = new char[bind->buffer_length + 1]{};
++ bind->buffer = f.outField = field;
+
+ ++i;
+ }
+@@ -1369,20 +1367,20 @@ bool QMYSQLDriver::open(const QString& db,
+ }
+
+ #if MYSQL_VERSION_ID >= 50007
+- if (mysql_get_client_version() >= 50503 && mysql_get_server_version(d->mysql) >= 50503) {
+- // force the communication to be utf8mb4 (only utf8mb4 supports 4-byte characters)
+- mysql_set_character_set(d->mysql, "utf8mb4");
++ // force the communication to be utf8mb4 (only utf8mb4 supports 4-byte characters)
++ if (mysql_set_character_set(d->mysql, "utf8mb4")) {
++ // this failed, try forcing it to utf (BMP only)
++ if (mysql_set_character_set(d->mysql, "utf8"))
++ qWarning() << "MySQL: Unable to set the client character set to utf8.";
+ #if QT_CONFIG(textcodec)
+- d->tc = QTextCodec::codecForName("UTF-8");
++ else
++ d->tc = codec(d->mysql);
+ #endif
+- } else
+- {
+- // force the communication to be utf8
+- mysql_set_character_set(d->mysql, "utf8");
++ }
+ #if QT_CONFIG(textcodec)
+- d->tc = codec(d->mysql);
++ else
++ d->tc = QTextCodec::codecForName("UTF-8");
+ #endif
+- }
+ #endif // MYSQL_VERSION_ID >= 50007
+
+ d->preparedQuerysEnabled = checkPreparedQueries(d->mysql);
+diff --git a/qtbase/src/printsupport/dialogs/images/print-24.png b/qtbase/src/printsupport/dialogs/images/printer-24.png
+similarity index 100%
+rename from src/printsupport/dialogs/images/print-24.png
+rename to src/printsupport/dialogs/images/printer-24.png
+diff --git a/qtbase/src/printsupport/dialogs/images/print-32.png b/qtbase/src/printsupport/dialogs/images/printer-32.png
+similarity index 100%
+rename from src/printsupport/dialogs/images/print-32.png
+rename to src/printsupport/dialogs/images/printer-32.png
+diff --git a/qtbase/src/printsupport/dialogs/images/view-page-sided-24.png b/qtbase/src/printsupport/dialogs/images/view-pages-facing-24.png
+similarity index 100%
+rename from src/printsupport/dialogs/images/view-page-sided-24.png
+rename to src/printsupport/dialogs/images/view-pages-facing-24.png
+diff --git a/qtbase/src/printsupport/dialogs/images/view-page-sided-32.png b/qtbase/src/printsupport/dialogs/images/view-pages-facing-32.png
+similarity index 100%
+rename from src/printsupport/dialogs/images/view-page-sided-32.png
+rename to src/printsupport/dialogs/images/view-pages-facing-32.png
+diff --git a/qtbase/src/printsupport/dialogs/images/view-page-multi-24.png b/qtbase/src/printsupport/dialogs/images/view-pages-overview-24.png
+similarity index 100%
+rename from src/printsupport/dialogs/images/view-page-multi-24.png
+rename to src/printsupport/dialogs/images/view-pages-overview-24.png
+diff --git a/qtbase/src/printsupport/dialogs/images/view-page-multi-32.png b/qtbase/src/printsupport/dialogs/images/view-pages-overview-32.png
+similarity index 100%
+rename from src/printsupport/dialogs/images/view-page-multi-32.png
+rename to src/printsupport/dialogs/images/view-pages-overview-32.png
+diff --git a/qtbase/src/printsupport/dialogs/images/view-page-one-24.png b/qtbase/src/printsupport/dialogs/images/view-pages-single-24.png
+similarity index 100%
+rename from src/printsupport/dialogs/images/view-page-one-24.png
+rename to src/printsupport/dialogs/images/view-pages-single-24.png
+diff --git a/qtbase/src/printsupport/dialogs/images/view-page-one-32.png b/qtbase/src/printsupport/dialogs/images/view-pages-single-32.png
+similarity index 100%
+rename from src/printsupport/dialogs/images/view-page-one-32.png
+rename to src/printsupport/dialogs/images/view-pages-single-32.png
+diff --git a/qtbase/src/printsupport/dialogs/images/fit-page-24.png b/qtbase/src/printsupport/dialogs/images/zoom-fit-page-24.png
+similarity index 100%
+rename from src/printsupport/dialogs/images/fit-page-24.png
+rename to src/printsupport/dialogs/images/zoom-fit-page-24.png
+diff --git a/qtbase/src/printsupport/dialogs/images/fit-page-32.png b/qtbase/src/printsupport/dialogs/images/zoom-fit-page-32.png
+similarity index 100%
+rename from src/printsupport/dialogs/images/fit-page-32.png
+rename to src/printsupport/dialogs/images/zoom-fit-page-32.png
+diff --git a/qtbase/src/printsupport/dialogs/images/fit-width-24.png b/qtbase/src/printsupport/dialogs/images/zoom-fit-width-24.png
+similarity index 100%
+rename from src/printsupport/dialogs/images/fit-width-24.png
+rename to src/printsupport/dialogs/images/zoom-fit-width-24.png
+diff --git a/qtbase/src/printsupport/dialogs/images/fit-width-32.png b/qtbase/src/printsupport/dialogs/images/zoom-fit-width-32.png
+similarity index 100%
+rename from src/printsupport/dialogs/images/fit-width-32.png
+rename to src/printsupport/dialogs/images/zoom-fit-width-32.png
+diff --git a/qtbase/src/printsupport/dialogs/qpagesetupdialog_unix.cpp b/qtbase/src/printsupport/dialogs/qpagesetupdialog_unix.cpp
+index 78e5b8d1ef..2a28516719 100644
+--- a/qtbase/src/printsupport/dialogs/qpagesetupdialog_unix.cpp
++++ b/qtbase/src/printsupport/dialogs/qpagesetupdialog_unix.cpp
+@@ -532,6 +532,7 @@ void QPageSetupWidget::updateWidget()
+ void QPageSetupWidget::setupPrinter() const
+ {
+ m_printer->setPageLayout(m_pageLayout);
++ m_printer->setPageOrientation(m_pageLayout.orientation());
+ #if QT_CONFIG(cups)
+ QCUPSSupport::PagesPerSheet pagesPerSheet = qvariant_cast<QCUPSSupport::PagesPerSheet>(m_ui.pagesPerSheetCombo->currentData()
+ );
+diff --git a/qtbase/src/printsupport/dialogs/qprintdialog.qrc b/qtbase/src/printsupport/dialogs/qprintdialog.qrc
+index 5a579baa55..10b8e1d341 100644
+--- a/qtbase/src/printsupport/dialogs/qprintdialog.qrc
++++ b/qtbase/src/printsupport/dialogs/qprintdialog.qrc
+@@ -1,9 +1,9 @@
+ <!DOCTYPE RCC><RCC version="1.0">
+ <qresource prefix="/qt-project.org/dialogs/qprintpreviewdialog">
+-<file>images/fit-page-24.png</file>
+-<file>images/fit-page-32.png</file>
+-<file>images/fit-width-24.png</file>
+-<file>images/fit-width-32.png</file>
++<file>images/zoom-fit-page-24.png</file>
++<file>images/zoom-fit-page-32.png</file>
++<file>images/zoom-fit-width-24.png</file>
++<file>images/zoom-fit-width-32.png</file>
+ <file>images/go-first-24.png</file>
+ <file>images/go-first-32.png</file>
+ <file>images/go-last-24.png</file>
+@@ -18,14 +18,14 @@
+ <file>images/layout-portrait-32.png</file>
+ <file>images/page-setup-24.png</file>
+ <file>images/page-setup-32.png</file>
+-<file>images/print-24.png</file>
+-<file>images/print-32.png</file>
+-<file>images/view-page-multi-24.png</file>
+-<file>images/view-page-multi-32.png</file>
+-<file>images/view-page-one-24.png</file>
+-<file>images/view-page-one-32.png</file>
+-<file>images/view-page-sided-24.png</file>
+-<file>images/view-page-sided-32.png</file>
++<file>images/printer-24.png</file>
++<file>images/printer-32.png</file>
++<file>images/view-pages-overview-24.png</file>
++<file>images/view-pages-overview-32.png</file>
++<file>images/view-pages-single-24.png</file>
++<file>images/view-pages-single-32.png</file>
++<file>images/view-pages-facing-24.png</file>
++<file>images/view-pages-facing-32.png</file>
+ <file>images/zoom-in-24.png</file>
+ <file>images/zoom-in-32.png</file>
+ <file>images/zoom-out-24.png</file>
+diff --git a/qtbase/src/printsupport/dialogs/qprintdialog_unix.cpp b/qtbase/src/printsupport/dialogs/qprintdialog_unix.cpp
+index c5b845f4ec..5a5ba1d0a8 100644
+--- a/qtbase/src/printsupport/dialogs/qprintdialog_unix.cpp
++++ b/qtbase/src/printsupport/dialogs/qprintdialog_unix.cpp
+@@ -702,13 +702,14 @@ void QPrintDialogPrivate::selectPrinter(const QPrinter::OutputFormat outputForma
+ else
+ options.grayscale->setChecked(true);
+
+- // keep duplex value explicitly set by user, if any, and selected printer supports it;
+- // use device default otherwise
++ // duplex priorities to be as follows:
++ // 1) a user-selected duplex value in the dialog has highest prority
++ // 2) duplex value set in the QPrinter
+ QPrint::DuplexMode duplex;
+ if (explicitDuplexMode != QPrint::DuplexAuto && supportedDuplexMode.contains(explicitDuplexMode))
+ duplex = explicitDuplexMode;
+ else
+- duplex = top->d->m_currentPrintDevice.defaultDuplexMode();
++ duplex = static_cast<QPrint::DuplexMode>(p->duplex());
+ switch (duplex) {
+ case QPrint::DuplexNone:
+ options.noDuplex->setChecked(true); break;
+@@ -1242,10 +1243,10 @@ void QUnixPrintWidgetPrivate::_q_printerChanged(int index)
+ QString filename = widget.filename->text();
+ widget.filename->setText(filename);
+ widget.lOutput->setEnabled(true);
+- if (optionsPane)
+- optionsPane->selectPrinter(QPrinter::PdfFormat);
+ printer->setOutputFormat(QPrinter::PdfFormat);
+ m_currentPrintDevice = QPrintDevice();
++ if (optionsPane)
++ optionsPane->selectPrinter(QPrinter::PdfFormat);
+ return;
+ }
+ }
+diff --git a/qtbase/src/printsupport/dialogs/qprintpreviewdialog.cpp b/qtbase/src/printsupport/dialogs/qprintpreviewdialog.cpp
+index 39575d5f57..23b7e89538 100644
+--- a/qtbase/src/printsupport/dialogs/qprintpreviewdialog.cpp
++++ b/qtbase/src/printsupport/dialogs/qprintpreviewdialog.cpp
+@@ -352,7 +352,7 @@ void QPrintPreviewDialogPrivate::init(QPrinter *_printer)
+ static inline void qt_setupActionIcon(QAction *action, QLatin1String name)
+ {
+ QLatin1String imagePrefix(":/qt-project.org/dialogs/qprintpreviewdialog/images/");
+- QIcon icon;
++ QIcon icon = QIcon::fromTheme(name);
+ icon.addFile(imagePrefix + name + QLatin1String("-24.png"), QSize(24, 24));
+ icon.addFile(imagePrefix + name + QLatin1String("-32.png"), QSize(32, 32));
+ action->setIcon(icon);
+@@ -383,8 +383,8 @@ void QPrintPreviewDialogPrivate::setupActions()
+ fitPageAction->setObjectName(QLatin1String("fitPageAction"));
+ fitWidthAction->setCheckable(true);
+ fitPageAction->setCheckable(true);
+- qt_setupActionIcon(fitWidthAction, QLatin1String("fit-width"));
+- qt_setupActionIcon(fitPageAction, QLatin1String("fit-page"));
++ qt_setupActionIcon(fitWidthAction, QLatin1String("zoom-fit-width"));
++ qt_setupActionIcon(fitPageAction, QLatin1String("zoom-fit-page"));
+ QObject::connect(fitGroup, SIGNAL(triggered(QAction*)), q, SLOT(_q_fit(QAction*)));
+
+ // Zoom
+@@ -410,9 +410,9 @@ void QPrintPreviewDialogPrivate::setupActions()
+ singleModeAction = modeGroup->addAction(QCoreApplication::translate("QPrintPreviewDialog", "Show single page"));
+ facingModeAction = modeGroup->addAction(QCoreApplication::translate("QPrintPreviewDialog", "Show facing pages"));
+ overviewModeAction = modeGroup->addAction(QCoreApplication::translate("QPrintPreviewDialog", "Show overview of all pages"));
+- qt_setupActionIcon(singleModeAction, QLatin1String("view-page-one"));
+- qt_setupActionIcon(facingModeAction, QLatin1String("view-page-sided"));
+- qt_setupActionIcon(overviewModeAction, QLatin1String("view-page-multi"));
++ qt_setupActionIcon(singleModeAction, QLatin1String("view-pages-single"));
++ qt_setupActionIcon(facingModeAction, QLatin1String("view-pages-facing"));
++ qt_setupActionIcon(overviewModeAction, QLatin1String("view-pages-overview"));
+ singleModeAction->setObjectName(QLatin1String("singleModeAction"));
+ facingModeAction->setObjectName(QLatin1String("facingModeAction"));
+ overviewModeAction->setObjectName(QLatin1String("overviewModeAction"));
+@@ -426,7 +426,7 @@ void QPrintPreviewDialogPrivate::setupActions()
+ printerGroup = new QActionGroup(q);
+ printAction = printerGroup->addAction(QCoreApplication::translate("QPrintPreviewDialog", "Print"));
+ pageSetupAction = printerGroup->addAction(QCoreApplication::translate("QPrintPreviewDialog", "Page setup"));
+- qt_setupActionIcon(printAction, QLatin1String("print"));
++ qt_setupActionIcon(printAction, QLatin1String("printer"));
+ qt_setupActionIcon(pageSetupAction, QLatin1String("page-setup"));
+ QObject::connect(printAction, SIGNAL(triggered(bool)), q, SLOT(_q_print()));
+ QObject::connect(pageSetupAction, SIGNAL(triggered(bool)), q, SLOT(_q_pageSetup()));
+diff --git a/qtbase/src/sql/kernel/qsqlquery.cpp b/qtbase/src/sql/kernel/qsqlquery.cpp
+index 32c6166c79..60afef10c3 100644
+--- a/qtbase/src/sql/kernel/qsqlquery.cpp
++++ b/qtbase/src/sql/kernel/qsqlquery.cpp
+@@ -1,6 +1,6 @@
+ /****************************************************************************
+ **
+-** Copyright (C) 2016 The Qt Company Ltd.
++** Copyright (C) 2022 The Qt Company Ltd.
+ ** Contact: https://www.qt.io/licensing/
+ **
+ ** This file is part of the QtSql module of the Qt Toolkit.
+@@ -377,6 +377,10 @@ bool QSqlQuery::exec(const QString& query)
+ QElapsedTimer t;
+ t.start();
+ #endif
++ if (!driver()) {
++ qWarning("QSqlQuery::exec: called before driver has been set up");
++ return false;
++ }
+ if (d->ref.loadRelaxed() != 1) {
+ bool fo = isForwardOnly();
+ *this = QSqlQuery(driver()->createResult());
+diff --git a/qtbase/src/testlib/qabstractitemmodeltester.cpp b/qtbase/src/testlib/qabstractitemmodeltester.cpp
+index 8efb9c53d4..ce062f66d7 100644
+--- a/qtbase/src/testlib/qabstractitemmodeltester.cpp
++++ b/qtbase/src/testlib/qabstractitemmodeltester.cpp
+@@ -454,7 +454,7 @@ void QAbstractItemModelTesterPrivate::parent()
+
+ // Common error test #2, make sure that a second level index has a parent
+ // that is the first level index.
+- if (model->rowCount(topIndex) > 0) {
++ if (model->rowCount(topIndex) > 0 && model->columnCount(topIndex) > 0) {
+ QModelIndex childIndex = model->index(0, 0, topIndex);
+ MODELTESTER_VERIFY(childIndex.isValid());
+ MODELTESTER_COMPARE(model->parent(childIndex), topIndex);
+diff --git a/qtbase/src/testlib/qasciikey.cpp b/qtbase/src/testlib/qasciikey.cpp
+index 9a308da2bc..93498b256f 100644
+--- a/qtbase/src/testlib/qasciikey.cpp
++++ b/qtbase/src/testlib/qasciikey.cpp
+@@ -498,6 +498,11 @@ char QTest::keyToAscii(Qt::Key key)
+ case Qt::Key_LaunchE : return 0; // = 0x10b0,
+ case Qt::Key_LaunchF : return 0; // = 0x10b1,
+
++ // Keypad navigation keys
++ case Qt::Key_Select : return 0; // = 0x01010000
++ case Qt::Key_Yes : return 0; // = 0x01010001
++ case Qt::Key_No : return 0; // = 0x01010002
++
+ default: QTEST_ASSERT(false); return 0;
+ }
+ }
+diff --git a/qtbase/src/testlib/qtestresult.cpp b/qtbase/src/testlib/qtestresult.cpp
+index 88028aac6e..2e89930776 100644
+--- a/qtbase/src/testlib/qtestresult.cpp
++++ b/qtbase/src/testlib/qtestresult.cpp
+@@ -251,7 +251,8 @@ bool QTestResult::verify(bool statement, const char *statementStr,
+ {
+ QTEST_ASSERT(statementStr);
+
+- char msg[1024] = {'\0'};
++ char msg[1024];
++ msg[0] = '\0';
+
+ if (QTestLog::verboseLevel() >= 2) {
+ qsnprintf(msg, 1024, "QVERIFY(%s)", statementStr);
+@@ -309,7 +310,8 @@ static bool compareHelper(bool success, const char *failureMsg,
+ bool hasValues = true)
+ {
+ const size_t maxMsgLen = 1024;
+- char msg[maxMsgLen] = {'\0'};
++ char msg[maxMsgLen];
++ msg[0] = '\0';
+
+ QTEST_ASSERT(expected);
+ QTEST_ASSERT(actual);
+diff --git a/qtbase/src/widgets/dialogs/qcolordialog.cpp b/qtbase/src/widgets/dialogs/qcolordialog.cpp
+index 4247731275..cb325be85c 100644
+--- a/qtbase/src/widgets/dialogs/qcolordialog.cpp
++++ b/qtbase/src/widgets/dialogs/qcolordialog.cpp
+@@ -78,7 +78,10 @@
+ #include "qwindow.h"
+
+ #include "private/qdialog_p.h"
++#include "private/qguiapplication_p.h"
+
++#include <qpa/qplatformservices.h>
++#include <qpa/qplatformintegration.h>
+ #include <algorithm>
+
+ QT_BEGIN_NAMESPACE
+@@ -1611,6 +1614,20 @@ void QColorDialogPrivate::_q_newStandard(int r, int c)
+ void QColorDialogPrivate::_q_pickScreenColor()
+ {
+ Q_Q(QColorDialog);
++
++ auto *platformServices = QGuiApplicationPrivate::platformIntegration()->services();
++ if (platformServices->hasCapability(QPlatformServices::Capability::ColorPicking)) {
++ if (auto *colorPicker = platformServices->colorPicker(q->windowHandle())) {
++ q->connect(colorPicker, &QPlatformServiceColorPicker::colorPicked, q,
++ [q, colorPicker](const QColor &color) {
++ colorPicker->deleteLater();
++ q->setCurrentColor(color);
++ });
++ colorPicker->pickColor();
++ return;
++ }
++ }
++
+ if (!colorPickingEventFilter)
+ colorPickingEventFilter = new QColorPickingEventFilter(this, q);
+ q->installEventFilter(colorPickingEventFilter);
+diff --git a/qtbase/src/widgets/itemviews/qabstractitemdelegate.cpp b/qtbase/src/widgets/itemviews/qabstractitemdelegate.cpp
+index e120817edc..8ea36b5427 100644
+--- a/qtbase/src/widgets/itemviews/qabstractitemdelegate.cpp
++++ b/qtbase/src/widgets/itemviews/qabstractitemdelegate.cpp
+@@ -400,12 +400,7 @@ bool QAbstractItemDelegate::helpEvent(QHelpEvent *event,
+ const QString tooltip = index.isValid() ?
+ d->textForRole(Qt::ToolTipRole, index.data(Qt::ToolTipRole), option.locale, precision) :
+ QString();
+- QRect rect;
+- if (index.isValid()) {
+- const QRect r = view->visualRect(index);
+- rect = QRect(view->mapToGlobal(r.topLeft()), r.size());
+- }
+- QToolTip::showText(he->globalPos(), tooltip, view, rect);
++ QToolTip::showText(he->globalPos(), tooltip, view->viewport(), option.rect);
+ event->setAccepted(!tooltip.isEmpty());
+ break;
+ }
+diff --git a/qtbase/src/widgets/itemviews/qlistview.cpp b/qtbase/src/widgets/itemviews/qlistview.cpp
+index 2b34476642..eebfaa030e 100644
+--- a/qtbase/src/widgets/itemviews/qlistview.cpp
++++ b/qtbase/src/widgets/itemviews/qlistview.cpp
+@@ -3386,6 +3386,7 @@ void QIconModeViewBase::updateContentsSize()
+ */
+ void QListView::currentChanged(const QModelIndex ¤t, const QModelIndex &previous)
+ {
++ QAbstractItemView::currentChanged(current, previous);
+ #ifndef QT_NO_ACCESSIBILITY
+ if (QAccessible::isActive()) {
+ if (current.isValid()) {
+@@ -3396,7 +3397,6 @@ void QListView::currentChanged(const QModelIndex ¤t, const QModelIndex &pr
+ }
+ }
+ #endif
+- QAbstractItemView::currentChanged(current, previous);
+ }
+
+ /*!
+diff --git a/qtbase/src/widgets/itemviews/qtableview.cpp b/qtbase/src/widgets/itemviews/qtableview.cpp
+index 934ac581b2..f79bb24249 100644
+--- a/qtbase/src/widgets/itemviews/qtableview.cpp
++++ b/qtbase/src/widgets/itemviews/qtableview.cpp
+@@ -1013,6 +1013,7 @@ void QTableViewPrivate::drawCell(QPainter *painter, const QStyleOptionViewItem &
+ int QTableViewPrivate::widthHintForIndex(const QModelIndex &index, int hint, const QStyleOptionViewItem &option) const
+ {
+ Q_Q(const QTableView);
++ const int oldHint = hint;
+ QWidget *editor = editorForIndex(index).widget.data();
+ if (editor && persistent.contains(editor)) {
+ hint = qMax(hint, editor->sizeHint().width());
+@@ -1021,6 +1022,17 @@ int QTableViewPrivate::widthHintForIndex(const QModelIndex &index, int hint, con
+ hint = qBound(min, hint, max);
+ }
+ hint = qMax(hint, q->itemDelegate(index)->sizeHint(option, index).width());
++
++ if (hasSpans()) {
++ auto span = spans.spanAt(index.column(), index.row());
++ if (span && span->m_left == index.column() && span->m_top == index.row()) {
++ // spans are screwed up when sections are moved
++ const auto left = logicalColumn(span->m_left);
++ for (int i = 1; i <= span->width(); ++i)
++ hint -= q->columnWidth(visualColumn(left + i));
++ }
++ hint = std::max(hint, oldHint);
++ }
+ return hint;
+ }
+
+@@ -1053,6 +1065,11 @@ int QTableViewPrivate::heightHintForIndex(const QModelIndex &index, int hint, QS
+ option.rect.setHeight(height);
+ option.rect.setX(q->columnViewportPosition(index.column()));
+ option.rect.setWidth(q->columnWidth(index.column()));
++ if (hasSpans()) {
++ auto span = spans.spanAt(index.column(), index.row());
++ if (span && span->m_left == index.column() && span->m_top == index.row())
++ option.rect.setWidth(std::max(option.rect.width(), visualSpanRect(*span).width()));
++ }
+ // 1px less space when grid is shown (see drawCell)
+ if (showGrid)
+ option.rect.setWidth(option.rect.width() - 1);
+diff --git a/qtbase/src/widgets/kernel/qaction.h b/qtbase/src/widgets/kernel/qaction.h
+index 258a1ea0a0..737c1e8285 100644
+--- a/qtbase/src/widgets/kernel/qaction.h
++++ b/qtbase/src/widgets/kernel/qaction.h
+@@ -81,7 +81,7 @@ class Q_WIDGETS_EXPORT QAction : public QObject
+ Q_PROPERTY(MenuRole menuRole READ menuRole WRITE setMenuRole NOTIFY changed)
+ Q_PROPERTY(bool iconVisibleInMenu READ isIconVisibleInMenu WRITE setIconVisibleInMenu NOTIFY changed)
+ Q_PROPERTY(bool shortcutVisibleInContextMenu READ isShortcutVisibleInContextMenu WRITE setShortcutVisibleInContextMenu NOTIFY changed)
+- Q_PROPERTY(Priority priority READ priority WRITE setPriority)
++ Q_PROPERTY(Priority priority READ priority WRITE setPriority NOTIFY changed)
+
+ public:
+ // note this is copied into qplatformmenu.h, which must stay in sync
+diff --git a/qtbase/src/widgets/kernel/qwidget.cpp b/qtbase/src/widgets/kernel/qwidget.cpp
+index 9eba1e001e..26f6d27e18 100644
+--- a/qtbase/src/widgets/kernel/qwidget.cpp
++++ b/qtbase/src/widgets/kernel/qwidget.cpp
+@@ -5296,7 +5296,7 @@ void QWidgetPrivate::drawWidget(QPaintDevice *pdev, const QRegion &rgn, const QP
+ QWidgetEffectSourcePrivate *sourced = static_cast<QWidgetEffectSourcePrivate *>
+ (source->d_func());
+ if (!sourced->context) {
+- const QRegion effectRgn(rgn.boundingRect());
++ const QRegion effectRgn((flags & UseEffectRegionBounds) ? rgn.boundingRect() : rgn);
+ QWidgetPaintContext context(pdev, effectRgn, offset, flags, sharedPainter, repaintManager);
+ sourced->context = &context;
+ if (!sharedPainter) {
+@@ -5328,6 +5328,7 @@ void QWidgetPrivate::drawWidget(QPaintDevice *pdev, const QRegion &rgn, const QP
+ }
+ }
+ #endif // QT_CONFIG(graphicseffect)
++ flags = flags & ~UseEffectRegionBounds;
+
+ const bool alsoOnScreen = flags & DrawPaintOnScreen;
+ const bool recursive = flags & DrawRecursive;
+diff --git a/qtbase/src/widgets/kernel/qwidget_p.h b/qtbase/src/widgets/kernel/qwidget_p.h
+index eef6b8fa2c..c432f4b5d5 100644
+--- a/qtbase/src/widgets/kernel/qwidget_p.h
++++ b/qtbase/src/widgets/kernel/qwidget_p.h
+@@ -229,7 +229,8 @@ public:
+ DontSubtractOpaqueChildren = 0x10,
+ DontDrawOpaqueChildren = 0x20,
+ DontDrawNativeChildren = 0x40,
+- DontSetCompositionMode = 0x80
++ DontSetCompositionMode = 0x80,
++ UseEffectRegionBounds = 0x100
+ };
+ Q_DECLARE_FLAGS(DrawWidgetFlags, DrawWidgetFlag)
+ Q_FLAG(DrawWidgetFlags)
+diff --git a/qtbase/src/widgets/kernel/qwidgetrepaintmanager.cpp b/qtbase/src/widgets/kernel/qwidgetrepaintmanager.cpp
+index 02880b34da..0d44e1326d 100644
+--- a/qtbase/src/widgets/kernel/qwidgetrepaintmanager.cpp
++++ b/qtbase/src/widgets/kernel/qwidgetrepaintmanager.cpp
+@@ -1018,7 +1018,8 @@ void QWidgetRepaintManager::paintAndFlush()
+
+ // Paint the rest with composition.
+ if (repaintAllWidgets || !dirtyCopy.isEmpty()) {
+- QWidgetPrivate::DrawWidgetFlags flags = QWidgetPrivate::DrawAsRoot | QWidgetPrivate::DrawRecursive;
++ QWidgetPrivate::DrawWidgetFlags flags = QWidgetPrivate::DrawAsRoot | QWidgetPrivate::DrawRecursive
++ | QWidgetPrivate::UseEffectRegionBounds;
+ tlw->d_func()->drawWidget(store->paintDevice(), dirtyCopy, QPoint(), flags, nullptr, this);
+ }
+
+diff --git a/qtbase/src/widgets/styles/qfusionstyle.cpp b/qtbase/src/widgets/styles/qfusionstyle.cpp
+index f4345d97c4..962912c838 100644
+--- a/qtbase/src/widgets/styles/qfusionstyle.cpp
++++ b/qtbase/src/widgets/styles/qfusionstyle.cpp
+@@ -1772,14 +1772,6 @@ void QFusionStyle::drawControl(ControlElement element, const QStyleOption *optio
+ proxy()->drawControl(CE_PushButtonLabel, &subopt, painter, widget);
+ }
+ break;
+- case CE_PushButtonLabel:
+- if (const QStyleOptionButton *button = qstyleoption_cast<const QStyleOptionButton *>(option)) {
+- QStyleOptionButton b(*button);
+- // no PM_ButtonShiftHorizontal and PM_ButtonShiftVertical for fusion style
+- b.state &= ~(State_On | State_Sunken);
+- QCommonStyle::drawControl(element, &b, painter, widget);
+- }
+- break;
+ case CE_MenuBarEmptyArea:
+ painter->save();
+ {
+diff --git a/qtbase/src/widgets/util/qcompleter.cpp b/qtbase/src/widgets/util/qcompleter.cpp
+index 18b24063d8..ef7207a8a3 100644
+--- a/qtbase/src/widgets/util/qcompleter.cpp
++++ b/qtbase/src/widgets/util/qcompleter.cpp
+@@ -1120,6 +1120,8 @@ void QCompleter::setModel(QAbstractItemModel *model)
+ {
+ Q_D(QCompleter);
+ QAbstractItemModel *oldModel = d->proxy->sourceModel();
++ if (oldModel == model)
++ return;
+ #if QT_CONFIG(filesystemmodel)
+ if (qobject_cast<const QFileSystemModel *>(oldModel))
+ setCompletionRole(Qt::EditRole); // QTBUG-54642, clear FileNameRole set by QFileSystemModel
+diff --git a/qtbase/src/widgets/widgets/qabstractbutton.cpp b/qtbase/src/widgets/widgets/qabstractbutton.cpp
+index a128b23950..dc40bf62fb 100644
+--- a/qtbase/src/widgets/widgets/qabstractbutton.cpp
++++ b/qtbase/src/widgets/widgets/qabstractbutton.cpp
+@@ -56,6 +56,7 @@
+ #ifndef QT_NO_ACCESSIBILITY
+ #include "qaccessible.h"
+ #endif
++#include <qpa/qplatformtheme.h>
+
+ #include <algorithm>
+
+@@ -1076,19 +1077,19 @@ void QAbstractButton::keyPressEvent(QKeyEvent *e)
+ {
+ Q_D(QAbstractButton);
+ bool next = true;
+- switch (e->key()) {
+- case Qt::Key_Enter:
+- case Qt::Key_Return:
+- e->ignore();
+- break;
+- case Qt::Key_Select:
+- case Qt::Key_Space:
+- if (!e->isAutoRepeat()) {
+- setDown(true);
+- repaint();
+- d->emitPressed();
+- }
+- break;
++
++ const auto key = static_cast<Qt::Key>(e->key());
++ const auto buttonPressKeys = QGuiApplicationPrivate::platformTheme()
++ ->themeHint(QPlatformTheme::ButtonPressKeys)
++ .value<QList<Qt::Key>>();
++ if (buttonPressKeys.contains(key) && !e->isAutoRepeat()) {
++ setDown(true);
++ repaint();
++ d->emitPressed();
++ return;
++ }
++
++ switch (key) {
+ case Qt::Key_Up:
+ next = false;
+ Q_FALLTHROUGH();
+@@ -1153,15 +1154,15 @@ void QAbstractButton::keyReleaseEvent(QKeyEvent *e)
+ if (!e->isAutoRepeat())
+ d->repeatTimer.stop();
+
+- switch (e->key()) {
+- case Qt::Key_Select:
+- case Qt::Key_Space:
+- if (!e->isAutoRepeat() && d->down)
+- d->click();
+- break;
+- default:
+- e->ignore();
++ const auto buttonPressKeys = QGuiApplicationPrivate::platformTheme()
++ ->themeHint(QPlatformTheme::ButtonPressKeys)
++ .value<QList<Qt::Key>>();
++ if (buttonPressKeys.contains(static_cast<Qt::Key>(e->key())) && !e->isAutoRepeat() && d->down) {
++ d->click();
++ return;
+ }
++
++ e->ignore();
+ }
+
+ /*!\reimp
+diff --git a/qtbase/src/widgets/widgets/qcombobox.cpp b/qtbase/src/widgets/widgets/qcombobox.cpp
+index 7a496c27e0..0a3d96647b 100644
+--- a/qtbase/src/widgets/widgets/qcombobox.cpp
++++ b/qtbase/src/widgets/widgets/qcombobox.cpp
+@@ -3352,7 +3352,23 @@ void QComboBox::keyPressEvent(QKeyEvent *e)
+
+ Move move = NoMove;
+ int newIndex = currentIndex();
+- switch (e->key()) {
++
++ bool pressLikeButton = !d->lineEdit;
++#ifdef QT_KEYPAD_NAVIGATION
++ pressLikeButton |= QApplicationPrivate::keypadNavigationEnabled() && !hasEditFocus();
++#endif
++ auto key = static_cast<Qt::Key>(e->key());
++ if (pressLikeButton) {
++ const auto buttonPressKeys = QGuiApplicationPrivate::platformTheme()
++ ->themeHint(QPlatformTheme::ButtonPressKeys)
++ .value<QList<Qt::Key>>();
++ if (buttonPressKeys.contains(key)) {
++ showPopup();
++ return;
++ }
++ }
++
++ switch (key) {
+ case Qt::Key_Up:
+ if (e->modifiers() & Qt::ControlModifier)
+ break; // pass to line edit for auto completion
+@@ -3394,26 +3410,11 @@ void QComboBox::keyPressEvent(QKeyEvent *e)
+ return;
+ }
+ break;
+- case Qt::Key_Space:
+- if (!d->lineEdit) {
+- showPopup();
+- return;
+- }
+- break;
+- case Qt::Key_Enter:
+- case Qt::Key_Return:
+ case Qt::Key_Escape:
+ if (!d->lineEdit)
+ e->ignore();
+ break;
+ #ifdef QT_KEYPAD_NAVIGATION
+- case Qt::Key_Select:
+- if (QApplicationPrivate::keypadNavigationEnabled()
+- && (!hasEditFocus() || !d->lineEdit)) {
+- showPopup();
+- return;
+- }
+- break;
+ case Qt::Key_Left:
+ case Qt::Key_Right:
+ if (QApplicationPrivate::keypadNavigationEnabled() && !hasEditFocus())
+diff --git a/qtbase/src/widgets/widgets/qdatetimeedit_p.h b/qtbase/src/widgets/widgets/qdatetimeedit_p.h
+index d36b6f8f9a..e0df5b5158 100644
+--- a/qtbase/src/widgets/widgets/qdatetimeedit_p.h
++++ b/qtbase/src/widgets/widgets/qdatetimeedit_p.h
+@@ -1,6 +1,6 @@
+ /****************************************************************************
+ **
+-** Copyright (C) 2018 The Qt Company Ltd.
++** Copyright (C) 2021 The Qt Company Ltd.
+ ** Contact: https://www.qt.io/licensing/
+ **
+ ** This file is part of the QtWidgets module of the Qt Toolkit.
+diff --git a/qtbase/src/widgets/widgets/qgroupbox.cpp b/qtbase/src/widgets/widgets/qgroupbox.cpp
+index 02a0bed325..3f3eccc370 100644
+--- a/qtbase/src/widgets/widgets/qgroupbox.cpp
++++ b/qtbase/src/widgets/widgets/qgroupbox.cpp
+@@ -54,6 +54,8 @@
+ #include "qaccessible.h"
+ #endif
+ #include <private/qwidget_p.h>
++#include <private/qguiapplication_p.h>
++#include <qpa/qplatformtheme.h>
+
+ #include "qdebug.h"
+
+@@ -360,7 +362,10 @@ bool QGroupBox::event(QEvent *e)
+ return true;
+ case QEvent::KeyPress: {
+ QKeyEvent *k = static_cast<QKeyEvent*>(e);
+- if (!k->isAutoRepeat() && (k->key() == Qt::Key_Select || k->key() == Qt::Key_Space)) {
++ const auto buttonPressKeys = QGuiApplicationPrivate::platformTheme()
++ ->themeHint(QPlatformTheme::ButtonPressKeys)
++ .value<QList<Qt::Key>>();
++ if (!k->isAutoRepeat() && buttonPressKeys.contains(static_cast<Qt::Key>(k->key()))) {
+ d->pressedControl = QStyle::SC_GroupBoxCheckBox;
+ update(style()->subControlRect(QStyle::CC_GroupBox, &box, QStyle::SC_GroupBoxCheckBox, this));
+ return true;
+@@ -369,7 +374,10 @@ bool QGroupBox::event(QEvent *e)
+ }
+ case QEvent::KeyRelease: {
+ QKeyEvent *k = static_cast<QKeyEvent*>(e);
+- if (!k->isAutoRepeat() && (k->key() == Qt::Key_Select || k->key() == Qt::Key_Space)) {
++ const auto buttonPressKeys = QGuiApplicationPrivate::platformTheme()
++ ->themeHint(QPlatformTheme::ButtonPressKeys)
++ .value<QList<Qt::Key>>();
++ if (!k->isAutoRepeat() && buttonPressKeys.contains(static_cast<Qt::Key>(k->key()))) {
+ bool toggle = (d->pressedControl == QStyle::SC_GroupBoxLabel
+ || d->pressedControl == QStyle::SC_GroupBoxCheckBox);
+ d->pressedControl = QStyle::SC_None;
+diff --git a/qtbase/src/widgets/widgets/qlabel.cpp b/qtbase/src/widgets/widgets/qlabel.cpp
+index 30ff80cbb0..cf2605c17c 100644
+--- a/qtbase/src/widgets/widgets/qlabel.cpp
++++ b/qtbase/src/widgets/widgets/qlabel.cpp
+@@ -421,9 +421,6 @@ void QLabel::setPixmap(const QPixmap &pixmap)
+ d->pixmap = new QPixmap(pixmap);
+ }
+
+- if (d->pixmap->depth() == 1 && !d->pixmap->mask())
+- d->pixmap->setMask(*((QBitmap *)d->pixmap));
+-
+ d->updateLabel();
+ }
+
+diff --git a/qtbase/src/widgets/widgets/qtoolbararealayout.cpp b/qtbase/src/widgets/widgets/qtoolbararealayout.cpp
+index 493c094cc1..d5f4b59017 100644
+--- a/qtbase/src/widgets/widgets/qtoolbararealayout.cpp
++++ b/qtbase/src/widgets/widgets/qtoolbararealayout.cpp
+@@ -1367,7 +1367,7 @@ bool QToolBarAreaLayout::restoreState(QDataStream &stream, const QList<QToolBar*
+ item.widgetItem = new QWidgetItemV2(toolBar);
+ toolBar->setOrientation(floating ? ((shown & 2) ? Qt::Vertical : Qt::Horizontal) : dock.o);
+ toolBar->setVisible(shown & 1);
+- toolBar->d_func()->setWindowState(floating, true, rect);
++ toolBar->d_func()->setWindowState(floating, false, rect);
+
+ item.preferredSize = item.size;
+ line.toolBarItems.append(item);
+diff --git a/qtbase/tests/auto/concurrent/qtconcurrentiteratekernel/tst_qtconcurrentiteratekernel.cpp b/qtbase/tests/auto/concurrent/qtconcurrentiteratekernel/tst_qtconcurrentiteratekernel.cpp
+index 212c0a2e13..3c77b1ba0b 100644
+--- a/qtbase/tests/auto/concurrent/qtconcurrentiteratekernel/tst_qtconcurrentiteratekernel.cpp
++++ b/qtbase/tests/auto/concurrent/qtconcurrentiteratekernel/tst_qtconcurrentiteratekernel.cpp
+@@ -126,8 +126,7 @@ public:
+
+ void tst_QtConcurrentIterateKernel::instantiate()
+ {
+- auto future = startThreadEngine(new PrintFor(0, 40)).startAsynchronously();
+- future.waitForFinished();
++ startThreadEngine(new PrintFor(0, 40)).startBlocking();
+ QCOMPARE(iterations.loadRelaxed(), 40);
+ }
+
+@@ -166,10 +165,8 @@ void tst_QtConcurrentIterateKernel::stresstest()
+ const int times = 50;
+ for (int i = 0; i < times; ++i) {
+ counter.storeRelaxed(0);
+- // ThreadEngine will delete f when it finishes
+- auto f = new CountFor(0, iterations);
+- auto future = f->startAsynchronously();
+- future.waitForFinished();
++ CountFor f(0, iterations);
++ f.startBlocking();
+ QCOMPARE(counter.loadRelaxed(), iterations);
+ }
+ }
+@@ -177,11 +174,8 @@ void tst_QtConcurrentIterateKernel::stresstest()
+ void tst_QtConcurrentIterateKernel::noIterations()
+ {
+ const int times = 20000;
+- for (int i = 0; i < times; ++i) {
+- auto future = startThreadEngine(new IterateKernel<TestIterator, void>(0, 0))
+- .startAsynchronously();
+- future.waitForFinished();
+- }
++ for (int i = 0; i < times; ++i)
++ startThreadEngine(new IterateKernel<TestIterator, void>(0, 0)).startBlocking();
+ }
+
+ QMutex threadsMutex;
+@@ -236,10 +230,8 @@ void tst_QtConcurrentIterateKernel::throttling()
+
+ threads.clear();
+
+- // ThreadEngine will delete f when it finishes
+- auto f = new ThrottleFor(0, totalIterations);
+- auto future = f->startAsynchronously();
+- future.waitForFinished();
++ ThrottleFor f(0, totalIterations);
++ f.startBlocking();
+
+ QCOMPARE(iterations.loadRelaxed(), totalIterations);
+
+diff --git a/qtbase/tests/auto/concurrent/qtconcurrentthreadengine/tst_qtconcurrentthreadengine.cpp b/qtbase/tests/auto/concurrent/qtconcurrentthreadengine/tst_qtconcurrentthreadengine.cpp
+index ac7be7acdd..81bc64c8d9 100644
+--- a/qtbase/tests/auto/concurrent/qtconcurrentthreadengine/tst_qtconcurrentthreadengine.cpp
++++ b/qtbase/tests/auto/concurrent/qtconcurrentthreadengine/tst_qtconcurrentthreadengine.cpp
+@@ -65,9 +65,16 @@ public:
+
+ void tst_QtConcurrentThreadEngine::runDirectly()
+ {
+- PrintUser *engine = new PrintUser();
+- QFuture<void> f = engine->startAsynchronously();
+- f.waitForFinished();
++ {
++ PrintUser engine;
++ engine.startSingleThreaded();
++ engine.startBlocking();
++ }
++ {
++ PrintUser *engine = new PrintUser();
++ QFuture<void> f = engine->startAsynchronously();
++ f.waitForFinished();
++ }
+ }
+
+ class StringResultUser : public ThreadEngine<QString>
+@@ -99,10 +106,8 @@ public:
+
+ void tst_QtConcurrentThreadEngine::result()
+ {
+- // ThreadEngine will delete 'engine' when it finishes
+- auto engine = new StringResultUser();
+- auto future = engine->startAsynchronously();
+- QCOMPARE(future.result(), QString("Foo"));
++ StringResultUser engine;
++ QCOMPARE(*engine.startBlocking(), QString("Foo"));
+ }
+
+ class VoidResultUser : public ThreadEngine<void>
+@@ -128,9 +133,17 @@ public:
+
+ void tst_QtConcurrentThreadEngine::runThroughStarter()
+ {
+- ThreadEngineStarter<QString> starter = startThreadEngine(new StringResultUser());
+- QFuture<QString> f = starter.startAsynchronously();
+- QCOMPARE(f.result(), QString("Foo"));
++ {
++ ThreadEngineStarter<QString> starter = startThreadEngine(new StringResultUser());
++ QFuture<QString> f = starter.startAsynchronously();
++ QCOMPARE(f.result(), QString("Foo"));
++ }
++
++ {
++ ThreadEngineStarter<QString> starter = startThreadEngine(new StringResultUser());
++ QString str = starter.startBlocking();
++ QCOMPARE(str, QString("Foo"));
++ }
+ }
+
+ class CancelUser : public ThreadEngine<void>
+@@ -213,6 +226,12 @@ void tst_QtConcurrentThreadEngine::throttle()
+ f.waitForFinished();
+ QCOMPARE(count.loadRelaxed(), 0);
+ }
++
++ for (int i = 0; i < repeats; ++i) {
++ ThrottleAlwaysUser t;
++ t.startBlocking();
++ QCOMPARE(count.loadRelaxed(), 0);
++ }
+ }
+
+ QSet<QThread *> threads;
+@@ -249,17 +268,35 @@ void tst_QtConcurrentThreadEngine::threadCount()
+ {
+ const int repeats = 10;
+ for (int i = 0; i < repeats; ++i) {
++ ThreadCountUser t;
++ t.startBlocking();
++ int count = threads.count();
++ int count_expected = QThreadPool::globalInstance()->maxThreadCount() + 1; // +1 for the main thread.
++ if (count != count_expected)
++ QEXPECT_FAIL("", "QTBUG-23333", Abort);
++ QCOMPARE(count, count_expected);
++
+ (new ThreadCountUser())->startAsynchronously().waitForFinished();
+- const auto count = threads.count();
+- const auto maxThreadCount = QThreadPool::globalInstance()->maxThreadCount();
+- QVERIFY(count <= maxThreadCount);
+- QVERIFY(!threads.contains(QThread::currentThread()));
++ count = threads.count();
++ count_expected = QThreadPool::globalInstance()->maxThreadCount();
++ if (count != count_expected)
++ QEXPECT_FAIL("", "QTBUG-23333", Abort);
++ QCOMPARE(count, count_expected);
+ }
+
+ // Set the finish flag immediately, this should give us one thread only.
+ for (int i = 0; i < repeats; ++i) {
++ ThreadCountUser t(true /*finishImmediately*/);
++ t.startBlocking();
++ int count = threads.count();
++ if (count != 1)
++ QEXPECT_FAIL("", "QTBUG-23333", Abort);
++ QCOMPARE(count, 1);
++
+ (new ThreadCountUser(true /*finishImmediately*/))->startAsynchronously().waitForFinished();
+- const auto count = threads.count();
++ count = threads.count();
++ if (count != 1)
++ QEXPECT_FAIL("", "QTBUG-23333", Abort);
+ QCOMPARE(count, 1);
+ QVERIFY(!threads.contains(QThread::currentThread()));
+ }
+@@ -400,6 +437,7 @@ public:
+
+ void tst_QtConcurrentThreadEngine::exceptions()
+ {
++ // Asynchronous mode:
+ {
+ bool caught = false;
+ try {
+@@ -412,6 +450,32 @@ void tst_QtConcurrentThreadEngine::exceptions()
+ QVERIFY2(caught, "did not get exception");
+ }
+
++ // Blocking mode:
++ // test throwing the exception from a worker thread.
++ {
++ bool caught = false;
++ try {
++ QtConcurrentExceptionThrower e(QThread::currentThread());
++ e.startBlocking();
++ } catch (const QException &) {
++ caught = true;
++ }
++ QVERIFY2(caught, "did not get exception");
++ }
++
++ // test throwing the exception from the main thread (different code path)
++ {
++ bool caught = false;
++ try {
++ QtConcurrentExceptionThrower e(0);
++ e.startBlocking();
++ } catch (const QException &) {
++ caught = true;
++ }
++ QVERIFY2(caught, "did not get exception");
++ }
++
++ // Asynchronous mode:
+ {
+ bool caught = false;
+ try {
+@@ -423,6 +487,31 @@ void tst_QtConcurrentThreadEngine::exceptions()
+ }
+ QVERIFY2(caught, "did not get exception");
+ }
++
++ // Blocking mode:
++ // test throwing the exception from a worker thread.
++ {
++ bool caught = false;
++ try {
++ UnrelatedExceptionThrower e(QThread::currentThread());
++ e.startBlocking();
++ } catch (const QUnhandledException &) {
++ caught = true;
++ }
++ QVERIFY2(caught, "did not get exception");
++ }
++
++ // test throwing the exception from the main thread (different code path)
++ {
++ bool caught = false;
++ try {
++ UnrelatedExceptionThrower e(0);
++ e.startBlocking();
++ } catch (const QUnhandledException &) {
++ caught = true;
++ }
++ QVERIFY2(caught, "did not get exception");
++ }
+ }
+
+ #endif
+diff --git a/qtbase/tests/auto/corelib/io/qbuffer/tst_qbuffer.cpp b/qtbase/tests/auto/corelib/io/qbuffer/tst_qbuffer.cpp
+index 4968742110..f4c3fb711d 100644
+--- a/qtbase/tests/auto/corelib/io/qbuffer/tst_qbuffer.cpp
++++ b/qtbase/tests/auto/corelib/io/qbuffer/tst_qbuffer.cpp
+@@ -42,6 +42,7 @@ private slots:
+ void writeBlock_data();
+ void writeBlock();
+ void seek();
++ void invalidSeeks();
+ void seekTest_data();
+ void seekTest();
+ void read_rawdata();
+@@ -286,6 +287,29 @@ void tst_QBuffer::seek()
+ QCOMPARE(buffer.size(), pos);
+ }
+
++void tst_QBuffer::invalidSeeks()
++{
++ if constexpr (sizeof(qsizetype) == sizeof(qint64)) {
++ // sizeof(qsizetype) == sizeof(qint64), so +1 would overflow
++ QSKIP("This is a 32-bit-only test.");
++ } else {
++ QBuffer buffer;
++ buffer.open(QIODevice::WriteOnly);
++ QCOMPARE(buffer.buffer().size(), qsizetype(0));
++ QCOMPARE(buffer.pos(), qint64(0));
++ constexpr qint64 MaxQByteArrayCapacity = (std::numeric_limits<qsizetype>::max)();
++ // this should fail fast, not after trying to allocate nearly 2 GiB of data,
++ // potentially crashing in the process:
++ QVERIFY(!buffer.seek(2 * MaxQByteArrayCapacity - 1));
++ QCOMPARE(buffer.buffer().size(), qsizetype(0));
++ QCOMPARE(buffer.pos(), qint64(0));
++ // ditto:
++ QVERIFY(!buffer.seek(MaxQByteArrayCapacity + 1));
++ QCOMPARE(buffer.buffer().size(), qsizetype(0));
++ QCOMPARE(buffer.pos(), qint64(0));
++ }
++}
++
+ void tst_QBuffer::seekTest_data()
+ {
+ writeBlock_data();
+diff --git a/qtbase/tests/auto/corelib/io/qiodevice/tst_qiodevice.cpp b/qtbase/tests/auto/corelib/io/qiodevice/tst_qiodevice.cpp
+index da5327594c..4a04e0f7c6 100644
+--- a/qtbase/tests/auto/corelib/io/qiodevice/tst_qiodevice.cpp
++++ b/qtbase/tests/auto/corelib/io/qiodevice/tst_qiodevice.cpp
+@@ -561,7 +561,8 @@ protected:
+ qint64 readData(char *data, qint64 maxSize) override
+ {
+ maxSize = qMin(maxSize, qint64(buf->size() - offset));
+- memcpy(data, buf->constData() + offset, maxSize);
++ if (maxSize > 0)
++ memcpy(data, buf->constData() + offset, maxSize);
+ offset += maxSize;
+ return maxSize;
+ }
+@@ -604,13 +605,15 @@ protected:
+ qint64 readData(char *data, qint64 maxSize) override
+ {
+ maxSize = qMin(maxSize, qint64(buf.size() - pos()));
+- memcpy(data, buf.constData() + pos(), maxSize);
++ if (maxSize > 0)
++ memcpy(data, buf.constData() + pos(), maxSize);
+ return maxSize;
+ }
+ qint64 writeData(const char *data, qint64 maxSize) override
+ {
+ maxSize = qMin(maxSize, qint64(buf.size() - pos()));
+- memcpy(buf.data() + pos(), data, maxSize);
++ if (maxSize > 0)
++ memcpy(buf.data() + pos(), data, maxSize);
+ return maxSize;
+ }
+
+diff --git a/qtbase/tests/auto/corelib/io/qprocess/tst_qprocess.cpp b/qtbase/tests/auto/corelib/io/qprocess/tst_qprocess.cpp
+index db60bead64..f345a44414 100644
+--- a/qtbase/tests/auto/corelib/io/qprocess/tst_qprocess.cpp
++++ b/qtbase/tests/auto/corelib/io/qprocess/tst_qprocess.cpp
+@@ -1,7 +1,8 @@
+ /****************************************************************************
+ **
+ ** Copyright (C) 2021 The Qt Company Ltd.
+-** Copyright (C) 2020 Intel Corporation.
++** Copyright (C) 2020 The Qt Company Ltd.
++** Copyright (C) 2022 Intel Corporation.
+ ** Contact: https://www.qt.io/licensing/
+ **
+ ** This file is part of the test suite of the Qt Toolkit.
+@@ -150,6 +151,8 @@ private slots:
+ void startStopStartStopBuffers();
+ void processEventsInAReadyReadSlot_data();
+ void processEventsInAReadyReadSlot();
++ void startFromCurrentWorkingDir_data();
++ void startFromCurrentWorkingDir();
+
+ // keep these at the end, since they use lots of processes and sometimes
+ // caused obscure failures to occur in tests that followed them (esp. on the Mac)
+@@ -2731,5 +2734,94 @@ void tst_QProcess::finishProcessBeforeReadingDone_deprecated()
+
+ #endif
+
++enum class ChdirMode {
++ None = 0,
++ InParent,
++ InChild
++};
++Q_DECLARE_METATYPE(ChdirMode)
++
++void tst_QProcess::startFromCurrentWorkingDir_data()
++{
++ qRegisterMetaType<ChdirMode>();
++ QTest::addColumn<QString>("programPrefix");
++ QTest::addColumn<ChdirMode>("chdirMode");
++ QTest::addColumn<bool>("success");
++
++ constexpr bool IsWindows = true
++#ifdef Q_OS_UNIX
++ && false
++#endif
++ ;
++
++ // baseline: trying to execute the directory, this can't possibly succeed!
++ QTest::newRow("plain-same-cwd") << QString() << ChdirMode::None << false;
++
++ // cross-platform behavior: neither OS searches the setWorkingDirectory()
++ // dir without "./"
++ QTest::newRow("plain-child-chdir") << QString() << ChdirMode::InChild << false;
++
++ // cross-platform behavior: both OSes search the parent's CWD with "./"
++ QTest::newRow("prefixed-parent-chdir") << "./" << ChdirMode::InParent << true;
++
++ // opposite behaviors: Windows searches the parent's CWD and Unix searches
++ // the child's with "./"
++ QTest::newRow("prefixed-child-chdir") << "./" << ChdirMode::InChild << !IsWindows;
++
++ // Windows searches the parent's CWD without "./"
++ QTest::newRow("plain-parent-chdir") << QString() << ChdirMode::InParent << IsWindows;
++}
++
++void tst_QProcess::startFromCurrentWorkingDir()
++{
++ QFETCH(QString, programPrefix);
++ QFETCH(ChdirMode, chdirMode);
++ QFETCH(bool, success);
++
++ QProcess process;
++ qRegisterMetaType<QProcess::ProcessError>();
++ QSignalSpy errorSpy(&process, &QProcess::errorOccurred);
++ QVERIFY(errorSpy.isValid());
++
++ // both the dir name and the executable name
++ const QString target = QStringLiteral("testProcessNormal");
++ process.setProgram(programPrefix + target);
++
++#ifdef Q_OS_UNIX
++ // Reset PATH, to be sure it doesn't contain . or the empty path.
++ // We can't do this on Windows because DLLs are searched in PATH
++ // and Windows always searches "." anyway.
++ auto restoreEnv = qScopeGuard([old = qgetenv("PATH")] {
++ qputenv("PATH", old);
++ });
++ qputenv("PATH", "/");
++#endif
++
++ switch (chdirMode) {
++ case ChdirMode::InParent: {
++ auto restoreCwd = qScopeGuard([old = QDir::currentPath()] {
++ QDir::setCurrent(old);
++ });
++ QVERIFY(QDir::setCurrent(target));
++ process.start();
++ break;
++ }
++ case ChdirMode::InChild:
++ process.setWorkingDirectory(target);
++ Q_FALLTHROUGH();
++ case ChdirMode::None:
++ process.start();
++ break;
++ }
++
++ QCOMPARE(process.waitForStarted(), success);
++ QCOMPARE(errorSpy.count(), int(!success));
++ if (success) {
++ QVERIFY(process.waitForFinished());
++ } else {
++ QCOMPARE(process.error(), QProcess::FailedToStart);
++ }
++}
++
+ QTEST_MAIN(tst_QProcess)
+ #include "tst_qprocess.moc"
+diff --git a/qtbase/tests/auto/corelib/itemmodels/qconcatenatetablesproxymodel/tst_qconcatenatetablesproxymodel.cpp b/qtbase/tests/auto/corelib/itemmodels/qconcatenatetablesproxymodel/tst_qconcatenatetablesproxymodel.cpp
+index e1ea7a4552..90972caa57 100644
+--- a/qtbase/tests/auto/corelib/itemmodels/qconcatenatetablesproxymodel/tst_qconcatenatetablesproxymodel.cpp
++++ b/qtbase/tests/auto/corelib/itemmodels/qconcatenatetablesproxymodel/tst_qconcatenatetablesproxymodel.cpp
+@@ -117,6 +117,7 @@ private Q_SLOTS:
+ void shouldPropagateDropAfterLastRow_data();
+ void shouldPropagateDropAfterLastRow();
+ void qtbug91788();
++ void qtbug91878();
+
+ private:
+ QStandardItemModel mod;
+@@ -843,6 +844,22 @@ void tst_QConcatenateTablesProxyModel::qtbug91788()
+ QCOMPARE(proxyConcat.columnCount(), 0);
+ }
+
++void tst_QConcatenateTablesProxyModel::qtbug91878()
++{
++ QStandardItemModel m;
++ m.setRowCount(4);
++ m.setColumnCount(4);
++
++ QConcatenateTablesProxyModel pm;
++ QSortFilterProxyModel proxyFilter;
++ proxyFilter.setSourceModel(&pm);
++ proxyFilter.setFilterFixedString("something");
++ pm.addSourceModel(&m); // This should not assert
++
++ QCOMPARE(pm.columnCount(), 4);
++ QCOMPARE(pm.rowCount(), 4);
++}
++
+ QTEST_GUILESS_MAIN(tst_QConcatenateTablesProxyModel)
+
+ #include "tst_qconcatenatetablesproxymodel.moc"
+diff --git a/qtbase/tests/auto/corelib/kernel/qobject/tst_qobject.cpp b/qtbase/tests/auto/corelib/kernel/qobject/tst_qobject.cpp
+index 9bd66c0835..ed4a0bae5d 100644
+--- a/qtbase/tests/auto/corelib/kernel/qobject/tst_qobject.cpp
++++ b/qtbase/tests/auto/corelib/kernel/qobject/tst_qobject.cpp
+@@ -158,6 +158,7 @@ private slots:
+ void nullReceiver();
+ void functorReferencesConnection();
+ void disconnectDisconnects();
++ void declarativeData();
+ };
+
+ struct QObjectCreatedOnShutdown
+@@ -7679,5 +7680,81 @@ void tst_QObject::disconnectDisconnects()
+ Q_STATIC_ASSERT(QtPrivate::HasQ_OBJECT_Macro<tst_QObject>::Value);
+ Q_STATIC_ASSERT(!QtPrivate::HasQ_OBJECT_Macro<SiblingDeleter>::Value);
+
++#ifdef QT_BUILD_INTERNAL
++/*
++ Since QObjectPrivate stores the declarativeData pointer in a union with the pointer
++ to the currently destroyed child, calls to the QtDeclarative handlers need to be
++ correctly guarded. QTBUG-105286
++*/
++namespace QtDeclarative {
++static QAbstractDeclarativeData *theData;
++
++static void destroyed(QAbstractDeclarativeData *data, QObject *)
++{
++ QCOMPARE(data, theData);
++}
++static void signalEmitted(QAbstractDeclarativeData *data, QObject *, int, void **)
++{
++ QCOMPARE(data, theData);
++}
++// we can't use QCOMPARE in the next two functions, as they don't return void
++static int receivers(QAbstractDeclarativeData *data, const QObject *, int)
++{
++ QTest::qCompare(data, theData, "data", "theData", __FILE__, __LINE__);
++ return 0;
++}
++static bool isSignalConnected(QAbstractDeclarativeData *data, const QObject *, int)
++{
++ QTest::qCompare(data, theData, "data", "theData", __FILE__, __LINE__);
++ return true;
++}
++
++class Object : public QObject
++{
++ Q_OBJECT
++public:
++ using QObject::QObject;
++ ~Object()
++ {
++ if (Object *p = static_cast<Object *>(parent()))
++ p->emitSignal();
++ }
++
++ void emitSignal()
++ {
++ emit theSignal();
++ }
++
++signals:
++ void theSignal();
++};
++
++}
++#endif
++
++void tst_QObject::declarativeData()
++{
++#ifdef QT_BUILD_INTERNAL
++ QScopedValueRollback destroyed(QAbstractDeclarativeData::destroyed,
++ QtDeclarative::destroyed);
++ QScopedValueRollback signalEmitted(QAbstractDeclarativeData::signalEmitted,
++ QtDeclarative::signalEmitted);
++ QScopedValueRollback receivers(QAbstractDeclarativeData::receivers,
++ QtDeclarative::receivers);
++ QScopedValueRollback isSignalConnected(QAbstractDeclarativeData::isSignalConnected,
++ QtDeclarative::isSignalConnected);
++
++ QtDeclarative::Object p;
++ QObjectPrivate *priv = QObjectPrivate::get(&p);
++ priv->declarativeData = QtDeclarative::theData = new QAbstractDeclarativeData;
++
++ connect(&p, &QtDeclarative::Object::theSignal, &p, []{
++ });
++
++ QtDeclarative::Object *child = new QtDeclarative::Object;
++ child->setParent(&p);
++#endif
++}
++
+ QTEST_MAIN(tst_QObject)
+ #include "tst_qobject.moc"
+diff --git a/qtbase/tests/auto/corelib/mimetypes/qmimedatabase/tst_qmimedatabase.cpp b/qtbase/tests/auto/corelib/mimetypes/qmimedatabase/tst_qmimedatabase.cpp
+index 0ea422ecbc..1a3256534b 100644
+--- a/qtbase/tests/auto/corelib/mimetypes/qmimedatabase/tst_qmimedatabase.cpp
++++ b/qtbase/tests/auto/corelib/mimetypes/qmimedatabase/tst_qmimedatabase.cpp
+@@ -70,15 +70,15 @@ static inline QString testSuiteWarning()
+
+ QString result;
+ QTextStream str(&result);
+- str << "\nCannot find the shared-mime-info test suite\nstarting from: "
++ str << "\nCannot find the shared-mime-info test suite\nin the parent of: "
+ << QDir::toNativeSeparators(QDir::currentPath()) << "\n"
+ "cd " << QDir::toNativeSeparators(QStringLiteral("tests/auto/corelib/mimetypes/qmimedatabase")) << "\n"
+- "wget http://cgit.freedesktop.org/xdg/shared-mime-info/snapshot/Release-1-10.zip\n"
+- "unzip Release-1-10.zip\n";
++ "wget https://gitlab.freedesktop.org/xdg/shared-mime-info/-/archive/2.1/shared-mime-info-2.1.zip\n"
++ "unzip shared-mime-info-2.1.zip\n";
+ #ifdef Q_OS_WIN
+- str << "mkdir testfiles\nxcopy /s Release-1-10 s-m-i\n";
++ str << "mkdir testfiles\nxcopy /s shared-mime-info-2.1 s-m-i\n";
+ #else
+- str << "ln -s Release-1-10 s-m-i\n";
++ str << "ln -s shared-mime-info-2.1 s-m-i\n";
+ #endif
+ return result;
+ }
+@@ -154,7 +154,7 @@ void tst_QMimeDatabase::initTestCase()
+ QVERIFY2(copyResourceFile(xmlFileName, xmlTargetFileName, &errorMessage), qPrintable(errorMessage));
+ #endif
+
+- m_testSuite = QFINDTESTDATA("s-m-i/tests");
++ m_testSuite = QFINDTESTDATA("s-m-i/tests/mime-detection");
+ if (m_testSuite.isEmpty())
+ qWarning("%s", qPrintable(testSuiteWarning()));
+
+@@ -611,7 +611,7 @@ void tst_QMimeDatabase::allMimeTypes()
+ QVERIFY(!lst.isEmpty());
+
+ // Hardcoding this is the only way to check both providers find the same number of mimetypes.
+- QCOMPARE(lst.count(), 779);
++ QCOMPARE(lst.count(), 811);
+
+ foreach (const QMimeType &mime, lst) {
+ const QString name = mime.name();
+@@ -631,10 +631,9 @@ void tst_QMimeDatabase::suffixes_data()
+
+ QTest::newRow("mimetype with a single pattern") << "application/pdf" << "*.pdf" << "pdf";
+ QTest::newRow("mimetype with multiple patterns") << "application/x-kpresenter" << "*.kpr;*.kpt" << "kpr";
+- QTest::newRow("jpeg") << "image/jpeg" << "*.jpe;*.jpg;*.jpeg" << "jpeg";
+- //if (KMimeType::sharedMimeInfoVersion() > KDE_MAKE_VERSION(0, 60, 0)) {
+- QTest::newRow("mimetype with many patterns") << "application/vnd.wordperfect" << "*.wp;*.wp4;*.wp5;*.wp6;*.wpd;*.wpp" << "wp";
+- //}
++ // The preferred suffix for image/jpeg is *.jpg, as per https://bugs.kde.org/show_bug.cgi?id=176737
++ QTest::newRow("jpeg") << "image/jpeg" << "*.jpe;*.jpg;*.jpeg" << "jpg";
++ QTest::newRow("mimetype with many patterns") << "application/vnd.wordperfect" << "*.wp;*.wp4;*.wp5;*.wp6;*.wpd;*.wpp" << "wp";
+ QTest::newRow("oasis text mimetype") << "application/vnd.oasis.opendocument.text" << "*.odt" << "odt";
+ QTest::newRow("oasis presentation mimetype") << "application/vnd.oasis.opendocument.presentation" << "*.odp" << "odp";
+ QTest::newRow("mimetype with multiple patterns") << "text/plain" << "*.asc;*.txt;*,v" << "txt";
+diff --git a/qtbase/tests/auto/corelib/serialization/json/tst_qtjson.cpp b/qtbase/tests/auto/corelib/serialization/json/tst_qtjson.cpp
+index 3e58dd03cc..c8f82ef5d5 100644
+--- a/qtbase/tests/auto/corelib/serialization/json/tst_qtjson.cpp
++++ b/qtbase/tests/auto/corelib/serialization/json/tst_qtjson.cpp
+@@ -176,6 +176,8 @@ private Q_SLOTS:
+ void fromToVariantConversions_data();
+ void fromToVariantConversions();
+
++ void noLeakOnNameClash();
++
+ private:
+ QString testDataDir;
+ };
+@@ -3685,5 +3687,23 @@ void tst_QtJson::fromToVariantConversions()
+ }
+ }
+
++void tst_QtJson::noLeakOnNameClash()
++{
++ QJsonDocument doc = QJsonDocument::fromJson("{\"\":{\"\":0},\"\":0}");
++ QVERIFY(!doc.isNull());
++ const QJsonObject obj = doc.object();
++
++ // Removed the duplicate key.
++ QCOMPARE(obj.length(), 1);
++
++ // Retained the last of the duplicates.
++ const QJsonValue val = obj.begin().value();
++ QVERIFY(val.isDouble());
++ QCOMPARE(val.toDouble(), 0.0);
++
++ // It should not leak.
++ // In particular it should not forget to deref the container for the inner object.
++}
++
+ QTEST_MAIN(tst_QtJson)
+ #include "tst_qtjson.moc"
+diff --git a/qtbase/tests/auto/corelib/time/qtimezone/tst_qtimezone.cpp b/qtbase/tests/auto/corelib/time/qtimezone/tst_qtimezone.cpp
+index a59b58d57f..241c3e84ac 100644
+--- a/qtbase/tests/auto/corelib/time/qtimezone/tst_qtimezone.cpp
++++ b/qtbase/tests/auto/corelib/time/qtimezone/tst_qtimezone.cpp
+@@ -63,6 +63,7 @@ private slots:
+ void isValidId_data();
+ void isValidId();
+ void malformed();
++ void serialize();
+ // Backend tests
+ void utcTest();
+ void icuTest();
+@@ -947,6 +948,33 @@ void tst_QTimeZone::malformed()
+ barf.offsetFromUtc(now);
+ }
+
++void tst_QTimeZone::serialize()
++{
++ int parts = 0;
++#ifndef QT_NO_DEBUG_STREAM
++ qDebug() << QTimeZone(); // to verify no crash
++ parts++;
++#endif
++#ifndef QT_NO_DATASTREAM
++ QByteArray blob;
++ {
++ QDataStream stream(&blob, QIODevice::WriteOnly);
++ stream << QTimeZone("Europe/Oslo") << QTimeZone(420) << QTimeZone() << qint64(-1);
++ }
++ QDataStream stream(&blob, QIODevice::ReadOnly);
++ QTimeZone invalid, offset, oslo;
++ qint64 minusone;
++ stream >> oslo >> offset >> invalid >> minusone;
++ QCOMPARE(oslo, QTimeZone("Europe/Oslo"));
++ QCOMPARE(offset, QTimeZone(420));
++ QVERIFY(!invalid.isValid());
++ QCOMPARE(minusone, qint64(-1));
++ parts++;
++#endif
++ if (!parts)
++ QSKIP("No serialization enabled");
++}
++
+ void tst_QTimeZone::utcTest()
+ {
+ #ifdef QT_BUILD_INTERNAL
+diff --git a/qtbase/tests/auto/dbus/qdbusinterface/tst_qdbusinterface.cpp b/qtbase/tests/auto/dbus/qdbusinterface/tst_qdbusinterface.cpp
+index 05480c6dd2..70f4c75756 100644
+--- a/qtbase/tests/auto/dbus/qdbusinterface/tst_qdbusinterface.cpp
++++ b/qtbase/tests/auto/dbus/qdbusinterface/tst_qdbusinterface.cpp
+@@ -324,6 +324,13 @@ void tst_QDBusInterface::notValid()
+
+ QVERIFY(!interface.isValid());
+ QVERIFY(!QMetaObject::invokeMethod(&interface, "ListNames", Qt::DirectConnection));
++
++ // With a connection, but empty/null service and path specified
++ QDBusConnection con = QDBusConnection::sessionBus();
++ QVERIFY(con.isConnected());
++ QDBusInterface iface({}, {}, {}, con);
++ QVERIFY(!iface.isValid());
++ QVERIFY(!QMetaObject::invokeMethod(&interface, "ListNames", Qt::DirectConnection));
+ }
+
+ void tst_QDBusInterface::notValidDerived()
+diff --git a/qtbase/tests/auto/gui/kernel/qkeysequence/tst_qkeysequence.cpp b/qtbase/tests/auto/gui/kernel/qkeysequence/tst_qkeysequence.cpp
+index 874468c954..04ceb4ab65 100644
+--- a/qtbase/tests/auto/gui/kernel/qkeysequence/tst_qkeysequence.cpp
++++ b/qtbase/tests/auto/gui/kernel/qkeysequence/tst_qkeysequence.cpp
+@@ -507,6 +507,10 @@ void tst_QKeySequence::toStringFromKeycode_data()
+ QTest::newRow("Ctrl+Alt+Num+Del") << QKeySequence(Qt::ControlModifier | Qt::AltModifier | Qt::KeypadModifier | Qt::Key_Delete) << "Ctrl+Alt+Num+Del";
+ QTest::newRow("Ctrl+Ins") << QKeySequence(Qt::ControlModifier | Qt::Key_Insert) << "Ctrl+Ins";
+ QTest::newRow("Ctrl+Num+Ins(1)") << QKeySequence(Qt::Key_Insert | Qt::KeypadModifier | Qt::ControlModifier) << "Ctrl+Num+Ins";
++ QTest::newRow("Ctrl") << QKeySequence(Qt::Key_Control) << "Control";
++ QTest::newRow("Alt") << QKeySequence(Qt::Key_Alt) << "Alt";
++ QTest::newRow("Shift") << QKeySequence(Qt::Key_Shift) << "Shift";
++ QTest::newRow("Meta") << QKeySequence(Qt::Key_Meta) << "Meta";
+ }
+
+ void tst_QKeySequence::toStringFromKeycode()
+diff --git a/qtbase/tests/auto/gui/text/qfontdatabase/tst_qfontdatabase.cpp b/qtbase/tests/auto/gui/text/qfontdatabase/tst_qfontdatabase.cpp
+index 15e0ecadaa..b4eca74283 100644
+--- a/qtbase/tests/auto/gui/text/qfontdatabase/tst_qfontdatabase.cpp
++++ b/qtbase/tests/auto/gui/text/qfontdatabase/tst_qfontdatabase.cpp
+@@ -81,6 +81,8 @@ private slots:
+ void registerOpenTypePreferredNamesSystem();
+ void registerOpenTypePreferredNamesApplication();
+
++ void stretchRespected();
++
+ private:
+ QString m_ledFont;
+ QString m_testFont;
+@@ -355,6 +357,28 @@ static QString testString()
+ return QStringLiteral("foo bar");
+ }
+
++void tst_QFontDatabase::stretchRespected()
++{
++ int italicId = QFontDatabase::addApplicationFont(m_testFontItalic);
++ QVERIFY(italicId != -1);
++
++ QVERIFY(!QFontDatabase::applicationFontFamilies(italicId).isEmpty());
++
++ QString italicFontName = QFontDatabase::applicationFontFamilies(italicId).first();
++
++ QFont italicFont = QFontDatabase().font(italicFontName,
++ QString::fromLatin1("Italic"), 14);
++ QVERIFY(italicFont.italic());
++
++ QFont italicStretchedFont = italicFont;
++ italicStretchedFont.setStretch( 400 );
++
++ QVERIFY(QFontMetricsF(italicFont).horizontalAdvance(QStringLiteral("foobar")) <
++ QFontMetricsF(italicStretchedFont).horizontalAdvance(QStringLiteral("foobar")));
++
++ QFontDatabase::removeApplicationFont(italicId);
++}
++
+ void tst_QFontDatabase::condensedFontWidthNoFontMerging()
+ {
+ int regularFontId = QFontDatabase::addApplicationFont(m_testFont);
+diff --git a/qtbase/tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp b/qtbase/tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp
+index 3d4a094c43..b423e11a99 100644
+--- a/qtbase/tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp
++++ b/qtbase/tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp
+@@ -281,6 +281,7 @@ private Q_SLOTS:
+ void ioGetFromFileSpecial();
+ void ioGetFromFile_data();
+ void ioGetFromFile();
++ void ioGetFromFileUrl();
+ void ioGetFromFtp_data();
+ void ioGetFromFtp();
+ void ioGetFromFtpWithReuse();
+@@ -3300,6 +3301,18 @@ void tst_QNetworkReply::ioGetFromFile()
+ QCOMPARE(reader.data, data);
+ }
+
++void tst_QNetworkReply::ioGetFromFileUrl()
++{
++ // This immediately fails on non-windows platforms:
++ QNetworkRequest request(QUrl("file://unc-server/some/path"));
++ QNetworkReplyPtr reply(manager.get(request));
++ QSignalSpy finishedSpy(reply.get(), &QNetworkReply::finished);
++ // QTBUG-105618: This would, on non-Windows platforms, never happen because the signal
++ // was emitted before the constructor finished, leaving no chance at all to connect to the
++ // signal
++ QVERIFY(finishedSpy.wait());
++}
++
+ void tst_QNetworkReply::ioGetFromFtp_data()
+ {
+ QTest::addColumn<QString>("fileName");
+diff --git a/qtbase/tests/auto/network/ssl/qsslsocket/certs/fluke.cert b/qtbase/tests/auto/network/ssl/qsslsocket/certs/fluke.cert
+index 069fa6b341..4cc4d9a5ea 100644
+--- a/qtbase/tests/auto/network/ssl/qsslsocket/certs/fluke.cert
++++ b/qtbase/tests/auto/network/ssl/qsslsocket/certs/fluke.cert
+@@ -1,75 +1,34 @@
+-Certificate:
+- Data:
+- Version: 3 (0x2)
+- Serial Number: 0 (0x0)
+- Signature Algorithm: sha1WithRSAEncryption
+- Issuer: C=NO, ST=Oslo, L=Nydalen, O=Nokia Corporation and/or its subsidiary(-ies), OU=Development, CN=fluke.troll.no/emailAddress=ahanssen@trolltech.com
+- Validity
+- Not Before: Dec 4 01:10:32 2007 GMT
+- Not After : Apr 21 01:10:32 2035 GMT
+- Subject: C=NO, ST=Oslo, O=Nokia Corporation and/or its subsidiary(-ies), OU=Development, CN=fluke.troll.no
+- Subject Public Key Info:
+- Public Key Algorithm: rsaEncryption
+- RSA Public Key: (1024 bit)
+- Modulus (1024 bit):
+- 00:a7:c8:a0:4a:c4:19:05:1b:66:ba:32:e2:d2:f1:
+- 1c:6f:17:82:e4:39:2e:01:51:90:db:04:34:32:11:
+- 21:c2:0d:6f:59:d8:53:90:54:3f:83:8f:a9:d3:b3:
+- d5:ee:1a:9b:80:ae:c3:25:c9:5e:a5:af:4b:60:05:
+- aa:a0:d1:91:01:1f:ca:04:83:e3:58:1c:99:32:45:
+- 84:70:72:58:03:98:4a:63:8b:41:f5:08:49:d2:91:
+- 02:60:6b:e4:64:fe:dd:a0:aa:74:08:e9:34:4c:91:
+- 5f:12:3d:37:4d:54:2c:ad:7f:5b:98:60:36:02:8c:
+- 3b:f6:45:f3:27:6a:9b:94:9d
+- Exponent: 65537 (0x10001)
+- X509v3 extensions:
+- X509v3 Basic Constraints:
+- CA:FALSE
+- Netscape Comment:
+- OpenSSL Generated Certificate
+- X509v3 Subject Key Identifier:
+- 21:85:04:3D:23:01:66:E5:F7:9F:1A:84:24:8A:AF:0A:79:F4:E5:AC
+- X509v3 Authority Key Identifier:
+- DirName:/C=NO/ST=Oslo/L=Nydalen/O=Nokia Corporation and/or its subsidiary(-ies)/OU=Development/CN=fluke.troll.no/emailAddress=ahanssen@trolltech.com
+- serial:8E:A8:B4:E8:91:B7:54:2E
+-
+- Signature Algorithm: sha1WithRSAEncryption
+- 6d:57:5f:d1:05:43:f0:62:05:ec:2a:71:a5:dc:19:08:f2:c4:
+- a6:bd:bb:25:d9:ca:89:01:0e:e4:cf:1f:c1:8c:c8:24:18:35:
+- 53:59:7b:c0:43:b4:32:e6:98:b2:a6:ef:15:05:0b:48:5f:e1:
+- a0:0c:97:a9:a1:77:d8:35:18:30:bc:a9:8f:d3:b7:54:c7:f1:
+- a9:9e:5d:e6:19:bf:f6:3c:5b:2b:d8:e4:3e:62:18:88:8b:d3:
+- 24:e1:40:9b:0c:e6:29:16:62:ab:ea:05:24:70:36:aa:55:93:
+- ef:02:81:1b:23:10:a2:04:eb:56:95:75:fc:f8:94:b1:5d:42:
+- c5:3f:36:44:85:5d:3a:2e:90:46:8a:a2:b9:6f:87:ae:0c:15:
+- 40:19:31:90:fc:3b:25:bb:ae:f1:66:13:0d:85:90:d9:49:34:
+- 8f:f2:5d:f9:7a:db:4d:5d:27:f6:76:9d:35:8c:06:a6:4c:a3:
+- b1:b2:b6:6f:1d:d7:a3:00:fd:72:eb:9e:ea:44:a1:af:21:34:
+- 7d:c7:42:e2:49:91:19:8b:c0:ad:ba:82:80:a8:71:70:f4:35:
+- 31:91:63:84:20:95:e9:60:af:64:8b:cc:ff:3d:8a:76:74:3d:
+- c8:55:6d:e4:8e:c3:2b:1c:e8:42:18:ae:9f:e6:6b:9c:34:06:
+- ec:6a:f2:c3
+ -----BEGIN CERTIFICATE-----
+-MIIEEzCCAvugAwIBAgIBADANBgkqhkiG9w0BAQUFADCBnDELMAkGA1UEBhMCTk8x
+-DTALBgNVBAgTBE9zbG8xEDAOBgNVBAcTB055ZGFsZW4xFjAUBgNVBAoTDVRyb2xs
+-dGVjaCBBU0ExFDASBgNVBAsTC0RldmVsb3BtZW50MRcwFQYDVQQDEw5mbHVrZS50
+-cm9sbC5ubzElMCMGCSqGSIb3DQEJARYWYWhhbnNzZW5AdHJvbGx0ZWNoLmNvbTAe
+-Fw0wNzEyMDQwMTEwMzJaFw0zNTA0MjEwMTEwMzJaMGMxCzAJBgNVBAYTAk5PMQ0w
+-CwYDVQQIEwRPc2xvMRYwFAYDVQQKEw1Ucm9sbHRlY2ggQVNBMRQwEgYDVQQLEwtE
+-ZXZlbG9wbWVudDEXMBUGA1UEAxMOZmx1a2UudHJvbGwubm8wgZ8wDQYJKoZIhvcN
+-AQEBBQADgY0AMIGJAoGBAKfIoErEGQUbZroy4tLxHG8XguQ5LgFRkNsENDIRIcIN
+-b1nYU5BUP4OPqdOz1e4am4CuwyXJXqWvS2AFqqDRkQEfygSD41gcmTJFhHByWAOY
+-SmOLQfUISdKRAmBr5GT+3aCqdAjpNEyRXxI9N01ULK1/W5hgNgKMO/ZF8ydqm5Sd
+-AgMBAAGjggEaMIIBFjAJBgNVHRMEAjAAMCwGCWCGSAGG+EIBDQQfFh1PcGVuU1NM
+-IEdlbmVyYXRlZCBDZXJ0aWZpY2F0ZTAdBgNVHQ4EFgQUIYUEPSMBZuX3nxqEJIqv
+-Cnn05awwgbsGA1UdIwSBszCBsKGBoqSBnzCBnDELMAkGA1UEBhMCTk8xDTALBgNV
+-BAgTBE9zbG8xEDAOBgNVBAcTB055ZGFsZW4xFjAUBgNVBAoTDVRyb2xsdGVjaCBB
+-U0ExFDASBgNVBAsTC0RldmVsb3BtZW50MRcwFQYDVQQDEw5mbHVrZS50cm9sbC5u
+-bzElMCMGCSqGSIb3DQEJARYWYWhhbnNzZW5AdHJvbGx0ZWNoLmNvbYIJAI6otOiR
+-t1QuMA0GCSqGSIb3DQEBBQUAA4IBAQBtV1/RBUPwYgXsKnGl3BkI8sSmvbsl2cqJ
+-AQ7kzx/BjMgkGDVTWXvAQ7Qy5piypu8VBQtIX+GgDJepoXfYNRgwvKmP07dUx/Gp
+-nl3mGb/2PFsr2OQ+YhiIi9Mk4UCbDOYpFmKr6gUkcDaqVZPvAoEbIxCiBOtWlXX8
+-+JSxXULFPzZEhV06LpBGiqK5b4euDBVAGTGQ/Dslu67xZhMNhZDZSTSP8l35ettN
+-XSf2dp01jAamTKOxsrZvHdejAP1y657qRKGvITR9x0LiSZEZi8CtuoKAqHFw9DUx
+-kWOEIJXpYK9ki8z/PYp2dD3IVW3kjsMrHOhCGK6f5mucNAbsavLD
++MIIF6zCCA9OgAwIBAgIUfo9amJtJGWqWE6f+SkAO85zkGr4wDQYJKoZIhvcNAQEL
++BQAwgYMxCzAJBgNVBAYTAk5PMQ0wCwYDVQQIDARPc2xvMQ0wCwYDVQQHDARPc2xv
++MRcwFQYDVQQKDA5UaGUgUXQgQ29tcGFueTEMMAoGA1UECwwDUiZEMRIwEAYDVQQD
++DAlIMiBUZXN0ZXIxGzAZBgkqhkiG9w0BCQEWDG1pbmltaUBxdC5pbzAgFw0yMDEw
++MjYxMjAxMzFaGA8yMTIwMTAwMjEyMDEzMVowgYMxCzAJBgNVBAYTAk5PMQ0wCwYD
++VQQIDARPc2xvMQ0wCwYDVQQHDARPc2xvMRcwFQYDVQQKDA5UaGUgUXQgQ29tcGFu
++eTEMMAoGA1UECwwDUiZEMRIwEAYDVQQDDAlIMiBUZXN0ZXIxGzAZBgkqhkiG9w0B
++CQEWDG1pbmltaUBxdC5pbzCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIB
++AOiUp5+E4blouKH7q+rVNR8NoYX2XkBW+q+rpy1zu5ssRSzbqxAjDx9dkht7Qlnf
++VlDT00JvpOWdeuPon5915edQRsY4Unl6mKH29ra3OtUa1/yCJXsGVJTKCj7k4Bxb
++5mZzb/fTlZntMLdTIBMfUbw62FKir1WjKIcJ9fCoG8JaGeKVO4Rh5p0ezd4UUUId
++r1BXl5Nqdqy2vTMsEDnjOsD3egkv8I2SKN4O6n/C3wWYpMOWYZkGoZiKz7rJs/i/
++ez7bsV7JlwdzTlhpJzkcOSVFBP6JlEOxTNNxZ1wtKy7PtZGmsSSATq2e6+bw38Ae
++Op0XnzzqcGjtDDofBmT7OFzZWjS9VZS6+DOOe2QHWle1nCHcHyH4ku6IRlsr9xkR
++NAIlOfnvHHxqJUenoeaZ4oQDjCBKS1KXygJO/tL7BLTQVn/xK1EmPvKNnjzWk4tR
++PnibUhhs5635qpOU/YPqFBh1JjVruZbsWcDAhRcew0uxONXOa9E+4lttQ9ySYa1A
++LvWqJuAX7gu2BsBMLyqfm811YnA7CIFMyO+HlqmkLFfv5L/xIRAXR7l26YGO0VwX
++CGjMfz4NVPMMke4nB7qa9NkpXQBQKMms3Qzd5JW0Hy9Ruj5O8GPcFZmV0twjd1uJ
++PD/cAjkWLaXjdNsJ16QWc2nghQRS6HYqKRX6j+CXOxupAgMBAAGjUzBRMB0GA1Ud
++DgQWBBRSCOU58j9NJZkMamt623qyCrhN3TAfBgNVHSMEGDAWgBRSCOU58j9NJZkM
++amt623qyCrhN3TAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEBCwUAA4ICAQCq
++q4jxsWeNDv5Nq14hJtF9HB+ZL64zcZtRjJP1YgNs0QppKICmjPOL2nIMGmI/jKrs
++0eGAL/9XXNVHPxm1OPOncvimMMmU6emZfpMdEtTfKP43+Pg9HgKRjLoQp406vGeQ
++8ki/mbBhrItVPgEm3tu2AFA02XTYi+YxCI9kRZLGkM3FbgtOuTLPl0Z9y+kiPc9F
++uCSC03anBEqv+vDSI8+wODymQ/IJ3Jyz1lxIRDfp4qAekmy0jU2c91VOHHEmOmqq
++kqygGFRdwbe99m9yP63r6q0b5K3X2UnJ6bns0hmTwThYwpVPXLU8jdaTddbMukN2
++/Ef96Tsw8nWOEOPMySHOTIPgwyZRp26b0kA9EmhLwOP401SxXVQCmSRmtwNagmtg
++jJKmZoYBN+//D45ibK8z6Q0oOm9P+Whf/uUXehcRxBxyV3xz7k0wKGQbHj/ddwcy
++IUoIN4lrAlib+lK170kTKN352PDmrpo2gmIzPEsfurKAIMSelDl6H+kih16BtZ8y
++Nz6fh9Soqrg3OSAware8pxV7k51crBMoPLN78KoRV8MFCK4K7Fddq4rRISq6hiXq
++r1nsjoEPuKM9huprmZVZe9t5YcDa2I+wb3IiE3uwpZbAdaLDyQ5n6F/qpsiIkZXn
++gtcF7oqpG5oYrwCcZ53y/ezUgUg7PlSz2XwAGvQtgg==
+ -----END CERTIFICATE-----
+diff --git a/qtbase/tests/auto/network/ssl/qsslsocket/certs/fluke.key b/qtbase/tests/auto/network/ssl/qsslsocket/certs/fluke.key
+index 9d1664d609..337ce541a6 100644
+--- a/qtbase/tests/auto/network/ssl/qsslsocket/certs/fluke.key
++++ b/qtbase/tests/auto/network/ssl/qsslsocket/certs/fluke.key
+@@ -1,15 +1,52 @@
+------BEGIN RSA PRIVATE KEY-----
+-MIICXAIBAAKBgQCnyKBKxBkFG2a6MuLS8RxvF4LkOS4BUZDbBDQyESHCDW9Z2FOQ
+-VD+Dj6nTs9XuGpuArsMlyV6lr0tgBaqg0ZEBH8oEg+NYHJkyRYRwclgDmEpji0H1
+-CEnSkQJga+Rk/t2gqnQI6TRMkV8SPTdNVCytf1uYYDYCjDv2RfMnapuUnQIDAQAB
+-AoGANFzLkanTeSGNFM0uttBipFT9F4a00dqHz6JnO7zXAT26I5r8sU1pqQBb6uLz
+-/+Qz5Zwk8RUAQcsMRgJetuPQUb0JZjF6Duv24hNazqXBCu7AZzUenjafwmKC/8ri
+-KpX3fTwqzfzi//FKGgbXQ80yykSSliDL3kn/drATxsLCgQECQQDXhEFWLJ0vVZ1s
+-1Ekf+3NITE+DR16X+LQ4W6vyEHAjTbaNWtcTKdAWLA2l6N4WAAPYSi6awm+zMxx4
+-VomVTsjdAkEAx0z+e7natLeFcrrq8pbU+wa6SAP1VfhQWKitxL1e7u/QO90NCpxE
+-oQYKzMkmmpOOFjQwEMAy1dvFMbm4LHlewQJAC/ksDBaUcQHHqjktCtrUb8rVjAyW
+-A8lscckeB2fEYyG5J6dJVaY4ClNOOs5yMDS2Afk1F6H/xKvtQ/5CzInA/QJATDub
+-K+BPU8jO9q+gpuIi3VIZdupssVGmCgObVCHLakG4uO04y9IyPhV9lA9tALtoIf4c
+-VIvv5fWGXBrZ48kZAQJBAJmVCdzQxd9LZI5vxijUCj5EI4e+x5DRqVUvyP8KCZrC
+-AiNyoDP85T+hBZaSXK3aYGpVwelyj3bvo1GrTNwNWLw=
+------END RSA PRIVATE KEY-----
++-----BEGIN PRIVATE KEY-----
++MIIJQgIBADANBgkqhkiG9w0BAQEFAASCCSwwggkoAgEAAoICAQDolKefhOG5aLih
+++6vq1TUfDaGF9l5AVvqvq6ctc7ubLEUs26sQIw8fXZIbe0JZ31ZQ09NCb6TlnXrj
++6J+fdeXnUEbGOFJ5epih9va2tzrVGtf8giV7BlSUygo+5OAcW+Zmc2/305WZ7TC3
++UyATH1G8OthSoq9VoyiHCfXwqBvCWhnilTuEYeadHs3eFFFCHa9QV5eTanastr0z
++LBA54zrA93oJL/CNkijeDup/wt8FmKTDlmGZBqGYis+6ybP4v3s+27FeyZcHc05Y
++aSc5HDklRQT+iZRDsUzTcWdcLSsuz7WRprEkgE6tnuvm8N/AHjqdF5886nBo7Qw6
++HwZk+zhc2Vo0vVWUuvgzjntkB1pXtZwh3B8h+JLuiEZbK/cZETQCJTn57xx8aiVH
++p6HmmeKEA4wgSktSl8oCTv7S+wS00FZ/8StRJj7yjZ481pOLUT54m1IYbOet+aqT
++lP2D6hQYdSY1a7mW7FnAwIUXHsNLsTjVzmvRPuJbbUPckmGtQC71qibgF+4LtgbA
++TC8qn5vNdWJwOwiBTMjvh5appCxX7+S/8SEQF0e5dumBjtFcFwhozH8+DVTzDJHu
++Jwe6mvTZKV0AUCjJrN0M3eSVtB8vUbo+TvBj3BWZldLcI3dbiTw/3AI5Fi2l43Tb
++CdekFnNp4IUEUuh2KikV+o/glzsbqQIDAQABAoICAFw1q6tr5I48vY7DF+rXsuLn
++5ZUWE1IQ6fzB4lr72nJv/9EEGnMgYzt9PpMUsD6vdCpBgS2C0+6RHArFzJtNA+RM
++iHLIG7K7702veyr/xBx/MwiSlMeMv/XpkFxVI6E6skMGG2s3AMXxKvJTy5CpRx+I
++eQFyLG+Ya1X2lgJes/q+/CpAHkOjCOpcLySQC5NZ74q734V7nSdmn+Zs3tYEh+O/
++eiuwTP/j5b38Te5vVTqDxTciJPmljmXLCwa0N100lWlbcpvw8qbqiTI2Jm3XCbUE
++AzHjW9vmrF3cRS1fXxKFGShw3SRqlkbxjfeWoi8qDPUBS4m8LOr8qG9Wo5Nfon0z
++zLP4bci3zHDvVcaaZrrsUBs/yZbg+Dgka1DmX7ekmeccr2yTdKDFgPupYUyxVbTl
++a9ZLJysjFD7rgBv1ZclHonLp6Vbm+ZoTqvteo4ikAy6L9RtBWJ23XEK34PkP/+c5
++2vWZaOrnjSeBHbFce8cdJSxqWpP+eSCI5I9XbDrYFIsQ/gqKgtzDKy2ihJ2Y8STL
++yO4hyFPFjxc+Gg4/P2PpmT5CY2ty44M0BWs+JGW96CJPrrplf2lmQUQJj5LZY66X
++Z/4C9L7ZYtKZ+bs5SvU46yWugAvQZX22Xm9xLXWyVXRdx3bj+3M3fDnF9di/zdbh
++CgLx7oWPNrXc7FCajnn9AoIBAQD5FMYwRpw9NWT9WDxQwx+cSI4Icbd88ByTW63S
++LzeRwZA0J9/SfwO+aBRupzc9GkGXCiZcGMw3AGsCtig8yFlw8E5KnzN7KlftDMnM
++9NUxxzlR8VwKyLnZfG7sDTl057ZlUujnqhmt/F8F7dIy7FVO1dE/8nngA+FYTCOG
++UZdGjwyBDlDM0JJdUWGY3xslutcpCDN5mzSTKjy9drMvImAshRawxRF6WBpn7vr2
++nC6vciqfx1Mzx1vyk0Jm0ilaydDdLMADjt/iL4Nkr0BEs4k+UzQiKDwp8gu7abQ1
++eBfxd9Iar4htQa2I1Ewl6P01G/q+ZYwgHhJ9RVn4AxQXefILAoIBAQDvCouORdQX
++C8wsyp7MwXlF/3NQeNN5/+B2mhbxrBOf7PmMCXLnkRWcjwJtzypWFqJ0sqai/2+0
++bqbMcjX5maT8stT2shl3zXe/Ejt2e3TBYpc1tyuses8Kb5BMU8hu6tTd3G2CMXpD
++dT6DVemJZCTtwj9aBNIxSizvlgMolJnCpzhPnlfHSI6E+g3m/LTTo3HwbjMSw/Uq
++irgjOpI2wSBB6LZPSgjvfcYPRyWUk16L4A5uSX0cADnovDFLa5/h0wJvN/OoCSQg
++rLCXG5E18EyL5Wc58BCY1ZvxmjG3lQtgPxYu2Jwc36R/y/JKlxW5suER5ZNpbbD4
++uOyTt2VxMQ2bAoIBAQC5+MzRFqdo/AjfL5Y5JrbfVTzXCTDa09xCGd16ZU60QTWN
+++4ed/r+o1sUKqUcRFB2MzEM/2DQBjQpZB/CbEWvWa1XJWXxypXbowveZU+QqOnmN
++uQvj8WLyA3o+PNF9e9QvauwCrHpn8VpxbtPWuaYoKnUFreFZZQxHhPGxRBIS2JOZ
++eDrT8ZaWnkCkh1AZp5smQ71LOprSlmKrg4jd1GjCVMxQR5N5KXbtyv0OTCZ/UFqK
++2aRBsMPyJgkaBChkZPLRcKwc+/wlQRx1fHQb14DNTApMxoXFO7eOwqmOkpAt9iyl
++SBIwoS0UUI5ab88+bBmXNvKcuFdNuQ4nowTJUn9pAoIBADMNkILBXSvS5DeIyuO2
++Sp1tkoZUV+5NfPY3sMDK3KIibaW/+t+EOBZo4L7tKQCb8vRzl21mmsfxfgRaPDbj
++3r3tv9g0b4YLxxBy52pFscj/soXRai17SS7UZwA2QK+XzgDYbDcLNC6mIsTQG4Gx
++dsWk3/zs3KuUSQaehmwrWK+fIUK38c1pLK8v7LoxrLkqxlHwZ04RthHw8KTthH7X
++Pnl1J0LF8CSeOyfWLSuPUfkT0GEzptnNHpEbaHfQM6R6eaGhVJPF6AZme4y6YYgg
++m2ihhSt1n0XVEWpHYWjxFy3mK2mz75unFC4LM+NEY2p2zuUQoCw7NjnY3QYrfCnx
++rRMCggEAXeXsMSLFjjyuoL7iKbAxo52HD/P0fBoy58LyRcwfNVr0lvYan4pYEx+o
++KijIh9K16PqXZXKMA9v003B+ulmF8bJ7SddCZ5NGvnFhUTDe4DdTKgp2RuwQ3Bsc
++3skPIDbhVETyOLCtys34USHrq8U/0DlGY3eLRfxw9GnbKxSBGa/KEu/qQLPNUo50
++7xHZDg7GKeC3kqNJeqKM9rkp0VzIGkEnaD9127LeNDmERDfftxJzFoC/THvUBLfU
++6Sus2ZYwRE8VFvKC30Q45t/c54X3IuhYvAuiCuTmyfE4ruyzyOwKzhUkeeLq1APX
++g0veFbyfzlJ0q8qzD/iffqqIa2ZSmQ==
++-----END PRIVATE KEY-----
+diff --git a/qtbase/tests/auto/other/qaccessibilitylinux/tst_qaccessibilitylinux.cpp b/qtbase/tests/auto/other/qaccessibilitylinux/tst_qaccessibilitylinux.cpp
+index 7ba3715e13..752aa122f6 100644
+--- a/qtbase/tests/auto/other/qaccessibilitylinux/tst_qaccessibilitylinux.cpp
++++ b/qtbase/tests/auto/other/qaccessibilitylinux/tst_qaccessibilitylinux.cpp
+@@ -179,6 +179,7 @@ void tst_QAccessibilityLinux::initTestCase()
+ QVERIFY(!address.isEmpty());
+
+ m_window = new AccessibleTestWindow();
++ m_window->setObjectName("mainWindow"_L1);
+ m_window->show();
+
+ QVERIFY(QTest::qWaitForWindowExposed(m_window));
+@@ -236,8 +237,11 @@ bool hasState(QDBusInterface *interface, AtspiStateType state)
+ void tst_QAccessibilityLinux::testLabel()
+ {
+ QLabel *l = new QLabel(m_window);
++ l->setObjectName("theObjectName"_L1);
+ l->setText("Hello A11y");
+ m_window->addWidget(l);
++ auto a11yEmpty = new QLabel(m_window);
++ m_window->addWidget(l);
+
+ // Application
+ QCOMPARE(getParent(mainWindow), QLatin1String(ATSPI_DBUS_PATH_ROOT));
+@@ -249,6 +253,8 @@ void tst_QAccessibilityLinux::testLabel()
+ QCOMPARE(getChildren(labelInterface).count(), 0);
+ QCOMPARE(labelInterface->call(QDBus::Block, "GetRoleName").arguments().first().toString(), QLatin1String("label"));
+ QCOMPARE(labelInterface->call(QDBus::Block, "GetRole").arguments().first().toUInt(), 29u);
++ QCOMPARE(labelInterface->call(QDBus::Block, "GetAccessibleId").arguments().first().toString(),
++ QLatin1String("mainWindow.theObjectName"));
+ QCOMPARE(getParent(labelInterface), mainWindow->path());
+ QVERIFY(!hasState(labelInterface, ATSPI_STATE_EDITABLE));
+ QVERIFY(hasState(labelInterface, ATSPI_STATE_READ_ONLY));
+@@ -256,7 +262,12 @@ void tst_QAccessibilityLinux::testLabel()
+ l->setText("New text");
+ QCOMPARE(labelInterface->property("Name").toString(), l->text());
+
++ auto *a11yEmptyInterface = getInterface(children.at(1), "org.a11y.atspi.Accessible");
++ QCOMPARE(a11yEmptyInterface->call(QDBus::Block, "GetAccessibleId").arguments().first().toString(),
++ QLatin1String("mainWindow.QLabel"));
++
+ m_window->clearChildren();
++ delete a11yEmptyInterface;
+ delete labelInterface;
+ }
+
+diff --git a/qtbase/tests/auto/sql/kernel/qsqlquery/tst_qsqlquery.cpp b/qtbase/tests/auto/sql/kernel/qsqlquery/tst_qsqlquery.cpp
+index 76df61c892..6d6d65b791 100644
+--- a/qtbase/tests/auto/sql/kernel/qsqlquery/tst_qsqlquery.cpp
++++ b/qtbase/tests/auto/sql/kernel/qsqlquery/tst_qsqlquery.cpp
+@@ -1,6 +1,6 @@
+ /****************************************************************************
+ **
+-** Copyright (C) 2016 The Qt Company Ltd.
++** Copyright (C) 2022 The Qt Company Ltd.
+ ** Contact: https://www.qt.io/licensing/
+ **
+ ** This file is part of the test suite of the Qt Toolkit.
+@@ -68,6 +68,8 @@ private slots:
+ void query_exec();
+ void execErrorRecovery_data() { generic_data(); }
+ void execErrorRecovery();
++ void prematureExec_data() { generic_data(); }
++ void prematureExec();
+ void first_data() { generic_data(); }
+ void first();
+ void next_data() { generic_data(); }
+@@ -2770,6 +2772,35 @@ void tst_QSqlQuery::execErrorRecovery()
+ QVERIFY_SQL( q, exec() );
+ }
+
++void tst_QSqlQuery::prematureExec()
++{
++ QFETCH(QString, dbName);
++ // We only want the engine name, for addDatabase():
++ int cut = dbName.indexOf(QChar('@'));
++ if (cut < 0)
++ QSKIP("Failed to parse database type out of name");
++ dbName.truncate(cut);
++ cut = dbName.indexOf(QChar('_'));
++ if (cut >= 0)
++ dbName = dbName.mid(cut + 1);
++
++ auto db = QSqlDatabase::addDatabase(dbName);
++ QSqlQuery q(db);
++
++ QTest::ignoreMessage(QtWarningMsg,
++ "QSqlDatabasePrivate::removeDatabase: connection "
++ "'qt_sql_default_connection' is still in use, all "
++ "queries will cease to work.");
++ QTest::ignoreMessage(QtWarningMsg,
++ "QSqlDatabasePrivate::addDatabase: duplicate connection name "
++ "'qt_sql_default_connection', old connection removed.");
++ auto otherDb = QSqlDatabase::addDatabase(dbName);
++
++ QTest::ignoreMessage(QtWarningMsg, "QSqlQuery::exec: called before driver has been set up");
++ // QTBUG-100037: shouldn't crash !
++ QVERIFY(!q.exec("select stuff from TheVoid"));
++}
++
+ void tst_QSqlQuery::lastInsertId()
+ {
+ QFETCH( QString, dbName );
+diff --git a/qtbase/tests/auto/testlib/qabstractitemmodeltester/tst_qabstractitemmodeltester.cpp b/qtbase/tests/auto/testlib/qabstractitemmodeltester/tst_qabstractitemmodeltester.cpp
+index 4aa3f8d60b..d2050a61aa 100644
+--- a/qtbase/tests/auto/testlib/qabstractitemmodeltester/tst_qabstractitemmodeltester.cpp
++++ b/qtbase/tests/auto/testlib/qabstractitemmodeltester/tst_qabstractitemmodeltester.cpp
+@@ -115,6 +115,10 @@ void tst_QAbstractItemModelTester::standardItemModelZeroColumns()
+ // QTBUG-92886
+ model.insertRows(0, 5);
+ model.removeRows(1, 2);
++
++ const QModelIndex parentIndex = model.index(0, 0);
++ model.insertRows(0, 5, parentIndex);
++ model.removeRows(1, 2, parentIndex);
+ }
+
+ void tst_QAbstractItemModelTester::testInsertThroughProxy()
+diff --git a/qtbase/tests/auto/tools/moc/allmocs_baseline_in.json b/qtbase/tests/auto/tools/moc/allmocs_baseline_in.json
+index 12a4a22a19..ce518e78fb 100644
+--- a/qtbase/tests/auto/tools/moc/allmocs_baseline_in.json
++++ b/qtbase/tests/auto/tools/moc/allmocs_baseline_in.json
+@@ -668,50 +668,6 @@
+ "inputFile": "task192552.h",
+ "outputRevision": 67
+ },
+- {
+- "classes": [
+- {
+- "className": "InlineSlotsWithThrowDeclaration",
+- "object": true,
+- "qualifiedClassName": "InlineSlotsWithThrowDeclaration",
+- "slots": [
+- {
+- "access": "public",
+- "name": "a",
+- "returnType": "void"
+- },
+- {
+- "access": "public",
+- "name": "b",
+- "returnType": "void"
+- },
+- {
+- "access": "public",
+- "name": "c",
+- "returnType": "void"
+- },
+- {
+- "access": "public",
+- "name": "d",
+- "returnType": "void"
+- },
+- {
+- "access": "public",
+- "name": "e",
+- "returnType": "void"
+- }
+- ],
+- "superClasses": [
+- {
+- "access": "public",
+- "name": "QObject"
+- }
+- ]
+- }
+- ],
+- "inputFile": "task189996.h",
+- "outputRevision": 67
+- },
+ {
+ "classes": [
+ {
+diff --git a/qtbase/tests/auto/tools/moc/moc.pro b/qtbase/tests/auto/tools/moc/moc.pro
+index c324b3a8cd..4aceb78dc0 100644
+--- a/qtbase/tests/auto/tools/moc/moc.pro
++++ b/qtbase/tests/auto/tools/moc/moc.pro
+@@ -15,7 +15,7 @@ cross_compile: DEFINES += MOC_CROSS_COMPILED
+ HEADERS += using-namespaces.h no-keywords.h task87883.h c-comments.h backslash-newlines.h oldstyle-casts.h \
+ slots-with-void-template.h qinvokable.h namespaced-flags.h trigraphs.h \
+ escapes-in-string-literals.h cstyle-enums.h qprivateslots.h gadgetwithnoenums.h \
+- dir-in-include-path.h single_function_keyword.h task192552.h task189996.h \
++ dir-in-include-path.h single_function_keyword.h task192552.h \
+ task234909.h task240368.h pure-virtual-signals.h cxx11-enums.h \
+ cxx11-final-classes.h \
+ cxx11-explicit-override-control.h \
+diff --git a/qtbase/tests/auto/tools/moc/task189996.h b/qtbase/tests/auto/tools/moc/task189996.h
+deleted file mode 100644
+index f94a051b3a..0000000000
+--- a/qtbase/tests/auto/tools/moc/task189996.h
++++ /dev/null
+@@ -1,47 +0,0 @@
+-/****************************************************************************
+-**
+-** Copyright (C) 2016 The Qt Company Ltd.
+-** Contact: https://www.qt.io/licensing/
+-**
+-** This file is part of the test suite of the Qt Toolkit.
+-**
+-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+-** Commercial License Usage
+-** Licensees holding valid commercial Qt licenses may use this file in
+-** accordance with the commercial license agreement provided with the
+-** Software or, alternatively, in accordance with the terms contained in
+-** a written agreement between you and The Qt Company. For licensing terms
+-** and conditions see https://www.qt.io/terms-conditions. For further
+-** information use the contact form at https://www.qt.io/contact-us.
+-**
+-** GNU General Public License Usage
+-** Alternatively, this file may be used under the terms of the GNU
+-** General Public License version 3 as published by the Free Software
+-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+-** included in the packaging of this file. Please review the following
+-** information to ensure the GNU General Public License requirements will
+-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+-**
+-** $QT_END_LICENSE$
+-**
+-****************************************************************************/
+-// inline functions can have throw declarations
+-
+-#ifndef TASK189996_H
+-#define TASK189996_H
+-
+-#include <QObject>
+-
+-class InlineSlotsWithThrowDeclaration : public QObject
+-{
+- Q_OBJECT
+-
+-public slots:
+- void a() throw() { }
+- void b() const throw() { }
+- void c() throw();
+- void d() throw(int) { }
+- void e() const throw(int,double) { }
+-};
+-
+-#endif
+diff --git a/qtbase/tests/auto/tools/moc/tst_moc.cpp b/qtbase/tests/auto/tools/moc/tst_moc.cpp
+index c716aead21..15dd9e41e5 100644
+--- a/qtbase/tests/auto/tools/moc/tst_moc.cpp
++++ b/qtbase/tests/auto/tools/moc/tst_moc.cpp
+@@ -631,7 +631,6 @@ public:
+ private slots:
+ void initTestCase();
+
+- void slotWithException() throw(MyStruct);
+ void dontStripNamespaces();
+ void oldStyleCasts();
+ void warnOnExtraSignalSlotQualifiaction();
+@@ -673,7 +672,6 @@ private slots:
+ void templateGtGt();
+ void qprivateslots();
+ void qprivateproperties();
+- void inlineSlotsWithThrowDeclaration();
+ void warnOnPropertyWithoutREAD();
+ void constructors();
+ void typenameWithUnsigned();
+@@ -784,12 +782,6 @@ void tst_Moc::initTestCase()
+ #endif
+ }
+
+-void tst_Moc::slotWithException() throw(MyStruct)
+-{
+- // be happy
+- QVERIFY(true);
+-}
+-
+ void tst_Moc::dontStripNamespaces()
+ {
+ Sender sender;
+@@ -824,7 +816,7 @@ void tst_Moc::oldStyleCasts()
+
+ QStringList args;
+ args << "-c" << "-x" << "c++" << "-Wold-style-cast" << "-I" << "."
+- << "-I" << qtIncludePath << "-o" << "/dev/null" << "-fPIC" << "-std=c++11" << "-";
++ << "-I" << qtIncludePath << "-o" << "/dev/null" << "-fPIC" << "-std=c++1z" << "-";
+ proc.start("gcc", args);
+ QVERIFY(proc.waitForStarted());
+ proc.write(mocOut);
+@@ -894,7 +886,7 @@ void tst_Moc::inputFileNameWithDotsButNoExtension()
+
+ QStringList args;
+ args << "-c" << "-x" << "c++" << "-I" << ".."
+- << "-I" << qtIncludePath << "-o" << "/dev/null" << "-fPIC" << "-std=c++11" << "-";
++ << "-I" << qtIncludePath << "-o" << "/dev/null" << "-fPIC" << "-std=c++1z" << "-";
+ proc.start("gcc", args);
+ QVERIFY(proc.waitForStarted());
+ proc.write(mocOut);
+@@ -1174,7 +1166,7 @@ void tst_Moc::ignoreOptionClashes()
+ QStringList gccArgs;
+ gccArgs << "-c" << "-x" << "c++" << "-I" << ".."
+ << "-I" << qtIncludePath << "-I" << includeDir << "-o" << "/dev/null"
+- << "-fPIC" << "-std=c++11" << "-";
++ << "-fPIC" << "-std=c++1z" << "-";
+ proc.start("gcc", gccArgs);
+ QVERIFY(proc.waitForStarted());
+ proc.write(mocOut);
+@@ -1593,21 +1585,6 @@ void tst_Moc::qprivateproperties()
+
+ }
+
+-#include "task189996.h"
+-
+-void InlineSlotsWithThrowDeclaration::c() throw() {}
+-
+-void tst_Moc::inlineSlotsWithThrowDeclaration()
+-{
+- InlineSlotsWithThrowDeclaration tst;
+- const QMetaObject *mobj = tst.metaObject();
+- QVERIFY(mobj->indexOfSlot("a()") != -1);
+- QVERIFY(mobj->indexOfSlot("b()") != -1);
+- QVERIFY(mobj->indexOfSlot("c()") != -1);
+- QVERIFY(mobj->indexOfSlot("d()") != -1);
+- QVERIFY(mobj->indexOfSlot("e()") != -1);
+-}
+-
+ void tst_Moc::warnOnPropertyWithoutREAD()
+ {
+ #ifdef MOC_CROSS_COMPILED
+@@ -1869,7 +1846,7 @@ void tst_Moc::notifyError()
+
+ QStringList args;
+ args << "-c" << "-x" << "c++" << "-I" << "."
+- << "-I" << qtIncludePath << "-o" << "/dev/null" << "-fPIC" << "-std=c++11" << "-";
++ << "-I" << qtIncludePath << "-o" << "/dev/null" << "-fPIC" << "-std=c++1z" << "-";
+ proc.start("gcc", args);
+ QVERIFY(proc.waitForStarted());
+ proc.write(mocOut);
+diff --git a/qtbase/tests/auto/widgets/itemviews/qheaderview/tst_qheaderview.cpp b/qtbase/tests/auto/widgets/itemviews/qheaderview/tst_qheaderview.cpp
+index c355ee9665..88c09de8e0 100644
+--- a/qtbase/tests/auto/widgets/itemviews/qheaderview/tst_qheaderview.cpp
++++ b/qtbase/tests/auto/widgets/itemviews/qheaderview/tst_qheaderview.cpp
+@@ -251,6 +251,7 @@ private slots:
+ void testResetCachedSizeHint();
+ void statusTips();
+ void testRemovingColumnsViaLayoutChanged();
++ void testModelMovingColumns();
+
+ protected:
+ void setupTestData(bool use_reset_model = false);
+@@ -360,6 +361,12 @@ public:
+ endRemoveColumns();
+ }
+
++ void moveColumn(int from, int to)
++ {
++ beginMoveColumns(QModelIndex(), from, from, QModelIndex(), to);
++ endMoveColumns();
++ }
++
+ void cleanup()
+ {
+ emit layoutAboutToBeChanged();
+@@ -3627,5 +3634,18 @@ void tst_QHeaderView::testRemovingColumnsViaLayoutChanged()
+ // The main point of this test is that the section-size restoring code didn't go out of bounds.
+ }
+
++void tst_QHeaderView::testModelMovingColumns()
++{
++ QtTestModel model(10, 10);
++ QHeaderView hv(Qt::Horizontal);
++ hv.setModel(&model);
++ hv.resizeSections(QHeaderView::ResizeToContents);
++ hv.show();
++
++ QPersistentModelIndex index3 = model.index(0, 3);
++ model.moveColumn(3, 1);
++ QCOMPARE(index3.column(), 1);
++}
++
+ QTEST_MAIN(tst_QHeaderView)
+ #include "tst_qheaderview.moc"
+diff --git a/qtbase/tests/auto/widgets/itemviews/qtableview/tst_qtableview.cpp b/qtbase/tests/auto/widgets/itemviews/qtableview/tst_qtableview.cpp
+index 761357b252..06bb706074 100644
+--- a/qtbase/tests/auto/widgets/itemviews/qtableview/tst_qtableview.cpp
++++ b/qtbase/tests/auto/widgets/itemviews/qtableview/tst_qtableview.cpp
+@@ -397,6 +397,7 @@ private slots:
+ void checkHeaderMinSize();
+
+ void resizeToContents();
++ void resizeToContentsSpans();
+
+ void tabFocus();
+ void bigModel();
+@@ -3721,6 +3722,70 @@ void tst_QTableView::resizeToContents()
+
+ }
+
++
++class SpanModel : public QAbstractTableModel
++{
++public:
++ SpanModel(bool sectionsMoved)
++ : _sectionsMoved(sectionsMoved)
++ {}
++ int columnCount(const QModelIndex & = {}) const override { return 2; }
++ int rowCount(const QModelIndex & = {}) const override { return 1; }
++ QVariant data(const QModelIndex &idx, int role = Qt::DisplayRole) const override
++ {
++ if (role != Qt::DisplayRole)
++ return QVariant();
++ const int col = _sectionsMoved ? 1 - idx.column() : idx.column();
++ if (col == 0)
++ return "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.";
++ return QVariant();
++ }
++private:
++ bool _sectionsMoved;
++};
++
++
++void tst_QTableView::resizeToContentsSpans()
++{
++ SpanModel model1(false);
++ SpanModel model2(true);
++ QTableView view1, view2, view3;
++ view1.setModel(&model1);
++ view2.setModel(&model2);
++ view2.horizontalHeader()->moveSection(0, 1);
++ view3.setModel(&model1);
++
++ view1.setSpan(0, 0, 1, 2);
++ view2.setSpan(0, 1, 1, 2);
++ view1.show();
++ view2.show();
++ view3.show();
++ QVERIFY(QTest::qWaitForWindowExposed(&view1));
++ QVERIFY(QTest::qWaitForWindowExposed(&view2));
++ QVERIFY(QTest::qWaitForWindowExposed(&view3));
++ view1.setColumnWidth(0, 100);
++ view1.setColumnWidth(1, 100);
++ view2.setColumnWidth(0, 100);
++ view2.setColumnWidth(1, 100);
++ view3.setColumnWidth(0, 200);
++
++ view1.resizeRowToContents(0);
++ view2.resizeRowToContents(0);
++ view3.resizeRowToContents(0);
++ QCOMPARE(view1.rowHeight(0), view3.rowHeight(0));
++ QCOMPARE(view2.rowHeight(0), view3.rowHeight(0));
++
++ view3.resizeColumnToContents(0);
++ view3.resizeRowToContents(0);
++ // height should be only 1 text line for easy testing
++ view1.setRowHeight(0, view3.verticalHeader()->sectionSize(0));
++ view2.setRowHeight(0, view3.verticalHeader()->sectionSize(0));
++ view1.resizeColumnToContents(0);
++ view2.resizeColumnToContents(1);
++ QCOMPARE(view1.columnWidth(0), view3.columnWidth(0) - view1.columnWidth(1));
++ QCOMPARE(view2.columnWidth(0), view3.columnWidth(0) - view2.columnWidth(1));
++}
++
+ QT_BEGIN_NAMESPACE
+ extern bool Q_WIDGETS_EXPORT qt_tab_all_widgets(); // qapplication.cpp
+ QT_END_NAMESPACE
+diff --git a/qtbase/tests/auto/widgets/kernel/qapplication/tst_qapplication.cpp b/qtbase/tests/auto/widgets/kernel/qapplication/tst_qapplication.cpp
+index a3b8ef78d8..4955cebd5d 100644
+--- a/qtbase/tests/auto/widgets/kernel/qapplication/tst_qapplication.cpp
++++ b/qtbase/tests/auto/widgets/kernel/qapplication/tst_qapplication.cpp
+@@ -1498,7 +1498,7 @@ void tst_QApplication::desktopSettingsAware()
+ environment += QLatin1String("QT_MAC_DISABLE_FOREGROUND_APPLICATION_TRANSFORM=1");
+ testProcess.setEnvironment(environment);
+ #endif
+- testProcess.start("desktopsettingsaware_helper");
++ testProcess.start("./desktopsettingsaware_helper");
+ QVERIFY2(testProcess.waitForStarted(),
+ qPrintable(QString::fromLatin1("Cannot start 'desktopsettingsaware_helper': %1").arg(testProcess.errorString())));
+ QVERIFY(testProcess.waitForFinished(10000));
+@@ -2452,7 +2452,7 @@ void tst_QApplication::qtbug_12673()
+ #if QT_CONFIG(process)
+ QProcess testProcess;
+ QStringList arguments;
+- testProcess.start("modal_helper", arguments);
++ testProcess.start("./modal_helper", arguments);
+ QVERIFY2(testProcess.waitForStarted(),
+ qPrintable(QString::fromLatin1("Cannot start 'modal_helper': %1").arg(testProcess.errorString())));
+ QVERIFY(testProcess.waitForFinished(20000));
+diff --git a/qtbase/tests/auto/widgets/widgets/qabstractbutton/tst_qabstractbutton.cpp b/qtbase/tests/auto/widgets/widgets/qabstractbutton/tst_qabstractbutton.cpp
+index eb108a40de..dca5528c1b 100644
+--- a/qtbase/tests/auto/widgets/widgets/qabstractbutton/tst_qabstractbutton.cpp
++++ b/qtbase/tests/auto/widgets/widgets/qabstractbutton/tst_qabstractbutton.cpp
+@@ -41,6 +41,7 @@
+
+ #include <private/qguiapplication_p.h>
+ #include <qpa/qplatformintegration.h>
++#include <qpa/qplatformtheme.h>
+
+ class tst_QAbstractButton : public QObject
+ {
+@@ -76,6 +77,8 @@ private slots:
+ void keyNavigation();
+ #endif
+
++ void buttonPressKeys();
++
+ protected slots:
+ void onClicked();
+ void onToggled( bool on );
+@@ -269,7 +272,13 @@ void tst_QAbstractButton::setAutoRepeat()
+ QCOMPARE(press_count, click_count);
+ QVERIFY(click_count > 1);
+ break;
+- case 4:
++ case 4: {
++ const auto buttonPressKeys = QGuiApplicationPrivate::platformTheme()
++ ->themeHint(QPlatformTheme::ButtonPressKeys)
++ .value<QList<Qt::Key>>();
++ if (buttonPressKeys.contains(Qt::Key_Enter)) {
++ QSKIP("platform theme has Key_Enter in ButtonPressKeys");
++ }
+ // check that pressing ENTER has no effect when autorepeat is false
+ testWidget->setDown( false );
+ testWidget->setAutoRepeat( false );
+@@ -286,7 +295,14 @@ void tst_QAbstractButton::setAutoRepeat()
+
+ QVERIFY( click_count == 0 );
+ break;
+- case 5:
++ }
++ case 5: {
++ const auto buttonPressKeys = QGuiApplicationPrivate::platformTheme()
++ ->themeHint(QPlatformTheme::ButtonPressKeys)
++ .value<QList<Qt::Key>>();
++ if (buttonPressKeys.contains(Qt::Key_Enter)) {
++ QSKIP("platform theme has Key_Enter in ButtonPressKeys");
++ }
+ // check that pressing ENTER has no effect when autorepeat is true
+ testWidget->setDown( false );
+ testWidget->setAutoRepeat( true );
+@@ -304,6 +320,7 @@ void tst_QAbstractButton::setAutoRepeat()
+
+ QVERIFY( click_count == 0 );
+ break;
++ }
+ case 6:
+ // verify autorepeat is off by default.
+ MyButton tmp( 0);
+@@ -651,5 +668,16 @@ void tst_QAbstractButton::keyNavigation()
+ }
+ #endif
+
++void tst_QAbstractButton::buttonPressKeys()
++{
++ const auto buttonPressKeys = QGuiApplicationPrivate::platformTheme()
++ ->themeHint(QPlatformTheme::ButtonPressKeys)
++ .value<QList<Qt::Key>>();
++ for (int i = 0; i < buttonPressKeys.length(); ++i) {
++ QTest::keyClick(testWidget, buttonPressKeys[i]);
++ QCOMPARE(click_count, i + 1);
++ }
++}
++
+ QTEST_MAIN(tst_QAbstractButton)
+ #include "tst_qabstractbutton.moc"
+diff --git a/qtbase/tests/auto/widgets/widgets/qcombobox/tst_qcombobox.cpp b/qtbase/tests/auto/widgets/widgets/qcombobox/tst_qcombobox.cpp
+index 32437050f5..46b5af6d63 100644
+--- a/qtbase/tests/auto/widgets/widgets/qcombobox/tst_qcombobox.cpp
++++ b/qtbase/tests/auto/widgets/widgets/qcombobox/tst_qcombobox.cpp
+@@ -168,6 +168,7 @@ private slots:
+ void checkMenuItemPosWhenStyleSheetIsSet();
+ void checkEmbeddedLineEditWhenStyleSheetIsSet();
+ void propagateStyleChanges();
++ void buttonPressKeys();
+
+ private:
+ PlatformInputContext m_platformInputContext;
+@@ -1682,6 +1683,16 @@ void tst_QComboBox::setModel()
+ QCOMPARE(box.rootModelIndex(), rootModelIndex);
+ box.setModel(box.model());
+ QCOMPARE(box.rootModelIndex(), rootModelIndex);
++
++ // check that setting the same model as the completer's doesn't crash
++ QCompleter *completer = new QCompleter(&box);
++ box.setEditable(true);
++ box.setCompleter(completer);
++ auto *listModel = new QStringListModel({ "one", "two" }, completer);
++ completer->setModel(listModel);
++ QCOMPARE(listModel->rowCount(), 2); // make sure it wasn't deleted
++ box.setModel(listModel);
++ QCOMPARE(listModel->rowCount(), 2); // make sure it wasn't deleted
+ }
+
+ void tst_QComboBox::setCustomModelAndView()
+@@ -3632,5 +3643,24 @@ void tst_QComboBox::propagateStyleChanges()
+ QVERIFY(frameStyle.inquired);
+ }
+
++void tst_QComboBox::buttonPressKeys()
++{
++ QComboBox comboBox;
++ comboBox.setEditable(false);
++ comboBox.addItem(QString::number(1));
++ comboBox.addItem(QString::number(2));
++ const auto buttonPressKeys = QGuiApplicationPrivate::platformTheme()
++ ->themeHint(QPlatformTheme::ButtonPressKeys)
++ .value<QList<Qt::Key>>();
++ for (int i = 0; i < buttonPressKeys.length(); ++i) {
++ QTest::keyClick(&comboBox, buttonPressKeys[i]);
++ // On some platforms, a window will not be immediately visible,
++ // but take some event-loop iterations to complete.
++ // Using QTRY_VERIFY to deal with that.
++ QTRY_VERIFY(comboBox.view()->isVisible());
++ comboBox.hidePopup();
++ }
++}
++
+ QTEST_MAIN(tst_QComboBox)
+ #include "tst_qcombobox.moc"
+diff --git a/qtbase/tests/auto/widgets/widgets/qcommandlinkbutton/qcommandlinkbutton.pro b/qtbase/tests/auto/widgets/widgets/qcommandlinkbutton/qcommandlinkbutton.pro
+index be3cfcd104..c228fdfcca 100644
+--- a/qtbase/tests/auto/widgets/widgets/qcommandlinkbutton/qcommandlinkbutton.pro
++++ b/qtbase/tests/auto/widgets/widgets/qcommandlinkbutton/qcommandlinkbutton.pro
+@@ -1,6 +1,6 @@
+ CONFIG += testcase
+ TARGET = tst_qcommandlinkbutton
+-QT += widgets testlib
++QT += widgets testlib gui-private
+ SOURCES += tst_qcommandlinkbutton.cpp
+
+
+diff --git a/qtbase/tests/auto/widgets/widgets/qcommandlinkbutton/tst_qcommandlinkbutton.cpp b/qtbase/tests/auto/widgets/widgets/qcommandlinkbutton/tst_qcommandlinkbutton.cpp
+index 0044d33c66..4cf06296e4 100644
+--- a/qtbase/tests/auto/widgets/widgets/qcommandlinkbutton/tst_qcommandlinkbutton.cpp
++++ b/qtbase/tests/auto/widgets/widgets/qcommandlinkbutton/tst_qcommandlinkbutton.cpp
+@@ -40,6 +40,9 @@
+ #include <QGridLayout>
+ #include <QPainter>
+
++#include <private/qguiapplication_p.h>
++#include <qpa/qplatformtheme.h>
++
+ class tst_QCommandLinkButton : public QObject
+ {
+ Q_OBJECT
+@@ -223,6 +226,13 @@ void tst_QCommandLinkButton::setAutoRepeat()
+ // check that pressing ENTER has no effect
+ resetCounters();
+ testWidget->setDown( false );
++ // Skip after reset if ButtonPressKeys has Key_Enter
++ const auto buttonPressKeys = QGuiApplicationPrivate::platformTheme()
++ ->themeHint(QPlatformTheme::ButtonPressKeys)
++ .value<QList<Qt::Key>>();
++ if (buttonPressKeys.contains(Qt::Key_Enter)) {
++ return;
++ }
+ testWidget->setAutoRepeat( false );
+ QTest::keyPress( testWidget, Qt::Key_Enter );
+
+@@ -255,6 +265,14 @@ void tst_QCommandLinkButton::pressed()
+ QCOMPARE( press_count, (uint)1 );
+ QCOMPARE( release_count, (uint)1 );
+
++ // Skip if ButtonPressKeys has Key_Enter
++ const auto buttonPressKeys = QGuiApplicationPrivate::platformTheme()
++ ->themeHint(QPlatformTheme::ButtonPressKeys)
++ .value<QList<Qt::Key>>();
++ if (buttonPressKeys.contains(Qt::Key_Enter)) {
++ return;
++ }
++
+ QTest::keyPress( testWidget,Qt::Key_Enter );
+ QCOMPARE( press_count, (uint)1 );
+ QCOMPARE( release_count, (uint)1 );
+diff --git a/qtbase/tests/auto/widgets/widgets/qgroupbox/qgroupbox.pro b/qtbase/tests/auto/widgets/widgets/qgroupbox/qgroupbox.pro
+index 4a5e76ff65..a235fa1fac 100644
+--- a/qtbase/tests/auto/widgets/widgets/qgroupbox/qgroupbox.pro
++++ b/qtbase/tests/auto/widgets/widgets/qgroupbox/qgroupbox.pro
+@@ -1,6 +1,6 @@
+ CONFIG += testcase
+ TARGET = tst_qgroupbox
+-QT += widgets testlib
++QT += widgets testlib gui-private
+ SOURCES += tst_qgroupbox.cpp
+
+
+diff --git a/qtbase/tests/auto/widgets/widgets/qgroupbox/tst_qgroupbox.cpp b/qtbase/tests/auto/widgets/widgets/qgroupbox/tst_qgroupbox.cpp
+index 4fb5d262ca..d8d7562b73 100644
+--- a/qtbase/tests/auto/widgets/widgets/qgroupbox/tst_qgroupbox.cpp
++++ b/qtbase/tests/auto/widgets/widgets/qgroupbox/tst_qgroupbox.cpp
+@@ -35,6 +35,9 @@
+ #include <QRadioButton>
+ #include <QDialog>
+
++#include <private/qguiapplication_p.h>
++#include <qpa/qplatformtheme.h>
++
+ #include "qgroupbox.h"
+
+ class tst_QGroupBox : public QObject
+@@ -69,6 +72,7 @@ private slots:
+ void propagateFocus();
+ void task_QTBUG_19170_ignoreMouseReleaseEvent();
+ void task_QTBUG_15519_propagateMouseEvents();
++ void buttonPressKeys();
+
+ private:
+ bool checked;
+@@ -610,6 +614,20 @@ void tst_QGroupBox::task_QTBUG_15519_propagateMouseEvents()
+ QCOMPARE(parent.mouseMoved, true);
+ }
+
++void tst_QGroupBox::buttonPressKeys()
++{
++ QGroupBox groupBox;
++ groupBox.setCheckable(true);
++ QSignalSpy clickedSpy(&groupBox, &QGroupBox::clicked);
++ const auto buttonPressKeys = QGuiApplicationPrivate::platformTheme()
++ ->themeHint(QPlatformTheme::ButtonPressKeys)
++ .value<QList<Qt::Key>>();
++ for (int i = 0; i < buttonPressKeys.length(); ++i) {
++ QTest::keyClick(&groupBox, buttonPressKeys[i]);
++ QCOMPARE(clickedSpy.length(), i + 1);
++ }
++}
++
+ void tst_QGroupBox::sendMouseMoveEvent(QWidget *widget, const QPoint &localPos)
+ {
+ // Send a MouseMove event without actually moving the pointer
+diff --git a/qtbase/tests/auto/widgets/widgets/qpushbutton/qpushbutton.pro b/qtbase/tests/auto/widgets/widgets/qpushbutton/qpushbutton.pro
+index 353ad06ca2..e55f6148f2 100644
+--- a/qtbase/tests/auto/widgets/widgets/qpushbutton/qpushbutton.pro
++++ b/qtbase/tests/auto/widgets/widgets/qpushbutton/qpushbutton.pro
+@@ -1,6 +1,6 @@
+ CONFIG += testcase
+ TARGET = tst_qpushbutton
+-QT += widgets testlib
++QT += widgets testlib gui-private
+ SOURCES += tst_qpushbutton.cpp
+
+
+diff --git a/qtbase/tests/auto/widgets/widgets/qpushbutton/tst_qpushbutton.cpp b/qtbase/tests/auto/widgets/widgets/qpushbutton/tst_qpushbutton.cpp
+index e818514a79..4043e9326a 100644
+--- a/qtbase/tests/auto/widgets/widgets/qpushbutton/tst_qpushbutton.cpp
++++ b/qtbase/tests/auto/widgets/widgets/qpushbutton/tst_qpushbutton.cpp
+@@ -41,6 +41,9 @@
+ #include <QStyleFactory>
+ #include <QTabWidget>
+
++#include <private/qguiapplication_p.h>
++#include <qpa/qplatformtheme.h>
++
+ class tst_QPushButton : public QObject
+ {
+ Q_OBJECT
+@@ -212,6 +215,13 @@ void tst_QPushButton::autoRepeat()
+ // check that pressing ENTER has no effect
+ resetCounters();
+ testWidget->setDown( false );
++ // Skip after reset if ButtonPressKeys has Key_Enter
++ const auto buttonPressKeys = QGuiApplicationPrivate::platformTheme()
++ ->themeHint(QPlatformTheme::ButtonPressKeys)
++ .value<QList<Qt::Key>>();
++ if (buttonPressKeys.contains(Qt::Key_Enter)) {
++ return;
++ }
+ testWidget->setAutoRepeat( false );
+ QTest::keyPress( testWidget, Qt::Key_Enter );
+
+@@ -247,6 +257,14 @@ void tst_QPushButton::pressed()
+ QCOMPARE( press_count, (uint)1 );
+ QCOMPARE( release_count, (uint)1 );
+
++ // Skip if ButtonPressKeys has Key_Enter
++ const auto buttonPressKeys = QGuiApplicationPrivate::platformTheme()
++ ->themeHint(QPlatformTheme::ButtonPressKeys)
++ .value<QList<Qt::Key>>();
++ if (buttonPressKeys.contains(Qt::Key_Enter)) {
++ return;
++ }
++
+ QTest::keyPress( testWidget,Qt::Key_Enter );
+ QCOMPARE( press_count, (uint)1 );
+ QCOMPARE( release_count, (uint)1 );
+diff --git a/qtbase/tests/manual/rhi/cubemap_render/buildshader.bat b/qtbase/tests/manual/rhi/cubemap_render/buildshader.bat
+old mode 100755
+new mode 100644
+Submodule qtconnectivity e957d481..056294c0:
+diff --git a/qtconnectivity/src/bluetooth/bluez/hcimanager.cpp b/qtconnectivity/src/bluetooth/bluez/hcimanager.cpp
+index e2635fae..a8b8e3b9 100644
+--- a/qtconnectivity/src/bluetooth/bluez/hcimanager.cpp
++++ b/qtconnectivity/src/bluetooth/bluez/hcimanager.cpp
+@@ -563,9 +563,11 @@ void HciManager::handleHciAclPacket(const quint8 *data, int size)
+
+ void HciManager::handleLeMetaEvent(const quint8 *data)
+ {
+- // Spec v4.2, Vol 2, part E, 7.7.65ff
++ // Spec v5.3, Vol 4, part E, 7.7.65.*
+ switch (*data) {
+- case 0x1: {
++ case 0x1: // HCI_LE_Connection_Complete
++ case 0xA: // HCI_LE_Enhanced_Connection_Complete
++ {
+ const quint16 handle = bt_get_le16(data + 2);
+ emit connectionComplete(handle);
+ break;
+diff --git a/qtconnectivity/src/bluetooth/qbluetoothservicediscoveryagent_bluez.cpp b/qtconnectivity/src/bluetooth/qbluetoothservicediscoveryagent_bluez.cpp
+index 6a93143b..4a18cfc7 100644
+--- a/qtconnectivity/src/bluetooth/qbluetoothservicediscoveryagent_bluez.cpp
++++ b/qtconnectivity/src/bluetooth/qbluetoothservicediscoveryagent_bluez.cpp
+@@ -320,7 +320,10 @@ void QBluetoothServiceDiscoveryAgentPrivate::_q_finishSdpScan(QBluetoothServiceD
+ for (const QBluetoothUuid &id : serviceClassUuids) {
+ if (id.minimumSize() == 16) {
+ serviceInfo.setServiceUuid(id);
+- serviceInfo.setServiceName(QBluetoothServiceDiscoveryAgent::tr("Custom Service"));
++ if (serviceInfo.serviceName().isEmpty()) {
++ serviceInfo.setServiceName(
++ QBluetoothServiceDiscoveryAgent::tr("Custom Service"));
++ }
+ QBluetoothServiceInfo::Sequence modSeq =
+ serviceInfo.attribute(QBluetoothServiceInfo::ServiceClassIds).value<QBluetoothServiceInfo::Sequence>();
+ modSeq.removeOne(QVariant::fromValue(id));
+@@ -334,8 +337,10 @@ void QBluetoothServiceDiscoveryAgentPrivate::_q_finishSdpScan(QBluetoothServiceD
+ qCDebug(QT_BT_BLUEZ) << "Discovered services" << discoveredDevices.at(0).address().toString()
+ << serviceInfo.serviceName() << serviceInfo.serviceUuid()
+ << ">>>" << serviceInfo.serviceClassUuids();
+-
+- emit q->serviceDiscovered(serviceInfo);
++ // Use queued connection to allow us finish the service looping; the application
++ // might call stop() when it has detected the service-of-interest.
++ QMetaObject::invokeMethod(q, "serviceDiscovered", Qt::QueuedConnection,
++ Q_ARG(QBluetoothServiceInfo, serviceInfo));
+ }
+ }
+ }
+diff --git a/qtconnectivity/src/bluetooth/qbluetoothsocket.cpp b/qtconnectivity/src/bluetooth/qbluetoothsocket.cpp
+index e4d85447..aadd4755 100644
+--- a/qtconnectivity/src/bluetooth/qbluetoothsocket.cpp
++++ b/qtconnectivity/src/bluetooth/qbluetoothsocket.cpp
+@@ -593,7 +593,7 @@ void QBluetoothSocket::setSocketState(QBluetoothSocket::SocketState state)
+ bool QBluetoothSocket::canReadLine() const
+ {
+ Q_D(const QBluetoothSocketBase);
+- return d->canReadLine();
++ return d->canReadLine() || QIODevice::canReadLine();
+ }
+
+ /*!
+diff --git a/qtconnectivity/src/bluetooth/qbluetoothsocket_bluezdbus.cpp b/qtconnectivity/src/bluetooth/qbluetoothsocket_bluezdbus.cpp
+index 084aa958..d6aa17a7 100644
+--- a/qtconnectivity/src/bluetooth/qbluetoothsocket_bluezdbus.cpp
++++ b/qtconnectivity/src/bluetooth/qbluetoothsocket_bluezdbus.cpp
+@@ -284,6 +284,10 @@ void QBluetoothSocketPrivateBluezDBus::connectToService(
+ return;
+ }
+
++ if (service.socketProtocol() != QBluetoothServiceInfo::Protocol::UnknownProtocol)
++ socketType = service.socketProtocol();
++ qCDebug(QT_BT_BLUEZ) << "Socket protocol used:" << socketType;
++
+ connectToService(service.device().address(), targetService, openMode);
+ }
+
+diff --git a/qtconnectivity/tests/auto/qbluetoothsocket/tst_qbluetoothsocket.cpp b/qtconnectivity/tests/auto/qbluetoothsocket/tst_qbluetoothsocket.cpp
+index 05bc1a0f..a7b5ef1f 100644
+--- a/qtconnectivity/tests/auto/qbluetoothsocket/tst_qbluetoothsocket.cpp
++++ b/qtconnectivity/tests/auto/qbluetoothsocket/tst_qbluetoothsocket.cpp
+@@ -142,7 +142,7 @@ void tst_QBluetoothSocket::initTestCase()
+ qDebug() << "Starting discovery";
+
+ sda->setUuidFilter(QBluetoothUuid(QString(TEST_SERVICE_UUID)));
+- sda->start(QBluetoothServiceDiscoveryAgent::MinimalDiscovery);
++ sda->start(QBluetoothServiceDiscoveryAgent::FullDiscovery);
+
+ for (int connectTime = MaxConnectTime; !done_discovery && connectTime > 0; connectTime -= 1000)
+ QTest::qWait(1000);
+Submodule qtdeclarative f5701f0d..8defe7bf:
+diff --git a/qtdeclarative/src/qml/common/qqmljsfixedpoolarray_p.h b/qtdeclarative/src/qml/common/qqmljsfixedpoolarray_p.h
+index b65b994d6c..15a8cd6878 100644
+--- a/qtdeclarative/src/qml/common/qqmljsfixedpoolarray_p.h
++++ b/qtdeclarative/src/qml/common/qqmljsfixedpoolarray_p.h
+@@ -86,7 +86,7 @@ public:
+ if (QTypeInfo<T>::isComplex) {
+ for (int i = 0; i < count; ++i)
+ new (data + i) T(vector.at(i));
+- } else {
++ } else if (count) {
+ memcpy(data, static_cast<const void*>(vector.constData()), count * sizeof(T));
+ }
+ }
+diff --git a/qtdeclarative/src/qml/jsruntime/qv4qobjectwrapper.cpp b/qtdeclarative/src/qml/jsruntime/qv4qobjectwrapper.cpp
+index e57cdd8278..94613598af 100644
+--- a/qtdeclarative/src/qml/jsruntime/qv4qobjectwrapper.cpp
++++ b/qtdeclarative/src/qml/jsruntime/qv4qobjectwrapper.cpp
+@@ -1145,8 +1145,7 @@ void Heap::QObjectWrapper::markObjects(Heap::Base *that, QV4::MarkStack *markSta
+ void QObjectWrapper::destroyObject(bool lastCall)
+ {
+ Heap::QObjectWrapper *h = d();
+- if (!h->internalClass)
+- return; // destroyObject already got called
++ Q_ASSERT(h->internalClass);
+
+ if (h->object()) {
+ QQmlData *ddata = QQmlData::get(h->object(), false);
+@@ -1176,7 +1175,7 @@ void QObjectWrapper::destroyObject(bool lastCall)
+ }
+ }
+
+- h->~Data();
++ h->destroy();
+ }
+
+
+diff --git a/qtdeclarative/src/qml/memory/qv4mm.cpp b/qtdeclarative/src/qml/memory/qv4mm.cpp
+index 06caf04e5a..da149a67c4 100644
+--- a/qtdeclarative/src/qml/memory/qv4mm.cpp
++++ b/qtdeclarative/src/qml/memory/qv4mm.cpp
+@@ -981,7 +981,7 @@ void MemoryManager::sweep(bool lastSweep, ClassDestroyStatsCallback classCountPt
+
+ if (MultiplyWrappedQObjectMap *multiplyWrappedQObjects = engine->m_multiplyWrappedQObjects) {
+ for (MultiplyWrappedQObjectMap::Iterator it = multiplyWrappedQObjects->begin(); it != multiplyWrappedQObjects->end();) {
+- if (!it.value().isNullOrUndefined())
++ if (it.value().isNullOrUndefined())
+ it = multiplyWrappedQObjects->erase(it);
+ else
+ ++it;
+diff --git a/qtdeclarative/src/qmlmodels/qqmldelegatemodel.cpp b/qtdeclarative/src/qmlmodels/qqmldelegatemodel.cpp
+index 2079a8ed04..a577cb2351 100644
+--- a/qtdeclarative/src/qmlmodels/qqmldelegatemodel.cpp
++++ b/qtdeclarative/src/qmlmodels/qqmldelegatemodel.cpp
+@@ -389,6 +389,12 @@ void QQmlDelegateModelPrivate::connectToAbstractItemModel()
+ q, QQmlDelegateModel, SLOT(_q_rowsRemoved(QModelIndex,int,int)));
+ qmlobject_connect(aim, QAbstractItemModel, SIGNAL(rowsAboutToBeRemoved(QModelIndex,int,int)),
+ q, QQmlDelegateModel, SLOT(_q_rowsAboutToBeRemoved(QModelIndex,int,int)));
++ qmlobject_connect(aim, QAbstractItemModel, SIGNAL(columnsInserted(QModelIndex,int,int)),
++ q, QQmlDelegateModel, SLOT(_q_columnsInserted(QModelIndex,int,int)));
++ qmlobject_connect(aim, QAbstractItemModel, SIGNAL(columnsRemoved(QModelIndex,int,int)),
++ q, QQmlDelegateModel, SLOT(_q_columnsRemoved(QModelIndex,int,int)));
++ qmlobject_connect(aim, QAbstractItemModel, SIGNAL(columnsMoved(QModelIndex,int,int,QModelIndex,int)),
++ q, QQmlDelegateModel, SLOT(_q_columnsMoved(QModelIndex,int,int,QModelIndex,int)));
+ qmlobject_connect(aim, QAbstractItemModel, SIGNAL(dataChanged(QModelIndex,QModelIndex,QVector<int>)),
+ q, QQmlDelegateModel, SLOT(_q_dataChanged(QModelIndex,QModelIndex,QVector<int>)));
+ qmlobject_connect(aim, QAbstractItemModel, SIGNAL(rowsMoved(QModelIndex,int,int,QModelIndex,int)),
+@@ -413,6 +419,12 @@ void QQmlDelegateModelPrivate::disconnectFromAbstractItemModel()
+ q, SLOT(_q_rowsAboutToBeRemoved(QModelIndex,int,int)));
+ QObject::disconnect(aim, SIGNAL(rowsRemoved(QModelIndex,int,int)),
+ q, SLOT(_q_rowsRemoved(QModelIndex,int,int)));
++ QObject::disconnect(aim, SIGNAL(columnsInserted(QModelIndex,int,int)), q,
++ SLOT(_q_columnsInserted(QModelIndex,int,int)));
++ QObject::disconnect(aim, SIGNAL(columnsRemoved(QModelIndex,int,int)), q,
++ SLOT(_q_columnsRemoved(QModelIndex,int,int)));
++ QObject::disconnect(aim, SIGNAL(columnsMoved(QModelIndex,int,int,QModelIndex,int)), q,
++ SLOT(_q_columnsMoved(QModelIndex,int,int,QModelIndex,int)));
+ QObject::disconnect(aim, SIGNAL(dataChanged(QModelIndex,QModelIndex,QVector<int>)),
+ q, SLOT(_q_dataChanged(QModelIndex,QModelIndex,QVector<int>)));
+ QObject::disconnect(aim, SIGNAL(rowsMoved(QModelIndex,int,int,QModelIndex,int)),
+@@ -1973,6 +1985,38 @@ void QQmlDelegateModel::_q_rowsMoved(
+ }
+ }
+
++void QQmlDelegateModel::_q_columnsInserted(const QModelIndex &parent, int begin, int end)
++{
++ Q_D(QQmlDelegateModel);
++ Q_UNUSED(end);
++ if (parent == d->m_adaptorModel.rootIndex && begin == 0) {
++ // mark all items as changed
++ _q_itemsChanged(0, d->m_count, QVector<int>());
++ }
++}
++
++void QQmlDelegateModel::_q_columnsRemoved(const QModelIndex &parent, int begin, int end)
++{
++ Q_D(QQmlDelegateModel);
++ Q_UNUSED(end);
++ if (parent == d->m_adaptorModel.rootIndex && begin == 0) {
++ // mark all items as changed
++ _q_itemsChanged(0, d->m_count, QVector<int>());
++ }
++}
++
++void QQmlDelegateModel::_q_columnsMoved(const QModelIndex &parent, int start, int end,
++ const QModelIndex &destination, int column)
++{
++ Q_D(QQmlDelegateModel);
++ Q_UNUSED(end);
++ if ((parent == d->m_adaptorModel.rootIndex && start == 0)
++ || (destination == d->m_adaptorModel.rootIndex && column == 0)) {
++ // mark all items as changed
++ _q_itemsChanged(0, d->m_count, QVector<int>());
++ }
++}
++
+ void QQmlDelegateModel::_q_dataChanged(const QModelIndex &begin, const QModelIndex &end, const QVector<int> &roles)
+ {
+ Q_D(QQmlDelegateModel);
+diff --git a/qtdeclarative/src/qmlmodels/qqmldelegatemodel_p.h b/qtdeclarative/src/qmlmodels/qqmldelegatemodel_p.h
+index 8aab4badca..d140bfbaaf 100644
+--- a/qtdeclarative/src/qmlmodels/qqmldelegatemodel_p.h
++++ b/qtdeclarative/src/qmlmodels/qqmldelegatemodel_p.h
+@@ -152,6 +152,9 @@ private Q_SLOTS:
+ void _q_itemsMoved(int from, int to, int count);
+ void _q_modelReset();
+ void _q_rowsInserted(const QModelIndex &,int,int);
++ void _q_columnsInserted(const QModelIndex &, int, int);
++ void _q_columnsRemoved(const QModelIndex &, int, int);
++ void _q_columnsMoved(const QModelIndex &, int, int, const QModelIndex &, int);
+ void _q_rowsAboutToBeRemoved(const QModelIndex &parent, int begin, int end);
+ void _q_rowsRemoved(const QModelIndex &,int,int);
+ void _q_rowsMoved(const QModelIndex &, int, int, const QModelIndex &, int);
+diff --git a/qtdeclarative/src/quick/accessible/qaccessiblequickitem.cpp b/qtdeclarative/src/quick/accessible/qaccessiblequickitem.cpp
+index 85719fdc80..78e2ab302c 100644
+--- a/qtdeclarative/src/quick/accessible/qaccessiblequickitem.cpp
++++ b/qtdeclarative/src/quick/accessible/qaccessiblequickitem.cpp
+@@ -46,6 +46,7 @@
+ #include "QtQuick/private/qquicktextinput_p.h"
+ #include "QtQuick/private/qquickaccessibleattached_p.h"
+ #include "QtQuick/qquicktextdocument.h"
++#include "QtQuick/qquickrendercontrol.h"
+ QT_BEGIN_NAMESPACE
+
+ #if QT_CONFIG(accessibility)
+@@ -57,7 +58,19 @@ QAccessibleQuickItem::QAccessibleQuickItem(QQuickItem *item)
+
+ QWindow *QAccessibleQuickItem::window() const
+ {
+- return item()->window();
++ QQuickWindow *window = item()->window();
++
++ // For QQuickWidget the above window will be the offscreen QQuickWindow,
++ // which is not a part of the accessibility tree. Detect this case and
++ // return the window for the QQuickWidget instead.
++ if (window && !window->handle()) {
++ if (QQuickRenderControl *renderControl = QQuickWindowPrivate::get(window)->renderControl) {
++ if (QWindow *renderWindow = renderControl->renderWindow(nullptr))
++ return renderWindow;
++ }
++ }
++
++ return window;
+ }
+
+ int QAccessibleQuickItem::childCount() const
+@@ -113,19 +126,15 @@ QAccessibleInterface *QAccessibleQuickItem::childAt(int x, int y) const
+ QAccessibleInterface *QAccessibleQuickItem::parent() const
+ {
+ QQuickItem *parent = item()->parentItem();
+- QQuickWindow *window = item()->window();
+- QQuickItem *ci = window ? window->contentItem() : nullptr;
++ QQuickWindow *itemWindow = item()->window();
++ QQuickItem *ci = itemWindow ? itemWindow->contentItem() : nullptr;
+ while (parent && !QQuickItemPrivate::get(parent)->isAccessible && parent != ci)
+ parent = parent->parentItem();
+
+ if (parent) {
+ if (parent == ci) {
+- // Jump out to the scene widget if the parent is the root item.
+- // There are two root items, QQuickWindow::rootItem and
+- // QQuickView::declarativeRoot. The former is the true root item,
+- // but is not a part of the accessibility tree. Check if we hit
+- // it here and return an interface for the scene instead.
+- return QAccessible::queryAccessibleInterface(window);
++ // Jump out to the window if the parent is the root item
++ return QAccessible::queryAccessibleInterface(window());
+ } else {
+ while (parent && !parent->d_func()->isAccessible)
+ parent = parent->parentItem();
+@@ -188,7 +197,7 @@ QAccessible::State QAccessibleQuickItem::state() const
+ QRect viewRect_ = viewRect();
+ QRect itemRect = rect();
+
+- if (viewRect_.isNull() || itemRect.isNull() || !item()->window() || !item()->window()->isVisible() ||!item()->isVisible() || qFuzzyIsNull(item()->opacity()))
++ if (viewRect_.isNull() || itemRect.isNull() || !window() || !window()->isVisible() ||!item()->isVisible() || qFuzzyIsNull(item()->opacity()))
+ state.invisible = true;
+ if (!viewRect_.intersects(itemRect))
+ state.offscreen = true;
+@@ -201,6 +210,10 @@ QAccessible::State QAccessibleQuickItem::state() const
+ if (role() == QAccessible::EditableText)
+ if (auto ti = qobject_cast<QQuickTextInput *>(item()))
+ state.passwordEdit = ti->echoMode() != QQuickTextInput::Normal;
++ if (!item()->isEnabled()) {
++ state.focusable = false;
++ state.disabled = true;
++ }
+ return state;
+ }
+
+diff --git a/qtdeclarative/src/quick/accessible/qaccessiblequickview_p.h b/qtdeclarative/src/quick/accessible/qaccessiblequickview_p.h
+index 39ffcaf39c..8baa01330c 100644
+--- a/qtdeclarative/src/quick/accessible/qaccessiblequickview_p.h
++++ b/qtdeclarative/src/quick/accessible/qaccessiblequickview_p.h
+@@ -58,7 +58,7 @@ QT_BEGIN_NAMESPACE
+
+ #if QT_CONFIG(accessibility)
+
+-class QAccessibleQuickWindow : public QAccessibleObject
++class Q_QUICK_EXPORT QAccessibleQuickWindow : public QAccessibleObject
+ {
+ public:
+ QAccessibleQuickWindow(QQuickWindow *object);
+diff --git a/qtdeclarative/src/quick/items/qquickdrag.cpp b/qtdeclarative/src/quick/items/qquickdrag.cpp
+index 8321fcfeed..383078b3b9 100644
+--- a/qtdeclarative/src/quick/items/qquickdrag.cpp
++++ b/qtdeclarative/src/quick/items/qquickdrag.cpp
+@@ -481,7 +481,9 @@ void QQuickDragAttached::setKeys(const QStringList &keys)
+ \qmlattachedproperty stringlist QtQuick::Drag::mimeData
+ \since 5.2
+
+- This property holds a map of mimeData that is used during startDrag.
++ This property holds a map from mime type to data that is used during startDrag.
++ The mime data needs to be a \c string, or an \c ArrayBuffer with the data encoded
++ according to the mime type.
+ */
+
+ QVariantMap QQuickDragAttached::mimeData() const
+@@ -766,8 +768,12 @@ Qt::DropAction QQuickDragAttachedPrivate::startDrag(Qt::DropActions supportedAct
+ QDrag *drag = new QDrag(source ? source : q);
+ QMimeData *mimeData = new QMimeData();
+
+- for (auto it = externalMimeData.cbegin(), end = externalMimeData.cend(); it != end; ++it)
+- mimeData->setData(it.key(), it.value().toString().toUtf8());
++ for (auto it = externalMimeData.cbegin(), end = externalMimeData.cend(); it != end; ++it) {
++ if (static_cast<QMetaType::Type>(it.value().type()) == QMetaType::QByteArray)
++ mimeData->setData(it.key(), it.value().toByteArray());
++ else
++ mimeData->setData(it.key(), it.value().toString().toUtf8());
++ }
+
+ drag->setMimeData(mimeData);
+ if (pixmapLoader.isReady()) {
+diff --git a/qtdeclarative/src/quick/items/qquickitem.cpp b/qtdeclarative/src/quick/items/qquickitem.cpp
+index 75f1457816..dec0ae19ae 100644
+--- a/qtdeclarative/src/quick/items/qquickitem.cpp
++++ b/qtdeclarative/src/quick/items/qquickitem.cpp
+@@ -59,6 +59,7 @@
+ #include <QtCore/private/qnumeric_p.h>
+ #include <QtGui/qpa/qplatformtheme.h>
+ #include <QtCore/qloggingcategory.h>
++#include <QtCore/private/qduplicatetracker_p.h>
+
+ #include <private/qqmlglobal_p.h>
+ #include <private/qqmlengine_p.h>
+@@ -2326,6 +2327,7 @@ QQuickItem::QQuickItem(QQuickItemPrivate &dd, QQuickItem *parent)
+ QQuickItem::~QQuickItem()
+ {
+ Q_D(QQuickItem);
++ d->inDestructor = true;
+
+ if (d->windowRefCount > 1)
+ d->windowRefCount = 1; // Make sure window is set to null in next call to derefWindow().
+@@ -2526,6 +2528,7 @@ QQuickItem* QQuickItemPrivate::nextPrevItemInTabFocusChain(QQuickItem *item, boo
+ QQuickItem *current = item;
+ qCDebug(DBG_FOCUS) << "QQuickItemPrivate::nextPrevItemInTabFocusChain: startItem:" << startItem;
+ qCDebug(DBG_FOCUS) << "QQuickItemPrivate::nextPrevItemInTabFocusChain: firstFromItem:" << firstFromItem;
++ QDuplicateTracker<QQuickItem *> cycleDetector;
+ do {
+ qCDebug(DBG_FOCUS) << "QQuickItemPrivate::nextPrevItemInTabFocusChain: current:" << current;
+ qCDebug(DBG_FOCUS) << "QQuickItemPrivate::nextPrevItemInTabFocusChain: from:" << from;
+@@ -2592,7 +2595,10 @@ QQuickItem* QQuickItemPrivate::nextPrevItemInTabFocusChain(QQuickItem *item, boo
+ // traversed all of the chain (by compare the [current] item with [startItem])
+ // Since the [startItem] might be promoted to its parent if it is invisible,
+ // we still have to check [current] item with original start item
+- if ((current == startItem || current == originalStartItem) && from == firstFromItem) {
++ // We might also run into a cycle before we reach firstFromItem again
++ // but note that we have to ignore current if we are meant to skip it
++ if (((current == startItem || current == originalStartItem) && from == firstFromItem) ||
++ (!skip && cycleDetector.hasSeen(current))) {
+ // wrapped around, avoid endless loops
+ if (item == contentItem) {
+ qCDebug(DBG_FOCUS) << "QQuickItemPrivate::nextPrevItemInTabFocusChain: looped, return contentItem";
+@@ -2689,9 +2695,8 @@ void QQuickItem::setParentItem(QQuickItem *parentItem)
+
+ const bool wasVisible = isVisible();
+ op->removeChild(this);
+- if (wasVisible) {
++ if (wasVisible && !op->inDestructor)
+ emit oldParentItem->visibleChildrenChanged();
+- }
+ } else if (d->window) {
+ QQuickWindowPrivate::get(d->window)->parentlessItems.remove(this);
+ }
+@@ -2768,8 +2773,9 @@ void QQuickItem::setParentItem(QQuickItem *parentItem)
+
+ d->itemChange(ItemParentHasChanged, d->parentItem);
+
+- emit parentChanged(d->parentItem);
+- if (isVisible() && d->parentItem)
++ if (!d->inDestructor)
++ emit parentChanged(d->parentItem);
++ if (isVisible() && d->parentItem && !QQuickItemPrivate::get(d->parentItem)->inDestructor)
+ emit d->parentItem->visibleChildrenChanged();
+ }
+
+@@ -2965,7 +2971,8 @@ void QQuickItemPrivate::removeChild(QQuickItem *child)
+
+ itemChange(QQuickItem::ItemChildRemovedChange, child);
+
+- emit q->childrenChanged();
++ if (!inDestructor)
++ emit q->childrenChanged();
+ }
+
+ void QQuickItemPrivate::refWindow(QQuickWindow *c)
+@@ -3194,6 +3201,7 @@ QQuickItemPrivate::QQuickItemPrivate()
+ , touchEnabled(false)
+ #endif
+ , hasCursorHandler(false)
++ , inDestructor(false)
+ , dirtyAttributes(0)
+ , nextDirtyItem(nullptr)
+ , prevDirtyItem(nullptr)
+@@ -5120,6 +5128,13 @@ void QQuickItem::componentComplete()
+ d->addToDirtyList();
+ QQuickWindowPrivate::get(d->window)->dirtyItem(this);
+ }
++
++#if QT_CONFIG(accessibility)
++ if (d->isAccessible && d->effectiveVisible) {
++ QAccessibleEvent ev(this, QAccessible::ObjectShow);
++ QAccessible::updateAccessibility(&ev);
++ }
++#endif
+ }
+
+ QQuickStateGroup *QQuickItemPrivate::_states()
+@@ -6106,9 +6121,11 @@ bool QQuickItemPrivate::setEffectiveVisibleRecur(bool newEffectiveVisible)
+ QAccessible::updateAccessibility(&ev);
+ }
+ #endif
+- emit q->visibleChanged();
+- if (childVisibilityChanged)
+- emit q->visibleChildrenChanged();
++ if (!inDestructor) {
++ emit q->visibleChanged();
++ if (childVisibilityChanged)
++ emit q->visibleChildrenChanged();
++ }
+
+ return true; // effective visibility DID change
+ }
+@@ -6157,6 +6174,15 @@ void QQuickItemPrivate::setEffectiveEnableRecur(QQuickItem *scope, bool newEffec
+ }
+
+ itemChange(QQuickItem::ItemEnabledHasChanged, effectiveEnable);
++#if QT_CONFIG(accessibility)
++ if (isAccessible) {
++ QAccessible::State changedState;
++ changedState.disabled = true;
++ changedState.focusable = true;
++ QAccessibleStateChangeEvent ev(q, changedState);
++ QAccessible::updateAccessibility(&ev);
++ }
++#endif
+ emit q->enabledChanged();
+ }
+
+diff --git a/qtdeclarative/src/quick/items/qquickitem_p.h b/qtdeclarative/src/quick/items/qquickitem_p.h
+index 841d91bb40..ade8fb61f2 100644
+--- a/qtdeclarative/src/quick/items/qquickitem_p.h
++++ b/qtdeclarative/src/quick/items/qquickitem_p.h
+@@ -472,6 +472,7 @@ public:
+ bool replayingPressEvent:1;
+ bool touchEnabled:1;
+ bool hasCursorHandler:1;
++ quint32 inDestructor:1; // has entered ~QQuickItem
+
+ enum DirtyType {
+ TransformOrigin = 0x00000001,
+diff --git a/qtdeclarative/src/quick/items/qquickitemview.cpp b/qtdeclarative/src/quick/items/qquickitemview.cpp
+index 010a0152e1..f8ad168a17 100644
+--- a/qtdeclarative/src/quick/items/qquickitemview.cpp
++++ b/qtdeclarative/src/quick/items/qquickitemview.cpp
+@@ -1785,7 +1785,7 @@ void QQuickItemViewPrivate::refill(qreal from, qreal to)
+
+ do {
+ bufferPause.stop();
+- if (currentChanges.hasPendingChanges() || bufferedChanges.hasPendingChanges()) {
++ if (currentChanges.hasPendingChanges() || bufferedChanges.hasPendingChanges() || currentChanges.active) {
+ currentChanges.reset();
+ bufferedChanges.reset();
+ releaseVisibleItems(reusableFlag);
+diff --git a/qtdeclarative/src/quick/items/qquickmousearea_p_p.h b/qtdeclarative/src/quick/items/qquickmousearea_p_p.h
+index fba383e268..0d63618622 100644
+--- a/qtdeclarative/src/quick/items/qquickmousearea_p_p.h
++++ b/qtdeclarative/src/quick/items/qquickmousearea_p_p.h
+@@ -61,7 +61,6 @@ QT_BEGIN_NAMESPACE
+
+ class QQuickMouseEvent;
+ class QQuickMouseArea;
+-class QQuickPointerMask;
+ class QQuickMouseAreaPrivate : public QQuickItemPrivate
+ {
+ Q_DECLARE_PUBLIC(QQuickMouseArea)
+@@ -100,7 +99,6 @@ public:
+ #if QT_CONFIG(quick_draganddrop)
+ QQuickDrag *drag;
+ #endif
+- QPointer<QQuickPointerMask> mask;
+ QPointF startScene;
+ QPointF targetStartPos;
+ QPointF lastPos;
+diff --git a/qtdeclarative/src/quick/items/qquicktext.cpp b/qtdeclarative/src/quick/items/qquicktext.cpp
+index 6230186933..e823ca1095 100644
+--- a/qtdeclarative/src/quick/items/qquicktext.cpp
++++ b/qtdeclarative/src/quick/items/qquicktext.cpp
+@@ -2168,7 +2168,7 @@ void QQuickText::resetMaximumLineCount()
+ <img src="" align="top,middle,bottom" width="" height=""> - inline images
+ <ol type="">, <ul type=""> and <li> - ordered and unordered lists
+ <pre></pre> - preformatted
+- > < &
++ > < & " '
+ \endcode
+
+ \c Text.StyledText parser is strict, requiring tags to be correctly nested.
+diff --git a/qtdeclarative/src/quick/scenegraph/qsgrhidistancefieldglyphcache.cpp b/qtdeclarative/src/quick/scenegraph/qsgrhidistancefieldglyphcache.cpp
+index eb4db0f85e..2325a2665b 100644
+--- a/qtdeclarative/src/quick/scenegraph/qsgrhidistancefieldglyphcache.cpp
++++ b/qtdeclarative/src/quick/scenegraph/qsgrhidistancefieldglyphcache.cpp
+@@ -446,7 +446,7 @@ bool QSGRhiDistanceFieldGlyphCache::loadPregeneratedCache(const QRawFont &font)
+
+ const char *textureRecord = allocatorData;
+ for (int i = 0; i < textureCount; ++i, textureRecord += Qtdf::TextureRecordSize) {
+- if (textureRecord + Qtdf::TextureRecordSize > qtdfTableEnd) {
++ if (qtdfTableEnd - textureRecord < Qtdf::TextureRecordSize) {
+ qWarning("qtdf table too small in font '%s'.",
+ qPrintable(font.familyName()));
+ return false;
+@@ -462,7 +462,7 @@ bool QSGRhiDistanceFieldGlyphCache::loadPregeneratedCache(const QRawFont &font)
+
+ const char *glyphRecord = textureRecord;
+ for (quint32 i = 0; i < glyphCount; ++i, glyphRecord += Qtdf::GlyphRecordSize) {
+- if (glyphRecord + Qtdf::GlyphRecordSize > qtdfTableEnd) {
++ if (qtdfTableEnd - glyphRecord < Qtdf:: GlyphRecordSize) {
+ qWarning("qtdf table too small in font '%s'.",
+ qPrintable(font.familyName()));
+ return false;
+@@ -512,8 +512,8 @@ bool QSGRhiDistanceFieldGlyphCache::loadPregeneratedCache(const QRawFont &font)
+
+ int width = texInfo->allocatedArea.width();
+ int height = texInfo->allocatedArea.height();
+- qint64 size = width * height;
+- if (reinterpret_cast<const char *>(textureData + size) > qtdfTableEnd) {
++ qint64 size = qint64(width) * height;
++ if (qtdfTableEnd - reinterpret_cast<const char *>(textureData) < size) {
+ qWarning("qtdf table too small in font '%s'.",
+ qPrintable(font.familyName()));
+ return false;
+diff --git a/qtdeclarative/src/quick/util/qquickstyledtext.cpp b/qtdeclarative/src/quick/util/qquickstyledtext.cpp
+index d531fc9205..a25af90414 100644
+--- a/qtdeclarative/src/quick/util/qquickstyledtext.cpp
++++ b/qtdeclarative/src/quick/util/qquickstyledtext.cpp
+@@ -564,6 +564,8 @@ void QQuickStyledTextPrivate::parseEntity(const QChar *&ch, const QString &textI
+ textOut += QChar(60);
+ else if (entity == QLatin1String("amp"))
+ textOut += QChar(38);
++ else if (entity == QLatin1String("apos"))
++ textOut += QChar(39);
+ else if (entity == QLatin1String("quot"))
+ textOut += QChar(34);
+ else if (entity == QLatin1String("nbsp"))
+diff --git a/qtdeclarative/src/quickwidgets/qaccessiblequickwidget.cpp b/qtdeclarative/src/quickwidgets/qaccessiblequickwidget.cpp
+new file mode 100644
+index 0000000000..8a1c901880
+--- /dev/null
++++ b/qtdeclarative/src/quickwidgets/qaccessiblequickwidget.cpp
+@@ -0,0 +1,110 @@
++/****************************************************************************
++**
++** Copyright (C) 2021 The Qt Company Ltd.
++** Contact: https://www.qt.io/licensing/
++**
++** This file is part of the QtQuick module of the Qt Toolkit.
++**
++** $QT_BEGIN_LICENSE:LGPL$
++** Commercial License Usage
++** Licensees holding valid commercial Qt licenses may use this file in
++** accordance with the commercial license agreement provided with the
++** Software or, alternatively, in accordance with the terms contained in
++** a written agreement between you and The Qt Company. For licensing terms
++** and conditions see https://www.qt.io/terms-conditions. For further
++** information use the contact form at https://www.qt.io/contact-us.
++**
++** GNU Lesser General Public License Usage
++** Alternatively, this file may be used under the terms of the GNU Lesser
++** General Public License version 3 as published by the Free Software
++** Foundation and appearing in the file LICENSE.LGPL3 included in the
++** packaging of this file. Please review the following information to
++** ensure the GNU Lesser General Public License version 3 requirements
++** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
++**
++** GNU General Public License Usage
++** Alternatively, this file may be used under the terms of the GNU
++** General Public License version 2.0 or (at your option) the GNU General
++** Public license version 3 or any later version approved by the KDE Free
++** Qt Foundation. The licenses are as published by the Free Software
++** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
++** included in the packaging of this file. Please review the following
++** information to ensure the GNU General Public License requirements will
++** be met: https://www.gnu.org/licenses/gpl-2.0.html and
++** https://www.gnu.org/licenses/gpl-3.0.html.
++**
++** $QT_END_LICENSE$
++**
++****************************************************************************/
++
++#include "qaccessiblequickwidget_p.h"
++
++#include "qquickwidget_p.h"
++
++QT_BEGIN_NAMESPACE
++
++#if QT_CONFIG(accessibility)
++
++QAccessibleQuickWidget::QAccessibleQuickWidget(QQuickWidget* widget)
++: QAccessibleWidget(widget)
++, m_accessibleWindow(QQuickWidgetPrivate::get(widget)->offscreenWindow)
++{
++ // NOTE: m_accessibleWindow is a QAccessibleQuickWindow, and not a
++ // QAccessibleQuickWidgetOffscreenWindow (defined below). This means
++ // it will return the Quick item child interfaces, which is what's needed here
++ // (unlike QAccessibleQuickWidgetOffscreenWindow, which will report 0 children).
++}
++
++QAccessibleInterface *QAccessibleQuickWidget::child(int index) const
++{
++ return m_accessibleWindow.child(index);
++}
++
++int QAccessibleQuickWidget::childCount() const
++{
++ return m_accessibleWindow.childCount();
++}
++
++int QAccessibleQuickWidget::indexOfChild(const QAccessibleInterface *iface) const
++{
++ return m_accessibleWindow.indexOfChild(iface);
++}
++
++QAccessibleInterface *QAccessibleQuickWidget::childAt(int x, int y) const
++{
++ return m_accessibleWindow.childAt(x, y);
++}
++
++QAccessibleQuickWidgetOffscreenWindow::QAccessibleQuickWidgetOffscreenWindow(QQuickWindow *window)
++:QAccessibleQuickWindow(window)
++{
++
++}
++
++QAccessibleInterface *QAccessibleQuickWidgetOffscreenWindow::child(int index) const
++{
++ Q_UNUSED(index);
++ return nullptr;
++}
++
++int QAccessibleQuickWidgetOffscreenWindow::childCount() const
++{
++ return 0;
++}
++
++int QAccessibleQuickWidgetOffscreenWindow::indexOfChild(const QAccessibleInterface *iface) const
++{
++ Q_UNUSED(iface);
++ return -1;
++}
++
++QAccessibleInterface *QAccessibleQuickWidgetOffscreenWindow::QAccessibleQuickWidgetOffscreenWindow::childAt(int x, int y) const
++{
++ Q_UNUSED(x);
++ Q_UNUSED(y);
++ return nullptr;
++}
++
++#endif // accessibility
++
++QT_END_NAMESPACE
+diff --git a/qtdeclarative/src/quickwidgets/qaccessiblequickwidget_p.h b/qtdeclarative/src/quickwidgets/qaccessiblequickwidget_p.h
+new file mode 100644
+index 0000000000..7c2ab930e0
+--- /dev/null
++++ b/qtdeclarative/src/quickwidgets/qaccessiblequickwidget_p.h
+@@ -0,0 +1,95 @@
++/****************************************************************************
++**
++** Copyright (C) 2021 The Qt Company Ltd.
++** Contact: https://www.qt.io/licensing/
++**
++** This file is part of the QtQuick module of the Qt Toolkit.
++**
++** $QT_BEGIN_LICENSE:LGPL$
++** Commercial License Usage
++** Licensees holding valid commercial Qt licenses may use this file in
++** accordance with the commercial license agreement provided with the
++** Software or, alternatively, in accordance with the terms contained in
++** a written agreement between you and The Qt Company. For licensing terms
++** and conditions see https://www.qt.io/terms-conditions. For further
++** information use the contact form at https://www.qt.io/contact-us.
++**
++** GNU Lesser General Public License Usage
++** Alternatively, this file may be used under the terms of the GNU Lesser
++** General Public License version 3 as published by the Free Software
++** Foundation and appearing in the file LICENSE.LGPL3 included in the
++** packaging of this file. Please review the following information to
++** ensure the GNU Lesser General Public License version 3 requirements
++** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
++**
++** GNU General Public License Usage
++** Alternatively, this file may be used under the terms of the GNU
++** General Public License version 2.0 or (at your option) the GNU General
++** Public license version 3 or any later version approved by the KDE Free
++** Qt Foundation. The licenses are as published by the Free Software
++** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
++** included in the packaging of this file. Please review the following
++** information to ensure the GNU General Public License requirements will
++** be met: https://www.gnu.org/licenses/gpl-2.0.html and
++** https://www.gnu.org/licenses/gpl-3.0.html.
++**
++** $QT_END_LICENSE$
++**
++****************************************************************************/
++
++#ifndef QACCESSIBLEQUICKWIDGET_H
++#define QACCESSIBLEQUICKWIDGET_H
++
++//
++// W A R N I N G
++// -------------
++//
++// This file is not part of the Qt API. It exists purely as an
++// implementation detail. This header file may change from version to
++// version without notice, or even be removed.
++//
++// We mean it.
++//
++
++#include "qquickwidget.h"
++#include <QtWidgets/qaccessiblewidget.h>
++
++#include <private/qaccessiblequickview_p.h>
++
++QT_BEGIN_NAMESPACE
++
++#if QT_CONFIG(accessibility)
++
++// These classes implement the QQuickWiget accessibility switcharoo,
++// where the child items of the QQuickWidgetOffscreenWindow are reported
++// as child accessible interfaces of the QAccessibleQuickWidget.
++class QAccessibleQuickWidget: public QAccessibleWidget
++{
++public:
++ QAccessibleQuickWidget(QQuickWidget* widget);
++
++ QAccessibleInterface *child(int index) const override;
++ int childCount() const override;
++ int indexOfChild(const QAccessibleInterface *iface) const override;
++ QAccessibleInterface *childAt(int x, int y) const override;
++
++private:
++ QAccessibleQuickWindow m_accessibleWindow;
++ Q_DISABLE_COPY(QAccessibleQuickWidget)
++};
++
++class QAccessibleQuickWidgetOffscreenWindow: public QAccessibleQuickWindow
++{
++public:
++ QAccessibleQuickWidgetOffscreenWindow(QQuickWindow *window);
++ QAccessibleInterface *child(int index) const override;
++ int childCount() const override;
++ int indexOfChild(const QAccessibleInterface *iface) const override;
++ QAccessibleInterface *childAt(int x, int y) const override;
++};
++
++#endif // accessibility
++
++QT_END_NAMESPACE
++
++#endif
+diff --git a/qtdeclarative/src/quickwidgets/qaccessiblequickwidgetfactory.cpp b/qtdeclarative/src/quickwidgets/qaccessiblequickwidgetfactory.cpp
+new file mode 100644
+index 0000000000..7ba88a1769
+--- /dev/null
++++ b/qtdeclarative/src/quickwidgets/qaccessiblequickwidgetfactory.cpp
+@@ -0,0 +1,60 @@
++/****************************************************************************
++**
++** Copyright (C) 2021 The Qt Company Ltd.
++** Contact: https://www.qt.io/licensing/
++**
++** This file is part of the QtQuick module of the Qt Toolkit.
++**
++** $QT_BEGIN_LICENSE:LGPL$
++** Commercial License Usage
++** Licensees holding valid commercial Qt licenses may use this file in
++** accordance with the commercial license agreement provided with the
++** Software or, alternatively, in accordance with the terms contained in
++** a written agreement between you and The Qt Company. For licensing terms
++** and conditions see https://www.qt.io/terms-conditions. For further
++** information use the contact form at https://www.qt.io/contact-us.
++**
++** GNU Lesser General Public License Usage
++** Alternatively, this file may be used under the terms of the GNU Lesser
++** General Public License version 3 as published by the Free Software
++** Foundation and appearing in the file LICENSE.LGPL3 included in the
++** packaging of this file. Please review the following information to
++** ensure the GNU Lesser General Public License version 3 requirements
++** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
++**
++** GNU General Public License Usage
++** Alternatively, this file may be used under the terms of the GNU
++** General Public License version 2.0 or (at your option) the GNU General
++** Public license version 3 or any later version approved by the KDE Free
++** Qt Foundation. The licenses are as published by the Free Software
++** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
++** included in the packaging of this file. Please review the following
++** information to ensure the GNU General Public License requirements will
++** be met: https://www.gnu.org/licenses/gpl-2.0.html and
++** https://www.gnu.org/licenses/gpl-3.0.html.
++**
++** $QT_END_LICENSE$
++**
++****************************************************************************/
++
++#include "qaccessiblequickwidgetfactory_p.h"
++#include "qaccessiblequickwidget_p.h"
++
++QT_BEGIN_NAMESPACE
++
++#if QT_CONFIG(accessibility)
++
++QAccessibleInterface *qAccessibleQuickWidgetFactory(const QString &classname, QObject *object)
++{
++ if (classname == QLatin1String("QQuickWidget")) {
++ return new QAccessibleQuickWidget(qobject_cast<QQuickWidget *>(object));
++ } else if (classname == QLatin1String("QQuickWidgetOffscreenWindow")) {
++ return new QAccessibleQuickWidgetOffscreenWindow(qobject_cast<QQuickWindow *>(object));
++ }
++ return 0;
++}
++
++#endif // accessibility
++
++QT_END_NAMESPACE
++
+diff --git a/qtdeclarative/src/quickwidgets/qaccessiblequickwidgetfactory_p.h b/qtdeclarative/src/quickwidgets/qaccessiblequickwidgetfactory_p.h
+new file mode 100644
+index 0000000000..8c63b09f81
+--- /dev/null
++++ b/qtdeclarative/src/quickwidgets/qaccessiblequickwidgetfactory_p.h
+@@ -0,0 +1,66 @@
++/****************************************************************************
++**
++** Copyright (C) 2021 The Qt Company Ltd.
++** Contact: https://www.qt.io/licensing/
++**
++** This file is part of the QtQuick module of the Qt Toolkit.
++**
++** $QT_BEGIN_LICENSE:LGPL$
++** Commercial License Usage
++** Licensees holding valid commercial Qt licenses may use this file in
++** accordance with the commercial license agreement provided with the
++** Software or, alternatively, in accordance with the terms contained in
++** a written agreement between you and The Qt Company. For licensing terms
++** and conditions see https://www.qt.io/terms-conditions. For further
++** information use the contact form at https://www.qt.io/contact-us.
++**
++** GNU Lesser General Public License Usage
++** Alternatively, this file may be used under the terms of the GNU Lesser
++** General Public License version 3 as published by the Free Software
++** Foundation and appearing in the file LICENSE.LGPL3 included in the
++** packaging of this file. Please review the following information to
++** ensure the GNU Lesser General Public License version 3 requirements
++** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
++**
++** GNU General Public License Usage
++** Alternatively, this file may be used under the terms of the GNU
++** General Public License version 2.0 or (at your option) the GNU General
++** Public license version 3 or any later version approved by the KDE Free
++** Qt Foundation. The licenses are as published by the Free Software
++** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
++** included in the packaging of this file. Please review the following
++** information to ensure the GNU General Public License requirements will
++** be met: https://www.gnu.org/licenses/gpl-2.0.html and
++** https://www.gnu.org/licenses/gpl-3.0.html.
++**
++** $QT_END_LICENSE$
++**
++****************************************************************************/
++
++#include <QtGui/qaccessible.h>
++
++#ifndef QACCESSIBLEQUICKWIDGETFACTORY_H
++#define QACCESSIBLEQUICKWIDGETFACTORY_H
++
++//
++// W A R N I N G
++// -------------
++//
++// This file is not part of the Qt API. It exists purely as an
++// implementation detail. This header file may change from version to
++// version without notice, or even be removed.
++//
++// We mean it.
++//
++
++QT_BEGIN_NAMESPACE
++
++#if QT_CONFIG(accessibility)
++
++QAccessibleInterface *qAccessibleQuickWidgetFactory(const QString &classname, QObject *object);
++
++#endif
++
++QT_END_NAMESPACE
++
++#endif
+diff --git a/qtdeclarative/src/quickwidgets/qquickwidget.cpp b/qtdeclarative/src/quickwidgets/qquickwidget.cpp
+index 39780f8de3..9c97b43518 100644
+--- a/qtdeclarative/src/quickwidgets/qquickwidget.cpp
++++ b/qtdeclarative/src/quickwidgets/qquickwidget.cpp
+@@ -39,6 +39,7 @@
+
+ #include "qquickwidget.h"
+ #include "qquickwidget_p.h"
++#include "qaccessiblequickwidgetfactory_p.h"
+
+ #include "private/qquickwindow_p.h"
+ #include "private/qquickitem_p.h"
+@@ -75,9 +76,16 @@
+
+ QT_BEGIN_NAMESPACE
+
++QQuickWidgetOffscreenWindow::QQuickWidgetOffscreenWindow(QQuickWindowPrivate &dd, QQuickRenderControl *control)
++:QQuickWindow(dd, control)
++{
++ setTitle(QString::fromLatin1("Offscreen"));
++ setObjectName(QString::fromLatin1("QQuickOffScreenWindow"));
++}
++
+ // override setVisble to prevent accidental offscreen window being created
+ // by base class.
+-class QQuickOffcreenWindowPrivate: public QQuickWindowPrivate {
++class QQuickWidgetOffscreenWindowPrivate: public QQuickWindowPrivate {
+ public:
+ void setVisible(bool visible) override {
+ Q_Q(QWindow);
+@@ -105,9 +113,8 @@ void QQuickWidgetPrivate::init(QQmlEngine* e)
+ Q_Q(QQuickWidget);
+
+ renderControl = new QQuickWidgetRenderControl(q);
+- offscreenWindow = new QQuickWindow(*new QQuickOffcreenWindowPrivate(),renderControl);
+- offscreenWindow->setTitle(QString::fromLatin1("Offscreen"));
+- offscreenWindow->setObjectName(QString::fromLatin1("QQuickOffScreenWindow"));
++ offscreenWindow = new QQuickWidgetOffscreenWindow(*new QQuickWidgetOffscreenWindowPrivate(), renderControl);
++ offscreenWindow->setScreen(q->screen());
+ // Do not call create() on offscreenWindow.
+
+ // Check if the Software Adaptation is being used
+@@ -138,6 +145,10 @@ void QQuickWidgetPrivate::init(QQmlEngine* e)
+ QWidget::connect(offscreenWindow, &QQuickWindow::focusObjectChanged, q, &QQuickWidget::propagateFocusObjectChanged);
+ QObject::connect(renderControl, SIGNAL(renderRequested()), q, SLOT(triggerUpdate()));
+ QObject::connect(renderControl, SIGNAL(sceneChanged()), q, SLOT(triggerUpdate()));
++
++#if QT_CONFIG(accessibility)
++ QAccessible::installFactory(&qAccessibleQuickWidgetFactory);
++#endif
+ }
+
+ void QQuickWidgetPrivate::ensureEngine() const
+@@ -901,9 +912,7 @@ void QQuickWidgetPrivate::createContext()
+
+ context = new QOpenGLContext;
+ context->setFormat(offscreenWindow->requestedFormat());
+- const QWindow *win = q->window()->windowHandle();
+- if (win && win->screen())
+- context->setScreen(win->screen());
++ context->setScreen(q->screen());
+ QOpenGLContext *shareContext = qt_gl_global_share_context();
+ if (!shareContext)
+ shareContext = QWidgetPrivate::get(q->window())->shareContext();
+@@ -1520,19 +1529,16 @@ bool QQuickWidget::event(QEvent *e)
+ d->handleWindowChange();
+ break;
+
+- case QEvent::ScreenChangeInternal:
+- if (QWindow *window = this->window()->windowHandle()) {
+- QScreen *newScreen = window->screen();
+-
+- if (d->offscreenWindow)
+- d->offscreenWindow->setScreen(newScreen);
+- if (d->offscreenSurface)
+- d->offscreenSurface->setScreen(newScreen);
++ case QEvent::ScreenChangeInternal: {
++ QScreen *newScreen = screen();
++ if (d->offscreenWindow)
++ d->offscreenWindow->setScreen(newScreen);
++ if (d->offscreenSurface)
++ d->offscreenSurface->setScreen(newScreen);
+ #if QT_CONFIG(opengl)
+- if (d->context)
+- d->context->setScreen(newScreen);
++ if (d->context)
++ d->context->setScreen(newScreen);
+ #endif
+- }
+
+ if (d->useSoftwareRenderer
+ #if QT_CONFIG(opengl)
+@@ -1545,7 +1551,7 @@ bool QQuickWidget::event(QEvent *e)
+ d->render(true);
+ }
+ break;
+-
++ }
+ case QEvent::Show:
+ case QEvent::Move:
+ d->updatePosition();
+diff --git a/qtdeclarative/src/quickwidgets/qquickwidget_p.h b/qtdeclarative/src/quickwidgets/qquickwidget_p.h
+index 881f7f9220..1a946bcc71 100644
+--- a/qtdeclarative/src/quickwidgets/qquickwidget_p.h
++++ b/qtdeclarative/src/quickwidgets/qquickwidget_p.h
+@@ -148,6 +148,14 @@ public:
+ bool forceFullUpdate;
+ };
+
++class QQuickWidgetOffscreenWindow: public QQuickWindow
++{
++ Q_OBJECT
++
++public:
++ QQuickWidgetOffscreenWindow(QQuickWindowPrivate &dd, QQuickRenderControl *control);
++};
++
+ QT_END_NAMESPACE
+
+ #endif // QQuickWidget_P_H
+diff --git a/qtdeclarative/src/quickwidgets/quickwidgets.pro b/qtdeclarative/src/quickwidgets/quickwidgets.pro
+index 2438e577ae..85d156b8a3 100644
+--- a/qtdeclarative/src/quickwidgets/quickwidgets.pro
++++ b/qtdeclarative/src/quickwidgets/quickwidgets.pro
+@@ -7,9 +7,13 @@ DEFINES += QT_NO_URL_CAST_FROM_STRING QT_NO_INTEGER_EVENT_COORDINATES QT_NO_FO
+ HEADERS += \
+ qquickwidget.h \
+ qquickwidget_p.h \
+- qtquickwidgetsglobal.h
++ qtquickwidgetsglobal.h \
++ qaccessiblequickwidget_p.h \
++ qaccessiblequickwidgetfactory_p.h
+
+ SOURCES += \
+- qquickwidget.cpp
++ qquickwidget.cpp \
++ qaccessiblequickwidget.cpp \
++ qaccessiblequickwidgetfactory.cpp
+
+ load(qt_module)
+diff --git a/qtdeclarative/tests/auto/qml/qjsengine/tst_qjsengine.cpp b/qtdeclarative/tests/auto/qml/qjsengine/tst_qjsengine.cpp
+index 3b7d74df63..b75bf820d5 100644
+--- a/qtdeclarative/tests/auto/qml/qjsengine/tst_qjsengine.cpp
++++ b/qtdeclarative/tests/auto/qml/qjsengine/tst_qjsengine.cpp
+@@ -102,6 +102,7 @@ private slots:
+ void valueConversion_RegularExpression();
+ void castWithMultipleInheritance();
+ void collectGarbage();
++ void collectGarbageNestedWrappersTwoEngines();
+ void gcWithNestedDataStructure();
+ void stacktrace();
+ void numberParsing_data();
+@@ -1809,6 +1810,44 @@ void tst_QJSEngine::collectGarbage()
+ QVERIFY(ptr.isNull());
+ }
+
++class TestObjectContainer : public QObject
++{
++ Q_OBJECT
++ Q_PROPERTY(QObject *dummy MEMBER m_dummy CONSTANT)
++
++public:
++ TestObjectContainer() : m_dummy(new QObject(this)) {}
++
++private:
++ QObject *m_dummy;
++};
++
++void tst_QJSEngine::collectGarbageNestedWrappersTwoEngines()
++{
++ QJSEngine engine1;
++ QJSEngine engine2;
++
++ TestObjectContainer container;
++ QQmlEngine::setObjectOwnership(&container, QQmlEngine::CppOwnership);
++
++ engine1.globalObject().setProperty("foobar", engine1.newQObject(&container));
++ engine2.globalObject().setProperty("foobar", engine2.newQObject(&container));
++
++ engine1.evaluate("foobar.dummy.baz = 42");
++ engine2.evaluate("foobar.dummy.baz = 43");
++
++ QCOMPARE(engine1.evaluate("foobar.dummy.baz").toInt(), 42);
++ QCOMPARE(engine2.evaluate("foobar.dummy.baz").toInt(), 43);
++
++ engine1.collectGarbage();
++ engine2.collectGarbage();
++
++ // The GC should not collect dummy object wrappers neither in engine1 nor engine2, we
++ // verify that by checking whether the baz property still has its previous value.
++ QCOMPARE(engine1.evaluate("foobar.dummy.baz").toInt(), 42);
++ QCOMPARE(engine2.evaluate("foobar.dummy.baz").toInt(), 43);
++}
++
+ void tst_QJSEngine::gcWithNestedDataStructure()
+ {
+ // The GC must be able to traverse deeply nested objects, otherwise this
+diff --git a/qtdeclarative/tests/auto/qml/qqmldelegatemodel/data/redrawUponColumnChange.qml b/qtdeclarative/tests/auto/qml/qqmldelegatemodel/data/redrawUponColumnChange.qml
+new file mode 100644
+index 0000000000..206133bb39
+--- /dev/null
++++ b/qtdeclarative/tests/auto/qml/qqmldelegatemodel/data/redrawUponColumnChange.qml
+@@ -0,0 +1,11 @@
++import QtQuick 2.8
++
++ListView {
++ id: root
++ width: 200
++ height: 200
++
++ delegate: Text {
++ text: display
++ }
++}
+diff --git a/qtdeclarative/tests/auto/qml/qqmldelegatemodel/tst_qqmldelegatemodel.cpp b/qtdeclarative/tests/auto/qml/qqmldelegatemodel/tst_qqmldelegatemodel.cpp
+index 35f1e2c94d..1722447830 100644
+--- a/qtdeclarative/tests/auto/qml/qqmldelegatemodel/tst_qqmldelegatemodel.cpp
++++ b/qtdeclarative/tests/auto/qml/qqmldelegatemodel/tst_qqmldelegatemodel.cpp
+@@ -27,6 +27,8 @@
+ ****************************************************************************/
+
+ #include <QtTest/qtest.h>
++#include <QtCore/QConcatenateTablesProxyModel>
++#include <QtGui/QStandardItemModel>
+ #include <QtQml/qqmlcomponent.h>
+ #include <QtQmlModels/private/qqmldelegatemodel_p.h>
+ #include <QtQuick/qquickview.h>
+@@ -47,6 +49,7 @@ private slots:
+ void filterOnGroup_removeWhenCompleted();
+ void qtbug_86017();
+ void contextAccessedByHandler();
++ void redrawUponColumnChange();
+ };
+
+ class AbstractItemModel : public QAbstractItemModel
+@@ -186,6 +189,30 @@ void tst_QQmlDelegateModel::contextAccessedByHandler()
+ QVERIFY(root->property("works").toBool());
+ }
+
++void tst_QQmlDelegateModel::redrawUponColumnChange()
++{
++ QStandardItemModel m1;
++ m1.appendRow({
++ new QStandardItem("Banana"),
++ new QStandardItem("Coconut"),
++ });
++
++ QQuickView view(testFileUrl("redrawUponColumnChange.qml"));
++ QCOMPARE(view.status(), QQuickView::Ready);
++ view.show();
++ QQuickItem *root = view.rootObject();
++ root->setProperty("model", QVariant::fromValue<QObject *>(&m1));
++
++ QObject *item = root->property("currentItem").value<QObject *>();
++ QVERIFY(item);
++ QCOMPARE(item->property("text").toString(), "Banana");
++
++ QVERIFY(root);
++ m1.removeColumn(0);
++
++ QCOMPARE(item->property("text").toString(), "Coconut");
++}
++
+ QTEST_MAIN(tst_QQmlDelegateModel)
+
+ #include "tst_qqmldelegatemodel.moc"
+diff --git a/qtdeclarative/tests/auto/qml/qv4mm/tst_qv4mm.cpp b/qtdeclarative/tests/auto/qml/qv4mm/tst_qv4mm.cpp
+index 5d635aa63b..824fd89e5b 100644
+--- a/qtdeclarative/tests/auto/qml/qv4mm/tst_qv4mm.cpp
++++ b/qtdeclarative/tests/auto/qml/qv4mm/tst_qv4mm.cpp
+@@ -76,10 +76,10 @@ void tst_qv4mm::multiWrappedQObjects()
+ QCOMPARE(engine1.memoryManager->m_pendingFreedObjectWrapperValue.size(), 1);
+ QCOMPARE(engine2.memoryManager->m_pendingFreedObjectWrapperValue.size(), 0);
+
+- // Moves the additional WeakValue from m_multiplyWrappedQObjects to
+- // m_pendingFreedObjectWrapperValue. It's still alive after all.
++ // The additional WeakValue from m_multiplyWrappedQObjects hasn't been moved
++ // to m_pendingFreedObjectWrapperValue yet. It's still alive after all.
+ engine1.memoryManager->runGC();
+- QCOMPARE(engine1.memoryManager->m_pendingFreedObjectWrapperValue.size(), 2);
++ QCOMPARE(engine1.memoryManager->m_pendingFreedObjectWrapperValue.size(), 1);
+
+ // engine2 doesn't own the object as engine1 was the first to wrap it above.
+ // Therefore, no effect here.
+diff --git a/qtdeclarative/tests/auto/quick/qquickitem2/data/activeFocusOnTab_infiniteLoop3.qml b/qtdeclarative/tests/auto/quick/qquickitem2/data/activeFocusOnTab_infiniteLoop3.qml
+new file mode 100644
+index 0000000000..889e480f3b
+--- /dev/null
++++ b/qtdeclarative/tests/auto/quick/qquickitem2/data/activeFocusOnTab_infiniteLoop3.qml
+@@ -0,0 +1,13 @@
++import QtQuick 2.6
++
++Item {
++ visible: true
++ Item {
++ visible: false
++ Item {
++ objectName: "hiddenChild"
++ activeFocusOnTab: true
++ focus: true
++ }
++ }
++}
+diff --git a/qtdeclarative/tests/auto/quick/qquickitem2/tst_qquickitem.cpp b/qtdeclarative/tests/auto/quick/qquickitem2/tst_qquickitem.cpp
+index c8f251dbe1..c8ef36ee68 100644
+--- a/qtdeclarative/tests/auto/quick/qquickitem2/tst_qquickitem.cpp
++++ b/qtdeclarative/tests/auto/quick/qquickitem2/tst_qquickitem.cpp
+@@ -67,6 +67,7 @@ private slots:
+ void activeFocusOnTab10();
+ void activeFocusOnTab_infiniteLoop_data();
+ void activeFocusOnTab_infiniteLoop();
++ void activeFocusOnTab_infiniteLoopControls();
+
+ void nextItemInFocusChain();
+ void nextItemInFocusChain2();
+@@ -1057,6 +1058,17 @@ void tst_QQuickItem::activeFocusOnTab_infiniteLoop()
+ QCOMPARE(item, window->rootObject());
+ }
+
++
++void tst_QQuickItem::activeFocusOnTab_infiniteLoopControls()
++{
++ auto source = testFileUrl("activeFocusOnTab_infiniteLoop3.qml");
++ QScopedPointer<QQuickView>window(new QQuickView());
++ window->setSource(source);
++ window->show();
++ QVERIFY(window->errors().isEmpty());
++ QTest::keyClick(window.get(), Qt::Key_Tab); // should not hang
++}
++
+ void tst_QQuickItem::nextItemInFocusChain()
+ {
+ if (!qt_tab_all_widgets())
+Submodule qtdoc c0c7bf07...79d6ef69:
+Submodule qtimageformats 2dcf2899..abe44c0f:
+diff --git a/qtimageformats/src/plugins/imageformats/icns/qicnshandler.cpp b/qtimageformats/src/plugins/imageformats/icns/qicnshandler.cpp
+index dde783c..1bf9074 100644
+--- a/qtimageformats/src/plugins/imageformats/icns/qicnshandler.cpp
++++ b/qtimageformats/src/plugins/imageformats/icns/qicnshandler.cpp
+@@ -462,8 +462,12 @@ static bool parseIconEntryInfo(ICNSEntry &icon)
+ if (isIconCompressed(icon))
+ return true;
+ // Icon depth:
+- if (!depth.isEmpty())
+- icon.depth = ICNSEntry::Depth(depth.toUInt());
++ if (!depth.isEmpty()) {
++ const uint depthUInt = depth.toUInt();
++ if (depthUInt > 32)
++ return false;
++ icon.depth = ICNSEntry::Depth(depthUInt);
++ }
+ // Try mono if depth not found
+ if (icon.depth == ICNSEntry::DepthUnknown)
+ icon.depth = ICNSEntry::DepthMono;
+@@ -515,6 +519,9 @@ static bool parseIconEntryInfo(ICNSEntry &icon)
+ }
+ icon.height = icon.width;
+ }
++ // Sanity check
++ if (icon.width == 0 || icon.width > 4096)
++ return false;
+ return true;
+ }
+
+@@ -685,7 +692,7 @@ bool QICNSHandler::canRead() const
+ bool QICNSHandler::read(QImage *outImage)
+ {
+ QImage img;
+- if (!ensureScanned()) {
++ if (!ensureScanned() || m_currentIconIndex >= m_icons.size()) {
+ qWarning("QICNSHandler::read(): The device wasn't parsed properly!");
+ return false;
+ }
+@@ -892,7 +899,7 @@ bool QICNSHandler::scanDevice()
+ return false;
+
+ const qint64 blockDataOffset = device()->pos();
+- if (!isBlockHeaderValid(blockHeader)) {
++ if (!isBlockHeaderValid(blockHeader, ICNSBlockHeaderSize + filelength - blockDataOffset)) {
+ qWarning("QICNSHandler::scanDevice(): Failed, bad header at pos %s. OSType \"%s\", length %u",
+ QByteArray::number(blockDataOffset).constData(),
+ nameFromOSType(blockHeader.ostype).constData(), blockHeader.length);
+@@ -927,11 +934,14 @@ bool QICNSHandler::scanDevice()
+ case ICNSBlockHeader::TypeOdrp:
+ // Icns container seems to have an embedded icon variant container
+ // Let's start a scan for entries
+- while (device()->pos() < nextBlockOffset) {
++ while (!stream.atEnd() && device()->pos() < nextBlockOffset) {
+ ICNSBlockHeader icon;
+ stream >> icon;
++ if (stream.status() != QDataStream::Ok)
++ return false;
+ // Check for incorrect variant entry header and stop scan
+- if (!isBlockHeaderValid(icon, blockDataLength))
++ quint64 remaining = blockDataLength - (device()->pos() - blockDataOffset);
++ if (!isBlockHeaderValid(icon, ICNSBlockHeaderSize + remaining))
+ break;
+ if (!addEntry(icon, device()->pos(), blockHeader.ostype))
+ return false;
+@@ -1003,7 +1013,7 @@ bool QICNSHandler::scanDevice()
+ break;
+ }
+ }
+- return true;
++ return (m_icons.size() > 0);
+ }
+
+ const ICNSEntry &QICNSHandler::getIconMask(const ICNSEntry &icon) const
+diff --git a/qtimageformats/src/plugins/imageformats/jp2/qjp2handler.cpp b/qtimageformats/src/plugins/imageformats/jp2/qjp2handler.cpp
+index 5082023..cb34374 100644
+--- a/qtimageformats/src/plugins/imageformats/jp2/qjp2handler.cpp
++++ b/qtimageformats/src/plugins/imageformats/jp2/qjp2handler.cpp
+@@ -43,6 +43,7 @@
+ #include "qimage.h"
+ #include "qvariant.h"
+ #include "qcolor.h"
++#include "qimagereader.h"
+
+ #include <jasper/jasper.h>
+ #include <math.h> // for pow
+@@ -333,16 +334,46 @@ private:
+ Jpeg2000JasperReader::Jpeg2000JasperReader(QIODevice *iod, SubFormat format)
+ : jasperOk(true), ioDevice(iod), format(format), hasAlpha(false)
+ {
++#if JAS_VERSION_MAJOR < 3
+ if (jas_init()) {
+ jasperOk = false;
+ qDebug("Jasper Library initialization failed");
+ }
++#else
++ jas_conf_clear();
++#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
++ jas_conf_set_max_mem_usage(QImageReader::allocationLimit() * 1024 * 1024);
++#else
++ // 128MB seems to be enough.
++ jas_conf_set_max_mem_usage(128 * 1024 * 1024);
++#endif
++ if (jas_init_library()) {
++ jasperOk = false;
++ qDebug("Jasper library initialization failed");
++ }
++ if (jas_init_thread()) {
++ jas_cleanup_library();
++ jasperOk = false;
++ qDebug("Jasper thread initialization failed");
++ }
++#endif
+ }
+
+ Jpeg2000JasperReader::~Jpeg2000JasperReader()
+ {
++#if JAS_VERSION_MAJOR < 3
+ if (jasperOk)
+ jas_cleanup();
++#else
++ if (jasperOk) {
++ if (jas_cleanup_thread()) {
++ qDebug("Jasper thread cleanup failed");
++ }
++ if (jas_cleanup_library()) {
++ qDebug("Jasper library cleanup failed");
++ }
++ }
++#endif
+ }
+
+ /*! \internal
+@@ -857,7 +888,7 @@ bool Jpeg2000JasperReader::write(const QImage &image, int quality)
+ }
+
+ // Open an empty jasper stream that grows automatically
+- jas_stream_t * memory_stream = jas_stream_memopen(0, -1);
++ jas_stream_t * memory_stream = jas_stream_memopen(0, 0);
+
+ // Jasper wants a non-const string.
+ char *str = qstrdup(jasperFormatString.toLatin1().constData());
+diff --git a/qtimageformats/src/plugins/imageformats/tiff/qtiffhandler.cpp b/qtimageformats/src/plugins/imageformats/tiff/qtiffhandler.cpp
+index 1386750..ac8956c 100644
+--- a/qtimageformats/src/plugins/imageformats/tiff/qtiffhandler.cpp
++++ b/qtimageformats/src/plugins/imageformats/tiff/qtiffhandler.cpp
+@@ -361,6 +361,8 @@ bool QTiffHandler::read(QImage *image)
+ }
+
+ TIFF *const tiff = d->tiff;
++ if (TIFFIsTiled(tiff) && TIFFTileSize64(tiff) > uint64_t(image->sizeInBytes())) // Corrupt image
++ return false;
+ const quint32 width = d->size.width();
+ const quint32 height = d->size.height();
+
+diff --git a/qtimageformats/src/plugins/imageformats/webp/qwebphandler.cpp b/qtimageformats/src/plugins/imageformats/webp/qwebphandler.cpp
+index 82d38cb..d02eb05 100644
+--- a/qtimageformats/src/plugins/imageformats/webp/qwebphandler.cpp
++++ b/qtimageformats/src/plugins/imageformats/webp/qwebphandler.cpp
+@@ -45,6 +45,7 @@
+ #include <qdebug.h>
+ #include <qpainter.h>
+ #include <qvariant.h>
++#include <QtEndian>
+
+ static const int riffHeaderSize = 12; // RIFF_HEADER_SIZE from webp/format_constants.h
+
+@@ -102,21 +103,23 @@ bool QWebpHandler::ensureScanned() const
+
+ m_scanState = ScanError;
+
+- if (device()->isSequential()) {
+- qWarning() << "Sequential devices are not supported";
++ QWebpHandler *that = const_cast<QWebpHandler *>(this);
++ const int headerBytesNeeded = sizeof(WebPBitstreamFeatures);
++ QByteArray header = device()->peek(headerBytesNeeded);
++ if (header.size() < headerBytesNeeded)
+ return false;
+- }
+
+- qint64 oldPos = device()->pos();
+- device()->seek(0);
+-
+- QWebpHandler *that = const_cast<QWebpHandler *>(this);
+- QByteArray header = device()->peek(sizeof(WebPBitstreamFeatures));
++ // We do no random access during decoding, just a readAll() of the whole image file. So if
++ // if it is all available already, we can accept a sequential device. The riff header contains
++ // the file size minus 8 bytes header
++ qint64 byteSize = qFromLittleEndian<quint32>(header.constData() + 4);
++ if (device()->isSequential() && device()->bytesAvailable() < byteSize + 8) {
++ qWarning() << "QWebpHandler: Insufficient data available in sequential device";
++ return false;
++ }
+ if (WebPGetFeatures((const uint8_t*)header.constData(), header.size(), &(that->m_features)) == VP8_STATUS_OK) {
+ if (m_features.has_animation) {
+ // For animation, we have to read and scan whole file to determine loop count and images count
+- device()->seek(oldPos);
+-
+ if (that->ensureDemuxer()) {
+ that->m_loop = WebPDemuxGetI(m_demuxer, WEBP_FF_LOOP_COUNT);
+ that->m_frameCount = WebPDemuxGetI(m_demuxer, WEBP_FF_FRAME_COUNT);
+@@ -126,17 +129,13 @@ bool QWebpHandler::ensureScanned() const
+ if (that->m_features.has_alpha)
+ that->m_composited->fill(Qt::transparent);
+
+- // We do not reset device position since we have read in all data
+ m_scanState = ScanSuccess;
+- return true;
+ }
+ } else {
+ m_scanState = ScanSuccess;
+ }
+ }
+
+- device()->seek(oldPos);
+-
+ return m_scanState == ScanSuccess;
+ }
+
+@@ -159,7 +158,7 @@ bool QWebpHandler::ensureDemuxer()
+
+ bool QWebpHandler::read(QImage *image)
+ {
+- if (!ensureScanned() || device()->isSequential() || !ensureDemuxer())
++ if (!ensureScanned() || !ensureDemuxer())
+ return false;
+
+ QRect prevFrameRect;
+Submodule qtlocation 98a5c511..f991e28c:
+diff --git a/qtlocation/src/location/configure.json b/qtlocation/src/location/configure.json
+index 6d01a9a3..d1e623a1 100644
+--- a/qtlocation/src/location/configure.json
++++ b/qtlocation/src/location/configure.json
+@@ -9,7 +9,7 @@
+ "label": "Qt.labs.location experimental QML plugin",
+ "purpose": "Provides experimental QtLocation QML types",
+ "section": "Location",
+- "condition": "config.opengl",
++ "condition": "features.opengl",
+ "output": [ "privateFeature" ]
+ },
+ "geoservices_osm": {
+diff --git a/qtlocation/src/location/labs/qsg/qgeomapobjectqsgsupport.cpp b/qtlocation/src/location/labs/qsg/qgeomapobjectqsgsupport.cpp
+index a978573d..11e1466f 100644
+--- a/qtlocation/src/location/labs/qsg/qgeomapobjectqsgsupport.cpp
++++ b/qtlocation/src/location/labs/qsg/qgeomapobjectqsgsupport.cpp
+@@ -158,7 +158,7 @@ void QGeoMapObjectQSGSupport::updateMapObjects(QSGNode *root, QQuickWindow *wind
+ if (!root)
+ return;
+
+- if (m_mapObjectsRootNode && m_mapObjectsRootNode->parent())
++ if (m_mapObjectsRootNode && !m_mapObjectsRootNode->parent())
+ root->appendChildNode(m_mapObjectsRootNode.get());
+
+ if (!m_mapObjectsRootNode) {
+diff --git a/qtlocation/src/plugins/geoservices/esri/geocodingmanagerengine_esri.cpp b/qtlocation/src/plugins/geoservices/esri/geocodingmanagerengine_esri.cpp
+index 5a40467e..d123c6a8 100644
+--- a/qtlocation/src/plugins/geoservices/esri/geocodingmanagerengine_esri.cpp
++++ b/qtlocation/src/plugins/geoservices/esri/geocodingmanagerengine_esri.cpp
+@@ -59,8 +59,10 @@ QT_BEGIN_NAMESPACE
+ static const QString kPrefixEsri(QStringLiteral("esri."));
+ static const QString kParamUserAgent(kPrefixEsri + QStringLiteral("useragent"));
+
+-static const QString kUrlGeocode(QStringLiteral("http://geocode.arcgis.com/arcgis/rest/services/World/GeocodeServer/findAddressCandidates"));
+-static const QString kUrlReverseGeocode(QStringLiteral("http://geocode.arcgis.com/arcgis/rest/services/World/GeocodeServer/reverseGeocode"));
++static const QString kUrlGeocode(QStringLiteral("https://geocode.arcgis.com/arcgis/rest/services/"
++ "World/GeocodeServer/findAddressCandidates"));
++static const QString kUrlReverseGeocode(QStringLiteral(
++ "https://geocode.arcgis.com/arcgis/rest/services/World/GeocodeServer/reverseGeocode"));
+
+ static QString addressToQuery(const QGeoAddress &address)
+ {
+diff --git a/qtlocation/src/plugins/geoservices/esri/georoutejsonparser_esri.cpp b/qtlocation/src/plugins/geoservices/esri/georoutejsonparser_esri.cpp
+index 17492d94..96c12b1b 100644
+--- a/qtlocation/src/plugins/geoservices/esri/georoutejsonparser_esri.cpp
++++ b/qtlocation/src/plugins/geoservices/esri/georoutejsonparser_esri.cpp
+@@ -46,7 +46,8 @@
+
+ QT_BEGIN_NAMESPACE
+
+-// JSON reference: http://resources.arcgis.com/en/help/arcgis-rest-api/#/Route_service_with_synchronous_execution/02r300000036000000/
++// JSON reference:
++// https://resources.arcgis.com/en/help/arcgis-rest-api/#/Route_service_with_synchronous_execution/02r300000036000000/
+
+ static const QString kErrorMessage(QStringLiteral("Error %1: %2."));
+ static const QString kErrorJson(QStringLiteral("Error: invalide JSON document."));
+diff --git a/qtlocation/src/plugins/geoservices/esri/georoutereply_esri.cpp b/qtlocation/src/plugins/geoservices/esri/georoutereply_esri.cpp
+index 8cadfb29..92b6bb13 100644
+--- a/qtlocation/src/plugins/geoservices/esri/georoutereply_esri.cpp
++++ b/qtlocation/src/plugins/geoservices/esri/georoutereply_esri.cpp
+@@ -44,7 +44,8 @@
+
+ QT_BEGIN_NAMESPACE
+
+-// JSON reference: http://resources.arcgis.com/en/help/arcgis-rest-api/#/Route_service_with_synchronous_execution/02r300000036000000/
++// JSON reference:
++// https://resources.arcgis.com/en/help/arcgis-rest-api/#/Route_service_with_synchronous_execution/02r300000036000000/
+
+ GeoRouteReplyEsri::GeoRouteReplyEsri(QNetworkReply *reply, const QGeoRouteRequest &request,
+ QObject *parent) :
+diff --git a/qtlocation/src/plugins/geoservices/esri/georoutingmanagerengine_esri.cpp b/qtlocation/src/plugins/geoservices/esri/georoutingmanagerengine_esri.cpp
+index 0e6bc2c7..ed613f4b 100644
+--- a/qtlocation/src/plugins/geoservices/esri/georoutingmanagerengine_esri.cpp
++++ b/qtlocation/src/plugins/geoservices/esri/georoutingmanagerengine_esri.cpp
+@@ -48,7 +48,8 @@ static const QString kPrefixEsri(QStringLiteral("esri."));
+ static const QString kParamUserAgent(kPrefixEsri + QStringLiteral("useragent"));
+ static const QString kParamToken(kPrefixEsri + QStringLiteral("token"));
+
+-static const QString kUrlRouting(QStringLiteral("http://route.arcgis.com/arcgis/rest/services/World/Route/NAServer/Route_World/solve"));
++static const QString kUrlRouting(QStringLiteral(
++ "https://route.arcgis.com/arcgis/rest/services/World/Route/NAServer/Route_World/solve"));
+
+ GeoRoutingManagerEngineEsri::GeoRoutingManagerEngineEsri(const QVariantMap ¶meters,
+ QGeoServiceProvider::Error *error,
+@@ -70,7 +71,8 @@ GeoRoutingManagerEngineEsri::~GeoRoutingManagerEngineEsri()
+ {
+ }
+
+-// REST reference: http://resources.arcgis.com/en/help/arcgis-rest-api/index.html#//02r300000036000000
++// REST reference:
++// https://resources.arcgis.com/en/help/arcgis-rest-api/index.html#//02r300000036000000
+
+ QGeoRouteReply *GeoRoutingManagerEngineEsri::calculateRoute(const QGeoRouteRequest &request)
+ {
+@@ -125,7 +127,7 @@ void GeoRoutingManagerEngineEsri::replyError(QGeoRouteReply::Error errorCode, co
+ QString GeoRoutingManagerEngineEsri::preferedDirectionLangage()
+ {
+ // list of supported langages is defined in:
+- // http://resources.arcgis.com/en/help/arcgis-rest-api/index.html#//02r300000036000000
++ // https://resources.arcgis.com/en/help/arcgis-rest-api/index.html#//02r300000036000000
+ const QStringList supportedLanguages = {
+ "ar", // Generate directions in Arabic
+ "cs", // Generate directions in Czech
+diff --git a/qtlocation/src/plugins/geoservices/esri/geotiledmappingmanagerengine_esri.cpp b/qtlocation/src/plugins/geoservices/esri/geotiledmappingmanagerengine_esri.cpp
+index 5d15835d..24148f95 100644
+--- a/qtlocation/src/plugins/geoservices/esri/geotiledmappingmanagerengine_esri.cpp
++++ b/qtlocation/src/plugins/geoservices/esri/geotiledmappingmanagerengine_esri.cpp
+@@ -230,7 +230,8 @@ QGeoMap *GeoTiledMappingManagerEngineEsri::createMap()
+ // ${y} = Y
+ // ${token} = Token
+
+-// template = 'http://services.arcgisonline.com/ArcGIS/rest/services/World_Topo_Map/MapServer/tile/{{z}}/{{y}}/{{x}}.png'
++// template =
++// 'https://services.arcgisonline.com/ArcGIS/rest/services/World_Topo_Map/MapServer/tile/{{z}}/{{y}}/{{x}}.png'
+
+ bool GeoTiledMappingManagerEngineEsri::initializeMapSources(QGeoServiceProvider::Error *error,
+ QString *errorString,
+diff --git a/qtlocation/src/plugins/geoservices/esri/maps.json b/qtlocation/src/plugins/geoservices/esri/maps.json
+index 8167ae7d..862e087d 100644
+--- a/qtlocation/src/plugins/geoservices/esri/maps.json
++++ b/qtlocation/src/plugins/geoservices/esri/maps.json
+@@ -6,8 +6,8 @@
+ "description": "ArcGIS Online World Street Map",
+ "mobile": true,
+ "night": false,
+- "url": "http://services.arcgisonline.com/ArcGIS/rest/services/World_Street_Map/MapServer",
+- "copyrightText": "© <a href='http://www.arcgis.com/home/item.html?id=3b93337983e9436f8db950e38a8629af'>Esri</a> contributors"
++ "url": "https://services.arcgisonline.com/ArcGIS/rest/services/World_Street_Map/MapServer",
++ "copyrightText": "© <a href='https://www.arcgis.com/home/item.html?id=3b93337983e9436f8db950e38a8629af'>Esri</a> contributors"
+ },
+
+ {
+@@ -16,8 +16,8 @@
+ "": "ArcGIS Online World Imagery",
+ "mobile": true,
+ "night": false,
+- "url": "http://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer",
+- "copyrightText": "© <a href='http://www.arcgis.com/home/item.html?id=10df2279f9684e4a9f6a7f08febac2a9'>Esri</a> contributors"
++ "url": "https://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer",
++ "copyrightText": "© <a href='https://www.arcgis.com/home/item.html?id=10df2279f9684e4a9f6a7f08febac2a9'>Esri</a> contributors"
+ },
+
+ {
+@@ -26,8 +26,8 @@
+ "description": "ArcGIS Online World Terrain Base",
+ "mobile": false,
+ "night": false,
+- "url": "http://server.arcgisonline.com/ArcGIS/rest/services/World_Terrain_Base/MapServer",
+- "copyrightText": "© <a href='http://www.arcgis.com/home/item.html?id=c61ad8ab017d49e1a82f580ee1298931'>Esri</a> contributors"
++ "url": "https://server.arcgisonline.com/ArcGIS/rest/services/World_Terrain_Base/MapServer",
++ "copyrightText": "© <a href='https://www.arcgis.com/home/item.html?id=c61ad8ab017d49e1a82f580ee1298931'>Esri</a> contributors"
+ },
+
+ {
+@@ -36,8 +36,8 @@
+ "description": "ArcGIS Online World Topography",
+ "mobile": true,
+ "night": false,
+- "url": "http://server.arcgisonline.com/ArcGIS/rest/services/World_Topo_Map/MapServer",
+- "copyrightText": "© <a href='http://www.arcgis.com/home/item.html?id=30e5fe3149c34df1ba922e6f5bbf808f'>Esri</a> contributors"
++ "url": "https://server.arcgisonline.com/ArcGIS/rest/services/World_Topo_Map/MapServer",
++ "copyrightText": "© <a href='https://www.arcgis.com/home/item.html?id=30e5fe3149c34df1ba922e6f5bbf808f'>Esri</a> contributors"
+ },
+
+ {
+@@ -46,8 +46,8 @@
+ "description": "This map presents land cover and detailed topographic maps for the United States.",
+ "mobile": true,
+ "night": false,
+- "url": "http://services.arcgisonline.com/ArcGIS/rest/services/USA_Topo_Maps/MapServer",
+- "copyrightText": "© <a href='http://www.arcgis.com/home/item.html?id=99cd5fbd98934028802b4f797c4b1732'>Esri</a> contributors"
++ "url": "https://services.arcgisonline.com/ArcGIS/rest/services/USA_Topo_Maps/MapServer",
++ "copyrightText": "© <a href='https://www.arcgis.com/home/item.html?id=99cd5fbd98934028802b4f797c4b1732'>Esri</a> contributors"
+ },
+
+ {
+@@ -56,8 +56,8 @@
+ "description": "National Geographic World Map",
+ "mobile": false,
+ "night": false,
+- "url": "http://services.arcgisonline.com/ArcGIS/rest/services/NatGeo_World_Map/MapServer",
+- "copyrightText": "© <a href='http://www.arcgis.com/home/item.html?id=b9b1b422198944fbbd5250b3241691b6'>Esri</a> contributors"
++ "url": "https://services.arcgisonline.com/ArcGIS/rest/services/NatGeo_World_Map/MapServer",
++ "copyrightText": "© <a href='https://www.arcgis.com/home/item.html?id=b9b1b422198944fbbd5250b3241691b6'>Esri</a> contributors"
+ },
+
+ {
+@@ -66,8 +66,8 @@
+ "description": "Thematic content providing a neutral background with minimal colors",
+ "mobile": true,
+ "night": false,
+- "url": "http://services.arcgisonline.com/ArcGIS/rest/services/Canvas/World_Light_Gray_Base/MapServer",
+- "copyrightText": "© <a href='http://www.arcgis.com/home/item.html?id=ed712cb1db3e4bae9e85329040fb9a49'>Esri</a> contributors"
++ "url": "https://services.arcgisonline.com/ArcGIS/rest/services/Canvas/World_Light_Gray_Base/MapServer",
++ "copyrightText": "© <a href='https://www.arcgis.com/home/item.html?id=ed712cb1db3e4bae9e85329040fb9a49'>Esri</a> contributors"
+ },
+
+ {
+@@ -76,8 +76,8 @@
+ "description": "Natural Earth physical map for the world",
+ "mobile": false,
+ "night": false,
+- "url": "http://server.arcgisonline.com/ArcGIS/rest/services/World_Physical_Map/MapServer",
+- "copyrightText": "© <a href='http://www.arcgis.com/home/item.html?id=c4ec722a1cd34cf0a23904aadf8923a0'>Esri</a> contributors"
++ "url": "https://server.arcgisonline.com/ArcGIS/rest/services/World_Physical_Map/MapServer",
++ "copyrightText": "© <a href='https://www.arcgis.com/home/item.html?id=c4ec722a1cd34cf0a23904aadf8923a0'>Esri</a> contributors"
+ },
+
+ {
+@@ -86,8 +86,8 @@
+ "description": "Portrays surface elevation as shaded relief",
+ "mobile": false,
+ "night": false,
+- "url": "http://server.arcgisonline.com/ArcGIS/rest/services/World_Shaded_Relief/MapServer",
+- "copyrightText": "© <a href='http://www.arcgis.com/home/item.html?id=9c5370d0b54f4de1b48a3792d7377ff2'>Esri</a> contributors"
++ "url": "https://server.arcgisonline.com/ArcGIS/rest/services/World_Shaded_Relief/MapServer",
++ "copyrightText": "© <a href='https://www.arcgis.com/home/item.html?id=9c5370d0b54f4de1b48a3792d7377ff2'>Esri</a> contributors"
+ },
+
+ {
+@@ -96,8 +96,8 @@
+ "description": "This map is designed to be used as a basemap by marine GIS professionals and as a reference map by anyone interested in ocean data",
+ "mobile": false,
+ "night": false,
+- "url": "http://server.arcgisonline.com/arcgis/rest/services/Ocean/World_Ocean_Base/MapServer",
+- "copyrightText": "© <a href='http://www.arcgis.com/home/item.html?id=1e126e7520f9466c9ca28b8f28b5e500'>Esri</a> contributors"
++ "url": "https://server.arcgisonline.com/arcgis/rest/services/Ocean/World_Ocean_Base/MapServer",
++ "copyrightText": "© <a href='https://www.arcgis.com/home/item.html?id=1e126e7520f9466c9ca28b8f28b5e500'>Esri</a> contributors"
+ },
+
+ {
+@@ -106,8 +106,8 @@
+ "description": "Thematic content providing a neutral background with minimal colors",
+ "mobile": false,
+ "night": true,
+- "url": "http://services.arcgisonline.com/ArcGIS/rest/services/Canvas/World_Dark_Gray_Base/MapServer",
+- "copyrightText": "© <a href='http://www.arcgis.com/home/item.html?id=a284a9b99b3446a3910d4144a50990f6'>Esri</a> contributors"
++ "url": "https://services.arcgisonline.com/ArcGIS/rest/services/Canvas/World_Dark_Gray_Base/MapServer",
++ "copyrightText": "© <a href='https://www.arcgis.com/home/item.html?id=a284a9b99b3446a3910d4144a50990f6'>Esri</a> contributors"
+ },
+
+ {
+@@ -116,8 +116,8 @@
+ "description": "DeLorme’s topographic basemap is a seamless global data set that portrays transportation, hydrography, jurisdiction boundaries, and major geographic features",
+ "mobile": false,
+ "night": false,
+- "url": "http://server.arcgisonline.com/ArcGIS/rest/services/Specialty/DeLorme_World_Base_Map/MapServer",
+- "copyrightText": "© <a href='http://www.arcgis.com/home/item.html?id=b165c3df453e4be6b5ac4fdb241effbe'>Esri</a> contributors"
++ "url": "https://server.arcgisonline.com/ArcGIS/rest/services/Specialty/DeLorme_World_Base_Map/MapServer",
++ "copyrightText": "© <a href='https://www.arcgis.com/home/item.html?id=b165c3df453e4be6b5ac4fdb241effbe'>Esri</a> contributors"
+ }
+ ]
+ }
+diff --git a/qtlocation/src/plugins/geoservices/esri/placemanagerengine_esri.cpp b/qtlocation/src/plugins/geoservices/esri/placemanagerengine_esri.cpp
+index 3858ddf5..af66f28e 100644
+--- a/qtlocation/src/plugins/geoservices/esri/placemanagerengine_esri.cpp
++++ b/qtlocation/src/plugins/geoservices/esri/placemanagerengine_esri.cpp
+@@ -63,8 +63,10 @@ static const QString kCountriesKey(QStringLiteral("detailedCountries"));
+ static const QString kLocalizedNamesKey(QStringLiteral("localizedNames"));
+ static const QString kMaxLocationsKey(QStringLiteral("maxLocations"));
+
+-static const QUrl kUrlGeocodeServer("http://geocode.arcgis.com/arcgis/rest/services/World/GeocodeServer?f=pjson");
+-static const QUrl kUrlFindAddressCandidates("http://geocode.arcgis.com/arcgis/rest/services/World/GeocodeServer/findAddressCandidates");
++static const QUrl kUrlGeocodeServer(
++ "https://geocode.arcgis.com/arcgis/rest/services/World/GeocodeServer?f=pjson");
++static const QUrl kUrlFindAddressCandidates("https://geocode.arcgis.com/arcgis/rest/services/World/"
++ "GeocodeServer/findAddressCandidates");
+
+ PlaceManagerEngineEsri::PlaceManagerEngineEsri(const QVariantMap ¶meters, QGeoServiceProvider::Error *error,
+ QString *errorString) :
+Submodule qtmultimedia f0344079..0d7cc33a:
+diff --git a/qtmultimedia/src/plugins/pulseaudio/qaudioinput_pulse.cpp b/qtmultimedia/src/plugins/pulseaudio/qaudioinput_pulse.cpp
+index 2b5325132..b68b4af1b 100644
+--- a/qtmultimedia/src/plugins/pulseaudio/qaudioinput_pulse.cpp
++++ b/qtmultimedia/src/plugins/pulseaudio/qaudioinput_pulse.cpp
+@@ -402,6 +402,8 @@ int QPulseAudioInput::bytesReady() const
+
+ qint64 QPulseAudioInput::read(char *data, qint64 len)
+ {
++ Q_ASSERT(data != nullptr || len == 0);
++
+ m_bytesAvailable = checkBytesReady();
+
+ setError(QAudio::NoError);
+@@ -411,7 +413,8 @@ qint64 QPulseAudioInput::read(char *data, qint64 len)
+
+ if (!m_pullMode && !m_tempBuffer.isEmpty()) {
+ readBytes = qMin(static_cast<int>(len), m_tempBuffer.size());
+- memcpy(data, m_tempBuffer.constData(), readBytes);
++ if (readBytes)
++ memcpy(data, m_tempBuffer.constData(), readBytes);
+ m_totalTimeValue += readBytes;
+
+ if (readBytes < m_tempBuffer.size()) {
+@@ -502,9 +505,10 @@ qint64 QPulseAudioInput::read(char *data, qint64 len)
+
+ void QPulseAudioInput::applyVolume(const void *src, void *dest, int len)
+ {
++ Q_ASSERT((src && dest) || len == 0);
+ if (m_volume < 1.f)
+ QAudioHelperInternal::qMultiplySamples(m_volume, m_format, src, dest, len);
+- else
++ else if (len)
+ memcpy(dest, src, len);
+ }
+
+Submodule qtpim 02efef5e...f9a8f0fc (commits not present)
+Submodule qtquick3d b85cf622..47defc8b:
+diff --git a/qtquick3d/src/plugins/assetimporters/assimp/assimp.pro b/qtquick3d/src/plugins/assetimporters/assimp/assimp.pro
+index ca5c499e..174a075b 100644
+--- a/qtquick3d/src/plugins/assetimporters/assimp/assimp.pro
++++ b/qtquick3d/src/plugins/assetimporters/assimp/assimp.pro
+@@ -10,7 +10,7 @@ QT_FOR_CONFIG += assetimporters-private
+ include($$OUT_PWD/../qtassetimporters-config.pri)
+
+ qtConfig(system-assimp):!if(cross_compile:host_build) {
+- QMAKE_USE_PRIVATE += assimp
++ QMAKE_USE_PRIVATE += quick3d-assimp
+ } else {
+ include(../../../3rdparty/assimp/assimp.pri)
+ }
+Submodule qtquickcontrols2 3a657dc0..56ce8233:
+diff --git a/qtquickcontrols2/src/imports/platform/widgets/qwidgetplatformmenu.cpp b/qtquickcontrols2/src/imports/platform/widgets/qwidgetplatformmenu.cpp
+index e5fe734f7..e36922775 100644
+--- a/qtquickcontrols2/src/imports/platform/widgets/qwidgetplatformmenu.cpp
++++ b/qtquickcontrols2/src/imports/platform/widgets/qwidgetplatformmenu.cpp
+@@ -38,6 +38,7 @@
+ #include "qwidgetplatformmenuitem_p.h"
+
+ #include <QtGui/qwindow.h>
++#include <QtGui/private/qhighdpiscaling_p.h>
+ #include <QtWidgets/qmenu.h>
+ #include <QtWidgets/qaction.h>
+
+@@ -145,7 +146,7 @@ void QWidgetPlatformMenu::showPopup(const QWindow *window, const QRect &targetRe
+
+ QPoint targetPos = targetRect.bottomLeft();
+ if (window)
+- targetPos = window->mapToGlobal(targetPos);
++ targetPos = window->mapToGlobal(QHighDpi::fromNativeLocalPosition(targetPos, window));
+
+ const QWidgetPlatformMenuItem *widgetItem = qobject_cast<const QWidgetPlatformMenuItem *>(item);
+ m_menu->popup(targetPos, widgetItem ? widgetItem->action() : nullptr);
+diff --git a/qtquickcontrols2/src/quicktemplates2/qquickabstractbutton.cpp b/qtquickcontrols2/src/quicktemplates2/qquickabstractbutton.cpp
+index 950e4e099..b81fbea0b 100644
+--- a/qtquickcontrols2/src/quicktemplates2/qquickabstractbutton.cpp
++++ b/qtquickcontrols2/src/quicktemplates2/qquickabstractbutton.cpp
+@@ -387,6 +387,17 @@ void QQuickAbstractButtonPrivate::itemImplicitHeightChanged(QQuickItem *item)
+ emit q->implicitIndicatorHeightChanged();
+ }
+
++void QQuickAbstractButtonPrivate::itemDestroyed(QQuickItem *item)
++{
++ Q_Q(QQuickAbstractButton);
++ QQuickControlPrivate::itemDestroyed(item);
++ if (item == indicator) {
++ indicator = nullptr;
++ emit q->implicitIndicatorWidthChanged();
++ emit q->implicitIndicatorHeightChanged();
++ }
++}
++
+ QQuickAbstractButton *QQuickAbstractButtonPrivate::findCheckedButton() const
+ {
+ Q_Q(const QQuickAbstractButton);
+@@ -1176,6 +1187,12 @@ QAccessible::Role QQuickAbstractButton::accessibleRole() const
+ }
+ return QAccessible::Button;
+ }
++
++void QQuickAbstractButton::accessiblePressAction()
++{
++ Q_D(QQuickAbstractButton);
++ d->trigger();
++}
+ #endif
+
+ QT_END_NAMESPACE
+diff --git a/qtquickcontrols2/src/quicktemplates2/qquickabstractbutton_p.h b/qtquickcontrols2/src/quicktemplates2/qquickabstractbutton_p.h
+index 0fa48980e..ab66220d0 100644
+--- a/qtquickcontrols2/src/quicktemplates2/qquickabstractbutton_p.h
++++ b/qtquickcontrols2/src/quicktemplates2/qquickabstractbutton_p.h
+@@ -209,6 +209,7 @@ protected:
+ #if QT_CONFIG(accessibility)
+ void accessibilityActiveChanged(bool active) override;
+ QAccessible::Role accessibleRole() const override;
++ Q_INVOKABLE void accessiblePressAction();
+ #endif
+
+ private:
+diff --git a/qtquickcontrols2/src/quicktemplates2/qquickabstractbutton_p_p.h b/qtquickcontrols2/src/quicktemplates2/qquickabstractbutton_p_p.h
+index 9291c1a87..b729720f2 100644
+--- a/qtquickcontrols2/src/quicktemplates2/qquickabstractbutton_p_p.h
++++ b/qtquickcontrols2/src/quicktemplates2/qquickabstractbutton_p_p.h
+@@ -109,6 +109,7 @@ public:
+
+ void itemImplicitWidthChanged(QQuickItem *item) override;
+ void itemImplicitHeightChanged(QQuickItem *item) override;
++ void itemDestroyed(QQuickItem *item) override;
+
+ // copied from qabstractbutton.cpp
+ static const int AUTO_REPEAT_DELAY = 300;
+diff --git a/qtquickcontrols2/src/quicktemplates2/qquickaction.cpp b/qtquickcontrols2/src/quicktemplates2/qquickaction.cpp
+index 2041e7741..8610cdfae 100644
+--- a/qtquickcontrols2/src/quicktemplates2/qquickaction.cpp
++++ b/qtquickcontrols2/src/quicktemplates2/qquickaction.cpp
+@@ -145,7 +145,7 @@ int QQuickActionPrivate::ShortcutEntry::shortcutId() const
+
+ void QQuickActionPrivate::ShortcutEntry::grab(const QKeySequence &shortcut, bool enabled)
+ {
+- if (shortcut.isEmpty())
++ if (shortcut.isEmpty() || m_shortcutId)
+ return;
+
+ Qt::ShortcutContext context = Qt::WindowShortcut; // TODO
+diff --git a/qtquickcontrols2/src/quicktemplates2/qquickcontainer.cpp b/qtquickcontrols2/src/quicktemplates2/qquickcontainer.cpp
+index f38c2b09c..6eed2a024 100644
+--- a/qtquickcontrols2/src/quicktemplates2/qquickcontainer.cpp
++++ b/qtquickcontrols2/src/quicktemplates2/qquickcontainer.cpp
+@@ -225,6 +225,7 @@ void QQuickContainerPrivate::cleanup()
+ QObject::disconnect(contentModel, &QQmlObjectModel::countChanged, q, &QQuickContainer::countChanged);
+ QObject::disconnect(contentModel, &QQmlObjectModel::childrenChanged, q, &QQuickContainer::contentChildrenChanged);
+ delete contentModel;
++ contentModel = nullptr;
+ }
+
+ QQuickItem *QQuickContainerPrivate::itemAt(int index) const
+@@ -436,7 +437,7 @@ void QQuickContainerPrivate::contentChildren_clear(QQmlListProperty<QQuickItem>
+ void QQuickContainerPrivate::updateContentWidth()
+ {
+ Q_Q(QQuickContainer);
+- if (hasContentWidth || qFuzzyCompare(contentWidth, implicitContentWidth))
++ if (hasContentWidth || qFuzzyCompare(contentWidth, implicitContentWidth) || !contentModel)
+ return;
+
+ contentWidth = implicitContentWidth;
+@@ -446,7 +447,7 @@ void QQuickContainerPrivate::updateContentWidth()
+ void QQuickContainerPrivate::updateContentHeight()
+ {
+ Q_Q(QQuickContainer);
+- if (hasContentHeight || qFuzzyCompare(contentHeight, implicitContentHeight))
++ if (hasContentHeight || qFuzzyCompare(contentHeight, implicitContentHeight) || !contentModel)
+ return;
+
+ contentHeight = implicitContentHeight;
+diff --git a/qtquickcontrols2/src/quicktemplates2/qquickcontrol.cpp b/qtquickcontrols2/src/quicktemplates2/qquickcontrol.cpp
+index bbbd0e622..1f4b47343 100644
+--- a/qtquickcontrols2/src/quicktemplates2/qquickcontrol.cpp
++++ b/qtquickcontrols2/src/quicktemplates2/qquickcontrol.cpp
+@@ -845,6 +845,13 @@ void QQuickControlPrivate::executeBackground(bool complete)
+ quickCompleteDeferred(q, backgroundName(), background);
+ }
+
++/*
++ \internal
++
++ Hides an item that was replaced by a newer one, rather than
++ deleting it, as the item is typically created in QML and hence
++ we don't own it.
++*/
+ void QQuickControlPrivate::hideOldItem(QQuickItem *item)
+ {
+ if (!item)
+@@ -863,6 +870,29 @@ void QQuickControlPrivate::hideOldItem(QQuickItem *item)
+ #endif
+ }
+
++/*
++ \internal
++
++ Named "unhide" because it's used for cases where an item
++ that was previously hidden by \l hideOldItem() wants to be
++ shown by a control again, such as a ScrollBar in ScrollView.
++*/
++void QQuickControlPrivate::unhideOldItem(QQuickControl *control, QQuickItem *item)
++{
++ Q_ASSERT(item);
++ qCDebug(lcItemManagement) << "unhiding old item" << item;
++
++ item->setVisible(true);
++ item->setParentItem(control);
++
++#if QT_CONFIG(accessibility)
++ // Add the item back in to the accessibility tree.
++ QQuickAccessibleAttached *accessible = accessibleAttached(item);
++ if (accessible)
++ accessible->setIgnored(false);
++#endif
++}
++
+ void QQuickControlPrivate::updateBaselineOffset()
+ {
+ Q_Q(QQuickControl);
+diff --git a/qtquickcontrols2/src/quicktemplates2/qquickcontrol_p_p.h b/qtquickcontrols2/src/quicktemplates2/qquickcontrol_p_p.h
+index 8e979079e..a6e624c91 100644
+--- a/qtquickcontrols2/src/quicktemplates2/qquickcontrol_p_p.h
++++ b/qtquickcontrols2/src/quicktemplates2/qquickcontrol_p_p.h
+@@ -173,6 +173,7 @@ public:
+ virtual void executeBackground(bool complete = false);
+
+ static void hideOldItem(QQuickItem *item);
++ static void unhideOldItem(QQuickControl *control, QQuickItem *item);
+
+ void updateBaselineOffset();
+
+diff --git a/qtquickcontrols2/src/quicktemplates2/qquickdialogbuttonbox.cpp b/qtquickcontrols2/src/quicktemplates2/qquickdialogbuttonbox.cpp
+index e6db14eb5..6197d1547 100644
+--- a/qtquickcontrols2/src/quicktemplates2/qquickdialogbuttonbox.cpp
++++ b/qtquickcontrols2/src/quicktemplates2/qquickdialogbuttonbox.cpp
+@@ -237,7 +237,7 @@ static QRectF alignedRect(Qt::LayoutDirection direction, Qt::Alignment alignment
+ void QQuickDialogButtonBoxPrivate::resizeContent()
+ {
+ Q_Q(QQuickDialogButtonBox);
+- if (!contentItem)
++ if (!contentItem || !contentModel)
+ return;
+
+ QRectF geometry = q->boundingRect().adjusted(q->leftPadding(), q->topPadding(), -q->rightPadding(), -q->bottomPadding());
+@@ -322,6 +322,9 @@ void QQuickDialogButtonBoxPrivate::updateLayout()
+ qreal QQuickDialogButtonBoxPrivate::getContentWidth() const
+ {
+ Q_Q(const QQuickDialogButtonBox);
++ if (!contentModel)
++ return 0;
++
+ const int count = contentModel->count();
+ const qreal totalSpacing = qMax(0, count - 1) * spacing;
+ qreal totalWidth = totalSpacing;
+@@ -341,6 +344,9 @@ qreal QQuickDialogButtonBoxPrivate::getContentWidth() const
+ qreal QQuickDialogButtonBoxPrivate::getContentHeight() const
+ {
+ Q_Q(const QQuickDialogButtonBox);
++ if (!contentModel)
++ return 0;
++
+ const int count = contentModel->count();
+ qreal maxHeight = 0;
+ for (int i = 0; i < count; ++i) {
+diff --git a/qtquickcontrols2/src/quicktemplates2/qquickoverlay.cpp b/qtquickcontrols2/src/quicktemplates2/qquickoverlay.cpp
+index 91bd59184..0ce518f84 100644
+--- a/qtquickcontrols2/src/quicktemplates2/qquickoverlay.cpp
++++ b/qtquickcontrols2/src/quicktemplates2/qquickoverlay.cpp
+@@ -399,8 +399,11 @@ void QQuickOverlay::itemChange(ItemChange change, const ItemChangeData &data)
+ Q_D(QQuickOverlay);
+ QQuickItem::itemChange(change, data);
+
+- if (change == ItemChildAddedChange || change == ItemChildRemovedChange)
++ if (change == ItemChildAddedChange || change == ItemChildRemovedChange) {
+ setVisible(!d->allDrawers.isEmpty() || !childItems().isEmpty());
++ if (data.item->parent() == d->mouseGrabberPopup)
++ d->setMouseGrabberPopup(nullptr);
++ }
+ }
+
+ void QQuickOverlay::geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry)
+diff --git a/qtquickcontrols2/src/quicktemplates2/qquickscrollbar.cpp b/qtquickcontrols2/src/quicktemplates2/qquickscrollbar.cpp
+index 4e2f509db..1c4b308cd 100644
+--- a/qtquickcontrols2/src/quicktemplates2/qquickscrollbar.cpp
++++ b/qtquickcontrols2/src/quicktemplates2/qquickscrollbar.cpp
+@@ -797,6 +797,14 @@ void QQuickScrollBarAttachedPrivate::initHorizontal()
+ if (parent && parent == flickable->parentItem())
+ horizontal->stackAfter(flickable);
+
++ // If a scroll bar was previously hidden (due to e.g. setting a new contentItem
++ // on a ScrollView), we need to make sure that we un-hide it.
++ // We don't bother checking if the item is actually the old one, because
++ // if it's not, all of the things the function does (setting parent, visibility, etc.)
++ // should be no-ops anyway.
++ if (auto control = qobject_cast<QQuickControl*>(q_ptr->parent()))
++ QQuickControlPrivate::unhideOldItem(control, horizontal);
++
+ layoutHorizontal();
+ horizontal->setSize(area->property("widthRatio").toReal());
+ horizontal->setPosition(area->property("xPosition").toReal());
+@@ -818,6 +826,9 @@ void QQuickScrollBarAttachedPrivate::initVertical()
+ if (parent && parent == flickable->parentItem())
+ vertical->stackAfter(flickable);
+
++ if (auto control = qobject_cast<QQuickControl*>(q_ptr->parent()))
++ QQuickControlPrivate::unhideOldItem(control, vertical);
++
+ layoutVertical();
+ vertical->setSize(area->property("heightRatio").toReal());
+ vertical->setPosition(area->property("yPosition").toReal());
+diff --git a/qtquickcontrols2/tests/auto/controls/data/tst_scrollview.qml b/qtquickcontrols2/tests/auto/controls/data/tst_scrollview.qml
+index 0e8b08352..cd4931184 100644
+--- a/qtquickcontrols2/tests/auto/controls/data/tst_scrollview.qml
++++ b/qtquickcontrols2/tests/auto/controls/data/tst_scrollview.qml
+@@ -576,4 +576,51 @@ TestCase {
+ verify(newHorizontalScrollBar.visible)
+ verify(!oldHorizontalScrollBar.visible)
+ }
++
++ Component {
++ id: bindingToContentItemAndStandaloneFlickable
++
++ Item {
++ width: 200
++ height: 200
++
++ property alias scrollView: scrollView
++
++ ScrollView {
++ id: scrollView
++ anchors.fill: parent
++ contentItem: listView
++
++ property Item someBinding: contentItem
++ }
++ ListView {
++ id: listView
++ model: 10
++ delegate: ItemDelegate {
++ text: modelData
++ width: listView.width
++ }
++ }
++ }
++ }
++
++ // Tests that scroll bars show up for a ScrollView where
++ // - its contentItem is declared as a standalone, separate item
++ // - there is a binding to contentItem (which causes a default Flickable to be created)
++ function test_bindingToContentItemAndStandaloneFlickable() {
++ let root = createTemporaryObject(bindingToContentItemAndStandaloneFlickable, testCase)
++ verify(root)
++
++ let control = root.scrollView
++ let verticalScrollBar = control.ScrollBar.vertical
++ let horizontalScrollBar = control.ScrollBar.horizontal
++ compare(verticalScrollBar.parent, control)
++ compare(horizontalScrollBar.parent, control)
++ verify(verticalScrollBar.visible)
++ verify(horizontalScrollBar.visible)
++
++ mouseDrag(verticalScrollBar, verticalScrollBar.width / 2, verticalScrollBar.height / 2, 0, 50)
++ verify(verticalScrollBar.active)
++ verify(horizontalScrollBar.active)
++ }
+ }
+diff --git a/qtquickcontrols2/tests/auto/controls/data/tst_switch.qml b/qtquickcontrols2/tests/auto/controls/data/tst_switch.qml
+index b3fab41ca..10b6baa02 100644
+--- a/qtquickcontrols2/tests/auto/controls/data/tst_switch.qml
++++ b/qtquickcontrols2/tests/auto/controls/data/tst_switch.qml
+@@ -608,4 +608,27 @@ TestCase {
+ mouseClick(control.indicator)
+ verify(control.activeFocus)
+ }
++
++ Component {
++ id: deletionOrder1
++ Item {
++ Image { id: innerImage }
++ Switch { indicator: innerImage }
++ }
++ }
++
++ Component {
++ id: deletionOrder2
++ Item {
++ Switch { indicator: innerImage }
++ Image { id: innerImage }
++ }
++ }
++
++ function test_deletionOrder() {
++ var control1 = createTemporaryObject(deletionOrder1, testCase)
++ verify(control1)
++ var control2 = createTemporaryObject(deletionOrder2, testCase)
++ verify(control2)
++ }
+ }
+diff --git a/qtquickcontrols2/tests/auto/qquickpopup/data/releaseAfterExitTransition.qml b/qtquickcontrols2/tests/auto/qquickpopup/data/releaseAfterExitTransition.qml
+new file mode 100644
+index 000000000..9e4598b9f
+--- /dev/null
++++ b/qtquickcontrols2/tests/auto/qquickpopup/data/releaseAfterExitTransition.qml
+@@ -0,0 +1,78 @@
++/****************************************************************************
++**
++** Copyright (C) 2021 The Qt Company Ltd.
++** Contact: https://www.qt.io/licensing/
++**
++** This file is part of the test suite of the Qt Toolkit.
++**
++** $QT_BEGIN_LICENSE:BSD$
++** Commercial License Usage
++** Licensees holding valid commercial Qt licenses may use this file in
++** accordance with the commercial license agreement provided with the
++** Software or, alternatively, in accordance with the terms contained in
++** a written agreement between you and The Qt Company. For licensing terms
++** and conditions see https://www.qt.io/terms-conditions. For further
++** information use the contact form at https://www.qt.io/contact-us.
++**
++** BSD License Usage
++** Alternatively, you may use this file under the terms of the BSD license
++** as follows:
++**
++** "Redistribution and use in source and binary forms, with or without
++** modification, are permitted provided that the following conditions are
++** met:
++** * Redistributions of source code must retain the above copyright
++** notice, this list of conditions and the following disclaimer.
++** * Redistributions in binary form must reproduce the above copyright
++** notice, this list of conditions and the following disclaimer in
++** the documentation and/or other materials provided with the
++** distribution.
++** * Neither the name of The Qt Company Ltd nor the names of its
++** contributors may be used to endorse or promote products derived
++** from this software without specific prior written permission.
++**
++**
++** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
++** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
++** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
++** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
++** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
++** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
++** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
++** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
++** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
++** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
++** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
++**
++** $QT_END_LICENSE$
++**
++****************************************************************************/
++
++import QtQuick 2.15
++import QtQuick.Controls 2.15
++
++ApplicationWindow {
++ id: window
++ width: 400
++ height: 400
++ title: "releaseAfterExitTransition"
++
++ property alias popup: popup
++ property alias modalPopup: modalPopup
++
++ Popup {
++ id: popup
++ y: parent.height - height
++ width: 50
++ height: 50
++ }
++
++ Popup {
++ id: modalPopup
++ modal: true
++ y: parent.height - height
++ width: 50
++ height: 50
++ exit: Transition { PauseAnimation { duration: 100 } }
++ }
++}
+diff --git a/qtquickcontrols2/tests/auto/qquickpopup/tst_qquickpopup.cpp b/qtquickcontrols2/tests/auto/qquickpopup/tst_qquickpopup.cpp
+index 54952d128..3d50e2dd4 100644
+--- a/qtquickcontrols2/tests/auto/qquickpopup/tst_qquickpopup.cpp
++++ b/qtquickcontrols2/tests/auto/qquickpopup/tst_qquickpopup.cpp
+@@ -100,6 +100,7 @@ private slots:
+ void invisibleToolTipOpen();
+ void centerInOverlayWithinStackViewItem();
+ void destroyDuringExitTransition();
++ void releaseAfterExitTransition();
+ };
+
+ void tst_QQuickPopup::initTestCase()
+@@ -1575,6 +1576,34 @@ void tst_QQuickPopup::destroyDuringExitTransition()
+ QVERIFY(!button->isDown());
+ }
+
++void tst_QQuickPopup::releaseAfterExitTransition()
++{
++ QQuickApplicationHelper helper(this, "releaseAfterExitTransition.qml");
++ QVERIFY2(helper.ready, helper.failureMessage());
++
++ QQuickWindow *window = helper.window;
++ window->show();
++ QVERIFY(QTest::qWaitForWindowActive(window));
++
++ QQuickOverlay *overlay = QQuickOverlay::overlay(window);
++ QQuickPopup *modalPopup = window->property("modalPopup").value<QQuickPopup *>();
++ QQuickPopup *popup = window->property("popup").value<QQuickPopup *>();
++
++ modalPopup->open();
++ QTRY_VERIFY(modalPopup->isOpened());
++
++ QTest::mousePress(window, Qt::LeftButton, Qt::NoModifier, QPoint(1, 1));
++ // wait until the transition is finished and the overlay hides itself
++ QTRY_VERIFY(!overlay->isVisible());
++ QTest::mouseRelease(window, Qt::LeftButton, Qt::NoModifier, QPoint(1, 1));
++
++ popup->open();
++ QTRY_VERIFY(popup->isOpened());
++ QTest::mouseClick(window, Qt::LeftButton, Qt::NoModifier, QPoint(1, 1));
++ QTRY_VERIFY(!popup->isOpened());
++}
++
++
+ QTEST_QUICKCONTROLS_MAIN(tst_QQuickPopup)
+
+ #include "tst_qquickpopup.moc"
+Submodule qtscript 5be95f96...4d8e4bd2 (commits not present)
+Submodule qtspeech 17fc9fde..255845e2:
+diff --git a/qtspeech/src/plugins/tts/speechdispatcher/qtexttospeech_speechd.cpp b/qtspeech/src/plugins/tts/speechdispatcher/qtexttospeech_speechd.cpp
+index 6eb74b8..bcc7dd1 100644
+--- a/qtspeech/src/plugins/tts/speechdispatcher/qtexttospeech_speechd.cpp
++++ b/qtspeech/src/plugins/tts/speechdispatcher/qtexttospeech_speechd.cpp
+@@ -357,7 +357,9 @@ QVector<QLocale> QTextToSpeechEngineSpeechd::availableLocales() const
+
+ QVector<QVoice> QTextToSpeechEngineSpeechd::availableVoices() const
+ {
+- return m_voices.values(m_currentLocale.name()).toVector();
++ QList<QVoice> resultList = m_voices.values(m_currentLocale.name());
++ std::reverse(resultList.begin(), resultList.end());
++ return resultList.toVector();
+ }
+
+ // We have no way of knowing our own client_id since speech-dispatcher seems to be incomplete
+Submodule qtsvg 0c05780e..a7a0f249:
+diff --git a/qtsvg/src/plugins/imageformats/svg/qsvgiohandler.cpp b/qtsvg/src/plugins/imageformats/svg/qsvgiohandler.cpp
+index 561e77e..12e0574 100644
+--- a/qtsvg/src/plugins/imageformats/svg/qsvgiohandler.cpp
++++ b/qtsvg/src/plugins/imageformats/svg/qsvgiohandler.cpp
+@@ -191,6 +191,8 @@ bool QSvgIOHandler::read(QImage *image)
+ }
+ }
+ if (!finalSize.isEmpty()) {
++ if (qMax(finalSize.width(), finalSize.height()) > 0xffff)
++ return false; // Assume corrupted file
+ image->fill(d->backColor.rgba());
+ QPainter p(image);
+ d->r.render(&p, bounds);
+diff --git a/qtsvg/src/svg/qsvghandler.cpp b/qtsvg/src/svg/qsvghandler.cpp
+index a5f877f..8dda563 100644
+--- a/qtsvg/src/svg/qsvghandler.cpp
++++ b/qtsvg/src/svg/qsvghandler.cpp
+@@ -1393,9 +1393,10 @@ static void parseFont(QSvgNode *node,
+ case FontSizeNone:
+ break;
+ case FontSizeValue: {
+- QSvgHandler::LengthType dummy; // should always be pixel size
+- fontStyle->setSize(qMin(parseLength(attributes.fontSize, dummy, handler),
+- qreal(0xffff)));
++ QSvgHandler::LengthType type;
++ qreal fs = parseLength(attributes.fontSize, type, handler);
++ fs = convertToPixels(fs, true, type);
++ fontStyle->setSize(qMin(fs, qreal(0xffff)));
+ }
+ break;
+ default:
+@@ -2513,6 +2514,8 @@ static bool parseAnimateTransformNode(QSvgNode *parent,
+ ++s;
+ }
+ }
++ if (vals.count() % 3 != 0)
++ return false;
+
+ bool ok = true;
+ int begin = parseClockValue(beginStr, &ok);
+@@ -2576,6 +2579,8 @@ static QSvgNode *createCircleNode(QSvgNode *parent,
+ qreal ncx = toDouble(cx);
+ qreal ncy = toDouble(cy);
+ qreal nr = toDouble(r);
++ if (nr < 0.0)
++ return nullptr;
+
+ QRectF rect(ncx-nr, ncy-nr, nr*2, nr*2);
+ QSvgNode *circle = new QSvgCircle(parent, rect);
+@@ -3046,15 +3051,16 @@ static QSvgStyleProperty *createRadialGradientNode(QSvgNode *node,
+
+ qreal ncx = 0.5;
+ qreal ncy = 0.5;
+- qreal nr = 0.5;
+ if (!cx.isEmpty())
+ ncx = toDouble(cx);
+ if (!cy.isEmpty())
+ ncy = toDouble(cy);
++
++ qreal nr = 0.0;
+ if (!r.isEmpty())
+ nr = toDouble(r);
+- if (nr < 0.5)
+- nr = 0.5;
++ if (nr <= 0.0)
++ return nullptr;
+
+ qreal nfx = ncx;
+ if (!fx.isEmpty())
+@@ -3350,7 +3356,9 @@ static QSvgNode *createTextNode(QSvgNode *parent,
+ //### editable and rotate not handled
+ QSvgHandler::LengthType type;
+ qreal nx = parseLength(x, type, handler);
++ nx = convertToPixels(nx, true, type);
+ qreal ny = parseLength(y, type, handler);
++ ny = convertToPixels(ny, true, type);
+
+ QSvgNode *text = new QSvgText(parent, QPointF(nx, ny));
+ return text;
+@@ -3691,9 +3699,7 @@ void QSvgHandler::parse()
+ case QXmlStreamReader::EndElement:
+ endElement(xml->name());
+ ++remainingUnfinishedElements;
+- // if we are using somebody else's qxmlstreamreader
+- // we should not read until the end of the stream
+- done = !m_ownsReader && (xml->name() == QLatin1String("svg"));
++ done = (xml->name() == QLatin1String("svg"));
+ break;
+ case QXmlStreamReader::Characters:
+ characters(xml->text());
+diff --git a/qtsvg/src/svg/qsvgstructure.cpp b/qtsvg/src/svg/qsvgstructure.cpp
+index b89608b..89c9e4e 100644
+--- a/qtsvg/src/svg/qsvgstructure.cpp
++++ b/qtsvg/src/svg/qsvgstructure.cpp
+@@ -255,9 +255,13 @@ inline static bool isSupportedSvgFeature(const QString &str)
+ };
+
+ if (str.length() <= MAX_WORD_LENGTH && str.length() >= MIN_WORD_LENGTH) {
++ const char16_t unicode44 = str.at(44).unicode();
++ const char16_t unicode45 = str.at(45).unicode();
++ if (unicode44 >= sizeof(asso_values) || unicode45 >= sizeof(asso_values))
++ return false;
+ const int key = str.length()
+- + asso_values[str.at(45).unicode()]
+- + asso_values[str.at(44).unicode()];
++ + asso_values[unicode45]
++ + asso_values[unicode44];
+ if (key <= MAX_HASH_VALUE && key >= 0)
+ return str == QLatin1String(wordlist[key]);
+ }
+diff --git a/qtsvg/src/svg/qsvgtinydocument.cpp b/qtsvg/src/svg/qsvgtinydocument.cpp
+index 63d0797..19e7154 100644
+--- a/qtsvg/src/svg/qsvgtinydocument.cpp
++++ b/qtsvg/src/svg/qsvgtinydocument.cpp
+@@ -433,8 +433,16 @@ void QSvgTinyDocument::draw(QPainter *p, QSvgExtraStates &)
+ draw(p);
+ }
+
++static bool isValidMatrix(const QTransform &transform)
++{
++ qreal determinant = transform.determinant();
++ return qIsFinite(determinant);
++}
++
+ void QSvgTinyDocument::mapSourceToTarget(QPainter *p, const QRectF &targetRect, const QRectF &sourceRect)
+ {
++ QTransform oldTransform = p->worldTransform();
++
+ QRectF target = targetRect;
+ if (target.isEmpty()) {
+ QPaintDevice *dev = p->device();
+@@ -487,6 +495,9 @@ void QSvgTinyDocument::mapSourceToTarget(QPainter *p, const QRectF &targetRect,
+ }
+ #endif
+ }
++
++ if (!isValidMatrix(p->worldTransform()))
++ p->setWorldTransform(oldTransform);
+ }
+
+ QRectF QSvgTinyDocument::boundsOnElement(const QString &id) const
+diff --git a/qtsvg/tests/auto/qsvgrenderer/tst_qsvgrenderer.cpp b/qtsvg/tests/auto/qsvgrenderer/tst_qsvgrenderer.cpp
+index 36c76ec..db71e02 100644
+--- a/qtsvg/tests/auto/qsvgrenderer/tst_qsvgrenderer.cpp
++++ b/qtsvg/tests/auto/qsvgrenderer/tst_qsvgrenderer.cpp
+@@ -86,6 +86,8 @@ private slots:
+ void oss_fuzz_23731();
+ void oss_fuzz_24131();
+ void oss_fuzz_24738();
++ void illegalAnimateTransform_data();
++ void illegalAnimateTransform();
+
+ #ifndef QT_NO_COMPRESS
+ void testGzLoading();
+@@ -1646,5 +1648,22 @@ void tst_QSvgRenderer::oss_fuzz_24738()
+ QSvgRenderer().load(QByteArray("<svg><path d=\"a 2 1e-212.....\">"));
+ }
+
++void tst_QSvgRenderer::illegalAnimateTransform_data()
++{
++ QTest::addColumn<QByteArray>("svg");
++
++ QTest::newRow("case1") << QByteArray("<svg><animateTransform type=\"rotate\" begin=\"1\" dur=\"2\" values=\"8,0,5,0\">");
++ QTest::newRow("case2") << QByteArray("<svg><animateTransform type=\"rotate\" begin=\"1\" dur=\"2\" values=\"1,2\">");
++ QTest::newRow("case3") << QByteArray("<svg><animateTransform type=\"rotate\" begin=\"1\" dur=\"2\" from=\".. 5 2\" to=\"f\">");
++ QTest::newRow("case4") << QByteArray("<svg><animateTransform type=\"scale\" begin=\"1\" dur=\"2\" by=\"--,..\">");
++}
++
++void tst_QSvgRenderer::illegalAnimateTransform()
++{
++ QFETCH(QByteArray, svg);
++ QSvgRenderer renderer;
++ QVERIFY(!renderer.load(svg)); // also shouldn't assert
++}
++
+ QTEST_MAIN(tst_QSvgRenderer)
+ #include "tst_qsvgrenderer.moc"
+Submodule qttools 6914f7c8..090e526e:
+diff --git a/qttools/src/assistant/qhelpgenerator/helpgenerator.cpp b/qttools/src/assistant/qhelpgenerator/helpgenerator.cpp
+index feab1e2d5..cbfb82507 100644
+--- a/qttools/src/assistant/qhelpgenerator/helpgenerator.cpp
++++ b/qttools/src/assistant/qhelpgenerator/helpgenerator.cpp
+@@ -445,7 +445,9 @@ bool HelpGeneratorPrivate::insertFiles(const QStringList &files, const QString &
+ if (filterSetId < 0)
+ return false;
+ ++filterSetId;
+- for (int attId : qAsConst(filterAtts)) {
++ QList<int> attValues = filterAtts.values();
++ std::sort(attValues.begin(), attValues.end());
++ for (int attId : qAsConst(attValues)) {
+ m_query->prepare(QLatin1String("INSERT INTO FileAttributeSetTable "
+ "VALUES(?, ?)"));
+ m_query->bindValue(0, filterSetId);
+Submodule qtwayland dfb0129c..2904e1b3:
+diff --git a/qtwayland/src/client/configure.json b/qtwayland/src/client/configure.json
+index 2f424580..29222357 100644
+--- a/qtwayland/src/client/configure.json
++++ b/qtwayland/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/qtwayland/src/client/global/qwaylandclientextension.cpp b/qtwayland/src/client/global/qwaylandclientextension.cpp
+index 125b1e19..edccfe63 100644
+--- a/qtwayland/src/client/global/qwaylandclientextension.cpp
++++ b/qtwayland/src/client/global/qwaylandclientextension.cpp
+@@ -74,7 +74,10 @@ void QWaylandClientExtensionPrivate::handleRegistryGlobal(void *data, ::wl_regis
+ void QWaylandClientExtension::addRegistryListener()
+ {
+ Q_D(QWaylandClientExtension);
+- d->waylandIntegration->display()->addRegistryListener(&QWaylandClientExtensionPrivate::handleRegistryGlobal, this);
++ if (!d->registered) {
++ d->waylandIntegration->display()->addRegistryListener(&QWaylandClientExtensionPrivate::handleRegistryGlobal, this);
++ d->registered = true;
++ }
+ }
+
+ QWaylandClientExtension::QWaylandClientExtension(const int ver)
+@@ -88,6 +91,13 @@ QWaylandClientExtension::QWaylandClientExtension(const int ver)
+ QMetaObject::invokeMethod(this, "addRegistryListener", Qt::QueuedConnection);
+ }
+
++QWaylandClientExtension::~QWaylandClientExtension()
++{
++ Q_D(QWaylandClientExtension);
++ if (d->registered && !QCoreApplication::closingDown())
++ d->waylandIntegration->display()->removeListener(&QWaylandClientExtensionPrivate::handleRegistryGlobal, this);
++}
++
+ QtWaylandClient::QWaylandIntegration *QWaylandClientExtension::integration() const
+ {
+ Q_D(const QWaylandClientExtension);
+diff --git a/qtwayland/src/client/global/qwaylandclientextension.h b/qtwayland/src/client/global/qwaylandclientextension.h
+index 98272e57..5bd28398 100644
+--- a/qtwayland/src/client/global/qwaylandclientextension.h
++++ b/qtwayland/src/client/global/qwaylandclientextension.h
+@@ -63,6 +63,7 @@ class Q_WAYLAND_CLIENT_EXPORT QWaylandClientExtension : public QObject
+ Q_PROPERTY(bool active READ isActive NOTIFY activeChanged)
+ public:
+ QWaylandClientExtension(const int version);
++ ~QWaylandClientExtension();
+
+ QtWaylandClient::QWaylandIntegration *integration() const;
+ int version() const;
+diff --git a/qtwayland/src/client/global/qwaylandclientextension_p.h b/qtwayland/src/client/global/qwaylandclientextension_p.h
+index 69cc46a0..9091efbe 100644
+--- a/qtwayland/src/client/global/qwaylandclientextension_p.h
++++ b/qtwayland/src/client/global/qwaylandclientextension_p.h
+@@ -68,6 +68,7 @@ public:
+ QtWaylandClient::QWaylandIntegration *waylandIntegration = nullptr;
+ int version = -1;
+ bool active = false;
++ bool registered = false;
+ };
+
+ class Q_WAYLAND_CLIENT_EXPORT QWaylandClientExtensionTemplatePrivate : public QWaylandClientExtensionPrivate
+diff --git a/qtwayland/src/client/qwaylanddatadevice.cpp b/qtwayland/src/client/qwaylanddatadevice.cpp
+index 7e2e3308..e3e60ed5 100644
+--- a/qtwayland/src/client/qwaylanddatadevice.cpp
++++ b/qtwayland/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,7 +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::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;
+@@ -152,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;
+ }
+@@ -162,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();
+ }
+ }
+
+@@ -186,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,
+@@ -197,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()
+@@ -235,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());
+
+@@ -246,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)
+
+@@ -277,14 +296,10 @@ void QWaylandDataDevice::selectionSourceCancelled()
+ #if QT_CONFIG(draganddrop)
+ void QWaylandDataDevice::dragSourceCancelled()
+ {
++ static_cast<QWaylandDrag *>(QGuiApplicationPrivate::platformIntegration()->drag())->finishDrag();
+ 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));
+@@ -297,6 +312,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/qtwayland/src/client/qwaylanddatadevice_p.h b/qtwayland/src/client/qwaylanddatadevice_p.h
+index 16c3ad28..801dcc2c 100644
+--- a/qtwayland/src/client/qwaylanddatadevice_p.h
++++ b/qtwayland/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/qtwayland/src/client/qwaylanddatadevicemanager.cpp b/qtwayland/src/client/qwaylanddatadevicemanager.cpp
+index 35d67307..6dc4f77f 100644
+--- a/qtwayland/src/client/qwaylanddatadevicemanager.cpp
++++ b/qtwayland/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/qtwayland/src/client/qwaylanddatadevicemanager_p.h b/qtwayland/src/client/qwaylanddatadevicemanager_p.h
+index bd05c0fb..510d9be4 100644
+--- a/qtwayland/src/client/qwaylanddatadevicemanager_p.h
++++ b/qtwayland/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/qtwayland/src/client/qwaylanddataoffer.cpp b/qtwayland/src/client/qwaylanddataoffer.cpp
+index 2297e8a1..fe0ea8c9 100644
+--- a/qtwayland/src/client/qwaylanddataoffer.cpp
++++ b/qtwayland/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)
+ {
+@@ -163,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");
+diff --git a/qtwayland/src/client/qwaylanddataoffer_p.h b/qtwayland/src/client/qwaylanddataoffer_p.h
+index 9cf1483c..6f667398 100644
+--- a/qtwayland/src/client/qwaylanddataoffer_p.h
++++ b/qtwayland/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/qtwayland/src/client/qwaylanddatasource.cpp b/qtwayland/src/client/qwaylanddatasource.cpp
+index f45122fb..5599cbd4 100644
+--- a/qtwayland/src/client/qwaylanddatasource.cpp
++++ b/qtwayland/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/qtwayland/src/client/qwaylanddatasource_p.h b/qtwayland/src/client/qwaylanddatasource_p.h
+index 25afff79..96f07bc3 100644
+--- a/qtwayland/src/client/qwaylanddatasource_p.h
++++ b/qtwayland/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/qtwayland/src/client/qwaylanddisplay.cpp b/qtwayland/src/client/qwaylanddisplay.cpp
+index f10c1f79..c01e238b 100644
+--- a/qtwayland/src/client/qwaylanddisplay.cpp
++++ b/qtwayland/src/client/qwaylanddisplay.cpp
+@@ -85,10 +85,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)
+@@ -158,17 +351,16 @@ 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)
+ {
++ if (m_eventThread)
++ m_eventThread->stop();
++
++ if (m_frameEventQueueThread)
++ m_frameEventQueueThread->stop();
++
+ if (mSyncCallback)
+ wl_callback_destroy(mSyncCallback);
+
+@@ -187,6 +379,21 @@ 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
++// 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()
+@@ -203,98 +410,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
+@@ -345,7 +491,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));
+@@ -354,7 +500,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));
+@@ -369,6 +515,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));
+@@ -427,6 +575,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;
+ }
+@@ -452,9 +607,10 @@ void QWaylandDisplay::addRegistryListener(RegistryListener listener, void *data)
+
+ void QWaylandDisplay::removeListener(RegistryListener listener, void *data)
+ {
+- std::remove_if(mRegistryListeners.begin(), mRegistryListeners.end(), [=](Listener l){
++ auto iter = std::remove_if(mRegistryListeners.begin(), mRegistryListeners.end(), [=](Listener l){
+ return (l.listener == listener && l.data == data);
+ });
++ mRegistryListeners.erase(iter, mRegistryListeners.end());
+ }
+
+ uint32_t QWaylandDisplay::currentTimeMillisec()
+@@ -467,50 +623,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
+@@ -574,14 +689,10 @@ void QWaylandDisplay::handleKeyboardFocusChanged(QWaylandInputDevice *inputDevic
+ if (mLastKeyboardFocus == keyboardFocus)
+ return;
+
+- if (mWaylandIntegration->mShellIntegration) {
+- mWaylandIntegration->mShellIntegration->handleKeyboardFocusChanged(keyboardFocus, mLastKeyboardFocus);
+- } else {
+- if (keyboardFocus)
+- handleWindowActivated(keyboardFocus);
+- if (mLastKeyboardFocus)
+- handleWindowDeactivated(mLastKeyboardFocus);
+- }
++ if (keyboardFocus)
++ handleWindowActivated(keyboardFocus);
++ if (mLastKeyboardFocus)
++ handleWindowDeactivated(mLastKeyboardFocus);
+
+ mLastKeyboardFocus = keyboardFocus;
+ }
+@@ -600,6 +711,19 @@ void QWaylandDisplay::handleWaylandSync()
+ QWindow *activeWindow = mActiveWindows.empty() ? nullptr : mActiveWindows.last()->window();
+ if (activeWindow != QGuiApplication::focusWindow())
+ QWindowSystemInterface::handleWindowActivated(activeWindow);
++
++ if (!activeWindow) {
++ if (lastInputDevice()) {
++#if QT_CONFIG(clipboard)
++ if (auto *dataDevice = lastInputDevice()->dataDevice())
++ dataDevice->invalidateSelectionOffer();
++#endif
++#if QT_CONFIG(wayland_client_primary_selection)
++ if (auto *device = lastInputDevice()->primarySelectionDevice())
++ device->invalidateSelectionOffer();
++#endif
++ }
++ }
+ }
+
+ const wl_callback_listener QWaylandDisplay::syncCallbackListener = {
+@@ -626,6 +750,13 @@ QWaylandInputDevice *QWaylandDisplay::defaultInputDevice() const
+ return mInputDevices.isEmpty() ? 0 : mInputDevices.first();
+ }
+
++bool QWaylandDisplay::isKeyboardAvailable() const
++{
++ return std::any_of(
++ mInputDevices.constBegin(), mInputDevices.constEnd(),
++ [this](const QWaylandInputDevice *device) { return device->keyboard() != nullptr; });
++}
++
+ #if QT_CONFIG(cursor)
+
+ QWaylandCursor *QWaylandDisplay::waylandCursor()
+@@ -652,4 +783,6 @@ QWaylandCursorTheme *QWaylandDisplay::loadCursorTheme(const QString &name, int p
+
+ } // namespace QtWaylandClient
+
++#include "qwaylanddisplay.moc"
++
+ QT_END_NAMESPACE
+diff --git a/qtwayland/src/client/qwaylanddisplay_p.h b/qtwayland/src/client/qwaylanddisplay_p.h
+index 3b092bc8..42bc661d 100644
+--- a/qtwayland/src/client/qwaylanddisplay_p.h
++++ b/qtwayland/src/client/qwaylanddisplay_p.h
+@@ -109,6 +109,7 @@ class QWaylandSurface;
+ class QWaylandShellIntegration;
+ class QWaylandCursor;
+ class QWaylandCursorTheme;
++class EventThread;
+
+ typedef void (*RegistryListener)(void *data,
+ struct wl_registry *registry,
+@@ -120,15 +121,11 @@ 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;
+
++ void initialize();
++
+ #if QT_CONFIG(xkbcommon)
+ struct xkb_context *xkbContext() const { return mXkbContext.get(); }
+ #endif
+@@ -210,11 +207,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();
+@@ -237,6 +234,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;
+@@ -273,11 +273,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/qtwayland/src/client/qwaylanddnd.cpp b/qtwayland/src/client/qwaylanddnd.cpp
+index 6535aa16..7c53f5fa 100644
+--- a/qtwayland/src/client/qwaylanddnd.cpp
++++ b/qtwayland/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
+@@ -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)
+@@ -103,33 +106,41 @@ 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);
++
++ if (drag())
++ drag()->deleteLater();
++}
++
++bool QWaylandDrag::ownsDragObject() const
++{
++ return true;
+ }
+
+ }
+diff --git a/qtwayland/src/client/qwaylanddnd_p.h b/qtwayland/src/client/qwaylanddnd_p.h
+index 474fe2ab..46f629ac 100644
+--- a/qtwayland/src/client/qwaylanddnd_p.h
++++ b/qtwayland/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;
+@@ -82,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;
+diff --git a/qtwayland/src/client/qwaylandinputdevice.cpp b/qtwayland/src/client/qwaylandinputdevice.cpp
+index 613fe862..4b90de84 100644
+--- a/qtwayland/src/client/qwaylandinputdevice.cpp
++++ b/qtwayland/src/client/qwaylandinputdevice.cpp
+@@ -685,6 +685,11 @@ public:
+
+ void QWaylandInputDevice::Pointer::pointer_leave(uint32_t time, struct wl_surface *surface)
+ {
++ invalidateFocus();
++ mButtons = Qt::NoButton;
++
++ mParent->mTime = time;
++
+ // The event may arrive after destroying the window, indicated by
+ // a null surface.
+ if (!surface)
+@@ -696,11 +701,6 @@ void QWaylandInputDevice::Pointer::pointer_leave(uint32_t time, struct wl_surfac
+
+ if (!QWaylandWindow::mouseGrab())
+ setFrameEvent(new LeaveEvent(window, mSurfacePos, mGlobalPos));
+-
+- invalidateFocus();
+- mButtons = Qt::NoButton;
+-
+- mParent->mTime = time;
+ }
+
+ class MotionEvent : public QWaylandPointerEvent
+@@ -1300,14 +1300,6 @@ void QWaylandInputDevice::Keyboard::handleFocusDestroyed()
+ void QWaylandInputDevice::Keyboard::handleFocusLost()
+ {
+ mFocus = nullptr;
+-#if QT_CONFIG(clipboard)
+- if (auto *dataDevice = mParent->dataDevice())
+- dataDevice->invalidateSelectionOffer();
+-#endif
+-#if QT_CONFIG(wayland_client_primary_selection)
+- if (auto *device = mParent->primarySelectionDevice())
+- device->invalidateSelectionOffer();
+-#endif
+ mParent->mQDisplay->handleKeyboardFocusChanged(mParent);
+ mRepeatTimer.stop();
+ }
+@@ -1396,6 +1388,7 @@ void QWaylandInputDevice::Touch::touch_cancel()
+ if (touchExt)
+ touchExt->touchCanceled();
+
++ mFocus = nullptr;
+ QWindowSystemInterface::handleTouchCancelEvent(nullptr, mParent->mTouchDevice);
+ }
+
+diff --git a/qtwayland/src/client/qwaylandintegration.cpp b/qtwayland/src/client/qwaylandintegration.cpp
+index c53ccb78..54861600 100644
+--- a/qtwayland/src/client/qwaylandintegration.cpp
++++ b/qtwayland/src/client/qwaylandintegration.cpp
+@@ -125,6 +125,9 @@ QWaylandIntegration::QWaylandIntegration()
+ #endif
+
+ reconfigureInputContext();
++
++ QWaylandWindow::fixedToplevelPositions =
++ !qEnvironmentVariableIsSet("QT_WAYLAND_DISABLE_FIXED_POSITIONS");
+ }
+
+ QWaylandIntegration::~QWaylandIntegration()
+@@ -192,14 +195,18 @@ QAbstractEventDispatcher *QWaylandIntegration::createEventDispatcher() const
+
+ void QWaylandIntegration::initialize()
+ {
++ mDisplay->initEventThread();
++
++ // 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()));
+
+- 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()));
+-
+ // Qt does not support running with no screens
+ mDisplay->ensureScreen();
+ }
+@@ -262,6 +269,14 @@ QWaylandDisplay *QWaylandIntegration::display() const
+ return mDisplay.data();
+ }
+
++Qt::KeyboardModifiers QWaylandIntegration::queryKeyboardModifiers() const
++{
++ if (auto *seat = mDisplay->currentInputDevice()) {
++ return seat->modifiers();
++ }
++ return Qt::NoModifier;
++}
++
+ QList<int> QWaylandIntegration::possibleKeys(const QKeyEvent *event) const
+ {
+ if (auto *seat = mDisplay->currentInputDevice())
+@@ -479,7 +494,7 @@ void QWaylandIntegration::reconfigureInputContext()
+ }
+ #endif
+
+- qCDebug(lcQpaWayland) << "using input method:" << inputContext()->metaObject()->className();
++ qCDebug(lcQpaWayland) << "using input method:" << (inputContext() ? inputContext()->metaObject()->className() : "<none>");
+ }
+
+ QWaylandShellIntegration *QWaylandIntegration::createShellIntegration(const QString &integrationName)
+diff --git a/qtwayland/src/client/qwaylandintegration_p.h b/qtwayland/src/client/qwaylandintegration_p.h
+index ff70ae25..73b80658 100644
+--- a/qtwayland/src/client/qwaylandintegration_p.h
++++ b/qtwayland/src/client/qwaylandintegration_p.h
+@@ -107,6 +107,8 @@ public:
+
+ QWaylandDisplay *display() const;
+
++ Qt::KeyboardModifiers queryKeyboardModifiers() const override;
++
+ QList<int> possibleKeys(const QKeyEvent *event) const override;
+
+ QStringList themeNames() const override;
+diff --git a/qtwayland/src/client/qwaylandprimaryselectionv1.cpp b/qtwayland/src/client/qwaylandprimaryselectionv1.cpp
+index 832f9678..ea508771 100644
+--- a/qtwayland/src/client/qwaylandprimaryselectionv1.cpp
++++ b/qtwayland/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)
+diff --git a/qtwayland/src/client/qwaylandscreen.cpp b/qtwayland/src/client/qwaylandscreen.cpp
+index 6cb337de..5537dafd 100644
+--- a/qtwayland/src/client/qwaylandscreen.cpp
++++ b/qtwayland/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))
+@@ -72,7 +72,7 @@ QWaylandScreen::QWaylandScreen(QWaylandDisplay *waylandDisplay, int version, uin
+ qCWarning(lcQpaWayland) << "wl_output done event not supported by compositor,"
+ << "QScreen may not work correctly";
+ mWaylandDisplay->forceRoundTrip(); // Give the compositor a chance to send geometry etc.
+- mOutputDone = true; // Fake the done event
++ mProcessedEvents |= OutputDoneEvent; // Fake the done event
+ maybeInitialize();
+ }
+ }
+@@ -81,16 +81,29 @@ 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
++{
++ uint ret = OutputDoneEvent;
++
++ if (mWaylandDisplay->xdgOutputManager()) {
++ ret |= XdgOutputNameEvent;
++
++ if (mWaylandDisplay->xdgOutputManager()->version() < 3)
++ ret |= XdgOutputDoneEvent;
++ }
++ return ret;
+ }
+
+ void QWaylandScreen::maybeInitialize()
+ {
+ Q_ASSERT(!mInitialized);
+
+- if (!mOutputDone)
+- return;
+-
+- if (mWaylandDisplay->xdgOutputManager() && !mXdgOutputDone)
++ const uint requiredEvents = this->requiredEvents();
++ if ((mProcessedEvents & requiredEvents) != requiredEvents)
+ return;
+
+ mInitialized = true;
+@@ -276,9 +289,8 @@ void QWaylandScreen::output_scale(int32_t factor)
+
+ void QWaylandScreen::output_done()
+ {
+- mOutputDone = true;
+- if (zxdg_output_v1::isInitialized() && mWaylandDisplay->xdgOutputManager()->version() >= 3)
+- mXdgOutputDone = true;
++ mProcessedEvents |= OutputDoneEvent;
++
+ if (mInitialized) {
+ updateOutputProperties();
+ if (zxdg_output_v1::isInitialized())
+@@ -339,7 +351,7 @@ void QWaylandScreen::zxdg_output_v1_done()
+ if (Q_UNLIKELY(mWaylandDisplay->xdgOutputManager()->version() >= 3))
+ qWarning(lcQpaWayland) << "zxdg_output_v1.done received on version 3 or newer, this is most likely a bug in the compositor";
+
+- mXdgOutputDone = true;
++ mProcessedEvents |= XdgOutputDoneEvent;
+ if (mInitialized)
+ updateXdgOutputProperties();
+ else
+@@ -348,7 +360,11 @@ void QWaylandScreen::zxdg_output_v1_done()
+
+ void QWaylandScreen::zxdg_output_v1_name(const QString &name)
+ {
++ if (Q_UNLIKELY(mInitialized))
++ qWarning(lcQpaWayland) << "zxdg_output_v1.name received after output has been initialized, this is most likely a bug in the compositor";
++
+ mOutputName = name;
++ mProcessedEvents |= XdgOutputNameEvent;
+ }
+
+ void QWaylandScreen::updateXdgOutputProperties()
+diff --git a/qtwayland/src/client/qwaylandscreen_p.h b/qtwayland/src/client/qwaylandscreen_p.h
+index df1c94f2..050cfdc0 100644
+--- a/qtwayland/src/client/qwaylandscreen_p.h
++++ b/qtwayland/src/client/qwaylandscreen_p.h
+@@ -116,6 +116,13 @@ public:
+ static QWaylandScreen *fromWlOutput(::wl_output *output);
+
+ private:
++ enum Event : uint {
++ XdgOutputDoneEvent = 0x1,
++ OutputDoneEvent = 0x2,
++ XdgOutputNameEvent = 0x4,
++ };
++ uint requiredEvents() const;
++
+ void output_mode(uint32_t flags, int width, int height, int refresh) override;
+ void output_geometry(int32_t x, int32_t y,
+ int32_t width, int32_t height,
+@@ -148,8 +155,7 @@ private:
+ QSize mPhysicalSize;
+ QString mOutputName;
+ Qt::ScreenOrientation m_orientation = Qt::PrimaryOrientation;
+- bool mOutputDone = false;
+- bool mXdgOutputDone = false;
++ uint mProcessedEvents = 0;
+ bool mInitialized = false;
+
+ #if QT_CONFIG(cursor)
+diff --git a/qtwayland/src/client/qwaylandshmbackingstore.cpp b/qtwayland/src/client/qwaylandshmbackingstore.cpp
+index dc7ff670..41cffdf7 100644
+--- a/qtwayland/src/client/qwaylandshmbackingstore.cpp
++++ b/qtwayland/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
+@@ -74,8 +78,10 @@ QWaylandShmBuffer::QWaylandShmBuffer(QWaylandDisplay *display,
+ int alloc = stride * size.height();
+ int fd = -1;
+
+-#ifdef SYS_memfd_create
+- fd = syscall(SYS_memfd_create, "wayland-shm", MFD_CLOEXEC);
++#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);
+ #endif
+
+ QScopedPointer<QFile> filePointer;
+diff --git a/qtwayland/src/client/qwaylandwindow.cpp b/qtwayland/src/client/qwaylandwindow.cpp
+index cb82857a..fb2c59dc 100644
+--- a/qtwayland/src/client/qwaylandwindow.cpp
++++ b/qtwayland/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,9 +94,6 @@ QWaylandWindow::QWaylandWindow(QWindow *window, QWaylandDisplay *display)
+
+ QWaylandWindow::~QWaylandWindow()
+ {
+- mDisplay->destroyFrameQueue(mFrameQueue);
+- mDisplay->handleWindowDestroyed(this);
+-
+ delete mWindowDecoration;
+
+ if (mSurface)
+@@ -243,6 +239,7 @@ bool QWaylandWindow::shouldCreateSubSurface() const
+
+ void QWaylandWindow::reset()
+ {
++ closeChildPopups();
+ delete mShellSurface;
+ mShellSurface = nullptr;
+ delete mSubSurfaceWindow;
+@@ -255,17 +252,22 @@ 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();
+ mQueuedBuffer = nullptr;
++
++ mDisplay->handleWindowDestroyed(this);
+ }
+
+ QWaylandWindow *QWaylandWindow::fromWlSurface(::wl_surface *surface)
+@@ -351,19 +353,25 @@ 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()) {
+ 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());
+@@ -374,7 +382,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)
+@@ -399,21 +407,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);
+@@ -433,10 +426,7 @@ void QWaylandWindow::setVisible(bool visible)
+ lastVisible = visible;
+
+ if (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
+@@ -444,7 +434,6 @@ void QWaylandWindow::setVisible(bool visible)
+ // QWaylandShmBackingStore::beginPaint().
+ } else {
+ sendExposeEvent(QRect());
+- closePopups(this);
+ reset();
+ }
+ }
+@@ -556,12 +545,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();
+
+@@ -583,7 +572,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)
+@@ -619,8 +612,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();
+@@ -635,42 +634,53 @@ 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);
+- 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();
+
+ // 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;
+- };
++ 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();
++ };
+
++ 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();
+ }
+
+ 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";
+@@ -868,6 +878,17 @@ bool QWaylandWindow::createDecoration()
+ subsurf->set_position(pos.x() + m.left(), pos.y() + m.top());
+ }
+ sendExposeEvent(QRect(QPoint(), geometry().size()));
++
++ // This is a special case where the buffer is recreated, but since
++ // the content rect remains the same, the widgets remain the same
++ // size and are not redrawn, leaving the new buffer empty. As a simple
++ // work-around, we trigger a full extra update whenever the client-side
++ // window decorations are toggled while the window is showing.
++ // Note: createDecoration() is sometimes called from the render thread
++ // of Qt Quick. This is essentially wrong and could potentially cause problems,
++ // but until the underlying issue has been fixed, we have to use invokeMethod()
++ // here to avoid asserts.
++ QMetaObject::invokeMethod(window(), &QWindow::requestUpdate);
+ }
+
+ return mWindowDecoration;
+@@ -1023,6 +1044,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) {
+@@ -1094,10 +1122,18 @@ bool QWaylandWindow::setMouseGrabEnabled(bool grab)
+ return true;
+ }
+
++Qt::WindowStates QWaylandWindow::windowStates() const
++{
++ return mLastReportedWindowStates;
++}
++
+ void QWaylandWindow::handleWindowStatesChanged(Qt::WindowStates states)
+ {
+ createDecoration();
+- QWindowSystemInterface::handleWindowStateChanged(window(), states, mLastReportedWindowStates);
++ Qt::WindowStates statesWithoutActive = states & ~Qt::WindowActive;
++ Qt::WindowStates lastStatesWithoutActive = mLastReportedWindowStates & ~Qt::WindowActive;
++ QWindowSystemInterface::handleWindowStateChanged(window(), statesWithoutActive,
++ lastStatesWithoutActive);
+ mLastReportedWindowStates = states;
+ }
+
+@@ -1139,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()
+@@ -1160,8 +1201,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
+@@ -1174,7 +1218,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);
+ }
+@@ -1185,19 +1234,18 @@ void QWaylandWindow::requestUpdate()
+ void QWaylandWindow::handleUpdate()
+ {
+ qCDebug(lcWaylandBackingstore) << "handleUpdate" << QThread::currentThread();
++
+ // TODO: Should sync subsurfaces avoid requesting frame callbacks?
+ QReadLocker lock(&mSurfaceLock);
+ if (!mSurface)
+ return;
+
+- if (mFrameCallback) {
+- wl_callback_destroy(mFrameCallback);
+- mFrameCallback = nullptr;
+- }
++ QMutexLocker locker(&mFrameSyncMutex);
++ if (mWaitingForFrameCallback)
++ return;
+
+- 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);
++ 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);
+@@ -1207,6 +1255,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);
+@@ -1267,6 +1317,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/qtwayland/src/client/qwaylandwindow_p.h b/qtwayland/src/client/qwaylandwindow_p.h
+index 01337cff..2f219d8c 100644
+--- a/qtwayland/src/client/qwaylandwindow_p.h
++++ b/qtwayland/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;
+@@ -148,6 +151,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;
+@@ -206,6 +210,10 @@ public:
+ void handleUpdate();
+ void deliverUpdateRequest() override;
+
++ void addChildPopup(QWaylandWindow* child);
++ void removeChildPopup(QWaylandWindow* child);
++ void closeChildPopups();
++
+ public slots:
+ void applyConfigure();
+
+@@ -215,7 +223,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;
+@@ -225,13 +237,14 @@ protected:
+ Qt::MouseButtons mMousePressedInContentArea = Qt::NoButton;
+
+ 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;
+- QWaylandDisplay::FrameQueue mFrameQueue;
++ 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;
+
+ // True when we have called deliverRequestUpdate, but the client has not yet attached a new buffer
+@@ -261,6 +274,8 @@ protected:
+ QWaylandBuffer *mQueuedBuffer = nullptr;
+ QRegion mQueuedBufferDamage;
+
++ QList<QPointer<QWaylandWindow>> mChildPopups;
++
+ private:
+ void setGeometry_helper(const QRect &rect);
+ void initWindow();
+@@ -283,12 +298,10 @@ private:
+ QRect mLastExposeGeometry;
+
+ static const wl_callback_listener callbackListener;
+- void handleFrameCallback();
++ void handleFrameCallback(struct ::wl_callback* callback);
+
+ static QWaylandWindow *mMouseGrab;
+
+- mutable QReadWriteLock mSurfaceLock;
+-
+ friend class QWaylandSubSurface;
+ };
+
+diff --git a/qtwayland/src/client/shellintegration/qwaylandshellintegration_p.h b/qtwayland/src/client/shellintegration/qwaylandshellintegration_p.h
+index ccad0048..4cc9b3b8 100644
+--- a/qtwayland/src/client/shellintegration/qwaylandshellintegration_p.h
++++ b/qtwayland/src/client/shellintegration/qwaylandshellintegration_p.h
+@@ -73,11 +73,10 @@ public:
+ return true;
+ }
+ virtual QWaylandShellSurface *createShellSurface(QWaylandWindow *window) = 0;
++ // kept for binary compat with layer-shell-qt
+ virtual void handleKeyboardFocusChanged(QWaylandWindow *newFocus, QWaylandWindow *oldFocus) {
+- if (newFocus)
+- m_display->handleWindowActivated(newFocus);
+- if (oldFocus)
+- m_display->handleWindowDeactivated(oldFocus);
++ Q_UNUSED(newFocus);
++ Q_UNUSED(oldFocus);
+ }
+ virtual void *nativeResourceForWindow(const QByteArray &resource, QWindow *window) {
+ Q_UNUSED(resource);
+diff --git a/qtwayland/src/compositor/configure.json b/qtwayland/src/compositor/configure.json
+index bcfd5215..da95d07b 100644
+--- a/qtwayland/src/compositor/configure.json
++++ b/qtwayland/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"
+ }
+ },
+
+diff --git a/qtwayland/src/hardwareintegration/client/wayland-egl/qwaylandeglwindow.cpp b/qtwayland/src/hardwareintegration/client/wayland-egl/qwaylandeglwindow.cpp
+index 7889f575..64140672 100644
+--- a/qtwayland/src/hardwareintegration/client/wayland-egl/qwaylandeglwindow.cpp
++++ b/qtwayland/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>
+@@ -124,6 +125,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();
+@@ -131,14 +133,16 @@ void QWaylandEglWindow::updateSurface(bool create)
+ if (!disableResizeCheck) {
+ wl_egl_window_get_attached_size(m_waylandEglWindow, ¤t_width, ¤t_height);
+ }
+- if (disableResizeCheck || (current_width != sizeWithMargins.width() || current_height != sizeWithMargins.height())) {
++ if (disableResizeCheck || (current_width != sizeWithMargins.width() || current_height != sizeWithMargins.height()) || m_requestedSize != sizeWithMargins) {
+ wl_egl_window_resize(m_waylandEglWindow, sizeWithMargins.width(), sizeWithMargins.height(), mOffset.x(), mOffset.y());
++ m_requestedSize = sizeWithMargins;
+ mOffset = QPoint();
+
+ 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;
+ }
+
+ if (!m_eglSurface && m_waylandEglWindow && create) {
+diff --git a/qtwayland/src/hardwareintegration/client/wayland-egl/qwaylandeglwindow.h b/qtwayland/src/hardwareintegration/client/wayland-egl/qwaylandeglwindow.h
+index 5b1f4d56..0079dfef 100644
+--- a/qtwayland/src/hardwareintegration/client/wayland-egl/qwaylandeglwindow.h
++++ b/qtwayland/src/hardwareintegration/client/wayland-egl/qwaylandeglwindow.h
+@@ -88,6 +88,7 @@ private:
+ mutable QOpenGLFramebufferObject *m_contentFBO = nullptr;
+
+ QSurfaceFormat m_format;
++ QSize m_requestedSize;
+ };
+
+ }
+diff --git a/qtwayland/src/hardwareintegration/compositor/linux-dmabuf-unstable-v1/linuxdmabuf.h b/qtwayland/src/hardwareintegration/compositor/linux-dmabuf-unstable-v1/linuxdmabuf.h
+index 56a710c3..c6a8b6c6 100644
+--- a/qtwayland/src/hardwareintegration/compositor/linux-dmabuf-unstable-v1/linuxdmabuf.h
++++ b/qtwayland/src/hardwareintegration/compositor/linux-dmabuf-unstable-v1/linuxdmabuf.h
+@@ -41,6 +41,8 @@
+ #include <QtCore/QTextStream>
+ #include <QtGui/QOpenGLTexture>
+
++#include <array>
++
+ #include <EGL/egl.h>
+ #include <EGL/eglext.h>
+
+diff --git a/qtwayland/src/plugins/decorations/bradient/main.cpp b/qtwayland/src/plugins/decorations/bradient/main.cpp
+index e75fda3c..fa885143 100644
+--- a/qtwayland/src/plugins/decorations/bradient/main.cpp
++++ b/qtwayland/src/plugins/decorations/bradient/main.cpp
+@@ -164,13 +164,10 @@ void QWaylandBradientDecoration::paint(QPaintDevice *device)
+ // Window icon
+ QIcon icon = waylandWindow()->windowIcon();
+ if (!icon.isNull()) {
+- QPixmap pixmap = icon.pixmap(QSize(128, 128));
+- QPixmap scaled = pixmap.scaled(22, 22, Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
+-
+ QRectF iconRect(0, 0, 22, 22);
+- p.drawPixmap(iconRect.adjusted(margins().left() + BUTTON_SPACING, 4,
+- margins().left() + BUTTON_SPACING, 4),
+- scaled, iconRect);
++ iconRect.adjust(margins().left() + BUTTON_SPACING, 4,
++ margins().left() + BUTTON_SPACING, 4),
++ icon.paint(&p, iconRect.toRect());
+ }
+
+ // Window title
+diff --git a/qtwayland/src/plugins/shellintegration/xdg-shell-v5/qwaylandxdgpopupv5.cpp b/qtwayland/src/plugins/shellintegration/xdg-shell-v5/qwaylandxdgpopupv5.cpp
+index 85d25e3c..60bdd491 100644
+--- a/qtwayland/src/plugins/shellintegration/xdg-shell-v5/qwaylandxdgpopupv5.cpp
++++ b/qtwayland/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/qtwayland/src/plugins/shellintegration/xdg-shell-v5/qwaylandxdgpopupv5_p.h b/qtwayland/src/plugins/shellintegration/xdg-shell-v5/qwaylandxdgpopupv5_p.h
+index 7494f6a6..d85f130b 100644
+--- a/qtwayland/src/plugins/shellintegration/xdg-shell-v5/qwaylandxdgpopupv5_p.h
++++ b/qtwayland/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/qtwayland/src/plugins/shellintegration/xdg-shell-v5/qwaylandxdgshellv5.cpp b/qtwayland/src/plugins/shellintegration/xdg-shell-v5/qwaylandxdgshellv5.cpp
+index 7e242c4a..def8452a 100644
+--- a/qtwayland/src/plugins/shellintegration/xdg-shell-v5/qwaylandxdgshellv5.cpp
++++ b/qtwayland/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/qtwayland/src/plugins/shellintegration/xdg-shell-v5/qwaylandxdgshellv5integration.cpp b/qtwayland/src/plugins/shellintegration/xdg-shell-v5/qwaylandxdgshellv5integration.cpp
+index 4e25949f..cfc60939 100644
+--- a/qtwayland/src/plugins/shellintegration/xdg-shell-v5/qwaylandxdgshellv5integration.cpp
++++ b/qtwayland/src/plugins/shellintegration/xdg-shell-v5/qwaylandxdgshellv5integration.cpp
+@@ -85,13 +85,6 @@ QWaylandShellSurface *QWaylandXdgShellV5Integration::createShellSurface(QWayland
+ return m_xdgShell->createXdgSurface(window);
+ }
+
+-void QWaylandXdgShellV5Integration::handleKeyboardFocusChanged(QWaylandWindow *newFocus, QWaylandWindow *oldFocus) {
+- if (newFocus && qobject_cast<QWaylandXdgPopupV5 *>(newFocus->shellSurface()))
+- m_display->handleWindowActivated(newFocus);
+- if (oldFocus && qobject_cast<QWaylandXdgPopupV5 *>(oldFocus->shellSurface()))
+- m_display->handleWindowDeactivated(oldFocus);
+-}
+-
+ }
+
+ QT_END_NAMESPACE
+diff --git a/qtwayland/src/plugins/shellintegration/xdg-shell-v5/qwaylandxdgshellv5integration_p.h b/qtwayland/src/plugins/shellintegration/xdg-shell-v5/qwaylandxdgshellv5integration_p.h
+index ce6bdb9e..aed88670 100644
+--- a/qtwayland/src/plugins/shellintegration/xdg-shell-v5/qwaylandxdgshellv5integration_p.h
++++ b/qtwayland/src/plugins/shellintegration/xdg-shell-v5/qwaylandxdgshellv5integration_p.h
+@@ -67,7 +67,6 @@ public:
+ QWaylandXdgShellV5Integration() {}
+ bool initialize(QWaylandDisplay *display) override;
+ QWaylandShellSurface *createShellSurface(QWaylandWindow *window) override;
+- void handleKeyboardFocusChanged(QWaylandWindow *newFocus, QWaylandWindow *oldFocus) override;
+
+ private:
+ QScopedPointer<QWaylandXdgShellV5> m_xdgShell;
+diff --git a/qtwayland/src/plugins/shellintegration/xdg-shell-v6/qwaylandxdgshellv6.cpp b/qtwayland/src/plugins/shellintegration/xdg-shell-v6/qwaylandxdgshellv6.cpp
+index 8c371661..151c78e3 100644
+--- a/qtwayland/src/plugins/shellintegration/xdg-shell-v6/qwaylandxdgshellv6.cpp
++++ b/qtwayland/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/qtwayland/src/plugins/shellintegration/xdg-shell-v6/qwaylandxdgshellv6integration.cpp b/qtwayland/src/plugins/shellintegration/xdg-shell-v6/qwaylandxdgshellv6integration.cpp
+index 03164316..e8da8ba1 100644
+--- a/qtwayland/src/plugins/shellintegration/xdg-shell-v6/qwaylandxdgshellv6integration.cpp
++++ b/qtwayland/src/plugins/shellintegration/xdg-shell-v6/qwaylandxdgshellv6integration.cpp
+@@ -68,20 +68,6 @@ QWaylandShellSurface *QWaylandXdgShellV6Integration::createShellSurface(QWayland
+ return m_xdgShell->getXdgSurface(window);
+ }
+
+-void QWaylandXdgShellV6Integration::handleKeyboardFocusChanged(QWaylandWindow *newFocus, QWaylandWindow *oldFocus)
+-{
+- if (newFocus) {
+- auto *xdgSurface = qobject_cast<QWaylandXdgSurfaceV6 *>(newFocus->shellSurface());
+- if (xdgSurface && !xdgSurface->handlesActiveState())
+- m_display->handleWindowActivated(newFocus);
+- }
+- if (oldFocus && qobject_cast<QWaylandXdgSurfaceV6 *>(oldFocus->shellSurface())) {
+- auto *xdgSurface = qobject_cast<QWaylandXdgSurfaceV6 *>(oldFocus->shellSurface());
+- if (xdgSurface && !xdgSurface->handlesActiveState())
+- m_display->handleWindowDeactivated(oldFocus);
+- }
+-}
+-
+ }
+
+ QT_END_NAMESPACE
+diff --git a/qtwayland/src/plugins/shellintegration/xdg-shell-v6/qwaylandxdgshellv6integration_p.h b/qtwayland/src/plugins/shellintegration/xdg-shell-v6/qwaylandxdgshellv6integration_p.h
+index 261f8cbb..c1bcd5c6 100644
+--- a/qtwayland/src/plugins/shellintegration/xdg-shell-v6/qwaylandxdgshellv6integration_p.h
++++ b/qtwayland/src/plugins/shellintegration/xdg-shell-v6/qwaylandxdgshellv6integration_p.h
+@@ -65,7 +65,6 @@ public:
+ QWaylandXdgShellV6Integration() {}
+ bool initialize(QWaylandDisplay *display) override;
+ QWaylandShellSurface *createShellSurface(QWaylandWindow *window) override;
+- void handleKeyboardFocusChanged(QWaylandWindow *newFocus, QWaylandWindow *oldFocus) override;
+
+ private:
+ QScopedPointer<QWaylandXdgShellV6> m_xdgShell;
+diff --git a/qtwayland/src/plugins/shellintegration/xdg-shell/qwaylandxdgshell.cpp b/qtwayland/src/plugins/shellintegration/xdg-shell/qwaylandxdgshell.cpp
+index f3e3c330..fa6d5808 100644
+--- a/qtwayland/src/plugins/shellintegration/xdg-shell/qwaylandxdgshell.cpp
++++ b/qtwayland/src/plugins/shellintegration/xdg-shell/qwaylandxdgshell.cpp
+@@ -67,11 +67,6 @@ QWaylandXdgSurface::Toplevel::Toplevel(QWaylandXdgSurface *xdgSurface)
+
+ QWaylandXdgSurface::Toplevel::~Toplevel()
+ {
+- if (m_applied.states & Qt::WindowActive) {
+- QWaylandWindow *window = m_xdgSurface->window();
+- window->display()->handleWindowDeactivated(window);
+- }
+-
+ // The protocol spec requires that the decoration object is deleted before xdg_toplevel.
+ delete m_decoration;
+ m_decoration = nullptr;
+@@ -85,16 +80,15 @@ void QWaylandXdgSurface::Toplevel::applyConfigure()
+ if (!(m_applied.states & (Qt::WindowMaximized|Qt::WindowFullScreen)))
+ 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)
++ && !m_xdgSurface->m_window->display()->isKeyboardAvailable())
+ 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)
++ && !m_xdgSurface->m_window->display()->isKeyboardAvailable())
+ m_xdgSurface->m_window->display()->handleWindowDeactivated(m_xdgSurface->m_window);
+
+- // TODO: none of the other plugins send WindowActive either, but is it on purpose?
+- Qt::WindowStates statesWithoutActive = m_pending.states & ~Qt::WindowActive;
+-
+- m_xdgSurface->m_window->handleWindowStatesChanged(statesWithoutActive);
++ m_xdgSurface->m_window->handleWindowStatesChanged(m_pending.states);
+
+ if (m_pending.size.isEmpty()) {
+ // An empty size in the configure means it's up to the client to choose the size
+@@ -105,8 +99,6 @@ void QWaylandXdgSurface::Toplevel::applyConfigure()
+ m_xdgSurface->m_window->resizeFromApplyConfigure(m_pending.size);
+ }
+
+- m_xdgSurface->setSizeHints();
+-
+ m_applied = m_pending;
+ qCDebug(lcQpaWayland) << "Applied pending xdg_toplevel configure event:" << m_applied.size << m_applied.states;
+ }
+@@ -203,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()
+@@ -216,10 +213,24 @@ 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
++ QWindow *leave = nullptr;
++ if (m_xdgSurface && m_xdgSurface->window())
++ leave = m_xdgSurface->window()->window();
++ QWindowSystemInterface::handleLeaveEvent(leave);
++
++ if (QWindow *enter = QGuiApplication::topLevelAt(QCursor::pos()))
++ QWindowSystemInterface::handleEnterEvent(enter, enter->mapFromGlobal(QCursor::pos()), QCursor::pos());
+ }
+ }
+
+@@ -257,6 +268,7 @@ QWaylandXdgSurface::QWaylandXdgSurface(QWaylandXdgShell *shell, ::xdg_surface *s
+ m_toplevel->set_parent(parentXdgSurface->m_toplevel->object());
+ }
+ }
++ setSizeHints();
+ }
+
+ QWaylandXdgSurface::~QWaylandXdgSurface()
+@@ -400,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
+@@ -414,8 +424,9 @@ void QWaylandXdgSurface::setPopup(QWaylandWindow *parent)
+ positioner->set_anchor(QtWayland::xdg_positioner::anchor_top_left);
+ positioner->set_gravity(QtWayland::xdg_positioner::gravity_bottom_right);
+ positioner->set_size(m_window->geometry().width(), m_window->geometry().height());
+- m_popup = new Popup(this, parentXdgSurface, positioner);
++ m_popup = new Popup(this, parent, positioner);
+ positioner->destroy();
++
+ delete positioner;
+ }
+
+@@ -437,6 +448,23 @@ void QWaylandXdgSurface::setGrabPopup(QWaylandWindow *parent, QWaylandInputDevic
+ }
+ setPopup(parent);
+ m_popup->grab(device, serial);
++
++ // Synthesize Qt enter/leave events for popup
++ if (!parent)
++ return;
++ QWindow *current = QGuiApplication::topLevelAt(QCursor::pos());
++ QWindow *leave = parent->window();
++ if (current != leave)
++ return;
++
++ QWindowSystemInterface::handleLeaveEvent(leave);
++
++ QWindow *enter = nullptr;
++ if (m_popup && m_popup->m_xdgSurface && m_popup->m_xdgSurface->window())
++ enter = m_popup->m_xdgSurface->window()->window();
++
++ if (enter)
++ QWindowSystemInterface::handleEnterEvent(enter, enter->mapFromGlobal(QCursor::pos()), QCursor::pos());
+ }
+
+ void QWaylandXdgSurface::xdg_surface_configure(uint32_t serial)
+diff --git a/qtwayland/src/plugins/shellintegration/xdg-shell/qwaylandxdgshell_p.h b/qtwayland/src/plugins/shellintegration/xdg-shell/qwaylandxdgshell_p.h
+index 96785205..4b518f0a 100644
+--- a/qtwayland/src/plugins/shellintegration/xdg-shell/qwaylandxdgshell_p.h
++++ b/qtwayland/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/qtwayland/src/plugins/shellintegration/xdg-shell/qwaylandxdgshellintegration.cpp b/qtwayland/src/plugins/shellintegration/xdg-shell/qwaylandxdgshellintegration.cpp
+index 8769d971..da0dd6a7 100644
+--- a/qtwayland/src/plugins/shellintegration/xdg-shell/qwaylandxdgshellintegration.cpp
++++ b/qtwayland/src/plugins/shellintegration/xdg-shell/qwaylandxdgshellintegration.cpp
+@@ -69,20 +69,6 @@ QWaylandShellSurface *QWaylandXdgShellIntegration::createShellSurface(QWaylandWi
+ return m_xdgShell->getXdgSurface(window);
+ }
+
+-void QWaylandXdgShellIntegration::handleKeyboardFocusChanged(QWaylandWindow *newFocus, QWaylandWindow *oldFocus)
+-{
+- if (newFocus) {
+- auto *xdgSurface = qobject_cast<QWaylandXdgSurface *>(newFocus->shellSurface());
+- if (xdgSurface && !xdgSurface->handlesActiveState())
+- m_display->handleWindowActivated(newFocus);
+- }
+- if (oldFocus && qobject_cast<QWaylandXdgSurface *>(oldFocus->shellSurface())) {
+- auto *xdgSurface = qobject_cast<QWaylandXdgSurface *>(oldFocus->shellSurface());
+- if (xdgSurface && !xdgSurface->handlesActiveState())
+- m_display->handleWindowDeactivated(oldFocus);
+- }
+-}
+-
+ }
+
+ QT_END_NAMESPACE
+diff --git a/qtwayland/src/plugins/shellintegration/xdg-shell/qwaylandxdgshellintegration_p.h b/qtwayland/src/plugins/shellintegration/xdg-shell/qwaylandxdgshellintegration_p.h
+index b6caa6c9..2f929f98 100644
+--- a/qtwayland/src/plugins/shellintegration/xdg-shell/qwaylandxdgshellintegration_p.h
++++ b/qtwayland/src/plugins/shellintegration/xdg-shell/qwaylandxdgshellintegration_p.h
+@@ -65,7 +65,6 @@ public:
+ QWaylandXdgShellIntegration() {}
+ bool initialize(QWaylandDisplay *display) override;
+ QWaylandShellSurface *createShellSurface(QWaylandWindow *window) override;
+- void handleKeyboardFocusChanged(QWaylandWindow *newFocus, QWaylandWindow *oldFocus) override;
+
+ private:
+ QScopedPointer<QWaylandXdgShell> m_xdgShell;
+diff --git a/qtwayland/src/shared/qwaylandinputmethodeventbuilder.cpp b/qtwayland/src/shared/qwaylandinputmethodeventbuilder.cpp
+index 526d0ef4..f50ccf30 100644
+--- a/qtwayland/src/shared/qwaylandinputmethodeventbuilder.cpp
++++ b/qtwayland/src/shared/qwaylandinputmethodeventbuilder.cpp
+@@ -39,7 +39,10 @@
+
+ #include "qwaylandinputmethodeventbuilder_p.h"
+
++#include <QBrush>
++#include <QGuiApplication>
+ #include <QInputMethod>
++#include <QPalette>
+ #include <QTextCharFormat>
+
+ #ifdef QT_BUILD_WAYLANDCOMPOSITOR_LIB
+@@ -81,32 +84,38 @@ void QWaylandInputMethodEventBuilder::addPreeditStyling(uint32_t index, uint32_t
+ QTextCharFormat format;
+
+ switch (style) {
+- case 0:
+- case 1:
++ case ZWP_TEXT_INPUT_V2_PREEDIT_STYLE_NONE:
++ break;
++ case ZWP_TEXT_INPUT_V2_PREEDIT_STYLE_DEFAULT:
++ case ZWP_TEXT_INPUT_V2_PREEDIT_STYLE_UNDERLINE:
+ format.setFontUnderline(true);
+ format.setUnderlineStyle(QTextCharFormat::SingleUnderline);
+ m_preeditStyles.append(QInputMethodEvent::Attribute(QInputMethodEvent::TextFormat, index, length, format));
+ break;
+- case 2:
+- case 3:
++ case ZWP_TEXT_INPUT_V2_PREEDIT_STYLE_ACTIVE:
++ case ZWP_TEXT_INPUT_V2_PREEDIT_STYLE_INACTIVE:
+ format.setFontWeight(QFont::Bold);
+ format.setFontUnderline(true);
+ format.setUnderlineStyle(QTextCharFormat::SingleUnderline);
+ m_preeditStyles.append(QInputMethodEvent::Attribute(QInputMethodEvent::TextFormat, index, length, format));
+ break;
+- case 4:
+- format.setFontUnderline(true);
+- format.setUnderlineStyle(QTextCharFormat::SingleUnderline);
+- m_preeditStyles.append(QInputMethodEvent::Attribute(QInputMethodEvent::TextFormat, index, length, format));
++ case ZWP_TEXT_INPUT_V2_PREEDIT_STYLE_HIGHLIGHT:
++ case ZWP_TEXT_INPUT_V2_PREEDIT_STYLE_SELECTION:
++ {
++ format.setFontUnderline(true);
++ format.setUnderlineStyle(QTextCharFormat::SingleUnderline);
++ QPalette palette = qApp->palette();
++ format.setBackground(QBrush(palette.color(QPalette::Active, QPalette::Highlight)));
++ format.setForeground(QBrush(palette.color(QPalette::Active, QPalette::HighlightedText)));
++ m_preeditStyles.append(QInputMethodEvent::Attribute(QInputMethodEvent::TextFormat, index, length, format));
++ }
+ break;
+- case 5:
++ case ZWP_TEXT_INPUT_V2_PREEDIT_STYLE_INCORRECT:
+ format.setFontUnderline(true);
+ format.setUnderlineStyle(QTextCharFormat::WaveUnderline);
+ format.setUnderlineColor(QColor(Qt::red));
+ m_preeditStyles.append(QInputMethodEvent::Attribute(QInputMethodEvent::TextFormat, index, length, format));
+ break;
+-// case QtWayland::wl_text_input::preedit_style_selection:
+-// case QtWayland::wl_text_input::preedit_style_none:
+ default:
+ break;
+ }
+@@ -153,7 +162,7 @@ QInputMethodEvent QWaylandInputMethodEventBuilder::buildPreedit(const QString &t
+
+ if (m_preeditCursor < 0) {
+ attributes.append(QInputMethodEvent::Attribute(QInputMethodEvent::Cursor, 0, 0, QVariant()));
+- } else if (m_preeditCursor > 0) {
++ } else {
+ attributes.append(QInputMethodEvent::Attribute(QInputMethodEvent::Cursor, indexFromWayland(text, m_preeditCursor), 1, QVariant()));
+ }
+
+diff --git a/qtwayland/src/shared/qwaylandmimehelper.cpp b/qtwayland/src/shared/qwaylandmimehelper.cpp
+index a5fdd34d..e2fe1928 100644
+--- a/qtwayland/src/shared/qwaylandmimehelper.cpp
++++ b/qtwayland/src/shared/qwaylandmimehelper.cpp
+@@ -60,7 +60,7 @@ QByteArray QWaylandMimeHelper::getByteArray(QMimeData *mimeData, const QString &
+ buf.open(QIODevice::ReadWrite);
+ QByteArray fmt = "BMP";
+ if (mimeType.startsWith(QLatin1String("image/"))) {
+- QByteArray imgFmt = mimeType.mid(6).toUpper().toLatin1();
++ QByteArray imgFmt = mimeType.mid(6).toLower().toLatin1();
+ if (QImageWriter::supportedImageFormats().contains(imgFmt))
+ fmt = imgFmt;
+ }
+@@ -74,7 +74,7 @@ QByteArray QWaylandMimeHelper::getByteArray(QMimeData *mimeData, const QString &
+ QList<QUrl> urls = mimeData->urls();
+ for (int i = 0; i < urls.count(); ++i) {
+ content.append(urls.at(i).toEncoded());
+- content.append('\n');
++ content.append("\r\n");
+ }
+ } else {
+ content = mimeData->data(mimeType);
+diff --git a/qtwayland/tests/auto/client/datadevicev1/tst_datadevicev1.cpp b/qtwayland/tests/auto/client/datadevicev1/tst_datadevicev1.cpp
+index 1568b3b9..067410d0 100644
+--- a/qtwayland/tests/auto/client/datadevicev1/tst_datadevicev1.cpp
++++ b/qtwayland/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:
+diff --git a/qtwayland/tests/auto/client/seatv5/tst_seatv5.cpp b/qtwayland/tests/auto/client/seatv5/tst_seatv5.cpp
+index 9312c2e5..2ea382f1 100644
+--- a/qtwayland/tests/auto/client/seatv5/tst_seatv5.cpp
++++ b/qtwayland/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, Qt::TouchPointPressed);
++ QCOMPARE(e.touchPoints.length(), 1);
++ QCOMPARE(e.touchPoints.first().pos(), 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/qtwayland/tests/auto/client/shared/corecompositor.cpp b/qtwayland/tests/auto/client/shared/corecompositor.cpp
+index 5c6c83ba..fa9b7662 100644
+--- a/qtwayland/tests/auto/client/shared/corecompositor.cpp
++++ b/qtwayland/tests/auto/client/shared/corecompositor.cpp
+@@ -27,6 +27,7 @@
+ ****************************************************************************/
+
+ #include "corecompositor.h"
++#include <thread>
+
+ namespace MockCompositor {
+
+diff --git a/qtwayland/tests/auto/client/shared/coreprotocol.cpp b/qtwayland/tests/auto/client/shared/coreprotocol.cpp
+index 0d988521..d1a2e7cb 100644
+--- a/qtwayland/tests/auto/client/shared/coreprotocol.cpp
++++ b/qtwayland/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/qtwayland/tests/auto/client/shared/coreprotocol.h b/qtwayland/tests/auto/client/shared/coreprotocol.h
+index a1af137a..210d8ddb 100644
+--- a/qtwayland/tests/auto/client/shared/coreprotocol.h
++++ b/qtwayland/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)
+ {}
+@@ -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;
+ };
+diff --git a/qtwayland/tests/auto/client/shared_old/mockcompositor.cpp b/qtwayland/tests/auto/client/shared_old/mockcompositor.cpp
+index a415cbf5..b1d3d07d 100644
+--- a/qtwayland/tests/auto/client/shared_old/mockcompositor.cpp
++++ b/qtwayland/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/qtwayland/tests/auto/client/shared_old/mocksurface.cpp b/qtwayland/tests/auto/client/shared_old/mocksurface.cpp
+index e9df5f90..c3246e4a 100644
+--- a/qtwayland/tests/auto/client/shared_old/mocksurface.cpp
++++ b/qtwayland/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/qtwayland/tests/auto/client/shared_old/mocksurface.h b/qtwayland/tests/auto/client/shared_old/mocksurface.h
+index 949dc23d..d176837e 100644
+--- a/qtwayland/tests/auto/client/shared_old/mocksurface.h
++++ b/qtwayland/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;
+diff --git a/qtwayland/tests/auto/client/surface/tst_surface.cpp b/qtwayland/tests/auto/client/surface/tst_surface.cpp
+index 95e4e609..60c672ce 100644
+--- a/qtwayland/tests/auto/client/surface/tst_surface.cpp
++++ b/qtwayland/tests/auto/client/surface/tst_surface.cpp
+@@ -129,6 +129,10 @@ void tst_surface::waitForFrameCallbackGl()
+ // Make sure we follow frame callbacks for some frames
+ for (int i = 0; i < 5; ++i) {
+ xdgPingAndWaitForPong(); // Make sure things have happened on the client
++ if (!qEnvironmentVariableIntValue("QT_WAYLAND_DISABLE_WINDOWDECORATION") && i == 0) {
++ QCOMPARE(bufferSpy.count(), 1);
++ bufferSpy.removeFirst();
++ }
+ exec([&] {
+ QVERIFY(bufferSpy.empty()); // Make sure no extra buffers have arrived
+ QVERIFY(!xdgToplevel()->surface()->m_waitingFrameCallbacks.empty());
+diff --git a/qtwayland/tests/auto/client/xdgshell/tst_xdgshell.cpp b/qtwayland/tests/auto/client/xdgshell/tst_xdgshell.cpp
+index 2277bbb8..747875b4 100644
+--- a/qtwayland/tests/auto/client/xdgshell/tst_xdgshell.cpp
++++ b/qtwayland/tests/auto/client/xdgshell/tst_xdgshell.cpp
+@@ -31,6 +31,7 @@
+ #include <QtGui/QOpenGLWindow>
+ #include <QtGui/qpa/qplatformnativeinterface.h>
+ #include <QtWaylandClient/private/wayland-wayland-client-protocol.h>
++#include <QtWaylandClient/private/qwaylandwindow_p.h>
+
+ using namespace MockCompositor;
+
+@@ -45,6 +46,7 @@ private slots:
+ void configureStates();
+ void popup();
+ void tooltipOnPopup();
++ void tooltipAndSiblingPopup();
+ void switchPopups();
+ void hidePopupParent();
+ void pongs();
+@@ -138,6 +140,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();
+@@ -154,9 +157,12 @@ void tst_xdgshell::configureStates()
+ // 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
+
+-// QEXPECT_FAIL("", "configure has already been acked, we shouldn't have to wait for isActive", Continue);
+-// QVERIFY(window.isActive());
+- QTRY_VERIFY(window.isActive()); // Just make sure it eventually get's set correctly
++ // window.windowstate() is driven by keyboard focus, however for decorations we want to follow
++ // XDGShell this is internal to QtWayland so it is queried directly
++ auto waylandWindow = static_cast<QtWaylandClient::QWaylandWindow *>(window.handle());
++ Q_ASSERT(waylandWindow);
++ QTRY_VERIFY(waylandWindow->windowStates().testFlag(
++ Qt::WindowActive)); // Just make sure it eventually get's set correctly
+
+ const QSize screenSize(640, 480);
+ const uint maximizedSerial = exec([=] {
+@@ -186,6 +192,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()
+@@ -340,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()
+ {
+@@ -505,7 +598,7 @@ void tst_xdgshell::minMaxSize()
+ window.show();
+ QCOMPOSITOR_TRY_VERIFY(xdgToplevel());
+
+- exec([=] { xdgToplevel()->sendCompleteConfigure(); });
++ // we don't roundtrip with our configuration the initial commit should be correct
+
+ QCOMPOSITOR_TRY_COMPARE(xdgToplevel()->m_committed.minSize, QSize(100, 100));
+ QCOMPOSITOR_TRY_COMPARE(xdgToplevel()->m_committed.maxSize, QSize(1000, 1000));
+Submodule qtwebchannel 618422ee..f8949655:
+diff --git a/qtwebchannel/src/webchannel/qmetaobjectpublisher.cpp b/qtwebchannel/src/webchannel/qmetaobjectpublisher.cpp
+index 536eb5c..898d769 100644
+--- a/qtwebchannel/src/webchannel/qmetaobjectpublisher.cpp
++++ b/qtwebchannel/src/webchannel/qmetaobjectpublisher.cpp
+@@ -186,8 +186,6 @@ Q_DECLARE_TYPEINFO(OverloadResolutionCandidate, Q_MOVABLE_TYPE);
+ QMetaObjectPublisher::QMetaObjectPublisher(QWebChannel *webChannel)
+ : QObject(webChannel)
+ , webChannel(webChannel)
+- , signalHandler(this)
+- , clientIsIdle(false)
+ , blockUpdates(false)
+ , propertyUpdatesInitialized(false)
+ {
+@@ -301,17 +299,17 @@ QJsonObject QMetaObjectPublisher::classInfoForObject(const QObject *object, QWeb
+ return data;
+ }
+
+-void QMetaObjectPublisher::setClientIsIdle(bool isIdle)
++void QMetaObjectPublisher::setClientIsIdle(bool isIdle, QWebChannelAbstractTransport *transport)
+ {
+- if (clientIsIdle == isIdle) {
+- return;
+- }
+- clientIsIdle = isIdle;
+- if (!isIdle && timer.isActive()) {
+- timer.stop();
+- } else if (isIdle && !timer.isActive()) {
+- timer.start(PROPERTY_UPDATE_INTERVAL, this);
+- }
++ transportState[transport].clientIsIdle = isIdle;
++ if (isIdle)
++ sendEnqueuedPropertyUpdates(transport);
++}
++
++bool QMetaObjectPublisher::isClientIdle(QWebChannelAbstractTransport *transport)
++{
++ auto found = transportState.find(transport);
++ return found != transportState.end() && found.value().clientIsIdle;
+ }
+
+ QJsonObject QMetaObjectPublisher::initializeClient(QWebChannelAbstractTransport *transport)
+@@ -333,6 +331,7 @@ QJsonObject QMetaObjectPublisher::initializeClient(QWebChannelAbstractTransport
+
+ void QMetaObjectPublisher::initializePropertyUpdates(const QObject *const object, const QJsonObject &objectInfo)
+ {
++ auto *signalHandler = signalHandlerFor(object);
+ foreach (const QJsonValue &propertyInfoVar, objectInfo[KEY_PROPERTIES].toArray()) {
+ const QJsonArray &propertyInfo = propertyInfoVar.toArray();
+ if (propertyInfo.size() < 2) {
+@@ -353,19 +352,19 @@ void QMetaObjectPublisher::initializePropertyUpdates(const QObject *const object
+
+ // Only connect for a property update once
+ if (connectedProperties.isEmpty()) {
+- signalHandler.connectTo(object, signalIndex);
++ signalHandler->connectTo(object, signalIndex);
+ }
+
+ connectedProperties.insert(propertyIndex);
+ }
+
+ // also always connect to destroyed signal
+- signalHandler.connectTo(object, s_destroyedSignalIndex);
++ signalHandler->connectTo(object, s_destroyedSignalIndex);
+ }
+
+ void QMetaObjectPublisher::sendPendingPropertyUpdates()
+ {
+- if (blockUpdates || !clientIsIdle || pendingPropertyUpdates.isEmpty()) {
++ if (blockUpdates) {
+ return;
+ }
+
+@@ -415,18 +414,19 @@ void QMetaObjectPublisher::sendPendingPropertyUpdates()
+
+ // data does not contain specific updates
+ if (!data.isEmpty()) {
+- setClientIsIdle(false);
+-
+ message[KEY_DATA] = data;
+- broadcastMessage(message);
++ enqueueBroadcastMessage(message);
+ }
+
+ // send every property update which is not supposed to be broadcasted
+ const QHash<QWebChannelAbstractTransport*, QJsonArray>::const_iterator suend = specificUpdates.constEnd();
+ for (QHash<QWebChannelAbstractTransport*, QJsonArray>::const_iterator it = specificUpdates.constBegin(); it != suend; ++it) {
+ message[KEY_DATA] = it.value();
+- it.key()->sendMessage(message);
++ enqueueMessage(message, it.key());
+ }
++
++ for (auto state = transportState.begin(); state != transportState.end(); ++state)
++ sendEnqueuedPropertyUpdates(state.key());
+ }
+
+ QVariant QMetaObjectPublisher::invokeMethod(QObject *const object, const QMetaMethod &method,
+@@ -572,7 +572,7 @@ void QMetaObjectPublisher::signalEmitted(const QObject *object, const int signal
+ }
+ } else {
+ pendingPropertyUpdates[object][signalIndex] = arguments;
+- if (clientIsIdle && !blockUpdates && !timer.isActive()) {
++ if (!blockUpdates && !timer.isActive()) {
+ timer.start(PROPERTY_UPDATE_INTERVAL, this);
+ }
+ }
+@@ -590,7 +590,7 @@ void QMetaObjectPublisher::objectDestroyed(const QObject *object)
+ // only remove from handler when we initialized the property updates
+ // cf: https://bugreports.qt.io/browse/QTBUG-60250
+ if (propertyUpdatesInitialized) {
+- signalHandler.remove(object);
++ signalHandlerFor(object)->remove(object);
+ signalToPropertyMap.remove(object);
+ }
+ pendingPropertyUpdates.remove(object);
+@@ -852,6 +852,52 @@ void QMetaObjectPublisher::broadcastMessage(const QJsonObject &message) const
+ }
+ }
+
++void QMetaObjectPublisher::enqueueBroadcastMessage(const QJsonObject &message)
++{
++ if (webChannel->d_func()->transports.isEmpty()) {
++ qWarning("QWebChannel is not connected to any transports, cannot send message: %s",
++ QJsonDocument(message).toJson().constData());
++ return;
++ }
++
++ for (auto *transport : webChannel->d_func()->transports) {
++ auto &state = transportState[transport];
++ state.queuedMessages.append(message);
++ }
++}
++
++void QMetaObjectPublisher::enqueueMessage(const QJsonObject &message,
++ QWebChannelAbstractTransport *transport)
++{
++ auto &state = transportState[transport];
++ state.queuedMessages.append(message);
++}
++
++void QMetaObjectPublisher::sendEnqueuedPropertyUpdates(QWebChannelAbstractTransport *transport)
++{
++ auto found = transportState.find(transport);
++ if (found != transportState.end() && found.value().clientIsIdle
++ && !found.value().queuedMessages.isEmpty()) {
++
++ // If the client is connected with an in-process transport, it can
++ // happen that a message triggers a subsequent property change. In
++ // that case, we need to ensure that the queued messages have already
++ // been cleared; otherwise the recursive call will send everythig again.
++ // Case in point: The qmlwebchannel tests fail if we don't clear the
++ // queued messages before sending them out.
++ // For that same reason set the client to "busy" (aka non-idle) just
++ // right before sending out the messages; otherwise a potential
++ // "Idle" type message will not correctly restore the Idle state.
++ const auto messages = std::move(found.value().queuedMessages);
++ Q_ASSERT(found.value().queuedMessages.isEmpty());
++ found.value().clientIsIdle = false;
++
++ for (const auto &message : messages) {
++ transport->sendMessage(message);
++ }
++ }
++}
++
+ void QMetaObjectPublisher::handleMessage(const QJsonObject &message, QWebChannelAbstractTransport *transport)
+ {
+ if (!webChannel->d_func()->transports.contains(transport)) {
+@@ -866,7 +912,7 @@ void QMetaObjectPublisher::handleMessage(const QJsonObject &message, QWebChannel
+
+ const MessageType type = toType(message.value(KEY_TYPE));
+ if (type == TypeIdle) {
+- setClientIsIdle(true);
++ setClientIsIdle(true, transport);
+ } else if (type == TypeInit) {
+ if (!message.contains(KEY_ID)) {
+ qWarning("JSON message object is missing the id property: %s",
+@@ -913,9 +959,9 @@ void QMetaObjectPublisher::handleMessage(const QJsonObject &message, QWebChannel
+ return;
+ transport->sendMessage(createResponse(message.value(KEY_ID), wrapResult(result, transport)));
+ } else if (type == TypeConnectToSignal) {
+- signalHandler.connectTo(object, message.value(KEY_SIGNAL).toInt(-1));
++ signalHandlerFor(object)->connectTo(object, message.value(KEY_SIGNAL).toInt(-1));
+ } else if (type == TypeDisconnectFromSignal) {
+- signalHandler.disconnectFrom(object, message.value(KEY_SIGNAL).toInt(-1));
++ signalHandlerFor(object)->disconnectFrom(object, message.value(KEY_SIGNAL).toInt(-1));
+ } else if (type == TypeSetProperty) {
+ setProperty(object, message.value(KEY_PROPERTY).toInt(-1),
+ message.value(KEY_VALUE));
+@@ -931,6 +977,7 @@ void QMetaObjectPublisher::setBlockUpdates(bool block)
+ blockUpdates = block;
+
+ if (!blockUpdates) {
++ timer.start(PROPERTY_UPDATE_INTERVAL, this);
+ sendPendingPropertyUpdates();
+ } else if (timer.isActive()) {
+ timer.stop();
+@@ -948,4 +995,15 @@ void QMetaObjectPublisher::timerEvent(QTimerEvent *event)
+ }
+ }
+
++SignalHandler<QMetaObjectPublisher> *QMetaObjectPublisher::signalHandlerFor(const QObject *object)
++{
++ auto thread = object->thread();
++ auto it = signalHandlers.find(thread);
++ if (it == signalHandlers.end()) {
++ it = signalHandlers.emplace(thread, this).first;
++ it->second.moveToThread(thread);
++ }
++ return &it->second;
++}
++
+ QT_END_NAMESPACE
+diff --git a/qtwebchannel/src/webchannel/qmetaobjectpublisher_p.h b/qtwebchannel/src/webchannel/qmetaobjectpublisher_p.h
+index bbd9875..4713ef1 100644
+--- a/qtwebchannel/src/webchannel/qmetaobjectpublisher_p.h
++++ b/qtwebchannel/src/webchannel/qmetaobjectpublisher_p.h
+@@ -59,6 +59,9 @@
+ #include <QBasicTimer>
+ #include <QPointer>
+ #include <QJsonObject>
++#include <QQueue>
++
++#include <unordered_map>
+
+ #include "qwebchannelglobal.h"
+
+@@ -109,17 +112,36 @@ public:
+ */
+ void broadcastMessage(const QJsonObject &message) const;
+
++ /**
++ * Enqueue the given @p message to all known transports.
++ */
++ void enqueueBroadcastMessage(const QJsonObject &message);
++
++ /**
++ * Enqueue the given @p message to @p transport.
++ */
++ void enqueueMessage(const QJsonObject &message, QWebChannelAbstractTransport *transport);
++
++ /**
++ * If client for given @p transport is idle, send queued messaged to @p transport and then mark
++ * the client as not idle.
++ */
++ void sendEnqueuedPropertyUpdates(QWebChannelAbstractTransport *transport);
++
+ /**
+ * Serialize the QMetaObject of @p object and return it in JSON form.
+ */
+ QJsonObject classInfoForObject(const QObject *object, QWebChannelAbstractTransport *transport);
+
+ /**
+- * Set the client to idle or busy, based on the value of @p isIdle.
+- *
+- * When the value changed, start/stop the property update timer accordingly.
++ * Set the client to idle or busy for a single @p transport, based on the value of @p isIdle.
++ */
++ void setClientIsIdle(bool isIdle, QWebChannelAbstractTransport *transport);
++
++ /**
++ * Check that client is idle for @p transport.
+ */
+- void setClientIsIdle(bool isIdle);
++ bool isClientIdle(QWebChannelAbstractTransport *transport);
+
+ /**
+ * Initialize clients by sending them the class information of the registered objects.
+@@ -272,10 +294,18 @@ private:
+ friend class TestWebChannel;
+
+ QWebChannel *webChannel;
+- SignalHandler<QMetaObjectPublisher> signalHandler;
++ std::unordered_map<const QThread*, SignalHandler<QMetaObjectPublisher>> signalHandlers;
++ SignalHandler<QMetaObjectPublisher> *signalHandlerFor(const QObject *object);
+
+- // true when the client is idle, false otherwise
+- bool clientIsIdle;
++ struct TransportState
++ {
++ TransportState() : clientIsIdle(false) { }
++ // true when the client is idle, false otherwise
++ bool clientIsIdle;
++ // messages to send
++ QQueue<QJsonObject> queuedMessages;
++ };
++ QHash<QWebChannelAbstractTransport *, TransportState> transportState;
+
+ // true when no property updates should be sent, false otherwise
+ bool blockUpdates;
+diff --git a/qtwebchannel/src/webchannel/signalhandler_p.h b/qtwebchannel/src/webchannel/signalhandler_p.h
+index 27afadb..d77373c 100644
+--- a/qtwebchannel/src/webchannel/signalhandler_p.h
++++ b/qtwebchannel/src/webchannel/signalhandler_p.h
+@@ -56,6 +56,7 @@
+ #include <QVector>
+ #include <QMetaMethod>
+ #include <QDebug>
++#include <QThread>
+
+ QT_BEGIN_NAMESPACE
+
+@@ -71,6 +72,7 @@ static const int s_destroyedSignalIndex = QObject::staticMetaObject.indexOfMetho
+ template<class Receiver>
+ class SignalHandler : public QObject
+ {
++ Q_DISABLE_COPY(SignalHandler)
+ public:
+ SignalHandler(Receiver *receiver, QObject *parent = 0);
+
+@@ -268,6 +270,7 @@ int SignalHandler<Receiver>::qt_metacall(QMetaObject::Call call, int methodId, v
+ if (call == QMetaObject::InvokeMetaMethod) {
+ const QObject *object = sender();
+ Q_ASSERT(object);
++ Q_ASSERT(QThread::currentThread() == object->thread());
+ Q_ASSERT(senderSignalIndex() == methodId);
+ Q_ASSERT(m_connectionsCounter.contains(object));
+ Q_ASSERT(m_connectionsCounter.value(object).contains(methodId));
+diff --git a/qtwebchannel/tests/auto/qml/testwebchannel.cpp b/qtwebchannel/tests/auto/qml/testwebchannel.cpp
+index 9891687..3ca81c2 100644
+--- a/qtwebchannel/tests/auto/qml/testwebchannel.cpp
++++ b/qtwebchannel/tests/auto/qml/testwebchannel.cpp
+@@ -46,7 +46,11 @@ TestWebChannel::~TestWebChannel()
+
+ bool TestWebChannel::clientIsIdle() const
+ {
+- return QWebChannel::d_func()->publisher->clientIsIdle;
++ for (auto *transport : QWebChannel::d_func()->transports) {
++ if (QWebChannel::d_func()->publisher->isClientIdle(transport))
++ return true;
++ }
++ return false;
+ }
+
+ QT_END_NAMESPACE
+diff --git a/qtwebchannel/tests/auto/webchannel/tst_webchannel.cpp b/qtwebchannel/tests/auto/webchannel/tst_webchannel.cpp
+index 181da9e..37f989a 100644
+--- a/qtwebchannel/tests/auto/webchannel/tst_webchannel.cpp
++++ b/qtwebchannel/tests/auto/webchannel/tst_webchannel.cpp
+@@ -785,7 +785,7 @@ void TestWebChannel::testTransportWrapObjectProperties()
+ DummyTransport *dummyTransport = new DummyTransport(this);
+ channel.connectTo(dummyTransport);
+ channel.d_func()->publisher->initializeClient(dummyTransport);
+- channel.d_func()->publisher->setClientIsIdle(true);
++ channel.d_func()->publisher->setClientIsIdle(true, dummyTransport);
+
+ QCOMPARE(channel.d_func()->publisher->transportedWrappedObjects.size(), 0);
+
+@@ -943,8 +943,6 @@ void TestWebChannel::testInfiniteRecursion()
+
+ void TestWebChannel::testAsyncObject()
+ {
+- QSKIP("This test is broken. See QTBUG-80729");
+-
+ QWebChannel channel;
+ channel.connectTo(m_dummyTransport);
+
+@@ -990,6 +988,50 @@ void TestWebChannel::testAsyncObject()
+ thread.wait();
+ }
+
++void TestWebChannel::testPropertyMultipleTransports()
++{
++ DummyTransport transport1;
++ DummyTransport transport2;
++
++ QWebChannel channel;
++ QMetaObjectPublisher *publisher = channel.d_func()->publisher;
++
++ TestObject testObj;
++ testObj.setObjectName("testObject");
++ channel.registerObject(testObj.objectName(), &testObj);
++ channel.connectTo(&transport1);
++ channel.connectTo(&transport2);
++
++ testObj.setProp("Hello");
++
++ publisher->initializeClient(&transport1);
++ publisher->initializeClient(&transport2);
++ publisher->setClientIsIdle(true, &transport1);
++ QCOMPARE(publisher->isClientIdle(&transport1), true);
++ QCOMPARE(publisher->isClientIdle(&transport2), false);
++ QVERIFY(transport1.messagesSent().isEmpty());
++ QVERIFY(transport2.messagesSent().isEmpty());
++
++ testObj.setProp("World");
++ QTRY_COMPARE_WITH_TIMEOUT(transport1.messagesSent().size(), 1u, 2000);
++ QCOMPARE(transport2.messagesSent().size(), 0u);
++ publisher->setClientIsIdle(true, &transport2);
++ QTRY_COMPARE_WITH_TIMEOUT(transport2.messagesSent().size(), 1u, 2000);
++ QCOMPARE(publisher->isClientIdle(&transport1), false);
++ QCOMPARE(publisher->isClientIdle(&transport2), false);
++
++ testObj.setProp("!!!");
++ publisher->setClientIsIdle(true, &transport2);
++ QCOMPARE(publisher->isClientIdle(&transport2), true);
++ QCOMPARE(publisher->isClientIdle(&transport1), false);
++ QTRY_COMPARE_WITH_TIMEOUT(transport2.messagesSent().size(), 2u, 2000);
++ QCOMPARE(transport1.messagesSent().size(), 1u);
++ publisher->setClientIsIdle(true, &transport1);
++ QTRY_COMPARE_WITH_TIMEOUT(transport1.messagesSent().size(), 2u, 2000);
++ QCOMPARE(publisher->isClientIdle(&transport1), false);
++ QCOMPARE(publisher->isClientIdle(&transport2), false);
++}
++
+ class FunctionWrapper : public QObject
+ {
+ Q_OBJECT
+@@ -1082,7 +1124,7 @@ void TestWebChannel::benchInitializeClients()
+
+ publisher->propertyUpdatesInitialized = false;
+ publisher->signalToPropertyMap.clear();
+- publisher->signalHandler.clear();
++ publisher->signalHandlers.clear();
+ }
+ }
+
+@@ -1107,7 +1149,7 @@ void TestWebChannel::benchPropertyUpdates()
+ obj->change();
+ }
+
+- channel.d_func()->publisher->clientIsIdle = true;
++ channel.d_func()->publisher->setClientIsIdle(true, m_dummyTransport);
+ channel.d_func()->publisher->sendPendingPropertyUpdates();
+ }
+ }
+diff --git a/qtwebchannel/tests/auto/webchannel/tst_webchannel.h b/qtwebchannel/tests/auto/webchannel/tst_webchannel.h
+index eae21f4..dd4e690 100644
+--- a/qtwebchannel/tests/auto/webchannel/tst_webchannel.h
++++ b/qtwebchannel/tests/auto/webchannel/tst_webchannel.h
+@@ -348,6 +348,7 @@ private slots:
+ void testJsonToVariant();
+ void testInfiniteRecursion();
+ void testAsyncObject();
++ void testPropertyMultipleTransports();
+ void testDeletionDuringMethodInvocation_data();
+ void testDeletionDuringMethodInvocation();
+
+Submodule qtwebengine f328054d...38e0df6c (commits not present)
+Submodule qtwebsockets 65850954..63fb8da1:
+diff --git a/qtwebsockets/src/websockets/qwebsocketdataprocessor.cpp b/qtwebsockets/src/websockets/qwebsocketdataprocessor.cpp
+index 2affdd5..95f1194 100644
+--- a/qtwebsockets/src/websockets/qwebsocketdataprocessor.cpp
++++ b/qtwebsockets/src/websockets/qwebsocketdataprocessor.cpp
+@@ -273,6 +273,7 @@ void QWebSocketDataProcessor::clear()
+ if (!m_pConverterState)
+ m_pConverterState = new QTextCodec::ConverterState(QTextCodec::ConvertInvalidToNull |
+ QTextCodec::IgnoreHeader);
++ frame.clear();
+ }
+
+ /*!
+diff --git a/qtwebsockets/src/websockets/qwebsocketprotocol.cpp b/qtwebsockets/src/websockets/qwebsocketprotocol.cpp
+index df87a93..d0465f1 100644
+--- a/qtwebsockets/src/websockets/qwebsocketprotocol.cpp
++++ b/qtwebsockets/src/websockets/qwebsocketprotocol.cpp
+@@ -210,7 +210,7 @@ void QWebSocketProtocol::mask(char *payload, quint64 size, quint32 maskingKey)
+ quint8((maskingKey & 0x0000FF00u) >> 8),
+ quint8((maskingKey & 0x000000FFu))
+ };
+- int i = 0;
++ quint64 i = 0;
+ while (size-- > 0)
+ *payload++ ^= mask[i++ % 4];
+ }
diff --git a/srcpkgs/qt5/template b/srcpkgs/qt5/template
index e0463e1c9198..ca1800ce9dc2 100644
--- a/srcpkgs/qt5/template
+++ b/srcpkgs/qt5/template
@@ -2,11 +2,11 @@
#
# revbump libqtxdg after bumping patch version
pkgname=qt5
-version=5.15.7+20221119
+version=5.15.8
+revision=1
+build_style=meta
# commit f8c9fb304bc3e53b3aa07f962cd74e9160decccc
# base repo: https://invent.kde.org/qt/qt/qt5
-revision=4
-build_style=meta
hostmakedepends="cmake clang flex perl glib-devel pkg-config
python re2c ruby which"
makedepends="SDL2-devel Vulkan-Headers alsa-lib-devel double-conversion-devel
@@ -29,8 +29,9 @@ homepage="https://qt.io/"
# tarball is generated with `git archive-all qt5-$version.tar.gz`
# to keep the size smaller qtwebengine, qtwebview, qtdocgallery, qtactiveqt and qtpim
# can be marked with the export-ignore attribute
-distfiles="https://void.johnnynator.dev/distfiles/qt5-${version}.tar.gz"
-checksum=9d57af471c78029a362276b7c99108ea009f511bb9ba6ff6cb884f6ddd255e9f
+#distfiles="https://void.johnnynator.dev/distfiles/qt5-${version}.tar.gz"
+distfiles="https://download.qt.io/archive/qt/5.15/${version}/single/qt-everywhere-opensource-src-${version}.tar.xz"
+checksum=776a9302c336671f9406a53bd30b8e36f825742b2ec44a57c08217bff0fa86b9
python_version=2 #unverified
replaces="qt5-doc<5.6.0 qt5-quick1<5.6.0 qt5-quick1-devel<5.6.0 qt5-webkit<5.6.0 qt5-webkit-devel<5.6.0
qt5-enginio<5.7.1 qt5-enginio-devel<5.7.1 qt5-plugin-gtk<5.7.1 qt5-canvas3d<5.13.0"
@@ -248,7 +249,6 @@ do_configure() {
# opts+=" -v"
opts+=" -skip qtwebengine"
opts+=" -skip qtwebview"
- opts+=" -skip qtdocgallery"
opts+=" -skip qtpim"
opts+=" -skip qtsystems"
opts+=" -skip qtspeech"
From bc1b61f20e8527594560f24f45043e0e6ef5d0fe Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:51 -0400
Subject: [PATCH 078/115] qt6-multimedia: revbump for ffmpeg-6.0
---
srcpkgs/qt6-multimedia/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/qt6-multimedia/template b/srcpkgs/qt6-multimedia/template
index d89e7d54eb5a..aae15e57ca7b 100644
--- a/srcpkgs/qt6-multimedia/template
+++ b/srcpkgs/qt6-multimedia/template
@@ -1,7 +1,7 @@
# Template file for 'qt6-multimedia'
pkgname=qt6-multimedia
version=6.4.2
-revision=1
+revision=2
build_style=cmake
configure_args="-DQT_FEATURE_gstreamer=ON"
hostmakedepends="perl qt6-declarative-host-tools pkg-config qt6-shadertools"
From 9d4d602553af339cd07c691b538f1984292a6466 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:51 -0400
Subject: [PATCH 079/115] qtav: revbump for ffmpeg4-4.4.3
---
srcpkgs/qtav/template | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/srcpkgs/qtav/template b/srcpkgs/qtav/template
index 34c30b2c0c78..2d00ad104355 100644
--- a/srcpkgs/qtav/template
+++ b/srcpkgs/qtav/template
@@ -1,10 +1,10 @@
# Template file for 'qtav'
pkgname=qtav
version=1.13.0
-revision=1
+revision=2
build_style=qmake
hostmakedepends="qt5-qmake qt5-host-tools"
-makedepends="ffmpeg-devel libass-devel libopenal-devel
+makedepends="ffmpeg4-devel libass-devel libopenal-devel
libva-glx-devel libXv-devel pulseaudio-devel
qt5-declarative-devel qt5-svg-devel
qt5-quickcontrols"
From 30c1a8bf19a1a96269d13bb4b8ea5708fc8bf5e7 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:51 -0400
Subject: [PATCH 080/115] qtox: revbump for ffmpeg-6.0
---
srcpkgs/qtox/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/qtox/template b/srcpkgs/qtox/template
index 16019d7eaec9..5cea0b11b697 100644
--- a/srcpkgs/qtox/template
+++ b/srcpkgs/qtox/template
@@ -1,7 +1,7 @@
# Template file for 'qtox'
pkgname=qtox
version=1.17.6
-revision=2
+revision=3
build_style=cmake
configure_args="-DUPDATE_CHECK=OFF
-DGIT_DESCRIBE=${version}
From e848b0ff4ea790765360a25c63ad70c67519e21c Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:51 -0400
Subject: [PATCH 081/115] retroarch: revbump for ffmpeg-6.0
---
srcpkgs/retroarch/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/retroarch/template b/srcpkgs/retroarch/template
index 240d3df9db00..6d0b16ae2598 100644
--- a/srcpkgs/retroarch/template
+++ b/srcpkgs/retroarch/template
@@ -1,7 +1,7 @@
# Template file for 'retroarch'
pkgname=retroarch
version=1.14.0
-revision=1
+revision=2
build_style=configure
configure_args="--prefix=/usr --sysconfdir=/etc --enable-networking
--enable-udev --disable-builtinflac --disable-builtinglslang
From 5a81d1ee2a40c7d3fbdc00b1746fb58b4999e1e8 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:51 -0400
Subject: [PATCH 082/115] scrcpy: revbump for ffmpeg-6.0
---
srcpkgs/scrcpy/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/scrcpy/template b/srcpkgs/scrcpy/template
index ee6e698e387f..8ada5ca4323f 100644
--- a/srcpkgs/scrcpy/template
+++ b/srcpkgs/scrcpy/template
@@ -1,7 +1,7 @@
# Template file for 'scrcpy'
pkgname=scrcpy
version=2.0
-revision=1
+revision=2
build_style=meson
configure_args="-Dcompile_server=false
-Dprebuilt_server=/usr/share/scrcpy/scrcpy-server-v${version}"
From 5e7b3a48d0c49ff7847ea1ec1717f14bb506cc63 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:51 -0400
Subject: [PATCH 083/115] spek-alternative: revbump for ffmpeg4-4.4.3
---
srcpkgs/spek-alternative/template | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/srcpkgs/spek-alternative/template b/srcpkgs/spek-alternative/template
index d65086b8f008..05246f1b8d0c 100644
--- a/srcpkgs/spek-alternative/template
+++ b/srcpkgs/spek-alternative/template
@@ -1,11 +1,11 @@
# Template file for 'spek-alternative'
pkgname=spek-alternative
version=0.8.2.3
-revision=1
+revision=2
build_style=gnu-configure
hostmakedepends="automake gettext-devel intltool libtool pkg-config wxWidgets-common"
-makedepends="ffmpeg-devel wxWidgets-gtk3-devel"
-depends="ffmpeg"
+makedepends="ffmpeg4-devel wxWidgets-gtk3-devel"
+depends="ffmpeg4"
short_desc="Acoustic spectrum analyser"
maintainer="Kartik Singh <kartik.ynwa@gmail.com>"
license="GPL-3.0-or-later"
From d45e8418d9577a9851b1f7e2529698fd1f8f3c30 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:51 -0400
Subject: [PATCH 084/115] ssr: revbump for ffmpeg4-4.4.3
---
srcpkgs/ssr/template | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/srcpkgs/ssr/template b/srcpkgs/ssr/template
index b055b9ec0774..3448ca110eb0 100644
--- a/srcpkgs/ssr/template
+++ b/srcpkgs/ssr/template
@@ -1,11 +1,11 @@
# Template file for 'ssr'
pkgname=ssr
version=0.4.4
-revision=1
+revision=2
build_style=cmake
configure_args="-DWITH_QT5=ON"
hostmakedepends="pkg-config"
-makedepends="alsa-lib-devel ffmpeg-devel glu-devel jack-devel pulseaudio-devel
+makedepends="alsa-lib-devel ffmpeg4-devel glu-devel jack-devel pulseaudio-devel
qt5-tools-devel qt5-x11extras-devel libXinerama-devel v4l-utils-devel"
depends="desktop-file-utils hicolor-icon-theme"
short_desc="Simple Screen Recorder for programs and games"
From 6b4a1fd078cddf3a170a3620aa9a31587e72a993 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:51 -0400
Subject: [PATCH 085/115] sumo: revbump for ffmpeg-6.0
---
srcpkgs/sumo/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/sumo/template b/srcpkgs/sumo/template
index 0f9b9ec815f5..a3fe134aa5ac 100644
--- a/srcpkgs/sumo/template
+++ b/srcpkgs/sumo/template
@@ -1,7 +1,7 @@
# Template file for 'sumo'
pkgname=sumo
version=1.12.0
-revision=5
+revision=6
build_style=cmake
hostmakedepends="libgdal-tools pkg-config swig python3-setuptools"
makedepends="python3-devel ffmpeg-devel fox-devel gl2ps-devel libgdal-devel
From 0518000ffbec1d52ab1f6278f5c02f6a006ea394 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:52 -0400
Subject: [PATCH 086/115] synfig: revbump for ffmpeg-6.0 and mlt7
---
srcpkgs/synfig/patches/ffmpeg6.patch | 71 ++++++++++++++++++++++++++++
srcpkgs/synfig/template | 4 +-
2 files changed, 73 insertions(+), 2 deletions(-)
create mode 100644 srcpkgs/synfig/patches/ffmpeg6.patch
diff --git a/srcpkgs/synfig/patches/ffmpeg6.patch b/srcpkgs/synfig/patches/ffmpeg6.patch
new file mode 100644
index 000000000000..10780b42782f
--- /dev/null
+++ b/srcpkgs/synfig/patches/ffmpeg6.patch
@@ -0,0 +1,71 @@
+--- a/src/modules/mod_libavcodec/trgt_av.cpp 2022-10-25 09:14:12.000000000 -0400
++++ b/src/modules/mod_libavcodec/trgt_av.cpp 2023-05-05 21:34:17.899194559 -0400
+@@ -38,6 +41,7 @@
+ extern "C"
+ {
+ #ifdef HAVE_LIBAVFORMAT_AVFORMAT_H
++# include <libavcodec/avcodec.h>
+ # include <libavformat/avformat.h>
+ #elif defined(HAVE_AVFORMAT_H)
+ # include <avformat.h>
+@@ -155,11 +156,11 @@
+ }
+
+ bool open_video_stream() {
+- if (avcodec_open2(video_context, NULL, NULL) < 0) {
++ if (avcodec_open2(video_context, nullptr, nullptr) < 0) {
+ synfig::error("Target_LibAVCodec: could not open video codec");
+ // seems the calling of avcodec_free_context after error will cause crash
+ // so just forget about this context
+- video_context = NULL;
++ video_context = nullptr;
+ close();
+ return false;
+ }
+@@ -234,15 +235,21 @@
+ close();
+
+ if (!av_registered) {
++#if LIBAVCODEC_VERSION_MAJOR < 58 // FFMPEG < 4.0
+ av_register_all();
++#endif
+ av_registered = true;
+ }
+
+ // guess format
+- AVOutputFormat *format = av_guess_format(NULL, filename.c_str(), NULL);
++#if LIBAVCODEC_VERSION_MAJOR < 59 // FFMPEG < 5.0
++ AVOutputFormat* format = av_guess_format(nullptr, filename.c_str(), nullptr);
++#else
++ const AVOutputFormat* format = av_guess_format(nullptr, filename.c_str(), nullptr);
++#endif
+ if (!format) {
+ synfig::warning("Target_LibAVCodec: unable to guess the output format, defaulting to MPEG");
+- format = av_guess_format("mpeg", NULL, NULL);
++ format = av_guess_format("mpeg", nullptr, nullptr);
+ }
+ if (!format) {
+ synfig::error("Target_LibAVCodec: unable to find 'mpeg' output format");
+@@ -254,6 +261,7 @@
+ context = avformat_alloc_context();
+ assert(context);
+ context->oformat = format;
++#if LIBAVCODEC_VERSION_MAJOR < 58 // FFMPEG < 4.0
+ if (filename.size() + 1 > sizeof(context->filename)) {
+ synfig::error(
+ "Target_LibAVCodec: filename too long, max length is %d, filename is '%s'",
+@@ -263,6 +271,14 @@
+ return false;
+ }
+ memcpy(context->filename, filename.c_str(), filename.size() + 1);
++#else
++ context->url = av_strndup(filename.c_str(), filename.size());
++ if (!context->url) {
++ synfig::error("Target_LibAVCodec: cannot allocate space for filename");
++ close();
++ return false;
++ }
++#endif
+
+ packet = av_packet_alloc();
+ assert(packet);
diff --git a/srcpkgs/synfig/template b/srcpkgs/synfig/template
index 5f5f5bb3f4b2..6e0d713150ae 100644
--- a/srcpkgs/synfig/template
+++ b/srcpkgs/synfig/template
@@ -6,7 +6,7 @@ revision=2
build_style=gnu-configure
configure_args="--with-boost-libdir=${XBPS_CROSS_BASE}/usr/lib"
hostmakedepends="boost-build ImageMagick pkg-config intltool"
-makedepends="ETL gettext-devel libxml++-devel mlt-devel libmagick-devel
+makedepends="ETL gettext-devel libxml++-devel mlt7-devel libmagick-devel
libmng-devel boost-build boost-devel libopenexr-devel ffmpeg-devel"
depends="ImageMagick"
short_desc="CLI 2D vector and timeline-based animation software"
@@ -20,7 +20,7 @@ CXXFLAGS="-std=c++11 -DHAVE_LOCALE_H=1"
synfig-devel_package() {
depends="${sourcepkg}>=${version}_${revision}
- libopenexr-devel libxml++-devel mlt-devel"
+ libopenexr-devel libxml++-devel mlt7-devel"
short_desc+=" - development files"
pkg_install() {
vmove usr/bin/synfig-config
From 7e41b6e74c8e6eba7e97bdf2eadd5339d1f9391b Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Fri, 5 May 2023 12:57:57 -0400
Subject: [PATCH 087/115] synfigstudio: revbump for synfig mlt7
---
srcpkgs/synfigstudio/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/synfigstudio/template b/srcpkgs/synfigstudio/template
index 91349169ed2b..af1c5a296ef0 100644
--- a/srcpkgs/synfigstudio/template
+++ b/srcpkgs/synfigstudio/template
@@ -2,7 +2,7 @@
# Should be kept in sync with 'synfig' and 'ETL'
pkgname=synfigstudio
version=1.4.4
-revision=2
+revision=3
build_style=gnu-configure
configure_args="--disable-update-mimedb"
hostmakedepends="pkg-config intltool gettext synfig"
From 5df937a2be8e803722ff2b2018e0c871a21b8bcf Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:52 -0400
Subject: [PATCH 088/115] telegram-desktop: revbump for ffmpeg-6.0
---
srcpkgs/telegram-desktop/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/telegram-desktop/template b/srcpkgs/telegram-desktop/template
index 60df3278b05e..83aa72a67448 100644
--- a/srcpkgs/telegram-desktop/template
+++ b/srcpkgs/telegram-desktop/template
@@ -1,7 +1,7 @@
# Template file for 'telegram-desktop'
pkgname=telegram-desktop
version=4.8.1
-revision=1
+revision=2
build_style=cmake
build_helper="qemu"
configure_args="-DTDESKTOP_API_ID=209235
From db7ecc0a6e67f49e91efc2712fb0ff7a103b08b1 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:52 -0400
Subject: [PATCH 089/115] tg_owt: revbump for ffmpeg-6.0
---
srcpkgs/tg_owt/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/tg_owt/template b/srcpkgs/tg_owt/template
index 97d195ddb34a..551614b24956 100644
--- a/srcpkgs/tg_owt/template
+++ b/srcpkgs/tg_owt/template
@@ -1,7 +1,7 @@
# Template file for 'tg_owt'
pkgname=tg_owt
version=0.0.0.20230107
-revision=1
+revision=2
_commit=5098730b9eb6173f0b52068fe2555b7c1015123a
_libyuv_commit=00950840d1c9bcbb3eb6ebc5aac5793e71166c8b
_abseil_commit=8c0b94e793a66495e0b1f34a5eb26bd7dc672db0
From 80d2dae7c2952acab8be49fa49bf6b588b663424 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:52 -0400
Subject: [PATCH 090/115] timg: revbump for ffmpeg-6.0
---
srcpkgs/timg/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/timg/template b/srcpkgs/timg/template
index 91f1516b2597..334443d3f9bb 100644
--- a/srcpkgs/timg/template
+++ b/srcpkgs/timg/template
@@ -1,7 +1,7 @@
# Template file for 'timg'
pkgname=timg
version=1.4.4
-revision=1
+revision=2
build_style=cmake
configure_args="-DWITH_OPENSLIDE_SUPPORT=off -Wno-dev"
hostmakedepends="pkg-config git"
From 502dd1911003ea24f159739244fe8a47373a21cc Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:52 -0400
Subject: [PATCH 091/115] tvheadend: revbump for ffmpeg4-4.4.3
---
srcpkgs/tvheadend/template | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/srcpkgs/tvheadend/template b/srcpkgs/tvheadend/template
index e6b16d7ccf3b..46b52b6fb7f9 100644
--- a/srcpkgs/tvheadend/template
+++ b/srcpkgs/tvheadend/template
@@ -1,14 +1,14 @@
# Template file for 'tvheadend'
pkgname=tvheadend
version=4.2.8
-revision=6
+revision=7
build_style=gnu-configure
configure_args="--enable-dvbscan --disable-ffmpeg_static
--disable-hdhomerun_static --disable-bintray_cache --disable-libx264_static
--disable-libx265_static --disable-libvpx_static --disable-libtheora_static
--disable-libvorbis_static --disable-libfdkaac_static"
hostmakedepends="gettext pkg-config python git which"
-makedepends="avahi-libs-devel openssl-devel zlib-devel libcurl-devel ffmpeg-devel"
+makedepends="avahi-libs-devel openssl-devel zlib-devel libcurl-devel ffmpeg4-devel"
short_desc="TV streaming server"
maintainer="lemmi <lemmi@nerd2nerd.org>"
license="GPL-3.0-only"
From d35f3fe4518b1f82f61760bae4c4f18dbc6f180b Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:52 -0400
Subject: [PATCH 092/115] unpaper: update to 7.0.0.
---
srcpkgs/unpaper/template | 16 ++++++++--------
1 file changed, 8 insertions(+), 8 deletions(-)
diff --git a/srcpkgs/unpaper/template b/srcpkgs/unpaper/template
index 38ed47a58401..1ff910e722af 100644
--- a/srcpkgs/unpaper/template
+++ b/srcpkgs/unpaper/template
@@ -1,13 +1,13 @@
# Template file for 'unpaper'
pkgname=unpaper
-version=6.1
-revision=3
-build_style=gnu-configure
+version=7.0.0
+revision=1
+build_style=meson
+hostmakedepends="pkg-config meson libxslt"
+makedepends="ffmpeg-devel python3-Sphinx"
+short_desc="Post-processing tool for scanned sheets of paper"
maintainer="Orphaned <orphan@voidlinux.org>"
-hostmakedepends="pkg-config libxslt"
-makedepends="ffmpeg-devel"
-license="GPL-2"
+license="GPL-2.0-or-later"
homepage="https://www.flameeyes.eu/projects/unpaper"
-short_desc="A post-processing tool for scanned sheets of paper"
distfiles="https://www.flameeyes.eu/files/${pkgname}-${version}.tar.xz"
-checksum=237c84f5da544b3f7709827f9f12c37c346cdf029b1128fb4633f9bafa5cb930
+checksum=2575fbbf26c22719d1cb882b59602c9900c7f747118ac130883f63419be46a80
From eea586f6c737e2d82f5d2d0c2aa5b0f46a66cde6 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:52 -0400
Subject: [PATCH 093/115] vba-m: revbump for ffmpeg-6.0
---
srcpkgs/vba-m/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/vba-m/template b/srcpkgs/vba-m/template
index ba153e0b58ca..aa6093645e97 100644
--- a/srcpkgs/vba-m/template
+++ b/srcpkgs/vba-m/template
@@ -2,7 +2,7 @@
pkgname=vba-m
reverts=1292_2
version=2.1.5
-revision=1
+revision=2
build_style=cmake
configure_args="-DENABLE_GTK=TRUE -DENABLE_FFMPEG=TRUE -DENABLE_LINK=TRUE -DCMAKE_BUILD_TYPE=Release"
hostmakedepends="gettext pkg-config unzip zip yasm wxWidgets-gtk3-devel"
From dd4e871ae5e48efca9b23b5fdb23f71ad1b9c74e Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:52 -0400
Subject: [PATCH 094/115] vice: revbump for ffmpeg4-4.4.3
---
srcpkgs/vice/template | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/srcpkgs/vice/template b/srcpkgs/vice/template
index 0924767cfcfb..5981e45149d0 100644
--- a/srcpkgs/vice/template
+++ b/srcpkgs/vice/template
@@ -1,7 +1,7 @@
# Template file for 'vice'
pkgname=vice
version=3.5
-revision=1
+revision=2
build_style=gnu-configure
configure_args="
$(vopt_enable sdl2 sdlui2)
@@ -28,7 +28,7 @@ makedepends="
$(vopt_if gtk3 gtk+3-devel)
$(vopt_if gtk3 pulseaudio-devel)
$(vopt_if gtk3 pango-devel)
- $(vopt_if ffmpeg ffmpeg-devel)"
+ $(vopt_if ffmpeg ffmpeg4-devel)"
short_desc="Emulator for C64, C128, CBM-II, PET, VIC20, Plus4 and C16"
maintainer="Orphaned <orphan@voidlinux.org>"
license="GPL-2.0-or-later"
From 63cb2d5584bdfc1758c9f1f3fb1a17e0c1dd9a74 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:52 -0400
Subject: [PATCH 095/115] waypipe: revbump for ffmpeg-6.0
---
srcpkgs/waypipe/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/waypipe/template b/srcpkgs/waypipe/template
index 5c4161900060..1a46fe27f7d8 100644
--- a/srcpkgs/waypipe/template
+++ b/srcpkgs/waypipe/template
@@ -1,7 +1,7 @@
# Template file for 'waypipe'
pkgname=waypipe
version=0.8.4
-revision=1
+revision=2
build_style=meson
# lto is off because it causes linking errors in armv6l and armv7l (due to NEON)
configure_args="-Dwerror=false -Dwith_dmabuf=enabled -Dwith_lz4=enabled
From 553837596a2b6ddb2946b5dd24242ef853161613 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:52 -0400
Subject: [PATCH 096/115] wf-recorder: revbump for ffmpeg-6.0
---
srcpkgs/wf-recorder/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/wf-recorder/template b/srcpkgs/wf-recorder/template
index e278eb001600..5d014a5f28af 100644
--- a/srcpkgs/wf-recorder/template
+++ b/srcpkgs/wf-recorder/template
@@ -1,7 +1,7 @@
# Template file for 'wf-recorder'
pkgname=wf-recorder
version=0.3.0
-revision=1
+revision=2
build_style=meson
hostmakedepends="pkg-config scdoc wayland-devel"
makedepends="wayland-protocols wayland-devel ffmpeg-devel x264-devel
From ac2a750601716f05ba0ad759440fb362a77604f3 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:52 -0400
Subject: [PATCH 097/115] xpra: revbump for ffmpeg-6.0
---
srcpkgs/xpra/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/xpra/template b/srcpkgs/xpra/template
index 38f83283b1e5..b6e01ff0a813 100644
--- a/srcpkgs/xpra/template
+++ b/srcpkgs/xpra/template
@@ -1,7 +1,7 @@
# Template file for 'xpra'
pkgname=xpra
version=4.4.4
-revision=1
+revision=2
build_style=python3-module
make_build_args="--without-cuda_kernels --without-cuda_rebuild"
make_install_args="$(vopt_with docs) ${make_build_args}"
From ae03605321e65f9c7132a04107990b5823661826 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Fri, 31 Mar 2023 09:07:40 -0400
Subject: [PATCH 098/115] nv-codec-headers: update to 12.0.16.0
---
srcpkgs/nv-codec-headers/template | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/srcpkgs/nv-codec-headers/template b/srcpkgs/nv-codec-headers/template
index 3d422a61e489..251e057f826f 100644
--- a/srcpkgs/nv-codec-headers/template
+++ b/srcpkgs/nv-codec-headers/template
@@ -1,6 +1,6 @@
# Template file for 'nv-codec-headers'
pkgname=nv-codec-headers
-version=11.1.5.1
+version=12.0.16.0
revision=1
build_style=gnu-makefile
short_desc="FFmpeg version of headers required to interface with Nvidias codec APIs"
@@ -8,7 +8,7 @@ maintainer="Orphaned <orphan@voidlinux.org>"
license="MIT"
homepage="http://git.videolan.org/?p=ffmpeg/nv-codec-headers.git"
distfiles="https://github.com/FFmpeg/nv-codec-headers/archive/n${version}.tar.gz"
-checksum=d095fbd56aa93772471a323be0ebe65504a0f43f06c76a30b6d25da77b06ae9c
+checksum=2a1533b65f55f9da52956faf0627ed3b74868ac0c7f269990edd21369113b48f
post_install() {
sed -n '4,25p' include/ffnvcodec/nvEncodeAPI.h > LICENSE
From f34884257526429d1f688ba1987e352c96aec02e Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Fri, 31 Mar 2023 09:08:40 -0400
Subject: [PATCH 099/115] openimagedenoise: revbump for ffmpeg-6.0
---
srcpkgs/openimagedenoise/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/openimagedenoise/template b/srcpkgs/openimagedenoise/template
index db5ccdb055cc..cb90045afb63 100644
--- a/srcpkgs/openimagedenoise/template
+++ b/srcpkgs/openimagedenoise/template
@@ -1,7 +1,7 @@
# Template file for 'openimagedenoise'
pkgname=openimagedenoise
version=1.4.3
-revision=1
+revision=2
archs="x86_64*"
build_style=cmake
hostmakedepends="ispc python3"
From 967b51da24206060ad271ee224d7068740c1e612 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Mon, 3 Apr 2023 23:30:28 -0400
Subject: [PATCH 100/115] freecad: revbump for qt5-webengine-5.15.13
---
srcpkgs/freecad/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/freecad/template b/srcpkgs/freecad/template
index f62023ee8ce4..e301f32d3540 100644
--- a/srcpkgs/freecad/template
+++ b/srcpkgs/freecad/template
@@ -1,7 +1,7 @@
# Template file for 'freecad'
pkgname=freecad
version=0.20.2
-revision=3
+revision=4
build_style=cmake
_inst_prefix=/usr/lib/${pkgname}
From c0bd147974a6c4a8ba17893f41f852a43fdaeb6e Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Mon, 3 Apr 2023 23:31:45 -0400
Subject: [PATCH 101/115] shotcut: revbump for mlt7-7.14.0
---
srcpkgs/shotcut/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/shotcut/template b/srcpkgs/shotcut/template
index 32583277dab2..8d8a7a0ebdeb 100644
--- a/srcpkgs/shotcut/template
+++ b/srcpkgs/shotcut/template
@@ -1,7 +1,7 @@
# Template file for 'shotcut'
pkgname=shotcut
version=22.12.21
-revision=1
+revision=2
build_style=cmake
configure_args="-DSHOTCUT_VERSION=${version}"
hostmakedepends="pkg-config qt5-tools-devel"
From f3b03073f118fc856acf6bc05a003ee777c9917b Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Mon, 3 Apr 2023 23:33:30 -0400
Subject: [PATCH 102/115] shiboken2: revbump for qt5-5.15.8
---
srcpkgs/shiboken2/patches/importlib-machinery-bypass.patch | 1 +
srcpkgs/shiboken2/template | 2 +-
2 files changed, 2 insertions(+), 1 deletion(-)
create mode 120000 srcpkgs/shiboken2/patches/importlib-machinery-bypass.patch
diff --git a/srcpkgs/shiboken2/patches/importlib-machinery-bypass.patch b/srcpkgs/shiboken2/patches/importlib-machinery-bypass.patch
new file mode 120000
index 000000000000..efcf3249bd88
--- /dev/null
+++ b/srcpkgs/shiboken2/patches/importlib-machinery-bypass.patch
@@ -0,0 +1 @@
+../../python3-pyside2/patches/importlib-machinery-bypass.patch
\ No newline at end of file
diff --git a/srcpkgs/shiboken2/template b/srcpkgs/shiboken2/template
index 084ecc3ba1e1..2a21998997eb 100644
--- a/srcpkgs/shiboken2/template
+++ b/srcpkgs/shiboken2/template
@@ -1,7 +1,7 @@
# Template file for 'shiboken2'
pkgname=shiboken2
version=5.15.7
-revision=1
+revision=2
_pkgname="pyside-setup-opensource-src-${version}"
build_wrksrc="sources/shiboken2"
build_style=cmake
From c3fd5c25e7155c836e9c09f7f417b84525f53a7e Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Mon, 3 Apr 2023 23:33:53 -0400
Subject: [PATCH 103/115] python3-pyside2: update to 5.15.8
---
.../patches/importlib-machinery-bypass.patch | 15 +++++++++++++++
srcpkgs/python3-pyside2/template | 9 +++++----
2 files changed, 20 insertions(+), 4 deletions(-)
create mode 100644 srcpkgs/python3-pyside2/patches/importlib-machinery-bypass.patch
diff --git a/srcpkgs/python3-pyside2/patches/importlib-machinery-bypass.patch b/srcpkgs/python3-pyside2/patches/importlib-machinery-bypass.patch
new file mode 100644
index 000000000000..64c429584776
--- /dev/null
+++ b/srcpkgs/python3-pyside2/patches/importlib-machinery-bypass.patch
@@ -0,0 +1,15 @@
+Using this prevents an error around line 220 below it.
+"AttributeError: module 'importlib' has no attribute 'machinery'"
+The old backup logic is in place and compiles without issues.
+--- a/sources/shiboken2/libshiboken/embed/signature_bootstrap.py 2023-04-02 23:09:34.688912402 -0400
++++ b/sources/shiboken2/libshiboken/embed/signature_bootstrap.py 2023-04-02 23:10:03.395529582 -0400
+@@ -170,9 +170,6 @@
+
+ # 'zipstring_sequence' comes from signature.cpp
+ zipbytes = base64.b64decode(''.join(zipstring_sequence))
+- if sys.version_info[0] >= 3:
+- vzip = zipfile.ZipFile(io.BytesIO(zipbytes))
+- return sys.meta_path, EmbeddableZipImporter(vzip)
+
+ # Old version for Python 2.7, only.
+ import os
diff --git a/srcpkgs/python3-pyside2/template b/srcpkgs/python3-pyside2/template
index 50e6ff260d3b..b50e62bd215d 100644
--- a/srcpkgs/python3-pyside2/template
+++ b/srcpkgs/python3-pyside2/template
@@ -1,11 +1,12 @@
# Template file for 'python3-pyside2'
pkgname=python3-pyside2
-version=5.15.5
-revision=2
+version=5.15.8
+revision=1
_pkgname="pyside-setup-opensource-src-${version}"
build_wrksrc="sources/pyside2"
build_style=cmake
-configure_args="-DPYTHON_EXECUTABLE=/usr/bin/python"
+configure_args="-DPYTHON_EXECUTABLE=/usr/bin/python -DCMAKE_BUILD_TYPE=None
+ -DBUILD_TESTS=OFF"
hostmakedepends="cmake python3 shiboken2"
makedepends="python3-devel libshiboken2-devel qt5-devel
qt5-multimedia-devel qt5-tools-devel qt5-plugin-mysql qt5-plugin-odbc
@@ -23,7 +24,7 @@ maintainer="yopito <pierre.bourgin@free.fr>"
license="LGPL-3.0-or-later"
homepage="https://wiki.qt.io/Qt_for_Python"
distfiles="https://download.qt.io/official_releases/QtForPython/pyside2/PySide2-${version}-src/${_pkgname}.tar.xz"
-checksum=3920a4fb353300260c9bc46ff70f1fb975c5e7efa22e9d51222588928ce19b33
+checksum=23436302c8deb5b4cbc769b205d09604e38ba83b40708efccb7bd8c9af6f6b5d
build_options="webengine"
desc_option_webengine="Build Qt5 WebEngine bindings"
From 63e61b9b897d36f25c69411c103a36fa9cbde6d4 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Tue, 4 Apr 2023 11:14:35 -0400
Subject: [PATCH 104/115] konqueror: revbump for ffmpeg-6.0
---
srcpkgs/konqueror/template | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/srcpkgs/konqueror/template b/srcpkgs/konqueror/template
index d8d0e73a78ab..c5bdba601d3c 100644
--- a/srcpkgs/konqueror/template
+++ b/srcpkgs/konqueror/template
@@ -1,11 +1,11 @@
# Template file for 'konqueror'
pkgname=konqueror
version=23.04.0
-revision=1
+revision=2
build_style=cmake
configure_args="-DDESKTOPTOJSON_EXECUTABLE=/usr/bin/desktoptojson"
hostmakedepends="extra-cmake-modules python3 qt5-host-tools qt5-qmake kdoctools
-kcoreaddons kconfig gettext"
+ kcoreaddons kconfig gettext"
makedepends="qt5-devel qt5-webengine-devel qt5-declarative-devel
qt5-webchannel-devel qt5-location-devel kcmutils-devel kdelibs4support-devel
karchive-devel khtml-devel kdesu-devel kactivities5-devel"
From e723d92b42f62af025194c94bd366a56d6a5ea48 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Tue, 4 Apr 2023 11:14:58 -0400
Subject: [PATCH 105/115] qt5-speech: revbump for qt5-5.15.8
---
srcpkgs/qt5-speech/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/qt5-speech/template b/srcpkgs/qt5-speech/template
index 3ecd10d50650..2d7d4d4d2453 100644
--- a/srcpkgs/qt5-speech/template
+++ b/srcpkgs/qt5-speech/template
@@ -1,7 +1,7 @@
# Template file for 'qt5-speech'
pkgname=qt5-speech
version=5.15.7
-revision=2
+revision=3
_commit=d32f4a479d38a11f547598004b975f4356424a16
build_style=qmake
configure_args="-- -flite -flite-alsa -speechd"
From 325bb0d3cda357290757728543f210be8aebb4bc Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Tue, 4 Apr 2023 18:38:50 -0400
Subject: [PATCH 106/115] qt5-styleplugins: revbump for qt5-5.15.8
---
srcpkgs/qt5-styleplugins/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/qt5-styleplugins/template b/srcpkgs/qt5-styleplugins/template
index 96ed97d12cd2..30d93660a2a4 100644
--- a/srcpkgs/qt5-styleplugins/template
+++ b/srcpkgs/qt5-styleplugins/template
@@ -1,7 +1,7 @@
# Template file for 'qt5-styleplugins'
pkgname=qt5-styleplugins
version=5.0.0
-revision=20
+revision=21
_gitrev=335dbece103e2cbf6c7cf819ab6672c2956b17b3
build_style=qmake
hostmakedepends="pkg-config qt5-host-tools qt5-qmake"
From d106e08980845c05049d60a3c03b0a203411424f Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Thu, 27 Apr 2023 21:58:35 -0400
Subject: [PATCH 107/115] blender: update to 3.5.1
---
srcpkgs/blender/patches/numpy-2.24.patch | 22 ----------------------
srcpkgs/blender/template | 13 +++++++------
2 files changed, 7 insertions(+), 28 deletions(-)
delete mode 100644 srcpkgs/blender/patches/numpy-2.24.patch
diff --git a/srcpkgs/blender/patches/numpy-2.24.patch b/srcpkgs/blender/patches/numpy-2.24.patch
deleted file mode 100644
index 716315b74be7..000000000000
--- a/srcpkgs/blender/patches/numpy-2.24.patch
+++ /dev/null
@@ -1,22 +0,0 @@
-From 74e6e07cf7c67b55d384db72f5aa3892db8a3da6 Mon Sep 17 00:00:00 2001
-From: oreo639 <oreo6391@gmail.com>
-Date: Tue, 17 Jan 2023 14:36:54 -0800
-Subject: [PATCH] Remove usage of deprecated np.bool alias
-
----
- addons/io_scene_gltf2/blender/imp/gltf2_blender_mesh.py | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-diff --git a/addons/io_scene_gltf2/blender/imp/gltf2_blender_mesh.py b/addons/io_scene_gltf2/blender/imp/gltf2_blender_mesh.py
-index 6366434a6..8160c9e99 100644
---- a/release/scripts/addons/io_scene_gltf2/blender/imp/gltf2_blender_mesh.py
-+++ b/release/scripts/addons/io_scene_gltf2/blender/imp/gltf2_blender_mesh.py
-@@ -620,7 +620,7 @@ def set_poly_smoothing(gltf, pymesh, mesh, vert_normals, loop_vidxs):
- # Try to guess which polys should be flat based on the fact that all the
- # loop normals for a flat poly are = the poly's normal.
-
-- poly_smooths = np.empty(num_polys, dtype=np.bool)
-+ poly_smooths = np.empty(num_polys, dtype=bool)
-
- poly_normals = np.empty(num_polys * 3, dtype=np.float32)
- mesh.polygons.foreach_get('normal', poly_normals)
diff --git a/srcpkgs/blender/template b/srcpkgs/blender/template
index d18bc88838ff..900bc17937c3 100644
--- a/srcpkgs/blender/template
+++ b/srcpkgs/blender/template
@@ -1,7 +1,7 @@
# Template file for 'blender'
pkgname=blender
-version=3.4.1
-revision=4
+version=3.5.1
+revision=1
archs="x86_64* ppc64*"
build_style="cmake"
pycompile_dirs="/usr/share/blender/${version%.*}/scripts"
@@ -9,8 +9,8 @@ configure_args="-DWITH_INSTALL_PORTABLE=OFF -DWITH_PYTHON_INSTALL=OFF
-DWITH_JACK=ON -DWITH_CODEC_FFMPEG=ON -DWITH_CODEC_SNDFILE=ON -DWITH_OPENMP=ON
-DWITH_FFTW3=ON -DWITH_MOD_OCEANSIM=ON -DWITH_CYCLES_EMBREE=OFF -DWITH_OPENCOLORIO=ON
-DWITH_IMAGE_OPENEXR=ON -DWITH_IMAGE_OPENJPEG=ON -DWITH_OPENSUBDIV=ON
- -DWITH_OPENCOLLADA=ON -DWITH_SYSTEM_GLEW=ON -DWITH_OPENVDB=ON -DWITH_ALEMBIC=ON
- -DWITH_GHOST_X11=ON -DWITH_GHOST_WAYLAND=ON -DWITH_GHOST_LIBDECOR=ON
+ -DWITH_OPENCOLLADA=ON -DWITH_OPENVDB=ON -DWITH_ALEMBIC=ON
+ -DWITH_GHOST_X11=ON -DWITH_GHOST_WAYLAND=ON -DWITH_GHOST_WAYLAND_LIBDECOR=ON
-DWITH_BUILDINFO=OFF -DPYTHON_VERSION=${py3_ver} -DPYTHON_LIBPATH=/usr/lib
-DPYTHON_LIBRARY='python${py3_ver}${py3_abiver}'
-DPYTHON_INCLUDE_DIRS=/${py3_inc}"
@@ -22,14 +22,15 @@ makedepends="libgomp-devel libpng-devel tiff-devel python3-devel glu-devel
opencolorio-devel opencollada-devel python3-numpy libXrender-devel
OpenSubdiv-devel tbb-devel libxml2-devel openvdb-devel alembic-devel
pugixml-devel libXxf86vm-devel libepoxy-devel gmp-devel gmpxx-devel
- wayland-protocols wayland-devel libxkbcommon-devel libdecor-devel"
+ wayland-protocols wayland-devel libxkbcommon-devel libdecor-devel
+ level-zero-devel"
depends="desktop-file-utils hicolor-icon-theme"
short_desc="3D graphics creation suite"
maintainer="Enno Boland <gottox@voidlinux.org>"
license="GPL-3.0-or-later"
homepage="https://www.blender.org"
distfiles="https://download.blender.org/source/blender-${version}.tar.xz"
-checksum=247c4c1228270c9010f4721c985cb5b628ab50abcf9f2678630737142eeb91c3
+checksum=bd7428c7e6cba5a900216269c32111dffaabaf1bdb5472f231965e615174a809
python_version=3
LDFLAGS="-Wl,-z,stack-size=2097152"
# Blender tests are executed against a system installation of blender. This
From cc4c1a61ed63d09a5012651541f45f82eca10980 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Sun, 30 Apr 2023 20:22:26 -0400
Subject: [PATCH 108/115] gst-plugins-ugly1: revbump for ffmpeg-6.0
---
srcpkgs/gst-plugins-ugly1/template | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/srcpkgs/gst-plugins-ugly1/template b/srcpkgs/gst-plugins-ugly1/template
index e254fd40f869..85ae64bc7a0a 100644
--- a/srcpkgs/gst-plugins-ugly1/template
+++ b/srcpkgs/gst-plugins-ugly1/template
@@ -1,6 +1,6 @@
# Template file for 'gst-plugins-ugly1'
pkgname=gst-plugins-ugly1
-version=1.20.3
+version=1.22.2
revision=1
build_style=meson
configure_args="-Damrnb=disabled -Damrwbdec=disabled -Dsidplay=disabled"
@@ -15,4 +15,4 @@ maintainer="Orphaned <orphan@voidlinux.org>"
license="LGPL-2.1-or-later"
homepage="https://gstreamer.freedesktop.org"
distfiles="${homepage}/src/${pkgname/1/}/${pkgname/1/}-${version}.tar.xz"
-checksum=8caa20789a09c304b49cf563d33cca9421b1875b84fcc187e4a385fa01d6aefd
+checksum=8f30f44db0bd063709bf6fbe55138e3a98af0abcb61c360f35582bbe10e80691
From f10a956f45f41af81f7157432be1c09a826776ad Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Sun, 30 Apr 2023 20:22:26 -0400
Subject: [PATCH 109/115] gst-rtsp-server: revbump for ffmpeg-6.0
---
srcpkgs/gst-rtsp-server/template | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/srcpkgs/gst-rtsp-server/template b/srcpkgs/gst-rtsp-server/template
index 8ceea8d34b4b..980fd72cdd4c 100644
--- a/srcpkgs/gst-rtsp-server/template
+++ b/srcpkgs/gst-rtsp-server/template
@@ -1,7 +1,7 @@
# Template file for 'gst-rtsp-server'
pkgname=gst-rtsp-server
-version=1.20.3
-revision=3
+version=1.22.2
+revision=2
build_style=meson
hostmakedepends="pkg-config python3"
makedepends="glib-devel gst-plugins-bad1-devel gobject-introspection
@@ -10,5 +10,5 @@ short_desc="GStreamer multimedia graph framework - rtsp server"
maintainer="1is7ac3 <isaac.qa13@gmail.com>"
license="LGPL-2.1-or-later"
homepage="https://gstreamer.freedesktop.org"
-distfiles="https://gstreamer.freedesktop.org/src/gst-rtsp-server/gst-rtsp-server-${version}.tar.xz"
-checksum=ee402718be9b127f0e5e66ca4c1b4f42e4926ec93ba307b7ccca5dc6cc9794ca
+distfiles="${homepage}/src/${pkgname}/${pkgname}-${version}.tar.xz"
+checksum=2be4aecfb88710100ea7115ed0216403e8094344ebf146094271b8d4d73828bf
From 5ea533534cad672232cbf0dd072c994efd33e993 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Sun, 30 Apr 2023 20:22:26 -0400
Subject: [PATCH 110/115] gst-libav: revbump for ffmpeg-6.0
---
srcpkgs/gst-libav/template | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/srcpkgs/gst-libav/template b/srcpkgs/gst-libav/template
index f082bd211c65..04c39bff1489 100644
--- a/srcpkgs/gst-libav/template
+++ b/srcpkgs/gst-libav/template
@@ -1,6 +1,6 @@
# Template file for 'gst-libav'
pkgname=gst-libav
-version=1.20.3
+version=1.22.2
revision=2
build_style=meson
hostmakedepends="pkg-config yasm"
@@ -11,7 +11,7 @@ maintainer="Orphaned <orphan@voidlinux.org>"
license="LGPL-2.0-or-later"
homepage="https://gstreamer.freedesktop.org"
distfiles="${homepage}/src/${pkgname}/${pkgname}-${version}.tar.xz"
-checksum=3fedd10560fcdfaa1b6462cbf79a38c4e7b57d7f390359393fc0cef6dbf27dfe
+checksum=fcaaf9878fe8f3bc82317ef13a1558824cb68df1f8968c6797f556c5e33bcffd
case "$XBPS_TARGET_MACHINE" in
*-musl) # Required by musl for M_SQRT1_2
From df60a4c0794afb9c9f360c19e27e90b5bf48b011 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Sun, 7 May 2023 19:48:01 -0400
Subject: [PATCH 111/115] gtk4: revbump for ffmpeg-6.0
---
srcpkgs/gtk4/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/gtk4/template b/srcpkgs/gtk4/template
index a2566d4042d3..5fafa50f6f33 100644
--- a/srcpkgs/gtk4/template
+++ b/srcpkgs/gtk4/template
@@ -1,7 +1,7 @@
# Template file for 'gtk4'
pkgname=gtk4
version=4.10.3
-revision=1
+revision=2
build_style=meson
build_helper="gir"
configure_args="-Dman-pages=true -Dgtk_doc=true
From 84014ee3a140d3ed0185fb88070cc9b8496c6b14 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Sun, 7 May 2023 20:14:14 -0400
Subject: [PATCH 112/115] mlt7: revbump for ffmpeg-6.0
---
srcpkgs/gst-libav/template | 2 +-
srcpkgs/gst-omx/template | 4 ++--
srcpkgs/gst-plugins-base1/template | 4 ++--
srcpkgs/gst-plugins-good1/template | 4 ++--
srcpkgs/gst1-editing-services/template | 4 ++--
srcpkgs/gst1-python3/template | 6 +++---
srcpkgs/gstreamer-vaapi/template | 4 ++--
srcpkgs/gstreamer1/template | 4 ++--
srcpkgs/mlt7/template | 2 +-
9 files changed, 17 insertions(+), 17 deletions(-)
diff --git a/srcpkgs/gst-libav/template b/srcpkgs/gst-libav/template
index 04c39bff1489..8c72fc3e97ee 100644
--- a/srcpkgs/gst-libav/template
+++ b/srcpkgs/gst-libav/template
@@ -1,7 +1,7 @@
# Template file for 'gst-libav'
pkgname=gst-libav
version=1.22.2
-revision=2
+revision=1
build_style=meson
hostmakedepends="pkg-config yasm"
makedepends="orc-devel gst-plugins-base1-devel ffmpeg-devel"
diff --git a/srcpkgs/gst-omx/template b/srcpkgs/gst-omx/template
index 893535c463da..5ad54cc7b9d8 100644
--- a/srcpkgs/gst-omx/template
+++ b/srcpkgs/gst-omx/template
@@ -1,6 +1,6 @@
# Template file for 'gst-omx'
pkgname=gst-omx
-version=1.20.3
+version=1.22.2
revision=1
build_style=meson
configure_args="-Dexamples=disabled -Dtarget=generic"
@@ -11,4 +11,4 @@ maintainer="Orphaned <orphan@voidlinux.org>"
license="LGPL-2.1-only"
homepage="https://gstreamer.freedesktop.org"
distfiles="${homepage}/src/${pkgname}/${pkgname}-${version}.tar.xz"
-checksum=8db48040bb41f09edf8d17ff6d16c54888d7777ba4501c2c69f0083350ea9a15
+checksum=1b0c57f2cc4ddeec5e7f0c436e502f06665c4e93c73261855b94e04fc94337b2
diff --git a/srcpkgs/gst-plugins-base1/template b/srcpkgs/gst-plugins-base1/template
index 29e8f76bd1fe..2f20ea819849 100644
--- a/srcpkgs/gst-plugins-base1/template
+++ b/srcpkgs/gst-plugins-base1/template
@@ -1,6 +1,6 @@
# Template file for 'gst-plugins-base1'
pkgname=gst-plugins-base1
-version=1.20.3
+version=1.22.2
revision=1
build_style=meson
build_helper="gir"
@@ -22,7 +22,7 @@ maintainer="Orphaned <orphan@voidlinux.org>"
license="GPL-2.0-or-later, LGPL-2.0-or-later"
homepage="https://gstreamer.freedesktop.org"
distfiles="${homepage}/src/${pkgname/1/}/${pkgname/1/}-${version}.tar.xz"
-checksum=7e30b3dd81a70380ff7554f998471d6996ff76bbe6fc5447096f851e24473c9f
+checksum=eb65120c4ee79b7a153c3c1972d5c0158c2151877cc51ec7725bba5749679d49
build_options="cdparanoia gir sndio wayland"
build_options_default="cdparanoia gir wayland"
diff --git a/srcpkgs/gst-plugins-good1/template b/srcpkgs/gst-plugins-good1/template
index 1f5e620ce1fd..5d0fe1bfe284 100644
--- a/srcpkgs/gst-plugins-good1/template
+++ b/srcpkgs/gst-plugins-good1/template
@@ -1,6 +1,6 @@
# Template file for 'gst-plugins-good1'
pkgname=gst-plugins-good1
-version=1.20.3
+version=1.22.2
revision=1
build_style=meson
configure_args="-Ddv=disabled -Ddv1394=disabled -Dshout2=disabled -Dqt5=enabled
@@ -22,7 +22,7 @@ maintainer="Orphaned <orphan@voidlinux.org>"
license="LGPL-2.1-or-later"
homepage="https://gstreamer.freedesktop.org"
distfiles="${homepage}/src/${pkgname/1/}/${pkgname/1/}-${version}.tar.xz"
-checksum=f8f3c206bf5cdabc00953920b47b3575af0ef15e9f871c0b6966f6d0aa5868b7
+checksum=7c8cc59425f2b232f60ca7d13e56edd615da4f711e73dd01a7cffa46e6bc0cdd
build_options="gtk3 wayland"
build_options_default="gtk3 wayland"
diff --git a/srcpkgs/gst1-editing-services/template b/srcpkgs/gst1-editing-services/template
index 673b46970f24..102440f7f253 100644
--- a/srcpkgs/gst1-editing-services/template
+++ b/srcpkgs/gst1-editing-services/template
@@ -1,6 +1,6 @@
# Template file for 'gst1-editing-services'
pkgname=gst1-editing-services
-version=1.20.3
+version=1.22.2
revision=1
build_style=meson
build_helper="gir"
@@ -12,7 +12,7 @@ maintainer="Toyam Cox <Vaelatern@gmail.com>"
license="LGPL-2.0-or-later"
homepage="https://gstreamer.freedesktop.org"
distfiles="${homepage}/src/${pkgname/gst1/gst}/${pkgname/gst1/gst}-${version}.tar.xz"
-checksum=5fd896de69fbe24421eb6b0ff8d2f8b4c3cba3f3025ceacd302172f39a8abaa2
+checksum=453b1464fc3857de269a7cb0ebd966afe02171d97bef672a0b8a0a6d43e0cebf
do_check() {
: # Tests fail in older versions as well
diff --git a/srcpkgs/gst1-python3/template b/srcpkgs/gst1-python3/template
index 3f564ac64b93..789e40f036ea 100644
--- a/srcpkgs/gst1-python3/template
+++ b/srcpkgs/gst1-python3/template
@@ -1,7 +1,7 @@
# Template file for 'gst1-python3'
pkgname=gst1-python3
-version=1.20.3
-revision=2
+version=1.22.2
+revision=1
build_style=meson
hostmakedepends="pkg-config python3"
makedepends="libglib-devel python3-devel python3-gobject-devel gst-plugins-base1-devel"
@@ -11,4 +11,4 @@ maintainer="Orphaned <orphan@voidlinux.org>"
license="LGPL-2.1-or-later"
homepage="https://gstreamer.freedesktop.org"
distfiles="${homepage}/src/gst-python/gst-python-${version}.tar.xz"
-checksum=db348120eae955b8cc4de3560a7ea06e36d6e1ddbaa99a7ad96b59846601cfdc
+checksum=bef2b3d82ce4be46b775b1bb56305c1003ee01b535a53a82f9fe8924972153ad
diff --git a/srcpkgs/gstreamer-vaapi/template b/srcpkgs/gstreamer-vaapi/template
index 3cc4e057559a..0a5ee8b1ca3f 100644
--- a/srcpkgs/gstreamer-vaapi/template
+++ b/srcpkgs/gstreamer-vaapi/template
@@ -1,6 +1,6 @@
# Template file for 'gstreamer-vaapi'
pkgname=gstreamer-vaapi
-version=1.20.3
+version=1.22.2
revision=1
build_style=meson
hostmakedepends="pkg-config"
@@ -11,7 +11,7 @@ license="LGPL-2.1-or-later"
homepage="https://gstreamer.freedesktop.org"
changelog="https://raw.githubusercontent.com/GStreamer/gstreamer-vaapi/master/ChangeLog"
distfiles="${homepage}/src/gstreamer-vaapi/gstreamer-vaapi-${version}.tar.xz"
-checksum=6ee99eb316abdde9ad37002915bd8c3867918f6fdc74b7cf2ac4c1ae0d690b45
+checksum=d2e642f9745f97d9f73a7f5085e7659a9a31fe209b774e6e45dae041b435df06
pre_check() {
# Seems to need certain hardware to pass
diff --git a/srcpkgs/gstreamer1/template b/srcpkgs/gstreamer1/template
index ae8a49cb20e8..571148f2ff33 100644
--- a/srcpkgs/gstreamer1/template
+++ b/srcpkgs/gstreamer1/template
@@ -1,6 +1,6 @@
# Template file for 'gstreamer1'
pkgname=gstreamer1
-version=1.20.3
+version=1.22.2
revision=1
build_style=meson
build_helper="gir"
@@ -16,7 +16,7 @@ maintainer="Orphaned <orphan@voidlinux.org>"
license="LGPL-2.0-or-later"
homepage="https://gstreamer.freedesktop.org"
distfiles="${homepage}/src/gstreamer/gstreamer-${version}.tar.xz"
-checksum=607daf64bbbd5fb18af9d17e21c0d22c4d702fffe83b23cb22d1b1af2ca23a2a
+checksum=b2afe73603921c608ba48969dbb7d743776744bfe5d8059ece241137b7f88e21
pre_check() {
# gst_gstdatetime is known to fail according to LFS
diff --git a/srcpkgs/mlt7/template b/srcpkgs/mlt7/template
index 9fb7f60d692e..cca0eb68cfc3 100644
--- a/srcpkgs/mlt7/template
+++ b/srcpkgs/mlt7/template
@@ -1,7 +1,7 @@
# Template file for 'mlt7'
pkgname=mlt7
version=7.14.0
-revision=1
+revision=2
build_style=cmake
configure_args="-DSWIG_PYTHON=ON"
hostmakedepends="doxygen pkg-config ladspa-sdk swig python3 which
From 211368a3a80f245ae0cd7677ac4b247360cfa969 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Sun, 7 May 2023 20:15:03 -0400
Subject: [PATCH 113/115] qt6-webengine: revbump for ffmpeg-6.0
---
srcpkgs/qt6-webengine/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/qt6-webengine/template b/srcpkgs/qt6-webengine/template
index 96846feaee83..2f85d2e49ba2 100644
--- a/srcpkgs/qt6-webengine/template
+++ b/srcpkgs/qt6-webengine/template
@@ -1,7 +1,7 @@
# Template file for 'qt6-webengine'
pkgname=qt6-webengine
version=6.4.2
-revision=2
+revision=3
build_style=cmake
configure_args="
-DQT_FEATURE_webengine_system_ffmpeg=ON
From 698dae0d5267c5794ed12fa9d73ad32c31118b46 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Sun, 7 May 2023 20:15:29 -0400
Subject: [PATCH 114/115] tracker-miners: revbump for ffmpeg-6.0
---
srcpkgs/tracker-miners/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/tracker-miners/template b/srcpkgs/tracker-miners/template
index 8c005d697fa4..a6e5aa577702 100644
--- a/srcpkgs/tracker-miners/template
+++ b/srcpkgs/tracker-miners/template
@@ -1,7 +1,7 @@
# Template file for 'tracker-miners'
pkgname=tracker-miners
version=3.5.0
-revision=3
+revision=4
build_style=meson
build_helper=qemu
# missing libgrss for miner_rss
From c44c15e7be63d789f3c77a2a99c14b1317625070 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Sun, 7 May 2023 20:20:58 -0400
Subject: [PATCH 115/115] mpd: revbump for ffmpeg-6.0
---
srcpkgs/mpd/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/mpd/template b/srcpkgs/mpd/template
index df35e751ea60..c832f608b889 100644
--- a/srcpkgs/mpd/template
+++ b/srcpkgs/mpd/template
@@ -1,7 +1,7 @@
# Template file for 'mpd'
pkgname=mpd
version=0.23.12
-revision=2
+revision=3
build_style=meson
configure_args="-Dopus=enabled -Dmikmod=enabled -Dneighbor=true
-Dsoundcloud=enabled -Dpipe=true -Dtwolame=enabled -Dbzip2=enabled
^ permalink raw reply [flat|nested] 175+ messages in thread
* Re: [PR PATCH] [Updated] ffmpeg6 split
2023-05-05 13:20 [PR PATCH] ffmpeg6 split zlice
` (6 preceding siblings ...)
2023-05-08 0:23 ` zlice
@ 2023-05-29 1:43 ` zlice
2023-06-04 15:47 ` zlice
` (165 subsequent siblings)
173 siblings, 0 replies; 175+ messages in thread
From: zlice @ 2023-05-29 1:43 UTC (permalink / raw)
To: ml
[-- Attachment #1: Type: text/plain, Size: 3336 bytes --]
There is an updated pull request by zlice against master on the void-packages repository
https://github.com/zlice/void-packages ffmpeg6-split
https://github.com/void-linux/void-packages/pull/43761
ffmpeg6 split
[ci skip]
#### Testing the changes
- I tested the changes in this PR: **YES**
main testing has been vaapi in Firefox Nightly and enc/dec in Shotcut on Intel A770
#### New package
- This new package conforms to the [package requirements](https://github.com/void-linux/void-packages/blob/master/CONTRIBUTING.md#package-requirements): **YES**
#### Local build testing
- I built this PR locally for my native architecture, **x86_64**
#### Discussion
Continuation of https://github.com/void-linux/void-packages/pull/36315
`libavresample` is deprecated, but marked as a dependency when trying to build other packages and install `ffmpeg`(6). I think the right way to handle this is make a meta package and the add to removals?
##### Commit naming / misc
~~Commits are 'dirty' right now, running with [gstreamer 1.22.1 updates](https://github.com/void-linux/void-packages/pull/42861) and [Intel OpenCL](https://github.com/void-linux/void-packages/pull/43084). This will also make [intel packages pr](https://github.com/void-linux/void-packages/pull/41132) obsolete.~~ (see Requirements below)
Maintainer for previous ffmpeg(4) was orphaned, I can put my name in there if that matters, though I don't exactly see myself keeping up on ffmpeg.
This updates QT5 which looks like it is usually hosted by Johnny. Not sure if there's any reason to stay there or these sources are fine.
##### STILL FFMPEG4
These are a mix of emulators, games and/or older packages.
- attract (multiple patches in master)
- audacity (3.2.x+ should work but requires wxWidgets dev 3.1.x)
- ccextractor (master patches? no release)
- vice
- kodi
- mlt (only dep left is flowblade)
- ~~synfig (mlt)~~ (work with mlt7, bump synfigstudio)
- tvheadend
- ssr
- spek-alternative
- ppsspp
- olive
- moc
- mediastreamer
- libextractor
- idjc
- hedgewars
- ~~ffmpegthumbnailer~~ (patches for moviedecoder.xxx files)
- ~~ffmpegthumbs~~ (latest compiles)
- deadbeef
- omxplayer
- qtav (fork has ffmpeg 5 patch - https://github.com/cmguo/QtAV)
- `vlc` (vlc4 will support ffmpeg5, there's a patch to build 3.x with ffmpeg5 but it will lack vaapi)
- `osg` (OpenSceneGraph plus `xine-lib`)
##### HAVE NOT BUILT YET
- omxplayer (rpi only? ffmpeg4)
- kodi (big, but ffmpeg4)
##### UPDATED (for ffmpeg6)
- ~~blender: update to 3.5.1~~ will be revbump with https://github.com/void-linux/void-packages/pull/43992
- unpaper: update to 7.0.0.
- guvcview: update to 2.0.8.
- qt5: update to 5.15.8
- qt5-webengine: update to 5.18.13
- shiboken2: revbump for qt5.15.8 (patch)
- python3-pyside2: update to 5.15.8 (patch)
##### Requirements
- [gstreamer 1.22.2](https://github.com/void-linux/void-packages/pull/42861) - a few packages use ffmpeg-devel and require a revbump
- [Intel Packages](https://github.com/void-linux/void-packages/pull/41132) - ffmpeg4 uses different libraries than 6 (libmfx / Intel-MediaSDK vs only oneVPL that Intel is moving to), both are included here
A patch file from https://github.com/void-linux/void-packages/pull/43761.patch is attached
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: github-pr-ffmpeg6-split-43761.patch --]
[-- Type: text/x-diff, Size: 785284 bytes --]
From d5c6fdefbc13d6594697c10f5253de4d97aa02ab Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 19:55:46 -0400
Subject: [PATCH 001/113] ffmpeg: update to 6.0.
---
common/shlibs | 26 +++++---
srcpkgs/ffmpeg/files/altivec.patch | 60 -------------------
.../patches/armv5tel-floating-point.patch | 18 ------
.../workaround-mesa-readeon-vaapi-bug.patch | 28 ---------
srcpkgs/ffmpeg/template | 38 +++++-------
5 files changed, 32 insertions(+), 138 deletions(-)
delete mode 100644 srcpkgs/ffmpeg/files/altivec.patch
delete mode 100644 srcpkgs/ffmpeg/patches/armv5tel-floating-point.patch
delete mode 100644 srcpkgs/ffmpeg/patches/workaround-mesa-readeon-vaapi-bug.patch
diff --git a/common/shlibs b/common/shlibs
index f1e825819fb4..371e4ff11aa1 100644
--- a/common/shlibs
+++ b/common/shlibs
@@ -390,15 +390,23 @@ libid3tag.so.0 libid3tag-0.15.1b_1
libgif.so.7 giflib-5.1.0_1
libImlib2.so.1 imlib2-1.4.2_1
libmp3lame.so.0 lame-3.98.2_1
-libavdevice.so.58 libavdevice-4.0_1
-libavformat.so.58 libavformat-4.0_1
-libswscale.so.5 libswscale-4.0_1
-libswresample.so.3 libswresample-4.0_1
-libavresample.so.4 libavresample-4.0_1
-libpostproc.so.55 libpostproc-4.0_1
-libavcodec.so.58 libavcodec-4.0_1
-libavutil.so.56 libavutil-4.0_1
-libavfilter.so.7 libavfilter-4.0_1
+libavdevice.so.60 libavdevice-6.0_1
+libavformat.so.60 libavformat-6.0_1
+libswscale.so.7 libswscale-6.0_1
+libswresample.so.4 libswresample-6.0_1
+libpostproc.so.57 libpostproc-6.0_1
+libavcodec.so.60 libavcodec-6.0_1
+libavutil.so.58 libavutil-6.0_1
+libavfilter.so.9 libavfilter-6.0_1
+libavdevice.so.58 libavdevice4-4.0_1
+libavformat.so.58 libavformat4-4.0_1
+libswscale.so.5 libswscale4-4.0_1
+libswresample.so.3 libswresample4-4.0_1
+libavresample.so.4 libavresample4-4.0_1
+libpostproc.so.55 libpostproc4-4.0_1
+libavcodec.so.58 libavcodec4-4.0_1
+libavutil.so.56 libavutil4-4.0_1
+libavfilter.so.7 libavfilter4-4.0_1
libSDL-1.2.so.0 SDL-1.2.14_1
libSDL_image-1.2.so.0 SDL_image-1.2.10_1
libx264.so.157 x264-20190507.2245_1
diff --git a/srcpkgs/ffmpeg/files/altivec.patch b/srcpkgs/ffmpeg/files/altivec.patch
deleted file mode 100644
index 9c5720046332..000000000000
--- a/srcpkgs/ffmpeg/files/altivec.patch
+++ /dev/null
@@ -1,60 +0,0 @@
-revert some altivec specific change on all ppc* except ppc64le*
-
-q66: "We should also throw in a revert of FFmpeg/FFmpeg@3a557c5 but only
-conditionally, for ppc* but not ppc64le* (the new code is valid for
-POWER8 VSX which LE targets as a baseline but not BE)"
-
-
-This reverts commit 3a557c5d88b7b15b5954ba2743febb055549b536.
----
- libswscale/ppc/yuv2rgb_altivec.c | 24 ++++++++++++++++++++----
- 1 file changed, 20 insertions(+), 4 deletions(-)
-
-diff --git a/libswscale/ppc/yuv2rgb_altivec.c b/libswscale/ppc/yuv2rgb_altivec.c
-index 536545293d..c1e2852adb 100644
---- a/libswscale/ppc/yuv2rgb_altivec.c
-+++ b/libswscale/ppc/yuv2rgb_altivec.c
-@@ -305,6 +305,9 @@ static int altivec_ ## name(SwsContext *c, const unsigned char **in, \
- vector signed short R1, G1, B1; \
- vector unsigned char R, G, B; \
- \
-+ const vector unsigned char *y1ivP, *y2ivP, *uivP, *vivP; \
-+ vector unsigned char align_perm; \
-+ \
- vector signed short lCY = c->CY; \
- vector signed short lOY = c->OY; \
- vector signed short lCRV = c->CRV; \
-@@ -335,13 +338,26 @@ static int altivec_ ## name(SwsContext *c, const unsigned char **in, \
- vec_dstst(oute, (0x02000002 | (((w * 3 + 32) / 32) << 16)), 1); \
- \
- for (j = 0; j < w / 16; j++) { \
-- y0 = vec_xl(0, y1i); \
-+ y1ivP = (const vector unsigned char *) y1i; \
-+ y2ivP = (const vector unsigned char *) y2i; \
-+ uivP = (const vector unsigned char *) ui; \
-+ vivP = (const vector unsigned char *) vi; \
-+ \
-+ align_perm = vec_lvsl(0, y1i); \
-+ y0 = (vector unsigned char) \
-+ vec_perm(y1ivP[0], y1ivP[1], align_perm); \
- \
-- y1 = vec_xl(0, y2i); \
-+ align_perm = vec_lvsl(0, y2i); \
-+ y1 = (vector unsigned char) \
-+ vec_perm(y2ivP[0], y2ivP[1], align_perm); \
- \
-- u = (vector signed char) vec_xl(0, ui); \
-+ align_perm = vec_lvsl(0, ui); \
-+ u = (vector signed char) \
-+ vec_perm(uivP[0], uivP[1], align_perm); \
- \
-- v = (vector signed char) vec_xl(0, vi); \
-+ align_perm = vec_lvsl(0, vi); \
-+ v = (vector signed char) \
-+ vec_perm(vivP[0], vivP[1], align_perm); \
- \
- u = (vector signed char) \
- vec_sub(u, \
---
-2.27.0
-
diff --git a/srcpkgs/ffmpeg/patches/armv5tel-floating-point.patch b/srcpkgs/ffmpeg/patches/armv5tel-floating-point.patch
deleted file mode 100644
index 9a55178c74f0..000000000000
--- a/srcpkgs/ffmpeg/patches/armv5tel-floating-point.patch
+++ /dev/null
@@ -1,18 +0,0 @@
---- a/libavfilter/vf_drawtext.c 2017-10-26 21:03:03.000000000 +0200
-+++ b/libavfilter/vf_drawtext.c 2017-11-21 11:06:49.602284422 +0100
-@@ -39,6 +39,15 @@
- #endif
- #include <fenv.h>
-
-+#if (FE_ALL_EXCEPT == 0)
-+/* E.g. ARM soft float does not define these */
-+#define FE_INVALID 0
-+#define FE_DIVBYZERO 0
-+#define FE_OVERFLOW 0
-+#define FE_UNDERFLOW 0
-+#define FE_INEXACT 0
-+#endif
-+
- #if CONFIG_LIBFONTCONFIG
- #include <fontconfig/fontconfig.h>
- #endif
diff --git a/srcpkgs/ffmpeg/patches/workaround-mesa-readeon-vaapi-bug.patch b/srcpkgs/ffmpeg/patches/workaround-mesa-readeon-vaapi-bug.patch
deleted file mode 100644
index 00e3f68a415b..000000000000
--- a/srcpkgs/ffmpeg/patches/workaround-mesa-readeon-vaapi-bug.patch
+++ /dev/null
@@ -1,28 +0,0 @@
-From 811d290844206fc73dc39c3e5b67d5d895baedf8 Mon Sep 17 00:00:00 2001
-From: Rainer Hochecker <fernetmenta@online.de>
-Date: Sat, 26 Jan 2019 19:48:35 +0100
-Subject: [PATCH] avcodec/vaapi_h264: skip decode if pic has no slices
-
-This fixes / workarounds https://bugs.freedesktop.org/show_bug.cgi?id=105368.
-It was hit frequently when watching h264 channels received via DVB-X.
-Corresponding kodi bug: https://github.com/xbmc/xbmc/issues/15704
----
- libavcodec/vaapi_h264.c | 5 +++++
- 1 file changed, 5 insertions(+)
-
-diff --git a/libavcodec/vaapi_h264.c b/libavcodec/vaapi_h264.c
-index 5854587a255..f12fdc457a4 100644
---- a/libavcodec/vaapi_h264.c
-+++ b/libavcodec/vaapi_h264.c
-@@ -317,6 +317,11 @@ static int vaapi_h264_end_frame(AVCodecContext *avctx)
- H264SliceContext *sl = &h->slice_ctx[0];
- int ret;
-
-+ if (pic->nb_slices == 0) {
-+ ret = AVERROR_INVALIDDATA;
-+ goto finish;
-+ }
-+
- ret = ff_vaapi_decode_issue(avctx, pic);
- if (ret < 0)
- goto finish;
diff --git a/srcpkgs/ffmpeg/template b/srcpkgs/ffmpeg/template
index df4179d1963a..f742082bb520 100644
--- a/srcpkgs/ffmpeg/template
+++ b/srcpkgs/ffmpeg/template
@@ -1,7 +1,7 @@
# Template file for 'ffmpeg'
# audacity also needs to be bumped when a new ffmpeg version bumps libavformat's soname!
pkgname=ffmpeg
-version=4.4.4
+version=6.0
revision=1
short_desc="Decoding, encoding and streaming software"
maintainer="Orphaned <orphan@voidlinux.org>"
@@ -9,7 +9,7 @@ license="GPL-3.0-or-later"
homepage="https://www.ffmpeg.org"
changelog="https://raw.githubusercontent.com/FFmpeg/FFmpeg/master/Changelog"
distfiles="https://www.ffmpeg.org/releases/ffmpeg-${version}.tar.xz"
-checksum=e80b380d595c809060f66f96a5d849511ef4a76a26b76eacf5778b94c3570309
+checksum=57be87c22d9b49c112b6d24bc67d42508660e6b718b3db89c44e47e289137082
hostmakedepends="pkg-config perl"
makedepends="zlib-devel bzip2-devel freetype-devel alsa-lib-devel libXfixes-devel
@@ -26,12 +26,13 @@ makedepends="zlib-devel bzip2-devel freetype-devel alsa-lib-devel libXfixes-deve
$(vopt_if webp libwebp-devel) $(vopt_if sofa libmysofa-devel)
$(vopt_if drm libdrm-devel) $(vopt_if svtav1 libsvt-av1-devel)
$(vopt_if srt srt-devel) $(vopt_if rist librist-devel)
- $(vopt_if vulkan 'vulkan-loader Vulkan-Headers')
+ $(vopt_if vulkan 'vulkan-loader Vulkan-Headers Vulkan-Tools Vulkan-ValidationLayers')
+ $(vopt_if onevpl 'onevpl onevpl-devel')
$(vopt_if nvenc nv-codec-headers) $(vopt_if nvdec nv-codec-headers)"
depends="ffplay>=${version}_${revision}"
build_options="x265 v4l2 vaapi vdpau vpx fdk_aac aom nvenc sndio pulseaudio
- dav1d zimg webp sofa vulkan drm svtav1 srt rist nvdec"
+ dav1d zimg webp sofa vulkan drm svtav1 srt rist nvdec onevpl"
build_options_default="x265 v4l2 vpx aom sndio pulseaudio dav1d webp vulkan drm srt rist"
desc_option_srt="Enable support for SRT (Secure, Reliable, Transport)"
desc_option_rist="Enable support for RIST (Reliable Internet Stream Transport)"
@@ -39,10 +40,8 @@ desc_option_sofa="Enable support for AES SOFA"
desc_option_webp="Enable support for WebP"
case "$XBPS_TARGET_MACHINE" in
- i686*|x86_64*)
- hostmakedepends+=" nasm"
- build_options_default+=" vaapi vdpau nvenc nvdec"
- ;;
+ i686*) build_options_default+=" vaapi vdpau nvenc nvdec";;
+ x86_64*) build_options_default+=" vaapi vdpau nvenc nvdec onevpl";;
ppc64*) build_options_default+=" vaapi vdpau";;
mips*) CFLAGS="-mnan=legacy";;
esac
@@ -117,18 +116,19 @@ do_configure() {
$(vopt_enable x265 libx265) \
$(vopt_enable v4l2 libv4l2) \
$(vopt_enable aom libaom) $(vopt_enable vaapi) $(vopt_enable vdpau) \
- --enable-libbs2b --enable-avresample --enable-libvidstab \
+ --enable-libbs2b --enable-libvidstab \
$(vopt_enable dav1d libdav1d) \
$(vopt_enable zimg libzimg) \
$(vopt_enable webp libwebp) \
$(vopt_enable sofa libmysofa) \
$(vopt_enable vulkan) \
+ $(vopt_enable onevpl libvpl) \
$(vopt_enable drm libdrm) \
$(vopt_enable svtav1 libsvtav1) \
$(vopt_enable srt libsrt) \
$(vopt_enable rist librist) \
- $(vopt_if nvenc '--enable-nvenc') \
- $(vopt_if nvdec '--enable-nvdec')
+ $(vopt_enable nvenc nvenc) \
+ $(vopt_enable nvdec nvdec)
}
do_build() {
@@ -155,10 +155,8 @@ libavdevice_package() {
}
libavresample_package() {
- short_desc="FFmpeg audio resampling library"
- pkg_install() {
- vmove "usr/lib/libavresample.so.*"
- }
+ short_desc="Package deprecated, removal needed"
+ build_style=meta
}
libavformat_package() {
@@ -212,15 +210,9 @@ ffmpeg-devel_package() {
libavfilter>=${version}_${revision}
libpostproc>=${version}_${revision}
libswscale>=${version}_${revision}
- libswresample>=${version}_${revision}
- libavresample>=${version}_${revision}"
+ libswresample>=${version}_${revision}"
short_desc+=" - development files"
-
- if [ "$XBPS_TARGET_MACHINE" = "i686" ]; then
- # /usr/bin/strip: error: the input file '/destdir//ffmpeg-devel-4.4.4/usr/lib/libavfilter.a(vf_atadenoise.o)' has no sections
- nostrip_files="/usr/lib/libavfilter.a"
- fi
-
+ conflicts="ffmpeg4-devel"
pkg_install() {
vmove usr/include
vmove usr/lib/pkgconfig
From 9bc85f30b9a74d000fdaa7b814cd964dbe60e2a9 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 19:56:22 -0400
Subject: [PATCH 002/113] New package: ffmpeg4-4.4.4.
---
srcpkgs/ffmpeg4-devel | 1 +
srcpkgs/ffmpeg4/files/altivec.patch | 60 +++++
.../patches/armv5tel-floating-point.patch | 18 ++
.../workaround-mesa-readeon-vaapi-bug.patch | 28 +++
srcpkgs/ffmpeg4/template | 238 ++++++++++++++++++
srcpkgs/libavcodec4 | 1 +
srcpkgs/libavdevice4 | 1 +
srcpkgs/libavfilter4 | 1 +
srcpkgs/libavformat4 | 1 +
srcpkgs/libavresample4 | 1 +
srcpkgs/libavutil4 | 1 +
srcpkgs/libpostproc4 | 1 +
srcpkgs/libswresample4 | 1 +
srcpkgs/libswscale4 | 1 +
14 files changed, 354 insertions(+)
create mode 120000 srcpkgs/ffmpeg4-devel
create mode 100644 srcpkgs/ffmpeg4/files/altivec.patch
create mode 100644 srcpkgs/ffmpeg4/patches/armv5tel-floating-point.patch
create mode 100644 srcpkgs/ffmpeg4/patches/workaround-mesa-readeon-vaapi-bug.patch
create mode 100644 srcpkgs/ffmpeg4/template
create mode 120000 srcpkgs/libavcodec4
create mode 120000 srcpkgs/libavdevice4
create mode 120000 srcpkgs/libavfilter4
create mode 120000 srcpkgs/libavformat4
create mode 120000 srcpkgs/libavresample4
create mode 120000 srcpkgs/libavutil4
create mode 120000 srcpkgs/libpostproc4
create mode 120000 srcpkgs/libswresample4
create mode 120000 srcpkgs/libswscale4
diff --git a/srcpkgs/ffmpeg4-devel b/srcpkgs/ffmpeg4-devel
new file mode 120000
index 000000000000..887f354e7c6b
--- /dev/null
+++ b/srcpkgs/ffmpeg4-devel
@@ -0,0 +1 @@
+ffmpeg4
\ No newline at end of file
diff --git a/srcpkgs/ffmpeg4/files/altivec.patch b/srcpkgs/ffmpeg4/files/altivec.patch
new file mode 100644
index 000000000000..9c5720046332
--- /dev/null
+++ b/srcpkgs/ffmpeg4/files/altivec.patch
@@ -0,0 +1,60 @@
+revert some altivec specific change on all ppc* except ppc64le*
+
+q66: "We should also throw in a revert of FFmpeg/FFmpeg@3a557c5 but only
+conditionally, for ppc* but not ppc64le* (the new code is valid for
+POWER8 VSX which LE targets as a baseline but not BE)"
+
+
+This reverts commit 3a557c5d88b7b15b5954ba2743febb055549b536.
+---
+ libswscale/ppc/yuv2rgb_altivec.c | 24 ++++++++++++++++++++----
+ 1 file changed, 20 insertions(+), 4 deletions(-)
+
+diff --git a/libswscale/ppc/yuv2rgb_altivec.c b/libswscale/ppc/yuv2rgb_altivec.c
+index 536545293d..c1e2852adb 100644
+--- a/libswscale/ppc/yuv2rgb_altivec.c
++++ b/libswscale/ppc/yuv2rgb_altivec.c
+@@ -305,6 +305,9 @@ static int altivec_ ## name(SwsContext *c, const unsigned char **in, \
+ vector signed short R1, G1, B1; \
+ vector unsigned char R, G, B; \
+ \
++ const vector unsigned char *y1ivP, *y2ivP, *uivP, *vivP; \
++ vector unsigned char align_perm; \
++ \
+ vector signed short lCY = c->CY; \
+ vector signed short lOY = c->OY; \
+ vector signed short lCRV = c->CRV; \
+@@ -335,13 +338,26 @@ static int altivec_ ## name(SwsContext *c, const unsigned char **in, \
+ vec_dstst(oute, (0x02000002 | (((w * 3 + 32) / 32) << 16)), 1); \
+ \
+ for (j = 0; j < w / 16; j++) { \
+- y0 = vec_xl(0, y1i); \
++ y1ivP = (const vector unsigned char *) y1i; \
++ y2ivP = (const vector unsigned char *) y2i; \
++ uivP = (const vector unsigned char *) ui; \
++ vivP = (const vector unsigned char *) vi; \
++ \
++ align_perm = vec_lvsl(0, y1i); \
++ y0 = (vector unsigned char) \
++ vec_perm(y1ivP[0], y1ivP[1], align_perm); \
+ \
+- y1 = vec_xl(0, y2i); \
++ align_perm = vec_lvsl(0, y2i); \
++ y1 = (vector unsigned char) \
++ vec_perm(y2ivP[0], y2ivP[1], align_perm); \
+ \
+- u = (vector signed char) vec_xl(0, ui); \
++ align_perm = vec_lvsl(0, ui); \
++ u = (vector signed char) \
++ vec_perm(uivP[0], uivP[1], align_perm); \
+ \
+- v = (vector signed char) vec_xl(0, vi); \
++ align_perm = vec_lvsl(0, vi); \
++ v = (vector signed char) \
++ vec_perm(vivP[0], vivP[1], align_perm); \
+ \
+ u = (vector signed char) \
+ vec_sub(u, \
+--
+2.27.0
+
diff --git a/srcpkgs/ffmpeg4/patches/armv5tel-floating-point.patch b/srcpkgs/ffmpeg4/patches/armv5tel-floating-point.patch
new file mode 100644
index 000000000000..9a55178c74f0
--- /dev/null
+++ b/srcpkgs/ffmpeg4/patches/armv5tel-floating-point.patch
@@ -0,0 +1,18 @@
+--- a/libavfilter/vf_drawtext.c 2017-10-26 21:03:03.000000000 +0200
++++ b/libavfilter/vf_drawtext.c 2017-11-21 11:06:49.602284422 +0100
+@@ -39,6 +39,15 @@
+ #endif
+ #include <fenv.h>
+
++#if (FE_ALL_EXCEPT == 0)
++/* E.g. ARM soft float does not define these */
++#define FE_INVALID 0
++#define FE_DIVBYZERO 0
++#define FE_OVERFLOW 0
++#define FE_UNDERFLOW 0
++#define FE_INEXACT 0
++#endif
++
+ #if CONFIG_LIBFONTCONFIG
+ #include <fontconfig/fontconfig.h>
+ #endif
diff --git a/srcpkgs/ffmpeg4/patches/workaround-mesa-readeon-vaapi-bug.patch b/srcpkgs/ffmpeg4/patches/workaround-mesa-readeon-vaapi-bug.patch
new file mode 100644
index 000000000000..00e3f68a415b
--- /dev/null
+++ b/srcpkgs/ffmpeg4/patches/workaround-mesa-readeon-vaapi-bug.patch
@@ -0,0 +1,28 @@
+From 811d290844206fc73dc39c3e5b67d5d895baedf8 Mon Sep 17 00:00:00 2001
+From: Rainer Hochecker <fernetmenta@online.de>
+Date: Sat, 26 Jan 2019 19:48:35 +0100
+Subject: [PATCH] avcodec/vaapi_h264: skip decode if pic has no slices
+
+This fixes / workarounds https://bugs.freedesktop.org/show_bug.cgi?id=105368.
+It was hit frequently when watching h264 channels received via DVB-X.
+Corresponding kodi bug: https://github.com/xbmc/xbmc/issues/15704
+---
+ libavcodec/vaapi_h264.c | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+diff --git a/libavcodec/vaapi_h264.c b/libavcodec/vaapi_h264.c
+index 5854587a255..f12fdc457a4 100644
+--- a/libavcodec/vaapi_h264.c
++++ b/libavcodec/vaapi_h264.c
+@@ -317,6 +317,11 @@ static int vaapi_h264_end_frame(AVCodecContext *avctx)
+ H264SliceContext *sl = &h->slice_ctx[0];
+ int ret;
+
++ if (pic->nb_slices == 0) {
++ ret = AVERROR_INVALIDDATA;
++ goto finish;
++ }
++
+ ret = ff_vaapi_decode_issue(avctx, pic);
+ if (ret < 0)
+ goto finish;
diff --git a/srcpkgs/ffmpeg4/template b/srcpkgs/ffmpeg4/template
new file mode 100644
index 000000000000..5228c7df08fb
--- /dev/null
+++ b/srcpkgs/ffmpeg4/template
@@ -0,0 +1,238 @@
+# Template file for 'ffmpeg4'
+# audacity also needs to be bumped when a new ffmpeg version bumps libavformat's soname!
+pkgname=ffmpeg4
+version=4.4.4
+revision=1
+short_desc="Decoding, encoding and streaming software - ffmpeg4 libraries only"
+maintainer="Orphaned <orphan@voidlinux.org>"
+license="GPL-3.0-or-later"
+homepage="https://www.ffmpeg.org"
+changelog="https://raw.githubusercontent.com/FFmpeg/FFmpeg/master/Changelog"
+distfiles="https://www.ffmpeg.org/releases/ffmpeg-${version}.tar.xz"
+checksum=e80b380d595c809060f66f96a5d849511ef4a76a26b76eacf5778b94c3570309
+
+hostmakedepends="pkg-config perl"
+makedepends="zlib-devel bzip2-devel freetype-devel alsa-lib-devel libXfixes-devel
+ libXext-devel libXvMC-devel libxcb-devel lame-devel libtheora-devel
+ libvorbis-devel x264-devel xvidcore-devel jack-devel SDL2-devel
+ libcdio-paranoia-devel librtmp-devel libmodplug-devel gnutls-devel
+ speex-devel celt-devel harfbuzz-devel libass-devel opus-devel ocl-icd-devel
+ libbs2b-devel libvidstab-devel $(vopt_if pulseaudio pulseaudio-devel)
+ $(vopt_if vaapi libva-devel) $(vopt_if vdpau libvdpau-devel)
+ $(vopt_if x265 x265-devel) $(vopt_if v4l2 v4l-utils-devel)
+ $(vopt_if fdk_aac fdk-aac-devel) $(vopt_if vpx libvpx-devel)
+ $(vopt_if aom libaom-devel) $(vopt_if sndio sndio-devel)
+ $(vopt_if dav1d libdav1d-devel) $(vopt_if zimg zimg-devel)
+ $(vopt_if webp libwebp-devel) $(vopt_if sofa libmysofa-devel)
+ $(vopt_if drm libdrm-devel) $(vopt_if svtav1 libsvt-av1-devel)
+ $(vopt_if srt srt-devel) $(vopt_if rist librist-devel)
+ $(vopt_if vulkan 'vulkan-loader Vulkan-Headers')
+ $(vopt_if mfx 'libmfx libmfx-devel')
+ $(vopt_if nvenc nv-codec-headers) $(vopt_if nvdec nv-codec-headers)"
+
+build_options="x265 v4l2 vaapi vdpau vpx fdk_aac aom nvenc sndio pulseaudio
+ dav1d zimg webp sofa vulkan drm svtav1 srt rist nvdec mfx"
+build_options_default="x265 v4l2 vpx aom sndio pulseaudio dav1d webp vulkan drm srt rist"
+
+desc_option_srt="Enable support for SRT (Secure, Reliable, Transport)"
+desc_option_rist="Enable support for RIST (Reliable Internet Stream Transport)"
+desc_option_sofa="Enable support for AES SOFA"
+desc_option_webp="Enable support for WebP"
+
+case "$XBPS_TARGET_MACHINE" in
+ i686*)
+ hostmakedepends+=" nasm"
+ build_options_default+=" vaapi vdpau nvenc nvdec"
+ ;;
+ x86_64*)
+ hostmakedepends+=" nasm"
+ build_options_default+=" vaapi vdpau mfx nvenc nvdec"
+ ;;
+ ppc64*) build_options_default+=" vaapi vdpau";;
+ mips*) CFLAGS="-mnan=legacy";;
+esac
+
+if [ "$XBPS_TARGET_WORDSIZE" != "32" ]; then
+ build_options_default+=" svtav1"
+fi
+
+if [ "$XBPS_TARGET_NO_ATOMIC8" ]; then
+ makedepends+=" libatomic-devel"
+fi
+
+_apply_patch() {
+ local args="$1" pname="$(basename $2)"
+
+ if [ ! -f ".${pname}_done" ]; then
+ patch -N $args -i $2
+ touch .${pname}_done
+ fi
+}
+
+post_patch() {
+ case "$XBPS_TARGET_MACHINE" in
+ ppc64le*) ;;
+ ppc*) _apply_patch -p1 ${FILESDIR}/altivec.patch ;;
+ esac
+}
+
+do_configure() {
+ # Fix gcc on x86_64-musl only
+ if [ "$XBPS_TARGET_MACHINE" = "x86_64-musl" ]; then
+ vsed -i configure -e "s;_cflags_speed='-O3';_cflags_speed='-O2';"
+ fi
+
+ if [ "$CROSS_BUILD" ]; then
+ case "$XBPS_TARGET_MACHINE" in
+ arm*) _arch="arm";;
+ aarch64*) _arch="aarch64";;
+ mips*) _arch="mips";;
+ ppc64*) _arch="ppc64";;
+ ppc*) _arch="ppc";;
+ *) _arch="${XBPS_TARGET_MACHINE%%-musl}";;
+ esac
+
+ _args+=" --enable-cross-compile
+ --sysroot=$XBPS_CROSS_BASE
+ --cross-prefix=${XBPS_CROSS_TRIPLET}-
+ --target-os=linux --arch=${_arch}"
+ fi
+
+ case "$XBPS_TARGET_MACHINE" in
+ ppc|ppc-musl) _args+=" --disable-altivec";;
+ esac
+
+ if [ "$XBPS_TARGET_NO_ATOMIC8" ]; then
+ _args+=" --extra-libs=-latomic"
+ fi
+
+ ./configure --prefix=/usr --disable-debug --enable-gpl --enable-gnutls \
+ --disable-stripping \
+ --enable-libcdio --enable-version3 --enable-runtime-cpudetect \
+ --enable-libmp3lame --enable-libvorbis --enable-libxvid \
+ --enable-libx264 $(vopt_enable vpx libvpx) --enable-libtheora \
+ --enable-shared --enable-static --enable-libxcb \
+ $(vopt_enable pulseaudio libpulse) --enable-libfreetype --enable-libmodplug \
+ --enable-libspeex --enable-libcelt --enable-libass \
+ --enable-libopus --enable-librtmp --enable-libjack \
+ $(vopt_if fdk_aac '--enable-nonfree --enable-libfdk-aac') \
+ --disable-libopencore_amrnb --disable-libopencore_amrwb \
+ --disable-libopenjpeg \
+ --enable-postproc --enable-opencl ${_args} \
+ $(vopt_enable x265 libx265) \
+ $(vopt_enable v4l2 libv4l2) \
+ $(vopt_enable aom libaom) $(vopt_enable vaapi) $(vopt_enable vdpau) \
+ --enable-libbs2b --enable-avresample --enable-libvidstab \
+ $(vopt_enable dav1d libdav1d) \
+ $(vopt_enable zimg libzimg) \
+ $(vopt_enable webp libwebp) \
+ $(vopt_enable sofa libmysofa) \
+ $(vopt_enable vulkan) \
+ $(vopt_enable drm libdrm) \
+ $(vopt_enable svtav1 libsvtav1) \
+ $(vopt_enable srt libsrt) \
+ $(vopt_enable rist librist) \
+ $(vopt_enable mfx libmfx) \
+ $(vopt_if nvenc '--enable-nvenc') \
+ $(vopt_if nvdec '--enable-nvdec')
+}
+
+do_build() {
+ make ${makejobs}
+ make doc/ff{mpeg,play}.1
+}
+
+do_install() {
+ make DESTDIR=${DESTDIR} install install-man
+ rm -rf ${DESTDIR}/usr/bin
+}
+
+libavcodec4_package() {
+ short_desc="FFmpeg codec library"
+ pkg_install() {
+ vmove "usr/lib/libavcodec.so.*"
+ }
+}
+
+libavdevice4_package() {
+ short_desc="FFmpeg device handling library"
+ pkg_install() {
+ vmove "usr/lib/libavdevice.so.*"
+ }
+}
+
+libavresample4_package() {
+ short_desc="FFmpeg audio resampling library"
+ pkg_install() {
+ vmove "usr/lib/libavresample.so.*"
+ }
+}
+
+libavformat4_package() {
+ short_desc="FFmpeg file format library"
+ pkg_install() {
+ vmove "usr/lib/libavformat.so.*"
+ }
+}
+
+libavutil4_package() {
+ short_desc="FFmpeg utility library"
+ pkg_install() {
+ vmove "usr/lib/libavutil.so.*"
+ }
+}
+
+libavfilter4_package() {
+ short_desc="FFmpeg audio/video filter library"
+ pkg_install() {
+ vmove "usr/lib/libavfilter.so.*"
+ }
+}
+
+libpostproc4_package() {
+ short_desc="FFmpeg video postprocessing library"
+ pkg_install() {
+ vmove "usr/lib/libpostproc.so.*"
+ }
+}
+
+libswscale4_package() {
+ short_desc="FFmpeg video scaling library"
+ pkg_install() {
+ vmove "usr/lib/libswscale.so.*"
+ }
+}
+
+libswresample4_package() {
+ short_desc="FFmpeg video resampling library"
+ pkg_install() {
+ vmove "usr/lib/libswresample.so.*"
+ }
+}
+
+ffmpeg4-devel_package() {
+ depends="
+ libavcodec4>=${version}_${revision}
+ libavdevice4>=${version}_${revision}
+ libavformat4>=${version}_${revision}
+ libavutil4>=${version}_${revision}
+ libavfilter4>=${version}_${revision}
+ libpostproc4>=${version}_${revision}
+ libswscale4>=${version}_${revision}
+ libswresample4>=${version}_${revision}
+ libavresample4>=${version}_${revision}"
+ short_desc+=" - development files"
+ conflicts="ffmpeg-devel"
+ if [ "$XBPS_TARGET_MACHINE" = "i686" ]; then
+ # /usr/bin/strip: error: the input file '/destdir//ffmpeg-devel-4.4.4/usr/lib/libavfilter.a(vf_atadenoise.o)' has no sections
+ nostrip_files="/usr/lib/libavfilter.a"
+ fi
+ pkg_install() {
+ vmove usr/include
+ vmove usr/lib/pkgconfig
+ vmove "usr/lib/*.a"
+ vmove "usr/lib/*.so"
+ vmove usr/share/ffmpeg/examples
+ vmove usr/share/man/man3
+ }
+}
diff --git a/srcpkgs/libavcodec4 b/srcpkgs/libavcodec4
new file mode 120000
index 000000000000..887f354e7c6b
--- /dev/null
+++ b/srcpkgs/libavcodec4
@@ -0,0 +1 @@
+ffmpeg4
\ No newline at end of file
diff --git a/srcpkgs/libavdevice4 b/srcpkgs/libavdevice4
new file mode 120000
index 000000000000..887f354e7c6b
--- /dev/null
+++ b/srcpkgs/libavdevice4
@@ -0,0 +1 @@
+ffmpeg4
\ No newline at end of file
diff --git a/srcpkgs/libavfilter4 b/srcpkgs/libavfilter4
new file mode 120000
index 000000000000..887f354e7c6b
--- /dev/null
+++ b/srcpkgs/libavfilter4
@@ -0,0 +1 @@
+ffmpeg4
\ No newline at end of file
diff --git a/srcpkgs/libavformat4 b/srcpkgs/libavformat4
new file mode 120000
index 000000000000..887f354e7c6b
--- /dev/null
+++ b/srcpkgs/libavformat4
@@ -0,0 +1 @@
+ffmpeg4
\ No newline at end of file
diff --git a/srcpkgs/libavresample4 b/srcpkgs/libavresample4
new file mode 120000
index 000000000000..887f354e7c6b
--- /dev/null
+++ b/srcpkgs/libavresample4
@@ -0,0 +1 @@
+ffmpeg4
\ No newline at end of file
diff --git a/srcpkgs/libavutil4 b/srcpkgs/libavutil4
new file mode 120000
index 000000000000..887f354e7c6b
--- /dev/null
+++ b/srcpkgs/libavutil4
@@ -0,0 +1 @@
+ffmpeg4
\ No newline at end of file
diff --git a/srcpkgs/libpostproc4 b/srcpkgs/libpostproc4
new file mode 120000
index 000000000000..887f354e7c6b
--- /dev/null
+++ b/srcpkgs/libpostproc4
@@ -0,0 +1 @@
+ffmpeg4
\ No newline at end of file
diff --git a/srcpkgs/libswresample4 b/srcpkgs/libswresample4
new file mode 120000
index 000000000000..887f354e7c6b
--- /dev/null
+++ b/srcpkgs/libswresample4
@@ -0,0 +1 @@
+ffmpeg4
\ No newline at end of file
diff --git a/srcpkgs/libswscale4 b/srcpkgs/libswscale4
new file mode 120000
index 000000000000..887f354e7c6b
--- /dev/null
+++ b/srcpkgs/libswscale4
@@ -0,0 +1 @@
+ffmpeg4
\ No newline at end of file
From d8975c8329d4d0565f176ad41881012b0a8a031a Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 19:59:04 -0400
Subject: [PATCH 003/113] opencv: update to 4.7.0.
---
common/shlibs | 104 ++++++++++++++++++++--------------------
srcpkgs/opencv/template | 8 ++--
2 files changed, 56 insertions(+), 56 deletions(-)
diff --git a/common/shlibs b/common/shlibs
index 371e4ff11aa1..8cb5ff0f7457 100644
--- a/common/shlibs
+++ b/common/shlibs
@@ -2138,58 +2138,58 @@ libcapstone.so.4 capstone-4.0_1
libhavege.so.2 libhaveged-1.9.11_1
libnih.so.1 libnih-1.0.3_1
libnih-dbus.so.1 libnih-1.0.3_1
-libopencv_quality.so.406 libopencv-4.6.0_1
-libopencv_reg.so.406 libopencv-4.6.0_1
-libopencv_surface_matching.so.406 libopencv-4.6.0_1
-libopencv_xphoto.so.406 libopencv-4.6.0_1
-libopencv_freetype.so.406 libopencv-4.6.0_1
-libopencv_fuzzy.so.406 libopencv-4.6.0_1
-libopencv_hfs.so.406 libopencv-4.6.0_1
-libopencv_img_hash.so.406 libopencv-4.6.0_1
-libopencv_line_descriptor.so.406 libopencv-4.6.0_1
-libopencv_saliency.so.406 libopencv-4.6.0_1
-libopencv_structured_light.so.406 libopencv-4.6.0_1
-libopencv_aruco.so.406 libopencv-4.6.0_1
-libopencv_bgsegm.so.406 libopencv-4.6.0_1
-libopencv_bioinspired.so.406 libopencv-4.6.0_1
-libopencv_ccalib.so.406 libopencv-4.6.0_1
-libopencv_face.so.406 libopencv-4.6.0_1
-libopencv_tracking.so.406 libopencv-4.6.0_1
-libopencv_xfeatures2d.so.406 libopencv-4.6.0_1
-libopencv_optflow.so.406 libopencv-4.6.0_1
-libopencv_ximgproc.so.406 libopencv-4.6.0_1
-libopencv_plot.so.406 libopencv-4.6.0_1
-libopencv_text.so.406 libopencv-4.6.0_1
-libopencv_ml.so.406 libopencv-4.6.0_1
-libopencv_objdetect.so.406 libopencv-4.6.0_1
-libopencv_dnn.so.406 libopencv-4.6.0_1
-libopencv_shape.so.406 libopencv-4.6.0_1
-libopencv_stitching.so.406 libopencv-4.6.0_1
-libopencv_photo.so.406 libopencv-4.6.0_1
-libopencv_video.so.406 libopencv-4.6.0_1
-libopencv_calib3d.so.406 libopencv-4.6.0_1
-libopencv_features2d.so.406 libopencv-4.6.0_1
-libopencv_flann.so.406 libopencv-4.6.0_1
-libopencv_highgui.so.406 libopencv-4.6.0_1
-libopencv_videoio.so.406 libopencv-4.6.0_1
-libopencv_imgcodecs.so.406 libopencv-4.6.0_1
-libopencv_imgproc.so.406 libopencv-4.6.0_1
-libopencv_core.so.406 libopencv-4.6.0_1
-libopencv_superres.so.406 libopencv-4.6.0_1
-libopencv_videostab.so.406 libopencv-4.6.0_1
-libopencv_gapi.so.406 libopencv-4.6.0_1
-libopencv_xobjdetect.so.406 libopencv-4.6.0_1
-libopencv_datasets.so.406 libopencv-4.6.0_1
-libopencv_dnn_objdetect.so.406 libopencv-4.6.0_1
-libopencv_dnn_superres.so.406 libopencv-4.6.0_1
-libopencv_dpm.so.406 libopencv-4.6.0_1
-libopencv_phase_unwrapping.so.406 libopencv-4.6.0_1
-libopencv_stereo.so.406 libopencv-4.6.0_1
-libopencv_rapid.so.406 libopencv-4.6.0_1
-libopencv_intensity_transform.so.406 libopencv-4.6.0_1
-libopencv_alphamat.so.406 libopencv-4.6.0_1
-libopencv_barcode.so.406 libopencv-4.6.0_1
-libopencv_mcc.so.406 libopencv-4.6.0_1
+libopencv_quality.so.407 libopencv-4.7.0_1
+libopencv_reg.so.407 libopencv-4.7.0_1
+libopencv_surface_matching.so.407 libopencv-4.7.0_1
+libopencv_xphoto.so.407 libopencv-4.7.0_1
+libopencv_freetype.so.407 libopencv-4.7.0_1
+libopencv_fuzzy.so.407 libopencv-4.7.0_1
+libopencv_hfs.so.407 libopencv-4.7.0_1
+libopencv_img_hash.so.407 libopencv-4.7.0_1
+libopencv_line_descriptor.so.407 libopencv-4.7.0_1
+libopencv_saliency.so.407 libopencv-4.7.0_1
+libopencv_structured_light.so.407 libopencv-4.7.0_1
+libopencv_aruco.so.407 libopencv-4.7.0_1
+libopencv_bgsegm.so.407 libopencv-4.7.0_1
+libopencv_bioinspired.so.407 libopencv-4.7.0_1
+libopencv_ccalib.so.407 libopencv-4.7.0_1
+libopencv_face.so.407 libopencv-4.7.0_1
+libopencv_tracking.so.407 libopencv-4.7.0_1
+libopencv_xfeatures2d.so.407 libopencv-4.7.0_1
+libopencv_optflow.so.407 libopencv-4.7.0_1
+libopencv_ximgproc.so.407 libopencv-4.7.0_1
+libopencv_plot.so.407 libopencv-4.7.0_1
+libopencv_text.so.407 libopencv-4.7.0_1
+libopencv_ml.so.407 libopencv-4.7.0_1
+libopencv_objdetect.so.407 libopencv-4.7.0_1
+libopencv_dnn.so.407 libopencv-4.7.0_1
+libopencv_shape.so.407 libopencv-4.7.0_1
+libopencv_stitching.so.407 libopencv-4.7.0_1
+libopencv_photo.so.407 libopencv-4.7.0_1
+libopencv_video.so.407 libopencv-4.7.0_1
+libopencv_calib3d.so.407 libopencv-4.7.0_1
+libopencv_features2d.so.407 libopencv-4.7.0_1
+libopencv_flann.so.407 libopencv-4.7.0_1
+libopencv_highgui.so.407 libopencv-4.7.0_1
+libopencv_videoio.so.407 libopencv-4.7.0_1
+libopencv_imgcodecs.so.407 libopencv-4.7.0_1
+libopencv_imgproc.so.407 libopencv-4.7.0_1
+libopencv_core.so.407 libopencv-4.7.0_1
+libopencv_superres.so.407 libopencv-4.7.0_1
+libopencv_videostab.so.407 libopencv-4.7.0_1
+libopencv_gapi.so.407 libopencv-4.7.0_1
+libopencv_xobjdetect.so.407 libopencv-4.7.0_1
+libopencv_datasets.so.407 libopencv-4.7.0_1
+libopencv_dnn_objdetect.so.407 libopencv-4.7.0_1
+libopencv_dnn_superres.so.407 libopencv-4.7.0_1
+libopencv_dpm.so.407 libopencv-4.7.0_1
+libopencv_phase_unwrapping.so.407 libopencv-4.7.0_1
+libopencv_stereo.so.407 libopencv-4.7.0_1
+libopencv_rapid.so.407 libopencv-4.7.0_1
+libopencv_intensity_transform.so.407 libopencv-4.7.0_1
+libopencv_alphamat.so.407 libopencv-4.7.0_1
+libopencv_barcode.so.407 libopencv-4.7.0_1
+libopencv_mcc.so.407 libopencv-4.7.0_1
libuniconf.so.4.6 wvstreams-4.6.1_20
libwvbase.so.4.6 wvstreams-4.6.1_20
libwvutils.so.4.6 wvstreams-4.6.1_20
diff --git a/srcpkgs/opencv/template b/srcpkgs/opencv/template
index 69c635b1ad2b..41f3183f1582 100644
--- a/srcpkgs/opencv/template
+++ b/srcpkgs/opencv/template
@@ -1,7 +1,7 @@
# Template file for 'opencv'
pkgname=opencv
-version=4.6.0
-revision=4
+version=4.7.0
+revision=1
create_wrksrc=yes
build_wrksrc=${pkgname}-${version}
build_style=cmake
@@ -24,8 +24,8 @@ homepage="https://opencv.org"
changelog="https://github.com/opencv/opencv/wiki/ChangeLog"
distfiles="https://github.com/opencv/opencv/archive/${version}.tar.gz
https://github.com/opencv/opencv_contrib/archive/${version}.tar.gz>contrib.tar.gz"
-checksum="1ec1cba65f9f20fe5a41fda1586e01c70ea0c9a6d7b67c9e13edf0cfe2239277
- 1777d5fd2b59029cf537e5fd6f8aa68d707075822f90bde683fcde086f85f7a7"
+checksum="8df0079cdbe179748a18d44731af62a245a45ebf5085223dc03133954c662973
+ 42df840cf9055e59d0e22c249cfb19f04743e1bdad113d31b1573d3934d62584"
patch_args="-Np1 -d ${build_wrksrc}"
# tests hang indenfinitely, even with test data included
make_check=no
From 2d9046a902bb05c5ed2dfe78a51aa7f862a98c1b Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 19:59:45 -0400
Subject: [PATCH 004/113] actiona: revbump for opencv-4.7.0
---
srcpkgs/actiona/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/actiona/template b/srcpkgs/actiona/template
index cf5f0b7a2ae6..0d899311e6df 100644
--- a/srcpkgs/actiona/template
+++ b/srcpkgs/actiona/template
@@ -1,7 +1,7 @@
# Template file for 'actiona'
pkgname=actiona
version=3.10.1
-revision=2
+revision=3
build_style=qmake
configure_args="PKGCONFIG_OPENCV=opencv4"
hostmakedepends="pkg-config qt5-plugin-mysql qt5-qmake qt5-host-tools"
From 1aa3fb40730d812682a6de2c61101187ebdeccfa Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 19:59:45 -0400
Subject: [PATCH 005/113] gmic: revbump for opencv-4.7.0
---
srcpkgs/gmic/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/gmic/template b/srcpkgs/gmic/template
index 24a9c7218fdf..0bb4034d5cc8 100644
--- a/srcpkgs/gmic/template
+++ b/srcpkgs/gmic/template
@@ -1,7 +1,7 @@
# Template file for 'gmic'
pkgname=gmic
version=3.1.6
-revision=3
+revision=4
_zart_hash=34ebf6cce0bafb98abe57cec83c4a02cd1abeca0
create_wrksrc=yes
build_wrksrc="src"
From 2e483a731a92414cec2431ef03a2864c46148887 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 19:59:46 -0400
Subject: [PATCH 006/113] qimgv: revbump for opencv-4.7.0
---
srcpkgs/qimgv/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/qimgv/template b/srcpkgs/qimgv/template
index 7eb30db33992..dd341dfe1bfc 100644
--- a/srcpkgs/qimgv/template
+++ b/srcpkgs/qimgv/template
@@ -1,7 +1,7 @@
# Template file for 'qimgv'
pkgname=qimgv
version=1.0.2
-revision=2
+revision=3
build_style=cmake
configure_args="$(vopt_if video -DVIDEO_SUPPORT=ON -DVIDEO_SUPPORT=OFF)
$(vopt_if scale -DOPENCV_SUPPORT=ON -DOPENCV_SUPPORT=OFF)
From 19cae0de21654f98d7ecfd56c1468f2852c9a663 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 19:59:46 -0400
Subject: [PATCH 007/113] retroshare: revbump for opencv-4.7.0
---
srcpkgs/retroshare/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/retroshare/template b/srcpkgs/retroshare/template
index 8a0786c21a08..72023fa98b75 100644
--- a/srcpkgs/retroshare/template
+++ b/srcpkgs/retroshare/template
@@ -1,7 +1,7 @@
# Template file for 'retroshare'
pkgname=retroshare
version=0.6.6
-revision=2
+revision=4
build_style=qmake
#XXX broadcast feature requires an ancient udp-discovery-cpp which either needs
# to be fetched+patched (FTBFS) here or packaged :/
From a9b8cc4bb37271625cd7a2906349ffadb050ca2e Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 19:59:46 -0400
Subject: [PATCH 008/113] siril: revbump for opencv-4.7.0
---
srcpkgs/siril/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/siril/template b/srcpkgs/siril/template
index e88f30fb6178..84332f79d060 100644
--- a/srcpkgs/siril/template
+++ b/srcpkgs/siril/template
@@ -1,7 +1,7 @@
# Template file for 'siril'
pkgname=siril
version=0.9.12
-revision=9
+revision=10
build_style=gnu-configure
hostmakedepends="pkg-config intltool autoconf automake gettext-devel"
makedepends="fftw-devel libconfig-devel libopencv-devel libffms2-devel
From 3214c1e239c798129a4d04a51476af9d364ce5c1 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 19:59:46 -0400
Subject: [PATCH 009/113] waifu2x-converter-cpp: revbump for opencv-4.7.0
---
srcpkgs/waifu2x-converter-cpp/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/waifu2x-converter-cpp/template b/srcpkgs/waifu2x-converter-cpp/template
index 8c095d0d7bab..aa52d8c981a8 100644
--- a/srcpkgs/waifu2x-converter-cpp/template
+++ b/srcpkgs/waifu2x-converter-cpp/template
@@ -1,7 +1,7 @@
# Template file for 'waifu2x-converter-cpp'
pkgname=waifu2x-converter-cpp
version=5.2.4
-revision=2
+revision=3
build_style=cmake
configure_args="-DINSTALL_MODELS=ON"
hostmakedepends="pkg-config"
From e0d12d4b5cd3ead65c6cf96a47370a9b2086978e Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:00:38 -0400
Subject: [PATCH 010/113] vlc: revbump for ffmpeg4-4.4.3
---
srcpkgs/vlc/template | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/srcpkgs/vlc/template b/srcpkgs/vlc/template
index 210762b0a7e2..855ca5238662 100644
--- a/srcpkgs/vlc/template
+++ b/srcpkgs/vlc/template
@@ -1,7 +1,7 @@
# Template file for 'vlc'
pkgname=vlc
version=3.0.18
-revision=3
+revision=4
build_style=gnu-configure
configure_args="--disable-gme --disable-libtar --enable-jack
--enable-live555 --disable-fluidsynth --enable-dvdread
@@ -25,7 +25,7 @@ lib32disabled=yes
hostmakedepends="automake libtool pkg-config flex gettext libgcrypt-devel
live555-devel gettext-devel $(vopt_if lua lua52) $(vopt_if chromecast protobuf)"
makedepends="
- avahi-libs-devel dbus-glib-devel faad2-devel ffmpeg-devel freefont-ttf
+ avahi-libs-devel dbus-glib-devel faad2-devel ffmpeg4-devel freefont-ttf
gnutls-devel jack-devel liba52-devel libass-devel libbluray-devel
libcdio-devel libdca-devel libdvbpsi-devel libdvdnav-devel libmad-devel
libmatroska-devel libmodplug-devel libmpcdec-devel libmpeg2-devel
From fa941e18d6b52166da41d8ae7e63f8a2cd0c0f2e Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:00:55 -0400
Subject: [PATCH 011/113] osg: revbump for ffmpeg4-4.4.3
---
srcpkgs/osg/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/osg/template b/srcpkgs/osg/template
index a9ebbd287933..755793f7e11b 100644
--- a/srcpkgs/osg/template
+++ b/srcpkgs/osg/template
@@ -8,7 +8,7 @@ build_helper="qemu"
configure_args="-DLIB_POSTFIX="
hostmakedepends="pkg-config xrandr"
makedepends="MesaLib-devel gtkglext-devel libcurl-devel giflib-devel librsvg-devel
- jasper-devel tiff-devel libgdal-devel libgta-devel ffmpeg-devel xine-lib-devel
+ jasper-devel tiff-devel libgdal-devel libgta-devel ffmpeg4-devel xine-lib-devel
SDL2-devel gst-plugins-base1-devel
$(vopt_if openexr libopenexr-devel)
$(vopt_if poppler poppler-glib-devel)
From a174da9af8aa41c8577b840c470136721afcbe53 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:13 -0400
Subject: [PATCH 012/113] xine-lib: revbump for ffmpeg4-4.4.3
---
srcpkgs/xine-lib/template | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/srcpkgs/xine-lib/template b/srcpkgs/xine-lib/template
index f713eff49b07..ed6194c17d11 100644
--- a/srcpkgs/xine-lib/template
+++ b/srcpkgs/xine-lib/template
@@ -1,6 +1,6 @@
# Template file for 'xine-lib'
pkgname=xine-lib
-version=1.2.12
+version=1.2.13
revision=1
build_style=gnu-configure
configure_args="--disable-vcd --disable-gnomevfs --without-esound --disable-dxr3
@@ -8,7 +8,7 @@ configure_args="--disable-vcd --disable-gnomevfs --without-esound --disable-dxr3
hostmakedepends="automake gettext-devel libtool pkg-config perl"
makedepends="
zlib-devel alsa-lib-devel libxcb-devel libSM-devel libXext-devel libXv-devel
- libXvMC-devel liba52-devel libmad-devel ffmpeg-devel pulseaudio-devel
+ libXvMC-devel liba52-devel libmad-devel ffmpeg4-devel pulseaudio-devel
jack-devel samba-devel libflac-devel libmodplug-devel libmpcdec-devel
speex-devel libtheora-devel libvorbis-devel libdca-devel faad2-devel
libcdio-devel libbluray-devel aalib-devel libcaca-devel libXinerama-devel
@@ -19,7 +19,7 @@ license="GPL-2.0-or-later, LGPL-2.0-or-later"
homepage="http://www.xine-project.org"
changelog="https://sourceforge.net/projects/xine/files/xine-lib/${version}/README.txt/view"
distfiles="${SOURCEFORGE_SITE}/xine/${pkgname}-${version}.tar.xz"
-checksum=d606270468e1540c2a89c0d7f5fdf11e17ecc0c2698cc0bcb1065ff26abee098
+checksum=5f10d6d718a4a51c17ed1b32b031d4f9b80b061e8276535b2be31e5ac4b75e6f
case "$XBPS_TARGET_MACHINE" in
i686-musl)
From e0d2dc7db5bd285c88376d01cd3e66f96cdacb5f Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:45 -0400
Subject: [PATCH 013/113] QMPlay2: revbump for ffmpeg-6.0
---
srcpkgs/QMPlay2/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/QMPlay2/template b/srcpkgs/QMPlay2/template
index ad73cbb01bae..55284c051161 100644
--- a/srcpkgs/QMPlay2/template
+++ b/srcpkgs/QMPlay2/template
@@ -1,7 +1,7 @@
# Template file for 'QMPlay2'
pkgname=QMPlay2
version=23.02.05
-revision=1
+revision=2
build_style=cmake
hostmakedepends="pkg-config qt5-qmake qt5-host-tools"
makedepends="alsa-lib-devel ffmpeg-devel libass-devel libcdio-devel libgme-devel
From 23d1443cbfdb5a75da2e3c9e78a1b50601d2634c Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:45 -0400
Subject: [PATCH 014/113] alsa-plugins: revbump for ffmpeg-6.0
---
srcpkgs/alsa-plugins/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/alsa-plugins/template b/srcpkgs/alsa-plugins/template
index 0bfa6d9fd264..a5708a7d82a8 100644
--- a/srcpkgs/alsa-plugins/template
+++ b/srcpkgs/alsa-plugins/template
@@ -1,7 +1,7 @@
# Template file for 'alsa-plugins'
pkgname=alsa-plugins
version=1.2.7.1
-revision=1
+revision=2
build_style=gnu-configure
configure_args="--disable-maemo-plugin"
hostmakedepends="pkg-config"
From c925ef5494ac63f5627378d3e040a81cf847cb44 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:45 -0400
Subject: [PATCH 015/113] arcan: revbump for ffmpeg-6.0
---
srcpkgs/arcan/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/arcan/template b/srcpkgs/arcan/template
index 7be9652eccf3..ccc7df11ceac 100644
--- a/srcpkgs/arcan/template
+++ b/srcpkgs/arcan/template
@@ -2,7 +2,7 @@
# !! keep synced with: acfgfs aclip aloadimage
pkgname=arcan
version=0.6.2.1
-revision=1
+revision=2
create_wrksrc=yes
build_wrksrc=arcan/src
build_style=cmake
From 3ef0e5fc9b03920896ce40120d29ce01b0e2976a Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:45 -0400
Subject: [PATCH 016/113] attract: revbump for ffmpeg4-4.4.3
---
srcpkgs/attract/template | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/srcpkgs/attract/template b/srcpkgs/attract/template
index 26144e931a3c..e760bf0d18ae 100644
--- a/srcpkgs/attract/template
+++ b/srcpkgs/attract/template
@@ -1,12 +1,12 @@
# Template file for 'attract'
pkgname=attract
version=2.6.2
-revision=1
+revision=2
build_style=gnu-makefile
make_build_args="VERBOSE=1"
make_use_env=yes
hostmakedepends="pkg-config"
-makedepends="SFML-devel ffmpeg-devel fontconfig-devel glu-devel libarchive-devel
+makedepends="SFML-devel ffmpeg4-devel fontconfig-devel glu-devel libarchive-devel
libcurl-devel libjpeg-turbo-devel xine-lib rapidjson libXrandr-devel"
depends="git"
short_desc="Attract-Mode is a graphical frontend for emulators"
From 81d6a7a7579319d61b2c81d352cb9c2de071b9ad Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:45 -0400
Subject: [PATCH 017/113] aubio: revbump for ffmpeg-6.0
---
srcpkgs/aubio/patches/ffmpeg5.patch | 25 +++++++++++++++++++++++++
srcpkgs/aubio/template | 2 +-
2 files changed, 26 insertions(+), 1 deletion(-)
create mode 100644 srcpkgs/aubio/patches/ffmpeg5.patch
diff --git a/srcpkgs/aubio/patches/ffmpeg5.patch b/srcpkgs/aubio/patches/ffmpeg5.patch
new file mode 100644
index 000000000000..aace41a6e6d9
--- /dev/null
+++ b/srcpkgs/aubio/patches/ffmpeg5.patch
@@ -0,0 +1,25 @@
+From 8a05420e5dd8c7b8b2447f82dc919765876511b3 Mon Sep 17 00:00:00 2001
+From: Paul Brossier <piem@piem.org>
+Date: Tue, 25 Jan 2022 18:30:27 +0100
+Subject: [PATCH] [source_avcodec] define FF_API_LAVF_AVCTX for libavcodec >
+ 59, thx @berolinux (closes gh-353)
+
+---
+ src/io/source_avcodec.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/src/io/source_avcodec.c b/src/io/source_avcodec.c
+index e0ae93b5..1421bd9a 100644
+--- a/src/io/source_avcodec.c
++++ b/src/io/source_avcodec.c
+@@ -68,6 +68,10 @@
+ #define AUBIO_AVCODEC_MAX_BUFFER_SIZE AV_INPUT_BUFFER_MIN_SIZE
+ #endif
+
++#if LIBAVCODEC_VERSION_MAJOR >= 59
++#define FF_API_LAVF_AVCTX 1
++#endif
++
+ struct _aubio_source_avcodec_t {
+ uint_t hop_size;
+ uint_t samplerate;
diff --git a/srcpkgs/aubio/template b/srcpkgs/aubio/template
index ad1c4b256991..7d875cc02541 100644
--- a/srcpkgs/aubio/template
+++ b/srcpkgs/aubio/template
@@ -1,7 +1,7 @@
# Template file for 'aubio'
pkgname=aubio
version=0.4.9
-revision=1
+revision=2
build_style=waf3
# XXX lash, pure and swig support.
hostmakedepends="pkg-config txt2man"
From 690a45dccdcfd3be935c60cec2b74017cde993a2 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:45 -0400
Subject: [PATCH 018/113] audacious-plugins: revbump for ffmpeg-6.0
---
.../audacious-plugins/patches/ffmpeg5.patch | 43 +++++++++++++++++++
srcpkgs/audacious-plugins/template | 2 +-
2 files changed, 44 insertions(+), 1 deletion(-)
create mode 100644 srcpkgs/audacious-plugins/patches/ffmpeg5.patch
diff --git a/srcpkgs/audacious-plugins/patches/ffmpeg5.patch b/srcpkgs/audacious-plugins/patches/ffmpeg5.patch
new file mode 100644
index 000000000000..4e5e34099d71
--- /dev/null
+++ b/srcpkgs/audacious-plugins/patches/ffmpeg5.patch
@@ -0,0 +1,43 @@
+commit 298aa371c56c2f52c25a33d9bdec4918b11cebdc
+Author: tibequadorian <tibequadorian@posteo.de>
+Date: Sat Mar 19 18:40:12 2022 +0100
+
+ audacious-plugins: rebuild against ffmpeg-5.0
+
+diff --git a/srcpkgs/audacious-plugins/patches/ffmpeg-5.0.patch b/srcpkgs/audacious-plugins/patches/ffmpeg-5.0.patch
+new file mode 100644
+index 0000000000..617c11215b
+--- /dev/null
++++ b/srcpkgs/audacious-plugins/patches/ffmpeg-5.0.patch
+@@ -0,0 +1,31 @@
++From f60beb400eeb1e4778bbfd738bc4a4ccef3de539 Mon Sep 17 00:00:00 2001
++From: John Lindgren <john@jlindgren.net>
++Date: Sat, 5 Mar 2022 12:05:34 -0500
++Subject: [PATCH] Fix build with FFmpeg 5.0
++
++---
++ src/ffaudio/ffaudio-core.cc | 4 ++--
++ 1 file changed, 2 insertions(+), 2 deletions(-)
++
++diff --git a/src/ffaudio/ffaudio-core.cc b/src/ffaudio/ffaudio-core.cc
++index 16dc63e3a..a2b95fd6c 100644
++--- a/src/ffaudio/ffaudio-core.cc
+++++ b/src/ffaudio/ffaudio-core.cc
++@@ -274,7 +274,7 @@ static AVInputFormat * get_format_by_content (const char * name, VFSFile & file)
++ AVProbeData d = {name, buf, filled};
++ score = target;
++
++- f = av_probe_input_format2 (& d, true, & score);
+++ f = (AVInputFormat *) av_probe_input_format2 (& d, true, & score);
++ if (f)
++ break;
++
++@@ -347,7 +347,7 @@ static bool find_codec (AVFormatContext * c, CodecInfo * cinfo)
++ #endif
++ if (stream && stream->codecpar && stream->codecpar->codec_type == AVMEDIA_TYPE_AUDIO)
++ {
++- AVCodec * codec = avcodec_find_decoder (stream->codecpar->codec_id);
+++ AVCodec * codec = (AVCodec *) avcodec_find_decoder (stream->codecpar->codec_id);
++
++ if (codec)
++ {
diff --git a/srcpkgs/audacious-plugins/template b/srcpkgs/audacious-plugins/template
index 88cbc1671fc6..beebfae59ed4 100644
--- a/srcpkgs/audacious-plugins/template
+++ b/srcpkgs/audacious-plugins/template
@@ -2,7 +2,7 @@
#Keep in sync with audacious!
pkgname=audacious-plugins
version=4.3.1
-revision=1
+revision=2
build_style=meson
configure_args="$(vopt_bool gtk3 gtk) $(vopt_bool gtk3)
$(vopt_bool qt) $(vopt_bool qt qt6)"
From b988a316310239c7c52e48cc6bf0ac4779db6a5d Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:45 -0400
Subject: [PATCH 019/113] audacity: revbump for ffmpeg4-4.4.3
---
srcpkgs/audacity/template | 5 ++---
1 file changed, 2 insertions(+), 3 deletions(-)
diff --git a/srcpkgs/audacity/template b/srcpkgs/audacity/template
index d509c0a89407..11e20255685b 100644
--- a/srcpkgs/audacity/template
+++ b/srcpkgs/audacity/template
@@ -1,7 +1,7 @@
# Template file for 'audacity'
pkgname=audacity
version=2.4.1
-revision=2
+revision=3
build_style=gnu-configure
configure_args="--with-ffmpeg=system --with-libsndfile=system --with-expat=system
--with-libsoxr=system --with-lame=system --with-lv2=system ac_cv_path_WX_CONFIG=wx-config-gtk3"
@@ -9,7 +9,7 @@ hostmakedepends="pkg-config cmake gettext libtool m4 which"
makedepends="jack-devel wxWidgets-gtk3-devel gtk+3-devel
libmad-devel soundtouch-devel libsoxr-devel
vamp-plugin-sdk-devel lame-devel libid3tag-devel libflac-devel
- ffmpeg-devel twolame-devel serd-devel lv2 lilv-devel suil-devel"
+ ffmpeg4-devel twolame-devel serd-devel lv2 lilv-devel suil-devel"
depends="desktop-file-utils hicolor-icon-theme"
short_desc="Graphical cross-platform audio editor"
maintainer="Orphaned <orphan@voidlinux.org>"
@@ -33,5 +33,4 @@ post_install() {
vcopy plug-ins /usr/share/audacity
rm ${DESTDIR}/usr/share/doc/audacity/LICENSE.txt
- vlicense LICENSE.txt LICENSE
}
From 85b8be67a2c1d4ce6598721614fa59fc7a9577dc Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:45 -0400
Subject: [PATCH 020/113] avidemux: revbump for ffmpeg-6.0
---
srcpkgs/avidemux/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/avidemux/template b/srcpkgs/avidemux/template
index 253a0243e225..557285982d2b 100644
--- a/srcpkgs/avidemux/template
+++ b/srcpkgs/avidemux/template
@@ -1,7 +1,7 @@
# Template file for 'avidemux'
pkgname=avidemux
version=2.8.0
-revision=2
+revision=3
# Can't be compiled for aarch64, arm* or mips*
archs="x86_64* i686*"
hostmakedepends="cmake pkg-config qt5-host-tools qt5-devel tar yasm"
From f7c3fa5758a7c359009c9526ab8129c3b55f31a4 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:45 -0400
Subject: [PATCH 021/113] baresip: revbump for ffmpeg-6.0
---
srcpkgs/baresip/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/baresip/template b/srcpkgs/baresip/template
index f1bd1817048b..b21e22334316 100644
--- a/srcpkgs/baresip/template
+++ b/srcpkgs/baresip/template
@@ -1,7 +1,7 @@
# Template file for 'baresip'
pkgname=baresip
version=2.10.0
-revision=1
+revision=2
build_style=cmake
hostmakedepends="pkg-config glib-devel"
makedepends="libgsm-devel libpng-devel openssl-devel libsndfile-devel
From 6839e620329230527734dd59a91639d373220982 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:46 -0400
Subject: [PATCH 022/113] blender: revbump for ffmpeg-6.0
---
srcpkgs/blender/template | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/srcpkgs/blender/template b/srcpkgs/blender/template
index ec724bb0a6dc..0f72876d4d70 100644
--- a/srcpkgs/blender/template
+++ b/srcpkgs/blender/template
@@ -1,7 +1,7 @@
# Template file for 'blender'
pkgname=blender
version=3.5.1
-revision=1
+revision=2
archs="x86_64* ppc64*"
build_style="cmake"
pycompile_dirs="/usr/share/blender/${version%.*}/scripts"
@@ -9,8 +9,8 @@ configure_args="-DWITH_INSTALL_PORTABLE=OFF -DWITH_PYTHON_INSTALL=OFF
-DWITH_JACK=ON -DWITH_CODEC_FFMPEG=ON -DWITH_CODEC_SNDFILE=ON -DWITH_OPENMP=ON
-DWITH_FFTW3=ON -DWITH_MOD_OCEANSIM=ON -DWITH_CYCLES_EMBREE=OFF -DWITH_OPENCOLORIO=ON
-DWITH_IMAGE_OPENEXR=ON -DWITH_IMAGE_OPENJPEG=ON -DWITH_OPENSUBDIV=ON
- -DWITH_OPENCOLLADA=ON -DWITH_SYSTEM_GLEW=ON -DWITH_OPENVDB=ON -DWITH_ALEMBIC=ON
- -DWITH_GHOST_X11=ON -DWITH_GHOST_WAYLAND=ON -DWITH_GHOST_LIBDECOR=ON
+ -DWITH_OPENCOLLADA=ON -DWITH_OPENVDB=ON -DWITH_ALEMBIC=ON
+ -DWITH_GHOST_X11=ON -DWITH_GHOST_WAYLAND=ON -DWITH_GHOST_WAYLAND_LIBDECOR=ON
-DWITH_BUILDINFO=OFF -DPYTHON_VERSION=${py3_ver} -DPYTHON_LIBPATH=/usr/lib
-DPYTHON_LIBRARY=python${py3_ver}${py3_abiver} -DPYTHON_INCLUDE_DIRS=/${py3_inc}
-DWITH_SYSTEM_LZO=ON -DWITH_SYSTEM_EIGEN3=ON -DWITH_SYSTEM_FREETYPE=ON"
From c2f3df750cadc5b0cde59b979dd8bc1d4120db7e Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:46 -0400
Subject: [PATCH 023/113] cantata: revbump for ffmpeg-6.0
---
srcpkgs/cantata/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/cantata/template b/srcpkgs/cantata/template
index 4b417d80d5c2..8a90aaa4c07a 100644
--- a/srcpkgs/cantata/template
+++ b/srcpkgs/cantata/template
@@ -1,7 +1,7 @@
# Template file for 'cantata'
pkgname=cantata
version=2.5.0
-revision=1
+revision=2
build_style=cmake
hostmakedepends="pkg-config qt5-qmake qt5-host-tools qt5-tools"
makedepends="qt5-devel qt5-tools-devel qt5-svg-devel qt5-xmlpatterns-devel
From cd8ee1eb823ebaec8872457ff73d47ba673c1832 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:46 -0400
Subject: [PATCH 024/113] ccextractor: revbump for ffmpeg4-4.4.3
---
srcpkgs/ccextractor/template | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/srcpkgs/ccextractor/template b/srcpkgs/ccextractor/template
index 9abcd82852b2..6eccad5885af 100644
--- a/srcpkgs/ccextractor/template
+++ b/srcpkgs/ccextractor/template
@@ -1,12 +1,12 @@
# Template file for 'ccextractor'
pkgname=ccextractor
version=0.93
-revision=1
+revision=2
build_wrksrc="linux"
build_style=gnu-configure
configure_args="--enable-ocr --enable-hardsubx"
hostmakedepends="automake pkg-config"
-makedepends="leptonica-devel tesseract-ocr-devel ffmpeg-devel"
+makedepends="leptonica-devel tesseract-ocr-devel ffmpeg4-devel"
short_desc="Extract subtitles from video streams"
maintainer="newbluemoon <blaumolch@mailbox.org>"
license="GPL-2.0-or-later"
From 4a432c7e27e4ceaec4aa4c3a2e4b811a4767e879 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:46 -0400
Subject: [PATCH 025/113] chromaprint: revbump for ffmpeg-6.0
---
srcpkgs/chromaprint/patches/ffmpeg5.patch | 569 ++++++++++++++++++++++
srcpkgs/chromaprint/template | 2 +-
2 files changed, 570 insertions(+), 1 deletion(-)
create mode 100644 srcpkgs/chromaprint/patches/ffmpeg5.patch
diff --git a/srcpkgs/chromaprint/patches/ffmpeg5.patch b/srcpkgs/chromaprint/patches/ffmpeg5.patch
new file mode 100644
index 000000000000..a9fd307a23c8
--- /dev/null
+++ b/srcpkgs/chromaprint/patches/ffmpeg5.patch
@@ -0,0 +1,569 @@
+From 8ccad6937177b1b92e40ab8f4447ea27bac009a7 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Luk=C3=A1=C5=A1=20Lalinsk=C3=BD?= <lalinsky@gmail.com>
+Date: Fri, 4 Nov 2022 21:47:38 +0100
+Subject: [PATCH] Use FFmpeg 5.x (#120)
+
+* Use FFmpeg 5.1.2 for CI builds
+
+* Build on Ubuntu 20.04
+
+* Upgrade code to FFmpeg 5.x APIs
+
+* Only set FFmpeg include dirs if building tools
+
+* No longer needed
+
+* Use ubuntu 20.04
+---
+ .github/workflows/build.yml | 6 +-
+ CMakeLists.txt | 16 --
+ package/build.sh | 4 +-
+ src/audio/ffmpeg_audio_processor.h | 2 -
+ src/audio/ffmpeg_audio_processor_avresample.h | 72 -------
+ src/audio/ffmpeg_audio_processor_swresample.h | 18 +-
+ src/audio/ffmpeg_audio_reader.h | 197 +++++++++---------
+ tests/CMakeLists.txt | 6 +
+ 8 files changed, 122 insertions(+), 199 deletions(-)
+ delete mode 100644 src/audio/ffmpeg_audio_processor_avresample.h
+
+diff --git a/CMakeLists.txt b/CMakeLists.txt
+index f8d6a32..4da2405 100644
+--- a/CMakeLists.txt
++++ b/CMakeLists.txt
+@@ -84,9 +84,6 @@ find_package(FFmpeg)
+ if(FFMPEG_LIBRARIES)
+ cmake_push_check_state(RESET)
+ set(CMAKE_REQUIRED_LIBRARIES ${FFMPEG_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT} -lm)
+- check_function_exists(av_packet_unref HAVE_AV_PACKET_UNREF)
+- check_function_exists(av_frame_alloc HAVE_AV_FRAME_ALLOC)
+- check_function_exists(av_frame_free HAVE_AV_FRAME_FREE)
+ cmake_pop_check_state()
+ endif()
+
+@@ -163,14 +160,11 @@ message(STATUS "Using ${FFT_LIB} for FFT calculations")
+ if(NOT AUDIO_PROCESSOR_LIB)
+ if(FFMPEG_LIBSWRESAMPLE_FOUND)
+ set(AUDIO_PROCESSOR_LIB "swresample")
+- elseif(FFMPEG_LIBAVRESAMPLE_FOUND)
+- set(AUDIO_PROCESSOR_LIB "avresample")
+ endif()
+ endif()
+
+ if(AUDIO_PROCESSOR_LIB STREQUAL "swresample")
+ if(FFMPEG_LIBSWRESAMPLE_FOUND)
+- set(USE_AVRESAMPLE OFF)
+ set(USE_SWRESAMPLE ON)
+ set(AUDIO_PROCESSOR_LIBRARIES ${FFMPEG_LIBSWRESAMPLE_LIBRARIES})
+ set(AUDIO_PROCESSOR_INCLUDE_DIRS ${FFMPEG_LIBSWRESAMPLE_INCLUDE_DIRS})
+@@ -178,16 +172,6 @@ if(AUDIO_PROCESSOR_LIB STREQUAL "swresample")
+ message(FATAL_ERROR "Selected ${AUDIO_PROCESSOR_LIB} for audio processing, but the library is not found")
+ endif()
+ message(STATUS "Using ${AUDIO_PROCESSOR_LIB} for audio conversion")
+-elseif(AUDIO_PROCESSOR_LIB STREQUAL "avresample")
+- if(FFMPEG_LIBAVRESAMPLE_FOUND)
+- set(USE_AVRESAMPLE ON)
+- set(USE_SWRESAMPLE OFF)
+- set(AUDIO_PROCESSOR_LIBRARIES ${FFMPEG_LIBAVRESAMPLE_LIBRARIES})
+- set(AUDIO_PROCESSOR_INCLUDE_DIRS ${FFMPEG_LIBAVRESAMPLE_INCLUDE_DIRS})
+- else()
+- message(FATAL_ERROR "Selected ${AUDIO_PROCESSOR_LIB} for audio processing, but the library is not found")
+- endif()
+- message(STATUS "Using ${AUDIO_PROCESSOR_LIB} for audio conversion")
+ else()
+ message(STATUS "Building without audio conversion support, please install FFmpeg with libswresample")
+ endif()
+diff --git a/package/build.sh b/package/build.sh
+index da631ae..b41d36e 100755
+--- a/package/build.sh
++++ b/package/build.sh
+@@ -7,8 +7,8 @@ set -eux
+
+ BASE_DIR=$(cd $(dirname $0)/.. && pwd)
+
+-FFMPEG_VERSION=4.4.1
+-FFMPEG_BUILD_TAG=v4.4.1-1
++FFMPEG_VERSION=5.1.2
++FFMPEG_BUILD_TAG=v${FFMPEG_VERSION}-1
+
+ TMP_BUILD_DIR=$BASE_DIR/$(mktemp -d build.XXXXXXXX)
+ trap 'rm -rf $TMP_BUILD_DIR' EXIT
+diff --git a/src/audio/ffmpeg_audio_processor.h b/src/audio/ffmpeg_audio_processor.h
+index 7628fc7..39f4f6d 100644
+--- a/src/audio/ffmpeg_audio_processor.h
++++ b/src/audio/ffmpeg_audio_processor.h
+@@ -10,8 +10,6 @@
+
+ #if defined(USE_SWRESAMPLE)
+ #include "audio/ffmpeg_audio_processor_swresample.h"
+-#elif defined(USE_AVRESAMPLE)
+-#include "audio/ffmpeg_audio_processor_avresample.h"
+ #else
+ #error "no audio processing library"
+ #endif
+diff --git a/src/audio/ffmpeg_audio_processor_avresample.h b/src/audio/ffmpeg_audio_processor_avresample.h
+deleted file mode 100644
+index bd85f92..0000000
+--- a/src/audio/ffmpeg_audio_processor_avresample.h
++++ /dev/null
+@@ -1,72 +0,0 @@
+-// Copyright (C) 2016 Lukas Lalinsky
+-// Distributed under the MIT license, see the LICENSE file for details.
+-
+-#ifndef CHROMAPRINT_AUDIO_FFMPEG_AUDIO_PROCESSOR_AVRESAMPLE_H_
+-#define CHROMAPRINT_AUDIO_FFMPEG_AUDIO_PROCESSOR_AVRESAMPLE_H_
+-
+-extern "C" {
+-#include <libavresample/avresample.h>
+-}
+-
+-namespace chromaprint {
+-
+-class FFmpegAudioProcessor {
+-public:
+- FFmpegAudioProcessor() {
+- m_resample_ctx = avresample_alloc_context();
+- }
+-
+- ~FFmpegAudioProcessor() {
+- avresample_free(&m_resample_ctx);
+- }
+-
+- void SetCompatibleMode() {
+- av_opt_set_int(m_resample_ctx, "filter_size", 16, 0);
+- av_opt_set_int(m_resample_ctx, "phase_shift", 8, 0);
+- av_opt_set_int(m_resample_ctx, "linear_interp", 1, 0);
+- av_opt_set_double(m_resample_ctx, "cutoff", 0.8, 0);
+- }
+-
+- void SetInputChannelLayout(int64_t channel_layout) {
+- av_opt_set_int(m_resample_ctx, "in_channel_layout", channel_layout, 0);
+- }
+-
+- void SetInputSampleFormat(AVSampleFormat sample_format) {
+- av_opt_set_int(m_resample_ctx, "in_sample_fmt", sample_format, 0);
+- }
+-
+- void SetInputSampleRate(int sample_rate) {
+- av_opt_set_int(m_resample_ctx, "in_sample_rate", sample_rate, 0);
+- }
+-
+- void SetOutputChannelLayout(int64_t channel_layout) {
+- av_opt_set_int(m_resample_ctx, "out_channel_layout", channel_layout, 0);
+- }
+-
+- void SetOutputSampleFormat(AVSampleFormat sample_format) {
+- av_opt_set_int(m_resample_ctx, "out_sample_fmt", sample_format, 0);
+- }
+-
+- void SetOutputSampleRate(int sample_rate) {
+- av_opt_set_int(m_resample_ctx, "out_sample_fmt", sample_rate, 0);
+- }
+-
+- int Init() {
+- return avresample_open(m_resample_ctx);
+- }
+-
+- int Convert(uint8_t **out, int out_count, const uint8_t **in, int in_count) {
+- return avresample_convert(m_resample_ctx, out, 0, out_count, (uint8_t **) in, 0, in_count);
+- }
+-
+- int Flush(uint8_t **out, int out_count) {
+- return avresample_read(m_resample_ctx, out, out_count);
+- }
+-
+-private:
+- AVAudioResampleContext *m_resample_ctx = nullptr;
+-};
+-
+-}; // namespace chromaprint
+-
+-#endif
+diff --git a/src/audio/ffmpeg_audio_processor_swresample.h b/src/audio/ffmpeg_audio_processor_swresample.h
+index b86266b..b1d4bea 100644
+--- a/src/audio/ffmpeg_audio_processor_swresample.h
++++ b/src/audio/ffmpeg_audio_processor_swresample.h
+@@ -28,30 +28,28 @@ public:
+ av_opt_set_double(m_swr_ctx, "cutoff", 0.8, 0);
+ }
+
+- void SetInputChannelLayout(int64_t channel_layout) {
+- av_opt_set_int(m_swr_ctx, "icl", channel_layout, 0);
+- av_opt_set_int(m_swr_ctx, "ich", av_get_channel_layout_nb_channels(channel_layout), 0);
++ void SetInputChannelLayout(AVChannelLayout *channel_layout) {
++ av_opt_set_int(m_swr_ctx, "in_channel_layout", channel_layout->u.mask, 0);
+ }
+
+ void SetInputSampleFormat(AVSampleFormat sample_format) {
+- av_opt_set_int(m_swr_ctx, "isf", sample_format, 0);
++ av_opt_set_sample_fmt(m_swr_ctx, "in_sample_fmt", sample_format, 0);
+ }
+
+ void SetInputSampleRate(int sample_rate) {
+- av_opt_set_int(m_swr_ctx, "isr", sample_rate, 0);
++ av_opt_set_int(m_swr_ctx, "in_sample_rate", sample_rate, 0);
+ }
+
+- void SetOutputChannelLayout(int64_t channel_layout) {
+- av_opt_set_int(m_swr_ctx, "ocl", channel_layout, 0);
+- av_opt_set_int(m_swr_ctx, "och", av_get_channel_layout_nb_channels(channel_layout), 0);
++ void SetOutputChannelLayout(AVChannelLayout *channel_layout) {
++ av_opt_set_int(m_swr_ctx, "out_channel_layout", channel_layout->u.mask, 0);
+ }
+
+ void SetOutputSampleFormat(AVSampleFormat sample_format) {
+- av_opt_set_int(m_swr_ctx, "osf", sample_format, 0);
++ av_opt_set_sample_fmt(m_swr_ctx, "out_sample_fmt", sample_format, 0);
+ }
+
+ void SetOutputSampleRate(int sample_rate) {
+- av_opt_set_int(m_swr_ctx, "osr", sample_rate, 0);
++ av_opt_set_int(m_swr_ctx, "out_sample_rate", sample_rate, 0);
+ }
+
+ int Init() {
+diff --git a/src/audio/ffmpeg_audio_reader.h b/src/audio/ffmpeg_audio_reader.h
+index 5550164..1c6b346 100644
+--- a/src/audio/ffmpeg_audio_reader.h
++++ b/src/audio/ffmpeg_audio_reader.h
+@@ -62,7 +62,7 @@ public:
+ bool Read(const int16_t **data, size_t *size);
+
+ bool IsOpen() const { return m_opened; }
+- bool IsFinished() const { return m_finished && !m_got_frame; }
++ bool IsFinished() const { return !m_has_more_packets && !m_has_more_frames; }
+
+ std::string GetError() const { return m_error; }
+ int GetErrorCode() const { return m_error_code; }
+@@ -74,20 +74,19 @@ private:
+ uint8_t *m_convert_buffer[1] = { nullptr };
+ int m_convert_buffer_nb_samples = 0;
+
+- AVInputFormat *m_input_fmt = nullptr;
++ const AVInputFormat *m_input_fmt = nullptr;
+ AVDictionary *m_input_opts = nullptr;
+
+ AVFormatContext *m_format_ctx = nullptr;
+ AVCodecContext *m_codec_ctx = nullptr;
+- AVFrame *m_frame = nullptr;
+ int m_stream_index = -1;
+ std::string m_error;
+ int m_error_code = 0;
+- bool m_finished = false;
+ bool m_opened = false;
+- int m_got_frame = 0;
+- AVPacket m_packet;
+- AVPacket m_packet0;
++ bool m_has_more_packets = true;
++ bool m_has_more_frames = true;
++ AVPacket *m_packet = nullptr;
++ AVFrame *m_frame = nullptr;
+
+ int m_output_sample_rate = 0;
+ int m_output_channels = 0;
+@@ -98,19 +97,12 @@ private:
+
+ inline FFmpegAudioReader::FFmpegAudioReader() {
+ av_log_set_level(AV_LOG_QUIET);
+-
+- av_init_packet(&m_packet);
+- m_packet.data = nullptr;
+- m_packet.size = 0;
+-
+- m_packet0 = m_packet;
+ }
+
+ inline FFmpegAudioReader::~FFmpegAudioReader() {
+ Close();
+ av_dict_free(&m_input_opts);
+ av_freep(&m_convert_buffer[0]);
+- av_packet_unref(&m_packet0);
+ }
+
+ inline bool FFmpegAudioReader::SetInputFormat(const char *name) {
+@@ -135,11 +127,10 @@ inline bool FFmpegAudioReader::Open(const std::string &file_name) {
+
+ Close();
+
+- av_init_packet(&m_packet);
+- m_packet.data = nullptr;
+- m_packet.size = 0;
+-
+- m_packet0 = m_packet;
++ m_packet = av_packet_alloc();
++ if (!m_packet) {
++ return false;
++ }
+
+ ret = avformat_open_input(&m_format_ctx, file_name.c_str(), m_input_fmt, &m_input_opts);
+ if (ret < 0) {
+@@ -153,26 +144,31 @@ inline bool FFmpegAudioReader::Open(const std::string &file_name) {
+ return false;
+ }
+
+- AVCodec *codec;
++ const AVCodec *codec;
+ ret = av_find_best_stream(m_format_ctx, AVMEDIA_TYPE_AUDIO, -1, -1, &codec, 0);
+ if (ret < 0) {
+ SetError("Could not find any audio stream in the file", ret);
+ return false;
+ }
+ m_stream_index = ret;
++ auto stream = m_format_ctx->streams[m_stream_index];
+
+- m_codec_ctx = m_format_ctx->streams[m_stream_index]->codec;
++ m_codec_ctx = avcodec_alloc_context3(codec);
+ m_codec_ctx->request_sample_fmt = AV_SAMPLE_FMT_S16;
+
++ ret = avcodec_parameters_to_context(m_codec_ctx, stream->codecpar);
++ if (ret < 0) {
++ SetError("Could not copy the stream parameters", ret);
++ return false;
++ }
++
+ ret = avcodec_open2(m_codec_ctx, codec, nullptr);
+ if (ret < 0) {
+ SetError("Could not open the codec", ret);
+ return false;
+ }
+
+- if (!m_codec_ctx->channel_layout) {
+- m_codec_ctx->channel_layout = av_get_default_channel_layout(m_codec_ctx->channels);
+- }
++ av_dump_format(m_format_ctx, 0, "foo", 0);
+
+ m_frame = av_frame_alloc();
+ if (!m_frame) {
+@@ -183,19 +179,23 @@ inline bool FFmpegAudioReader::Open(const std::string &file_name) {
+ m_output_sample_rate = m_codec_ctx->sample_rate;
+ }
+
+- if (!m_output_channels) {
+- m_output_channels = m_codec_ctx->channels;
++ AVChannelLayout output_channel_layout;
++ if (m_output_channels) {
++ av_channel_layout_default(&output_channel_layout, m_output_channels);
++ } else {
++ m_output_channels = m_codec_ctx->ch_layout.nb_channels;
++ av_channel_layout_default(&output_channel_layout, m_output_channels);
+ }
+
+- if (m_codec_ctx->sample_fmt != AV_SAMPLE_FMT_S16 || m_codec_ctx->channels != m_output_channels || m_codec_ctx->sample_rate != m_output_sample_rate) {
++ if (m_codec_ctx->sample_fmt != AV_SAMPLE_FMT_S16 || m_codec_ctx->ch_layout.nb_channels != m_output_channels || m_codec_ctx->sample_rate != m_output_sample_rate) {
+ m_converter.reset(new FFmpegAudioProcessor());
+ m_converter->SetCompatibleMode();
+ m_converter->SetInputSampleFormat(m_codec_ctx->sample_fmt);
+ m_converter->SetInputSampleRate(m_codec_ctx->sample_rate);
+- m_converter->SetInputChannelLayout(m_codec_ctx->channel_layout);
++ m_converter->SetInputChannelLayout(&(m_codec_ctx->ch_layout));
+ m_converter->SetOutputSampleFormat(AV_SAMPLE_FMT_S16);
+ m_converter->SetOutputSampleRate(m_output_sample_rate);
+- m_converter->SetOutputChannelLayout(av_get_default_channel_layout(m_output_channels));
++ m_converter->SetOutputChannelLayout(&output_channel_layout);
+ auto ret = m_converter->Init();
+ if (ret != 0) {
+ SetError("Could not create an audio converter instance", ret);
+@@ -203,10 +203,11 @@ inline bool FFmpegAudioReader::Open(const std::string &file_name) {
+ }
+ }
+
++ av_channel_layout_uninit(&output_channel_layout);
++
+ m_opened = true;
+- m_finished = false;
+- m_got_frame = 0;
+- m_nb_packets = 0;
++ m_has_more_packets = true;
++ m_has_more_frames = true;
+ m_decode_error = 0;
+
+ return true;
+@@ -214,6 +215,7 @@ inline bool FFmpegAudioReader::Open(const std::string &file_name) {
+
+ inline void FFmpegAudioReader::Close() {
+ av_frame_free(&m_frame);
++ av_packet_free(&m_packet);
+
+ m_stream_index = -1;
+
+@@ -252,91 +254,98 @@ inline bool FFmpegAudioReader::Read(const int16_t **data, size_t *size) {
+ return false;
+ }
+
++ *data = nullptr;
++ *size = 0;
++
+ int ret;
++ bool needs_packet = false;
+ while (true) {
+- while (m_packet.size <= 0) {
+- av_packet_unref(&m_packet0);
+- av_init_packet(&m_packet);
+- m_packet.data = nullptr;
+- m_packet.size = 0;
+- ret = av_read_frame(m_format_ctx, &m_packet);
++ while (needs_packet && m_packet->size == 0) {
++ ret = av_read_frame(m_format_ctx, m_packet);
+ if (ret < 0) {
+ if (ret == AVERROR_EOF) {
+- m_finished = true;
++ needs_packet = false;
++ m_has_more_packets = false;
+ break;
+- } else {
++ }
++ SetError("Error reading from the audio source", ret);
++ return false;
++ }
++ if (m_packet->stream_index == m_stream_index) {
++ needs_packet = false;
++ } else {
++ av_packet_unref(m_packet);
++ }
++ }
++
++ if (m_packet->size != 0) {
++ ret = avcodec_send_packet(m_codec_ctx, m_packet);
++ if (ret < 0) {
++ if (ret != AVERROR(EAGAIN)) {
+ SetError("Error reading from the audio source", ret);
+ return false;
+ }
+- }
+- m_packet0 = m_packet;
+- if (m_packet.stream_index != m_stream_index) {
+- m_packet.data = nullptr;
+- m_packet.size = 0;
+ } else {
+- m_nb_packets++;
++ av_packet_unref(m_packet);
+ }
+ }
+
+- ret = avcodec_decode_audio4(m_codec_ctx, m_frame, &m_got_frame, &m_packet);
++ ret = avcodec_receive_frame(m_codec_ctx, m_frame);
+ if (ret < 0) {
+- if (m_decode_error) {
+- SetError("Error decoding audio frame", m_decode_error);
+- return false;
++ if (ret == AVERROR_EOF) {
++ m_has_more_frames = false;
++ } else if (ret == AVERROR(EAGAIN)) {
++ if (m_has_more_packets) {
++ needs_packet = true;
++ continue;
++ } else {
++ m_has_more_frames = false;
++ }
+ }
+- m_decode_error = ret;
+- m_packet.data = nullptr;
+- m_packet.size = 0;
+- continue;
++ SetError("Error decoding the audio source", ret);
++ return false;
+ }
+
+- break;
+- }
+-
+- m_decode_error = 0;
+-
+- const int decoded = std::min(ret, m_packet.size);
+- m_packet.data += decoded;
+- m_packet.size -= decoded;
+-
+- if (m_got_frame) {
+- if (m_converter) {
+- if (m_frame->nb_samples > m_convert_buffer_nb_samples) {
+- int linsize;
+- av_freep(&m_convert_buffer[0]);
+- m_convert_buffer_nb_samples = std::max(1024 * 8, m_frame->nb_samples);
+- ret = av_samples_alloc(m_convert_buffer, &linsize, m_codec_ctx->channels, m_convert_buffer_nb_samples, AV_SAMPLE_FMT_S16, 1);
+- if (ret < 0) {
+- SetError("Couldn't allocate audio converter buffer", ret);
++ if (m_frame->nb_samples > 0) {
++ if (m_converter) {
++ if (m_frame->nb_samples > m_convert_buffer_nb_samples) {
++ int linsize;
++ av_freep(&m_convert_buffer[0]);
++ m_convert_buffer_nb_samples = std::max(1024 * 8, m_frame->nb_samples);
++ ret = av_samples_alloc(m_convert_buffer, &linsize, m_codec_ctx->ch_layout.nb_channels, m_convert_buffer_nb_samples, AV_SAMPLE_FMT_S16, 1);
++ if (ret < 0) {
++ SetError("Couldn't allocate audio converter buffer", ret);
++ return false;
++ }
++ }
++ auto nb_samples = m_converter->Convert(m_convert_buffer, m_convert_buffer_nb_samples, (const uint8_t **) m_frame->data, m_frame->nb_samples);
++ if (nb_samples < 0) {
++ SetError("Couldn't convert audio", ret);
+ return false;
+ }
+- }
+- auto nb_samples = m_converter->Convert(m_convert_buffer, m_convert_buffer_nb_samples, (const uint8_t **) m_frame->data, m_frame->nb_samples);
+- if (nb_samples < 0) {
+- SetError("Couldn't convert audio", ret);
+- return false;
+- }
+- *data = (const int16_t *) m_convert_buffer[0];
+- *size = nb_samples;
+- } else {
+- *data = (const int16_t *) m_frame->data[0];
+- *size = m_frame->nb_samples;
+- }
+- } else {
+- if (m_finished && m_converter) {
+- auto nb_samples = m_converter->Flush(m_convert_buffer, m_convert_buffer_nb_samples);
+- if (nb_samples < 0) {
+- SetError("Couldn't convert audio", ret);
+- return false;
+- } else if (nb_samples > 0) {
+- m_got_frame = 1;
+ *data = (const int16_t *) m_convert_buffer[0];
+ *size = nb_samples;
++ } else {
++ *data = (const int16_t *) m_frame->data[0];
++ *size = m_frame->nb_samples;
++ }
++ } else {
++ if (m_converter) {
++ if (IsFinished()) {
++ auto nb_samples = m_converter->Flush(m_convert_buffer, m_convert_buffer_nb_samples);
++ if (nb_samples < 0) {
++ SetError("Couldn't convert audio", ret);
++ return false;
++ } else if (nb_samples > 0) {
++ *data = (const int16_t *) m_convert_buffer[0];
++ *size = nb_samples;
++ }
++ }
+ }
+ }
+- }
+
+- return true;
++ return true;
++ }
+ }
+
+ inline void FFmpegAudioReader::SetError(const char *message, int errnum) {
+diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt
+index a2b517b..123e643 100644
+--- a/tests/CMakeLists.txt
++++ b/tests/CMakeLists.txt
+@@ -38,6 +38,12 @@ set(SRCS
+
+ if(BUILD_TOOLS)
+ set(SRCS ${SRCS} ../src/audio/ffmpeg_audio_reader_test.cpp)
++ include_directories(
++ ${FFMPEG_LIBAVFORMAT_INCLUDE_DIRS}
++ ${FFMPEG_LIBAVCODEC_INCLUDE_DIRS}
++ ${FFMPEG_LIBAVUTIL_INCLUDE_DIRS}
++ ${AUDIO_PROCESSOR_INCLUDE_DIRS}
++ )
+ link_libraries(fpcalc_libs)
+ endif()
+
+--
+2.38.1
+
+
diff --git a/srcpkgs/chromaprint/template b/srcpkgs/chromaprint/template
index 7ef7838949f3..1f7bbc70a22c 100644
--- a/srcpkgs/chromaprint/template
+++ b/srcpkgs/chromaprint/template
@@ -1,7 +1,7 @@
# Template file for 'chromaprint'
pkgname=chromaprint
version=1.5.1
-revision=1
+revision=2
build_style=cmake
configure_args="-DBUILD_TOOLS=ON"
make_check_target="check"
From 5d06b9e797a214e01cfe39dec92e9a22e777bdb5 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:46 -0400
Subject: [PATCH 026/113] chromium: revbump for ffmpeg-6.0
---
.../patches/chromium-93-ffmpeg-4.4.patch | 36 --------------
srcpkgs/chromium/patches/ffmpeg5.patch | 47 +++++++++++++++++++
srcpkgs/chromium/template | 2 +-
3 files changed, 48 insertions(+), 37 deletions(-)
delete mode 100644 srcpkgs/chromium/patches/chromium-93-ffmpeg-4.4.patch
create mode 100644 srcpkgs/chromium/patches/ffmpeg5.patch
diff --git a/srcpkgs/chromium/patches/chromium-93-ffmpeg-4.4.patch b/srcpkgs/chromium/patches/chromium-93-ffmpeg-4.4.patch
deleted file mode 100644
index f0ec736f98bc..000000000000
--- a/srcpkgs/chromium/patches/chromium-93-ffmpeg-4.4.patch
+++ /dev/null
@@ -1,36 +0,0 @@
-diff --git a/media/filters/ffmpeg_demuxer.cc b/media/filters/ffmpeg_demuxer.cc
-index ac4713b07268..492a9a37d096 100644
---- a/media/filters/ffmpeg_demuxer.cc
-+++ b/media/filters/ffmpeg_demuxer.cc
-@@ -427,11 +427,11 @@ void FFmpegDemuxerStream::EnqueuePacket(ScopedAVPacket packet) {
- scoped_refptr<DecoderBuffer> buffer;
-
- if (type() == DemuxerStream::TEXT) {
-- size_t id_size = 0;
-+ int id_size = 0;
- uint8_t* id_data = av_packet_get_side_data(
- packet.get(), AV_PKT_DATA_WEBVTT_IDENTIFIER, &id_size);
-
-- size_t settings_size = 0;
-+ int settings_size = 0;
- uint8_t* settings_data = av_packet_get_side_data(
- packet.get(), AV_PKT_DATA_WEBVTT_SETTINGS, &settings_size);
-
-@@ -443,7 +443,7 @@ void FFmpegDemuxerStream::EnqueuePacket(ScopedAVPacket packet) {
- buffer = DecoderBuffer::CopyFrom(packet->data, packet->size,
- side_data.data(), side_data.size());
- } else {
-- size_t side_data_size = 0;
-+ int side_data_size = 0;
- uint8_t* side_data = av_packet_get_side_data(
- packet.get(), AV_PKT_DATA_MATROSKA_BLOCKADDITIONAL, &side_data_size);
-
-@@ -504,7 +504,7 @@ void FFmpegDemuxerStream::EnqueuePacket(ScopedAVPacket packet) {
- packet->size - data_offset);
- }
-
-- size_t skip_samples_size = 0;
-+ int skip_samples_size = 0;
- const uint32_t* skip_samples_ptr =
- reinterpret_cast<const uint32_t*>(av_packet_get_side_data(
- packet.get(), AV_PKT_DATA_SKIP_SAMPLES, &skip_samples_size));
diff --git a/srcpkgs/chromium/patches/ffmpeg5.patch b/srcpkgs/chromium/patches/ffmpeg5.patch
new file mode 100644
index 000000000000..24e2da38e34c
--- /dev/null
+++ b/srcpkgs/chromium/patches/ffmpeg5.patch
@@ -0,0 +1,47 @@
+--- a/media/filters/ffmpeg_demuxer.cc 2023-01-23 17:33:57.366213805 +0200
++++ b/media/filters/ffmpeg_demuxer.cc 2023-01-23 17:43:09.283436983 +0200
+@@ -92,24 +92,12 @@
+
+ static base::TimeDelta ExtractStartTime(AVStream* stream) {
+ // The default start time is zero.
+- base::TimeDelta start_time;
++ base::TimeDelta start_time = kNoTimestamp;
+
+ // First try to use the |start_time| value as is.
+- if (stream->start_time != kNoFFmpegTimestamp)
++ if (stream->start_time != kNoFFmpegTimestamp) // AV_NOPTS_VALUE
+ start_time = ConvertFromTimeBase(stream->time_base, stream->start_time);
+
+- // Next try to use the first DTS value, for codecs where we know PTS == DTS
+- // (excludes all H26x codecs). The start time must be returned in PTS.
+- if (av_stream_get_first_dts(stream) != kNoFFmpegTimestamp &&
+- stream->codecpar->codec_id != AV_CODEC_ID_HEVC &&
+- stream->codecpar->codec_id != AV_CODEC_ID_H264 &&
+- stream->codecpar->codec_id != AV_CODEC_ID_MPEG4) {
+- const base::TimeDelta first_pts =
+- ConvertFromTimeBase(stream->time_base, av_stream_get_first_dts(stream));
+- if (first_pts < start_time)
+- start_time = first_pts;
+- }
+-
+ return start_time;
+ }
+
+@@ -1597,7 +1585,7 @@
+ for (const auto& stream : streams_) {
+ if (!stream || stream->IsEnabled() != enabled)
+ continue;
+- if (av_stream_get_first_dts(stream->av_stream()) == kInvalidPTSMarker)
++ if (stream->av_stream()->start_time == AV_NOPTS_VALUE)
+ continue;
+ if (!lowest_start_time_stream ||
+ stream->start_time() < lowest_start_time_stream->start_time()) {
+@@ -1618,7 +1606,7 @@
+ if (stream->type() != DemuxerStream::VIDEO)
+ continue;
+
+- if (av_stream_get_first_dts(stream->av_stream()) == kInvalidPTSMarker)
++ if (stream->av_stream()->start_time == AV_NOPTS_VALUE)
+ continue;
+
+ if (!stream->IsEnabled())
diff --git a/srcpkgs/chromium/template b/srcpkgs/chromium/template
index cafc2fe324c6..9df782b5fd9b 100644
--- a/srcpkgs/chromium/template
+++ b/srcpkgs/chromium/template
@@ -2,7 +2,7 @@
pkgname=chromium
# See https://chromiumdash.appspot.com/releases?platform=Linux for the latest version
version=113.0.5672.92
-revision=1
+revision=2
archs="i686* x86_64* aarch64* armv7l*"
hostmakedepends="
$(vopt_if clang "clang lld llvm15")
From f2e2efe42cbf4aa0b4af713a9a506cdf7d7b7cdb Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:46 -0400
Subject: [PATCH 027/113] cmus: revbump for ffmpeg-6.0
---
srcpkgs/cmus/patches/ffmpeg6.patch | 12 ++++++++++++
srcpkgs/cmus/template | 2 +-
2 files changed, 13 insertions(+), 1 deletion(-)
create mode 100644 srcpkgs/cmus/patches/ffmpeg6.patch
diff --git a/srcpkgs/cmus/patches/ffmpeg6.patch b/srcpkgs/cmus/patches/ffmpeg6.patch
new file mode 100644
index 000000000000..ffa95ab81110
--- /dev/null
+++ b/srcpkgs/cmus/patches/ffmpeg6.patch
@@ -0,0 +1,12 @@
+--- a/ip/ffmpeg.c
++++ b/ip/ffmpeg.c
+@@ -202,9 +202,6 @@ static int ffmpeg_open(struct input_plugin_data *ip_data)
+ break;
+ }
+
+- if (codec->capabilities & AV_CODEC_CAP_TRUNCATED)
+- cc->flags |= AV_CODEC_FLAG_TRUNCATED;
+-
+ if (avcodec_open2(cc, codec, NULL) < 0) {
+ d_print("could not open codec: %d, %s\n", cc->codec_id, avcodec_get_name(cc->codec_id));
+ err = -IP_ERROR_UNSUPPORTED_FILE_TYPE;
diff --git a/srcpkgs/cmus/template b/srcpkgs/cmus/template
index 0fcb424ce336..05b77d0fecae 100644
--- a/srcpkgs/cmus/template
+++ b/srcpkgs/cmus/template
@@ -1,7 +1,7 @@
# Template file for 'cmus'
pkgname=cmus
version=2.10.0
-revision=1
+revision=2
build_style=configure
configure_args="prefix=/usr LD=$CC"
hostmakedepends="pkg-config"
From 14dab0aa98000943de0205d412dc4e40096eae50 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:46 -0400
Subject: [PATCH 028/113] cyanrip: revbump for ffmpeg-6.0
---
srcpkgs/cyanrip/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/cyanrip/template b/srcpkgs/cyanrip/template
index 9796e3461601..5db30e020d17 100644
--- a/srcpkgs/cyanrip/template
+++ b/srcpkgs/cyanrip/template
@@ -1,7 +1,7 @@
# Template file for 'cyanrip'
pkgname=cyanrip
version=0.9.0
-revision=1
+revision=2
build_style=meson
hostmakedepends="pkg-config"
makedepends="ffmpeg-devel libcdio-devel libcdio-paranoia-devel libcurl-devel libmusicbrainz5-devel"
From d4ba82f678407cc94d056ca998fa4f422f5629e3 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:46 -0400
Subject: [PATCH 029/113] deadbeef: revbump for ffmpeg4-4.4.3
---
srcpkgs/deadbeef/template | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/srcpkgs/deadbeef/template b/srcpkgs/deadbeef/template
index b664bb1b9bd9..165b3c7b9cad 100644
--- a/srcpkgs/deadbeef/template
+++ b/srcpkgs/deadbeef/template
@@ -1,14 +1,14 @@
# Template file for 'deadbeef'
pkgname=deadbeef
version=1.8.8
-revision=1
+revision=2
create_wrksrc=yes
build_style=gnu-configure
configure_args="--disable-oss --disable-lfm --disable-notify --disable-gtk2"
hostmakedepends="automake libtool gettext gettext-devel intltool pkg-config
yasm clang glib-devel"
makedepends="
- alsa-lib-devel dbus-devel faad2-devel ffmpeg-devel gtk+3-devel imlib2-devel
+ alsa-lib-devel dbus-devel faad2-devel ffmpeg4-devel gtk+3-devel imlib2-devel
jansson-devel libcddb-devel libcdio-devel libcurl-devel libflac-devel
libmad-devel libpng-devel libsamplerate-devel libsndfile-devel libvorbis-devel
libzip-devel mpg123-devel opusfile-devel pulseaudio-devel wavpack-devel"
From d793160a9a3e55424407177a57bd25509f43f8dd Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:46 -0400
Subject: [PATCH 030/113] dolphin-emu: revbump for ffmpeg-6.0
---
srcpkgs/dolphin-emu/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/dolphin-emu/template b/srcpkgs/dolphin-emu/template
index 7ea197ceb2a8..7aeb0a5b645e 100644
--- a/srcpkgs/dolphin-emu/template
+++ b/srcpkgs/dolphin-emu/template
@@ -1,7 +1,7 @@
# Template file for 'dolphin-emu'
pkgname=dolphin-emu
version=5.0.16101
-revision=1
+revision=2
_dolphin_commit=8ecfa537a242de74d2e372e30d9d79b14584b2fb
_mgba_commit=40d4c430fc36caeb7ea32fd39624947ed487d2f2
#Version/hash pair can be found at https://dolphin-emu.org/download/
From ecb3d524c6418ca311c76e4aefcc643690c5abdf Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:46 -0400
Subject: [PATCH 031/113] droidcam-obs-plugin: revbump for ffmpeg-6.0
---
srcpkgs/droidcam-obs-plugin/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/droidcam-obs-plugin/template b/srcpkgs/droidcam-obs-plugin/template
index fc9c9bf6b9d5..fb0480754df4 100644
--- a/srcpkgs/droidcam-obs-plugin/template
+++ b/srcpkgs/droidcam-obs-plugin/template
@@ -1,7 +1,7 @@
# Template file for 'droidcam-obs-plugin'
pkgname=droidcam-obs-plugin
version=2.0.1
-revision=1
+revision=2
build_style=gnu-makefile
make_use_env=yes
make_build_args="ALLOW_STATIC=no"
From ee1262f298f5f745ae325a63b56c2d1d53bd7a29 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:46 -0400
Subject: [PATCH 032/113] droidcam: revbump for ffmpeg-6.0
---
srcpkgs/droidcam/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/droidcam/template b/srcpkgs/droidcam/template
index 1c3f1b8b1fc6..32a9220b79a4 100644
--- a/srcpkgs/droidcam/template
+++ b/srcpkgs/droidcam/template
@@ -1,7 +1,7 @@
# Template file for 'droidcam'
pkgname=droidcam
version=1.8.2
-revision=2
+revision=3
build_style=gnu-makefile
make_build_args="USBMUXD=-lusbmuxd-2.0 JPEG=-lturbojpeg"
hostmakedepends="pkg-config"
From 7cec78ac4d2a68ef05091e1367f45891845861e1 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:47 -0400
Subject: [PATCH 033/113] ffmpegthumbnailer: revbump for ffmpeg-6.0
---
.../ffmpegthumbnailer/patches/ffmpeg6.patch | 202 ++++++++++++++++++
srcpkgs/ffmpegthumbnailer/template | 6 +-
2 files changed, 205 insertions(+), 3 deletions(-)
create mode 100644 srcpkgs/ffmpegthumbnailer/patches/ffmpeg6.patch
diff --git a/srcpkgs/ffmpegthumbnailer/patches/ffmpeg6.patch b/srcpkgs/ffmpegthumbnailer/patches/ffmpeg6.patch
new file mode 100644
index 000000000000..363ff35a2841
--- /dev/null
+++ b/srcpkgs/ffmpegthumbnailer/patches/ffmpeg6.patch
@@ -0,0 +1,202 @@
+--- a/libffmpegthumbnailer/moviedecoder.cpp 2017-11-21 14:06:57.000000000 -0500
++++ b/libffmpegthumbnailer/moviedecoder.cpp 2023-05-05 13:14:47.946560668 -0400
+@@ -41,11 +41,6 @@
+ namespace ffmpegthumbnailer
+ {
+
+-struct SilenceLogLevel
+-{
+- SilenceLogLevel() { av_log_set_level(AV_LOG_QUIET); }
+-};
+-
+ MovieDecoder::MovieDecoder(AVFormatContext* pavContext)
+ : m_VideoStream(-1)
+ , m_pFormatContext(pavContext)
+@@ -70,8 +65,6 @@
+
+ void MovieDecoder::initialize(const string& filename, bool preferEmbeddedMetadata)
+ {
+- av_register_all();
+- avcodec_register_all();
+ avformat_network_init();
+
+ string inputFile = filename == "-" ? "pipe:" : filename;
+@@ -97,8 +90,7 @@
+ {
+ if (m_pVideoCodecContext)
+ {
+- avcodec_close(m_pVideoCodecContext);
+- m_pVideoCodecContext = nullptr;
++ avcodec_free_context(&m_pVideoCodecContext);
+ }
+
+ if ((!m_FormatContextWasGiven) && m_pFormatContext)
+@@ -152,10 +144,10 @@
+ for (unsigned int i = 0; i < m_pFormatContext->nb_streams; ++i)
+ {
+ AVStream *stream = m_pFormatContext->streams[i];
+- auto ctx = m_pFormatContext->streams[i]->codec;
+- if (ctx->codec_type == AVMEDIA_TYPE_VIDEO)
++ auto par = m_pFormatContext->streams[i]->codecpar;
++ if (par->codec_type == AVMEDIA_TYPE_VIDEO)
+ {
+- if (!preferEmbeddedMetadata || !isStillImageCodec(ctx->codec_id))
++ if (!preferEmbeddedMetadata || !isStillImageCodec(par->codec_id))
+ {
+ videoStreams.push_back(i);
+ continue;
+@@ -203,8 +195,7 @@
+ }
+
+ m_pVideoStream = m_pFormatContext->streams[m_VideoStream];
+- m_pVideoCodecContext = m_pVideoStream->codec;
+- m_pVideoCodec = avcodec_find_decoder(m_pVideoCodecContext->codec_id);
++ m_pVideoCodec = avcodec_find_decoder(m_pVideoStream->codecpar->codec_id);
+
+ if (m_pVideoCodec == nullptr)
+ {
+@@ -214,6 +205,20 @@
+ throw logic_error("Video Codec not found");
+ }
+
++ m_pVideoCodecContext = avcodec_alloc_context3(m_pVideoCodec);
++
++ if (m_pVideoCodecContext == nullptr)
++ {
++ destroy();
++ throw logic_error("Could not allocate video codec context");
++ }
++
++ if (avcodec_parameters_to_context(m_pVideoCodecContext, m_pVideoStream->codecpar) < 0)
++ {
++ destroy();
++ throw logic_error("Could not configure video codec context");
++ }
++
+ m_pVideoCodecContext->workaround_bugs = 1;
+
+ if (avcodec_open2(m_pVideoCodecContext, m_pVideoCodec, nullptr) < 0)
+@@ -386,13 +391,6 @@
+
+ void MovieDecoder::initializeFilterGraph(const AVRational& timeBase, const std::string& size, bool maintainAspectRatio)
+ {
+- static const AVPixelFormat pixelFormats[] = { AV_PIX_FMT_RGB24, AV_PIX_FMT_NONE };
+-
+- auto del = [] (AVBufferSinkParams* p) { av_freep(p); };
+- std::unique_ptr<AVBufferSinkParams, decltype(del)> buffersinkParams(av_buffersink_params_alloc(), del);
+-
+- avfilter_register_all();
+-
+ m_pFilterGraph = avfilter_graph_alloc();
+ assert(m_pFilterGraph);
+
+@@ -404,10 +402,8 @@
+
+ checkRc(avfilter_graph_create_filter(&m_pFilterSource, avfilter_get_by_name("buffer"), "thumb_buffer", ss.str().c_str(), nullptr, m_pFilterGraph),
+ "Failed to create filter source");
+- buffersinkParams->pixel_fmts = pixelFormats;
+- checkRc(avfilter_graph_create_filter(&m_pFilterSink, avfilter_get_by_name("buffersink"), "thumb_buffersink", nullptr, buffersinkParams.get(), m_pFilterGraph),
++ checkRc(avfilter_graph_create_filter(&m_pFilterSink, avfilter_get_by_name("buffersink"), "thumb_buffersink", nullptr, nullptr, m_pFilterGraph),
+ "Failed to create filter sink");
+- buffersinkParams.release();
+
+ AVFilterContext* yadifFilter = nullptr;
+ if (m_pFrame->interlaced_frame != 0)
+@@ -500,15 +496,15 @@
+ }
+
+ checkRc(av_seek_frame(m_pFormatContext, -1, timestamp, 0), "Seeking in video failed");
+- avcodec_flush_buffers(m_pFormatContext->streams[m_VideoStream]->codec);
++ avcodec_flush_buffers(m_pVideoCodecContext);
+
+ int keyFrameAttempts = 0;
+- bool gotFrame = 0;
++ bool gotFrame;
+
+ do
+ {
+ int count = 0;
+- gotFrame = 0;
++ gotFrame = false;
+
+ while (!gotFrame && count < 20)
+ {
+@@ -552,17 +548,33 @@
+ return false;
+ }
+
+- av_frame_unref(m_pFrame);
+-
+- int frameFinished;
++ int rc = avcodec_send_packet(m_pVideoCodecContext, m_pPacket);
++ if(rc == AVERROR(EAGAIN))
++ {
++ rc = 0;
++ }
+
+- int bytesDecoded = avcodec_decode_video2(m_pVideoCodecContext, m_pFrame, &frameFinished, m_pPacket);
+- if (bytesDecoded < 0)
++ if(rc == AVERROR_EOF)
++ {
++ return false;
++ }
++ else if(rc < 0)
+ {
+- throw logic_error("Failed to decode video frame: bytesDecoded < 0");
++ throw logic_error("Failed to decode video frame: avcodec_send_packet() < 0");
+ }
+
+- return frameFinished > 0;
++ rc = avcodec_receive_frame(m_pVideoCodecContext, m_pFrame);
++ switch(rc)
++ {
++ case 0:
++ return true;
++
++ case AVERROR(EAGAIN):
++ return false;
++
++ default:
++ throw logic_error("Failed to decode video frame: avcodec_receive_frame() < 0");
++ }
+ }
+
+ bool MovieDecoder::getVideoPacket()
+@@ -570,8 +582,6 @@
+ bool framesAvailable = true;
+ bool frameDecoded = false;
+
+- int attempts = 0;
+-
+ if (m_pPacket)
+ {
+ av_packet_unref(m_pPacket);
+@@ -580,6 +590,7 @@
+
+ m_pPacket = new AVPacket();
+
++
+ while (framesAvailable && !frameDecoded)
+ {
+ framesAvailable = av_read_frame(m_pFormatContext, m_pPacket) >= 0;
+@@ -644,7 +655,7 @@
+
+ int32_t MovieDecoder::getStreamRotation()
+ {
+- int32_t* matrix = reinterpret_cast<int32_t*>(av_stream_get_side_data(m_pVideoStream, AV_PKT_DATA_DISPLAYMATRIX, nullptr));
++ auto matrix = reinterpret_cast<int32_t*>(av_stream_get_side_data(m_pVideoStream, AV_PKT_DATA_DISPLAYMATRIX, nullptr));
+ if (matrix)
+ {
+ auto angle = lround(av_display_rotation_get(matrix));
+
+--- a/libffmpegthumbnailer/moviedecoder.h 2017-11-12 04:23:38.000000000 -0500
++++ b/libffmpegthumbnailer/moviedecoder.h 2023-05-05 13:26:07.095529911 -0400
+@@ -78,7 +78,7 @@
+ int m_VideoStream;
+ AVFormatContext* m_pFormatContext;
+ AVCodecContext* m_pVideoCodecContext;
+- AVCodec* m_pVideoCodec;
++ const AVCodec* m_pVideoCodec;
+ AVFilterGraph* m_pFilterGraph;
+ AVFilterContext* m_pFilterSource;
+ AVFilterContext* m_pFilterSink;
diff --git a/srcpkgs/ffmpegthumbnailer/template b/srcpkgs/ffmpegthumbnailer/template
index 039eea7622b3..35d546018d12 100644
--- a/srcpkgs/ffmpegthumbnailer/template
+++ b/srcpkgs/ffmpegthumbnailer/template
@@ -1,7 +1,7 @@
# Template file for 'ffmpegthumbnailer'
pkgname=ffmpegthumbnailer
version=2.2.2
-revision=1
+revision=2
build_style=cmake
hostmakedepends="pkg-config"
makedepends="libpng-devel libjpeg-turbo-devel ffmpeg-devel"
@@ -9,8 +9,8 @@ depends="ffmpeg"
short_desc="Lightweight video thumbnailer"
maintainer="Orphaned <orphan@voidlinux.org>"
license="GPL-2.0-or-later"
-homepage="https://github.com/dirkvdb/${pkgname}"
-distfiles="${homepage}/releases/download/${version}/${pkgname}-${version}.tar.bz2"
+homepage="https://github.com/dirkvdb"
+distfiles="${homepage}/${pkgname}/releases/download/${version}/${pkgname}-${version}.tar.bz2"
checksum=1cb24059c38223f657b300c84dd80491b7040d4b69471c4fea69be862bc99b5b
post_install() {
From e09be981a4cd994f9f16029cac74101c3e1d431e Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:47 -0400
Subject: [PATCH 034/113] ffmpegthumbs: revbump for ffmpeg-6.0
---
srcpkgs/ffmpegthumbs/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/ffmpegthumbs/template b/srcpkgs/ffmpegthumbs/template
index 5f0b9414dada..11b88193528f 100644
--- a/srcpkgs/ffmpegthumbs/template
+++ b/srcpkgs/ffmpegthumbs/template
@@ -1,7 +1,7 @@
# Template file for 'ffmpegthumbs'
pkgname=ffmpegthumbs
version=22.12.1
-revision=1
+revision=2
build_style=cmake
hostmakedepends="extra-cmake-modules kcoreaddons kconfig-devel
pkg-config qt5-host-tools qt5-qmake gettext"
From 9fcc0b702b637a19cbec68dc75589b67d9914dd6 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:47 -0400
Subject: [PATCH 035/113] ffms2: revbump for ffmpeg-6.0
---
srcpkgs/ffms2/patches/ffmpeg5.patch | 424 ++++++++++++++++++++++++++++
srcpkgs/ffms2/template | 2 +-
2 files changed, 425 insertions(+), 1 deletion(-)
create mode 100644 srcpkgs/ffms2/patches/ffmpeg5.patch
diff --git a/srcpkgs/ffms2/patches/ffmpeg5.patch b/srcpkgs/ffms2/patches/ffmpeg5.patch
new file mode 100644
index 000000000000..1479fabcafcb
--- /dev/null
+++ b/srcpkgs/ffms2/patches/ffmpeg5.patch
@@ -0,0 +1,424 @@
+From 45673149e9a2f5586855ad472e3059084eaa36b1 Mon Sep 17 00:00:00 2001
+From: Derek Buitenhuis <derek.buitenhuis@gmail.com>
+Date: Tue, 4 May 2021 14:41:21 +0100
+Subject: [PATCH] Use auto for AVCodec
+
+The geniuses over at FFmpeg decided to constify this API, so old
+versions of the library will return AVCodec *, while new versions
+of the libary will return const AVCodec *, which, in C++, are not
+OK to convert between.
+
+Rather than use some macro hell in ffmscompat.h, we can work around
+this by using auto.
+
+Gross.
+
+Signed-off-by: Derek Buitenhuis <derek.buitenhuis@gmail.com>
+---
+ src/core/audiosource.cpp | 2 +-
+ src/core/indexing.cpp | 6 +++---
+ src/core/videosource.cpp | 2 +-
+ 3 files changed, 5 insertions(+), 5 deletions(-)
+
+diff --git a/src/core/audiosource.cpp b/src/core/audiosource.cpp
+index e4ce97c..ac09666 100644
+--- a/src/core/audiosource.cpp
++++ b/src/core/audiosource.cpp
+@@ -469,7 +469,7 @@ void FFMS_AudioSource::OpenFile() {
+
+ LAVFOpenFile(SourceFile.c_str(), FormatContext, TrackNumber);
+
+- AVCodec *Codec = avcodec_find_decoder(FormatContext->streams[TrackNumber]->codecpar->codec_id);
++ auto *Codec = avcodec_find_decoder(FormatContext->streams[TrackNumber]->codecpar->codec_id);
+ if (Codec == nullptr)
+ throw FFMS_Exception(FFMS_ERROR_DECODING, FFMS_ERROR_CODEC,
+ "Audio codec not found");
+diff --git a/src/core/indexing.cpp b/src/core/indexing.cpp
+index e547c5a..59fb4e8 100644
+--- a/src/core/indexing.cpp
++++ b/src/core/indexing.cpp
+@@ -384,7 +384,7 @@ FFMS_TrackType FFMS_Indexer::GetTrackType(int Track) {
+ }
+
+ const char *FFMS_Indexer::GetTrackCodec(int Track) {
+- AVCodec *codec = avcodec_find_decoder(FormatContext->streams[Track]->codecpar->codec_id);
++ auto *codec = avcodec_find_decoder(FormatContext->streams[Track]->codecpar->codec_id);
+ return codec ? codec->name : nullptr;
+ }
+
+@@ -402,7 +402,7 @@ FFMS_Index *FFMS_Indexer::DoIndexing() {
+ UseDTS);
+
+ if (IndexMask.count(i) && FormatContext->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
+- AVCodec *VideoCodec = avcodec_find_decoder(FormatContext->streams[i]->codecpar->codec_id);
++ auto *VideoCodec = avcodec_find_decoder(FormatContext->streams[i]->codecpar->codec_id);
+ if (!VideoCodec) {
+ FormatContext->streams[i]->discard = AVDISCARD_ALL;
+ IndexMask.erase(i);
+@@ -433,7 +433,7 @@ FFMS_Index *FFMS_Indexer::DoIndexing() {
+ IndexMask.insert(i);
+ }
+ } else if (IndexMask.count(i) && FormatContext->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) {
+- AVCodec *AudioCodec = avcodec_find_decoder(FormatContext->streams[i]->codecpar->codec_id);
++ auto *AudioCodec = avcodec_find_decoder(FormatContext->streams[i]->codecpar->codec_id);
+ if (AudioCodec == nullptr)
+ throw FFMS_Exception(FFMS_ERROR_CODEC, FFMS_ERROR_UNSUPPORTED,
+ "Audio codec not found");
+diff --git a/src/core/videosource.cpp b/src/core/videosource.cpp
+index b889970..8956c22 100644
+--- a/src/core/videosource.cpp
++++ b/src/core/videosource.cpp
+@@ -171,7 +171,7 @@ FFMS_VideoSource::FFMS_VideoSource(const char *SourceFile, FFMS_Index &Index, in
+
+ LAVFOpenFile(SourceFile, FormatContext, VideoTrack);
+
+- AVCodec *Codec = avcodec_find_decoder(FormatContext->streams[VideoTrack]->codecpar->codec_id);
++ auto *Codec = avcodec_find_decoder(FormatContext->streams[VideoTrack]->codecpar->codec_id);
+ if (Codec == nullptr)
+ throw FFMS_Exception(FFMS_ERROR_DECODING, FFMS_ERROR_CODEC,
+ "Video codec not found");
+--
+2.40.0
+
+From 96cbf38ea9381829a1314f432a2c60495dcefaad Mon Sep 17 00:00:00 2001
+From: Derek Buitenhuis <derek.buitenhuis@gmail.com>
+Date: Tue, 4 May 2021 14:12:41 +0100
+Subject: [PATCH] all: Update AVPacket API usage
+
+AVPackets must all be on the heap now, since it is no longer
+part of the libav* ABI.
+
+Signed-off-by: Derek Buitenhuis <derek.buitenhuis@gmail.com>
+---
+ src/core/audiosource.cpp | 16 ++++++----
+ src/core/indexing.cpp | 63 ++++++++++++++++++++++------------------
+ src/core/indexing.h | 4 +--
+ src/core/utils.cpp | 6 ----
+ src/core/utils.h | 1 -
+ src/core/videosource.cpp | 30 ++++++++++---------
+ 6 files changed, 64 insertions(+), 56 deletions(-)
+
+diff --git a/src/core/audiosource.cpp b/src/core/audiosource.cpp
+index 37cf9ae..e4ce97c 100644
+--- a/src/core/audiosource.cpp
++++ b/src/core/audiosource.cpp
+@@ -285,10 +285,15 @@ FFMS_AudioSource::AudioBlock *FFMS_AudioSource::CacheBlock(CacheIterator &pos) {
+ int FFMS_AudioSource::DecodeNextBlock(CacheIterator *pos) {
+ CurrentFrame = &Frames[PacketNumber];
+
+- AVPacket Packet;
+- if (!ReadPacket(&Packet))
++ AVPacket *Packet = av_packet_alloc();
++ if (!Packet)
++ throw FFMS_Exception(FFMS_ERROR_PARSER, FFMS_ERROR_ALLOCATION_FAILED,
++ "Could not allocate packet.");
++ if (!ReadPacket(Packet)) {
++ av_packet_free(&Packet);
+ throw FFMS_Exception(FFMS_ERROR_PARSER, FFMS_ERROR_UNKNOWN,
+ "ReadPacket unexpectedly failed to read a packet");
++ }
+
+ // ReadPacket may have changed the packet number
+ CurrentFrame = &Frames[PacketNumber];
+@@ -297,8 +302,9 @@ int FFMS_AudioSource::DecodeNextBlock(CacheIterator *pos) {
+ int NumberOfSamples = 0;
+ AudioBlock *CachedBlock = nullptr;
+
+- int Ret = avcodec_send_packet(CodecContext, &Packet);
+- av_packet_unref(&Packet);
++ int Ret = avcodec_send_packet(CodecContext, Packet);
++ av_packet_unref(Packet);
++ av_packet_free(&Packet);
+
+ av_frame_unref(DecodeFrame);
+ Ret = avcodec_receive_frame(CodecContext, DecodeFrame);
+@@ -513,8 +519,6 @@ void FFMS_AudioSource::Seek() {
+ }
+
+ bool FFMS_AudioSource::ReadPacket(AVPacket *Packet) {
+- InitNullPacket(*Packet);
+-
+ while (av_read_frame(FormatContext, Packet) >= 0) {
+ if (Packet->stream_index == TrackNumber) {
+ // Required because not all audio packets, especially in ogg, have a pts. Use the previous valid packet's pts instead.
+diff --git a/src/core/indexing.cpp b/src/core/indexing.cpp
+index 23fb95b..e547c5a 100644
+--- a/src/core/indexing.cpp
++++ b/src/core/indexing.cpp
+@@ -320,7 +320,7 @@ void FFMS_Indexer::CheckAudioProperties(int Track, AVCodecContext *Context) {
+ }
+ }
+
+-void FFMS_Indexer::ParseVideoPacket(SharedAVContext &VideoContext, AVPacket &pkt, int *RepeatPict,
++void FFMS_Indexer::ParseVideoPacket(SharedAVContext &VideoContext, AVPacket *pkt, int *RepeatPict,
+ int *FrameType, bool *Invisible, enum AVPictureStructure *LastPicStruct) {
+ if (VideoContext.Parser) {
+ uint8_t *OB;
+@@ -330,8 +330,8 @@ void FFMS_Indexer::ParseVideoPacket(SharedAVContext &VideoContext, AVPacket &pkt
+ av_parser_parse2(VideoContext.Parser,
+ VideoContext.CodecContext,
+ &OB, &OBSize,
+- pkt.data, pkt.size,
+- pkt.pts, pkt.dts, pkt.pos);
++ pkt->data, pkt->size,
++ pkt->pts, pkt->dts, pkt->pos);
+
+ // H.264 (PAFF) and HEVC may have one field per packet, so we need to track
+ // when we have a full or half frame available, and mark one of them as
+@@ -351,15 +351,15 @@ void FFMS_Indexer::ParseVideoPacket(SharedAVContext &VideoContext, AVPacket &pkt
+
+ *RepeatPict = VideoContext.Parser->repeat_pict;
+ *FrameType = VideoContext.Parser->pict_type;
+- *Invisible = (IncompleteFrame || VideoContext.Parser->repeat_pict < 0 || (pkt.flags & AV_PKT_FLAG_DISCARD));
++ *Invisible = (IncompleteFrame || VideoContext.Parser->repeat_pict < 0 || (pkt->flags & AV_PKT_FLAG_DISCARD));
+ } else {
+- *Invisible = !!(pkt.flags & AV_PKT_FLAG_DISCARD);
++ *Invisible = !!(pkt->flags & AV_PKT_FLAG_DISCARD);
+ }
+
+ if (VideoContext.CodecContext->codec_id == AV_CODEC_ID_VP8)
+- ParseVP8(pkt.data[0], Invisible, FrameType);
++ ParseVP8(pkt->data[0], Invisible, FrameType);
+ else if (VideoContext.CodecContext->codec_id == AV_CODEC_ID_VP9)
+- ParseVP9(pkt.data[0], Invisible, FrameType);
++ ParseVP9(pkt->data[0], Invisible, FrameType);
+ }
+
+ void FFMS_Indexer::Free() {
+@@ -458,32 +458,36 @@ FFMS_Index *FFMS_Indexer::DoIndexing() {
+ }
+ }
+
+- AVPacket Packet;
+- InitNullPacket(Packet);
++ AVPacket *Packet = av_packet_alloc();
++ if (!Packet)
++ throw FFMS_Exception(FFMS_ERROR_CODEC, FFMS_ERROR_ALLOCATION_FAILED,
++ "Could not allocate packet.");
+ std::vector<int64_t> LastValidTS(FormatContext->nb_streams, AV_NOPTS_VALUE);
+
+ int64_t filesize = avio_size(FormatContext->pb);
+ enum AVPictureStructure LastPicStruct = AV_PICTURE_STRUCTURE_UNKNOWN;
+- while (av_read_frame(FormatContext, &Packet) >= 0) {
++ while (av_read_frame(FormatContext, Packet) >= 0) {
+ // Update progress
+ // FormatContext->pb can apparently be NULL when opening images.
+ if (IC && FormatContext->pb) {
+- if ((*IC)(FormatContext->pb->pos, filesize, ICPrivate))
++ if ((*IC)(FormatContext->pb->pos, filesize, ICPrivate)) {
++ av_packet_free(&Packet);
+ throw FFMS_Exception(FFMS_ERROR_CANCELLED, FFMS_ERROR_USER,
+ "Cancelled by user");
++ }
+ }
+- if (!IndexMask.count(Packet.stream_index)) {
+- av_packet_unref(&Packet);
++ if (!IndexMask.count(Packet->stream_index)) {
++ av_packet_unref(Packet);
+ continue;
+ }
+
+- int Track = Packet.stream_index;
++ int Track = Packet->stream_index;
+ FFMS_Track &TrackInfo = (*TrackIndices)[Track];
+- bool KeyFrame = !!(Packet.flags & AV_PKT_FLAG_KEY);
++ bool KeyFrame = !!(Packet->flags & AV_PKT_FLAG_KEY);
+ ReadTS(Packet, LastValidTS[Track], (*TrackIndices)[Track].UseDTS);
+
+ if (FormatContext->streams[Track]->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
+- int64_t PTS = TrackInfo.UseDTS ? Packet.dts : Packet.pts;
++ int64_t PTS = TrackInfo.UseDTS ? Packet->dts : Packet->pts;
+ if (PTS == AV_NOPTS_VALUE) {
+ // VPx alt-refs are output as packets which lack timestmps or durations, since
+ // they are invisible. Currently, the timestamp mangling code in libavformat
+@@ -495,9 +499,11 @@ FFMS_Index *FFMS_Indexer::DoIndexing() {
+ // FFMS2 currently sorts packets by PTS, which will break decoding, otherwise.
+ bool HasAltRefs = (FormatContext->streams[Track]->codecpar->codec_id == AV_CODEC_ID_VP8 ||
+ FormatContext->streams[Track]->codecpar->codec_id == AV_CODEC_ID_VP9);
+- if (Packet.duration == 0 && !HasAltRefs)
++ if (Packet->duration == 0 && !HasAltRefs) {
++ av_packet_free(&Packet);
+ throw FFMS_Exception(FFMS_ERROR_INDEXING, FFMS_ERROR_PARSER,
+ "Invalid packet pts, dts, and duration");
++ }
+
+ if (TrackInfo.empty())
+ PTS = 0;
+@@ -513,7 +519,7 @@ FFMS_Index *FFMS_Indexer::DoIndexing() {
+ ParseVideoPacket(AVContexts[Track], Packet, &RepeatPict, &FrameType, &Invisible, &LastPicStruct);
+
+ TrackInfo.AddVideoFrame(PTS, RepeatPict, KeyFrame,
+- FrameType, Packet.pos, Invisible);
++ FrameType, Packet->pos, Invisible);
+ } else if (FormatContext->streams[Track]->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) {
+ // For video seeking timestamps are used only if all packets have
+ // timestamps, while for audio they're used if any have timestamps,
+@@ -522,28 +528,29 @@ FFMS_Index *FFMS_Indexer::DoIndexing() {
+ TrackInfo.HasTS = true;
+
+ int64_t StartSample = AVContexts[Track].CurrentSample;
+- uint32_t SampleCount = IndexAudioPacket(Track, &Packet, AVContexts[Track], *TrackIndices);
++ uint32_t SampleCount = IndexAudioPacket(Track, Packet, AVContexts[Track], *TrackIndices);
+ TrackInfo.SampleRate = AVContexts[Track].CodecContext->sample_rate;
+
+ TrackInfo.AddAudioFrame(LastValidTS[Track],
+- StartSample, SampleCount, KeyFrame, Packet.pos, Packet.flags & AV_PKT_FLAG_DISCARD);
++ StartSample, SampleCount, KeyFrame, Packet->pos, Packet->flags & AV_PKT_FLAG_DISCARD);
+ }
+
+- if (!(Packet.flags & AV_PKT_FLAG_DISCARD))
+- TrackInfo.LastDuration = Packet.duration;
++ if (!(Packet->flags & AV_PKT_FLAG_DISCARD))
++ TrackInfo.LastDuration = Packet->duration;
+
+- av_packet_unref(&Packet);
++ av_packet_unref(Packet);
+ }
++ av_packet_free(&Packet);
+
+ TrackIndices->Finalize(AVContexts, FormatContext->iformat->name);
+ return TrackIndices.release();
+ }
+
+-void FFMS_Indexer::ReadTS(const AVPacket &Packet, int64_t &TS, bool &UseDTS) {
+- if (!UseDTS && Packet.pts != AV_NOPTS_VALUE)
+- TS = Packet.pts;
++void FFMS_Indexer::ReadTS(const AVPacket *Packet, int64_t &TS, bool &UseDTS) {
++ if (!UseDTS && Packet->pts != AV_NOPTS_VALUE)
++ TS = Packet->pts;
+ if (TS == AV_NOPTS_VALUE)
+ UseDTS = true;
+- if (UseDTS && Packet.dts != AV_NOPTS_VALUE)
+- TS = Packet.dts;
++ if (UseDTS && Packet->dts != AV_NOPTS_VALUE)
++ TS = Packet->dts;
+ }
+diff --git a/src/core/indexing.h b/src/core/indexing.h
+index 3cfc3c3..5c06868 100644
+--- a/src/core/indexing.h
++++ b/src/core/indexing.h
+@@ -80,10 +80,10 @@ private:
+ int64_t Filesize;
+ uint8_t Digest[20];
+
+- void ReadTS(const AVPacket &Packet, int64_t &TS, bool &UseDTS);
++ void ReadTS(const AVPacket *Packet, int64_t &TS, bool &UseDTS);
+ void CheckAudioProperties(int Track, AVCodecContext *Context);
+ uint32_t IndexAudioPacket(int Track, AVPacket *Packet, SharedAVContext &Context, FFMS_Index &TrackIndices);
+- void ParseVideoPacket(SharedAVContext &VideoContext, AVPacket &pkt, int *RepeatPict, int *FrameType, bool *Invisible, enum AVPictureStructure *LastPicStruct);
++ void ParseVideoPacket(SharedAVContext &VideoContext, AVPacket *pkt, int *RepeatPict, int *FrameType, bool *Invisible, enum AVPictureStructure *LastPicStruct);
+ void Free();
+ public:
+ FFMS_Indexer(const char *Filename);
+diff --git a/src/core/utils.cpp b/src/core/utils.cpp
+index ce67533..8a2e997 100644
+--- a/src/core/utils.cpp
++++ b/src/core/utils.cpp
+@@ -62,12 +62,6 @@ void ClearErrorInfo(FFMS_ErrorInfo *ErrorInfo) {
+ }
+ }
+
+-void InitNullPacket(AVPacket &pkt) {
+- av_init_packet(&pkt);
+- pkt.data = nullptr;
+- pkt.size = 0;
+-}
+-
+ void FillAP(FFMS_AudioProperties &AP, AVCodecContext *CTX, FFMS_Track &Frames) {
+ AP.SampleFormat = static_cast<FFMS_SampleFormat>(av_get_packed_sample_fmt(CTX->sample_fmt));
+ AP.BitsPerSample = av_get_bytes_per_sample(CTX->sample_fmt) * 8;
+diff --git a/src/core/utils.h b/src/core/utils.h
+index 9819dc7..003ab79 100644
+--- a/src/core/utils.h
++++ b/src/core/utils.h
+@@ -58,7 +58,6 @@ std::unique_ptr<T> make_unique(Args&&... args) {
+ }
+
+ void ClearErrorInfo(FFMS_ErrorInfo *ErrorInfo);
+-void InitNullPacket(AVPacket &pkt);
+ void FillAP(FFMS_AudioProperties &AP, AVCodecContext *CTX, FFMS_Track &Frames);
+
+ void LAVFOpenFile(const char *SourceFile, AVFormatContext *&FormatContext, int Track);
+diff --git a/src/core/videosource.cpp b/src/core/videosource.cpp
+index 06bd161..b889970 100644
+--- a/src/core/videosource.cpp
++++ b/src/core/videosource.cpp
+@@ -673,30 +673,34 @@ void FFMS_VideoSource::DecodeNextFrame(int64_t &AStartTime, int64_t &Pos) {
+ if (HasPendingDelayedFrames())
+ return;
+
+- AVPacket Packet;
+- InitNullPacket(Packet);
+-
+- while (ReadFrame(&Packet) >= 0) {
+- if (Packet.stream_index != VideoTrack) {
+- av_packet_unref(&Packet);
++ AVPacket *Packet = av_packet_alloc();
++ if (!Packet)
++ throw FFMS_Exception(FFMS_ERROR_DECODING, FFMS_ERROR_ALLOCATION_FAILED,
++ "Could not allocate packet.");
++
++ while (ReadFrame(Packet) >= 0) {
++ if (Packet->stream_index != VideoTrack) {
++ av_packet_unref(Packet);
+ continue;
+ }
+
+ if (AStartTime < 0)
+- AStartTime = Frames.UseDTS ? Packet.dts : Packet.pts;
++ AStartTime = Frames.UseDTS ? Packet->dts : Packet->pts;
+
+ if (Pos < 0)
+- Pos = Packet.pos;
++ Pos = Packet->pos;
+
+- bool FrameFinished = DecodePacket(&Packet);
+- av_packet_unref(&Packet);
+- if (FrameFinished)
++ bool FrameFinished = DecodePacket(Packet);
++ av_packet_unref(Packet);
++ if (FrameFinished) {
++ av_packet_free(&Packet);
+ return;
++ }
+ }
+
+ // Flush final frames
+- InitNullPacket(Packet);
+- DecodePacket(&Packet);
++ DecodePacket(Packet);
++ av_packet_free(&Packet);
+ }
+
+ bool FFMS_VideoSource::SeekTo(int n, int SeekOffset) {
+--
+2.40.0
+
+From bf9e03e9e08534c024e5a744a6437c4aac160201 Mon Sep 17 00:00:00 2001
+From: Derek Buitenhuis <derek.buitenhuis@gmail.com>
+Date: Tue, 4 May 2021 14:20:47 +0100
+Subject: [PATCH 2/3] configure: Remove deprecated API use
+
+Signed-off-by: Derek Buitenhuis <derek.buitenhuis@gmail.com>
+---
+ configure.ac | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/configure.ac b/configure.ac
+index b35ef80bc..d19714d0f 100644
+--- a/configure.ac
++++ b/configure.ac
+@@ -102,10 +102,10 @@ CFLAGS="$_CFLAGS $FFMPEG_CFLAGS"
+
+ AC_DEFUN([TEST_FFMPEG],
+ [AC_LINK_IFELSE([AC_LANG_PROGRAM([[
+- #include <libavcodec/avcodec.h>
++ #include <libavformat/avformat.h>
+ #include <libswscale/swscale.h>
+ ]],[[
+- avcodec_register_all();
++ avformat_network_init();
+ swscale_version();
+ ]])], [eval $1=yes], [eval $1=no])
+ ])
+
diff --git a/srcpkgs/ffms2/template b/srcpkgs/ffms2/template
index 68e8a0c14bce..2acfadac44b3 100644
--- a/srcpkgs/ffms2/template
+++ b/srcpkgs/ffms2/template
@@ -1,7 +1,7 @@
# Template file for 'ffms2'
pkgname=ffms2
version=2.40
-revision=1
+revision=2
build_style=gnu-configure
configure_args="--enable-shared --disable-static"
hostmakedepends="pkg-config autoconf automake libtool"
From 7459ee6ae6a5f23c73e85d3753bd9e8f03951d5d Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:47 -0400
Subject: [PATCH 036/113] freerdp: revbump for ffmpeg-6.0
---
.../freerdp/patches/ffmpeg6_aa2cb9aa.patch | 42 +++++++++++++++++++
srcpkgs/freerdp/template | 2 +-
2 files changed, 43 insertions(+), 1 deletion(-)
create mode 100644 srcpkgs/freerdp/patches/ffmpeg6_aa2cb9aa.patch
diff --git a/srcpkgs/freerdp/patches/ffmpeg6_aa2cb9aa.patch b/srcpkgs/freerdp/patches/ffmpeg6_aa2cb9aa.patch
new file mode 100644
index 000000000000..a4324da3a882
--- /dev/null
+++ b/srcpkgs/freerdp/patches/ffmpeg6_aa2cb9aa.patch
@@ -0,0 +1,42 @@
+From aa2cb9aa5ff5562433598ba168a466e0752bca0e Mon Sep 17 00:00:00 2001
+From: akallabeth <akallabeth@posteo.net>
+Date: Tue, 14 Feb 2023 07:48:54 +0100
+Subject: [PATCH] Fixed #8686: Update h264 to use new FFMPEG API
+
+---
+ channels/tsmf/client/ffmpeg/tsmf_ffmpeg.c | 2 ++
+ libfreerdp/codec/h264_ffmpeg.c | 2 ++
+ 2 files changed, 4 insertions(+)
+
+diff --git a/channels/tsmf/client/ffmpeg/tsmf_ffmpeg.c b/channels/tsmf/client/ffmpeg/tsmf_ffmpeg.c
+index 339462d865f..beea80b7a1e 100644
+--- a/channels/tsmf/client/ffmpeg/tsmf_ffmpeg.c
++++ b/channels/tsmf/client/ffmpeg/tsmf_ffmpeg.c
+@@ -239,8 +239,10 @@ static BOOL tsmf_ffmpeg_init_stream(ITSMFDecoder* decoder, const TS_AM_MEDIA_TYP
+ }
+ }
+
++#if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(59, 18, 100)
+ if (mdecoder->codec->capabilities & AV_CODEC_CAP_TRUNCATED)
+ mdecoder->codec_context->flags |= AV_CODEC_FLAG_TRUNCATED;
++#endif
+
+ return TRUE;
+ }
+diff --git a/libfreerdp/codec/h264_ffmpeg.c b/libfreerdp/codec/h264_ffmpeg.c
+index 8a23db2473c..896a333019b 100644
+--- a/libfreerdp/codec/h264_ffmpeg.c
++++ b/libfreerdp/codec/h264_ffmpeg.c
+@@ -615,10 +615,12 @@ static BOOL libavcodec_init(H264_CONTEXT* h264)
+ goto EXCEPTION;
+ }
+
++#if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(59, 18, 100)
+ if (sys->codecDecoder->capabilities & AV_CODEC_CAP_TRUNCATED)
+ {
+ sys->codecDecoderContext->flags |= AV_CODEC_FLAG_TRUNCATED;
+ }
++#endif
+
+ #ifdef WITH_VAAPI
+
diff --git a/srcpkgs/freerdp/template b/srcpkgs/freerdp/template
index 25e8aa9677f0..4d51c8189902 100644
--- a/srcpkgs/freerdp/template
+++ b/srcpkgs/freerdp/template
@@ -1,7 +1,7 @@
# Template file for 'freerdp'
pkgname=freerdp
version=2.10.0
-revision=1
+revision=2
build_style=cmake
configure_args="-DWITH_ALSA=ON -DWITH_CUPS=OFF -DWITH_FFMPEG=ON
-DWITH_GSTREAMER_0_10=OFF -DWITH_GSTREAMER_1_0=OFF -DWITH_JPEG=ON
From fed19b531c5934a2ada8401fa68e11eeeaae642b Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:47 -0400
Subject: [PATCH 037/113] gerbera: revbump for ffmpeg-6.0
---
srcpkgs/gerbera/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/gerbera/template b/srcpkgs/gerbera/template
index ae14f35c767c..2dc0ac0ce03b 100644
--- a/srcpkgs/gerbera/template
+++ b/srcpkgs/gerbera/template
@@ -1,7 +1,7 @@
# Template file for 'gerbera'
pkgname=gerbera
version=1.12.1
-revision=1
+revision=2
build_style=cmake
configure_args="-DWITH_SYSTEMD=0 -DWITH_AVCODEC=1"
hostmakedepends="pkg-config"
From 14e830a23cb53c2cf3e9b36efee7d095a76be1e2 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:47 -0400
Subject: [PATCH 038/113] goldendict: revbump for ffmpeg-6.0
---
srcpkgs/goldendict/patches/ffmpeg4.patch | 21 --
srcpkgs/goldendict/patches/ffmpeg5.patch | 232 +++++++++++++++++++++++
srcpkgs/goldendict/template | 2 +-
3 files changed, 233 insertions(+), 22 deletions(-)
delete mode 100644 srcpkgs/goldendict/patches/ffmpeg4.patch
create mode 100644 srcpkgs/goldendict/patches/ffmpeg5.patch
diff --git a/srcpkgs/goldendict/patches/ffmpeg4.patch b/srcpkgs/goldendict/patches/ffmpeg4.patch
deleted file mode 100644
index f045fa27f54b..000000000000
--- a/srcpkgs/goldendict/patches/ffmpeg4.patch
+++ /dev/null
@@ -1,21 +0,0 @@
---- a/ffmpegaudio.cc.orig 2018-05-09 22:16:13.480659958 +0200
-+++ b/ffmpegaudio.cc 2018-05-09 22:16:50.748322790 +0200
-@@ -143,7 +143,7 @@
- return false;
- }
-
-- unsigned char * avioBuffer = ( unsigned char * )av_malloc( kBufferSize + FF_INPUT_BUFFER_PADDING_SIZE );
-+ unsigned char * avioBuffer = ( unsigned char * )av_malloc( kBufferSize + AV_INPUT_BUFFER_PADDING_SIZE );
- if ( !avioBuffer )
- {
- errorString = QObject::tr( "av_malloc() failed." );
-@@ -380,7 +380,7 @@
- }
-
- if ( !Qt4x5::AtomicInt::loadAcquire( isCancelled_ ) &&
-- codecContext_->codec->capabilities & CODEC_CAP_DELAY )
-+ codecContext_->codec->capabilities & AV_CODEC_CAP_DELAY )
- {
- av_init_packet( &packet );
- int gotFrame = 0;
-
diff --git a/srcpkgs/goldendict/patches/ffmpeg5.patch b/srcpkgs/goldendict/patches/ffmpeg5.patch
new file mode 100644
index 000000000000..7cfc98ada368
--- /dev/null
+++ b/srcpkgs/goldendict/patches/ffmpeg5.patch
@@ -0,0 +1,232 @@
+From 03bbe01b79a1f07a6780cb60f23a087104c5d77b Mon Sep 17 00:00:00 2001
+From: Abs62 <ottomann@yandex.ru>
+Date: Fri, 30 Mar 2018 22:53:24 +0300
+Subject: [PATCH] Fix warnings while compile with FFMpeg 3.4.2 (issue #978)
+
+---
+ ffmpegaudio.cc | 68 +++++++++++++++++++++++++++++++++++++++++++++-----
+ 1 file changed, 62 insertions(+), 6 deletions(-)
+
+diff --git a/ffmpegaudio.cc b/ffmpegaudio.cc
+index ed1172bdd..56e8f788e 100644
+--- a/ffmpegaudio.cc
++++ b/ffmpegaudio.cc
+@@ -91,6 +91,7 @@ struct DecoderContext
+ QByteArray audioData_;
+ QDataStream audioDataStream_;
+ AVFormatContext * formatContext_;
++ AVCodec * codec_;
+ AVCodecContext * codecContext_;
+ AVIOContext * avioContext_;
+ AVStream * audioStream_;
+@@ -114,6 +115,7 @@ DecoderContext::DecoderContext( QByteArray const & audioData, QAtomicInt & isCan
+ audioData_( audioData ),
+ audioDataStream_( audioData_ ),
+ formatContext_( NULL ),
++ codec_( NULL ),
+ codecContext_( NULL ),
+ avioContext_( NULL ),
+ audioStream_( NULL ),
+@@ -143,7 +145,11 @@ bool DecoderContext::openCodec( QString & errorString )
+ return false;
+ }
+
++#if LIBAVCODEC_VERSION_MAJOR < 56 || ( LIBAVCODEC_VERSION_MAJOR == 56 && LIBAVCODEC_VERSION_MINOR < 56 )
+ unsigned char * avioBuffer = ( unsigned char * )av_malloc( kBufferSize + FF_INPUT_BUFFER_PADDING_SIZE );
++#else
++ unsigned char * avioBuffer = ( unsigned char * )av_malloc( kBufferSize + AV_INPUT_BUFFER_PADDING_SIZE );
++#endif
+ if ( !avioBuffer )
+ {
+ errorString = QObject::tr( "av_malloc() failed." );
+@@ -186,7 +192,11 @@ bool DecoderContext::openCodec( QString & errorString )
+ // Find audio stream, use the first audio stream if available
+ for ( unsigned i = 0; i < formatContext_->nb_streams; i++ )
+ {
++#if LIBAVCODEC_VERSION_MAJOR < 57 || ( LIBAVCODEC_VERSION_MAJOR == 57 && LIBAVCODEC_VERSION_MINOR < 33 )
+ if ( formatContext_->streams[i]->codec->codec_type == AVMEDIA_TYPE_AUDIO )
++#else
++ if ( formatContext_->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_AUDIO )
++#endif
+ {
+ audioStream_ = formatContext_->streams[i];
+ break;
+@@ -198,22 +208,38 @@ bool DecoderContext::openCodec( QString & errorString )
+ return false;
+ }
+
++#if LIBAVCODEC_VERSION_MAJOR < 57 || ( LIBAVCODEC_VERSION_MAJOR == 57 && LIBAVCODEC_VERSION_MINOR < 33 )
+ codecContext_ = audioStream_->codec;
+- AVCodec * codec = avcodec_find_decoder( codecContext_->codec_id );
+- if ( !codec )
++ codec_ = avcodec_find_decoder( codecContext_->codec_id );
++ if ( !codec_ )
+ {
+ errorString = QObject::tr( "Codec [id: %1] not found." ).arg( codecContext_->codec_id );
+ return false;
+ }
++#else
++ codec_ = avcodec_find_decoder( audioStream_->codecpar->codec_id );
++ if ( !codec_ )
++ {
++ errorString = QObject::tr( "Codec [id: %1] not found." ).arg( audioStream_->codecpar->codec_id );
++ return false;
++ }
++ codecContext_ = avcodec_alloc_context3( codec_ );
++ if ( !codecContext_ )
++ {
++ errorString = QObject::tr( "avcodec_alloc_context3() failed." );
++ return false;
++ }
++ avcodec_parameters_to_context( codecContext_, audioStream_->codecpar );
++#endif
+
+- ret = avcodec_open2( codecContext_, codec, NULL );
++ ret = avcodec_open2( codecContext_, codec_, NULL );
+ if ( ret < 0 )
+ {
+ errorString = QObject::tr( "avcodec_open2() failed: %1." ).arg( avErrorString( ret ) );
+ return false;
+ }
+
+- av_log( NULL, AV_LOG_INFO, "Codec open: %s: channels: %d, rate: %d, format: %s\n", codec->long_name,
++ av_log( NULL, AV_LOG_INFO, "Codec open: %s: channels: %d, rate: %d, format: %s\n", codec_->long_name,
+ codecContext_->channels, codecContext_->sample_rate, av_get_sample_fmt_name( codecContext_->sample_fmt ) );
+ return true;
+ }
+@@ -252,10 +278,13 @@ void DecoderContext::closeCodec()
+
+ // Closing a codec context without prior avcodec_open2() will result in
+ // a crash in ffmpeg
+- if ( audioStream_ && audioStream_->codec && audioStream_->codec->codec )
++ if ( audioStream_ && codecContext_ && codec_ )
+ {
+ audioStream_->discard = AVDISCARD_ALL;
+- avcodec_close( audioStream_->codec );
++ avcodec_close( codecContext_ );
++#if LIBAVCODEC_VERSION_MAJOR > 57 || ( LIBAVCODEC_VERSION_MAJOR == 57 && LIBAVCODEC_VERSION_MINOR >= 33 )
++ avcodec_free_context( &codecContext_ );
++#endif
+ }
+
+ avformat_close_input( &formatContext_ );
+@@ -356,6 +385,7 @@ bool DecoderContext::play( QString & errorString )
+ if ( packet.stream_index == audioStream_->index )
+ {
+ AVPacket pack = packet;
++#if LIBAVCODEC_VERSION_MAJOR < 57 || ( LIBAVCODEC_VERSION_MAJOR == 57 && LIBAVCODEC_VERSION_MINOR < 37 )
+ int gotFrame = 0;
+ do
+ {
+@@ -370,6 +400,19 @@ bool DecoderContext::play( QString & errorString )
+ pack.data += len;
+ }
+ while( pack.size > 0 );
++#else
++ int ret = avcodec_send_packet( codecContext_, &pack );
++ /* read all the output frames (in general there may be any number of them) */
++ while( ret >= 0 )
++ {
++ ret = avcodec_receive_frame( codecContext_, frame);
++
++ if ( Qt4x5::AtomicInt::loadAcquire( isCancelled_ ) || ret < 0 )
++ break;
++
++ playFrame( frame );
++ }
++#endif
+ }
+ // av_free_packet() must be called after each call to av_read_frame()
+ #if LIBAVCODEC_VERSION_MAJOR < 57 || ( LIBAVCODEC_VERSION_MAJOR == 57 && LIBAVCODEC_VERSION_MINOR < 7 )
+@@ -379,6 +422,7 @@ bool DecoderContext::play( QString & errorString )
+ #endif
+ }
+
++#if LIBAVCODEC_VERSION_MAJOR < 57 || ( LIBAVCODEC_VERSION_MAJOR == 57 && LIBAVCODEC_VERSION_MINOR < 37 )
+ if ( !Qt4x5::AtomicInt::loadAcquire( isCancelled_ ) &&
+ codecContext_->codec->capabilities & CODEC_CAP_DELAY )
+ {
+@@ -391,6 +435,18 @@ bool DecoderContext::play( QString & errorString )
+ playFrame( frame );
+ }
+ }
++#else
++ /* flush the decoder */
++ av_init_packet( &packet );
++ int ret = avcodec_send_packet(codecContext_, &packet );
++ while( ret >= 0 )
++ {
++ ret = avcodec_receive_frame(codecContext_, frame);
++ if ( Qt4x5::AtomicInt::loadAcquire( isCancelled_ ) || ret < 0 )
++ break;
++ playFrame( frame );
++ }
++#endif
+
+ #if LIBAVCODEC_VERSION_MAJOR < 54
+ av_free( frame );
+32
+srcpkgs/goldendict/patches/ffmpeg5-2.patch
+Comment on this file
+@@ -0,0 +1,32 @@
+From 966f4a8b78e6324b930e5a50f2bb930bd87e565e Mon Sep 17 00:00:00 2001
+From: Abs62 <ottomann@yandex.ru>
+Date: Fri, 27 Sep 2019 17:00:52 +0300
+Subject: [PATCH] FFmpeg player: Fix some crashes on broken files
+
+---
+ ffmpegaudio.cc | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/ffmpegaudio.cc b/ffmpegaudio.cc
+index 56e8f788e..415fc79cb 100644
+--- a/ffmpegaudio.cc
++++ b/ffmpegaudio.cc
+@@ -51,7 +51,9 @@ AudioService & AudioService::instance()
+
+ AudioService::AudioService()
+ {
++#if LIBAVFORMAT_VERSION_MAJOR < 58 || ( LIBAVFORMAT_VERSION_MAJOR == 58 && LIBAVFORMAT_VERSION_MINOR < 9 )
+ av_register_all();
++#endif
+ ao_initialize();
+ }
+
+@@ -438,6 +440,8 @@ bool DecoderContext::play( QString & errorString )
+ #else
+ /* flush the decoder */
+ av_init_packet( &packet );
++ packet.data = NULL;
++ packet.size = 0;
+ int ret = avcodec_send_packet(codecContext_, &packet );
+ while( ret >= 0 )
+ {
+25
+srcpkgs/goldendict/patches/ffmpeg5-3.patch
+Comment on this file
+@@ -0,0 +1,25 @@
+From 8acb288c9e9bdb3c6bf2e803954dd3b6ac273c05 Mon Sep 17 00:00:00 2001
+From: Liao Junxuan <mikeljx@126.com>
+Date: Sun, 20 Feb 2022 12:28:05 +0800
+Subject: [PATCH] add support for ffmpeg 5.0
+
+---
+ ffmpegaudio.cc | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/ffmpegaudio.cc b/ffmpegaudio.cc
+index d550f4a77..7948d2187 100644
+--- a/ffmpegaudio.cc
++++ b/ffmpegaudio.cc
+@@ -94,7 +94,11 @@ struct DecoderContext
+ QByteArray audioData_;
+ QDataStream audioDataStream_;
+ AVFormatContext * formatContext_;
++#if LIBAVCODEC_VERSION_MAJOR < 59
+ AVCodec * codec_;
++#else
++ const AVCodec * codec_;
++#endif
+ AVCodecContext * codecContext_;
+ AVIOContext * avioContext_;
+ AVStream * audioStream_;
diff --git a/srcpkgs/goldendict/template b/srcpkgs/goldendict/template
index 4544ae710ee6..2ca4185e538a 100644
--- a/srcpkgs/goldendict/template
+++ b/srcpkgs/goldendict/template
@@ -9,7 +9,7 @@ makedepends="tiff-devel qt5-devel libvorbis-devel zlib-devel
libXtst-devel hunspell-devel qt5-tools-devel qt5-declarative-devel
qt5-webkit-devel lzo-devel bzip2-devel libao-devel qt5-svg-devel
libeb-devel qt5-x11extras-devel ffmpeg-devel liblzma-devel"
-short_desc="A feature-rich dictionary lookup program"
+short_desc="Feature-rich dictionary lookup program"
maintainer="John <me@johnnynator.dev>"
license="GPL-3.0-or-later"
homepage="http://goldendict.org/"
From f414f6a7f00e7483255eba780ae37452d68f8c7e Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:47 -0400
Subject: [PATCH 039/113] gst-libav: revbump for ffmpeg-6.0
---
srcpkgs/gst-libav/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/gst-libav/template b/srcpkgs/gst-libav/template
index e9a79dc650a5..f082bd211c65 100644
--- a/srcpkgs/gst-libav/template
+++ b/srcpkgs/gst-libav/template
@@ -1,7 +1,7 @@
# Template file for 'gst-libav'
pkgname=gst-libav
version=1.20.3
-revision=1
+revision=2
build_style=meson
hostmakedepends="pkg-config yasm"
makedepends="orc-devel gst-plugins-base1-devel ffmpeg-devel"
From afa41e7a2a57f2aafc9f8e8cf19cc2bf84dbbba4 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:47 -0400
Subject: [PATCH 040/113] gst-plugins-bad1: revbump for ffmpeg-6.0
---
srcpkgs/gst-plugins-bad1/template | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/srcpkgs/gst-plugins-bad1/template b/srcpkgs/gst-plugins-bad1/template
index f55f82fd4c77..dc9d389734e1 100644
--- a/srcpkgs/gst-plugins-bad1/template
+++ b/srcpkgs/gst-plugins-bad1/template
@@ -1,7 +1,7 @@
# Template file for 'gst-plugins-bad1'
pkgname=gst-plugins-bad1
-version=1.20.3
-revision=3
+version=1.22.2
+revision=2
build_helper="gir"
build_style=meson
configure_args="-Dpackage-origin=https://voidlinux.org -Ddoc=disabled
From bc0672c386d341fa0403d1e36ccdce31b6cdabdb Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:47 -0400
Subject: [PATCH 041/113] gst-rtsp-server: revbump for ffmpeg-6.0
---
srcpkgs/gst-rtsp-server/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/gst-rtsp-server/template b/srcpkgs/gst-rtsp-server/template
index 33cd64ceb95e..8ceea8d34b4b 100644
--- a/srcpkgs/gst-rtsp-server/template
+++ b/srcpkgs/gst-rtsp-server/template
@@ -1,7 +1,7 @@
# Template file for 'gst-rtsp-server'
pkgname=gst-rtsp-server
version=1.20.3
-revision=2
+revision=3
build_style=meson
hostmakedepends="pkg-config python3"
makedepends="glib-devel gst-plugins-bad1-devel gobject-introspection
From 09ebfd5b75e04da3ec2f8dd83af6e0ddce34f605 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:47 -0400
Subject: [PATCH 042/113] guvcview: update to 2.0.8.
---
srcpkgs/guvcview/patches/fix-include.patch | 10 ++++++++++
srcpkgs/guvcview/template | 5 ++---
2 files changed, 12 insertions(+), 3 deletions(-)
create mode 100644 srcpkgs/guvcview/patches/fix-include.patch
diff --git a/srcpkgs/guvcview/patches/fix-include.patch b/srcpkgs/guvcview/patches/fix-include.patch
new file mode 100644
index 000000000000..503c2af3b78c
--- /dev/null
+++ b/srcpkgs/guvcview/patches/fix-include.patch
@@ -0,0 +1,10 @@
+--- a/guvcview/guvcview.c
++++ b/guvcview/guvcview.c
+@@ -28,6 +28,7 @@
+ #include <sys/stat.h>
+ #include <sys/resource.h>
+ #include <errno.h>
++#include <locale.h>
+
+ #include "gview.h"
+ #include "gviewv4l2core.h"
diff --git a/srcpkgs/guvcview/template b/srcpkgs/guvcview/template
index 345cf6006f24..86a7fd619612 100644
--- a/srcpkgs/guvcview/template
+++ b/srcpkgs/guvcview/template
@@ -1,8 +1,7 @@
# Template file for 'guvcview'
pkgname=guvcview
-version=2.0.7
+version=2.0.8
revision=1
-create_wrksrc=yes
build_style=gnu-configure
configure_args="--disable-static --disable-debian-menu"
hostmakedepends="pkg-config intltool autoconf automake libtool glib-devel"
@@ -14,7 +13,7 @@ maintainer="Orphaned <orphan@voidlinux.org>"
license="GPL-3.0-or-later"
homepage="http://guvcview.sourceforge.net/"
distfiles="${SOURCEFORGE_SITE}/${pkgname}/${pkgname}-src-${version}.tar.bz2"
-checksum=f47d51fbd06e44eeaa1a82f4a153c927527c90d94514197a70b2956028cc8ad4
+checksum=a21f4e448286666cf27bafef5290cc953a0a1796b752e5bbe521266dc1230c81
post_patch() {
sed '31a#include <locale.h>' -i guvcview/guvcview.c
From ac5f7f4f9bb7730e3bc2c32050c1758b2ea994df Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:48 -0400
Subject: [PATCH 043/113] handbrake: update to 1.6.1
---
.../patches/fix-missing-x265-link-flag.patch | 11 ++++++-----
.../handbrake/patches/libhb-vpl-include.patch | 15 +++++++++++++++
srcpkgs/handbrake/template | 17 ++++++++++-------
3 files changed, 31 insertions(+), 12 deletions(-)
create mode 100644 srcpkgs/handbrake/patches/libhb-vpl-include.patch
diff --git a/srcpkgs/handbrake/patches/fix-missing-x265-link-flag.patch b/srcpkgs/handbrake/patches/fix-missing-x265-link-flag.patch
index 26db03867a0c..d6bb2eda627a 100644
--- a/srcpkgs/handbrake/patches/fix-missing-x265-link-flag.patch
+++ b/srcpkgs/handbrake/patches/fix-missing-x265-link-flag.patch
@@ -1,14 +1,15 @@
--- a/gtk/configure.ac
+++ b/gtk/configure.ac
@@ -203,7 +203,7 @@
-
+
AM_CONDITIONAL([MINGW], [test "x$mingw_flag" = "xyes"])
-
--HB_LIBS="$HB_LIBS -lhandbrake -lavformat -lavfilter -lavcodec -lavutil -ldav1d -lswresample -lpostproc -ldvdnav -ldvdread -lmp3lame -lvorbis -lvorbisenc -logg -lswscale -ltheoraenc -ltheoradec -lvpx -lz -lbz2 -lbluray -lass -lfontconfig -lfreetype -lxml2 -ljansson -lopus -lspeex -lturbojpeg -llzma -lzimg"
-+HB_LIBS="$HB_LIBS -lhandbrake -lavformat -lavfilter -lavcodec -lavutil -ldav1d -lswresample -lpostproc -ldvdnav -ldvdread -lmp3lame -lvorbis -lvorbisenc -logg -lswscale -ltheoraenc -ltheoradec -lvpx -lz -lbz2 -lbluray -lass -lfontconfig -lfreetype -lxml2 -ljansson -lopus -lspeex -lturbojpeg -llzma -lzimg -ldl"
+
+-HB_LIBS="$HB_LIBS -lhandbrake -lavformat -lavfilter -lavcodec -lavutil -ldav1d -lswresample -lpostproc -ldvdnav -ldvdread -lmp3lame -lvorbis -lvorbisenc -logg -lswscale -ltheoraenc -ltheoradec -lvpx -lz -lbz2 -lbluray -lass -lfontconfig -lfreetype -lxml2 -ljansson -lopus -lspeex -lturbojpeg -llzma -lzimg -lSvtAv1Enc"
++HB_LIBS="$HB_LIBS -lhandbrake -lavformat -lavfilter -lavcodec -lavutil -ldav1d -lswresample -lpostproc -ldvdnav -ldvdread -lmp3lame -lvorbis -lvorbisenc -logg -lswscale -ltheoraenc -ltheoradec -lvpx -lz -lbz2 -lbluray -lass -lfontconfig -lfreetype -lxml2 -ljansson -lopus -lspeex -lturbojpeg -llzma -lzimg -lSvtAv1Enc -ldl"
HB_CPPFLAGS="$HB_CPPFLAGS $HBINC"
-
+
PKG_CHECK_MODULES([x264], [x264], sys_x264=yes, sys_x264=no)
+
--- a/test/module.defs
+++ b/test/module.defs
@@ -69,6 +69,9 @@
diff --git a/srcpkgs/handbrake/patches/libhb-vpl-include.patch b/srcpkgs/handbrake/patches/libhb-vpl-include.patch
new file mode 100644
index 000000000000..298f9f4ab28f
--- /dev/null
+++ b/srcpkgs/handbrake/patches/libhb-vpl-include.patch
@@ -0,0 +1,15 @@
+--- a/libhb/module.defs 2023-01-22 11:36:49.000000000 -0500
++++ b/libhb/module.defs 2023-04-03 22:37:52.395467010 -0400
+@@ -46,11 +46,7 @@
+ LIBHB.GCC.I += $(LIBHB.build/) $(CONTRIB.build/)include
+
+ ifeq (1,$(FEATURE.qsv))
+- ifeq ($(HOST.system),freebsd))
+- LIBHB.GCC.I += $(LOCALBASE)/include/vpl
+- else
+- LIBHB.GCC.I += $(CONTRIB.build/)include/vpl
+- endif
++ LIBHB.GCC.I += /usr/include/vpl
+ endif
+
+ ifneq (,$(filter $(HOST.system),freebsd netbsd openbsd))
diff --git a/srcpkgs/handbrake/template b/srcpkgs/handbrake/template
index ca5e4571e49c..c32cb1bfa31f 100644
--- a/srcpkgs/handbrake/template
+++ b/srcpkgs/handbrake/template
@@ -1,10 +1,10 @@
# Template file for 'handbrake'
pkgname=handbrake
-version=1.5.1
+version=1.6.1
revision=1
build_style=gnu-configure
configure_args="--force --disable-gtk-update-checks --disable-df-fetch --harden
- $(vopt_enable fdk_aac fdk-aac) $(vopt_enable nvenc)"
+ $(vopt_enable fdk_aac fdk-aac) $(vopt_enable nvenc) $(vopt_enable qsv)"
make_build_args="-C ${XBPS_TRIPLET}"
make_install_args="-C ${XBPS_TRIPLET}"
hostmakedepends="automake cmake gettext-devel glib-devel intltool libtool m4 meson nasm pkg-config python3"
@@ -12,8 +12,11 @@ makedepends="bzip2-devel ffmpeg-devel gst-plugins-base1-devel gtk+3-devel
jansson-devel lame-devel libass-devel libbluray-devel libdav1d-devel
libdvdnav-devel libdvdread-devel libgudev-devel libnuma-devel
libsamplerate-devel libtheora-devel libvorbis-devel libvpx-devel libxml2-devel
- opus-devel speex-devel x264-devel x265-devel zimg-devel
+ opus-devel speex-devel x264-devel x265-devel zimg-devel libsvt-av1-devel
$(vopt_if fdk_aac fdk-aac-devel)
+ $(vopt_if qsv libva-devel)
+ $(vopt_if qsv libdrm-devel)
+ $(vopt_if qsv onevpl-devel)
$(vopt_if nvenc nv-codec-headers)"
depends="desktop-file-utils gst-plugins-good1 hicolor-icon-theme"
short_desc="Multithreaded video transcoder"
@@ -21,15 +24,15 @@ maintainer="Enno Boland <gottox@voidlinux.org>"
license="GPL-2.0-only"
homepage="https://handbrake.fr/"
distfiles="https://github.com/HandBrake/HandBrake/releases/download/${version}/HandBrake-${version}-source.tar.bz2"
-checksum=3999fe06d5309c819799a73a968a8ec3840e7840c2b64af8f5cdb7fd8c9430f0
+checksum=94ccfe03db917a91650000c510f7fd53f844da19f19ad4b4be1b8f6bc31a8d4c
nocross=yes
-build_options="fdk_aac nvenc"
+build_options="fdk_aac nvenc qsv"
case "$XBPS_TARGET_MACHINE" in
x86_64*|i686*)
CFLAGS="-msse"
- build_options_default="nvenc"
+ build_options_default="nvenc qsv"
;;
esac
@@ -37,7 +40,7 @@ pre_configure() {
# use system libraries, don't download them
rm -rf contrib/
for module in fdk-aac ffmpeg libbluray libdav1d libdvdnav libdvdread nvenc \
- x265 zimg; do
+ x265 zimg svt-av1 libvpl; do
vsed -i "/MODULES += contrib\/${module}/d" make/include/main.defs
done
}
From c977407b468a0a18e120caefbee9a0c25f209707 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:48 -0400
Subject: [PATCH 044/113] hedgewars: revbump for ffmpeg4-4.4.3
---
srcpkgs/hedgewars/template | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/srcpkgs/hedgewars/template b/srcpkgs/hedgewars/template
index 419f29b98b44..926fe4fe3e68 100644
--- a/srcpkgs/hedgewars/template
+++ b/srcpkgs/hedgewars/template
@@ -1,13 +1,13 @@
# Template file for 'hedgewars'
pkgname=hedgewars
version=1.0.2
-revision=1
+revision=2
build_style=cmake
configure_args="-DNOSERVER=1 -DDATA_INSTALL_DIR=/usr/share/${pkgname}
-DPHYSFS_SYSTEM=1 -DMINIMAL_FLAGS=1"
make_cmd=make
hostmakedepends="lua51 pkg-config qt5-qmake qt5-host-tools"
-makedepends="ffmpeg-devel lua51-devel physfs-devel qt5-tools-devel SDL2_image-devel
+makedepends="ffmpeg4-devel lua51-devel physfs-devel qt5-tools-devel SDL2_image-devel
SDL2_mixer-devel SDL2_net-devel SDL2_ttf-devel"
depends="libfreeglut"
short_desc="Funny turn-based artillery game, featuring fighting Hedgehogs!"
From 8538d8a0d5b91779361e7d5799a7a5d98f14ef65 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:48 -0400
Subject: [PATCH 045/113] idjc: revbump for ffmpeg4-4.4.3
---
srcpkgs/idjc/template | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/srcpkgs/idjc/template b/srcpkgs/idjc/template
index df60318b3db9..36a75baf597c 100644
--- a/srcpkgs/idjc/template
+++ b/srcpkgs/idjc/template
@@ -1,11 +1,11 @@
# Template file for 'idjc'
pkgname=idjc
version=0.9.1
-revision=3
+revision=4
build_style=gnu-configure
hostmakedepends="pkg-config git python3 automake gettext-devel libtool"
makedepends="libvorbis-devel libogg-devel jack-devel libsamplerate-devel
- libflac-devel libsndfile-devel mpg123-devel ffmpeg-devel speex-devel
+ libflac-devel libsndfile-devel mpg123-devel ffmpeg4-devel speex-devel
glib-devel pixman-devel lame-devel python3-gobject-devel libshout-idjc-devel
opus-devel twolame-devel python3-mutagen python3-devel"
depends="python3-gobject python3-mutagen desktop-file-utils shared-mime-info python3-dbus jack"
From fb489f4ca059a5af8bab7f6531476ea4c9af8a52 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:48 -0400
Subject: [PATCH 046/113] kfilemetadata5: revbump for ffmpeg-6.0
---
srcpkgs/kfilemetadata5/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/kfilemetadata5/template b/srcpkgs/kfilemetadata5/template
index 8980121fbc69..f662a2043f93 100644
--- a/srcpkgs/kfilemetadata5/template
+++ b/srcpkgs/kfilemetadata5/template
@@ -1,7 +1,7 @@
# Template file for 'kfilemetadata5'
pkgname=kfilemetadata5
version=5.105.0
-revision=1
+revision=2
build_style=cmake
hostmakedepends="kcoreaddons extra-cmake-modules pkg-config qt5-host-tools qt5-qmake
gettext kcoreaddons python3"
From 9d82756c8286c2c2784e6efc62078decee54e7c2 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:48 -0400
Subject: [PATCH 047/113] kid3: revbump for ffmpeg-6.0
---
srcpkgs/kid3/patches/ffmpeg5.patch | 17 +++++++++++++++++
srcpkgs/kid3/template | 2 +-
2 files changed, 18 insertions(+), 1 deletion(-)
create mode 100644 srcpkgs/kid3/patches/ffmpeg5.patch
diff --git a/srcpkgs/kid3/patches/ffmpeg5.patch b/srcpkgs/kid3/patches/ffmpeg5.patch
new file mode 100644
index 000000000000..135fc50e07c9
--- /dev/null
+++ b/srcpkgs/kid3/patches/ffmpeg5.patch
@@ -0,0 +1,17 @@
+# https://aur.archlinux.org/cgit/aur.git/diff/ffmpeg5.patch?h=kid3-cli&id=12410a74906612e7efc0ec8fbce739b4a0fef7e7
+diff --git a/src/plugins/acoustidimport/ffmpegfingerprintdecoder.cpp b/src/plugins/acoustidimport/ffmpegfingerprintdecoder.cpp
+index e156d424..e12b9abd 100644
+--- a/src/plugins/acoustidimport/ffmpegfingerprintdecoder.cpp
++++ b/src/plugins/acoustidimport/ffmpegfingerprintdecoder.cpp
+@@ -232,7 +232,11 @@ private:
+ friend class Format;
+ friend class Converter;
+ AVCodecContext* m_ptr;
++#if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(59, 0, 0)
+ AVCodec* m_impl;
++#else
++ const AVCodec* m_impl;
++#endif
+ AVFrame* m_frame;
+ bool m_opened;
+ };
diff --git a/srcpkgs/kid3/template b/srcpkgs/kid3/template
index 456206d90e16..f32f9decb0e7 100644
--- a/srcpkgs/kid3/template
+++ b/srcpkgs/kid3/template
@@ -1,7 +1,7 @@
# Template file for 'kid3'
pkgname=kid3
version=3.9.1
-revision=2
+revision=3
build_style=cmake
configure_args="-DWITH_APPS='CLI;$(vopt_if KDE KDE Qt)'
-DWITH_DOCBOOKDIR=/usr/share/xsl/docbook -DWITH_FLAC=$(vopt_if flac ON OFF)
From ac6ea4392514528e8de733d0c4e31e4db9c618f6 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:48 -0400
Subject: [PATCH 048/113] kodi: revbump for ffmpeg4-4.4.3
---
srcpkgs/kodi/template | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/srcpkgs/kodi/template b/srcpkgs/kodi/template
index 8057964d78a3..6cc1874be7ba 100644
--- a/srcpkgs/kodi/template
+++ b/srcpkgs/kodi/template
@@ -1,7 +1,7 @@
# Template file for 'kodi'
pkgname=kodi
version=19.4
-revision=6
+revision=7
_codename="Matrix"
build_style=cmake
configure_args="-DWITH_FFMPEG=/usr -DENABLE_LDGOLD=OFF
@@ -54,7 +54,7 @@ makedepends="
libmad-devel fontconfig-devel libXinerama-devel libsamplerate-devel libmms-devel
enca-devel boost-devel libcurl-devel libva-devel libvdpau-devel libass-devel
libbluetooth-devel yajl-devel libplist-devel librtmp-devel tinyxml-devel
- taglib-devel libcap-devel lame-devel libbluray-devel libnfs-devel ffmpeg-devel
+ taglib-devel libcap-devel lame-devel libbluray-devel libnfs-devel ffmpeg4-devel
giflib-devel libxslt-devel gnutls-devel libssh-devel libmicrohttpd-devel
libcec-devel dcadec-devel flatbuffers-devel fmt-devel lcms2-devel
libfstrcmp-devel rapidjson libcdio-paranoia spdlog libwaylandpp-devel
From b04e2d2ce923099980f0a0b0f8e5f7ddc521ac0b Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:48 -0400
Subject: [PATCH 049/113] kpipewire: revbump for ffmpeg-6.0
---
srcpkgs/kpipewire/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/kpipewire/template b/srcpkgs/kpipewire/template
index 467ab823a5e1..51827f24db9e 100644
--- a/srcpkgs/kpipewire/template
+++ b/srcpkgs/kpipewire/template
@@ -1,7 +1,7 @@
# Template file for 'kpipewire'
pkgname=kpipewire
version=5.27.4
-revision=1
+revision=2
build_style=cmake
hostmakedepends="extra-cmake-modules plasma-wayland-protocols gettext
qt5-qmake qt5-host-tools pkg-config wayland-devel kcoreaddons
From a976f1db88006029cd6781dc39d9e4c180bbc34c Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:48 -0400
Subject: [PATCH 050/113] libextractor: revbump for ffmpeg4-4.4.3
---
srcpkgs/libextractor/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/libextractor/template b/srcpkgs/libextractor/template
index ddd4790f93e8..1fb9ca56a96a 100644
--- a/srcpkgs/libextractor/template
+++ b/srcpkgs/libextractor/template
@@ -7,7 +7,7 @@ configure_args="--disable-static"
hostmakedepends="pkg-config"
makedepends="zlib-devel bzip2-devel exiv2-devel tiff-devel libpng-devel
libjpeg-turbo-devel libvorbis-devel libflac-devel giflib-devel libmpeg2-devel
- ffmpeg-devel gtk+3-devel libltdl-devel libarchive-devel file-devel libgsf-devel"
+ ffmpeg4-devel gtk+3-devel libltdl-devel libarchive-devel file-devel libgsf-devel"
short_desc="Library used to extract meta data from files"
maintainer="Martin Riese <grauehaare@gmx.de>"
license="GPL-3.0-or-later"
From 759165a0bd96f98da94279facbe87e56bf8e2406 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:48 -0400
Subject: [PATCH 051/113] libopenal: revbump for ffmpeg-6.0
---
srcpkgs/libopenal/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/libopenal/template b/srcpkgs/libopenal/template
index 77218f9e539d..3f49ed75a1fd 100644
--- a/srcpkgs/libopenal/template
+++ b/srcpkgs/libopenal/template
@@ -1,7 +1,7 @@
# Template file for 'libopenal'
pkgname=libopenal
version=1.22.2
-revision=1
+revision=2
build_style=cmake
configure_args="-DALSOFT_EXAMPLES=OFF"
hostmakedepends="pkg-config"
From 4e11aa0b8cc515ac4d453fc0cbbb518a3bb43c65 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:48 -0400
Subject: [PATCH 052/113] libopenshot: revbump for ffmpeg-6.0
---
srcpkgs/libopenshot/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/libopenshot/template b/srcpkgs/libopenshot/template
index db831f69b474..81aa0d7136d9 100644
--- a/srcpkgs/libopenshot/template
+++ b/srcpkgs/libopenshot/template
@@ -1,7 +1,7 @@
# Template file for 'libopenshot'
pkgname=libopenshot
version=0.3.0
-revision=1
+revision=2
build_style=cmake
# Builds fail with Ruby-2.4.1
configure_args="-DENABLE_RUBY=OFF -DUSE_SYSTEM_JSONCPP=ON"
From b9a1bab81e45cab475ff5a9247a88032e8c9fb3a Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:48 -0400
Subject: [PATCH 053/113] loudgain: revbump for ffmpeg-6.0
---
srcpkgs/loudgain/patches/ffmpeg5.patch | 11 +++++++++++
srcpkgs/loudgain/template | 2 +-
2 files changed, 12 insertions(+), 1 deletion(-)
create mode 100644 srcpkgs/loudgain/patches/ffmpeg5.patch
diff --git a/srcpkgs/loudgain/patches/ffmpeg5.patch b/srcpkgs/loudgain/patches/ffmpeg5.patch
new file mode 100644
index 000000000000..16d4510ee98f
--- /dev/null
+++ b/srcpkgs/loudgain/patches/ffmpeg5.patch
@@ -0,0 +1,11 @@
+--- a/src/scan.c 2019-09-06 11:31:19.000000000 -0400
++++ b/src/scan.c 2023-03-23 11:15:40.867968521 -0400
+@@ -69,8 +69,6 @@
+ * It is now useless
+ * https://github.com/FFmpeg/FFmpeg/blob/70d25268c21cbee5f08304da95be1f647c630c15/doc/APIchanges#L86
+ */
+- if (avformat_version() < AV_VERSION_INT(58,9,100))
+- av_register_all();
+
+ av_log_set_callback(scan_av_log);
+
diff --git a/srcpkgs/loudgain/template b/srcpkgs/loudgain/template
index da4f2d56e94c..4d6bf29efb4f 100644
--- a/srcpkgs/loudgain/template
+++ b/srcpkgs/loudgain/template
@@ -1,7 +1,7 @@
# Template file for 'loudgain'
pkgname=loudgain
version=0.6.8
-revision=2
+revision=3
build_style=cmake
hostmakedepends="pkg-config"
makedepends="libebur128-devel taglib-devel ffmpeg-devel"
From 93c971e5dc9f21e91f136ed83262a2bc32809b19 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:48 -0400
Subject: [PATCH 054/113] mediastreamer: revbump for ffmpeg4-4.4.3
---
srcpkgs/mediastreamer/template | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/srcpkgs/mediastreamer/template b/srcpkgs/mediastreamer/template
index d0e97e858e29..1bde031443a5 100644
--- a/srcpkgs/mediastreamer/template
+++ b/srcpkgs/mediastreamer/template
@@ -1,11 +1,11 @@
# Template file for 'mediastreamer'
pkgname=mediastreamer
version=5.2.6
-revision=1
+revision=2
build_style=cmake
configure_args="-DENABLE_STRICT=0 -DENABLE_UNIT_TESTS=0"
hostmakedepends="python3"
-makedepends="bzrtp-devel ffmpeg-devel glew-devel libXv-devel libsrtp-devel
+makedepends="bzrtp-devel ffmpeg4-devel glew-devel libXv-devel libsrtp-devel
libupnp-devel libvpx-devel mbedtls-devel opus-devel ortp-devel pulseaudio-devel
libtheora-devel speex-devel v4l-utils-devel bcg729-devel bcmatroska2-devel libgsm-devel"
# zxing-cpp-devel (1.2.0 probably not compatible, check again after updaing xzing)
From a7398921fd507cc4f99d9ac405b5365a7a9dec71 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:48 -0400
Subject: [PATCH 055/113] mgba: revbump for ffmpeg-6.0
---
srcpkgs/mgba/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/mgba/template b/srcpkgs/mgba/template
index ae0504311eee..d31295a0cd3d 100644
--- a/srcpkgs/mgba/template
+++ b/srcpkgs/mgba/template
@@ -1,7 +1,7 @@
# Template file for 'mgba'
pkgname=mgba
version=0.10.2
-revision=1
+revision=2
build_style=cmake
hostmakedepends="pkg-config qt5-host-tools qt5-qmake desktop-file-utils"
makedepends="SDL2-devel ffmpeg-devel libedit-devel libepoxy-devel libmagick-devel
From 383c3ed41f29b18fb0f53b5af90962affcadc6e2 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:48 -0400
Subject: [PATCH 056/113] minidlna: revbump for ffmpeg-6.0
---
srcpkgs/minidlna/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/minidlna/template b/srcpkgs/minidlna/template
index e8081b1cbc67..9ee9714861fd 100644
--- a/srcpkgs/minidlna/template
+++ b/srcpkgs/minidlna/template
@@ -1,7 +1,7 @@
# Template file for 'minidlna'
pkgname=minidlna
version=1.3.2
-revision=1
+revision=2
build_style=gnu-configure
configure_args="
--sbindir=/usr/bin
From 69e08351149d93b98af6d905a3a14080653d0e5e Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:49 -0400
Subject: [PATCH 057/113] mixxx: revbump for ffmpeg-6.0
---
srcpkgs/mixxx/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/mixxx/template b/srcpkgs/mixxx/template
index 619ddca0d332..4b9ea00d3fb3 100644
--- a/srcpkgs/mixxx/template
+++ b/srcpkgs/mixxx/template
@@ -1,7 +1,7 @@
# Template file for 'mixxx'
pkgname=mixxx
version=2.3.3
-revision=1
+revision=2
build_style=cmake
configure_args="-DCMAKE_BUILD_TYPE=Release"
hostmakedepends="extra-cmake-modules pkg-config protobuf qt5-host-tools qt5-devel"
From 339268db1683a15859ce21a8cdcd55675ebc52bc Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:49 -0400
Subject: [PATCH 058/113] mlt: revbump for ffmpeg4-4.4.3
---
srcpkgs/mlt/template | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/srcpkgs/mlt/template b/srcpkgs/mlt/template
index 8933eb4e7bb9..73353fedafb5 100644
--- a/srcpkgs/mlt/template
+++ b/srcpkgs/mlt/template
@@ -1,14 +1,14 @@
# Template file for 'mlt'
pkgname=mlt
version=6.26.1
-revision=1
+revision=2
build_style=configure
configure_args="--prefix=/usr --libdir=/usr/lib$XBPS_TARGET_WORDSIZE
--enable-gpl --enable-gpl3 --disable-swfdec --without-kde
--swig-languages=python"
hostmakedepends="doxygen pkg-config ladspa-sdk swig python3 which"
# XXX: movit vid.stab
-makedepends="alsa-lib-devel ffmpeg-devel gtk+-devel jack-devel ladspa-sdk
+makedepends="alsa-lib-devel ffmpeg4-devel gtk+-devel jack-devel ladspa-sdk
libexif-devel libsamplerate-devel libxml2-devel sox-devel SDL_image-devel
fftw-devel frei0r-plugins python3-devel pulseaudio-devel movit-devel
libvidstab-devel libatomic-devel"
From 1dcf923887aa8125a2e5463058a63049db5b4bbb Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:49 -0400
Subject: [PATCH 059/113] moc: revbump for ffmpeg4-4.4.3
---
srcpkgs/moc/template | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/srcpkgs/moc/template b/srcpkgs/moc/template
index c42be650a1d2..d4f0eefbad52 100644
--- a/srcpkgs/moc/template
+++ b/srcpkgs/moc/template
@@ -1,10 +1,10 @@
# Template file for 'moc'
pkgname=moc
version=2.5.2
-revision=6
+revision=7
build_style=gnu-configure
hostmakedepends="pkg-config"
-makedepends="db-devel ncurses-devel libcurl-devel popt-devel ffmpeg-devel
+makedepends="db-devel ncurses-devel libcurl-devel popt-devel ffmpeg4-devel
jack-devel alsa-lib-devel libltdl-devel libflac-devel libvorbis-devel
libmad-devel libmpcdec-devel libmodplug-devel libid3tag-devel faad2-devel
taglib-devel libsndfile-devel wavpack-devel speex-devel libsamplerate-devel
From d23376c278c137073dbd451de087d06b752e01f7 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:49 -0400
Subject: [PATCH 060/113] motion: revbump for ffmpeg-6.0
---
srcpkgs/motion/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/motion/template b/srcpkgs/motion/template
index 3cf3c3035c5b..7dca12d851e3 100644
--- a/srcpkgs/motion/template
+++ b/srcpkgs/motion/template
@@ -1,7 +1,7 @@
# Template file for 'motion'
pkgname=motion
version=4.5.1
-revision=1
+revision=2
build_style=gnu-configure
hostmakedepends="automake pkg-config gettext-devel tar"
makedepends="ffmpeg-devel libmicrohttpd-devel v4l-utils-devel gettext-devel"
From 7d055b7a079c04ced1c8a67567b03311f475ad2e Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:49 -0400
Subject: [PATCH 061/113] mpv: revbump for ffmpeg-6.0
---
srcpkgs/mpv/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/mpv/template b/srcpkgs/mpv/template
index e163c496c6eb..d4fefbf5e3c7 100644
--- a/srcpkgs/mpv/template
+++ b/srcpkgs/mpv/template
@@ -1,7 +1,7 @@
# Template file for 'mpv'
pkgname=mpv
version=0.35.1
-revision=2
+revision=3
build_style=meson
configure_args="-Dcdda=enabled -Ddvbin=enabled -Ddvdnav=enabled
-Dlibmpv=true -Dcplugins=enabled
From fe527a863bd958c1591544338d983cd9fcd62455 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:49 -0400
Subject: [PATCH 062/113] musikcube: revbump for ffmpeg-6.0
---
srcpkgs/musikcube/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/musikcube/template b/srcpkgs/musikcube/template
index 7c569303c054..a4dea460c371 100644
--- a/srcpkgs/musikcube/template
+++ b/srcpkgs/musikcube/template
@@ -1,7 +1,7 @@
# Template file for 'musikcube'
pkgname=musikcube
version=3.0.0
-revision=1
+revision=2
build_style=cmake
make_cmd=make
configure_args="-DNO_NCURSESW=1"
From e88f6b56be144d38ed94d2cfd21b7a343866839b Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:49 -0400
Subject: [PATCH 063/113] notcurses: revbump for ffmpeg-6.0
---
srcpkgs/notcurses/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/notcurses/template b/srcpkgs/notcurses/template
index 6dd8a091319f..3110c30c9aff 100644
--- a/srcpkgs/notcurses/template
+++ b/srcpkgs/notcurses/template
@@ -1,7 +1,7 @@
# Template file for 'notcurses'
pkgname=notcurses
version=3.0.9
-revision=1
+revision=2
build_style=cmake
configure_args="-DUSE_STATIC=ON $(vopt_bool man USE_PANDOC)"
hostmakedepends="pkg-config $(vopt_if man pandoc)"
From 948eb108acbe600687863968224b6bc66d589382 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:49 -0400
Subject: [PATCH 064/113] obs: revbump for ffmpeg-6.0
---
srcpkgs/obs/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/obs/template b/srcpkgs/obs/template
index 7ee29ff3eac6..fd06df415301 100644
--- a/srcpkgs/obs/template
+++ b/srcpkgs/obs/template
@@ -1,7 +1,7 @@
# Template file for 'obs'
pkgname=obs
version=29.1.1
-revision=1
+revision=2
archs="i686* x86_64* ppc64le* aarch64*"
build_style=cmake
configure_args="-DOBS_VERSION_OVERRIDE=${version} -DENABLE_JACK=ON
From 642b1d475b863462e185aef8c317136d32fe2b83 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:49 -0400
Subject: [PATCH 065/113] olive: revbump for ffmpeg4-4.4.3
---
srcpkgs/olive/template | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/srcpkgs/olive/template b/srcpkgs/olive/template
index 12a46936c990..5c2917b9c512 100644
--- a/srcpkgs/olive/template
+++ b/srcpkgs/olive/template
@@ -1,10 +1,10 @@
# Template file for 'olive'
pkgname=olive
version=0.1.2
-revision=2
+revision=3
build_style=qmake
hostmakedepends="qt5-qmake qt5-host-tools pkg-config"
-makedepends="qt5-devel qt5-multimedia-devel qt5-svg-devel ffmpeg-devel frei0r-plugins"
+makedepends="qt5-devel qt5-multimedia-devel qt5-svg-devel ffmpeg4-devel frei0r-plugins"
short_desc="Non-linear video editor"
maintainer="Orphaned <orphan@voidlinux.org>"
license="GPL-3.0-or-later"
From 5e34fa4b95402f61dc12ec764758bdaa446fd3f5 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:49 -0400
Subject: [PATCH 066/113] omxplayer: revbump for ffmpeg4-4.4.3
---
srcpkgs/omxplayer/template | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/srcpkgs/omxplayer/template b/srcpkgs/omxplayer/template
index e70bf7873d4d..0e9bc70e7c8e 100644
--- a/srcpkgs/omxplayer/template
+++ b/srcpkgs/omxplayer/template
@@ -1,10 +1,10 @@
# Template file for 'omxplayer'
pkgname=omxplayer
version=20190102
-revision=1
+revision=2
short_desc="Commandline OMX player for the Raspberry Pi"
maintainer="Orphaned <orphan@voidlinux.org>"
-license="GPL-2"
+license="GPL-2.0-or-later"
homepage="https://github.com/popcornmix/omxplayer"
_commit="f06235cc9690a6d58187514452df8cf8fcdaacec"
@@ -15,7 +15,7 @@ checksum=af2d9450f8947842ea8c401fe9f71eec444013ebbdee29f2ac828c9c493c1329
archs="armv6l* armv7l*"
build_style=gnu-makefile
hostmakedepends="curl pkg-config"
-makedepends="alsa-lib-devel rpi-userland-devel pcre-devel boost-devel freetype-devel ffmpeg-devel dbus-devel"
+makedepends="alsa-lib-devel rpi-userland-devel pcre-devel boost-devel freetype-devel ffmpeg4-devel dbus-devel"
depends="freefont-ttf"
do_build() {
From 30d0a1b84ddc42e6bba853ffe14244f22360d505 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:50 -0400
Subject: [PATCH 067/113] openimageio: revbump for ffmpeg-6.0
---
common/shlibs | 2 ++
srcpkgs/openimageio/template | 2 +-
2 files changed, 3 insertions(+), 1 deletion(-)
diff --git a/common/shlibs b/common/shlibs
index 8cb5ff0f7457..d7ee22d4426e 100644
--- a/common/shlibs
+++ b/common/shlibs
@@ -2263,6 +2263,8 @@ libxmp.so.4 libxmp-4.3.7_1
libKF5ThreadWeaver.so.5 threadweaver-5.26.0_1
libOpenImageIO_Util.so.2.4 openimageio-2.4.9.0_1
libOpenImageIO.so.2.4 openimageio-2.4.9.0_1
+libOpenImageIO_Util.so.2.4 openimageio-2.4.8.1_1
+libOpenImageIO.so.2.4 openimageio-2.4.8.1_1
libOpenColorIO.so.2.1 opencolorio-2.1.2_1
libpystring.so.1 pystring-1.1.3_1
libyaml-cpp.so.0.7 yaml-cpp-0.7.0_1
diff --git a/srcpkgs/openimageio/template b/srcpkgs/openimageio/template
index 9b38ace50f7e..c2d36b4b3539 100644
--- a/srcpkgs/openimageio/template
+++ b/srcpkgs/openimageio/template
@@ -1,7 +1,7 @@
# Template file for 'openimageio'
pkgname=openimageio
version=2.4.9.0
-revision=3
+revision=4
build_style=cmake
build_helper=qemu
configure_args="-DUSE_QT=0 -DUSE_PYTHON=0 -DOIIO_BUILD_TESTS=0
From 4234f6fee056b6a7caad12bfedf4efdcaa33340b Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:50 -0400
Subject: [PATCH 068/113] openshot: revbump for ffmpeg-6.0
---
srcpkgs/openshot/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/openshot/template b/srcpkgs/openshot/template
index 322717d40abc..c074e0338773 100644
--- a/srcpkgs/openshot/template
+++ b/srcpkgs/openshot/template
@@ -1,7 +1,7 @@
# Template file for 'openshot'
pkgname=openshot
version=3.0.0
-revision=1
+revision=2
build_style=python3-module
hostmakedepends="python3 python3-setuptools"
makedepends="ffmpeg-devel python3-PyQt5"
From faffd94bc5fa34bf2cd94dbfea0c0069c7cd7593 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:50 -0400
Subject: [PATCH 069/113] opentoonz: revbump for ffmpeg-6.0
---
srcpkgs/opentoonz/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/opentoonz/template b/srcpkgs/opentoonz/template
index ee9f7603f55f..3e81834ca0ed 100644
--- a/srcpkgs/opentoonz/template
+++ b/srcpkgs/opentoonz/template
@@ -1,7 +1,7 @@
# Template file for 'opentoonz'
pkgname=opentoonz
version=1.6.0
-revision=2
+revision=3
build_wrksrc="toonz/sources"
build_style=cmake
make_cmd=make
From f98800733cc79de658d0523d44d2db2060452f49 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:50 -0400
Subject: [PATCH 070/113] pianobar: revbump for ffmpeg-6.0
---
srcpkgs/pianobar/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/pianobar/template b/srcpkgs/pianobar/template
index a9b29e91993f..81efcd122c4d 100644
--- a/srcpkgs/pianobar/template
+++ b/srcpkgs/pianobar/template
@@ -1,7 +1,7 @@
# Template file for 'pianobar'
pkgname=pianobar
version=2022.04.01
-revision=1
+revision=2
build_style=gnu-makefile
make_build_args="V=1"
hostmakedepends="pkg-config"
From 7f03f4c5e598da017c6ae15527bcdb5262328cc3 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:50 -0400
Subject: [PATCH 071/113] ppsspp: revbump for ffmpeg4-4.4.3
---
srcpkgs/ppsspp/template | 7 +++----
1 file changed, 3 insertions(+), 4 deletions(-)
diff --git a/srcpkgs/ppsspp/template b/srcpkgs/ppsspp/template
index 7984a733d4be..15a42fd2c993 100644
--- a/srcpkgs/ppsspp/template
+++ b/srcpkgs/ppsspp/template
@@ -1,7 +1,7 @@
# Template file for 'ppsspp'
pkgname=ppsspp
version=1.14.4
-revision=1
+revision=2
_glslang_commit=dc11adde23c455a24e13dd54de9b4ede8bdd7db8
_SPIRV_Cross_commit=9acb9ec31f5a8ef80ea6b994bb77be787b08d3d1
_armips_commit=6719edebaae03330ee5441d9b28280672edf00d5
@@ -13,7 +13,7 @@ configure_args="-DHEADLESS=1 -DUSE_SYSTEM_FFMPEG=1 -DUNITTEST=ON
-DUSING_QT_UI=$(vopt_if qt ON OFF) -DUSE_SYSTEM_ZSTD=ON
-DARMIPS_USE_STD_FILESYSTEM=ON"
hostmakedepends="pkg-config python3 $(vopt_if qt qt5-host-tools)"
-makedepends="zlib-devel glew-devel ffmpeg-devel libzip-devel
+makedepends="zlib-devel glew-devel ffmpeg4-devel libzip-devel
snappy-devel rapidjson libpng-devel libzstd-devel
$(vopt_if sdl2 SDL2-devel) $(vopt_if wayland wayland-devel)
$(vopt_if qt 'qt5-devel qt5-multimedia-devel')"
@@ -62,13 +62,12 @@ post_extract() {
mv ${wrksrc}/miniupnp-${_miniupnp_commit} ${wrksrc}/ext/miniupnp
}
-post_patch(){
+post_patch() {
# disable git versioning
vsed -e 's|find_package(Git)|# &|' -i git-version.cmake
}
do_install() {
- vlicense LICENSE.TXT
vinstall icons/icon.svg 644 usr/share/pixmaps ppsspp.svg
vinstall Qt/PPSSPP.desktop 644 usr/share/applications
vbin build/PPSSPPHeadless ppsspp-headless
From 67a235e385b2086ea2d9ec7983310b790d7efc05 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:50 -0400
Subject: [PATCH 072/113] pqiv: revbump for ffmpeg-6.0
---
srcpkgs/pqiv/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/pqiv/template b/srcpkgs/pqiv/template
index 542fc27a2d32..9308d949b6a1 100644
--- a/srcpkgs/pqiv/template
+++ b/srcpkgs/pqiv/template
@@ -1,7 +1,7 @@
# Template file for 'pqiv'
pkgname=pqiv
version=2.12
-revision=1
+revision=2
build_style=gnu-makefile
hostmakedepends="pkg-config"
makedepends="glib-devel gtk+3-devel $(vopt_if ffmpeg ffmpeg-devel)
From 9cd1ff7447c208e3f5d059261780fb25afe7598b Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:50 -0400
Subject: [PATCH 073/113] qmmp: revbump for ffmpeg-6.0
---
srcpkgs/qmmp/template | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/srcpkgs/qmmp/template b/srcpkgs/qmmp/template
index 26c661ed16be..a150d7441c7a 100644
--- a/srcpkgs/qmmp/template
+++ b/srcpkgs/qmmp/template
@@ -1,7 +1,7 @@
# Template file for 'qmmp'
pkgname=qmmp
version=1.6.1
-revision=1
+revision=2
build_style=cmake
configure_args="-DUSE_HAL:BOOL=FALSE -DQMMP_DEFAULT_UI:STRING=simple"
hostmakedepends="pkg-config qt5-host-tools qt5-qmake"
From 42fb11f68686570af73ef697926e1ab5ae72bce7 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:50 -0400
Subject: [PATCH 074/113] qt5-webengine: update to 5.15.13
---
.../chromium-media-filters-cpp14.patch | 11 ++
srcpkgs/qt5-webengine/patches/ffmpeg5.patch | 179 ++++++++++++++++++
srcpkgs/qt5-webengine/template | 10 +-
3 files changed, 195 insertions(+), 5 deletions(-)
create mode 100644 srcpkgs/qt5-webengine/patches/chromium-media-filters-cpp14.patch
create mode 100644 srcpkgs/qt5-webengine/patches/ffmpeg5.patch
diff --git a/srcpkgs/qt5-webengine/patches/chromium-media-filters-cpp14.patch b/srcpkgs/qt5-webengine/patches/chromium-media-filters-cpp14.patch
new file mode 100644
index 000000000000..04adc540f2cb
--- /dev/null
+++ b/srcpkgs/qt5-webengine/patches/chromium-media-filters-cpp14.patch
@@ -0,0 +1,11 @@
+--- a/src/3rdparty/chromium/media/filters/BUILD.gn 2023-02-27 13:32:59.000000000 -0500
++++ b/src/3rdparty/chromium/media/filters/BUILD.gn 2023-04-02 17:21:39.204066384 -0400
+@@ -96,6 +96,8 @@
+ "//ui/gfx/geometry:geometry",
+ ]
+
++ cflags_cc = [ "-std=c++14" ]
++
+ libs = []
+
+ if (proprietary_codecs) {
diff --git a/srcpkgs/qt5-webengine/patches/ffmpeg5.patch b/srcpkgs/qt5-webengine/patches/ffmpeg5.patch
new file mode 100644
index 000000000000..ac55e1634423
--- /dev/null
+++ b/srcpkgs/qt5-webengine/patches/ffmpeg5.patch
@@ -0,0 +1,179 @@
+--- a/src/3rdparty/chromium/media/filters/ffmpeg_demuxer.cc 2023-04-02 16:50:57.732547446 -0400
++++ b/src/3rdparty/chromium/media/filters/ffmpeg_demuxer.cc 2023-04-02 16:50:09.486478995 -0400
+@@ -57,6 +57,8 @@
+
+ namespace {
+
++constexpr int64_t kRelativeTsBase = static_cast<int64_t>(0x7ffeffffffffffff);
++
+ void SetAVStreamDiscard(AVStream* stream, AVDiscard discard) {
+ DCHECK(stream);
+ stream->discard = discard;
+@@ -90,24 +92,12 @@
+
+ static base::TimeDelta ExtractStartTime(AVStream* stream) {
+ // The default start time is zero.
+- base::TimeDelta start_time;
++ base::TimeDelta start_time = kNoTimestamp;
+
+ // First try to use the |start_time| value as is.
+ if (stream->start_time != kNoFFmpegTimestamp)
+ start_time = ConvertFromTimeBase(stream->time_base, stream->start_time);
+
+- // Next try to use the first DTS value, for codecs where we know PTS == DTS
+- // (excludes all H26x codecs). The start time must be returned in PTS.
+- if (stream->first_dts != kNoFFmpegTimestamp &&
+- stream->codecpar->codec_id != AV_CODEC_ID_HEVC &&
+- stream->codecpar->codec_id != AV_CODEC_ID_H264 &&
+- stream->codecpar->codec_id != AV_CODEC_ID_MPEG4) {
+- const base::TimeDelta first_pts =
+- ConvertFromTimeBase(stream->time_base, stream->first_dts);
+- if (first_pts < start_time)
+- start_time = first_pts;
+- }
+-
+ return start_time;
+ }
+
+@@ -408,11 +398,11 @@
+ scoped_refptr<DecoderBuffer> buffer;
+
+ if (type() == DemuxerStream::TEXT) {
+- int id_size = 0;
++ size_t id_size = 0;
+ uint8_t* id_data = av_packet_get_side_data(
+ packet.get(), AV_PKT_DATA_WEBVTT_IDENTIFIER, &id_size);
+
+- int settings_size = 0;
++ size_t settings_size = 0;
+ uint8_t* settings_data = av_packet_get_side_data(
+ packet.get(), AV_PKT_DATA_WEBVTT_SETTINGS, &settings_size);
+
+@@ -424,7 +414,7 @@
+ buffer = DecoderBuffer::CopyFrom(packet->data, packet->size,
+ side_data.data(), side_data.size());
+ } else {
+- int side_data_size = 0;
++ size_t side_data_size = 0;
+ uint8_t* side_data = av_packet_get_side_data(
+ packet.get(), AV_PKT_DATA_MATROSKA_BLOCKADDITIONAL, &side_data_size);
+
+@@ -485,7 +475,7 @@
+ packet->size - data_offset);
+ }
+
+- int skip_samples_size = 0;
++ size_t skip_samples_size = 0;
+ const uint32_t* skip_samples_ptr =
+ reinterpret_cast<const uint32_t*>(av_packet_get_side_data(
+ packet.get(), AV_PKT_DATA_SKIP_SAMPLES, &skip_samples_size));
+@@ -1587,6 +1577,8 @@
+ for (const auto& stream : streams_) {
+ if (!stream || stream->IsEnabled() != enabled)
+ continue;
++ if (stream->av_stream()->start_time == AV_NOPTS_VALUE)
++ continue;
+ if (!lowest_start_time_stream ||
+ stream->start_time() < lowest_start_time_stream->start_time()) {
+ lowest_start_time_stream = stream.get();
+@@ -1604,6 +1596,8 @@
+ if (stream && stream->type() == DemuxerStream::VIDEO &&
+ stream->IsEnabled()) {
+ video_stream = stream.get();
++ if (stream->av_stream()->start_time == AV_NOPTS_VALUE)
++ continue;
+ if (video_stream->start_time() <= seek_time) {
+ return video_stream;
+ }
+diff -Naurp qtwebengine-5.15.10.orig/src/3rdparty/chromium/media/ffmpeg/ffmpeg_common.h qtwebengine-5.15.10/src/3rdparty/chromium/media/ffmpeg/ffmpeg_common.h
+--- a/src/3rdparty/chromium/media/ffmpeg/ffmpeg_common.h 2022-05-23 06:38:40.000000000 -0500
++++ b/src/3rdparty/chromium/media/ffmpeg/ffmpeg_common.h 2022-07-11 22:12:47.917192788 -0500
+@@ -29,6 +29,7 @@ extern "C" {
+ #include <libavformat/avformat.h>
+ #include <libavformat/avio.h>
+ #include <libavutil/avutil.h>
++#include <libavutil/channel_layout.h>
+ #include <libavutil/imgutils.h>
+ #include <libavutil/log.h>
+ #include <libavutil/mastering_display_metadata.h>
+diff -Naurp qtwebengine-5.15.10.orig/src/3rdparty/chromium/media/filters/audio_file_reader.cc qtwebengine-5.15.10/src/3rdparty/chromium/media/filters/audio_file_reader.cc
+--- a/src/3rdparty/chromium/media/filters/audio_file_reader.cc 2022-05-23 06:38:40.000000000 -0500
++++ b/src/3rdparty/chromium/media/filters/audio_file_reader.cc 2022-07-11 22:12:47.917192788 -0500
+@@ -85,7 +85,7 @@ bool AudioFileReader::OpenDemuxer() {
+ }
+
+ bool AudioFileReader::OpenDecoder() {
+- AVCodec* codec = avcodec_find_decoder(codec_context_->codec_id);
++ const AVCodec* codec = avcodec_find_decoder(codec_context_->codec_id);
+ if (codec) {
+ // MP3 decodes to S16P which we don't support, tell it to use S16 instead.
+ if (codec_context_->sample_fmt == AV_SAMPLE_FMT_S16P)
+diff -Naurp qtwebengine-5.15.10.orig/src/3rdparty/chromium/media/filters/ffmpeg_audio_decoder.cc qtwebengine-5.15.10/src/3rdparty/chromium/media/filters/ffmpeg_audio_decoder.cc
+--- a/src/3rdparty/chromium/media/filters/ffmpeg_audio_decoder.cc 2022-05-23 06:38:40.000000000 -0500
++++ b/src/3rdparty/chromium/media/filters/ffmpeg_audio_decoder.cc 2022-07-11 22:12:47.917192788 -0500
+@@ -329,7 +329,7 @@ bool FFmpegAudioDecoder::ConfigureDecode
+ }
+ }
+
+- AVCodec* codec = avcodec_find_decoder(codec_context_->codec_id);
++ const AVCodec* codec = avcodec_find_decoder(codec_context_->codec_id);
+ if (!codec ||
+ avcodec_open2(codec_context_.get(), codec, &codec_options) < 0) {
+ DLOG(ERROR) << "Could not initialize audio decoder: "
+diff -Naurp qtwebengine-5.15.10.orig/src/3rdparty/chromium/media/filters/ffmpeg_glue.cc qtwebengine-5.15.10/src/3rdparty/chromium/media/filters/ffmpeg_glue.cc
+--- a/src/3rdparty/chromium/media/filters/ffmpeg_glue.cc 2022-05-23 06:38:40.000000000 -0500
++++ b/src/3rdparty/chromium/media/filters/ffmpeg_glue.cc 2022-07-11 22:12:47.918192779 -0500
+@@ -59,7 +59,6 @@ static int64_t AVIOSeekOperation(void* o
+ }
+
+ void FFmpegGlue::InitializeFFmpeg() {
+- av_register_all();
+ }
+
+ static void LogContainer(bool is_local_file,
+@@ -95,9 +94,6 @@ FFmpegGlue::FFmpegGlue(FFmpegURLProtocol
+ // Enable fast, but inaccurate seeks for MP3.
+ format_context_->flags |= AVFMT_FLAG_FAST_SEEK;
+
+- // Ensures we can read out various metadata bits like vp8 alpha.
+- format_context_->flags |= AVFMT_FLAG_KEEP_SIDE_DATA;
+-
+ // Ensures format parsing errors will bail out. From an audit on 11/2017, all
+ // instances were real failures. Solves bugs like http://crbug.com/710791.
+ format_context_->error_recognition |= AV_EF_EXPLODE;
+diff -Naurp qtwebengine-5.15.10.orig/src/3rdparty/chromium/media/filters/ffmpeg_video_decoder.cc qtwebengine-5.15.10/src/3rdparty/chromium/media/filters/ffmpeg_video_decoder.cc
+--- a/src/3rdparty/chromium/media/filters/ffmpeg_video_decoder.cc 2022-05-23 06:38:40.000000000 -0500
++++ b/src/3rdparty/chromium/media/filters/ffmpeg_video_decoder.cc 2022-07-11 22:12:47.918192779 -0500
+@@ -391,7 +391,7 @@ bool FFmpegVideoDecoder::ConfigureDecode
+ if (decode_nalus_)
+ codec_context_->flags2 |= AV_CODEC_FLAG2_CHUNKS;
+
+- AVCodec* codec = avcodec_find_decoder(codec_context_->codec_id);
++ const AVCodec* codec = avcodec_find_decoder(codec_context_->codec_id);
+ if (!codec || avcodec_open2(codec_context_.get(), codec, NULL) < 0) {
+ ReleaseFFmpegResources();
+ return false;
+diff -Naurp qtwebengine-5.15.10.orig/src/3rdparty/chromium/media/filters/media_file_checker.cc qtwebengine-5.15.10/src/3rdparty/chromium/media/filters/media_file_checker.cc
+--- a/src/3rdparty/chromium/media/filters/media_file_checker.cc 2022-05-23 06:38:40.000000000 -0500
++++ b/src/3rdparty/chromium/media/filters/media_file_checker.cc 2022-07-11 22:12:47.918192779 -0500
+@@ -68,7 +68,7 @@ bool MediaFileChecker::Start(base::TimeD
+ auto context = AVStreamToAVCodecContext(format_context->streams[i]);
+ if (!context)
+ continue;
+- AVCodec* codec = avcodec_find_decoder(cp->codec_id);
++ const AVCodec* codec = avcodec_find_decoder(cp->codec_id);
+ if (codec && avcodec_open2(context.get(), codec, nullptr) >= 0) {
+ auto loop = std::make_unique<FFmpegDecodingLoop>(context.get());
+ stream_contexts[i] = {std::move(context), std::move(loop)};
+diff -Naurp qtwebengine-5.15.10.orig/src/3rdparty/chromium/third_party/webrtc/modules/video_coding/codecs/h264/h264_decoder_impl.cc qtwebengine-5.15.10/src/3rdparty/chromium/third_party/webrtc/modules/video_coding/codecs/h264/h264_decoder_impl.cc
+--- a/src/3rdparty/chromium/third_party/webrtc/modules/video_coding/codecs/h264/h264_decoder_impl.cc 2022-05-23 06:38:40.000000000 -0500
++++ b/src/3rdparty/chromium/third_party/webrtc/modules/video_coding/codecs/h264/h264_decoder_impl.cc 2022-07-11 22:12:47.918192779 -0500
+@@ -203,7 +203,7 @@ int32_t H264DecoderImpl::InitDecode(cons
+ // a pointer |this|.
+ av_context_->opaque = this;
+
+- AVCodec* codec = avcodec_find_decoder(av_context_->codec_id);
++ const AVCodec* codec = avcodec_find_decoder(av_context_->codec_id);
+ if (!codec) {
+ // This is an indication that FFmpeg has not been initialized or it has not
+ // been compiled/initialized with the correct set of codecs.
diff --git a/srcpkgs/qt5-webengine/template b/srcpkgs/qt5-webengine/template
index 85267c7cf8a3..095ab67701e4 100644
--- a/srcpkgs/qt5-webengine/template
+++ b/srcpkgs/qt5-webengine/template
@@ -1,9 +1,9 @@
# Template file for 'qt5-webengine'
pkgname=qt5-webengine
-version=5.15.11
-revision=3
+version=5.15.13
+revision=1
_version="${version}-lts"
-_chromium_commit=be349eaf62e77955791d7bf29f893f1e8a37daf4
+_chromium_commit=e48df7803c7c98b0b2471c94057d32e44a301ad5
archs="x86_64* i686* armv[67]* ppc64* aarch64*"
create_wrksrc=yes
build_style=qmake
@@ -32,8 +32,8 @@ license="GPL-3.0-or-later, LGPL-3.0-or-later"
homepage="https://qt.io/"
distfiles="https://github.com/qt/qtwebengine/archive/v${_version}.tar.gz
https://github.com/qt/qtwebengine-chromium/archive/${_chromium_commit}.tar.gz"
-checksum="aa7466356c450c5f5870f979b93cd7e7e62da1165c328ffcab1a9928db18ad67
- 6f47ed8ab8cc062411f6f206da6353bc8263d6ed6d6290c689a05c01d91f646b"
+checksum="4b59838ed75ef788b59e1e412535a0e42dd9d311661fdeadb191b581ba815c63
+ a91686562b1d4e8b220e0bbcbab5feb64630e2de974b35ac034bf388af771a6c"
no_generic_pkgconfig_link=yes
build_options="sndio pipewire"
From 2a426ad733494415cdef1b33d7dde6928c055937 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:51 -0400
Subject: [PATCH 075/113] qt5: update to 5.15.8
---
...erywhere-opensource-src-5.15.8-kf5-1.patch | 12913 ++++++++++++++++
srcpkgs/qt5/template | 12 +-
2 files changed, 12919 insertions(+), 6 deletions(-)
create mode 100644 srcpkgs/qt5/patches/qt-everywhere-opensource-src-5.15.8-kf5-1.patch
diff --git a/srcpkgs/qt5/patches/qt-everywhere-opensource-src-5.15.8-kf5-1.patch b/srcpkgs/qt5/patches/qt-everywhere-opensource-src-5.15.8-kf5-1.patch
new file mode 100644
index 000000000000..966c98bcd3bb
--- /dev/null
+++ b/srcpkgs/qt5/patches/qt-everywhere-opensource-src-5.15.8-kf5-1.patch
@@ -0,0 +1,12913 @@
+Submitted By: Pierre Labastie <pierre_dot_labastie_at_neuf_dot_fr>
+Date: 2023-01-05
+Initial Package Version: 5.15.8
+Upstream Status: Applied (according to KDE)
+Origin: KDE patch set
+Description: Patch set maintained by the KDE folks
+see https://dot.kde.org/2021/04/06/announcing-kdes-qt-5-patch-collection
+Patch generated using the procedure in
+https://wiki.linuxfromscratch.org/blfs/ticket/17476#comment:3
+
+Submodule qtbase 4ee4fc18..9cf586d6:
+diff --git a/qtbase/mkspecs/common/android/qplatformdefs.h b/qtbase/mkspecs/common/android/qplatformdefs.h
+index f75bc4093b..2bd59410d4 100644
+--- a/qtbase/mkspecs/common/android/qplatformdefs.h
++++ b/qtbase/mkspecs/common/android/qplatformdefs.h
+@@ -144,11 +144,7 @@
+ #define QT_SIGNAL_ARGS int
+ #define QT_SIGNAL_IGNORE SIG_IGN
+
+-#if defined(__GLIBC__) && (__GLIBC__ >= 2)
+ #define QT_SOCKLEN_T socklen_t
+-#else
+-#define QT_SOCKLEN_T int
+-#endif
+
+ #if defined(_XOPEN_SOURCE) && (_XOPEN_SOURCE >= 500)
+ #define QT_SNPRINTF ::snprintf
+diff --git a/qtbase/mkspecs/features/mac/sdk.mk b/qtbase/mkspecs/features/mac/sdk.mk
+index f30b5830b4..a32ceacb6c 100644
+--- a/qtbase/mkspecs/features/mac/sdk.mk
++++ b/qtbase/mkspecs/features/mac/sdk.mk
+@@ -1,6 +1,6 @@
+
+ ifeq ($(QT_MAC_SDK_NO_VERSION_CHECK),)
+- CHECK_SDK_COMMAND = /usr/bin/xcrun --sdk $(EXPORT_QMAKE_MAC_SDK) -show-sdk-version 2>&1
++ CHECK_SDK_COMMAND = /usr/bin/xcrun --sdk $(EXPORT_QMAKE_MAC_SDK) -show-sdk-version 2>/dev/null
+ CURRENT_MAC_SDK_VERSION := $(shell DEVELOPER_DIR=$(EXPORT_QMAKE_XCODE_DEVELOPER_PATH) $(CHECK_SDK_COMMAND))
+ ifneq ($(CURRENT_MAC_SDK_VERSION),$(EXPORT_QMAKE_MAC_SDK_VERSION))
+ # We don't want to complain about out of date SDK unless the target needs to be remade.
+diff --git a/qtbase/mkspecs/linux-clang/qplatformdefs.h b/qtbase/mkspecs/linux-clang/qplatformdefs.h
+index a818d973f0..c1ab72fbc6 100644
+--- a/qtbase/mkspecs/linux-clang/qplatformdefs.h
++++ b/qtbase/mkspecs/linux-clang/qplatformdefs.h
+@@ -79,14 +79,6 @@
+ #define QT_USE_XOPEN_LFS_EXTENSIONS
+ #include "../common/posix/qplatformdefs.h"
+
+-#undef QT_SOCKLEN_T
+-
+-#if defined(__GLIBC__) && (__GLIBC__ >= 2)
+-#define QT_SOCKLEN_T socklen_t
+-#else
+-#define QT_SOCKLEN_T int
+-#endif
+-
+ #if defined(_XOPEN_SOURCE) && (_XOPEN_SOURCE >= 500)
+ #define QT_SNPRINTF ::snprintf
+ #define QT_VSNPRINTF ::vsnprintf
+diff --git a/qtbase/mkspecs/linux-g++/qplatformdefs.h b/qtbase/mkspecs/linux-g++/qplatformdefs.h
+index 13523f0702..4d2750d9ec 100644
+--- a/qtbase/mkspecs/linux-g++/qplatformdefs.h
++++ b/qtbase/mkspecs/linux-g++/qplatformdefs.h
+@@ -79,14 +79,6 @@
+ #define QT_USE_XOPEN_LFS_EXTENSIONS
+ #include "../common/posix/qplatformdefs.h"
+
+-#undef QT_SOCKLEN_T
+-
+-#if defined(__GLIBC__) && (__GLIBC__ < 2)
+-#define QT_SOCKLEN_T int
+-#else
+-#define QT_SOCKLEN_T socklen_t
+-#endif
+-
+ #if defined(_XOPEN_SOURCE) && (_XOPEN_SOURCE >= 500)
+ #define QT_SNPRINTF ::snprintf
+ #define QT_VSNPRINTF ::vsnprintf
+diff --git a/qtbase/mkspecs/linux-llvm/qplatformdefs.h b/qtbase/mkspecs/linux-llvm/qplatformdefs.h
+index dc750ab1ef..d3cc39b47f 100644
+--- a/qtbase/mkspecs/linux-llvm/qplatformdefs.h
++++ b/qtbase/mkspecs/linux-llvm/qplatformdefs.h
+@@ -80,14 +80,6 @@
+ #define QT_USE_XOPEN_LFS_EXTENSIONS
+ #include "../common/posix/qplatformdefs.h"
+
+-#undef QT_SOCKLEN_T
+-
+-#if defined(__GLIBC__) && (__GLIBC__ >= 2)
+-#define QT_SOCKLEN_T socklen_t
+-#else
+-#define QT_SOCKLEN_T int
+-#endif
+-
+ #if defined(_XOPEN_SOURCE) && (_XOPEN_SOURCE >= 500)
+ #define QT_SNPRINTF ::snprintf
+ #define QT_VSNPRINTF ::vsnprintf
+diff --git a/qtbase/mkspecs/linux-lsb-g++/qplatformdefs.h b/qtbase/mkspecs/linux-lsb-g++/qplatformdefs.h
+index 4c4e53da2a..83baffb3e3 100644
+--- a/qtbase/mkspecs/linux-lsb-g++/qplatformdefs.h
++++ b/qtbase/mkspecs/linux-lsb-g++/qplatformdefs.h
+@@ -85,16 +85,9 @@
+ #include "../common/posix/qplatformdefs.h"
+
+ #undef QT_OPEN_LARGEFILE
+-#undef QT_SOCKLEN_T
+
+ #define QT_OPEN_LARGEFILE 0
+
+-#if defined(__GLIBC__) && (__GLIBC__ >= 2)
+-#define QT_SOCKLEN_T socklen_t
+-#else
+-#define QT_SOCKLEN_T int
+-#endif
+-
+ #ifndef SIOCGIFBRDADDR
+ # define SIOCGIFBRDADDR 0x8919
+ #endif
+diff --git a/qtbase/mkspecs/lynxos-g++/qplatformdefs.h b/qtbase/mkspecs/lynxos-g++/qplatformdefs.h
+index 4339ea2b23..6007af0055 100644
+--- a/qtbase/mkspecs/lynxos-g++/qplatformdefs.h
++++ b/qtbase/mkspecs/lynxos-g++/qplatformdefs.h
+@@ -72,14 +72,6 @@
+
+ #include "../common/posix/qplatformdefs.h"
+
+-#undef QT_SOCKLEN_T
+-
+-#if defined(__GLIBC__) && (__GLIBC__ >= 2)
+-#define QT_SOCKLEN_T socklen_t
+-#else
+-#define QT_SOCKLEN_T int
+-#endif
+-
+ #if defined(_XOPEN_SOURCE) && (_XOPEN_SOURCE >= 500)
+ #define QT_SNPRINTF ::snprintf
+ #define QT_VSNPRINTF ::vsnprintf
+diff --git a/qtbase/src/3rdparty/angle/src/libANGLE/HandleAllocator.cpp b/qtbase/src/3rdparty/angle/src/libANGLE/HandleAllocator.cpp
+index c3c184258f..32af3f8f29 100644
+--- a/qtbase/src/3rdparty/angle/src/libANGLE/HandleAllocator.cpp
++++ b/qtbase/src/3rdparty/angle/src/libANGLE/HandleAllocator.cpp
+@@ -10,6 +10,7 @@
+ #include "libANGLE/HandleAllocator.h"
+
+ #include <algorithm>
++#include <limits>
+
+ #include "common/debug.h"
+
+diff --git a/qtbase/src/3rdparty/forkfd/forkfd_linux.c b/qtbase/src/3rdparty/forkfd/forkfd_linux.c
+index ffe0e9a5e2..b1f5408d11 100644
+--- a/qtbase/src/3rdparty/forkfd/forkfd_linux.c
++++ b/qtbase/src/3rdparty/forkfd/forkfd_linux.c
+@@ -82,7 +82,8 @@ static int sys_clone(unsigned long cloneflags, int *ptid)
+ return syscall(__NR_clone, cloneflags, child_stack, stack_size, ptid, newtls, ctid);
+ #elif defined(__arc__) || defined(__arm__) || defined(__aarch64__) || defined(__mips__) || \
+ defined(__nds32__) || defined(__hppa__) || defined(__powerpc__) || defined(__i386__) || \
+- defined(__x86_64__) || defined(__xtensa__) || defined(__alpha__) || defined(__riscv)
++ defined(__x86_64__) || defined(__xtensa__) || defined(__alpha__) || defined(__riscv) || \
++ defined(__loongarch__)
+ /* ctid and newtls are inverted on CONFIG_CLONE_BACKWARDS architectures,
+ * but since both values are 0, there's no harm. */
+ return syscall(__NR_clone, cloneflags, child_stack, ptid, ctid, newtls);
+diff --git a/qtbase/src/android/jar/src/org/qtproject/qt5/android/QtNative.java b/qtbase/src/android/jar/src/org/qtproject/qt5/android/QtNative.java
+index 5792b5b2f5..2f74750fcf 100644
+--- a/qtbase/src/android/jar/src/org/qtproject/qt5/android/QtNative.java
++++ b/qtbase/src/android/jar/src/org/qtproject/qt5/android/QtNative.java
+@@ -116,6 +116,7 @@ public class QtNative
+ public static QtThread m_qtThread = new QtThread();
+ private static HashMap<String, Uri> m_cachedUris = new HashMap<String, Uri>();
+ private static ArrayList<String> m_knownDirs = new ArrayList<String>();
++ private static final String NoPermissionErrorMessage = "No permissions to open Uri";
+
+ private static final Runnable runPendingCppRunnablesRunnable = new Runnable() {
+ @Override
+@@ -193,11 +194,10 @@ public class QtNative
+ return iterUri;
+ }
+
+- // Android 6 and earlier could still manage to open the file so we can return the
+- // parsed uri here
+- if (Build.VERSION.SDK_INT < 24)
+- return parsedUri;
+- return null;
++ // if we only have transient permissions on uri all the above will fail,
++ // but we will be able to read the file anyway, so continue with uri here anyway
++ // and check for SecurityExceptions later
++ return parsedUri;
+ } catch (SecurityException e) {
+ e.printStackTrace();
+ return null;
+@@ -244,7 +244,7 @@ public class QtNative
+ int error = -1;
+
+ if (uri == null) {
+- Log.e(QtTAG, "openFdForContentUrl(): No permissions to open Uri");
++ Log.e(QtTAG, "openFdForContentUrl(): " + NoPermissionErrorMessage);
+ return error;
+ }
+
+@@ -254,12 +254,13 @@ public class QtNative
+ return fdDesc.detachFd();
+ } catch (FileNotFoundException e) {
+ e.printStackTrace();
+- return error;
+ } catch (IllegalArgumentException e) {
+ Log.e(QtTAG, "openFdForContentUrl(): Invalid Uri");
+ e.printStackTrace();
+- return error;
++ } catch (SecurityException e) {
++ Log.e(QtTAG, NoPermissionErrorMessage);
+ }
++ return error;
+ }
+
+ public static long getSize(Context context, String contentUrl)
+@@ -270,7 +271,7 @@ public class QtNative
+ uri = getUriWithValidPermission(context, contentUrl, "r");
+
+ if (uri == null) {
+- Log.e(QtTAG, "getSize(): No permissions to open Uri");
++ Log.e(QtTAG, NoPermissionErrorMessage);
+ return size;
+ } else if (!m_cachedUris.containsKey(contentUrl)) {
+ m_cachedUris.put(contentUrl, uri);
+@@ -288,12 +289,13 @@ public class QtNative
+ } catch (IllegalArgumentException e) {
+ Log.e(QtTAG, "getSize(): Invalid Uri");
+ e.printStackTrace();
+- return size;
+ } catch (UnsupportedOperationException e) {
+ Log.e(QtTAG, "getSize(): Unsupported operation for given Uri");
+ e.printStackTrace();
+- return size;
++ } catch (SecurityException e) {
++ Log.e(QtTAG, NoPermissionErrorMessage);
+ }
++ return size;
+ }
+
+ public static boolean checkFileExists(Context context, String contentUrl)
+@@ -303,7 +305,7 @@ public class QtNative
+ if (uri == null)
+ uri = getUriWithValidPermission(context, contentUrl, "r");
+ if (uri == null) {
+- Log.e(QtTAG, "checkFileExists(): No permissions to open Uri");
++ Log.e(QtTAG, NoPermissionErrorMessage);
+ return exists;
+ } else {
+ if (!m_cachedUris.containsKey(contentUrl))
+@@ -321,12 +323,13 @@ public class QtNative
+ } catch (IllegalArgumentException e) {
+ Log.e(QtTAG, "checkFileExists(): Invalid Uri");
+ e.printStackTrace();
+- return exists;
+ } catch (UnsupportedOperationException e) {
+ Log.e(QtTAG, "checkFileExists(): Unsupported operation for given Uri");
+ e.printStackTrace();
+- return false;
++ } catch (SecurityException e) {
++ Log.e(QtTAG, NoPermissionErrorMessage);
+ }
++ return exists;
+ }
+
+ public static boolean checkIfWritable(Context context, String contentUrl)
+@@ -344,7 +347,7 @@ public class QtNative
+ uri = getUriWithValidPermission(context, contentUrl, "r");
+ }
+ if (uri == null) {
+- Log.e(QtTAG, "isDir(): No permissions to open Uri");
++ Log.e(QtTAG, NoPermissionErrorMessage);
+ return isDir;
+ } else {
+ if (!m_cachedUris.containsKey(contentUrl))
+@@ -374,12 +377,13 @@ public class QtNative
+ } catch (IllegalArgumentException e) {
+ Log.e(QtTAG, "checkIfDir(): Invalid Uri");
+ e.printStackTrace();
+- return false;
+ } catch (UnsupportedOperationException e) {
+ Log.e(QtTAG, "checkIfDir(): Unsupported operation for given Uri");
+ e.printStackTrace();
+- return false;
++ } catch (SecurityException e) {
++ Log.e(QtTAG, NoPermissionErrorMessage);
+ }
++ return false;
+ }
+ public static String[] listContentsFromTreeUri(Context context, String contentUrl)
+ {
+diff --git a/qtbase/src/concurrent/qtconcurrentreducekernel.h b/qtbase/src/concurrent/qtconcurrentreducekernel.h
+index 8f9a938952..a98dedef2e 100644
+--- a/qtbase/src/concurrent/qtconcurrentreducekernel.h
++++ b/qtbase/src/concurrent/qtconcurrentreducekernel.h
+@@ -212,11 +212,13 @@ public:
+
+ inline bool shouldThrottle()
+ {
++ std::lock_guard<QMutex> locker(mutex);
+ return (resultsMapSize > (ReduceQueueThrottleLimit * threadCount));
+ }
+
+ inline bool shouldStartThread()
+ {
++ std::lock_guard<QMutex> locker(mutex);
+ return (resultsMapSize <= (ReduceQueueStartLimit * threadCount));
+ }
+ };
+diff --git a/qtbase/src/concurrent/qtconcurrentthreadengine.cpp b/qtbase/src/concurrent/qtconcurrentthreadengine.cpp
+index ea6ce3ac42..7f91a2ba68 100644
+--- a/qtbase/src/concurrent/qtconcurrentthreadengine.cpp
++++ b/qtbase/src/concurrent/qtconcurrentthreadengine.cpp
+@@ -176,6 +176,39 @@ void ThreadEngineBase::startSingleThreaded()
+ finish();
+ }
+
++void ThreadEngineBase::startBlocking()
++{
++ start();
++ barrier.acquire();
++ startThreads();
++
++ bool throttled = false;
++#ifndef QT_NO_EXCEPTIONS
++ try {
++#endif
++ while (threadFunction() == ThrottleThread) {
++ if (threadThrottleExit()) {
++ throttled = true;
++ break;
++ }
++ }
++#ifndef QT_NO_EXCEPTIONS
++ } catch (QException &e) {
++ handleException(e);
++ } catch (...) {
++ handleException(QUnhandledException());
++ }
++#endif
++
++ if (throttled == false) {
++ barrier.release();
++ }
++
++ barrier.wait();
++ finish();
++ exceptionStore.throwPossibleException();
++}
++
+ void ThreadEngineBase::startThread()
+ {
+ startThreadInternal();
+diff --git a/qtbase/src/concurrent/qtconcurrentthreadengine.h b/qtbase/src/concurrent/qtconcurrentthreadengine.h
+index 7c30cebdbc..a4c8548cc4 100644
+--- a/qtbase/src/concurrent/qtconcurrentthreadengine.h
++++ b/qtbase/src/concurrent/qtconcurrentthreadengine.h
+@@ -91,6 +91,7 @@ public:
+ ThreadEngineBase();
+ virtual ~ThreadEngineBase();
+ void startSingleThreaded();
++ void startBlocking();
+ void startThread();
+ bool isCanceled();
+ void waitForResume();
+@@ -143,6 +144,15 @@ public:
+ return result();
+ }
+
++ // Runs the user algorithm using multiple threads.
++ // This function blocks until the algorithm is finished,
++ // and then returns the result.
++ T *startBlocking()
++ {
++ ThreadEngineBase::startBlocking();
++ return result();
++ }
++
+ // Runs the user algorithm using multiple threads.
+ // Does not block, returns a future.
+ QFuture<T> startAsynchronously()
+@@ -223,6 +233,13 @@ class ThreadEngineStarter : public ThreadEngineStarterBase<T>
+ public:
+ ThreadEngineStarter(TypedThreadEngine *eng)
+ : Base(eng) { }
++
++ T startBlocking()
++ {
++ T t = *this->threadEngine->startBlocking();
++ delete this->threadEngine;
++ return t;
++ }
+ };
+
+ // Full template specialization where T is void.
+@@ -232,6 +249,12 @@ class ThreadEngineStarter<void> : public ThreadEngineStarterBase<void>
+ public:
+ ThreadEngineStarter(ThreadEngine<void> *_threadEngine)
+ : ThreadEngineStarterBase<void>(_threadEngine) {}
++
++ void startBlocking()
++ {
++ this->threadEngine->startBlocking();
++ delete this->threadEngine;
++ }
+ };
+
+ //! [qtconcurrentthreadengine-1]
+diff --git a/qtbase/src/corelib/animation/qvariantanimation.cpp b/qtbase/src/corelib/animation/qvariantanimation.cpp
+index 98b02f0202..eac1524107 100644
+--- a/qtbase/src/corelib/animation/qvariantanimation.cpp
++++ b/qtbase/src/corelib/animation/qvariantanimation.cpp
+@@ -276,7 +276,9 @@ void QVariantAnimationPrivate::setCurrentValueForProgress(const qreal progress)
+
+ const qreal startProgress = currentInterval.start.first;
+ const qreal endProgress = currentInterval.end.first;
+- const qreal localProgress = (progress - startProgress) / (endProgress - startProgress);
++ const qreal localProgress =
++ qIsNull(progress - startProgress) ? 0.0 // avoid 0/0 below
++ /* else */ : (progress - startProgress) / (endProgress - startProgress);
+
+ QVariant ret = q->interpolated(currentInterval.start.second,
+ currentInterval.end.second,
+diff --git a/qtbase/src/corelib/global/qnamespace.h b/qtbase/src/corelib/global/qnamespace.h
+index ad4150b317..bf19b1627b 100644
+--- a/qtbase/src/corelib/global/qnamespace.h
++++ b/qtbase/src/corelib/global/qnamespace.h
+@@ -1864,7 +1864,7 @@ public:
+ QT_Q_ENUM(TimerType)
+ QT_Q_ENUM(ScrollPhase)
+ QT_Q_ENUM(MouseEventSource)
+- QT_Q_FLAG(MouseEventFlag)
++ QT_Q_FLAG(MouseEventFlags)
+ QT_Q_ENUM(ChecksumType)
+ QT_Q_ENUM(HighDpiScaleFactorRoundingPolicy)
+ QT_Q_ENUM(TabFocusBehavior)
+diff --git a/qtbase/src/corelib/global/qrandom.cpp b/qtbase/src/corelib/global/qrandom.cpp
+index 10672c1f92..25f87c7e6a 100644
+--- a/qtbase/src/corelib/global/qrandom.cpp
++++ b/qtbase/src/corelib/global/qrandom.cpp
+@@ -383,7 +383,6 @@ struct QRandomGenerator::SystemAndGlobalGenerators
+
+ constexpr SystemAndGlobalGenerators g = {};
+ Q_UNUSED(g);
+- Q_STATIC_ASSERT(std::is_literal_type<SystemAndGlobalGenerators>::value);
+ #endif
+ }
+
+diff --git a/qtbase/src/corelib/io/qbuffer.cpp b/qtbase/src/corelib/io/qbuffer.cpp
+index 595fcd2724..032c0ddd4b 100644
+--- a/qtbase/src/corelib/io/qbuffer.cpp
++++ b/qtbase/src/corelib/io/qbuffer.cpp
+@@ -41,6 +41,8 @@
+ #include <QtCore/qmetaobject.h>
+ #include "private/qiodevice_p.h"
+
++#include <limits>
++
+ QT_BEGIN_NAMESPACE
+
+ /** QBufferPrivate **/
+@@ -366,7 +368,9 @@ qint64 QBuffer::size() const
+ bool QBuffer::seek(qint64 pos)
+ {
+ Q_D(QBuffer);
+- if (pos > d->buf->size() && isWritable()) {
++ const auto oldBufSize = d->buf->size();
++ constexpr qint64 MaxSeekPos = (std::numeric_limits<decltype(oldBufSize)>::max)();
++ if (pos <= MaxSeekPos && pos > oldBufSize && isWritable()) {
+ if (seek(d->buf->size())) {
+ const qint64 gapSize = pos - d->buf->size();
+ if (write(QByteArray(gapSize, 0)) != gapSize) {
+@@ -377,7 +381,7 @@ bool QBuffer::seek(qint64 pos)
+ return false;
+ }
+ } else if (pos > d->buf->size() || pos < 0) {
+- qWarning("QBuffer::seek: Invalid pos: %d", int(pos));
++ qWarning("QBuffer::seek: Invalid pos: %lld", pos);
+ return false;
+ }
+ return QIODevice::seek(pos);
+diff --git a/qtbase/src/corelib/io/qfilesystemengine_win.cpp b/qtbase/src/corelib/io/qfilesystemengine_win.cpp
+index 81d3a71986..c86ed1f9b0 100644
+--- a/qtbase/src/corelib/io/qfilesystemengine_win.cpp
++++ b/qtbase/src/corelib/io/qfilesystemengine_win.cpp
+@@ -664,14 +664,14 @@ QFileSystemEntry QFileSystemEngine::absoluteName(const QFileSystemEntry &entry)
+ return QFileSystemEntry(ret, QFileSystemEntry::FromInternalPath());
+ }
+
+-#if defined(Q_CC_MINGW) && WINVER < 0x0602 // Windows 8 onwards
++#if defined(Q_CC_MINGW) && WINVER < 0x0602 && _WIN32_WINNT < _WIN32_WINNT_WIN8 // Windows 8 onwards
+
+ typedef struct _FILE_ID_INFO {
+ ULONGLONG VolumeSerialNumber;
+ FILE_ID_128 FileId;
+ } FILE_ID_INFO, *PFILE_ID_INFO;
+
+-#endif // if defined (Q_CC_MINGW) && WINVER < 0x0602
++#endif // if defined(Q_CC_MINGW) && WINVER < 0x0602 && _WIN32_WINNT < _WIN32_WINNT_WIN8
+
+ // File ID for Windows up to version 7 and FAT32 drives
+ static inline QByteArray fileId(HANDLE handle)
+diff --git a/qtbase/src/corelib/io/qfilesystemwatcher_inotify.cpp b/qtbase/src/corelib/io/qfilesystemwatcher_inotify.cpp
+index 94d9d06bcb..27e0b13b0b 100644
+--- a/qtbase/src/corelib/io/qfilesystemwatcher_inotify.cpp
++++ b/qtbase/src/corelib/io/qfilesystemwatcher_inotify.cpp
+@@ -366,7 +366,9 @@ void QInotifyFileSystemWatcherEngine::readFromInotify()
+ // qDebug("QInotifyFileSystemWatcherEngine::readFromInotify");
+
+ int buffSize = 0;
+- ioctl(inotifyFd, FIONREAD, (char *) &buffSize);
++ if (ioctl(inotifyFd, FIONREAD, (char *) &buffSize) == -1 || buffSize == 0)
++ return;
++
+ QVarLengthArray<char, 4096> buffer(buffSize);
+ buffSize = read(inotifyFd, buffer.data(), buffSize);
+ char *at = buffer.data();
+diff --git a/qtbase/src/corelib/io/qlockfile_win.cpp b/qtbase/src/corelib/io/qlockfile_win.cpp
+index 277f8d4230..38ecef5550 100644
+--- a/qtbase/src/corelib/io/qlockfile_win.cpp
++++ b/qtbase/src/corelib/io/qlockfile_win.cpp
+@@ -48,6 +48,8 @@
+ #include "QtCore/qdebug.h"
+ #include "QtCore/qthread.h"
+
++#include "private/qsystemlibrary_p.h"
++
+ QT_BEGIN_NAMESPACE
+
+ static inline bool fileExists(const wchar_t *fileName)
+@@ -150,7 +152,7 @@ QString QLockFilePrivate::processNameByPid(qint64 pid)
+ #if !defined(Q_OS_WINRT)
+ typedef DWORD (WINAPI *GetModuleFileNameExFunc)(HANDLE, HMODULE, LPTSTR, DWORD);
+
+- HMODULE hPsapi = LoadLibraryA("psapi");
++ HMODULE hPsapi = QSystemLibrary::load(L"psapi");
+ if (!hPsapi)
+ return QString();
+ GetModuleFileNameExFunc qGetModuleFileNameEx = reinterpret_cast<GetModuleFileNameExFunc>(
+diff --git a/qtbase/src/corelib/io/qprocess_unix.cpp b/qtbase/src/corelib/io/qprocess_unix.cpp
+index 50390e57f5..15c8f30745 100644
+--- a/qtbase/src/corelib/io/qprocess_unix.cpp
++++ b/qtbase/src/corelib/io/qprocess_unix.cpp
+@@ -1,7 +1,7 @@
+ /****************************************************************************
+ **
+ ** Copyright (C) 2016 The Qt Company Ltd.
+-** Copyright (C) 2016 Intel Corporation.
++** Copyright (C) 2022 Intel Corporation.
+ ** Contact: https://www.qt.io/licensing/
+ **
+ ** This file is part of the QtCore module of the Qt Toolkit.
+@@ -422,14 +422,15 @@ void QProcessPrivate::startProcess()
+ // Add the program name to the argument list.
+ argv[0] = nullptr;
+ if (!program.contains(QLatin1Char('/'))) {
++ // findExecutable() returns its argument if it's an absolute path,
++ // otherwise it searches $PATH; returns empty if not found (we handle
++ // that case much later)
+ const QString &exeFilePath = QStandardPaths::findExecutable(program);
+- if (!exeFilePath.isEmpty()) {
+- const QByteArray &tmp = QFile::encodeName(exeFilePath);
+- argv[0] = ::strdup(tmp.constData());
+- }
+- }
+- if (!argv[0])
++ const QByteArray &tmp = QFile::encodeName(exeFilePath);
++ argv[0] = ::strdup(tmp.constData());
++ } else {
+ argv[0] = ::strdup(encodedProgramName.constData());
++ }
+
+ // Add every argument to the list
+ for (int i = 0; i < arguments.count(); ++i)
+@@ -983,15 +984,16 @@ bool QProcessPrivate::startDetached(qint64 *pid)
+ envp = _q_dupEnvironment(environment.d.constData()->vars, &envc);
+ }
+
+- QByteArray tmp;
+ if (!program.contains(QLatin1Char('/'))) {
++ // findExecutable() returns its argument if it's an absolute path,
++ // otherwise it searches $PATH; returns empty if not found (we handle
++ // that case much later)
+ const QString &exeFilePath = QStandardPaths::findExecutable(program);
+- if (!exeFilePath.isEmpty())
+- tmp = QFile::encodeName(exeFilePath);
++ const QByteArray &tmp = QFile::encodeName(exeFilePath);
++ argv[0] = ::strdup(tmp.constData());
++ } else {
++ argv[0] = ::strdup(QFile::encodeName(program));
+ }
+- if (tmp.isEmpty())
+- tmp = QFile::encodeName(program);
+- argv[0] = tmp.data();
+
+ if (envp)
+ qt_safe_execve(argv[0], argv, envp);
+diff --git a/qtbase/src/corelib/itemmodels/qabstractitemmodel.cpp b/qtbase/src/corelib/itemmodels/qabstractitemmodel.cpp
+index 3a79c502af..997a634e76 100644
+--- a/qtbase/src/corelib/itemmodels/qabstractitemmodel.cpp
++++ b/qtbase/src/corelib/itemmodels/qabstractitemmodel.cpp
+@@ -3196,9 +3196,8 @@ bool QAbstractItemModel::beginMoveColumns(const QModelIndex &sourceParent, int s
+ destinationChange.needsAdjust = destinationParent.isValid() && destinationParent.row() >= sourceLast && destinationParent.parent() == sourceParent;
+ d->changes.push(destinationChange);
+
+- d->itemsAboutToBeMoved(sourceParent, sourceFirst, sourceLast, destinationParent, destinationChild, Qt::Horizontal);
+-
+ emit columnsAboutToBeMoved(sourceParent, sourceFirst, sourceLast, destinationParent, destinationChild, QPrivateSignal());
++ d->itemsAboutToBeMoved(sourceParent, sourceFirst, sourceLast, destinationParent, destinationChild, Qt::Horizontal);
+ return true;
+ }
+
+@@ -3231,7 +3230,6 @@ void QAbstractItemModel::endMoveColumns()
+ adjustedSource = createIndex(adjustedSource.row(), adjustedSource.column() + numMoved, adjustedSource.internalPointer());
+
+ d->itemsMoved(adjustedSource, removeChange.first, removeChange.last, adjustedDestination, insertChange.first, Qt::Horizontal);
+-
+ emit columnsMoved(adjustedSource, removeChange.first, removeChange.last, adjustedDestination, insertChange.first, QPrivateSignal());
+ }
+
+diff --git a/qtbase/src/corelib/itemmodels/qsortfilterproxymodel.cpp b/qtbase/src/corelib/itemmodels/qsortfilterproxymodel.cpp
+index dc6379d9fb..c5e287ee84 100644
+--- a/qtbase/src/corelib/itemmodels/qsortfilterproxymodel.cpp
++++ b/qtbase/src/corelib/itemmodels/qsortfilterproxymodel.cpp
+@@ -939,8 +939,9 @@ void QSortFilterProxyModelPrivate::insert_source_items(
+ q->beginInsertColumns(proxy_parent, proxy_start, proxy_end);
+ }
+
+- for (int i = 0; i < source_items.size(); ++i)
+- proxy_to_source.insert(proxy_start + i, source_items.at(i));
++ // TODO: use the range QList::insert() overload once it is implemented (QTBUG-58633).
++ proxy_to_source.insert(proxy_start, source_items.size(), 0);
++ std::copy(source_items.cbegin(), source_items.cend(), proxy_to_source.begin() + proxy_start);
+
+ build_source_to_proxy_mapping(proxy_to_source, source_to_proxy);
+
+@@ -3123,8 +3124,9 @@ bool QSortFilterProxyModel::filterAcceptsRow(int source_row, const QModelIndex &
+
+ if (d->filter_data.isEmpty())
+ return true;
++
++ int column_count = d->model->columnCount(source_parent);
+ if (d->filter_column == -1) {
+- int column_count = d->model->columnCount(source_parent);
+ for (int column = 0; column < column_count; ++column) {
+ QModelIndex source_index = d->model->index(source_row, column, source_parent);
+ QString key = d->model->data(source_index, d->filter_role).toString();
+@@ -3133,9 +3135,10 @@ bool QSortFilterProxyModel::filterAcceptsRow(int source_row, const QModelIndex &
+ }
+ return false;
+ }
+- QModelIndex source_index = d->model->index(source_row, d->filter_column, source_parent);
+- if (!source_index.isValid()) // the column may not exist
++
++ if (d->filter_column >= column_count) // the column may not exist
+ return true;
++ QModelIndex source_index = d->model->index(source_row, d->filter_column, source_parent);
+ QString key = d->model->data(source_index, d->filter_role).toString();
+ return d->filter_data.hasMatch(key);
+ }
+diff --git a/qtbase/src/corelib/kernel/qcoreapplication.cpp b/qtbase/src/corelib/kernel/qcoreapplication.cpp
+index ca2864df83..132b2eae52 100644
+--- a/qtbase/src/corelib/kernel/qcoreapplication.cpp
++++ b/qtbase/src/corelib/kernel/qcoreapplication.cpp
+@@ -1157,7 +1157,7 @@ static bool doNotify(QObject *receiver, QEvent *event)
+ bool QCoreApplicationPrivate::sendThroughApplicationEventFilters(QObject *receiver, QEvent *event)
+ {
+ // We can't access the application event filters outside of the main thread (race conditions)
+- Q_ASSERT(receiver->d_func()->threadData.loadRelaxed()->thread.loadAcquire() == mainThread());
++ Q_ASSERT(receiver->d_func()->threadData.loadAcquire()->thread.loadRelaxed() == mainThread());
+
+ if (extraData) {
+ // application event filters are only called for objects in the GUI thread
+diff --git a/qtbase/src/corelib/kernel/qobject.cpp b/qtbase/src/corelib/kernel/qobject.cpp
+index 1eb79138d9..36cd780ee1 100644
+--- a/qtbase/src/corelib/kernel/qobject.cpp
++++ b/qtbase/src/corelib/kernel/qobject.cpp
+@@ -1010,7 +1010,7 @@ QObject::~QObject()
+ emit destroyed(this);
+ }
+
+- if (d->declarativeData) {
++ if (!d->isDeletingChildren && d->declarativeData) {
+ if (static_cast<QAbstractDeclarativeDataImpl*>(d->declarativeData)->ownedByQml1) {
+ if (QAbstractDeclarativeData::destroyed_qml1)
+ QAbstractDeclarativeData::destroyed_qml1(d->declarativeData, this);
+@@ -1580,7 +1580,7 @@ void QObject::moveToThread(QThread *targetThread)
+
+ QThreadData *currentData = QThreadData::current();
+ QThreadData *targetData = targetThread ? QThreadData::get2(targetThread) : nullptr;
+- QThreadData *thisThreadData = d->threadData.loadRelaxed();
++ QThreadData *thisThreadData = d->threadData.loadAcquire();
+ if (!thisThreadData->thread.loadAcquire() && currentData == targetData) {
+ // one exception to the rule: we allow moving objects with no thread affinity to the current thread
+ currentData = d->threadData;
+@@ -2620,7 +2620,7 @@ int QObject::receivers(const char *signal) const
+ if (!d->isSignalConnected(signal_index))
+ return receivers;
+
+- if (d->declarativeData && QAbstractDeclarativeData::receivers) {
++ if (!d->isDeletingChildren && d->declarativeData && QAbstractDeclarativeData::receivers) {
+ receivers += QAbstractDeclarativeData::receivers(d->declarativeData, this,
+ signal_index);
+ }
+diff --git a/qtbase/src/corelib/kernel/qobject_p.h b/qtbase/src/corelib/kernel/qobject_p.h
+index 0b827a52ca..13ffb88999 100644
+--- a/qtbase/src/corelib/kernel/qobject_p.h
++++ b/qtbase/src/corelib/kernel/qobject_p.h
+@@ -444,7 +444,7 @@ inline void QObjectPrivate::checkForIncompatibleLibraryVersion(int version) cons
+
+ inline bool QObjectPrivate::isDeclarativeSignalConnected(uint signal_index) const
+ {
+- return declarativeData && QAbstractDeclarativeData::isSignalConnected
++ return !isDeletingChildren && declarativeData && QAbstractDeclarativeData::isSignalConnected
+ && QAbstractDeclarativeData::isSignalConnected(declarativeData, q_func(), signal_index);
+ }
+
+diff --git a/qtbase/src/corelib/kernel/qtranslator.cpp b/qtbase/src/corelib/kernel/qtranslator.cpp
+index 2812ffb7ea..bc0177c5ec 100644
+--- a/qtbase/src/corelib/kernel/qtranslator.cpp
++++ b/qtbase/src/corelib/kernel/qtranslator.cpp
+@@ -902,7 +902,7 @@ static QString getMessage(const uchar *m, const uchar *end, const char *context,
+ goto end;
+ case Tag_Translation: {
+ int len = read32(m);
+- if (len % 1)
++ if (len & 1)
+ return QString();
+ m += 4;
+ if (!numerus--) {
+diff --git a/qtbase/src/corelib/mimetypes/qmimedatabase.cpp b/qtbase/src/corelib/mimetypes/qmimedatabase.cpp
+index 9de22cef33..ff868a3268 100644
+--- a/qtbase/src/corelib/mimetypes/qmimedatabase.cpp
++++ b/qtbase/src/corelib/mimetypes/qmimedatabase.cpp
+@@ -389,20 +389,23 @@ QMimeType QMimeDatabasePrivate::mimeTypeForFileNameAndData(const QString &fileNa
+ // Disambiguate conflicting extensions (if magic matching found something)
+ if (candidateByData.isValid() && magicAccuracy > 0) {
+ const QString sniffedMime = candidateByData.name();
+- // If the sniffedMime matches a glob match, use it
++ // If the sniffedMime matches a highest-weight glob match, use it
+ if (candidatesByName.m_matchingMimeTypes.contains(sniffedMime)) {
+ *accuracyPtr = 100;
+ return candidateByData;
+ }
+- for (const QString &m : qAsConst(candidatesByName.m_matchingMimeTypes)) {
++ for (const QString &m : qAsConst(candidatesByName.m_allMatchingMimeTypes)) {
+ if (inherits(m, sniffedMime)) {
+ // We have magic + pattern pointing to this, so it's a pretty good match
+ *accuracyPtr = 100;
+ return mimeTypeForName(m);
+ }
+ }
+- *accuracyPtr = magicAccuracy;
+- return candidateByData;
++ if (candidatesByName.m_allMatchingMimeTypes.isEmpty()) {
++ // No glob, use magic
++ *accuracyPtr = magicAccuracy;
++ return candidateByData;
++ }
+ }
+ }
+
+diff --git a/qtbase/src/corelib/mimetypes/qmimeglobpattern.cpp b/qtbase/src/corelib/mimetypes/qmimeglobpattern.cpp
+index a81112d227..fa8f4c545d 100644
+--- a/qtbase/src/corelib/mimetypes/qmimeglobpattern.cpp
++++ b/qtbase/src/corelib/mimetypes/qmimeglobpattern.cpp
+@@ -83,7 +83,10 @@ void QMimeGlobMatchResult::addMatch(const QString &mimeType, int weight, const Q
+ }
+ if (!m_matchingMimeTypes.contains(mimeType)) {
+ m_matchingMimeTypes.append(mimeType);
+- m_allMatchingMimeTypes.append(mimeType);
++ if (replace)
++ m_allMatchingMimeTypes.prepend(mimeType); // highest-weight first
++ else
++ m_allMatchingMimeTypes.append(mimeType);
+ m_knownSuffixLength = knownSuffixLength;
+ }
+ }
+@@ -94,7 +97,7 @@ QMimeGlobPattern::PatternType QMimeGlobPattern::detectPatternType(const QString
+ if (!patternLength)
+ return OtherPattern;
+
+- const bool starCount = pattern.count(QLatin1Char('*')) == 1;
++ const int starCount = pattern.count(QLatin1Char('*'));
+ const bool hasSquareBracket = pattern.indexOf(QLatin1Char('[')) != -1;
+ const bool hasQuestionMark = pattern.indexOf(QLatin1Char('?')) != -1;
+
+@@ -106,10 +109,10 @@ QMimeGlobPattern::PatternType QMimeGlobPattern::detectPatternType(const QString
+ // Patterns like "README*" (well this is currently the only one like that...)
+ if (pattern.at(patternLength - 1) == QLatin1Char('*'))
+ return PrefixPattern;
+- }
+- // Names without any wildcards like "README"
+- if (starCount == 0)
++ } else if (starCount == 0) {
++ // Names without any wildcards like "README"
+ return LiteralPattern;
++ }
+ }
+
+ if (pattern == QLatin1String("[0-9][0-9][0-9].vdr"))
+diff --git a/qtbase/src/corelib/mimetypes/qmimeprovider.cpp b/qtbase/src/corelib/mimetypes/qmimeprovider.cpp
+index 258dddf8cb..4642d0f2d0 100644
+--- a/qtbase/src/corelib/mimetypes/qmimeprovider.cpp
++++ b/qtbase/src/corelib/mimetypes/qmimeprovider.cpp
+@@ -244,15 +244,18 @@ void QMimeBinaryProvider::addFileNameMatches(const QString &fileName, QMimeGlobM
+ const QString lowerFileName = fileName.toLower();
+ // Check literals (e.g. "Makefile")
+ matchGlobList(result, m_cacheFile, m_cacheFile->getUint32(PosLiteralListOffset), fileName);
+- // Check complex globs (e.g. "callgrind.out[0-9]*")
+- matchGlobList(result, m_cacheFile, m_cacheFile->getUint32(PosGlobListOffset), fileName);
+ // Check the very common *.txt cases with the suffix tree
+- const int reverseSuffixTreeOffset = m_cacheFile->getUint32(PosReverseSuffixTreeOffset);
+- const int numRoots = m_cacheFile->getUint32(reverseSuffixTreeOffset);
+- const int firstRootOffset = m_cacheFile->getUint32(reverseSuffixTreeOffset + 4);
+- matchSuffixTree(result, m_cacheFile, numRoots, firstRootOffset, lowerFileName, lowerFileName.length() - 1, false);
++ if (result.m_matchingMimeTypes.isEmpty()) {
++ const int reverseSuffixTreeOffset = m_cacheFile->getUint32(PosReverseSuffixTreeOffset);
++ const int numRoots = m_cacheFile->getUint32(reverseSuffixTreeOffset);
++ const int firstRootOffset = m_cacheFile->getUint32(reverseSuffixTreeOffset + 4);
++ matchSuffixTree(result, m_cacheFile, numRoots, firstRootOffset, lowerFileName, lowerFileName.length() - 1, false);
++ if (result.m_matchingMimeTypes.isEmpty())
++ matchSuffixTree(result, m_cacheFile, numRoots, firstRootOffset, fileName, fileName.length() - 1, true);
++ }
++ // Check complex globs (e.g. "callgrind.out[0-9]*" or "README*")
+ if (result.m_matchingMimeTypes.isEmpty())
+- matchSuffixTree(result, m_cacheFile, numRoots, firstRootOffset, fileName, fileName.length() - 1, true);
++ matchGlobList(result, m_cacheFile, m_cacheFile->getUint32(PosGlobListOffset), fileName);
+ }
+
+ void QMimeBinaryProvider::matchGlobList(QMimeGlobMatchResult &result, CacheFile *cacheFile, int off, const QString &fileName)
+diff --git a/qtbase/src/corelib/serialization/qjsonparser.cpp b/qtbase/src/corelib/serialization/qjsonparser.cpp
+index 17e6f111ab..2e40b6c8fb 100644
+--- a/qtbase/src/corelib/serialization/qjsonparser.cpp
++++ b/qtbase/src/corelib/serialization/qjsonparser.cpp
+@@ -379,10 +379,30 @@ error:
+ return QCborValue();
+ }
+
++// We need to retain the _last_ value for any duplicate keys and we need to deref containers.
++// Therefore the manual implementation of std::unique().
++template<typename Iterator, typename Compare, typename Assign>
++static Iterator customAssigningUniqueLast(Iterator first, Iterator last,
++ Compare compare, Assign assign)
++{
++ first = std::adjacent_find(first, last, compare);
++ if (first == last)
++ return last;
++
++ Iterator result = first;
++ while (++first != last) {
++ if (!compare(*result, *first))
++ ++result;
++ if (result != first)
++ assign(*result, *first);
++ }
++
++ return ++result;
++}
++
+ static void sortContainer(QCborContainerPrivate *container)
+ {
+ using Forward = QJsonPrivate::KeyIterator;
+- using Reverse = std::reverse_iterator<Forward>;
+ using Value = Forward::value_type;
+
+ auto compare = [container](const Value &a, const Value &b)
+@@ -420,17 +440,31 @@ static void sortContainer(QCborContainerPrivate *container)
+ }
+ };
+
+- std::sort(Forward(container->elements.begin()), Forward(container->elements.end()),
+- [&compare](const Value &a, const Value &b) { return compare(a, b) < 0; });
++ // The elements' containers are owned by the outer container, not by the elements themselves.
++ auto move = [](Forward::reference target, Forward::reference source)
++ {
++ QtCbor::Element &targetValue = target.value();
++
++ // If the target has a container, deref it before overwriting, so that we don't leak.
++ if (targetValue.flags & QtCbor::Element::IsContainer)
++ targetValue.container->deref();
++
++ // Do not move, so that we can clear the value afterwards.
++ target = source;
++
++ // Clear the source value, so that we don't store the same container twice.
++ source.value() = QtCbor::Element();
++ };
++
++ std::stable_sort(
++ Forward(container->elements.begin()), Forward(container->elements.end()),
++ [&compare](const Value &a, const Value &b) { return compare(a, b) < 0; });
+
+- // We need to retain the _last_ value for any duplicate keys. Therefore the reverse dance here.
+- auto it = std::unique(Reverse(container->elements.end()), Reverse(container->elements.begin()),
+- [&compare](const Value &a, const Value &b) {
+- return compare(a, b) == 0;
+- }).base().elementsIterator();
++ Forward result = customAssigningUniqueLast(
++ Forward(container->elements.begin()), Forward(container->elements.end()),
++ [&compare](const Value &a, const Value &b) { return compare(a, b) == 0; }, move);
+
+- // The erase from beginning is expensive but hopefully rare.
+- container->elements.erase(container->elements.begin(), it);
++ container->elements.erase(result.elementsIterator(), container->elements.end());
+ }
+
+
+diff --git a/qtbase/src/corelib/serialization/qxmlstream.cpp b/qtbase/src/corelib/serialization/qxmlstream.cpp
+index b2f846544d..7cd457ba3a 100644
+--- a/qtbase/src/corelib/serialization/qxmlstream.cpp
++++ b/qtbase/src/corelib/serialization/qxmlstream.cpp
+@@ -980,7 +980,7 @@ inline uint QXmlStreamReaderPrivate::peekChar()
+ bool QXmlStreamReaderPrivate::scanUntil(const char *str, short tokenToInject)
+ {
+ int pos = textBuffer.size();
+- int oldLineNumber = lineNumber;
++ const auto oldLineNumber = lineNumber;
+
+ uint c;
+ while ((c = getChar()) != StreamEOF) {
+diff --git a/qtbase/src/corelib/text/qstring.cpp b/qtbase/src/corelib/text/qstring.cpp
+index 3e88ab4859..8deeae47bb 100644
+--- a/qtbase/src/corelib/text/qstring.cpp
++++ b/qtbase/src/corelib/text/qstring.cpp
+@@ -12312,7 +12312,7 @@ static qsizetype qLastIndexOf(Haystack haystack0, qsizetype from,
+ const auto needle = needle0.data();
+ const auto *end = haystack;
+ haystack += from;
+- const std::size_t sl_minus_1 = sl - 1;
++ const std::size_t sl_minus_1 = sl ? sl - 1 : 0;
+ const auto *n = needle + sl_minus_1;
+ const auto *h = haystack + sl_minus_1;
+ std::size_t hashNeedle = 0, hashHaystack = 0;
+diff --git a/qtbase/src/corelib/text/qstringiterator_p.h b/qtbase/src/corelib/text/qstringiterator_p.h
+index 219589b6e4..1d0c66cc78 100644
+--- a/qtbase/src/corelib/text/qstringiterator_p.h
++++ b/qtbase/src/corelib/text/qstringiterator_p.h
+@@ -61,6 +61,8 @@ class QStringIterator
+ {
+ QString::const_iterator i, pos, e;
+ Q_STATIC_ASSERT((std::is_same<QString::const_iterator, const QChar *>::value));
++ static bool less(const QChar *lhs, const QChar *rhs) noexcept
++ { return std::less<QString::const_iterator>{}(lhs, rhs); }
+ public:
+ explicit QStringIterator(QStringView string, qsizetype idx = 0)
+ : i(string.begin()),
+@@ -95,7 +97,8 @@ public:
+
+ inline void setPosition(QString::const_iterator position)
+ {
+- Q_ASSERT_X(i <= position && position <= e, Q_FUNC_INFO, "position out of bounds");
++ Q_ASSERT_X(!less(position, i) && !less(e, position),
++ Q_FUNC_INFO, "position out of bounds");
+ pos = position;
+ }
+
+@@ -103,7 +106,7 @@ public:
+
+ inline bool hasNext() const
+ {
+- return pos < e;
++ return less(pos, e);
+ }
+
+ inline void advance()
+@@ -120,16 +123,20 @@ public:
+ {
+ Q_ASSERT_X(hasNext(), Q_FUNC_INFO, "iterator hasn't a next item");
+
+- if (Q_UNLIKELY((pos++)->isHighSurrogate()))
++ if (Q_UNLIKELY((pos++)->isHighSurrogate())) {
++ Q_ASSERT(hasNext() && pos->isLowSurrogate());
+ ++pos;
++ }
+ }
+
+ inline uint peekNextUnchecked() const
+ {
+ Q_ASSERT_X(hasNext(), Q_FUNC_INFO, "iterator hasn't a next item");
+
+- if (Q_UNLIKELY(pos->isHighSurrogate()))
++ if (Q_UNLIKELY(pos->isHighSurrogate())) {
++ Q_ASSERT(less(pos + 1, e) && pos[1].isLowSurrogate());
+ return QChar::surrogateToUcs4(pos[0], pos[1]);
++ }
+
+ return pos->unicode();
+ }
+@@ -155,8 +162,10 @@ public:
+ Q_ASSERT_X(hasNext(), Q_FUNC_INFO, "iterator hasn't a next item");
+
+ const QChar cur = *pos++;
+- if (Q_UNLIKELY(cur.isHighSurrogate()))
++ if (Q_UNLIKELY(cur.isHighSurrogate())) {
++ Q_ASSERT(hasNext() && pos->isLowSurrogate());
+ return QChar::surrogateToUcs4(cur, *pos++);
++ }
+ return cur.unicode();
+ }
+
+@@ -166,7 +175,7 @@ public:
+
+ const QChar uc = *pos++;
+ if (Q_UNLIKELY(uc.isSurrogate())) {
+- if (Q_LIKELY(uc.isHighSurrogate() && pos < e && pos->isLowSurrogate()))
++ if (Q_LIKELY(uc.isHighSurrogate() && hasNext() && pos->isLowSurrogate()))
+ return QChar::surrogateToUcs4(uc, *pos++);
+ return invalidAs;
+ }
+@@ -178,7 +187,7 @@ public:
+
+ inline bool hasPrevious() const
+ {
+- return pos > i;
++ return less(i, pos);
+ }
+
+ inline void recede()
+@@ -196,16 +205,20 @@ public:
+ {
+ Q_ASSERT_X(hasPrevious(), Q_FUNC_INFO, "iterator hasn't a previous item");
+
+- if (Q_UNLIKELY((--pos)->isLowSurrogate()))
++ if (Q_UNLIKELY((--pos)->isLowSurrogate())) {
++ Q_ASSERT(hasPrevious() && pos[-1].isHighSurrogate());
+ --pos;
++ }
+ }
+
+ inline uint peekPreviousUnchecked() const
+ {
+ Q_ASSERT_X(hasPrevious(), Q_FUNC_INFO, "iterator hasn't a previous item");
+
+- if (Q_UNLIKELY(pos[-1].isLowSurrogate()))
++ if (Q_UNLIKELY(pos[-1].isLowSurrogate())) {
++ Q_ASSERT(less(i + 1, pos) && pos[-2].isHighSurrogate());
+ return QChar::surrogateToUcs4(pos[-2], pos[-1]);
++ }
+ return pos[-1].unicode();
+ }
+
+@@ -230,8 +243,10 @@ public:
+ Q_ASSERT_X(hasPrevious(), Q_FUNC_INFO, "iterator hasn't a previous item");
+
+ const QChar cur = *--pos;
+- if (Q_UNLIKELY(cur.isLowSurrogate()))
++ if (Q_UNLIKELY(cur.isLowSurrogate())) {
++ Q_ASSERT(hasPrevious() && pos[-1].isHighSurrogate());
+ return QChar::surrogateToUcs4(*--pos, cur);
++ }
+ return cur.unicode();
+ }
+
+@@ -241,7 +256,7 @@ public:
+
+ const QChar uc = *--pos;
+ if (Q_UNLIKELY(uc.isSurrogate())) {
+- if (Q_LIKELY(uc.isLowSurrogate() && pos > i && pos[-1].isHighSurrogate()))
++ if (Q_LIKELY(uc.isLowSurrogate() && hasPrevious() && pos[-1].isHighSurrogate()))
+ return QChar::surrogateToUcs4(*--pos, uc);
+ return invalidAs;
+ }
+diff --git a/qtbase/src/corelib/thread/qfutex_p.h b/qtbase/src/corelib/thread/qfutex_p.h
+index f287b752d7..e294537787 100644
+--- a/qtbase/src/corelib/thread/qfutex_p.h
++++ b/qtbase/src/corelib/thread/qfutex_p.h
+@@ -52,6 +52,7 @@
+ //
+
+ #include <qglobal.h>
++#include <QtCore/qtsan_impl.h>
+
+ QT_BEGIN_NAMESPACE
+
+@@ -106,16 +107,13 @@ namespace QtLinuxFutex {
+ inline int _q_futex(int *addr, int op, int val, quintptr val2 = 0,
+ int *addr2 = nullptr, int val3 = 0) noexcept
+ {
+- // A futex call ensures total ordering on the futex words
+- // (in either success or failure of the call). Instruct TSAN accordingly,
+- // as TSAN does not understand the futex(2) syscall.
+- _q_tsan_release(addr, addr2);
++ QtTsan::futexRelease(addr, addr2);
+
+ // we use __NR_futex because some libcs (like Android's bionic) don't
+ // provide SYS_futex etc.
+ int result = syscall(__NR_futex, addr, op | FUTEX_PRIVATE_FLAG, val, val2, addr2, val3);
+
+- _q_tsan_acquire(addr, addr2);
++ QtTsan::futexAcquire(addr, addr2);
+
+ return result;
+ }
+diff --git a/qtbase/src/corelib/thread/qmutex.cpp b/qtbase/src/corelib/thread/qmutex.cpp
+index 310d1cb14f..7097122d8e 100644
+--- a/qtbase/src/corelib/thread/qmutex.cpp
++++ b/qtbase/src/corelib/thread/qmutex.cpp
+@@ -152,6 +152,7 @@ public:
+
+ /*!
+ \enum QMutex::RecursionMode
++ \obsolete Use QRecursiveMutex to create a recursive mutex.
+
+ \value Recursive In this mode, a thread can lock the same mutex
+ multiple times and the mutex won't be unlocked
+@@ -173,6 +174,7 @@ public:
+
+ /*!
+ Constructs a new mutex. The mutex is created in an unlocked state.
++ \obsolete Use QRecursiveMutex to create a recursive mutex.
+
+ If \a mode is QMutex::Recursive, a thread can lock the same mutex
+ multiple times and the mutex won't be unlocked until a
+@@ -197,7 +199,7 @@ QMutex::QMutex(RecursionMode mode)
+ QMutex::~QMutex()
+ {
+ QMutexData *d = d_ptr.loadRelaxed();
+- if (isRecursive()) {
++ if (QBasicMutex::isRecursive()) {
+ delete static_cast<QRecursiveMutexPrivate *>(d);
+ } else if (d) {
+ #ifndef QT_LINUX_FUTEX
+diff --git a/qtbase/src/corelib/thread/qmutex.h b/qtbase/src/corelib/thread/qmutex.h
+index 73c9e00663..1bae573a03 100644
+--- a/qtbase/src/corelib/thread/qmutex.h
++++ b/qtbase/src/corelib/thread/qmutex.h
+@@ -42,6 +42,7 @@
+
+ #include <QtCore/qglobal.h>
+ #include <QtCore/qatomic.h>
++#include <QtCore/qtsan_impl.h>
+ #include <new>
+
+ #if __has_include(<chrono>)
+@@ -77,19 +78,37 @@ public:
+
+ // BasicLockable concept
+ inline void lock() QT_MUTEX_LOCK_NOEXCEPT {
++ QtTsan::mutexPreLock(this, 0u);
++
+ if (!fastTryLock())
+ lockInternal();
++
++ QtTsan::mutexPostLock(this, 0u, 0);
+ }
+
+ // BasicLockable concept
+ inline void unlock() noexcept {
+ Q_ASSERT(d_ptr.loadRelaxed()); //mutex must be locked
++
++ QtTsan::mutexPreUnlock(this, 0u);
++
+ if (!fastTryUnlock())
+ unlockInternal();
++
++ QtTsan::mutexPostUnlock(this, 0u);
+ }
+
+ bool tryLock() noexcept {
+- return fastTryLock();
++ unsigned tsanFlags = QtTsan::TryLock;
++ QtTsan::mutexPreLock(this, tsanFlags);
++
++ const bool success = fastTryLock();
++
++ if (!success)
++ tsanFlags |= QtTsan::TryLockFailed;
++ QtTsan::mutexPostLock(this, tsanFlags, 0);
++
++ return success;
+ }
+
+ // Lockable concept
+@@ -134,8 +153,16 @@ public:
+ #else
+ QMutex() { d_ptr.storeRelaxed(nullptr); }
+ #endif
++#if QT_DEPRECATED_SINCE(5,15)
+ enum RecursionMode { NonRecursive, Recursive };
++ QT_DEPRECATED_VERSION_X(5, 15, "Use QRecursiveMutex instead of a recursive QMutex")
+ explicit QMutex(RecursionMode mode);
++
++ QT_DEPRECATED_VERSION_X(5, 15, "Use QRecursiveMutex instead of a recursive QMutex")
++ bool isRecursive() const noexcept
++ { return QBasicMutex::isRecursive(); }
++#endif
++
+ ~QMutex();
+
+ // BasicLockable concept
+@@ -166,9 +193,6 @@ public:
+ }
+ #endif
+
+- bool isRecursive() const noexcept
+- { return QBasicMutex::isRecursive(); }
+-
+ private:
+ Q_DISABLE_COPY(QMutex)
+ friend class QMutexLocker;
+diff --git a/qtbase/src/corelib/thread/qreadwritelock.cpp b/qtbase/src/corelib/thread/qreadwritelock.cpp
+index 8c28507d5a..9dd8503116 100644
+--- a/qtbase/src/corelib/thread/qreadwritelock.cpp
++++ b/qtbase/src/corelib/thread/qreadwritelock.cpp
+@@ -155,7 +155,7 @@ QReadWriteLock::QReadWriteLock(RecursionMode recursionMode)
+ */
+ QReadWriteLock::~QReadWriteLock()
+ {
+- auto d = d_ptr.loadRelaxed();
++ auto d = d_ptr.loadAcquire();
+ if (isUncontendedLocked(d)) {
+ qWarning("QReadWriteLock: destroying locked QReadWriteLock");
+ return;
+@@ -445,7 +445,7 @@ void QReadWriteLock::unlock()
+ /*! \internal Helper for QWaitCondition::wait */
+ QReadWriteLock::StateForWaitCondition QReadWriteLock::stateForWaitCondition() const
+ {
+- QReadWriteLockPrivate *d = d_ptr.loadRelaxed();
++ QReadWriteLockPrivate *d = d_ptr.loadAcquire();
+ switch (quintptr(d) & StateMask) {
+ case StateLockedForRead: return LockedForRead;
+ case StateLockedForWrite: return LockedForWrite;
+@@ -453,6 +453,7 @@ QReadWriteLock::StateForWaitCondition QReadWriteLock::stateForWaitCondition() co
+
+ if (!d)
+ return Unlocked;
++ const auto lock = qt_scoped_lock(d->mutex);
+ if (d->writerCount > 1)
+ return RecursivelyLocked;
+ else if (d->writerCount == 1)
+diff --git a/qtbase/src/corelib/thread/qsemaphore.cpp b/qtbase/src/corelib/thread/qsemaphore.cpp
+index 1d01fc1b28..3ecdee3747 100644
+--- a/qtbase/src/corelib/thread/qsemaphore.cpp
++++ b/qtbase/src/corelib/thread/qsemaphore.cpp
+@@ -354,7 +354,12 @@ void QSemaphore::release(int n)
+ quintptr nn = unsigned(n);
+ if (futexHasWaiterCount)
+ nn |= quint64(nn) << 32; // token count replicated in high word
+- quintptr prevValue = u.fetchAndAddRelease(nn);
++ quintptr prevValue = u.loadRelaxed();
++ quintptr newValue;
++ do { // loop just to ensure the operations are done atomically
++ newValue = prevValue + nn;
++ newValue &= (futexNeedsWakeAllBit - 1);
++ } while (!u.testAndSetRelease(prevValue, newValue, prevValue));
+ if (futexNeedsWake(prevValue)) {
+ #ifdef FUTEX_OP
+ if (futexHasWaiterCount) {
+@@ -376,7 +381,6 @@ void QSemaphore::release(int n)
+ quint32 oparg = 0;
+ quint32 cmp = FUTEX_OP_CMP_NE;
+ quint32 cmparg = 0;
+- u.fetchAndAndRelease(futexNeedsWakeAllBit - 1);
+ futexWakeOp(*futexLow32(&u), n, INT_MAX, *futexHigh32(&u), FUTEX_OP(op, oparg, cmp, cmparg));
+ return;
+ }
+@@ -388,7 +392,6 @@ void QSemaphore::release(int n)
+ // its acquisition anyway, so it has to wait;
+ // 2) it did not see the new counter value, in which case its
+ // futexWait will fail.
+- u.fetchAndAndRelease(futexNeedsWakeAllBit - 1);
+ if (futexHasWaiterCount) {
+ futexWakeAll(*futexLow32(&u));
+ futexWakeAll(*futexHigh32(&u));
+diff --git a/qtbase/src/corelib/thread/qthread_p.h b/qtbase/src/corelib/thread/qthread_p.h
+index b2d1628e6e..f32f6f0460 100644
+--- a/qtbase/src/corelib/thread/qthread_p.h
++++ b/qtbase/src/corelib/thread/qthread_p.h
+@@ -174,7 +174,7 @@ public:
+ int returnCode;
+
+ uint stackSize;
+- QThread::Priority priority;
++ std::underlying_type<QThread::Priority>::type priority;
+
+ static QThread *threadForId(int id);
+
+@@ -213,6 +213,13 @@ public:
+ QCoreApplication::instance()->postEvent(q_ptr, new QEvent(QEvent::Quit));
+ }
+ }
++
++#ifndef Q_OS_INTEGRITY
++private:
++ // Used in QThread(Private)::start to avoid racy access to QObject::objectName,
++ // unset afterwards. On INTEGRITY we set the thread name before starting it.
++ QString objectName;
++#endif
+ };
+
+ #else // QT_CONFIG(thread)
+diff --git a/qtbase/src/corelib/thread/qthread_unix.cpp b/qtbase/src/corelib/thread/qthread_unix.cpp
+index 56a8e0a038..610117a640 100644
+--- a/qtbase/src/corelib/thread/qthread_unix.cpp
++++ b/qtbase/src/corelib/thread/qthread_unix.cpp
+@@ -169,8 +169,7 @@ static void set_thread_data(QThreadData *data)
+
+ static void clear_thread_data()
+ {
+- currentThreadData = nullptr;
+- pthread_setspecific(current_thread_data_key, nullptr);
++ set_thread_data(nullptr);
+ }
+
+ template <typename T>
+@@ -296,7 +295,7 @@ void *QThreadPrivate::start(void *arg)
+ QMutexLocker locker(&thr->d_func()->mutex);
+
+ // do we need to reset the thread priority?
+- if (int(thr->d_func()->priority) & ThreadPriorityResetFlag) {
++ if (thr->d_func()->priority & ThreadPriorityResetFlag) {
+ thr->d_func()->setPriority(QThread::Priority(thr->d_func()->priority & ~ThreadPriorityResetFlag));
+ }
+
+@@ -316,10 +315,10 @@ void *QThreadPrivate::start(void *arg)
+ // Sets the name of the current thread. We can only do this
+ // when the thread is starting, as we don't have a cross
+ // platform way of setting the name of an arbitrary thread.
+- if (Q_LIKELY(thr->objectName().isEmpty()))
++ if (Q_LIKELY(thr->d_func()->objectName.isEmpty()))
+ setCurrentThreadName(thr->metaObject()->className());
+ else
+- setCurrentThreadName(thr->objectName().toLocal8Bit());
++ setCurrentThreadName(std::exchange(thr->d_func()->objectName, {}).toLocal8Bit());
+ }
+ #endif
+
+@@ -671,7 +670,7 @@ void QThread::start(Priority priority)
+ // could not set scheduling hints, fallback to inheriting them
+ // we'll try again from inside the thread
+ pthread_attr_setinheritsched(&attr, PTHREAD_INHERIT_SCHED);
+- d->priority = Priority(priority | ThreadPriorityResetFlag);
++ d->priority = static_cast<std::underlying_type<QThread::Priority>::type>(priority) | ThreadPriorityResetFlag;
+ }
+ break;
+ }
+@@ -702,7 +701,10 @@ void QThread::start(Priority priority)
+ pthread_attr_setthreadname(&attr, metaObject()->className());
+ else
+ pthread_attr_setthreadname(&attr, objectName().toLocal8Bit());
++#else
++ d->objectName = objectName();
+ #endif
++
+ pthread_t threadId;
+ int code = pthread_create(&threadId, &attr, QThreadPrivate::start, this);
+ if (code == EPERM) {
+diff --git a/qtbase/src/corelib/thread/qthread_win.cpp b/qtbase/src/corelib/thread/qthread_win.cpp
+index bc70e3178a..4e76972498 100644
+--- a/qtbase/src/corelib/thread/qthread_win.cpp
++++ b/qtbase/src/corelib/thread/qthread_win.cpp
+@@ -394,10 +394,9 @@ unsigned int __stdcall QT_ENSURE_STACK_ALIGNED_FOR_SSE QThreadPrivate::start(voi
+
+ #if !defined(QT_NO_DEBUG) && defined(Q_CC_MSVC) && !defined(Q_OS_WINRT)
+ // sets the name of the current thread.
+- QByteArray objectName = thr->objectName().toLocal8Bit();
+- qt_set_thread_name(HANDLE(-1),
+- objectName.isEmpty() ?
+- thr->metaObject()->className() : objectName.constData());
++ qt_set_thread_name(HANDLE(-1), thr->d_func()->objectName.isEmpty()
++ ? thr->metaObject()->className()
++ : std::exchange(thr->d_func()->objectName, {}).toLocal8Bit().constData());
+ #endif
+
+ emit thr->started(QThread::QPrivateSignal());
+@@ -503,6 +502,7 @@ void QThread::start(Priority priority)
+ if (d->running)
+ return;
+
++ d->objectName = objectName();
+ d->running = true;
+ d->finished = false;
+ d->exited = false;
+@@ -548,7 +548,7 @@ void QThread::start(Priority priority)
+
+ int prio;
+ d->priority = priority;
+- switch (d->priority) {
++ switch (priority) {
+ case IdlePriority:
+ prio = THREAD_PRIORITY_IDLE;
+ break;
+@@ -686,7 +686,7 @@ void QThreadPrivate::setPriority(QThread::Priority threadPriority)
+
+ int prio;
+ priority = threadPriority;
+- switch (priority) {
++ switch (threadPriority) {
+ case QThread::IdlePriority:
+ prio = THREAD_PRIORITY_IDLE;
+ break;
+diff --git a/qtbase/src/corelib/thread/qtsan_impl.h b/qtbase/src/corelib/thread/qtsan_impl.h
+new file mode 100644
+index 0000000000..580a738b91
+--- /dev/null
++++ b/qtbase/src/corelib/thread/qtsan_impl.h
+@@ -0,0 +1,115 @@
++/****************************************************************************
++**
++** Copyright (C) 2017 Intel Corporation.
++** Copyright (C) 2022 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Giuseppe D'Angelo <giuseppe.dangelo@kdab.com>
++** Contact: https://www.qt.io/licensing/
++**
++** This file is part of the QtCore module of the Qt Toolkit.
++**
++** $QT_BEGIN_LICENSE:LGPL$
++** Commercial License Usage
++** Licensees holding valid commercial Qt licenses may use this file in
++** accordance with the commercial license agreement provided with the
++** Software or, alternatively, in accordance with the terms contained in
++** a written agreement between you and The Qt Company. For licensing terms
++** and conditions see https://www.qt.io/terms-conditions. For further
++** information use the contact form at https://www.qt.io/contact-us.
++**
++** GNU Lesser General Public License Usage
++** Alternatively, this file may be used under the terms of the GNU Lesser
++** General Public License version 3 as published by the Free Software
++** Foundation and appearing in the file LICENSE.LGPL3 included in the
++** packaging of this file. Please review the following information to
++** ensure the GNU Lesser General Public License version 3 requirements
++** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
++**
++** GNU General Public License Usage
++** Alternatively, this file may be used under the terms of the GNU
++** General Public License version 2.0 or (at your option) the GNU General
++** Public license version 3 or any later version approved by the KDE Free
++** Qt Foundation. The licenses are as published by the Free Software
++** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
++** included in the packaging of this file. Please review the following
++** information to ensure the GNU General Public License requirements will
++** be met: https://www.gnu.org/licenses/gpl-2.0.html and
++** https://www.gnu.org/licenses/gpl-3.0.html.
++**
++** $QT_END_LICENSE$
++**
++****************************************************************************/
++
++#ifndef QTSAN_IMPL_H
++#define QTSAN_IMPL_H
++
++#include <QtCore/qglobal.h>
++
++#if (__has_feature(thread_sanitizer) || defined(__SANITIZE_THREAD__)) && __has_include(<sanitizer/tsan_interface.h>)
++# define QT_BUILDING_UNDER_TSAN
++# include <sanitizer/tsan_interface.h>
++#endif
++
++QT_BEGIN_NAMESPACE
++
++namespace QtTsan {
++#ifdef QT_BUILDING_UNDER_TSAN
++inline void futexAcquire(void *addr, void *addr2 = nullptr)
++{
++ // A futex call ensures total ordering on the futex words
++ // (in either success or failure of the call). Instruct TSAN accordingly,
++ // as TSAN does not understand the futex(2) syscall (or equivalent).
++ ::__tsan_acquire(addr);
++ if (addr2)
++ ::__tsan_acquire(addr2);
++}
++
++inline void futexRelease(void *addr, void *addr2 = nullptr)
++{
++ if (addr2)
++ ::__tsan_release(addr2);
++ ::__tsan_release(addr);
++}
++
++inline void mutexPreLock(void *addr, unsigned flags)
++{
++ ::__tsan_mutex_pre_lock(addr, flags);
++}
++
++inline void mutexPostLock(void *addr, unsigned flags, int recursion)
++{
++ ::__tsan_mutex_post_lock(addr, flags, recursion);
++}
++
++inline void mutexPreUnlock(void *addr, unsigned flags)
++{
++ ::__tsan_mutex_pre_unlock(addr, flags);
++}
++
++inline void mutexPostUnlock(void *addr, unsigned flags)
++{
++ ::__tsan_mutex_post_unlock(addr, flags);
++}
++
++enum : unsigned {
++ MutexWriteReentrant = ::__tsan_mutex_write_reentrant,
++ TryLock = ::__tsan_mutex_try_lock,
++ TryLockFailed = ::__tsan_mutex_try_lock_failed,
++};
++#else
++inline void futexAcquire(void *, void * = nullptr) {}
++inline void futexRelease(void *, void * = nullptr) {}
++
++enum : unsigned {
++ MutexWriteReentrant,
++ TryLock,
++ TryLockFailed,
++};
++inline void mutexPreLock(void *, unsigned) {}
++inline void mutexPostLock(void *, unsigned, int) {}
++inline void mutexPreUnlock(void *, unsigned) {}
++inline void mutexPostUnlock(void *, unsigned) {}
++#endif // QT_BUILDING_UNDER_TSAN
++} // namespace QtTsan
++
++QT_END_NAMESPACE
++
++#endif // QTSAN_IMPL_H
+diff --git a/qtbase/src/corelib/thread/qwaitcondition_unix.cpp b/qtbase/src/corelib/thread/qwaitcondition_unix.cpp
+index 88b058f410..0f1da4dc9b 100644
+--- a/qtbase/src/corelib/thread/qwaitcondition_unix.cpp
++++ b/qtbase/src/corelib/thread/qwaitcondition_unix.cpp
+@@ -213,7 +213,7 @@ bool QWaitCondition::wait(QMutex *mutex, QDeadlineTimer deadline)
+ {
+ if (! mutex)
+ return false;
+- if (mutex->isRecursive()) {
++ if (static_cast<QBasicMutex *>(mutex)->isRecursive()) {
+ qWarning("QWaitCondition: cannot wait on recursive mutexes");
+ return false;
+ }
+diff --git a/qtbase/src/corelib/time/qdatetime.cpp b/qtbase/src/corelib/time/qdatetime.cpp
+index ec12569e3f..2c0b098079 100644
+--- a/qtbase/src/corelib/time/qdatetime.cpp
++++ b/qtbase/src/corelib/time/qdatetime.cpp
+@@ -43,6 +43,7 @@
+ #if QT_CONFIG(datetimeparser)
+ #include "private/qdatetimeparser_p.h"
+ #endif
++#include <private/qnumeric_p.h>
+
+ #include "qdatastream.h"
+ #include "qset.h"
+@@ -1429,9 +1430,11 @@ QDate QDate::addDays(qint64 ndays) const
+ if (isNull())
+ return QDate();
+
+- // Due to limits on minJd() and maxJd() we know that any overflow
+- // will be invalid and caught by fromJulianDay().
+- return fromJulianDay(jd + ndays);
++ qint64 r;
++ if (Q_UNLIKELY(add_overflow(jd, ndays, &r)))
++ return QDate();
++ else
++ return fromJulianDay(r);
+ }
+
+ /*!
+diff --git a/qtbase/src/corelib/time/qtimezone.cpp b/qtbase/src/corelib/time/qtimezone.cpp
+index 0309e43e52..3d451696a1 100644
+--- a/qtbase/src/corelib/time/qtimezone.cpp
++++ b/qtbase/src/corelib/time/qtimezone.cpp
+@@ -1,6 +1,6 @@
+ /****************************************************************************
+ **
+-** Copyright (C) 2013 John Layt <jlayt@kde.org>
++** Copyright (C) 2020 John Layt <jlayt@kde.org>
+ ** Contact: https://www.qt.io/licensing/
+ **
+ ** This file is part of the QtCore module of the Qt Toolkit.
+@@ -975,9 +975,15 @@ QList<QByteArray> QTimeZone::windowsIdToIanaIds(const QByteArray &windowsId,
+ }
+
+ #ifndef QT_NO_DATASTREAM
++// Invalid, as an IANA ID: too long, starts with - and has other invalid characters in it
++static inline QString invalidId() { return QStringLiteral("-No Time Zone Specified!"); }
++
+ QDataStream &operator<<(QDataStream &ds, const QTimeZone &tz)
+ {
+- tz.d->serialize(ds);
++ if (tz.isValid())
++ tz.d->serialize(ds);
++ else
++ ds << invalidId();
+ return ds;
+ }
+
+@@ -985,7 +991,9 @@ QDataStream &operator>>(QDataStream &ds, QTimeZone &tz)
+ {
+ QString ianaId;
+ ds >> ianaId;
+- if (ianaId == QLatin1String("OffsetFromUtc")) {
++ if (ianaId == invalidId()) {
++ tz = QTimeZone();
++ } else if (ianaId == QLatin1String("OffsetFromUtc")) {
+ int utcOffset;
+ QString name;
+ QString abbreviation;
+diff --git a/qtbase/src/corelib/time/qtimezoneprivate_tz.cpp b/qtbase/src/corelib/time/qtimezoneprivate_tz.cpp
+index b1611d7ddb..a7a6a72ccf 100644
+--- a/qtbase/src/corelib/time/qtimezoneprivate_tz.cpp
++++ b/qtbase/src/corelib/time/qtimezoneprivate_tz.cpp
+@@ -42,6 +42,7 @@
+ #include "qtimezone.h"
+ #include "qtimezoneprivate_p.h"
+ #include "private/qlocale_tools_p.h"
++#include "private/qlocking_p.h"
+
+ #include <QtCore/QDataStream>
+ #include <QtCore/QDateTime>
+@@ -62,6 +63,10 @@
+
+ QT_BEGIN_NAMESPACE
+
++#if QT_CONFIG(icu)
++static QBasicMutex s_icu_mutex;
++#endif
++
+ /*
+ Private
+
+@@ -670,6 +675,9 @@ QTzTimeZonePrivate::~QTzTimeZonePrivate()
+
+ QTzTimeZonePrivate *QTzTimeZonePrivate::clone() const
+ {
++#if QT_CONFIG(icu)
++ const auto lock = qt_scoped_lock(s_icu_mutex);
++#endif
+ return new QTzTimeZonePrivate(*this);
+ }
+
+@@ -913,12 +921,14 @@ QString QTzTimeZonePrivate::displayName(qint64 atMSecsSinceEpoch,
+ const QLocale &locale) const
+ {
+ #if QT_CONFIG(icu)
++ auto lock = qt_unique_lock(s_icu_mutex);
+ if (!m_icu)
+ m_icu = new QIcuTimeZonePrivate(m_id);
+ // TODO small risk may not match if tran times differ due to outdated files
+ // TODO Some valid TZ names are not valid ICU names, use translation table?
+ if (m_icu->isValid())
+ return m_icu->displayName(atMSecsSinceEpoch, nameType, locale);
++ lock.unlock();
+ #else
+ Q_UNUSED(nameType)
+ Q_UNUSED(locale)
+@@ -932,12 +942,14 @@ QString QTzTimeZonePrivate::displayName(QTimeZone::TimeType timeType,
+ const QLocale &locale) const
+ {
+ #if QT_CONFIG(icu)
++ auto lock = qt_unique_lock(s_icu_mutex);
+ if (!m_icu)
+ m_icu = new QIcuTimeZonePrivate(m_id);
+ // TODO small risk may not match if tran times differ due to outdated files
+ // TODO Some valid TZ names are not valid ICU names, use translation table?
+ if (m_icu->isValid())
+ return m_icu->displayName(timeType, nameType, locale);
++ lock.unlock();
+ #else
+ Q_UNUSED(timeType)
+ Q_UNUSED(nameType)
+diff --git a/qtbase/src/corelib/tools/qarraydata.h b/qtbase/src/corelib/tools/qarraydata.h
+index dcd95924c1..d01739e7e6 100644
+--- a/qtbase/src/corelib/tools/qarraydata.h
++++ b/qtbase/src/corelib/tools/qarraydata.h
+@@ -42,6 +42,7 @@
+
+ #include <QtCore/qrefcount.h>
+ #include <string.h>
++#include <cstdint>
+
+ QT_BEGIN_NAMESPACE
+
+@@ -58,14 +59,14 @@ struct Q_CORE_EXPORT QArrayData
+ {
+ Q_ASSERT(size == 0
+ || offset < 0 || size_t(offset) >= sizeof(QArrayData));
+- return reinterpret_cast<char *>(this) + offset;
++ return reinterpret_cast<void *> (reinterpret_cast<uintptr_t>(this) + offset);
+ }
+
+ const void *data() const
+ {
+ Q_ASSERT(size == 0
+ || offset < 0 || size_t(offset) >= sizeof(QArrayData));
+- return reinterpret_cast<const char *>(this) + offset;
++ return reinterpret_cast<void *> (reinterpret_cast<uintptr_t>(this) + offset);
+ }
+
+ // This refers to array data mutability, not "header data" represented by
+diff --git a/qtbase/src/corelib/tools/qfreelist_p.h b/qtbase/src/corelib/tools/qfreelist_p.h
+index 5ba23b344b..9974102136 100644
+--- a/qtbase/src/corelib/tools/qfreelist_p.h
++++ b/qtbase/src/corelib/tools/qfreelist_p.h
+@@ -161,7 +161,7 @@ class QFreeList
+ return i;
+ x -= size;
+ }
+- Q_ASSERT(false);
++ Q_UNREACHABLE();
+ return -1;
+ }
+
+diff --git a/qtbase/src/corelib/tools/qversionnumber.h b/qtbase/src/corelib/tools/qversionnumber.h
+index d43b86ba51..2843f2b043 100644
+--- a/qtbase/src/corelib/tools/qversionnumber.h
++++ b/qtbase/src/corelib/tools/qversionnumber.h
+@@ -273,10 +273,10 @@ public:
+
+ Q_REQUIRED_RESULT Q_CORE_EXPORT QString toString() const;
+ #if QT_STRINGVIEW_LEVEL < 2
+- Q_REQUIRED_RESULT Q_CORE_EXPORT static Q_DECL_PURE_FUNCTION QVersionNumber fromString(const QString &string, int *suffixIndex = nullptr);
++ Q_REQUIRED_RESULT Q_CORE_EXPORT static QVersionNumber fromString(const QString &string, int *suffixIndex = nullptr);
+ #endif
+- Q_REQUIRED_RESULT Q_CORE_EXPORT static Q_DECL_PURE_FUNCTION QVersionNumber fromString(QLatin1String string, int *suffixIndex = nullptr);
+- Q_REQUIRED_RESULT Q_CORE_EXPORT static Q_DECL_PURE_FUNCTION QVersionNumber fromString(QStringView string, int *suffixIndex = nullptr);
++ Q_REQUIRED_RESULT Q_CORE_EXPORT static QVersionNumber fromString(QLatin1String string, int *suffixIndex = nullptr);
++ Q_REQUIRED_RESULT Q_CORE_EXPORT static QVersionNumber fromString(QStringView string, int *suffixIndex = nullptr);
+
+ private:
+ #ifndef QT_NO_DATASTREAM
+diff --git a/qtbase/src/dbus/qdbusintegrator.cpp b/qtbase/src/dbus/qdbusintegrator.cpp
+index 5b66ce971b..28a3b0ffea 100644
+--- a/qtbase/src/dbus/qdbusintegrator.cpp
++++ b/qtbase/src/dbus/qdbusintegrator.cpp
+@@ -1135,7 +1135,13 @@ void QDBusConnectionPrivate::closeConnection()
+ }
+ }
+
+- qDeleteAll(pendingCalls);
++ for (auto it = pendingCalls.begin(); it != pendingCalls.end(); ++it) {
++ auto call = *it;
++ if (!call->ref.deref()) {
++ delete call;
++ }
++ }
++ pendingCalls.clear();
+
+ // Disconnect all signals from signal hooks and from the object tree to
+ // avoid QObject::destroyed being sent to dbus daemon thread which has
+@@ -2584,6 +2590,11 @@ QDBusConnectionPrivate::findMetaObject(const QString &service, const QString &pa
+ if (mo)
+ return mo;
+ }
++ if (path.isEmpty()) {
++ error = QDBusError(QDBusError::InvalidObjectPath, QLatin1String("Object path cannot be empty"));
++ lastError = error;
++ return nullptr;
++ }
+
+ // introspect the target object
+ QDBusMessage msg = QDBusMessage::createMethodCall(service, path,
+diff --git a/qtbase/src/dbus/qdbusmetaobject.cpp b/qtbase/src/dbus/qdbusmetaobject.cpp
+index 5265568f42..7e9f0f1acc 100644
+--- a/qtbase/src/dbus/qdbusmetaobject.cpp
++++ b/qtbase/src/dbus/qdbusmetaobject.cpp
+@@ -210,6 +210,9 @@ QDBusMetaObjectGenerator::findType(const QByteArray &signature,
+ } else if (signature == "a{ss}") {
+ result.name = "QMap<QString,QString>";
+ type = qMetaTypeId<QMap<QString, QString> >();
++ } else if (signature == "aay") {
++ result.name = "QByteArrayList";
++ type = qMetaTypeId<QByteArrayList>();
+ } else {
+ result.name = "{D-Bus type \"" + signature + "\"}";
+ type = registerComplexDBusType(result.name);
+diff --git a/qtbase/src/gui/accessible/qaccessible.cpp b/qtbase/src/gui/accessible/qaccessible.cpp
+index d705bfccb5..0caf3c808c 100644
+--- a/qtbase/src/gui/accessible/qaccessible.cpp
++++ b/qtbase/src/gui/accessible/qaccessible.cpp
+@@ -54,6 +54,7 @@
+ #include <QtCore/qdebug.h>
+ #include <QtCore/qloggingcategory.h>
+ #include <QtCore/qmetaobject.h>
++#include <QtCore/private/qmetaobject_p.h>
+ #include <QtCore/qhash.h>
+ #include <private/qfactoryloader_p.h>
+
+@@ -681,6 +682,25 @@ QAccessibleInterface *QAccessible::queryAccessibleInterface(QObject *object)
+ // Create a QAccessibleInterface for the object class. Start by the most
+ // derived class and walk up the class hierarchy.
+ const QMetaObject *mo = object->metaObject();
++ const auto *objectPriv = QObjectPrivate::get(object);
++ /*
++ We do not want to cache each and every QML metaobject (Button_QMLTYPE_124,
++ Button_QMLTYPE_125, etc.). Those dynamic metaobjects shouldn't have an
++ accessible interface in any case. Instead, we start the whole checking
++ with the first non-dynamic meta-object. To avoid potential regressions
++ in other areas of Qt that also use dynamic metaobjects, we only do this
++ for objects that are QML-related (approximated by checking whether they
++ have ddata set).
++ */
++ const bool qmlRelated = !objectPriv->isDeletingChildren &&
++ objectPriv->declarativeData;
++ while (qmlRelated && mo) {
++ auto mop = QMetaObjectPrivate::get(mo);
++ if (!mop || !(mop->flags & DynamicMetaObject))
++ break;
++
++ mo = mo->superClass();
++ };
+ while (mo) {
+ const QString cn = QLatin1String(mo->className());
+
+@@ -696,14 +716,15 @@ QAccessibleInterface *QAccessible::queryAccessibleInterface(QObject *object)
+ // Find a QAccessiblePlugin (factory) for the class name. If there's
+ // no entry in the cache try to create it using the plugin loader.
+ if (!qAccessiblePlugins()->contains(cn)) {
++ QAccessiblePlugin *factory = nullptr; // 0 means "no plugin found". This is cached as well.
+ const int index = loader()->indexOf(cn);
+- if (index != -1) {
+- QAccessiblePlugin *factory = qobject_cast<QAccessiblePlugin *>(loader()->instance(index));
+- qAccessiblePlugins()->insert(cn, factory);
+- }
++ if (index != -1)
++ factory = qobject_cast<QAccessiblePlugin *>(loader()->instance(index));
++ qAccessiblePlugins()->insert(cn, factory);
+ }
+
+ // At this point the cache should contain a valid factory pointer or 0:
++ Q_ASSERT(qAccessiblePlugins()->contains(cn));
+ QAccessiblePlugin *factory = qAccessiblePlugins()->value(cn);
+ if (factory) {
+ QAccessibleInterface *result = factory->create(cn, object);
+diff --git a/qtbase/src/gui/configure.json b/qtbase/src/gui/configure.json
+index 1f08795c57..12c95742d2 100644
+--- a/qtbase/src/gui/configure.json
++++ b/qtbase/src/gui/configure.json
+@@ -834,7 +834,8 @@
+ "// embedded devices, are not intended to be used together with X. EGL support",
+ "// has to be disabled in plugins like xcb in this case since the native display,",
+ "// window and pixmap types will be different than what an X-based platform",
+- "// plugin would expect."
++ "// plugin would expect.",
++ "#define USE_X11"
+ ],
+ "include": [ "EGL/egl.h", "X11/Xlib.h" ],
+ "main": [
+diff --git a/qtbase/src/gui/image/qbmphandler.cpp b/qtbase/src/gui/image/qbmphandler.cpp
+index 96f1e8cb1d..0e73bbbdb0 100644
+--- a/qtbase/src/gui/image/qbmphandler.cpp
++++ b/qtbase/src/gui/image/qbmphandler.cpp
+@@ -150,16 +150,42 @@ static QDataStream &operator<<(QDataStream &s, const BMP_INFOHDR &bi)
+ return s;
+ }
+
+-static int calc_shift(uint mask)
++static uint calc_shift(uint mask)
+ {
+- int result = 0;
+- while (mask && !(mask & 1)) {
++ uint result = 0;
++ while ((mask >= 0x100) || (!(mask & 1) && mask)) {
+ result++;
+ mask >>= 1;
+ }
+ return result;
+ }
+
++static uint calc_scale(uint low_mask)
++{
++ uint result = 8;
++ while (low_mask && result) {
++ result--;
++ low_mask >>= 1;
++ }
++ return result;
++}
++
++static inline uint apply_scale(uint value, uint scale)
++{
++ if (!(scale & 0x07)) // return immediately if scale == 8 or 0
++ return value;
++
++ uint filled = 8 - scale;
++ uint result = value << scale;
++
++ do {
++ result |= result >> filled;
++ filled <<= 1;
++ } while (filled < 8);
++
++ return result;
++}
++
+ static bool read_dib_fileheader(QDataStream &s, BMP_FILEHDR &bf)
+ {
+ // read BMP file header
+@@ -222,14 +248,14 @@ static bool read_dib_body(QDataStream &s, const BMP_INFOHDR &bi, qint64 offset,
+ uint green_mask = 0;
+ uint blue_mask = 0;
+ uint alpha_mask = 0;
+- int red_shift = 0;
+- int green_shift = 0;
+- int blue_shift = 0;
+- int alpha_shift = 0;
+- int red_scale = 0;
+- int green_scale = 0;
+- int blue_scale = 0;
+- int alpha_scale = 0;
++ uint red_shift = 0;
++ uint green_shift = 0;
++ uint blue_shift = 0;
++ uint alpha_shift = 0;
++ uint red_scale = 0;
++ uint green_scale = 0;
++ uint blue_scale = 0;
++ uint alpha_scale = 0;
+
+ if (!d->isSequential())
+ d->seek(startpos + BMP_FILEHDR_SIZE + bi.biSize); // goto start of colormap or masks
+@@ -308,19 +334,19 @@ static bool read_dib_body(QDataStream &s, const BMP_INFOHDR &bi, qint64 offset,
+ red_shift = calc_shift(red_mask);
+ if (((red_mask >> red_shift) + 1) == 0)
+ return false;
+- red_scale = 256 / ((red_mask >> red_shift) + 1);
++ red_scale = calc_scale(red_mask >> red_shift);
+ green_shift = calc_shift(green_mask);
+ if (((green_mask >> green_shift) + 1) == 0)
+ return false;
+- green_scale = 256 / ((green_mask >> green_shift) + 1);
++ green_scale = calc_scale(green_mask >> green_shift);
+ blue_shift = calc_shift(blue_mask);
+ if (((blue_mask >> blue_shift) + 1) == 0)
+ return false;
+- blue_scale = 256 / ((blue_mask >> blue_shift) + 1);
++ blue_scale = calc_scale(blue_mask >> blue_shift);
+ alpha_shift = calc_shift(alpha_mask);
+ if (((alpha_mask >> alpha_shift) + 1) == 0)
+ return false;
+- alpha_scale = 256 / ((alpha_mask >> alpha_shift) + 1);
++ alpha_scale = calc_scale(alpha_mask >> alpha_shift);
+ } else if (comp == BMP_RGB && (nbits == 24 || nbits == 32)) {
+ blue_mask = 0x000000ff;
+ green_mask = 0x0000ff00;
+@@ -328,17 +354,15 @@ static bool read_dib_body(QDataStream &s, const BMP_INFOHDR &bi, qint64 offset,
+ blue_shift = 0;
+ green_shift = 8;
+ red_shift = 16;
+- blue_scale = green_scale = red_scale = 1;
++ blue_scale = green_scale = red_scale = 0;
+ } else if (comp == BMP_RGB && nbits == 16) {
+ blue_mask = 0x001f;
+ green_mask = 0x03e0;
+ red_mask = 0x7c00;
+ blue_shift = 0;
+- green_shift = 2;
+- red_shift = 7;
+- red_scale = 1;
+- green_scale = 1;
+- blue_scale = 8;
++ green_shift = 5;
++ red_shift = 10;
++ blue_scale = green_scale = red_scale = 3;
+ }
+
+ #if 0
+@@ -544,10 +568,10 @@ static bool read_dib_body(QDataStream &s, const BMP_INFOHDR &bi, qint64 offset,
+ c |= *(uchar*)(b+2)<<16;
+ if (nbits > 24)
+ c |= *(uchar*)(b+3)<<24;
+- *p++ = qRgba(((c & red_mask) >> red_shift) * red_scale,
+- ((c & green_mask) >> green_shift) * green_scale,
+- ((c & blue_mask) >> blue_shift) * blue_scale,
+- transp ? ((c & alpha_mask) >> alpha_shift) * alpha_scale : 0xff);
++ *p++ = qRgba(apply_scale((c & red_mask) >> red_shift, red_scale),
++ apply_scale((c & green_mask) >> green_shift, green_scale),
++ apply_scale((c & blue_mask) >> blue_shift, blue_scale),
++ transp ? apply_scale((c & alpha_mask) >> alpha_shift, alpha_scale) : 0xff);
+ b += nbits/8;
+ }
+ }
+diff --git a/qtbase/src/gui/image/qimage.cpp b/qtbase/src/gui/image/qimage.cpp
+index 7152ac1607..0df772564c 100644
+--- a/qtbase/src/gui/image/qimage.cpp
++++ b/qtbase/src/gui/image/qimage.cpp
+@@ -4694,6 +4694,8 @@ QImage QImage::smoothScaled(int w, int h) const {
+ static QImage rotated90(const QImage &image)
+ {
+ QImage out(image.height(), image.width(), image.format());
++ if (out.isNull())
++ return out;
+ copyMetadata(&out, image);
+ if (image.colorCount() > 0)
+ out.setColorTable(image.colorTable());
+@@ -4722,6 +4724,8 @@ static QImage rotated180(const QImage &image)
+ return image.mirrored(true, true);
+
+ QImage out(image.width(), image.height(), image.format());
++ if (out.isNull())
++ return out;
+ copyMetadata(&out, image);
+ if (image.colorCount() > 0)
+ out.setColorTable(image.colorTable());
+@@ -4734,6 +4738,8 @@ static QImage rotated180(const QImage &image)
+ static QImage rotated270(const QImage &image)
+ {
+ QImage out(image.height(), image.width(), image.format());
++ if (out.isNull())
++ return out;
+ copyMetadata(&out, image);
+ if (image.colorCount() > 0)
+ out.setColorTable(image.colorTable());
+diff --git a/qtbase/src/gui/kernel/qcursor.cpp b/qtbase/src/gui/kernel/qcursor.cpp
+index d6ccaff8ed..455088241c 100644
+--- a/qtbase/src/gui/kernel/qcursor.cpp
++++ b/qtbase/src/gui/kernel/qcursor.cpp
+@@ -251,7 +251,8 @@ void QCursor::setPos(QScreen *screen, int x, int y)
+ {
+ if (screen) {
+ if (QPlatformCursor *cursor = screen->handle()->cursor()) {
+- const QPoint devicePos = QHighDpi::toNativePixels(QPoint(x, y), screen);
++ const QPoint pos(x, y);
++ const QPoint devicePos = QHighDpi::toNativePixels(pos, screen->virtualSiblingAt(pos));
+ // Need to check, since some X servers generate null mouse move
+ // events, causing looping in applications which call setPos() on
+ // every mouse move event.
+diff --git a/qtbase/src/gui/kernel/qhighdpiscaling.cpp b/qtbase/src/gui/kernel/qhighdpiscaling.cpp
+index 9bbf2773a9..3ac4a4d8b6 100644
+--- a/qtbase/src/gui/kernel/qhighdpiscaling.cpp
++++ b/qtbase/src/gui/kernel/qhighdpiscaling.cpp
+@@ -580,9 +580,8 @@ void QHighDpiScaling::setScreenFactor(QScreen *screen, qreal factor)
+ else
+ qNamedScreenScaleFactors()->insert(name, factor);
+
+- // hack to force re-evaluation of screen geometry
+ if (screen->handle())
+- screen->d_func()->setPlatformScreen(screen->handle()); // updates geometries based on scale factor
++ screen->d_func()->updateLogicalDpi();
+ }
+
+ QPoint QHighDpiScaling::mapPositionToNative(const QPoint &pos, const QPlatformScreen *platformScreen)
+diff --git a/qtbase/src/gui/kernel/qkeysequence.cpp b/qtbase/src/gui/kernel/qkeysequence.cpp
+index a75b8ef920..4f2d294739 100644
+--- a/qtbase/src/gui/kernel/qkeysequence.cpp
++++ b/qtbase/src/gui/kernel/qkeysequence.cpp
+@@ -701,6 +701,10 @@ static const struct {
+ { Qt::Key_TouchpadToggle, QT_TRANSLATE_NOOP("QShortcut", "Touchpad Toggle") },
+ { Qt::Key_TouchpadOn, QT_TRANSLATE_NOOP("QShortcut", "Touchpad On") },
+ { Qt::Key_TouchpadOff, QT_TRANSLATE_NOOP("QShortcut", "Touchpad Off") },
++ { Qt::Key_Shift, QT_TRANSLATE_NOOP("QShortcut", "Shift") },
++ { Qt::Key_Control, QT_TRANSLATE_NOOP("QShortcut", "Control") },
++ { Qt::Key_Alt, QT_TRANSLATE_NOOP("QShortcut", "Alt") },
++ { Qt::Key_Meta, QT_TRANSLATE_NOOP("QShortcut", "Meta") },
+
+ };
+ static Q_CONSTEXPR int numKeyNames = sizeof keyname / sizeof *keyname;
+diff --git a/qtbase/src/gui/kernel/qplatformservices.cpp b/qtbase/src/gui/kernel/qplatformservices.cpp
+index fdc6a6c4aa..ac47f98c5d 100644
+--- a/qtbase/src/gui/kernel/qplatformservices.cpp
++++ b/qtbase/src/gui/kernel/qplatformservices.cpp
+@@ -55,6 +55,19 @@ QT_BEGIN_NAMESPACE
+ \brief The QPlatformServices provides the backend for desktop-related functionality.
+ */
+
++/*!
++ \enum QPlatformServices::Capability
++
++ Capabilities are used to determine a specific platform service's availability.
++
++ \value ColorPickingFromScreen The platform natively supports color picking from screen.
++ This capability indicates that the platform supports "opaque" color picking, where the
++ platform implements a complete user experience for color picking and outputs a color.
++ This is in contrast to the application implementing the color picking user experience
++ (taking care of showing a cross hair, instructing the platform integration to obtain
++ the color at a given pixel, etc.). The related service function is pickColor().
++ */
++
+ QPlatformServices::QPlatformServices()
+ { }
+
+@@ -85,5 +98,16 @@ QByteArray QPlatformServices::desktopEnvironment() const
+ return QByteArray("UNKNOWN");
+ }
+
++QPlatformServiceColorPicker *QPlatformServices::colorPicker(QWindow *parent)
++{
++ Q_UNUSED(parent);
++ return nullptr;
++}
++
++bool QPlatformServices::hasCapability(Capability capability) const
++{
++ Q_UNUSED(capability)
++ return false;
++}
+
+ QT_END_NAMESPACE
+diff --git a/qtbase/src/gui/kernel/qplatformservices.h b/qtbase/src/gui/kernel/qplatformservices.h
+index 5de96cfa7d..a8b2a4ce71 100644
+--- a/qtbase/src/gui/kernel/qplatformservices.h
++++ b/qtbase/src/gui/kernel/qplatformservices.h
+@@ -50,16 +50,32 @@
+ //
+
+ #include <QtGui/qtguiglobal.h>
++#include <QtCore/qobject.h>
+
+ QT_BEGIN_NAMESPACE
+
+ class QUrl;
++class QWindow;
++
++class Q_GUI_EXPORT QPlatformServiceColorPicker : public QObject
++{
++ Q_OBJECT
++public:
++ using QObject::QObject;
++ virtual void pickColor() = 0;
++Q_SIGNALS:
++ void colorPicked(const QColor &color);
++};
+
+ class Q_GUI_EXPORT QPlatformServices
+ {
+ public:
+ Q_DISABLE_COPY_MOVE(QPlatformServices)
+
++ enum Capability {
++ ColorPicking,
++ };
++
+ QPlatformServices();
+ virtual ~QPlatformServices() { }
+
+@@ -67,6 +83,10 @@ public:
+ virtual bool openDocument(const QUrl &url);
+
+ virtual QByteArray desktopEnvironment() const;
++
++ virtual bool hasCapability(Capability capability) const;
++
++ virtual QPlatformServiceColorPicker *colorPicker(QWindow *parent = nullptr);
+ };
+
+ QT_END_NAMESPACE
+diff --git a/qtbase/src/gui/kernel/qplatformtheme.cpp b/qtbase/src/gui/kernel/qplatformtheme.cpp
+index 71521c0339..2325873245 100644
+--- a/qtbase/src/gui/kernel/qplatformtheme.cpp
++++ b/qtbase/src/gui/kernel/qplatformtheme.cpp
+@@ -163,6 +163,8 @@ QT_BEGIN_NAMESPACE
+
+ \value ShowShortcutsInContextMenus (bool) Whether to display shortcut key sequences in context menus.
+
++ \value ButtonPressKeys (QList<Qt::Key>) A list of keys that can be used to press buttons via keyboard input.
++
+ \sa themeHint(), QStyle::pixelMetric()
+ */
+
+@@ -563,6 +565,8 @@ QVariant QPlatformTheme::defaultThemeHint(ThemeHint hint)
+ }
+ case MouseQuickSelectionThreshold:
+ return QVariant(10);
++ case ButtonPressKeys:
++ return QVariant::fromValue(QList<Qt::Key>({ Qt::Key_Space, Qt::Key_Select }));
+ }
+ return QVariant();
+ }
+diff --git a/qtbase/src/gui/kernel/qplatformtheme.h b/qtbase/src/gui/kernel/qplatformtheme.h
+index 3185fc4541..7e6c9d5740 100644
+--- a/qtbase/src/gui/kernel/qplatformtheme.h
++++ b/qtbase/src/gui/kernel/qplatformtheme.h
+@@ -120,7 +120,8 @@ public:
+ TouchDoubleTapDistance,
+ ShowShortcutsInContextMenus,
+ IconFallbackSearchPaths,
+- MouseQuickSelectionThreshold
++ MouseQuickSelectionThreshold,
++ ButtonPressKeys
+ };
+
+ enum DialogType {
+diff --git a/qtbase/src/gui/kernel/qscreen.cpp b/qtbase/src/gui/kernel/qscreen.cpp
+index 8e0eb35116..5d172a58dd 100644
+--- a/qtbase/src/gui/kernel/qscreen.cpp
++++ b/qtbase/src/gui/kernel/qscreen.cpp
+@@ -77,6 +77,12 @@ QScreen::QScreen(QPlatformScreen *screen)
+ d->setPlatformScreen(screen);
+ }
+
++void QScreenPrivate::updateLogicalDpi()
++{
++ logicalDpi = QPlatformScreen::overrideDpi(platformScreen->logicalDpi());
++ updateGeometriesWithSignals(); // updates geometries based on scale factor
++}
++
+ void QScreenPrivate::updateGeometriesWithSignals()
+ {
+ const QRect oldGeometry = geometry;
+diff --git a/qtbase/src/gui/kernel/qscreen_p.h b/qtbase/src/gui/kernel/qscreen_p.h
+index 7da542c25e..e50fc3190b 100644
+--- a/qtbase/src/gui/kernel/qscreen_p.h
++++ b/qtbase/src/gui/kernel/qscreen_p.h
+@@ -70,6 +70,7 @@ public:
+ geometry = platformScreen->deviceIndependentGeometry();
+ availableGeometry = QHighDpi::fromNative(platformScreen->availableGeometry(), QHighDpiScaling::factor(platformScreen), geometry.topLeft());
+ }
++ void updateLogicalDpi();
+
+ void updatePrimaryOrientation();
+ void updateGeometriesWithSignals();
+diff --git a/qtbase/src/gui/painting/qblendfunctions_p.h b/qtbase/src/gui/painting/qblendfunctions_p.h
+index 080da98ec4..6997d62b3c 100644
+--- a/qtbase/src/gui/painting/qblendfunctions_p.h
++++ b/qtbase/src/gui/painting/qblendfunctions_p.h
+@@ -246,25 +246,32 @@ void qt_transform_image_rasterize(DestT *destPixels, int dbpl,
+ int dudx, int dvdx, int dudy, int dvdy, int u0, int v0,
+ Blender blender)
+ {
+- int fromY = qMax(qRound(topY), clip.top());
+- int toY = qMin(qRound(bottomY), clip.top() + clip.height());
++ qint64 fromY = qMax(qRound(topY), clip.top());
++ qint64 toY = qMin(qRound(bottomY), clip.top() + clip.height());
+ if (fromY >= toY)
+ return;
+
+ qreal leftSlope = (bottomLeft.x - topLeft.x) / (bottomLeft.y - topLeft.y);
+ qreal rightSlope = (bottomRight.x - topRight.x) / (bottomRight.y - topRight.y);
+- int dx_l = int(leftSlope * 0x10000);
+- int dx_r = int(rightSlope * 0x10000);
+- int x_l = int((topLeft.x + (qreal(0.5) + fromY - topLeft.y) * leftSlope + qreal(0.5)) * 0x10000);
+- int x_r = int((topRight.x + (qreal(0.5) + fromY - topRight.y) * rightSlope + qreal(0.5)) * 0x10000);
+-
+- int fromX, toX, x1, x2, u, v, i, ii;
++ qint64 dx_l = qint64(leftSlope * 0x10000);
++ qint64 dx_r = qint64(rightSlope * 0x10000);
++ qint64 x_l = qint64((topLeft.x + (qreal(0.5) + fromY - topLeft.y) * leftSlope + qreal(0.5)) * 0x10000);
++ qint64 x_r = qint64((topRight.x + (qreal(0.5) + fromY - topRight.y) * rightSlope + qreal(0.5)) * 0x10000);
++
++ qint64 sourceRectTop = qint64(sourceRect.top());
++ qint64 sourceRectLeft = qint64(sourceRect.left());
++ qint64 sourceRectWidth = qint64(sourceRect.width());
++ qint64 sourceRectHeight = qint64(sourceRect.height());
++ qint64 clipLeft = qint64(clip.left());
++ qint64 clipWidth = qint64(clip.width());
++
++ qint64 fromX, toX, x1, x2, u, v, i, ii;
+ DestT *line;
+- for (int y = fromY; y < toY; ++y) {
++ for (qint64 y = fromY; y < toY; ++y) {
+ line = reinterpret_cast<DestT *>(reinterpret_cast<uchar *>(destPixels) + y * dbpl);
+
+- fromX = qMax(x_l >> 16, clip.left());
+- toX = qMin(x_r >> 16, clip.left() + clip.width());
++ fromX = qMax(x_l >> 16, clipLeft);
++ toX = qMin(x_r >> 16, clipLeft + clipWidth);
+ if (fromX < toX) {
+ // Because of rounding, we can get source coordinates outside the source image.
+ // Clamp these coordinates to the source rect to avoid segmentation fault and
+@@ -275,10 +282,10 @@ void qt_transform_image_rasterize(DestT *destPixels, int dbpl,
+ u = x1 * dudx + y * dudy + u0;
+ v = x1 * dvdx + y * dvdy + v0;
+ for (; x1 < toX; ++x1) {
+- int uu = u >> 16;
+- int vv = v >> 16;
+- if (uu >= sourceRect.left() && uu < sourceRect.left() + sourceRect.width()
+- && vv >= sourceRect.top() && vv < sourceRect.top() + sourceRect.height()) {
++ qint64 uu = u >> 16;
++ qint64 vv = v >> 16;
++ if (uu >= sourceRectLeft && uu < sourceRectLeft + sourceRectWidth
++ && vv >= sourceRectTop && vv < sourceRectTop + sourceRectHeight) {
+ break;
+ }
+ u += dudx;
+@@ -290,10 +297,10 @@ void qt_transform_image_rasterize(DestT *destPixels, int dbpl,
+ u = (x2 - 1) * dudx + y * dudy + u0;
+ v = (x2 - 1) * dvdx + y * dvdy + v0;
+ for (; x2 > x1; --x2) {
+- int uu = u >> 16;
+- int vv = v >> 16;
+- if (uu >= sourceRect.left() && uu < sourceRect.left() + sourceRect.width()
+- && vv >= sourceRect.top() && vv < sourceRect.top() + sourceRect.height()) {
++ qint64 uu = u >> 16;
++ qint64 vv = v >> 16;
++ if (uu >= sourceRectLeft && uu < sourceRectLeft + sourceRectWidth
++ && vv >= sourceRectTop && vv < sourceRectTop + sourceRectHeight) {
+ break;
+ }
+ u -= dudx;
+@@ -308,8 +315,8 @@ void qt_transform_image_rasterize(DestT *destPixels, int dbpl,
+ // Beginning of the scan line, with per-pixel checks.
+ i = x1 - fromX;
+ while (i) {
+- int uu = qBound(sourceRect.left(), u >> 16, sourceRect.left() + sourceRect.width() - 1);
+- int vv = qBound(sourceRect.top(), v >> 16, sourceRect.top() + sourceRect.height() - 1);
++ qint64 uu = qBound(sourceRectLeft, u >> 16, sourceRectLeft + sourceRectWidth - 1);
++ qint64 vv = qBound(sourceRectTop, v >> 16, sourceRectTop + sourceRectHeight - 1);
+ blender.write(line, reinterpret_cast<const SrcT *>(reinterpret_cast<const uchar *>(srcPixels) + vv * sbpl)[uu]);
+ u += dudx;
+ v += dvdx;
+@@ -348,8 +355,8 @@ void qt_transform_image_rasterize(DestT *destPixels, int dbpl,
+ // End of the scan line, with per-pixel checks.
+ i = toX - x2;
+ while (i) {
+- int uu = qBound(sourceRect.left(), u >> 16, sourceRect.left() + sourceRect.width() - 1);
+- int vv = qBound(sourceRect.top(), v >> 16, sourceRect.top() + sourceRect.height() - 1);
++ qint64 uu = qBound(sourceRectLeft, u >> 16, sourceRectLeft + sourceRectWidth - 1);
++ qint64 vv = qBound(sourceRectTop, v >> 16, sourceRectTop + sourceRectHeight - 1);
+ blender.write(line, reinterpret_cast<const SrcT *>(reinterpret_cast<const uchar *>(srcPixels) + vv * sbpl)[uu]);
+ u += dudx;
+ v += dvdx;
+diff --git a/qtbase/src/gui/painting/qcolortrclut_p.h b/qtbase/src/gui/painting/qcolortrclut_p.h
+index 76a6a60803..24fd522e6c 100644
+--- a/qtbase/src/gui/painting/qcolortrclut_p.h
++++ b/qtbase/src/gui/painting/qcolortrclut_p.h
+@@ -118,6 +118,7 @@ public:
+ return QRgba64::fromRgba64(r, g, b, qAlpha(rgb32) * 257);
+ #endif
+ }
++ QRgba64 toLinear64(QRgba64) const = delete;
+
+ QRgb toLinear(QRgb rgb32) const
+ {
+diff --git a/qtbase/src/gui/painting/qdrawhelper.cpp b/qtbase/src/gui/painting/qdrawhelper.cpp
+index a61793508a..5ba2d277b7 100644
+--- a/qtbase/src/gui/painting/qdrawhelper.cpp
++++ b/qtbase/src/gui/painting/qdrawhelper.cpp
+@@ -6091,7 +6091,7 @@ static inline void alphargbblend_argb32(quint32 *dst, uint coverage, const QRgba
+ static inline void rgbBlendPixel(QRgba64 &dst, int coverage, QRgba64 slinear, const QColorTrcLut *colorProfile)
+ {
+ // Do a gammacorrected RGB alphablend...
+- const QRgba64 dlinear = colorProfile ? colorProfile->toLinear64(dst) : dst;
++ const QRgba64 dlinear = colorProfile ? colorProfile->toLinear(dst) : dst;
+
+ QRgba64 blend = rgbBlend(dlinear, slinear, coverage);
+
+diff --git a/qtbase/src/gui/painting/qpaintengine_raster.cpp b/qtbase/src/gui/painting/qpaintengine_raster.cpp
+index 283923de52..f08eb9cbee 100644
+--- a/qtbase/src/gui/painting/qpaintengine_raster.cpp
++++ b/qtbase/src/gui/painting/qpaintengine_raster.cpp
+@@ -560,31 +560,6 @@ void QRasterPaintEngine::updateMatrix(const QTransform &matrix)
+ QRasterPaintEngineState *s = state();
+ // FALCON: get rid of this line, see drawImage call below.
+ s->matrix = matrix;
+- QTransform::TransformationType txop = s->matrix.type();
+-
+- switch (txop) {
+-
+- case QTransform::TxNone:
+- s->flags.int_xform = true;
+- break;
+-
+- case QTransform::TxTranslate:
+- s->flags.int_xform = qreal(int(s->matrix.dx())) == s->matrix.dx()
+- && qreal(int(s->matrix.dy())) == s->matrix.dy();
+- break;
+-
+- case QTransform::TxScale:
+- s->flags.int_xform = qreal(int(s->matrix.dx())) == s->matrix.dx()
+- && qreal(int(s->matrix.dy())) == s->matrix.dy()
+- && qreal(int(s->matrix.m11())) == s->matrix.m11()
+- && qreal(int(s->matrix.m22())) == s->matrix.m22();
+- break;
+-
+- default: // shear / perspective...
+- s->flags.int_xform = false;
+- break;
+- }
+-
+ s->flags.tx_noshear = qt_scaleForTransform(s->matrix, &s->txscale);
+
+ ensureOutlineMapper();
+@@ -617,7 +592,6 @@ QRasterPaintEngineState::QRasterPaintEngineState()
+ flags.bilinear = false;
+ flags.legacy_rounding = false;
+ flags.fast_text = true;
+- flags.int_xform = true;
+ flags.tx_noshear = true;
+ flags.fast_images = true;
+
+@@ -1793,7 +1767,7 @@ void QRasterPaintEngine::fill(const QVectorPath &path, const QBrush &brush)
+ QRectF cpRect = path.controlPointRect();
+ const QRectF pathDeviceRect = s->matrix.mapRect(cpRect);
+ // Skip paths that by conservative estimates are completely outside the paint device.
+- if (!pathDeviceRect.intersects(QRectF(d->deviceRect)))
++ if (!pathDeviceRect.intersects(QRectF(d->deviceRect)) || !pathDeviceRect.isValid())
+ return;
+
+ ProcessSpans blend = d->getBrushFunc(pathDeviceRect, &s->brushData);
+diff --git a/qtbase/src/gui/painting/qpaintengine_raster_p.h b/qtbase/src/gui/painting/qpaintengine_raster_p.h
+index 089aadc3f7..bf7363d5aa 100644
+--- a/qtbase/src/gui/painting/qpaintengine_raster_p.h
++++ b/qtbase/src/gui/painting/qpaintengine_raster_p.h
+@@ -111,7 +111,6 @@ public:
+ uint bilinear : 1;
+ uint legacy_rounding : 1;
+ uint fast_text : 1;
+- uint int_xform : 1;
+ uint tx_noshear : 1;
+ uint fast_images : 1;
+ };
+diff --git a/qtbase/src/gui/painting/qpainterpath.cpp b/qtbase/src/gui/painting/qpainterpath.cpp
+index f9544a3241..d80fafeaf1 100644
+--- a/qtbase/src/gui/painting/qpainterpath.cpp
++++ b/qtbase/src/gui/painting/qpainterpath.cpp
+@@ -1253,7 +1253,7 @@ void QPainterPath::addText(const QPointF &point, const QFont &f, const QString &
+
+ if (si.analysis.flags < QScriptAnalysis::TabOrObject) {
+ QGlyphLayout glyphs = eng->shapedGlyphs(&si);
+- QFontEngine *fe = f.d->engineForScript(si.analysis.script);
++ QFontEngine *fe = eng->fontEngine(si);
+ Q_ASSERT(fe);
+ fe->addOutlineToPath(x, y, glyphs, this,
+ si.analysis.bidiLevel % 2
+diff --git a/qtbase/src/gui/painting/qpathclipper_p.h b/qtbase/src/gui/painting/qpathclipper_p.h
+index 9444a87b71..18f64c5e8c 100644
+--- a/qtbase/src/gui/painting/qpathclipper_p.h
++++ b/qtbase/src/gui/painting/qpathclipper_p.h
+@@ -156,7 +156,7 @@ public:
+ int vertex(Direction direction) const;
+
+ private:
+- int m_next[2][2];
++ int m_next[2][2] = { { -1, -1 }, { -1, -1 } };
+ };
+
+ class QPathSegments
+@@ -296,10 +296,6 @@ inline QPathEdge::QPathEdge(int a, int b)
+ , angle(0)
+ , invAngle(0)
+ {
+- m_next[0][0] = -1;
+- m_next[1][0] = -1;
+- m_next[0][0] = -1;
+- m_next[1][0] = -1;
+ }
+
+ inline int QPathEdge::next(Traversal traversal, Direction direction) const
+diff --git a/qtbase/src/gui/painting/qpdf.cpp b/qtbase/src/gui/painting/qpdf.cpp
+index 3066744f1b..2c8d3c3b53 100644
+--- a/qtbase/src/gui/painting/qpdf.cpp
++++ b/qtbase/src/gui/painting/qpdf.cpp
+@@ -2760,6 +2760,8 @@ int QPdfEnginePrivate::addBrushPattern(const QTransform &m, bool *specifyColor,
+ return gradientBrush(brush, matrix, gStateObject);
+ }
+
++ matrix = brush.transform() * matrix;
++
+ if ((!brush.isOpaque() && brush.style() < Qt::LinearGradientPattern) || opacity != 1.0)
+ *gStateObject = addConstantAlphaObject(qRound(brush.color().alpha() * opacity),
+ qRound(pen.color().alpha() * opacity));
+diff --git a/qtbase/src/gui/painting/qstroker.cpp b/qtbase/src/gui/painting/qstroker.cpp
+index cb5d395e80..3b6357a893 100644
+--- a/qtbase/src/gui/painting/qstroker.cpp
++++ b/qtbase/src/gui/painting/qstroker.cpp
+@@ -1182,6 +1182,7 @@ void QDashStroker::processCurrentSubpath()
+ // Check if the entire line should be clipped away or simplified
+ bool clipIt = clipping && !lineIntersectsRect(prev, e, clip_tl, clip_br);
+ bool skipDashing = elen * invSumLength > repetitionLimit();
++ int maxDashes = dashCount;
+ if (skipDashing || clipIt) {
+ // Cut away full dash sequences.
+ elen -= std::floor(elen * invSumLength) * sumLength;
+@@ -1196,7 +1197,7 @@ void QDashStroker::processCurrentSubpath()
+ pos = estop; // move pos to next path element
+ done = true;
+ } else { // Dash is on this line
+- pos = dpos + estart;
++ pos = --maxDashes > 0 ? dpos + estart : estop;
+ done = pos >= estop;
+ if (++idash >= dashCount)
+ idash = 0;
+diff --git a/qtbase/src/gui/painting/qt_attribution.json b/qtbase/src/gui/painting/qt_attribution.json
+index 7b16e8c211..0e87d30aa2 100644
+--- a/qtbase/src/gui/painting/qt_attribution.json
++++ b/qtbase/src/gui/painting/qt_attribution.json
+@@ -10,7 +10,7 @@
+ "Homepage": "http://www.freetype.org",
+ "License": "Freetype Project License or GNU General Public License v2.0 only",
+ "LicenseId": "FTL or GPL-2.0",
+- "LicenseFile": "../../3rdparty/freetype/docs/LICENSE.TXT",
++ "LicenseFile": "../../3rdparty/freetype/LICENSE.TXT",
+ "Copyright": "Copyright 2000-2016 by David Turner, Robert Wilhelm, and Werner Lemberg."
+ },
+ {
+diff --git a/qtbase/src/gui/rhi/qshader_p_p.h b/qtbase/src/gui/rhi/qshader_p_p.h
+index ec9d25971f..4a5a7a6d51 100644
+--- a/qtbase/src/gui/rhi/qshader_p_p.h
++++ b/qtbase/src/gui/rhi/qshader_p_p.h
+@@ -68,13 +68,13 @@ struct Q_GUI_EXPORT QShaderPrivate
+ {
+ }
+
+- QShaderPrivate(const QShaderPrivate *other)
++ QShaderPrivate(const QShaderPrivate &other)
+ : ref(1),
+- qsbVersion(other->qsbVersion),
+- stage(other->stage),
+- desc(other->desc),
+- shaders(other->shaders),
+- bindings(other->bindings)
++ qsbVersion(other.qsbVersion),
++ stage(other.stage),
++ desc(other.desc),
++ shaders(other.shaders),
++ bindings(other.bindings)
+ {
+ }
+
+diff --git a/qtbase/src/gui/rhi/qshaderdescription_p_p.h b/qtbase/src/gui/rhi/qshaderdescription_p_p.h
+index ec2b0b6b4c..3da33a8a2b 100644
+--- a/qtbase/src/gui/rhi/qshaderdescription_p_p.h
++++ b/qtbase/src/gui/rhi/qshaderdescription_p_p.h
+@@ -63,16 +63,16 @@ struct Q_GUI_EXPORT QShaderDescriptionPrivate
+ localSize[0] = localSize[1] = localSize[2] = 0;
+ }
+
+- QShaderDescriptionPrivate(const QShaderDescriptionPrivate *other)
++ QShaderDescriptionPrivate(const QShaderDescriptionPrivate &other)
+ : ref(1),
+- inVars(other->inVars),
+- outVars(other->outVars),
+- uniformBlocks(other->uniformBlocks),
+- pushConstantBlocks(other->pushConstantBlocks),
+- storageBlocks(other->storageBlocks),
+- combinedImageSamplers(other->combinedImageSamplers),
+- storageImages(other->storageImages),
+- localSize(other->localSize)
++ inVars(other.inVars),
++ outVars(other.outVars),
++ uniformBlocks(other.uniformBlocks),
++ pushConstantBlocks(other.pushConstantBlocks),
++ storageBlocks(other.storageBlocks),
++ combinedImageSamplers(other.combinedImageSamplers),
++ storageImages(other.storageImages),
++ localSize(other.localSize)
+ {
+ }
+
+diff --git a/qtbase/src/gui/text/qfontdatabase.cpp b/qtbase/src/gui/text/qfontdatabase.cpp
+index a657a8c516..4fc0100958 100644
+--- a/qtbase/src/gui/text/qfontdatabase.cpp
++++ b/qtbase/src/gui/text/qfontdatabase.cpp
+@@ -983,7 +983,7 @@ QFontEngine *loadSingleEngine(int script,
+ if (style->key.stretch != 0 && request.stretch != 0
+ && (request.styleName.isEmpty() || request.styleName != style->styleName)) {
+ def.stretch = (request.stretch * 100 + style->key.stretch / 2) / style->key.stretch;
+- } else {
++ } else if (request.stretch == QFont::AnyStretch) {
+ def.stretch = 100;
+ }
+
+diff --git a/qtbase/src/gui/text/qtextdocumentlayout.cpp b/qtbase/src/gui/text/qtextdocumentlayout.cpp
+index f3e6ea2100..72267e9380 100644
+--- a/qtbase/src/gui/text/qtextdocumentlayout.cpp
++++ b/qtbase/src/gui/text/qtextdocumentlayout.cpp
+@@ -2123,7 +2123,7 @@ void QTextDocumentLayoutPrivate::drawListItem(const QPointF &offset, QPainter *p
+ {
+ Q_Q(const QTextDocumentLayout);
+ const QTextBlockFormat blockFormat = bl.blockFormat();
+- const QTextCharFormat charFormat = QTextCursor(bl).charFormat();
++ const QTextCharFormat charFormat = bl.charFormat();
+ QFont font(charFormat.font());
+ if (q->paintDevice())
+ font = QFont(font, q->paintDevice());
+diff --git a/qtbase/src/gui/text/qtextengine.cpp b/qtbase/src/gui/text/qtextengine.cpp
+index ce4abac472..a6c66e5d2d 100644
+--- a/qtbase/src/gui/text/qtextengine.cpp
++++ b/qtbase/src/gui/text/qtextengine.cpp
+@@ -1,6 +1,6 @@
+ /****************************************************************************
+ **
+-** Copyright (C) 2016 The Qt Company Ltd.
++** Copyright (C) 2021 The Qt Company Ltd.
+ ** Contact: https://www.qt.io/licensing/
+ **
+ ** This file is part of the QtGui module of the Qt Toolkit.
+@@ -1565,6 +1565,12 @@ void QTextEngine::shapeText(int item) const
+ // Overwrite with 0 token to indicate failure
+ QGlyphLayout g = availableGlyphs(&si);
+ g.glyphs[0] = 0;
++ g.attributes[0].clusterStart = true;
++
++ ushort *log_clusters = logClusters(&si);
++ for (int i = 0; i < itemLength; ++i)
++ log_clusters[i] = 0;
++
+ return;
+ }
+
+diff --git a/qtbase/src/gui/util/qdesktopservices.cpp b/qtbase/src/gui/util/qdesktopservices.cpp
+index fbb63a9408..4d5fafaaa7 100644
+--- a/qtbase/src/gui/util/qdesktopservices.cpp
++++ b/qtbase/src/gui/util/qdesktopservices.cpp
+@@ -54,6 +54,8 @@
+ #include <qpa/qplatformintegration.h>
+ #include <qdir.h>
+
++#include <QtCore/private/qlocking_p.h>
++
+ QT_BEGIN_NAMESPACE
+
+ class QOpenUrlHandlerRegistry : public QObject
+@@ -81,6 +83,7 @@ Q_GLOBAL_STATIC(QOpenUrlHandlerRegistry, handlerRegistry)
+
+ void QOpenUrlHandlerRegistry::handlerDestroyed(QObject *handler)
+ {
++ const auto lock = qt_scoped_lock(mutex);
+ HandlerHash::Iterator it = handlers.begin();
+ while (it != handlers.end()) {
+ if (it->receiver == handler) {
+@@ -294,7 +297,8 @@ void QDesktopServices::setUrlHandler(const QString &scheme, QObject *receiver, c
+ h.name = method;
+ registry->handlers.insert(scheme.toLower(), h);
+ QObject::connect(receiver, SIGNAL(destroyed(QObject*)),
+- registry, SLOT(handlerDestroyed(QObject*)));
++ registry, SLOT(handlerDestroyed(QObject*)),
++ Qt::DirectConnection);
+ }
+
+ /*!
+diff --git a/qtbase/src/gui/util/qpkmhandler.cpp b/qtbase/src/gui/util/qpkmhandler.cpp
+index e0c3b75efe..3414f9d8ba 100644
+--- a/qtbase/src/gui/util/qpkmhandler.cpp
++++ b/qtbase/src/gui/util/qpkmhandler.cpp
+@@ -57,7 +57,7 @@ struct PkmType
+ quint32 bytesPerBlock;
+ };
+
+-static PkmType typeMap[5] = {
++static constexpr PkmType typeMap[5] = {
+ { 0x8D64, 8 }, // GL_ETC1_RGB8_OES
+ { 0x9274, 8 }, // GL_COMPRESSED_RGB8_ETC2
+ { 0, 0 }, // unused (obsolete)
+diff --git a/qtbase/src/network/access/qnetworkreplyfileimpl.cpp b/qtbase/src/network/access/qnetworkreplyfileimpl.cpp
+index b6be93147a..6e69b4c4d3 100644
+--- a/qtbase/src/network/access/qnetworkreplyfileimpl.cpp
++++ b/qtbase/src/network/access/qnetworkreplyfileimpl.cpp
+@@ -89,9 +89,10 @@ QNetworkReplyFileImpl::QNetworkReplyFileImpl(QNetworkAccessManager *manager, con
+ // we handle only local files
+ QString msg = QCoreApplication::translate("QNetworkAccessFileBackend", "Request for opening non-local file %1").arg(url.toString());
+ setError(QNetworkReply::ProtocolInvalidOperationError, msg);
++ setFinished(true); // We're finished, will emit finished() after ctor is done.
+ QMetaObject::invokeMethod(this, "errorOccurred", Qt::QueuedConnection,
+ Q_ARG(QNetworkReply::NetworkError, QNetworkReply::ProtocolInvalidOperationError));
+- fileOpenFinished(false);
++ QMetaObject::invokeMethod(this, [this](){ fileOpenFinished(false); }, Qt::QueuedConnection);
+ return;
+ }
+ #endif
+diff --git a/qtbase/src/network/access/qnetworkreplyimpl.cpp b/qtbase/src/network/access/qnetworkreplyimpl.cpp
+index bcdf6ee2f1..3b6deb82bd 100644
+--- a/qtbase/src/network/access/qnetworkreplyimpl.cpp
++++ b/qtbase/src/network/access/qnetworkreplyimpl.cpp
+@@ -680,7 +680,7 @@ void QNetworkReplyImplPrivate::appendDownstreamData(QIODevice *data)
+ // read until EOF from data
+ if (Q_UNLIKELY(copyDevice)) {
+ qCritical("QNetworkReplyImpl: copy from QIODevice already in progress -- "
+- "backend probly needs to be fixed");
++ "backend probably needs to be fixed");
+ return;
+ }
+
+diff --git a/qtbase/src/network/kernel/qauthenticator.cpp b/qtbase/src/network/kernel/qauthenticator.cpp
+index d9fe7bc47b..ccd04b294a 100644
+--- a/qtbase/src/network/kernel/qauthenticator.cpp
++++ b/qtbase/src/network/kernel/qauthenticator.cpp
+@@ -50,6 +50,7 @@
+ #include <qstring.h>
+ #include <qdatetime.h>
+ #include <qrandom.h>
++#include "private/qsystemlibrary_p.h"
+
+ #ifdef Q_OS_WIN
+ #include <qmutex.h>
+@@ -1563,7 +1564,7 @@ static bool q_SSPI_library_load()
+
+ // Initialize security interface
+ if (pSecurityFunctionTable == nullptr) {
+- securityDLLHandle = LoadLibrary(L"secur32.dll");
++ securityDLLHandle = QSystemLibrary::load(L"secur32");
+ if (securityDLLHandle != nullptr) {
+ INIT_SECURITY_INTERFACE pInitSecurityInterface =
+ reinterpret_cast<INIT_SECURITY_INTERFACE>(
+diff --git a/qtbase/src/network/kernel/qhostinfo_unix.cpp b/qtbase/src/network/kernel/qhostinfo_unix.cpp
+index 9b0a2ee669..73679c9ef1 100644
+--- a/qtbase/src/network/kernel/qhostinfo_unix.cpp
++++ b/qtbase/src/network/kernel/qhostinfo_unix.cpp
+@@ -122,7 +122,6 @@ static QFunctionPointer resolveSymbol(QLibrary &lib, const char *sym)
+
+ LibResolv::LibResolv()
+ {
+- QLibrary lib;
+ #ifdef LIBRESOLV_SO
+ lib.setFileName(QStringLiteral(LIBRESOLV_SO));
+ if (!lib.load())
+diff --git a/qtbase/src/network/socket/qsocks5socketengine.cpp b/qtbase/src/network/socket/qsocks5socketengine.cpp
+index 3a046fd116..97fadca0b3 100644
+--- a/qtbase/src/network/socket/qsocks5socketengine.cpp
++++ b/qtbase/src/network/socket/qsocks5socketengine.cpp
+@@ -1296,7 +1296,7 @@ void QSocks5SocketEnginePrivate::_q_udpSocketReadNotification()
+ int pos = 0;
+ const char *buf = inBuf.constData();
+ if (inBuf.size() < 4) {
+- QSOCKS5_D_DEBUG << "bugus udp data, discarding";
++ QSOCKS5_D_DEBUG << "bogus udp data, discarding";
+ return;
+ }
+ QSocks5RevivedDatagram datagram;
+diff --git a/qtbase/src/network/ssl/qsslcontext_openssl.cpp b/qtbase/src/network/ssl/qsslcontext_openssl.cpp
+index c9f202f573..c992da9d8e 100644
+--- a/qtbase/src/network/ssl/qsslcontext_openssl.cpp
++++ b/qtbase/src/network/ssl/qsslcontext_openssl.cpp
+@@ -409,7 +409,7 @@ init_context:
+ break;
+ case QSsl::DtlsV1_0OrLater:
+ minVersion = DTLS1_VERSION;
+- maxVersion = DTLS_MAX_VERSION;
++ maxVersion = 0;
+ break;
+ case QSsl::DtlsV1_2:
+ minVersion = DTLS1_2_VERSION;
+@@ -417,7 +417,7 @@ init_context:
+ break;
+ case QSsl::DtlsV1_2OrLater:
+ minVersion = DTLS1_2_VERSION;
+- maxVersion = DTLS_MAX_VERSION;
++ maxVersion = 0;
+ break;
+ case QSsl::TlsV1_3OrLater:
+ #ifdef TLS1_3_VERSION
+@@ -455,7 +455,7 @@ init_context:
+ }
+
+ // Enable bug workarounds.
+- long options = QSslSocketBackendPrivate::setupOpenSslOptions(configuration.protocol(), configuration.d->sslOptions);
++ qssloptions options = QSslSocketBackendPrivate::setupOpenSslOptions(configuration.protocol(), configuration.d->sslOptions);
+ q_SSL_CTX_set_options(sslContext->ctx, options);
+
+ // Tell OpenSSL to release memory early
+diff --git a/qtbase/src/network/ssl/qssldiffiehellmanparameters_openssl.cpp b/qtbase/src/network/ssl/qssldiffiehellmanparameters_openssl.cpp
+index aaf8741130..b58935372c 100644
+--- a/qtbase/src/network/ssl/qssldiffiehellmanparameters_openssl.cpp
++++ b/qtbase/src/network/ssl/qssldiffiehellmanparameters_openssl.cpp
+@@ -59,57 +59,6 @@
+
+ QT_BEGIN_NAMESPACE
+
+-#ifdef OPENSSL_NO_DEPRECATED_3_0
+-
+-static int q_DH_check(DH *dh, int *status)
+-{
+- // DH_check was first deprecated in OpenSSL 3.0.0, as low-level
+- // API; the EVP_PKEY family of functions was advised as an alternative.
+- // As of now EVP_PKEY_params_check ends up calling ... DH_check,
+- // which is good enough.
+-
+- Q_ASSERT(dh);
+- Q_ASSERT(status);
+-
+- EVP_PKEY *key = q_EVP_PKEY_new();
+- if (!key) {
+- qCWarning(lcSsl, "EVP_PKEY_new failed");
+- QSslSocketBackendPrivate::logAndClearErrorQueue();
+- return 0;
+- }
+- const auto keyDeleter = qScopeGuard([key](){
+- q_EVP_PKEY_free(key);
+- });
+- if (!q_EVP_PKEY_set1_DH(key, dh)) {
+- qCWarning(lcSsl, "EVP_PKEY_set1_DH failed");
+- QSslSocketBackendPrivate::logAndClearErrorQueue();
+- return 0;
+- }
+-
+- EVP_PKEY_CTX *keyCtx = q_EVP_PKEY_CTX_new(key, nullptr);
+- if (!keyCtx) {
+- qCWarning(lcSsl, "EVP_PKEY_CTX_new failed");
+- QSslSocketBackendPrivate::logAndClearErrorQueue();
+- return 0;
+- }
+- const auto ctxDeleter = qScopeGuard([keyCtx]{
+- q_EVP_PKEY_CTX_free(keyCtx);
+- });
+-
+- const int result = q_EVP_PKEY_param_check(keyCtx);
+- QSslSocketBackendPrivate::logAndClearErrorQueue();
+- // Note: unlike DH_check, we cannot obtain the 'status',
+- // if the 'result' is 0 (actually the result is 1 only
+- // if this 'status' was 0). We could probably check the
+- // errors from the error queue, but it's not needed anyway
+- // - see the 'isSafeDH' below, how it returns immediately
+- // on 0.
+- Q_UNUSED(status)
+-
+- return result;
+-}
+-#endif // OPENSSL_NO_DEPRECATED_3_0
+-
+ static bool isSafeDH(DH *dh)
+ {
+ int status = 0;
+diff --git a/qtbase/src/network/ssl/qsslsocket_openssl.cpp b/qtbase/src/network/ssl/qsslsocket_openssl.cpp
+index 37fad2a68f..8f6858c867 100644
+--- a/qtbase/src/network/ssl/qsslsocket_openssl.cpp
++++ b/qtbase/src/network/ssl/qsslsocket_openssl.cpp
+@@ -550,9 +550,9 @@ static void q_loadCiphersForConnection(SSL *connection, QList<QSslCipher> &ciphe
+ // Defined in qsslsocket.cpp
+ void q_setDefaultDtlsCiphers(const QList<QSslCipher> &ciphers);
+
+-long QSslSocketBackendPrivate::setupOpenSslOptions(QSsl::SslProtocol protocol, QSsl::SslOptions sslOptions)
++qssloptions QSslSocketBackendPrivate::setupOpenSslOptions(QSsl::SslProtocol protocol, QSsl::SslOptions sslOptions)
+ {
+- long options;
++ qssloptions options;
+ if (protocol == QSsl::TlsV1SslV3)
+ options = SSL_OP_ALL|SSL_OP_NO_SSLv2|SSL_OP_NO_SSLv3;
+ else if (protocol == QSsl::SecureProtocols)
+diff --git a/qtbase/src/network/ssl/qsslsocket_openssl_p.h b/qtbase/src/network/ssl/qsslsocket_openssl_p.h
+index 4103de23e8..5547589256 100644
+--- a/qtbase/src/network/ssl/qsslsocket_openssl_p.h
++++ b/qtbase/src/network/ssl/qsslsocket_openssl_p.h
+@@ -107,6 +107,12 @@
+
+ QT_BEGIN_NAMESPACE
+
++#if defined(OPENSSL_VERSION_MAJOR) && OPENSSL_VERSION_MAJOR >= 3
++typedef uint64_t qssloptions;
++#else
++typedef unsigned long qssloptions;
++#endif
++
+ struct QSslErrorEntry {
+ int code;
+ int depth;
+@@ -171,7 +177,7 @@ public:
+ QVector<QSslError> ocspErrors;
+ QByteArray ocspResponseDer;
+
+- Q_AUTOTEST_EXPORT static long setupOpenSslOptions(QSsl::SslProtocol protocol, QSsl::SslOptions sslOptions);
++ Q_AUTOTEST_EXPORT static qssloptions setupOpenSslOptions(QSsl::SslProtocol protocol, QSsl::SslOptions sslOptions);
+ static QSslCipher QSslCipher_from_SSL_CIPHER(const SSL_CIPHER *cipher);
+ static QList<QSslCertificate> STACKOFX509_to_QSslCertificates(STACK_OF(X509) *x509);
+ static QList<QSslError> verify(const QList<QSslCertificate> &certificateChain, const QString &hostName);
+diff --git a/qtbase/src/network/ssl/qsslsocket_openssl_symbols.cpp b/qtbase/src/network/ssl/qsslsocket_openssl_symbols.cpp
+index e53fb279f0..459ccd0b19 100644
+--- a/qtbase/src/network/ssl/qsslsocket_openssl_symbols.cpp
++++ b/qtbase/src/network/ssl/qsslsocket_openssl_symbols.cpp
+@@ -148,7 +148,6 @@ DEFINEFUNC(int, EVP_PKEY_up_ref, EVP_PKEY *a, a, return 0, return)
+ DEFINEFUNC2(EVP_PKEY_CTX *, EVP_PKEY_CTX_new, EVP_PKEY *pkey, pkey, ENGINE *e, e, return nullptr, return)
+ DEFINEFUNC(int, EVP_PKEY_param_check, EVP_PKEY_CTX *ctx, ctx, return 0, return)
+ DEFINEFUNC(void, EVP_PKEY_CTX_free, EVP_PKEY_CTX *ctx, ctx, return, return)
+-DEFINEFUNC(int, EVP_PKEY_base_id, EVP_PKEY *a, a, return NID_undef, return)
+ DEFINEFUNC(int, RSA_bits, RSA *a, a, return 0, return)
+ DEFINEFUNC(int, DSA_bits, DSA *a, a, return 0, return)
+ DEFINEFUNC(int, OPENSSL_sk_num, OPENSSL_STACK *a, a, return -1, return)
+@@ -158,7 +157,7 @@ DEFINEFUNC2(void, OPENSSL_sk_push, OPENSSL_STACK *a, a, void *b, b, return, DUMM
+ DEFINEFUNC(void, OPENSSL_sk_free, OPENSSL_STACK *a, a, return, DUMMYARG)
+ DEFINEFUNC2(void *, OPENSSL_sk_value, OPENSSL_STACK *a, a, int b, b, return nullptr, return)
+ DEFINEFUNC(int, SSL_session_reused, SSL *a, a, return 0, return)
+-DEFINEFUNC2(unsigned long, SSL_CTX_set_options, SSL_CTX *ctx, ctx, unsigned long op, op, return 0, return)
++DEFINEFUNC2(qssloptions, SSL_CTX_set_options, SSL_CTX *ctx, ctx, qssloptions op, op, return 0, return)
+ DEFINEFUNC(int, SSL_CTX_get_security_level, const SSL_CTX *ctx, ctx, return -1, return)
+ DEFINEFUNC2(void, SSL_CTX_set_security_level, SSL_CTX *ctx, ctx, int level, level, return, return)
+ #ifdef TLS1_3_VERSION
+@@ -371,7 +370,15 @@ DEFINEFUNC(const SSL_CIPHER *, SSL_get_current_cipher, SSL *a, a, return nullptr
+ DEFINEFUNC(int, SSL_version, const SSL *a, a, return 0, return)
+ DEFINEFUNC2(int, SSL_get_error, SSL *a, a, int b, b, return -1, return)
+ DEFINEFUNC(STACK_OF(X509) *, SSL_get_peer_cert_chain, SSL *a, a, return nullptr, return)
++
++#if defined(OPENSSL_VERSION_MAJOR) && OPENSSL_VERSION_MAJOR >= 3
++DEFINEFUNC(X509 *, SSL_get1_peer_certificate, SSL *a, a, return nullptr, return)
++DEFINEFUNC(int, EVP_PKEY_get_base_id, const EVP_PKEY *pkey, pkey, return -1, return)
++#else
+ DEFINEFUNC(X509 *, SSL_get_peer_certificate, SSL *a, a, return nullptr, return)
++DEFINEFUNC(int, EVP_PKEY_base_id, EVP_PKEY *a, a, return NID_undef, return)
++#endif // OPENSSL_VERSION_MAJOR >= 3
++
+ DEFINEFUNC(long, SSL_get_verify_result, const SSL *a, a, return -1, return)
+ DEFINEFUNC(SSL *, SSL_new, SSL_CTX *a, a, return nullptr, return)
+ DEFINEFUNC(SSL_CTX *, SSL_get_SSL_CTX, SSL *a, a, return nullptr, return)
+@@ -492,9 +499,7 @@ DEFINEFUNC(DH *, DH_new, DUMMYARG, DUMMYARG, return nullptr, return)
+ DEFINEFUNC(void, DH_free, DH *dh, dh, return, DUMMYARG)
+ DEFINEFUNC3(DH *, d2i_DHparams, DH**a, a, const unsigned char **pp, pp, long length, length, return nullptr, return)
+ DEFINEFUNC2(int, i2d_DHparams, DH *a, a, unsigned char **p, p, return -1, return)
+-#ifndef OPENSSL_NO_DEPRECATED_3_0
+ DEFINEFUNC2(int, DH_check, DH *dh, dh, int *codes, codes, return 0, return)
+-#endif // OPENSSL_NO_DEPRECATED_3_0
+ DEFINEFUNC3(BIGNUM *, BN_bin2bn, const unsigned char *s, s, int len, len, BIGNUM *ret, ret, return nullptr, return)
+
+ #ifndef OPENSSL_NO_EC
+@@ -868,7 +873,6 @@ bool q_resolveOpenSslSymbols()
+ RESOLVEFUNC(EVP_PKEY_CTX_new)
+ RESOLVEFUNC(EVP_PKEY_param_check)
+ RESOLVEFUNC(EVP_PKEY_CTX_free)
+- RESOLVEFUNC(EVP_PKEY_base_id)
+ RESOLVEFUNC(RSA_bits)
+ RESOLVEFUNC(OPENSSL_sk_new_null)
+ RESOLVEFUNC(OPENSSL_sk_push)
+@@ -1107,7 +1111,15 @@ bool q_resolveOpenSslSymbols()
+ RESOLVEFUNC(SSL_version)
+ RESOLVEFUNC(SSL_get_error)
+ RESOLVEFUNC(SSL_get_peer_cert_chain)
++
++#if defined(OPENSSL_VERSION_MAJOR) && OPENSSL_VERSION_MAJOR >= 3
++ RESOLVEFUNC(SSL_get1_peer_certificate)
++ RESOLVEFUNC(EVP_PKEY_get_base_id)
++#else
+ RESOLVEFUNC(SSL_get_peer_certificate)
++ RESOLVEFUNC(EVP_PKEY_base_id)
++#endif // OPENSSL_VERSION_MAJOR >= 3
++
+ RESOLVEFUNC(SSL_get_verify_result)
+ RESOLVEFUNC(SSL_new)
+ RESOLVEFUNC(SSL_get_SSL_CTX)
+@@ -1206,9 +1218,7 @@ bool q_resolveOpenSslSymbols()
+ RESOLVEFUNC(DH_free)
+ RESOLVEFUNC(d2i_DHparams)
+ RESOLVEFUNC(i2d_DHparams)
+-#ifndef OPENSSL_NO_DEPRECATED_3_0
+ RESOLVEFUNC(DH_check)
+-#endif // OPENSSL_NO_DEPRECATED_3_0
+ RESOLVEFUNC(BN_bin2bn)
+
+ #ifndef OPENSSL_NO_EC
+diff --git a/qtbase/src/network/ssl/qsslsocket_openssl_symbols_p.h b/qtbase/src/network/ssl/qsslsocket_openssl_symbols_p.h
+index 95e8897a3b..27aeffa18a 100644
+--- a/qtbase/src/network/ssl/qsslsocket_openssl_symbols_p.h
++++ b/qtbase/src/network/ssl/qsslsocket_openssl_symbols_p.h
+@@ -237,7 +237,6 @@ Q_AUTOTEST_EXPORT int q_EVP_PKEY_up_ref(EVP_PKEY *a);
+ EVP_PKEY_CTX *q_EVP_PKEY_CTX_new(EVP_PKEY *pkey, ENGINE *e);
+ void q_EVP_PKEY_CTX_free(EVP_PKEY_CTX *ctx);
+ int q_EVP_PKEY_param_check(EVP_PKEY_CTX *ctx);
+-int q_EVP_PKEY_base_id(EVP_PKEY *a);
+ int q_RSA_bits(RSA *a);
+ Q_AUTOTEST_EXPORT int q_OPENSSL_sk_num(OPENSSL_STACK *a);
+ Q_AUTOTEST_EXPORT void q_OPENSSL_sk_pop_free(OPENSSL_STACK *a, void (*b)(void *));
+@@ -246,7 +245,7 @@ Q_AUTOTEST_EXPORT void q_OPENSSL_sk_push(OPENSSL_STACK *st, void *data);
+ Q_AUTOTEST_EXPORT void q_OPENSSL_sk_free(OPENSSL_STACK *a);
+ Q_AUTOTEST_EXPORT void * q_OPENSSL_sk_value(OPENSSL_STACK *a, int b);
+ int q_SSL_session_reused(SSL *a);
+-unsigned long q_SSL_CTX_set_options(SSL_CTX *ctx, unsigned long op);
++qssloptions q_SSL_CTX_set_options(SSL_CTX *ctx, qssloptions op);
+ int q_OPENSSL_init_ssl(uint64_t opts, const OPENSSL_INIT_SETTINGS *settings);
+ size_t q_SSL_get_client_random(SSL *a, unsigned char *out, size_t outlen);
+ size_t q_SSL_SESSION_get_master_key(const SSL_SESSION *session, unsigned char *out, size_t outlen);
+@@ -510,7 +509,6 @@ const SSL_CIPHER *q_SSL_get_current_cipher(SSL *a);
+ int q_SSL_version(const SSL *a);
+ int q_SSL_get_error(SSL *a, int b);
+ STACK_OF(X509) *q_SSL_get_peer_cert_chain(SSL *a);
+-X509 *q_SSL_get_peer_certificate(SSL *a);
+ long q_SSL_get_verify_result(const SSL *a);
+ SSL *q_SSL_new(SSL_CTX *a);
+ SSL_CTX *q_SSL_get_SSL_CTX(SSL *a);
+@@ -582,10 +580,7 @@ DH *q_DH_new();
+ void q_DH_free(DH *dh);
+ DH *q_d2i_DHparams(DH **a, const unsigned char **pp, long length);
+ int q_i2d_DHparams(DH *a, unsigned char **p);
+-
+-#ifndef OPENSSL_NO_DEPRECATED_3_0
+ int q_DH_check(DH *dh, int *codes);
+-#endif // OPENSSL_NO_DEPRECATED_3_0
+
+ BIGNUM *q_BN_bin2bn(const unsigned char *s, int len, BIGNUM *ret);
+ #define q_SSL_CTX_set_tmp_dh(ctx, dh) q_SSL_CTX_ctrl((ctx), SSL_CTRL_SET_TMP_DH, 0, (char *)dh)
+@@ -754,6 +749,17 @@ void q_CRYPTO_free(void *str, const char *file, int line);
+ int q_SSL_CTX_get_security_level(const SSL_CTX *ctx);
+ void q_SSL_CTX_set_security_level(SSL_CTX *ctx, int level);
+
++// Here we have the ones that make difference between OpenSSL pre/post v3:
++#if defined(OPENSSL_VERSION_MAJOR) && OPENSSL_VERSION_MAJOR >= 3
++X509 *q_SSL_get1_peer_certificate(SSL *a);
++#define q_SSL_get_peer_certificate q_SSL_get1_peer_certificate
++int q_EVP_PKEY_get_base_id(const EVP_PKEY *pkey);
++#define q_EVP_PKEY_base_id q_EVP_PKEY_get_base_id
++#else
++X509 *q_SSL_get_peer_certificate(SSL *a);
++int q_EVP_PKEY_base_id(EVP_PKEY *a);
++#endif // OPENSSL_VERSION_MAJOR >= 3
++
+ QT_END_NAMESPACE
+
+ #endif
+diff --git a/qtbase/src/platformsupport/eglconvenience/qt_egl_p.h b/qtbase/src/platformsupport/eglconvenience/qt_egl_p.h
+index bf37d07fd8..dbd42fb799 100644
+--- a/qtbase/src/platformsupport/eglconvenience/qt_egl_p.h
++++ b/qtbase/src/platformsupport/eglconvenience/qt_egl_p.h
+@@ -61,7 +61,11 @@
+ # if !defined(Q_OS_INTEGRITY)
+ # define WIN_INTERFACE_CUSTOM // NV
+ # endif // Q_OS_INTEGRITY
+-#endif // QT_EGL_NO_X11
++#else // QT_EGL_NO_X11
++// If one has an eglplatform.h with https://github.com/KhronosGroup/EGL-Registry/pull/130
++// that needs USE_X11 to be defined.
++# define USE_X11
++#endif
+
+ #ifdef QT_EGL_WAYLAND
+ # define WAYLAND // NV
+diff --git a/qtbase/src/platformsupport/fontdatabases/fontconfig/qfontconfigdatabase.cpp b/qtbase/src/platformsupport/fontdatabases/fontconfig/qfontconfigdatabase.cpp
+index 159b490ce0..00aa80cd58 100644
+--- a/qtbase/src/platformsupport/fontdatabases/fontconfig/qfontconfigdatabase.cpp
++++ b/qtbase/src/platformsupport/fontdatabases/fontconfig/qfontconfigdatabase.cpp
+@@ -567,6 +567,8 @@ void QFontconfigDatabase::populateFontDatabase()
+ fonts = FcFontList(nullptr, pattern, os);
+ FcObjectSetDestroy(os);
+ FcPatternDestroy(pattern);
++ if (!fonts)
++ return;
+ }
+
+ for (int i = 0; i < fonts->nfont; i++)
+diff --git a/qtbase/src/platformsupport/input/xkbcommon/qxkbcommon.cpp b/qtbase/src/platformsupport/input/xkbcommon/qxkbcommon.cpp
+index b713c19447..7cb9a8c79a 100644
+--- a/qtbase/src/platformsupport/input/xkbcommon/qxkbcommon.cpp
++++ b/qtbase/src/platformsupport/input/xkbcommon/qxkbcommon.cpp
+@@ -95,6 +95,7 @@ static constexpr const auto KeyTbl = qMakeArray(
+ Xkb2Qt<XKB_KEY_Clear, Qt::Key_Delete>,
+ Xkb2Qt<XKB_KEY_Pause, Qt::Key_Pause>,
+ Xkb2Qt<XKB_KEY_Print, Qt::Key_Print>,
++ Xkb2Qt<XKB_KEY_Sys_Req, Qt::Key_SysReq>,
+ Xkb2Qt<0x1005FF60, Qt::Key_SysReq>, // hardcoded Sun SysReq
+ Xkb2Qt<0x1007ff00, Qt::Key_SysReq>, // hardcoded X386 SysReq
+
+@@ -471,7 +472,7 @@ QVector<xkb_keysym_t> QXkbCommon::toKeysym(QKeyEvent *event)
+ } else if (event->modifiers() & Qt::KeypadModifier) {
+ if (qtKey >= Qt::Key_0 && qtKey <= Qt::Key_9)
+ keysyms.append(XKB_KEY_KP_0 + (qtKey - Qt::Key_0));
+- } else if (isLatin(qtKey) && event->text().isUpper()) {
++ } else if (isLatin1(qtKey) && event->text().isUpper()) {
+ keysyms.append(qtKey);
+ }
+
+@@ -523,7 +524,7 @@ int QXkbCommon::keysymToQtKey(xkb_keysym_t keysym, Qt::KeyboardModifiers modifie
+ // With standard shortcuts we should prefer a latin character, this is
+ // for checks like "some qkeyevent == QKeySequence::Copy" to work even
+ // when using for example 'russian' keyboard layout.
+- if (!QXkbCommon::isLatin(keysym)) {
++ if (!QXkbCommon::isLatin1(keysym)) {
+ xkb_keysym_t latinKeysym = QXkbCommon::lookupLatinKeysym(state, code);
+ if (latinKeysym != XKB_KEY_NoSymbol)
+ keysym = latinKeysym;
+@@ -546,7 +547,7 @@ static int keysymToQtKey_internal(xkb_keysym_t keysym, Qt::KeyboardModifiers mod
+ } else if (keysym >= XKB_KEY_KP_0 && keysym <= XKB_KEY_KP_9) {
+ // numeric keypad keys
+ qtKey = Qt::Key_0 + (keysym - XKB_KEY_KP_0);
+- } else if (QXkbCommon::isLatin(keysym)) {
++ } else if (QXkbCommon::isLatin1(keysym)) {
+ qtKey = QXkbCommon::qxkbcommon_xkb_keysym_to_upper(keysym);
+ } else {
+ // check if we have a direct mapping
+@@ -678,7 +679,7 @@ QList<int> QXkbCommon::possibleKeys(xkb_state *state, const QKeyEvent *event,
+ Qt::KeyboardModifiers neededMods = ModsTbl[i];
+ if ((modifiers & neededMods) == neededMods) {
+ if (i == 8) {
+- if (isLatin(baseQtKey))
++ if (isLatin1(baseQtKey))
+ continue;
+ // add a latin key as a fall back key
+ sym = lookupLatinKeysym(state, keycode);
+@@ -733,7 +734,7 @@ void QXkbCommon::verifyHasLatinLayout(xkb_keymap *keymap)
+ for (xkb_layout_index_t layout = 0; layout < layoutCount; ++layout) {
+ for (xkb_keycode_t code = minKeycode; code < maxKeycode; ++code) {
+ xkb_keymap_key_get_syms_by_level(keymap, code, layout, 0, &keysyms);
+- if (keysyms && isLatin(keysyms[0]))
++ if (keysyms && isLatin1(keysyms[0]))
+ nrLatinKeys++;
+ if (nrLatinKeys > 10) // arbitrarily chosen threshold
+ return;
+@@ -766,7 +767,7 @@ xkb_keysym_t QXkbCommon::lookupLatinKeysym(xkb_state *state, xkb_keycode_t keyco
+ xkb_level_index_t level = xkb_state_key_get_level(state, keycode, layout);
+ if (xkb_keymap_key_get_syms_by_level(keymap, keycode, layout, level, &syms) != 1)
+ continue;
+- if (isLatin(syms[0])) {
++ if (isLatin1(syms[0])) {
+ sym = syms[0];
+ break;
+ }
+diff --git a/qtbase/src/platformsupport/input/xkbcommon/qxkbcommon_p.h b/qtbase/src/platformsupport/input/xkbcommon/qxkbcommon_p.h
+index 561eae03db..8389bd8f5a 100644
+--- a/qtbase/src/platformsupport/input/xkbcommon/qxkbcommon_p.h
++++ b/qtbase/src/platformsupport/input/xkbcommon/qxkbcommon_p.h
+@@ -94,8 +94,8 @@ public:
+ static void verifyHasLatinLayout(xkb_keymap *keymap);
+ static xkb_keysym_t lookupLatinKeysym(xkb_state *state, xkb_keycode_t keycode);
+
+- static bool isLatin(xkb_keysym_t sym) {
+- return ((sym >= 'a' && sym <= 'z') || (sym >= 'A' && sym <= 'Z'));
++ static bool isLatin1(xkb_keysym_t sym) {
++ return sym <= 0xff;
+ }
+ static bool isKeypad(xkb_keysym_t sym) {
+ return sym >= XKB_KEY_KP_Space && sym <= XKB_KEY_KP_9;
+diff --git a/qtbase/src/platformsupport/kmsconvenience/qkmsdevice.cpp b/qtbase/src/platformsupport/kmsconvenience/qkmsdevice.cpp
+index 8cd7f9b368..406f84663f 100644
+--- a/qtbase/src/platformsupport/kmsconvenience/qkmsdevice.cpp
++++ b/qtbase/src/platformsupport/kmsconvenience/qkmsdevice.cpp
+@@ -318,7 +318,7 @@ QPlatformScreen *QKmsDevice::createScreenForConnector(drmModeResPtr resources,
+
+ if (current < 0 && crtc_mode.clock != 0) {
+ modes << crtc_mode;
+- current = mode.size() - 1;
++ current = modes.size() - 1;
+ }
+
+ if (configuration == OutputConfigCurrent)
+diff --git a/qtbase/src/platformsupport/linuxaccessibility/atspiadaptor.cpp b/qtbase/src/platformsupport/linuxaccessibility/atspiadaptor.cpp
+index 9153fd20bb..255ea5e33e 100644
+--- a/qtbase/src/platformsupport/linuxaccessibility/atspiadaptor.cpp
++++ b/qtbase/src/platformsupport/linuxaccessibility/atspiadaptor.cpp
+@@ -194,6 +194,9 @@ QString AtSpiAdaptor::introspect(const QString &path) const
+ " <arg direction=\"out\" type=\"(so)\"/>\n"
+ " <annotation value=\"QSpiObjectReference\" name=\"org.qtproject.QtDBus.QtTypeName.Out0\"/>\n"
+ " </method>\n"
++ " <method name=\"GetAccessibleId\">\n"
++ " <arg direction=\"out\" type=\"s\"/>\n"
++ " </method>\n"
+ " </interface>\n"
+ );
+
+@@ -913,8 +916,17 @@ void AtSpiAdaptor::notify(QAccessibleEvent *event)
+ }
+ case QAccessible::NameChanged: {
+ if (sendObject || sendObject_property_change || sendObject_property_change_accessible_name) {
+- QString path = pathForInterface(event->accessibleInterface());
+- QVariantList args = packDBusSignalArguments(QLatin1String("accessible-name"), 0, 0, variantForPath(path));
++ QAccessibleInterface *iface = event->accessibleInterface();
++ if (!iface) {
++ qCDebug(lcAccessibilityAtspi,
++ "NameChanged event from invalid accessible.");
++ return;
++ }
++
++ QString path = pathForInterface(iface);
++ QVariantList args = packDBusSignalArguments(
++ QLatin1String("accessible-name"), 0, 0,
++ QVariant::fromValue(QDBusVariant(iface->text(QAccessible::Name))));
+ sendDBusSignal(path, QLatin1String(ATSPI_DBUS_INTERFACE_EVENT_OBJECT),
+ QLatin1String("PropertyChange"), args);
+ }
+@@ -922,8 +934,17 @@ void AtSpiAdaptor::notify(QAccessibleEvent *event)
+ }
+ case QAccessible::DescriptionChanged: {
+ if (sendObject || sendObject_property_change || sendObject_property_change_accessible_description) {
+- QString path = pathForInterface(event->accessibleInterface());
+- QVariantList args = packDBusSignalArguments(QLatin1String("accessible-description"), 0, 0, variantForPath(path));
++ QAccessibleInterface *iface = event->accessibleInterface();
++ if (!iface) {
++ qCDebug(lcAccessibilityAtspi,
++ "DescriptionChanged event from invalid accessible.");
++ return;
++ }
++
++ QString path = pathForInterface(iface);
++ QVariantList args = packDBusSignalArguments(
++ QLatin1String("accessible-description"), 0, 0,
++ QVariant::fromValue(QDBusVariant(iface->text(QAccessible::Description))));
+ sendDBusSignal(path, QLatin1String(ATSPI_DBUS_INTERFACE_EVENT_OBJECT),
+ QLatin1String("PropertyChange"), args);
+ }
+@@ -1038,7 +1059,9 @@ void AtSpiAdaptor::notify(QAccessibleEvent *event)
+ // Combo Box with AT-SPI likes to be special
+ // It requires a name-change to update caches and then selection-changed
+ QString path = pathForInterface(iface);
+- QVariantList args1 = packDBusSignalArguments(QLatin1String("accessible-name"), 0, 0, variantForPath(path));
++ QVariantList args1 = packDBusSignalArguments(
++ QLatin1String("accessible-name"), 0, 0,
++ QVariant::fromValue(QDBusVariant(iface->text(QAccessible::Name))));
+ sendDBusSignal(path, QLatin1String(ATSPI_DBUS_INTERFACE_EVENT_OBJECT),
+ QLatin1String("PropertyChange"), args1);
+ QVariantList args2 = packDBusSignalArguments(QString(), 0, 0, QVariant::fromValue(QDBusVariant(QVariant(0))));
+@@ -1358,6 +1381,26 @@ void AtSpiAdaptor::registerApplication()
+ delete registry;
+ }
+
++namespace {
++QString accessibleIdForAccessible(QAccessibleInterface *accessible)
++{
++ QString result;
++ while (accessible) {
++ if (!result.isEmpty())
++ result.prepend(QLatin1Char('.'));
++ if (auto obj = accessible->object()) {
++ const QString name = obj->objectName();
++ if (!name.isEmpty())
++ result.prepend(name);
++ else
++ result.prepend(QString::fromUtf8(obj->metaObject()->className()));
++ }
++ accessible = accessible->parent();
++ }
++ return result;
++}
++} // namespace
++
+ // Accessible
+ bool AtSpiAdaptor::accessibleInterface(QAccessibleInterface *interface, const QString &function, const QDBusMessage &message, const QDBusConnection &connection)
+ {
+@@ -1441,6 +1484,9 @@ bool AtSpiAdaptor::accessibleInterface(QAccessibleInterface *interface, const QS
+ children << ref;
+ }
+ connection.send(message.createReply(QVariant::fromValue(children)));
++ } else if (function == QLatin1String("GetAccessibleId")) {
++ sendReply(connection, message,
++ QVariant::fromValue(QDBusVariant(accessibleIdForAccessible(interface))));
+ } else {
+ qCDebug(lcAccessibilityAtspi) << "WARNING: AtSpiAdaptor::accessibleInterface does not implement " << function << message.path();
+ return false;
+diff --git a/qtbase/src/platformsupport/linuxaccessibility/dbusconnection.cpp b/qtbase/src/platformsupport/linuxaccessibility/dbusconnection.cpp
+index 45ddc8e496..cc734abc63 100644
+--- a/qtbase/src/platformsupport/linuxaccessibility/dbusconnection.cpp
++++ b/qtbase/src/platformsupport/linuxaccessibility/dbusconnection.cpp
+@@ -69,6 +69,21 @@ QT_BEGIN_NAMESPACE
+ DBusConnection::DBusConnection(QObject *parent)
+ : QObject(parent), m_a11yConnection(QString()), m_enabled(false)
+ {
++ // If the bus is explicitly set via env var it overrides everything else.
++ QByteArray addressEnv = qgetenv("AT_SPI_BUS_ADDRESS");
++ if (!addressEnv.isEmpty()) {
++ // Only connect on next loop run, connections to our enabled signal are
++ // only established after the ctor returns.
++ QMetaObject::invokeMethod(
++ this,
++ [this, addressEnv] {
++ m_enabled = true;
++ connectA11yBus(QString::fromLocal8Bit(addressEnv));
++ },
++ Qt::QueuedConnection);
++ return;
++ }
++
+ // Start monitoring if "org.a11y.Bus" is registered as DBus service.
+ QDBusConnection c = QDBusConnection::sessionBus();
+ if (!c.isConnected()) {
+diff --git a/qtbase/src/platformsupport/services/genericunix/qgenericunixservices.cpp b/qtbase/src/platformsupport/services/genericunix/qgenericunixservices.cpp
+index 1a3cab275d..2abe039126 100644
+--- a/qtbase/src/platformsupport/services/genericunix/qgenericunixservices.cpp
++++ b/qtbase/src/platformsupport/services/genericunix/qgenericunixservices.cpp
+@@ -51,6 +51,9 @@
+ #include <QtCore/QStandardPaths>
+ #include <QtCore/QUrl>
+
++#include <QtGui/QGuiApplication>
++#include <QtGui/QWindow>
++
+ #if QT_CONFIG(dbus)
+ // These QtCore includes are needed for xdg-desktop-portal support
+ #include <QtCore/private/qcore_unix_p.h>
+@@ -58,6 +61,8 @@
+ #include <QtCore/QFileInfo>
+ #include <QtCore/QUrlQuery>
+
++#include <QtGui/QColor>
++
+ #include <QtDBus/QDBusConnection>
+ #include <QtDBus/QDBusMessage>
+ #include <QtDBus/QDBusPendingCall>
+@@ -142,6 +147,8 @@ static inline bool detectWebBrowser(const QByteArray &desktop,
+ }
+
+ if (desktop == QByteArray("KDE")) {
++ if (checkExecutable(QStringLiteral("kde-open5"), browser))
++ return true;
+ // Konqueror launcher
+ if (checkExecutable(QStringLiteral("kfmclient"), browser)) {
+ browser->append(QLatin1String(" exec"));
+@@ -296,8 +303,135 @@ static inline QDBusMessage xdgDesktopPortalSendEmail(const QUrl &url)
+
+ return QDBusConnection::sessionBus().call(message);
+ }
++
++namespace {
++struct XDGDesktopColor
++{
++ double r = 0;
++ double g = 0;
++ double b = 0;
++
++ QColor toQColor() const
++ {
++ constexpr auto rgbMax = 255;
++ return { static_cast<int>(r * rgbMax), static_cast<int>(g * rgbMax),
++ static_cast<int>(b * rgbMax) };
++ }
++};
++
++const QDBusArgument &operator>>(const QDBusArgument &argument, XDGDesktopColor &myStruct)
++{
++ argument.beginStructure();
++ argument >> myStruct.r >> myStruct.g >> myStruct.b;
++ argument.endStructure();
++ return argument;
++}
++
++class XdgDesktopPortalColorPicker : public QPlatformServiceColorPicker
++{
++ Q_OBJECT
++public:
++ XdgDesktopPortalColorPicker(const QString &parentWindowId, QWindow *parent)
++ : QPlatformServiceColorPicker(parent), m_parentWindowId(parentWindowId)
++ {
++ }
++
++ void pickColor() override
++ {
++ // DBus signature:
++ // PickColor (IN s parent_window,
++ // IN a{sv} options
++ // OUT o handle)
++ // Options:
++ // handle_token (s) - A string that will be used as the last element of the @handle.
++
++ QDBusMessage message = QDBusMessage::createMethodCall(
++ QStringLiteral("org.freedesktop.portal.Desktop"), QStringLiteral("/org/freedesktop/portal/desktop"),
++ QStringLiteral("org.freedesktop.portal.Screenshot"), QStringLiteral("PickColor"));
++ message << m_parentWindowId << QVariantMap();
++
++ QDBusPendingCall pendingCall = QDBusConnection::sessionBus().asyncCall(message);
++ auto watcher = new QDBusPendingCallWatcher(pendingCall, this);
++ connect(watcher, &QDBusPendingCallWatcher::finished, this,
++ [this](QDBusPendingCallWatcher *watcher) {
++ watcher->deleteLater();
++ QDBusPendingReply<QDBusObjectPath> reply = *watcher;
++ if (reply.isError()) {
++ qWarning("DBus call to pick color failed: %s",
++ qPrintable(reply.error().message()));
++ Q_EMIT colorPicked({});
++ } else {
++ QDBusConnection::sessionBus().connect(
++ QStringLiteral("org.freedesktop.portal.Desktop"), reply.value().path(),
++ QStringLiteral("org.freedesktop.portal.Request"), QStringLiteral("Response"), this,
++ // clang-format off
++ SLOT(gotColorResponse(uint,QVariantMap))
++ // clang-format on
++ );
++ }
++ });
++ }
++
++private Q_SLOTS:
++ void gotColorResponse(uint result, const QVariantMap &map)
++ {
++ if (result != 0)
++ return;
++ XDGDesktopColor color{};
++ map.value(QStringLiteral("color")).value<QDBusArgument>() >> color;
++ Q_EMIT colorPicked(color.toQColor());
++ deleteLater();
++ }
++
++private:
++ const QString m_parentWindowId;
++};
++} // namespace
++
+ #endif // QT_CONFIG(dbus)
+
++QGenericUnixServices::QGenericUnixServices()
++{
++#if QT_CONFIG(dbus)
++ if (qEnvironmentVariableIntValue("QT_NO_XDG_DESKTOP_PORTAL") > 0) {
++ return;
++ }
++ QDBusMessage message = QDBusMessage::createMethodCall(
++ QStringLiteral("org.freedesktop.portal.Desktop"), QStringLiteral("/org/freedesktop/portal/desktop"),
++ QStringLiteral("org.freedesktop.DBus.Properties"), QStringLiteral("Get"));
++ message << QStringLiteral("org.freedesktop.portal.Screenshot")
++ << QStringLiteral("version");
++
++ QDBusPendingCall pendingCall = QDBusConnection::sessionBus().asyncCall(message);
++ auto watcher = new QDBusPendingCallWatcher(pendingCall);
++ QObject::connect(watcher, &QDBusPendingCallWatcher::finished, watcher,
++ [this](QDBusPendingCallWatcher *watcher) {
++ watcher->deleteLater();
++ QDBusPendingReply<QVariant> reply = *watcher;
++ if (!reply.isError() && reply.value().toUInt() >= 2)
++ m_hasScreenshotPortalWithColorPicking = true;
++ });
++
++#endif
++}
++
++QPlatformServiceColorPicker *QGenericUnixServices::colorPicker(QWindow *parent)
++{
++#if QT_CONFIG(dbus)
++ // Make double sure that we are in a wayland environment. In particular check
++ // WAYLAND_DISPLAY so also XWayland apps benefit from portal-based color picking.
++ // Outside wayland we'll rather rely on other means than the XDG desktop portal.
++ if (!qEnvironmentVariableIsEmpty("WAYLAND_DISPLAY")
++ || QGuiApplication::platformName().startsWith(QLatin1String("wayland"))) {
++ return new XdgDesktopPortalColorPicker(portalWindowIdentifier(parent), parent);
++ }
++ return nullptr;
++#else
++ Q_UNUSED(parent);
++ return nullptr;
++#endif
++}
++
+ QByteArray QGenericUnixServices::desktopEnvironment() const
+ {
+ static const QByteArray result = detectDesktopEnvironment();
+@@ -352,6 +486,8 @@ bool QGenericUnixServices::openDocument(const QUrl &url)
+ }
+
+ #else
++QGenericUnixServices::QGenericUnixServices() = default;
++
+ QByteArray QGenericUnixServices::desktopEnvironment() const
+ {
+ return QByteArrayLiteral("UNKNOWN");
+@@ -371,6 +507,30 @@ bool QGenericUnixServices::openDocument(const QUrl &url)
+ return false;
+ }
+
++QPlatformServiceColorPicker *QGenericUnixServices::colorPicker(QWindow *parent)
++{
++ Q_UNUSED(parent);
++ return nullptr;
++}
++
+ #endif // QT_NO_MULTIPROCESS
+
++QString QGenericUnixServices::portalWindowIdentifier(QWindow *window)
++{
++ if (QGuiApplication::platformName() == QLatin1String("xcb"))
++ return QStringLiteral("x11:") + QString::number(window->winId(), 16);
++ return QString();
++}
++
++bool QGenericUnixServices::hasCapability(Capability capability) const
++{
++ switch (capability) {
++ case Capability::ColorPicking:
++ return m_hasScreenshotPortalWithColorPicking;
++ }
++ return false;
++}
++
+ QT_END_NAMESPACE
++
++#include "qgenericunixservices.moc"
+diff --git a/qtbase/src/platformsupport/services/genericunix/qgenericunixservices_p.h b/qtbase/src/platformsupport/services/genericunix/qgenericunixservices_p.h
+index 8ac3de6f03..30924e64bd 100644
+--- a/qtbase/src/platformsupport/services/genericunix/qgenericunixservices_p.h
++++ b/qtbase/src/platformsupport/services/genericunix/qgenericunixservices_p.h
+@@ -59,16 +59,21 @@ QT_BEGIN_NAMESPACE
+ class QGenericUnixServices : public QPlatformServices
+ {
+ public:
+- QGenericUnixServices() {}
++ QGenericUnixServices();
+
+ QByteArray desktopEnvironment() const override;
+
++ bool hasCapability(Capability capability) const override;
+ bool openUrl(const QUrl &url) override;
+ bool openDocument(const QUrl &url) override;
++ QPlatformServiceColorPicker *colorPicker(QWindow *parent = nullptr) override;
++
++ virtual QString portalWindowIdentifier(QWindow *window);
+
+ private:
+ QString m_webBrowser;
+ QString m_documentLauncher;
++ bool m_hasScreenshotPortalWithColorPicking = false;
+ };
+
+ QT_END_NAMESPACE
+diff --git a/qtbase/src/platformsupport/themes/genericunix/dbusmenu/qdbusmenuconnection.cpp b/qtbase/src/platformsupport/themes/genericunix/dbusmenu/qdbusmenuconnection.cpp
+index 09470bccc6..cc7c7d4d8a 100644
+--- a/qtbase/src/platformsupport/themes/genericunix/dbusmenu/qdbusmenuconnection.cpp
++++ b/qtbase/src/platformsupport/themes/genericunix/dbusmenu/qdbusmenuconnection.cpp
+@@ -69,6 +69,7 @@ const QString MenuBarPath = QLatin1String("/MenuBar");
+ */
+ QDBusMenuConnection::QDBusMenuConnection(QObject *parent, const QString &serviceName)
+ : QObject(parent)
++ , m_serviceName(serviceName)
+ , m_connection(serviceName.isNull() ? QDBusConnection::sessionBus()
+ : QDBusConnection::connectToBus(QDBusConnection::SessionBus, serviceName))
+ , m_dbusWatcher(new QDBusServiceWatcher(StatusNotifierWatcherService, m_connection, QDBusServiceWatcher::WatchForRegistration, this))
+@@ -83,6 +84,12 @@ QDBusMenuConnection::QDBusMenuConnection(QObject *parent, const QString &service
+ #endif
+ }
+
++QDBusMenuConnection::~QDBusMenuConnection()
++{
++ if (!m_serviceName.isEmpty() && m_connection.isConnected())
++ QDBusConnection::disconnectFromBus(m_serviceName);
++}
++
+ void QDBusMenuConnection::dbusError(const QDBusError &error)
+ {
+ qWarning() << "QDBusTrayIcon encountered a D-Bus error:" << error;
+@@ -105,13 +112,7 @@ void QDBusMenuConnection::unregisterTrayIconMenu(QDBusTrayIcon *item)
+
+ bool QDBusMenuConnection::registerTrayIcon(QDBusTrayIcon *item)
+ {
+- bool success = connection().registerService(item->instanceId());
+- if (!success) {
+- qWarning() << "failed to register service" << item->instanceId();
+- return false;
+- }
+-
+- success = connection().registerObject(StatusNotifierItemPath, item);
++ bool success = connection().registerObject(StatusNotifierItemPath, item);
+ if (!success) {
+ unregisterTrayIcon(item);
+ qWarning() << "failed to register" << item->instanceId() << StatusNotifierItemPath;
+@@ -126,21 +127,18 @@ bool QDBusMenuConnection::registerTrayIcon(QDBusTrayIcon *item)
+
+ bool QDBusMenuConnection::registerTrayIconWithWatcher(QDBusTrayIcon *item)
+ {
++ Q_UNUSED(item);
+ QDBusMessage registerMethod = QDBusMessage::createMethodCall(
+ StatusNotifierWatcherService, StatusNotifierWatcherPath, StatusNotifierWatcherService,
+ QLatin1String("RegisterStatusNotifierItem"));
+- registerMethod.setArguments(QVariantList() << item->instanceId());
++ registerMethod.setArguments(QVariantList() << m_connection.baseService());
+ return m_connection.callWithCallback(registerMethod, this, SIGNAL(trayIconRegistered()), SLOT(dbusError(QDBusError)));
+ }
+
+-bool QDBusMenuConnection::unregisterTrayIcon(QDBusTrayIcon *item)
++void QDBusMenuConnection::unregisterTrayIcon(QDBusTrayIcon *item)
+ {
+ unregisterTrayIconMenu(item);
+ connection().unregisterObject(StatusNotifierItemPath);
+- bool success = connection().unregisterService(item->instanceId());
+- if (!success)
+- qWarning() << "failed to unregister service" << item->instanceId();
+- return success;
+ }
+ #endif // QT_NO_SYSTEMTRAYICON
+
+diff --git a/qtbase/src/platformsupport/themes/genericunix/dbusmenu/qdbusmenuconnection_p.h b/qtbase/src/platformsupport/themes/genericunix/dbusmenu/qdbusmenuconnection_p.h
+index f484795fbb..97bdfabb85 100644
+--- a/qtbase/src/platformsupport/themes/genericunix/dbusmenu/qdbusmenuconnection_p.h
++++ b/qtbase/src/platformsupport/themes/genericunix/dbusmenu/qdbusmenuconnection_p.h
+@@ -70,6 +70,7 @@ class QDBusMenuConnection : public QObject
+
+ public:
+ QDBusMenuConnection(QObject *parent = nullptr, const QString &serviceName = QString());
++ ~QDBusMenuConnection();
+ QDBusConnection connection() const { return m_connection; }
+ QDBusServiceWatcher *dbusWatcher() const { return m_dbusWatcher; }
+ bool isStatusNotifierHostRegistered() const { return m_statusNotifierHostRegistered; }
+@@ -78,7 +79,7 @@ public:
+ void unregisterTrayIconMenu(QDBusTrayIcon *item);
+ bool registerTrayIcon(QDBusTrayIcon *item);
+ bool registerTrayIconWithWatcher(QDBusTrayIcon *item);
+- bool unregisterTrayIcon(QDBusTrayIcon *item);
++ void unregisterTrayIcon(QDBusTrayIcon *item);
+ #endif // QT_NO_SYSTEMTRAYICON
+
+ Q_SIGNALS:
+@@ -90,6 +91,7 @@ private Q_SLOTS:
+ void dbusError(const QDBusError &error);
+
+ private:
++ QString m_serviceName;
+ QDBusConnection m_connection;
+ QDBusServiceWatcher *m_dbusWatcher;
+ bool m_statusNotifierHostRegistered;
+diff --git a/qtbase/src/platformsupport/themes/genericunix/dbustray/qdbustrayicon.cpp b/qtbase/src/platformsupport/themes/genericunix/dbustray/qdbustrayicon.cpp
+index bede70975a..76bfec5e5a 100644
+--- a/qtbase/src/platformsupport/themes/genericunix/dbustray/qdbustrayicon.cpp
++++ b/qtbase/src/platformsupport/themes/genericunix/dbustray/qdbustrayicon.cpp
+@@ -71,8 +71,12 @@ Q_LOGGING_CATEGORY(qLcTray, "qt.qpa.tray")
+ static QString iconTempPath()
+ {
+ QString tempPath = QStandardPaths::writableLocation(QStandardPaths::RuntimeLocation);
+- if (!tempPath.isEmpty())
++ if (!tempPath.isEmpty()) {
++ QString flatpakId = qEnvironmentVariable("FLATPAK_ID");
++ if (!flatpakId.isEmpty() && QFileInfo::exists(QLatin1String("/.flatpak-info")))
++ tempPath += QLatin1String("/app/") + flatpakId;
+ return tempPath;
++ }
+
+ tempPath = QStandardPaths::writableLocation(QStandardPaths::GenericCacheLocation);
+
+diff --git a/qtbase/src/platformsupport/themes/genericunix/qgenericunixthemes.cpp b/qtbase/src/platformsupport/themes/genericunix/qgenericunixthemes.cpp
+index cb1b39db64..6e01af052c 100644
+--- a/qtbase/src/platformsupport/themes/genericunix/qgenericunixthemes.cpp
++++ b/qtbase/src/platformsupport/themes/genericunix/qgenericunixthemes.cpp
+@@ -755,6 +755,9 @@ QVariant QGnomeTheme::themeHint(QPlatformTheme::ThemeHint hint) const
+ return QVariant(QChar(0x2022));
+ case QPlatformTheme::UiEffects:
+ return QVariant(int(HoverEffect));
++ case QPlatformTheme::ButtonPressKeys:
++ return QVariant::fromValue(
++ QList<Qt::Key>({ Qt::Key_Space, Qt::Key_Return, Qt::Key_Enter, Qt::Key_Select }));
+ default:
+ break;
+ }
+diff --git a/qtbase/src/plugins/platforms/eglfs/api/qeglfscursor.cpp b/qtbase/src/plugins/platforms/eglfs/api/qeglfscursor.cpp
+index 98e05195ee..1e92f43dec 100644
+--- a/qtbase/src/plugins/platforms/eglfs/api/qeglfscursor.cpp
++++ b/qtbase/src/plugins/platforms/eglfs/api/qeglfscursor.cpp
+@@ -343,8 +343,7 @@ void QEglFSCursor::paintOnScreen()
+ // screens are siblings of each other. When not enabled, the sibling list
+ // only contains m_screen itself.
+ for (QPlatformScreen *screen : m_screen->virtualSiblings()) {
+- if (screen->geometry().contains(cr.topLeft().toPoint() + m_cursor.hotSpot)
+- && QOpenGLContext::currentContext()->screen() == screen->screen())
++ if (screen->geometry().contains(cr.topLeft().toPoint() + m_cursor.hotSpot))
+ {
+ cr.translate(-screen->geometry().topLeft());
+ const QSize screenSize = screen->geometry().size();
+@@ -468,11 +467,12 @@ void QEglFSCursor::draw(const QRectF &r)
+ {
+ StateSaver stateSaver;
+
+- QEglFSCursorData &gfx = static_cast<QEglFSContext*>(QOpenGLContext::currentContext()->handle())->cursorData;
+- if (!gfx.program) {
+- // one time initialization
++ // one time initialization
++ if (!QOpenGLFunctions::d_ptr)
+ initializeOpenGLFunctions();
+
++ QEglFSCursorData &gfx = static_cast<QEglFSContext*>(QOpenGLContext::currentContext()->handle())->cursorData;
++ if (!gfx.program) {
+ createShaderPrograms();
+
+ if (!gfx.atlasTexture) {
+diff --git a/qtbase/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmseventreader.cpp b/qtbase/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmseventreader.cpp
+index 645a0ae2e9..3e0e406f1a 100644
+--- a/qtbase/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmseventreader.cpp
++++ b/qtbase/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmseventreader.cpp
+@@ -179,7 +179,7 @@ void QEglFSKmsEventReader::create(QEglFSKmsDevice *device)
+
+ m_device = device;
+
+- qCDebug(qLcEglfsKmsDebug, "Initalizing event reader for device %p fd %d",
++ qCDebug(qLcEglfsKmsDebug, "Initializing event reader for device %p fd %d",
+ m_device, m_device->fd());
+
+ m_thread = new QEglFSKmsEventReaderThread(m_device->fd());
+diff --git a/qtbase/src/plugins/platforms/offscreen/qoffscreenintegration.cpp b/qtbase/src/plugins/platforms/offscreen/qoffscreenintegration.cpp
+index 141fb68a23..d4294d425a 100644
+--- a/qtbase/src/plugins/platforms/offscreen/qoffscreenintegration.cpp
++++ b/qtbase/src/plugins/platforms/offscreen/qoffscreenintegration.cpp
+@@ -122,11 +122,13 @@ QOffscreenIntegration::QOffscreenIntegration()
+ #endif
+ m_services.reset(new QPlatformServices);
+
+- QWindowSystemInterface::handleScreenAdded(new QOffscreenScreen);
++ m_screen = new QOffscreenScreen;
++ QWindowSystemInterface::handleScreenAdded(m_screen);
+ }
+
+ QOffscreenIntegration::~QOffscreenIntegration()
+ {
++ QWindowSystemInterface::handleScreenRemoved(m_screen);
+ }
+
+ void QOffscreenIntegration::initialize()
+diff --git a/qtbase/src/plugins/platforms/offscreen/qoffscreenintegration.h b/qtbase/src/plugins/platforms/offscreen/qoffscreenintegration.h
+index 0ea90f6c2f..fe00fde07c 100644
+--- a/qtbase/src/plugins/platforms/offscreen/qoffscreenintegration.h
++++ b/qtbase/src/plugins/platforms/offscreen/qoffscreenintegration.h
+@@ -84,6 +84,7 @@ protected:
+ #endif
+ QScopedPointer<QPlatformInputContext> m_inputContext;
+ QScopedPointer<QPlatformServices> m_services;
++ QPlatformScreen *m_screen;
+ mutable QScopedPointer<QPlatformNativeInterface> m_nativeInterface;
+ };
+
+diff --git a/qtbase/src/plugins/platforms/windows/qwindowsglcontext.cpp b/qtbase/src/plugins/platforms/windows/qwindowsglcontext.cpp
+index 6fa5a8a2b3..1f49f0aefd 100644
+--- a/qtbase/src/plugins/platforms/windows/qwindowsglcontext.cpp
++++ b/qtbase/src/plugins/platforms/windows/qwindowsglcontext.cpp
+@@ -48,6 +48,7 @@
+ #include <qpa/qplatformnativeinterface.h>
+ #include <QtPlatformHeaders/qwglnativecontext.h>
+
++#include <private/qsystemlibrary_p.h>
+ #include <algorithm>
+
+ #include <wingdi.h>
+@@ -162,19 +163,25 @@ QFunctionPointer QWindowsOpengl32DLL::resolve(const char *name)
+
+ bool QWindowsOpengl32DLL::init(bool softwareRendering)
+ {
+- const QByteArray opengl32 = QByteArrayLiteral("opengl32.dll");
+- const QByteArray swopengl = QByteArrayLiteral("opengl32sw.dll");
++ const QByteArray opengl32 = QByteArrayLiteral("opengl32");
++ const QByteArray swopengl = QByteArrayLiteral("opengl32sw");
++ bool useSystemLib = false;
+
+ QByteArray openglDll = qgetenv("QT_OPENGL_DLL");
+- if (openglDll.isEmpty())
++ if (openglDll.isEmpty()) {
+ openglDll = softwareRendering ? swopengl : opengl32;
++ useSystemLib = !softwareRendering;
++ }
+
+ openglDll = openglDll.toLower();
+ m_nonOpengl32 = openglDll != opengl32;
+
+ qCDebug(lcQpaGl) << "Qt: Using WGL and OpenGL from" << openglDll;
+
+- m_lib = ::LoadLibraryA(openglDll.constData());
++ if (useSystemLib)
++ m_lib = QSystemLibrary::load((wchar_t*)(QString::fromLatin1(openglDll).utf16()));
++ else
++ m_lib = LoadLibraryA(openglDll.constData());
+ if (!m_lib) {
+ qErrnoWarning(::GetLastError(), "Failed to load %s", openglDll.constData());
+ return false;
+@@ -184,7 +191,7 @@ bool QWindowsOpengl32DLL::init(bool softwareRendering)
+ // Load opengl32.dll always. GDI functions like ChoosePixelFormat do
+ // GetModuleHandle for opengl32.dll and behave differently (and call back into
+ // opengl32) when the module is present. This is fine for dummy contexts and windows.
+- ::LoadLibraryA("opengl32.dll");
++ QSystemLibrary::load(L"opengl32");
+ }
+
+ wglCreateContext = reinterpret_cast<HGLRC (WINAPI *)(HDC)>(resolve("wglCreateContext"));
+diff --git a/qtbase/src/plugins/platforms/windows/qwindowsopengltester.cpp b/qtbase/src/plugins/platforms/windows/qwindowsopengltester.cpp
+index d7d186e804..9eb4011bf2 100644
+--- a/qtbase/src/plugins/platforms/windows/qwindowsopengltester.cpp
++++ b/qtbase/src/plugins/platforms/windows/qwindowsopengltester.cpp
+@@ -49,6 +49,7 @@
+ #include <QtCore/qstandardpaths.h>
+ #include <QtCore/qlibraryinfo.h>
+ #include <QtCore/qhash.h>
++#include <private/qsystemlibrary_p.h>
+
+ #ifndef QT_NO_OPENGL
+ #include <private/qopengl_p.h>
+@@ -396,7 +397,7 @@ bool QWindowsOpenGLTester::testDesktopGL()
+
+ // Test #1: Load opengl32.dll and try to resolve an OpenGL 2 function.
+ // This will typically fail on systems that do not have a real OpenGL driver.
+- lib = LoadLibraryA("opengl32.dll");
++ lib = QSystemLibrary::load(L"opengl32");
+ if (lib) {
+ CreateContext = reinterpret_cast<CreateContextType>(
+ reinterpret_cast<QFunctionPointer>(::GetProcAddress(lib, "wglCreateContext")));
+diff --git a/qtbase/src/plugins/platforms/xcb/nativepainting/qtessellator.cpp b/qtbase/src/plugins/platforms/xcb/nativepainting/qtessellator.cpp
+index 1afa00cfc9..118af6ce73 100644
+--- a/qtbase/src/plugins/platforms/xcb/nativepainting/qtessellator.cpp
++++ b/qtbase/src/plugins/platforms/xcb/nativepainting/qtessellator.cpp
+@@ -41,6 +41,7 @@
+
+ #include <QRect>
+ #include <QList>
++#include <QMap>
+ #include <QDebug>
+
+ #include <qmath.h>
+diff --git a/qtbase/src/plugins/platforms/xcb/qxcbconnection.cpp b/qtbase/src/plugins/platforms/xcb/qxcbconnection.cpp
+index 9e2a37a6a1..e6e175a118 100644
+--- a/qtbase/src/plugins/platforms/xcb/qxcbconnection.cpp
++++ b/qtbase/src/plugins/platforms/xcb/qxcbconnection.cpp
+@@ -488,12 +488,12 @@ void QXcbConnection::printXcbError(const char *message, xcb_generic_error_t *err
+ uint clamped_error_code = qMin<uint>(error->error_code, (sizeof(xcb_errors) / sizeof(xcb_errors[0])) - 1);
+ uint clamped_major_code = qMin<uint>(error->major_code, (sizeof(xcb_protocol_request_codes) / sizeof(xcb_protocol_request_codes[0])) - 1);
+
+- qCWarning(lcQpaXcb, "%s: %d (%s), sequence: %d, resource id: %d, major code: %d (%s), minor code: %d",
+- message,
+- int(error->error_code), xcb_errors[clamped_error_code],
+- int(error->sequence), int(error->resource_id),
+- int(error->major_code), xcb_protocol_request_codes[clamped_major_code],
+- int(error->minor_code));
++ qCDebug(lcQpaXcb, "%s: %d (%s), sequence: %d, resource id: %d, major code: %d (%s), minor code: %d",
++ message,
++ int(error->error_code), xcb_errors[clamped_error_code],
++ int(error->sequence), int(error->resource_id),
++ int(error->major_code), xcb_protocol_request_codes[clamped_major_code],
++ int(error->minor_code));
+ }
+
+ static Qt::MouseButtons translateMouseButtons(int s)
+@@ -702,6 +702,8 @@ void QXcbConnection::handleXcbEvent(xcb_generic_event_t *event)
+ QXcbVirtualDesktop *virtualDesktop = virtualDesktopForRootWindow(propertyNotify->window);
+ if (virtualDesktop)
+ virtualDesktop->updateWorkArea();
++ } else if (propertyNotify->atom == atom(QXcbAtom::_NET_SUPPORTED)) {
++ m_wmSupport->updateNetWMAtoms();
+ } else {
+ HANDLE_PLATFORM_WINDOW_EVENT(xcb_property_notify_event_t, window, handlePropertyNotifyEvent);
+ }
+@@ -750,7 +752,7 @@ void QXcbConnection::handleXcbEvent(xcb_generic_event_t *event)
+ case XCB_XKB_NEW_KEYBOARD_NOTIFY: {
+ xcb_xkb_new_keyboard_notify_event_t *ev = &xkb_event->new_keyboard_notify;
+ if (ev->changed & XCB_XKB_NKN_DETAIL_KEYCODES)
+- m_keyboard->updateKeymap(ev);
++ m_keyboard->updateKeymap();
+ break;
+ }
+ default:
+diff --git a/qtbase/src/plugins/platforms/xcb/qxcbintegration.cpp b/qtbase/src/plugins/platforms/xcb/qxcbintegration.cpp
+index 76869ced60..02d2eebb56 100644
+--- a/qtbase/src/plugins/platforms/xcb/qxcbintegration.cpp
++++ b/qtbase/src/plugins/platforms/xcb/qxcbintegration.cpp
+@@ -274,8 +274,7 @@ QPlatformWindow *QXcbIntegration::createForeignWindow(QWindow *window, WId nativ
+ #ifndef QT_NO_OPENGL
+ QPlatformOpenGLContext *QXcbIntegration::createPlatformOpenGLContext(QOpenGLContext *context) const
+ {
+- QXcbScreen *screen = static_cast<QXcbScreen *>(context->screen()->handle());
+- QXcbGlIntegration *glIntegration = screen->connection()->glIntegration();
++ QXcbGlIntegration *glIntegration = defaultConnection()->glIntegration();
+ if (!glIntegration) {
+ qWarning("QXcbIntegration: Cannot create platform OpenGL context, neither GLX nor EGL are enabled");
+ return nullptr;
+diff --git a/qtbase/src/plugins/platforms/xcb/qxcbkeyboard.cpp b/qtbase/src/plugins/platforms/xcb/qxcbkeyboard.cpp
+index efecd7e2d1..e8286381a2 100644
+--- a/qtbase/src/plugins/platforms/xcb/qxcbkeyboard.cpp
++++ b/qtbase/src/plugins/platforms/xcb/qxcbkeyboard.cpp
+@@ -365,17 +365,6 @@ void QXcbKeyboard::updateKeymap(xcb_mapping_notify_event_t *event)
+ updateKeymap();
+ }
+
+-void QXcbKeyboard::updateKeymap(xcb_xkb_new_keyboard_notify_event_t *event)
+-{
+- if (!event)
+- return;
+-
+- if (event->deviceID != event->oldDeviceID)
+- m_config = false;
+-
+- updateKeymap();
+-}
+-
+ void QXcbKeyboard::updateKeymap()
+ {
+ KeysymModifierMap keysymMods;
+@@ -383,6 +372,8 @@ void QXcbKeyboard::updateKeymap()
+ keysymMods = keysymsToModifiers();
+ updateModifiers(keysymMods);
+
++ m_config = true;
++
+ if (!m_xkbContext) {
+ m_xkbContext.reset(xkb_context_new(XKB_CONTEXT_NO_DEFAULT_INCLUDES));
+ if (!m_xkbContext) {
+@@ -398,13 +389,8 @@ void QXcbKeyboard::updateKeymap()
+ if (connection()->hasXKB()) {
+ m_xkbKeymap.reset(xkb_x11_keymap_new_from_device(m_xkbContext.get(), xcb_connection(),
+ core_device_id, XKB_KEYMAP_COMPILE_NO_FLAGS));
+- if (m_xkbKeymap) {
+- if (m_config)
+- m_xkbState.reset(xkb_state_new(m_xkbKeymap.get()));
+- else
+- m_xkbState.reset(xkb_x11_state_new_from_device(m_xkbKeymap.get(), xcb_connection(), core_device_id));
+-
+- }
++ if (m_xkbKeymap)
++ m_xkbState.reset(xkb_x11_state_new_from_device(m_xkbKeymap.get(), xcb_connection(), core_device_id));
+ } else {
+ m_xkbKeymap.reset(keymapFromCore(keysymMods));
+ if (m_xkbKeymap)
+@@ -425,8 +411,6 @@ void QXcbKeyboard::updateKeymap()
+ updateXKBMods();
+
+ QXkbCommon::verifyHasLatinLayout(m_xkbKeymap.get());
+-
+- m_config = true;
+ }
+
+ QList<int> QXcbKeyboard::possibleKeys(const QKeyEvent *event) const
+diff --git a/qtbase/src/plugins/platforms/xcb/qxcbkeyboard.h b/qtbase/src/plugins/platforms/xcb/qxcbkeyboard.h
+index b652c85fe3..0ee08aeff2 100644
+--- a/qtbase/src/plugins/platforms/xcb/qxcbkeyboard.h
++++ b/qtbase/src/plugins/platforms/xcb/qxcbkeyboard.h
+@@ -69,7 +69,6 @@ public:
+
+ Qt::KeyboardModifiers translateModifiers(int s) const;
+ void updateKeymap(xcb_mapping_notify_event_t *event);
+- void updateKeymap(xcb_xkb_new_keyboard_notify_event_t *event);
+ void updateKeymap();
+ QList<int> possibleKeys(const QKeyEvent *event) const;
+
+diff --git a/qtbase/src/plugins/platforms/xcb/qxcbwindow.cpp b/qtbase/src/plugins/platforms/xcb/qxcbwindow.cpp
+index ffda7b6a57..863e961f4c 100644
+--- a/qtbase/src/plugins/platforms/xcb/qxcbwindow.cpp
++++ b/qtbase/src/plugins/platforms/xcb/qxcbwindow.cpp
+@@ -564,11 +564,6 @@ void QXcbWindow::setGeometry(const QRect &rect)
+ {
+ QPlatformWindow::setGeometry(rect);
+
+- if (shouldDeferTask(Task::SetGeometry)) {
+- m_deferredGeometry = rect;
+- return;
+- }
+-
+ propagateSizeHints();
+
+ QXcbScreen *currentScreen = xcbScreen();
+@@ -693,9 +688,6 @@ void QXcbWindow::setVisible(bool visible)
+
+ void QXcbWindow::show()
+ {
+- if (shouldDeferTask(Task::Map))
+- return;
+-
+ if (window()->isTopLevel()) {
+
+ // update WM_NORMAL_HINTS
+@@ -706,7 +698,7 @@ void QXcbWindow::show()
+ if (isTransient(window())) {
+ const QWindow *tp = window()->transientParent();
+ if (tp && tp->handle())
+- transientXcbParent = static_cast<const QXcbWindow *>(tp->handle())->winId();
++ transientXcbParent = tp->handle()->winId();
+ // Default to client leader if there is no transient parent, else modal dialogs can
+ // be hidden by their parents.
+ if (!transientXcbParent)
+@@ -746,10 +738,6 @@ void QXcbWindow::show()
+
+ void QXcbWindow::hide()
+ {
+- if (shouldDeferTask(Task::Unmap))
+- return;
+-
+- m_wmStateValid = false;
+ xcb_unmap_window(xcb_connection(), m_window);
+
+ // send synthetic UnmapNotify event according to icccm 4.1.4
+@@ -909,9 +897,6 @@ QXcbWindow::NetWmStates QXcbWindow::netWmStates()
+
+ void QXcbWindow::setWindowFlags(Qt::WindowFlags flags)
+ {
+- if (shouldDeferTask(Task::SetWindowFlags))
+- return;
+-
+ Qt::WindowType type = static_cast<Qt::WindowType>(int(flags & Qt::WindowType_Mask));
+
+ if (type == Qt::ToolTip)
+@@ -941,8 +926,6 @@ void QXcbWindow::setWindowFlags(Qt::WindowFlags flags)
+
+ setTransparentForMouseEvents(flags & Qt::WindowTransparentForInput);
+ updateDoesNotAcceptFocus(flags & Qt::WindowDoesNotAcceptFocus);
+-
+- m_isWmManagedWindow = !(flags & Qt::X11BypassWindowManagerHint);
+ }
+
+ void QXcbWindow::setMotifWmHints(Qt::WindowFlags flags)
+@@ -1142,9 +1125,6 @@ void QXcbWindow::setWindowState(Qt::WindowStates state)
+ if (state == m_windowState)
+ return;
+
+- if (shouldDeferTask(Task::SetWindowState))
+- return;
+-
+ // unset old state
+ if (m_windowState & Qt::WindowMinimized)
+ xcb_map_window(xcb_connection(), m_window);
+@@ -1350,6 +1330,12 @@ void QXcbWindow::setWindowIcon(const QIcon &icon)
+ }
+
+ if (!icon_data.isEmpty()) {
++ // Ignore icon exceeding maximum xcb request length
++ if (icon_data.size() > xcb_get_maximum_request_length(xcb_connection())) {
++ qWarning("Ignoring window icon: Size %llu exceeds maximum xcb request length %u.",
++ icon_data.size(), xcb_get_maximum_request_length(xcb_connection()));
++ return;
++ }
+ xcb_change_property(xcb_connection(),
+ XCB_PROP_MODE_REPLACE,
+ m_window,
+@@ -1639,7 +1625,7 @@ void QXcbWindow::setWmWindowType(QXcbWindowFunctions::WmWindowTypes types, Qt::W
+ break;
+ }
+
+- if ((flags & Qt::FramelessWindowHint) && !(type & QXcbWindowFunctions::KdeOverride)) {
++ if ((flags & Qt::FramelessWindowHint) && !(types & QXcbWindowFunctions::KdeOverride)) {
+ // override netwm type - quick and easy for KDE noborder
+ atoms.append(atom(QXcbAtom::_KDE_NET_WM_WINDOW_TYPE_OVERRIDE));
+ }
+@@ -1894,10 +1880,6 @@ void QXcbWindow::handleUnmapNotifyEvent(const xcb_unmap_notify_event_t *event)
+ if (event->window == m_window) {
+ m_mapped = false;
+ QWindowSystemInterface::handleExposeEvent(window(), QRegion());
+- if (!m_isWmManagedWindow || parent()) {
+- m_wmStateValid = true;
+- handleDeferredTasks();
+- }
+ }
+ }
+
+@@ -2212,98 +2194,30 @@ void QXcbWindow::handleLeaveNotifyEvent(const xcb_leave_notify_event_t *event)
+ handleLeaveNotifyEvent(event->root_x, event->root_y, event->mode, event->detail, event->time);
+ }
+
+-bool QXcbWindow::shouldDeferTask(Task task)
+-{
+- if (m_wmStateValid)
+- return false;
+-
+- m_deferredTasks.append(task);
+- return true;
+-}
+-
+-void QXcbWindow::handleDeferredTasks()
+-{
+- Q_ASSERT(m_wmStateValid == true);
+- if (m_deferredTasks.isEmpty())
+- return;
+-
+- bool map = false;
+- bool unmap = false;
+-
+- QVector<Task> tasks;
+- for (auto taskIt = m_deferredTasks.rbegin(); taskIt != m_deferredTasks.rend(); ++taskIt) {
+- if (!tasks.contains(*taskIt))
+- tasks.prepend(*taskIt);
+- }
+-
+- for (Task task : tasks) {
+- switch (task) {
+- case Task::Map:
+- map = true;
+- unmap = false;
+- break;
+- case Task::Unmap:
+- unmap = true;
+- map = false;
+- break;
+- case Task::SetGeometry:
+- setGeometry(m_deferredGeometry);
+- break;
+- case Task::SetWindowFlags:
+- setWindowFlags(window()->flags());
+- break;
+- case Task::SetWindowState:
+- setWindowState(window()->windowState());
+- break;
+- }
+- }
+- m_deferredTasks.clear();
+-
+- if (map) {
+- Q_ASSERT(unmap == false);
+- show();
+- }
+- if (unmap) {
+- Q_ASSERT(map == false);
+- hide();
+- }
+-}
+-
+ void QXcbWindow::handlePropertyNotifyEvent(const xcb_property_notify_event_t *event)
+ {
+ connection()->setTime(event->time);
+
+- const bool wmStateChanged = event->atom == atom(QXcbAtom::WM_STATE);
+- const bool netWmStateChanged = event->atom == atom(QXcbAtom::_NET_WM_STATE);
+- if (netWmStateChanged || wmStateChanged) {
+- if (wmStateChanged && !m_wmStateValid && m_isWmManagedWindow) {
+- // ICCCM 4.1.4
+- // Clients that want to re-use a client window (e.g. by mapping it again)
+- // after withdrawing it must wait for the withdrawal to be complete before
+- // proceeding. The preferred method for doing this is for clients to wait for
+- // a window manager to update or remove the WM_STATE property.
+- m_wmStateValid = true;
+- handleDeferredTasks();
+- }
+- if (event->state == XCB_PROPERTY_DELETE)
++ const bool propertyDeleted = event->state == XCB_PROPERTY_DELETE;
++
++ if (event->atom == atom(QXcbAtom::_NET_WM_STATE) || event->atom == atom(QXcbAtom::WM_STATE)) {
++ if (propertyDeleted)
+ return;
+
+- if (wmStateChanged) {
++ Qt::WindowStates newState = Qt::WindowNoState;
++
++ if (event->atom == atom(QXcbAtom::WM_STATE)) { // WM_STATE: Quick check for 'Minimize'.
+ auto reply = Q_XCB_REPLY(xcb_get_property, xcb_connection(),
+ 0, m_window, atom(QXcbAtom::WM_STATE),
+ XCB_ATOM_ANY, 0, 1024);
+ if (reply && reply->format == 32 && reply->type == atom(QXcbAtom::WM_STATE)) {
+- auto data = static_cast<const quint32 *>(xcb_get_property_value(reply.get()));
+- if (reply->length != 0) {
+- const bool changedToWithdrawn = data[0] == XCB_ICCCM_WM_STATE_WITHDRAWN;
+- const bool changedToIconic = data[0] == XCB_ICCCM_WM_STATE_ICONIC;
+- m_minimized = changedToIconic || (changedToWithdrawn && m_minimized);
+- }
++ const quint32 *data = (const quint32 *)xcb_get_property_value(reply.get());
++ if (reply->length != 0)
++ m_minimized = (data[0] == XCB_ICCCM_WM_STATE_ICONIC
++ || (data[0] == XCB_ICCCM_WM_STATE_WITHDRAWN && m_minimized));
+ }
+ }
+
+- // _NET_WM_STATE handling
+- Qt::WindowStates newState = Qt::WindowNoState;
+ const NetWmStates states = netWmStates();
+ // _NET_WM_STATE_HIDDEN should be set by the Window Manager to indicate that a window would
+ // not be visible on the screen if its desktop/viewport were active and its coordinates were
+@@ -2325,6 +2239,7 @@ void QXcbWindow::handlePropertyNotifyEvent(const xcb_property_notify_event_t *ev
+ if ((m_windowState & Qt::WindowMinimized) && connection()->mouseGrabber() == this)
+ connection()->setMouseGrabber(nullptr);
+ }
++ return;
+ } else if (event->atom == atom(QXcbAtom::_NET_FRAME_EXTENTS)) {
+ m_dirtyFrameMargins = true;
+ }
+diff --git a/qtbase/src/plugins/platforms/xcb/qxcbwindow.h b/qtbase/src/plugins/platforms/xcb/qxcbwindow.h
+index 55af9279b1..6f5c1f5ed9 100644
+--- a/qtbase/src/plugins/platforms/xcb/qxcbwindow.h
++++ b/qtbase/src/plugins/platforms/xcb/qxcbwindow.h
+@@ -74,14 +74,6 @@ public:
+
+ Q_DECLARE_FLAGS(NetWmStates, NetWmState)
+
+- enum Task {
+- Map,
+- Unmap,
+- SetGeometry,
+- SetWindowFlags,
+- SetWindowState
+- };
+-
+ QXcbWindow(QWindow *window);
+ ~QXcbWindow();
+
+@@ -151,9 +143,6 @@ public:
+
+ QXcbWindow *toWindow() override;
+
+- bool shouldDeferTask(Task task);
+- void handleDeferredTasks();
+-
+ void handleMouseEvent(xcb_timestamp_t time, const QPoint &local, const QPoint &global,
+ Qt::KeyboardModifiers modifiers, QEvent::Type type, Qt::MouseEventSource source);
+
+@@ -292,11 +281,6 @@ protected:
+ int m_swapInterval = -1;
+
+ qreal m_sizeHintsScaleFactor = 1.0;
+-
+- bool m_wmStateValid = true;
+- QVector<Task> m_deferredTasks;
+- bool m_isWmManagedWindow = true;
+- QRect m_deferredGeometry;
+ };
+
+ class QXcbForeignWindow : public QXcbWindow
+diff --git a/qtbase/src/plugins/platformthemes/gtk3/qgtk3menu.cpp b/qtbase/src/plugins/platformthemes/gtk3/qgtk3menu.cpp
+index d9d117faeb..640b49daa0 100644
+--- a/qtbase/src/plugins/platformthemes/gtk3/qgtk3menu.cpp
++++ b/qtbase/src/plugins/platformthemes/gtk3/qgtk3menu.cpp
+@@ -85,6 +85,7 @@ QGtk3MenuItem::QGtk3MenuItem()
+ m_checkable(false),
+ m_checked(false),
+ m_enabled(true),
++ m_exclusive(false),
+ m_underline(false),
+ m_invalid(true),
+ m_menu(nullptr),
+diff --git a/qtbase/src/plugins/platformthemes/xdgdesktopportal/qxdgdesktopportalfiledialog.cpp b/qtbase/src/plugins/platformthemes/xdgdesktopportal/qxdgdesktopportalfiledialog.cpp
+index 0048bbc1e6..396e7f6d1c 100644
+--- a/qtbase/src/plugins/platformthemes/xdgdesktopportal/qxdgdesktopportalfiledialog.cpp
++++ b/qtbase/src/plugins/platformthemes/xdgdesktopportal/qxdgdesktopportalfiledialog.cpp
+@@ -102,15 +102,12 @@ const QDBusArgument &operator >>(const QDBusArgument &arg, QXdgDesktopPortalFile
+ class QXdgDesktopPortalFileDialogPrivate
+ {
+ public:
+- QXdgDesktopPortalFileDialogPrivate(QPlatformFileDialogHelper *nativeFileDialog)
++ QXdgDesktopPortalFileDialogPrivate(QPlatformFileDialogHelper *nativeFileDialog, uint fileChooserPortalVersion)
+ : nativeFileDialog(nativeFileDialog)
++ , fileChooserPortalVersion(fileChooserPortalVersion)
+ { }
+
+- WId winId = 0;
+- bool directoryMode = false;
+- bool modal = false;
+- bool multipleFiles = false;
+- bool saveFile = false;
++ QEventLoop loop;
+ QString acceptLabel;
+ QString directory;
+ QString title;
+@@ -121,19 +118,27 @@ public:
+ QString selectedMimeTypeFilter;
+ QString selectedNameFilter;
+ QStringList selectedFiles;
+- QPlatformFileDialogHelper *nativeFileDialog = nullptr;
++ std::unique_ptr<QPlatformFileDialogHelper> nativeFileDialog;
++ uint fileChooserPortalVersion = 0;
++ bool failedToOpen = false;
++ bool directoryMode = false;
++ bool multipleFiles = false;
++ bool saveFile = false;
+ };
+
+-QXdgDesktopPortalFileDialog::QXdgDesktopPortalFileDialog(QPlatformFileDialogHelper *nativeFileDialog)
++QXdgDesktopPortalFileDialog::QXdgDesktopPortalFileDialog(QPlatformFileDialogHelper *nativeFileDialog, uint fileChooserPortalVersion)
+ : QPlatformFileDialogHelper()
+- , d_ptr(new QXdgDesktopPortalFileDialogPrivate(nativeFileDialog))
++ , d_ptr(new QXdgDesktopPortalFileDialogPrivate(nativeFileDialog, fileChooserPortalVersion))
+ {
+ Q_D(QXdgDesktopPortalFileDialog);
+
+ if (d->nativeFileDialog) {
+- connect(d->nativeFileDialog, SIGNAL(accept()), this, SIGNAL(accept()));
+- connect(d->nativeFileDialog, SIGNAL(reject()), this, SIGNAL(reject()));
++ connect(d->nativeFileDialog.get(), SIGNAL(accept()), this, SIGNAL(accept()));
++ connect(d->nativeFileDialog.get(), SIGNAL(reject()), this, SIGNAL(reject()));
+ }
++
++ d->loop.connect(this, SIGNAL(accept()), SLOT(quit()));
++ d->loop.connect(this, SIGNAL(reject()), SLOT(quit()));
+ }
+
+ QXdgDesktopPortalFileDialog::~QXdgDesktopPortalFileDialog()
+@@ -177,7 +182,7 @@ void QXdgDesktopPortalFileDialog::initializeDialog()
+ setDirectory(options()->initialDirectory());
+ }
+
+-void QXdgDesktopPortalFileDialog::openPortal()
++void QXdgDesktopPortalFileDialog::openPortal(Qt::WindowFlags windowFlags, Qt::WindowModality windowModality, QWindow *parent)
+ {
+ Q_D(QXdgDesktopPortalFileDialog);
+
+@@ -185,13 +190,13 @@ void QXdgDesktopPortalFileDialog::openPortal()
+ QLatin1String("/org/freedesktop/portal/desktop"),
+ QLatin1String("org.freedesktop.portal.FileChooser"),
+ d->saveFile ? QLatin1String("SaveFile") : QLatin1String("OpenFile"));
+- QString parentWindowId = QLatin1String("x11:") + QString::number(d->winId, 16);
++ QString parentWindowId = QLatin1String("x11:") + QString::number(parent ? parent->winId() : 0, 16);
+
+ QVariantMap options;
+ if (!d->acceptLabel.isEmpty())
+ options.insert(QLatin1String("accept_label"), d->acceptLabel);
+
+- options.insert(QLatin1String("modal"), d->modal);
++ options.insert(QLatin1String("modal"), windowModality != Qt::NonModal);
+ options.insert(QLatin1String("multiple"), d->multipleFiles);
+ options.insert(QLatin1String("directory"), d->directoryMode);
+
+@@ -290,10 +295,18 @@ void QXdgDesktopPortalFileDialog::openPortal()
+
+ QDBusPendingCall pendingCall = QDBusConnection::sessionBus().asyncCall(message);
+ QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(pendingCall);
+- connect(watcher, &QDBusPendingCallWatcher::finished, this, [this] (QDBusPendingCallWatcher *watcher) {
++ connect(watcher, &QDBusPendingCallWatcher::finished, this, [=] (QDBusPendingCallWatcher *watcher) {
+ QDBusPendingReply<QDBusObjectPath> reply = *watcher;
+- if (reply.isError()) {
+- Q_EMIT reject();
++ // Any error means the dialog is not shown and we need to fallback
++ d->failedToOpen = reply.isError();
++ if (d->failedToOpen) {
++ if (d->nativeFileDialog) {
++ d->nativeFileDialog->show(windowFlags, windowModality, parent);
++ if (d->loop.isRunning())
++ d->nativeFileDialog->exec();
++ } else {
++ Q_EMIT reject();
++ }
+ } else {
+ QDBusConnection::sessionBus().connect(nullptr,
+ reply.value().path(),
+@@ -302,6 +315,7 @@ void QXdgDesktopPortalFileDialog::openPortal()
+ this,
+ SLOT(gotResponse(uint,QVariantMap)));
+ }
++ watcher->deleteLater();
+ });
+ }
+
+@@ -326,7 +340,7 @@ QUrl QXdgDesktopPortalFileDialog::directory() const
+ {
+ Q_D(const QXdgDesktopPortalFileDialog);
+
+- if (d->nativeFileDialog && (options()->fileMode() == QFileDialogOptions::Directory || options()->fileMode() == QFileDialogOptions::DirectoryOnly))
++ if (d->nativeFileDialog && useNativeFileDialog())
+ return d->nativeFileDialog->directory();
+
+ return d->directory;
+@@ -348,7 +362,7 @@ QList<QUrl> QXdgDesktopPortalFileDialog::selectedFiles() const
+ {
+ Q_D(const QXdgDesktopPortalFileDialog);
+
+- if (d->nativeFileDialog && (options()->fileMode() == QFileDialogOptions::Directory || options()->fileMode() == QFileDialogOptions::DirectoryOnly))
++ if (d->nativeFileDialog && useNativeFileDialog())
+ return d->nativeFileDialog->selectedFiles();
+
+ QList<QUrl> files;
+@@ -403,16 +417,13 @@ void QXdgDesktopPortalFileDialog::exec()
+ {
+ Q_D(QXdgDesktopPortalFileDialog);
+
+- if (d->nativeFileDialog && (options()->fileMode() == QFileDialogOptions::Directory || options()->fileMode() == QFileDialogOptions::DirectoryOnly)) {
++ if (d->nativeFileDialog && useNativeFileDialog()) {
+ d->nativeFileDialog->exec();
+ return;
+ }
+
+ // HACK we have to avoid returning until we emit that the dialog was accepted or rejected
+- QEventLoop loop;
+- loop.connect(this, SIGNAL(accept()), SLOT(quit()));
+- loop.connect(this, SIGNAL(reject()), SLOT(quit()));
+- loop.exec();
++ d->loop.exec();
+ }
+
+ void QXdgDesktopPortalFileDialog::hide()
+@@ -429,13 +440,10 @@ bool QXdgDesktopPortalFileDialog::show(Qt::WindowFlags windowFlags, Qt::WindowMo
+
+ initializeDialog();
+
+- d->modal = windowModality != Qt::NonModal;
+- d->winId = parent ? parent->winId() : 0;
+-
+- if (d->nativeFileDialog && (options()->fileMode() == QFileDialogOptions::Directory || options()->fileMode() == QFileDialogOptions::DirectoryOnly))
++ if (d->nativeFileDialog && useNativeFileDialog(OpenFallback))
+ return d->nativeFileDialog->show(windowFlags, windowModality, parent);
+
+- openPortal();
++ openPortal(windowFlags, windowModality, parent);
+
+ return true;
+ }
+@@ -465,4 +473,21 @@ void QXdgDesktopPortalFileDialog::gotResponse(uint response, const QVariantMap &
+ }
+ }
+
++bool QXdgDesktopPortalFileDialog::useNativeFileDialog(QXdgDesktopPortalFileDialog::FallbackType fallbackType) const
++{
++ Q_D(const QXdgDesktopPortalFileDialog);
++
++ if (d->failedToOpen && fallbackType != OpenFallback)
++ return true;
++
++ if (d->fileChooserPortalVersion < 3) {
++ if (options()->fileMode() == QFileDialogOptions::Directory)
++ return true;
++ else if (options()->fileMode() == QFileDialogOptions::DirectoryOnly)
++ return true;
++ }
++
++ return false;
++}
++
+ QT_END_NAMESPACE
+diff --git a/qtbase/src/plugins/platformthemes/xdgdesktopportal/qxdgdesktopportalfiledialog_p.h b/qtbase/src/plugins/platformthemes/xdgdesktopportal/qxdgdesktopportalfiledialog_p.h
+index 4f4de96ecf..65e22a5cf2 100644
+--- a/qtbase/src/plugins/platformthemes/xdgdesktopportal/qxdgdesktopportalfiledialog_p.h
++++ b/qtbase/src/plugins/platformthemes/xdgdesktopportal/qxdgdesktopportalfiledialog_p.h
+@@ -51,6 +51,11 @@ class QXdgDesktopPortalFileDialog : public QPlatformFileDialogHelper
+ Q_OBJECT
+ Q_DECLARE_PRIVATE(QXdgDesktopPortalFileDialog)
+ public:
++ enum FallbackType {
++ GenericFallback,
++ OpenFallback
++ };
++
+ enum ConditionType : uint {
+ GlobalPattern = 0,
+ MimeType = 1
+@@ -69,7 +74,7 @@ public:
+ };
+ typedef QVector<Filter> FilterList;
+
+- QXdgDesktopPortalFileDialog(QPlatformFileDialogHelper *nativeFileDialog = nullptr);
++ QXdgDesktopPortalFileDialog(QPlatformFileDialogHelper *nativeFileDialog = nullptr, uint fileChooserPortalVersion = 0);
+ ~QXdgDesktopPortalFileDialog();
+
+ bool defaultNameFilterDisables() const override;
+@@ -92,7 +97,8 @@ private Q_SLOTS:
+
+ private:
+ void initializeDialog();
+- void openPortal();
++ void openPortal(Qt::WindowFlags windowFlags, Qt::WindowModality windowModality, QWindow *parent);
++ bool useNativeFileDialog(FallbackType fallbackType = GenericFallback) const;
+
+ QScopedPointer<QXdgDesktopPortalFileDialogPrivate> d_ptr;
+ };
+diff --git a/qtbase/src/plugins/platformthemes/xdgdesktopportal/qxdgdesktopportaltheme.cpp b/qtbase/src/plugins/platformthemes/xdgdesktopportal/qxdgdesktopportaltheme.cpp
+index fb324afbd8..b809503122 100644
+--- a/qtbase/src/plugins/platformthemes/xdgdesktopportal/qxdgdesktopportaltheme.cpp
++++ b/qtbase/src/plugins/platformthemes/xdgdesktopportal/qxdgdesktopportaltheme.cpp
+@@ -111,6 +111,7 @@ QXdgDesktopPortalTheme::QXdgDesktopPortalTheme()
+ if (reply.isValid()) {
+ d->fileChooserPortalVersion = reply.value().toUInt();
+ }
++ watcher->deleteLater();
+ });
+ }
+
+@@ -152,11 +153,12 @@ QPlatformDialogHelper* QXdgDesktopPortalTheme::createPlatformDialogHelper(Dialog
+ {
+ Q_D(const QXdgDesktopPortalTheme);
+
+- if (type == FileDialog) {
++ if (type == FileDialog && d->fileChooserPortalVersion) {
+ // Older versions of FileChooser portal don't support opening directories, therefore we fallback
+ // to native file dialog opened inside the sandbox to open a directory.
+- if (d->fileChooserPortalVersion < 3 && d->baseTheme->usePlatformNativeDialog(type))
+- return new QXdgDesktopPortalFileDialog(static_cast<QPlatformFileDialogHelper*>(d->baseTheme->createPlatformDialogHelper(type)));
++ if (d->baseTheme->usePlatformNativeDialog(type))
++ return new QXdgDesktopPortalFileDialog(static_cast<QPlatformFileDialogHelper*>(d->baseTheme->createPlatformDialogHelper(type)),
++ d->fileChooserPortalVersion);
+
+ return new QXdgDesktopPortalFileDialog;
+ }
+diff --git a/qtbase/src/plugins/printsupport/cups/qcupsprintengine.cpp b/qtbase/src/plugins/printsupport/cups/qcupsprintengine.cpp
+index 43d5e119ad..1f9cbc4565 100644
+--- a/qtbase/src/plugins/printsupport/cups/qcupsprintengine.cpp
++++ b/qtbase/src/plugins/printsupport/cups/qcupsprintengine.cpp
+@@ -89,8 +89,10 @@ void QCupsPrintEngine::setProperty(PrintEnginePropertyKey key, const QVariant &v
+ break;
+ case PPK_Duplex: {
+ QPrint::DuplexMode mode = QPrint::DuplexMode(value.toInt());
+- if (mode != d->duplex && d->m_printDevice.supportedDuplexModes().contains(mode))
++ if (d->m_printDevice.supportedDuplexModes().contains(mode)) {
+ d->duplex = mode;
++ d->duplexRequestedExplicitly = true;
++ }
+ break;
+ }
+ case PPK_PrinterName:
+@@ -277,9 +279,12 @@ void QCupsPrintEnginePrivate::changePrinter(const QString &newPrinter)
+ m_printDevice.swap(printDevice);
+ printerName = m_printDevice.id();
+
+- // Check if new printer supports current settings, otherwise us defaults
+- if (duplex != QPrint::DuplexAuto && !m_printDevice.supportedDuplexModes().contains(duplex))
++ // in case a duplex value was explicitly set, check if new printer supports current value,
++ // otherwise use device default
++ if (!duplexRequestedExplicitly || !m_printDevice.supportedDuplexModes().contains(duplex)) {
+ duplex = m_printDevice.defaultDuplexMode();
++ duplexRequestedExplicitly = false;
++ }
+ QPrint::ColorMode colorMode = grayscale ? QPrint::GrayScale : QPrint::Color;
+ if (!m_printDevice.supportedColorModes().contains(colorMode))
+ grayscale = m_printDevice.defaultColorMode() == QPrint::GrayScale;
+diff --git a/qtbase/src/plugins/printsupport/cups/qcupsprintengine_p.h b/qtbase/src/plugins/printsupport/cups/qcupsprintengine_p.h
+index c021b0c643..8f81fe478d 100644
+--- a/qtbase/src/plugins/printsupport/cups/qcupsprintengine_p.h
++++ b/qtbase/src/plugins/printsupport/cups/qcupsprintengine_p.h
+@@ -100,6 +100,7 @@ private:
+ QStringList cupsOptions;
+ QString cupsTempFile;
+ QPrint::DuplexMode duplex;
++ bool duplexRequestedExplicitly = false;
+ };
+
+ QT_END_NAMESPACE
+diff --git a/qtbase/src/plugins/sqldrivers/ibase/qsql_ibase.cpp b/qtbase/src/plugins/sqldrivers/ibase/qsql_ibase.cpp
+index 67e7154fa6..40876152e5 100644
+--- a/qtbase/src/plugins/sqldrivers/ibase/qsql_ibase.cpp
++++ b/qtbase/src/plugins/sqldrivers/ibase/qsql_ibase.cpp
+@@ -817,7 +817,7 @@ bool QIBaseResultPrivate::writeArray(int column, const QList<QVariant> &list)
+ ba.resize(int(bufLen));
+
+ if (list.size() > arraySize) {
+- error = QLatin1String("Array size missmatch: size of %1 is %2, size of provided list is %3");
++ error = QLatin1String("Array size mismatch: size of %1 is %2, size of provided list is %3");
+ error = error.arg(QLatin1String(sqlname)).arg(arraySize).arg(list.size());
+ q->setLastError(QSqlError(error, QLatin1String(""), QSqlError::StatementError));
+ return false;
+diff --git a/qtbase/src/plugins/sqldrivers/mysql/qsql_mysql.cpp b/qtbase/src/plugins/sqldrivers/mysql/qsql_mysql.cpp
+index 7ca055eea2..6bc9d46755 100644
+--- a/qtbase/src/plugins/sqldrivers/mysql/qsql_mysql.cpp
++++ b/qtbase/src/plugins/sqldrivers/mysql/qsql_mysql.cpp
+@@ -223,7 +223,7 @@ public:
+ struct QMyField
+ {
+ char *outField = nullptr;
+- MYSQL_FIELD *myField = nullptr;
++ const MYSQL_FIELD *myField = nullptr;
+ QMetaType::Type type = QMetaType::UnknownType;
+ my_bool nullIndicator = false;
+ ulong bufLength = 0ul;
+@@ -361,7 +361,7 @@ static bool qIsInteger(int t)
+ void QMYSQLResultPrivate::bindBlobs()
+ {
+ int i;
+- MYSQL_FIELD *fieldInfo;
++ const MYSQL_FIELD *fieldInfo;
+ MYSQL_BIND *bind;
+
+ for(i = 0; i < fields.count(); ++i) {
+@@ -379,7 +379,6 @@ void QMYSQLResultPrivate::bindBlobs()
+ bool QMYSQLResultPrivate::bindInValues()
+ {
+ MYSQL_BIND *bind;
+- char *field;
+ int i = 0;
+
+ if (!meta)
+@@ -392,35 +391,34 @@ bool QMYSQLResultPrivate::bindInValues()
+ inBinds = new MYSQL_BIND[fields.size()];
+ memset(inBinds, 0, fields.size() * sizeof(MYSQL_BIND));
+
+- MYSQL_FIELD *fieldInfo;
++ const MYSQL_FIELD *fieldInfo;
+
+ while((fieldInfo = mysql_fetch_field(meta))) {
++ bind = &inBinds[i];
++
+ QMyField &f = fields[i];
+ f.myField = fieldInfo;
+-
++ bind->buffer_length = f.bufLength = fieldInfo->length + 1;
++ bind->buffer_type = fieldInfo->type;
+ f.type = qDecodeMYSQLType(fieldInfo->type, fieldInfo->flags);
+ if (qIsBlob(fieldInfo->type)) {
+ // the size of a blob-field is available as soon as we call
+ // mysql_stmt_store_result()
+ // after mysql_stmt_exec() in QMYSQLResult::exec()
+- fieldInfo->length = 0;
++ bind->buffer_length = f.bufLength = 0;
+ hasBlobs = true;
+ } else if (qIsInteger(f.type)) {
+- fieldInfo->length = 8;
++ bind->buffer_length = f.bufLength = 8;
+ } else {
+- fieldInfo->type = MYSQL_TYPE_STRING;
++ bind->buffer_type = MYSQL_TYPE_STRING;
+ }
+- bind = &inBinds[i];
+- field = new char[fieldInfo->length + 1];
+- memset(field, 0, fieldInfo->length + 1);
+
+- bind->buffer_type = fieldInfo->type;
+- bind->buffer = field;
+- bind->buffer_length = f.bufLength = fieldInfo->length + 1;
+ bind->is_null = &f.nullIndicator;
+ bind->length = &f.bufLength;
+ bind->is_unsigned = fieldInfo->flags & UNSIGNED_FLAG ? 1 : 0;
+- f.outField=field;
++
++ char *field = new char[bind->buffer_length + 1]{};
++ bind->buffer = f.outField = field;
+
+ ++i;
+ }
+@@ -1369,20 +1367,20 @@ bool QMYSQLDriver::open(const QString& db,
+ }
+
+ #if MYSQL_VERSION_ID >= 50007
+- if (mysql_get_client_version() >= 50503 && mysql_get_server_version(d->mysql) >= 50503) {
+- // force the communication to be utf8mb4 (only utf8mb4 supports 4-byte characters)
+- mysql_set_character_set(d->mysql, "utf8mb4");
++ // force the communication to be utf8mb4 (only utf8mb4 supports 4-byte characters)
++ if (mysql_set_character_set(d->mysql, "utf8mb4")) {
++ // this failed, try forcing it to utf (BMP only)
++ if (mysql_set_character_set(d->mysql, "utf8"))
++ qWarning() << "MySQL: Unable to set the client character set to utf8.";
+ #if QT_CONFIG(textcodec)
+- d->tc = QTextCodec::codecForName("UTF-8");
++ else
++ d->tc = codec(d->mysql);
+ #endif
+- } else
+- {
+- // force the communication to be utf8
+- mysql_set_character_set(d->mysql, "utf8");
++ }
+ #if QT_CONFIG(textcodec)
+- d->tc = codec(d->mysql);
++ else
++ d->tc = QTextCodec::codecForName("UTF-8");
+ #endif
+- }
+ #endif // MYSQL_VERSION_ID >= 50007
+
+ d->preparedQuerysEnabled = checkPreparedQueries(d->mysql);
+diff --git a/qtbase/src/printsupport/dialogs/images/print-24.png b/qtbase/src/printsupport/dialogs/images/printer-24.png
+similarity index 100%
+rename from src/printsupport/dialogs/images/print-24.png
+rename to src/printsupport/dialogs/images/printer-24.png
+diff --git a/qtbase/src/printsupport/dialogs/images/print-32.png b/qtbase/src/printsupport/dialogs/images/printer-32.png
+similarity index 100%
+rename from src/printsupport/dialogs/images/print-32.png
+rename to src/printsupport/dialogs/images/printer-32.png
+diff --git a/qtbase/src/printsupport/dialogs/images/view-page-sided-24.png b/qtbase/src/printsupport/dialogs/images/view-pages-facing-24.png
+similarity index 100%
+rename from src/printsupport/dialogs/images/view-page-sided-24.png
+rename to src/printsupport/dialogs/images/view-pages-facing-24.png
+diff --git a/qtbase/src/printsupport/dialogs/images/view-page-sided-32.png b/qtbase/src/printsupport/dialogs/images/view-pages-facing-32.png
+similarity index 100%
+rename from src/printsupport/dialogs/images/view-page-sided-32.png
+rename to src/printsupport/dialogs/images/view-pages-facing-32.png
+diff --git a/qtbase/src/printsupport/dialogs/images/view-page-multi-24.png b/qtbase/src/printsupport/dialogs/images/view-pages-overview-24.png
+similarity index 100%
+rename from src/printsupport/dialogs/images/view-page-multi-24.png
+rename to src/printsupport/dialogs/images/view-pages-overview-24.png
+diff --git a/qtbase/src/printsupport/dialogs/images/view-page-multi-32.png b/qtbase/src/printsupport/dialogs/images/view-pages-overview-32.png
+similarity index 100%
+rename from src/printsupport/dialogs/images/view-page-multi-32.png
+rename to src/printsupport/dialogs/images/view-pages-overview-32.png
+diff --git a/qtbase/src/printsupport/dialogs/images/view-page-one-24.png b/qtbase/src/printsupport/dialogs/images/view-pages-single-24.png
+similarity index 100%
+rename from src/printsupport/dialogs/images/view-page-one-24.png
+rename to src/printsupport/dialogs/images/view-pages-single-24.png
+diff --git a/qtbase/src/printsupport/dialogs/images/view-page-one-32.png b/qtbase/src/printsupport/dialogs/images/view-pages-single-32.png
+similarity index 100%
+rename from src/printsupport/dialogs/images/view-page-one-32.png
+rename to src/printsupport/dialogs/images/view-pages-single-32.png
+diff --git a/qtbase/src/printsupport/dialogs/images/fit-page-24.png b/qtbase/src/printsupport/dialogs/images/zoom-fit-page-24.png
+similarity index 100%
+rename from src/printsupport/dialogs/images/fit-page-24.png
+rename to src/printsupport/dialogs/images/zoom-fit-page-24.png
+diff --git a/qtbase/src/printsupport/dialogs/images/fit-page-32.png b/qtbase/src/printsupport/dialogs/images/zoom-fit-page-32.png
+similarity index 100%
+rename from src/printsupport/dialogs/images/fit-page-32.png
+rename to src/printsupport/dialogs/images/zoom-fit-page-32.png
+diff --git a/qtbase/src/printsupport/dialogs/images/fit-width-24.png b/qtbase/src/printsupport/dialogs/images/zoom-fit-width-24.png
+similarity index 100%
+rename from src/printsupport/dialogs/images/fit-width-24.png
+rename to src/printsupport/dialogs/images/zoom-fit-width-24.png
+diff --git a/qtbase/src/printsupport/dialogs/images/fit-width-32.png b/qtbase/src/printsupport/dialogs/images/zoom-fit-width-32.png
+similarity index 100%
+rename from src/printsupport/dialogs/images/fit-width-32.png
+rename to src/printsupport/dialogs/images/zoom-fit-width-32.png
+diff --git a/qtbase/src/printsupport/dialogs/qpagesetupdialog_unix.cpp b/qtbase/src/printsupport/dialogs/qpagesetupdialog_unix.cpp
+index 78e5b8d1ef..2a28516719 100644
+--- a/qtbase/src/printsupport/dialogs/qpagesetupdialog_unix.cpp
++++ b/qtbase/src/printsupport/dialogs/qpagesetupdialog_unix.cpp
+@@ -532,6 +532,7 @@ void QPageSetupWidget::updateWidget()
+ void QPageSetupWidget::setupPrinter() const
+ {
+ m_printer->setPageLayout(m_pageLayout);
++ m_printer->setPageOrientation(m_pageLayout.orientation());
+ #if QT_CONFIG(cups)
+ QCUPSSupport::PagesPerSheet pagesPerSheet = qvariant_cast<QCUPSSupport::PagesPerSheet>(m_ui.pagesPerSheetCombo->currentData()
+ );
+diff --git a/qtbase/src/printsupport/dialogs/qprintdialog.qrc b/qtbase/src/printsupport/dialogs/qprintdialog.qrc
+index 5a579baa55..10b8e1d341 100644
+--- a/qtbase/src/printsupport/dialogs/qprintdialog.qrc
++++ b/qtbase/src/printsupport/dialogs/qprintdialog.qrc
+@@ -1,9 +1,9 @@
+ <!DOCTYPE RCC><RCC version="1.0">
+ <qresource prefix="/qt-project.org/dialogs/qprintpreviewdialog">
+-<file>images/fit-page-24.png</file>
+-<file>images/fit-page-32.png</file>
+-<file>images/fit-width-24.png</file>
+-<file>images/fit-width-32.png</file>
++<file>images/zoom-fit-page-24.png</file>
++<file>images/zoom-fit-page-32.png</file>
++<file>images/zoom-fit-width-24.png</file>
++<file>images/zoom-fit-width-32.png</file>
+ <file>images/go-first-24.png</file>
+ <file>images/go-first-32.png</file>
+ <file>images/go-last-24.png</file>
+@@ -18,14 +18,14 @@
+ <file>images/layout-portrait-32.png</file>
+ <file>images/page-setup-24.png</file>
+ <file>images/page-setup-32.png</file>
+-<file>images/print-24.png</file>
+-<file>images/print-32.png</file>
+-<file>images/view-page-multi-24.png</file>
+-<file>images/view-page-multi-32.png</file>
+-<file>images/view-page-one-24.png</file>
+-<file>images/view-page-one-32.png</file>
+-<file>images/view-page-sided-24.png</file>
+-<file>images/view-page-sided-32.png</file>
++<file>images/printer-24.png</file>
++<file>images/printer-32.png</file>
++<file>images/view-pages-overview-24.png</file>
++<file>images/view-pages-overview-32.png</file>
++<file>images/view-pages-single-24.png</file>
++<file>images/view-pages-single-32.png</file>
++<file>images/view-pages-facing-24.png</file>
++<file>images/view-pages-facing-32.png</file>
+ <file>images/zoom-in-24.png</file>
+ <file>images/zoom-in-32.png</file>
+ <file>images/zoom-out-24.png</file>
+diff --git a/qtbase/src/printsupport/dialogs/qprintdialog_unix.cpp b/qtbase/src/printsupport/dialogs/qprintdialog_unix.cpp
+index c5b845f4ec..5a5ba1d0a8 100644
+--- a/qtbase/src/printsupport/dialogs/qprintdialog_unix.cpp
++++ b/qtbase/src/printsupport/dialogs/qprintdialog_unix.cpp
+@@ -702,13 +702,14 @@ void QPrintDialogPrivate::selectPrinter(const QPrinter::OutputFormat outputForma
+ else
+ options.grayscale->setChecked(true);
+
+- // keep duplex value explicitly set by user, if any, and selected printer supports it;
+- // use device default otherwise
++ // duplex priorities to be as follows:
++ // 1) a user-selected duplex value in the dialog has highest prority
++ // 2) duplex value set in the QPrinter
+ QPrint::DuplexMode duplex;
+ if (explicitDuplexMode != QPrint::DuplexAuto && supportedDuplexMode.contains(explicitDuplexMode))
+ duplex = explicitDuplexMode;
+ else
+- duplex = top->d->m_currentPrintDevice.defaultDuplexMode();
++ duplex = static_cast<QPrint::DuplexMode>(p->duplex());
+ switch (duplex) {
+ case QPrint::DuplexNone:
+ options.noDuplex->setChecked(true); break;
+@@ -1242,10 +1243,10 @@ void QUnixPrintWidgetPrivate::_q_printerChanged(int index)
+ QString filename = widget.filename->text();
+ widget.filename->setText(filename);
+ widget.lOutput->setEnabled(true);
+- if (optionsPane)
+- optionsPane->selectPrinter(QPrinter::PdfFormat);
+ printer->setOutputFormat(QPrinter::PdfFormat);
+ m_currentPrintDevice = QPrintDevice();
++ if (optionsPane)
++ optionsPane->selectPrinter(QPrinter::PdfFormat);
+ return;
+ }
+ }
+diff --git a/qtbase/src/printsupport/dialogs/qprintpreviewdialog.cpp b/qtbase/src/printsupport/dialogs/qprintpreviewdialog.cpp
+index 39575d5f57..23b7e89538 100644
+--- a/qtbase/src/printsupport/dialogs/qprintpreviewdialog.cpp
++++ b/qtbase/src/printsupport/dialogs/qprintpreviewdialog.cpp
+@@ -352,7 +352,7 @@ void QPrintPreviewDialogPrivate::init(QPrinter *_printer)
+ static inline void qt_setupActionIcon(QAction *action, QLatin1String name)
+ {
+ QLatin1String imagePrefix(":/qt-project.org/dialogs/qprintpreviewdialog/images/");
+- QIcon icon;
++ QIcon icon = QIcon::fromTheme(name);
+ icon.addFile(imagePrefix + name + QLatin1String("-24.png"), QSize(24, 24));
+ icon.addFile(imagePrefix + name + QLatin1String("-32.png"), QSize(32, 32));
+ action->setIcon(icon);
+@@ -383,8 +383,8 @@ void QPrintPreviewDialogPrivate::setupActions()
+ fitPageAction->setObjectName(QLatin1String("fitPageAction"));
+ fitWidthAction->setCheckable(true);
+ fitPageAction->setCheckable(true);
+- qt_setupActionIcon(fitWidthAction, QLatin1String("fit-width"));
+- qt_setupActionIcon(fitPageAction, QLatin1String("fit-page"));
++ qt_setupActionIcon(fitWidthAction, QLatin1String("zoom-fit-width"));
++ qt_setupActionIcon(fitPageAction, QLatin1String("zoom-fit-page"));
+ QObject::connect(fitGroup, SIGNAL(triggered(QAction*)), q, SLOT(_q_fit(QAction*)));
+
+ // Zoom
+@@ -410,9 +410,9 @@ void QPrintPreviewDialogPrivate::setupActions()
+ singleModeAction = modeGroup->addAction(QCoreApplication::translate("QPrintPreviewDialog", "Show single page"));
+ facingModeAction = modeGroup->addAction(QCoreApplication::translate("QPrintPreviewDialog", "Show facing pages"));
+ overviewModeAction = modeGroup->addAction(QCoreApplication::translate("QPrintPreviewDialog", "Show overview of all pages"));
+- qt_setupActionIcon(singleModeAction, QLatin1String("view-page-one"));
+- qt_setupActionIcon(facingModeAction, QLatin1String("view-page-sided"));
+- qt_setupActionIcon(overviewModeAction, QLatin1String("view-page-multi"));
++ qt_setupActionIcon(singleModeAction, QLatin1String("view-pages-single"));
++ qt_setupActionIcon(facingModeAction, QLatin1String("view-pages-facing"));
++ qt_setupActionIcon(overviewModeAction, QLatin1String("view-pages-overview"));
+ singleModeAction->setObjectName(QLatin1String("singleModeAction"));
+ facingModeAction->setObjectName(QLatin1String("facingModeAction"));
+ overviewModeAction->setObjectName(QLatin1String("overviewModeAction"));
+@@ -426,7 +426,7 @@ void QPrintPreviewDialogPrivate::setupActions()
+ printerGroup = new QActionGroup(q);
+ printAction = printerGroup->addAction(QCoreApplication::translate("QPrintPreviewDialog", "Print"));
+ pageSetupAction = printerGroup->addAction(QCoreApplication::translate("QPrintPreviewDialog", "Page setup"));
+- qt_setupActionIcon(printAction, QLatin1String("print"));
++ qt_setupActionIcon(printAction, QLatin1String("printer"));
+ qt_setupActionIcon(pageSetupAction, QLatin1String("page-setup"));
+ QObject::connect(printAction, SIGNAL(triggered(bool)), q, SLOT(_q_print()));
+ QObject::connect(pageSetupAction, SIGNAL(triggered(bool)), q, SLOT(_q_pageSetup()));
+diff --git a/qtbase/src/sql/kernel/qsqlquery.cpp b/qtbase/src/sql/kernel/qsqlquery.cpp
+index 32c6166c79..60afef10c3 100644
+--- a/qtbase/src/sql/kernel/qsqlquery.cpp
++++ b/qtbase/src/sql/kernel/qsqlquery.cpp
+@@ -1,6 +1,6 @@
+ /****************************************************************************
+ **
+-** Copyright (C) 2016 The Qt Company Ltd.
++** Copyright (C) 2022 The Qt Company Ltd.
+ ** Contact: https://www.qt.io/licensing/
+ **
+ ** This file is part of the QtSql module of the Qt Toolkit.
+@@ -377,6 +377,10 @@ bool QSqlQuery::exec(const QString& query)
+ QElapsedTimer t;
+ t.start();
+ #endif
++ if (!driver()) {
++ qWarning("QSqlQuery::exec: called before driver has been set up");
++ return false;
++ }
+ if (d->ref.loadRelaxed() != 1) {
+ bool fo = isForwardOnly();
+ *this = QSqlQuery(driver()->createResult());
+diff --git a/qtbase/src/testlib/qabstractitemmodeltester.cpp b/qtbase/src/testlib/qabstractitemmodeltester.cpp
+index 8efb9c53d4..ce062f66d7 100644
+--- a/qtbase/src/testlib/qabstractitemmodeltester.cpp
++++ b/qtbase/src/testlib/qabstractitemmodeltester.cpp
+@@ -454,7 +454,7 @@ void QAbstractItemModelTesterPrivate::parent()
+
+ // Common error test #2, make sure that a second level index has a parent
+ // that is the first level index.
+- if (model->rowCount(topIndex) > 0) {
++ if (model->rowCount(topIndex) > 0 && model->columnCount(topIndex) > 0) {
+ QModelIndex childIndex = model->index(0, 0, topIndex);
+ MODELTESTER_VERIFY(childIndex.isValid());
+ MODELTESTER_COMPARE(model->parent(childIndex), topIndex);
+diff --git a/qtbase/src/testlib/qasciikey.cpp b/qtbase/src/testlib/qasciikey.cpp
+index 9a308da2bc..93498b256f 100644
+--- a/qtbase/src/testlib/qasciikey.cpp
++++ b/qtbase/src/testlib/qasciikey.cpp
+@@ -498,6 +498,11 @@ char QTest::keyToAscii(Qt::Key key)
+ case Qt::Key_LaunchE : return 0; // = 0x10b0,
+ case Qt::Key_LaunchF : return 0; // = 0x10b1,
+
++ // Keypad navigation keys
++ case Qt::Key_Select : return 0; // = 0x01010000
++ case Qt::Key_Yes : return 0; // = 0x01010001
++ case Qt::Key_No : return 0; // = 0x01010002
++
+ default: QTEST_ASSERT(false); return 0;
+ }
+ }
+diff --git a/qtbase/src/testlib/qtestresult.cpp b/qtbase/src/testlib/qtestresult.cpp
+index 88028aac6e..2e89930776 100644
+--- a/qtbase/src/testlib/qtestresult.cpp
++++ b/qtbase/src/testlib/qtestresult.cpp
+@@ -251,7 +251,8 @@ bool QTestResult::verify(bool statement, const char *statementStr,
+ {
+ QTEST_ASSERT(statementStr);
+
+- char msg[1024] = {'\0'};
++ char msg[1024];
++ msg[0] = '\0';
+
+ if (QTestLog::verboseLevel() >= 2) {
+ qsnprintf(msg, 1024, "QVERIFY(%s)", statementStr);
+@@ -309,7 +310,8 @@ static bool compareHelper(bool success, const char *failureMsg,
+ bool hasValues = true)
+ {
+ const size_t maxMsgLen = 1024;
+- char msg[maxMsgLen] = {'\0'};
++ char msg[maxMsgLen];
++ msg[0] = '\0';
+
+ QTEST_ASSERT(expected);
+ QTEST_ASSERT(actual);
+diff --git a/qtbase/src/widgets/dialogs/qcolordialog.cpp b/qtbase/src/widgets/dialogs/qcolordialog.cpp
+index 4247731275..cb325be85c 100644
+--- a/qtbase/src/widgets/dialogs/qcolordialog.cpp
++++ b/qtbase/src/widgets/dialogs/qcolordialog.cpp
+@@ -78,7 +78,10 @@
+ #include "qwindow.h"
+
+ #include "private/qdialog_p.h"
++#include "private/qguiapplication_p.h"
+
++#include <qpa/qplatformservices.h>
++#include <qpa/qplatformintegration.h>
+ #include <algorithm>
+
+ QT_BEGIN_NAMESPACE
+@@ -1611,6 +1614,20 @@ void QColorDialogPrivate::_q_newStandard(int r, int c)
+ void QColorDialogPrivate::_q_pickScreenColor()
+ {
+ Q_Q(QColorDialog);
++
++ auto *platformServices = QGuiApplicationPrivate::platformIntegration()->services();
++ if (platformServices->hasCapability(QPlatformServices::Capability::ColorPicking)) {
++ if (auto *colorPicker = platformServices->colorPicker(q->windowHandle())) {
++ q->connect(colorPicker, &QPlatformServiceColorPicker::colorPicked, q,
++ [q, colorPicker](const QColor &color) {
++ colorPicker->deleteLater();
++ q->setCurrentColor(color);
++ });
++ colorPicker->pickColor();
++ return;
++ }
++ }
++
+ if (!colorPickingEventFilter)
+ colorPickingEventFilter = new QColorPickingEventFilter(this, q);
+ q->installEventFilter(colorPickingEventFilter);
+diff --git a/qtbase/src/widgets/itemviews/qabstractitemdelegate.cpp b/qtbase/src/widgets/itemviews/qabstractitemdelegate.cpp
+index e120817edc..8ea36b5427 100644
+--- a/qtbase/src/widgets/itemviews/qabstractitemdelegate.cpp
++++ b/qtbase/src/widgets/itemviews/qabstractitemdelegate.cpp
+@@ -400,12 +400,7 @@ bool QAbstractItemDelegate::helpEvent(QHelpEvent *event,
+ const QString tooltip = index.isValid() ?
+ d->textForRole(Qt::ToolTipRole, index.data(Qt::ToolTipRole), option.locale, precision) :
+ QString();
+- QRect rect;
+- if (index.isValid()) {
+- const QRect r = view->visualRect(index);
+- rect = QRect(view->mapToGlobal(r.topLeft()), r.size());
+- }
+- QToolTip::showText(he->globalPos(), tooltip, view, rect);
++ QToolTip::showText(he->globalPos(), tooltip, view->viewport(), option.rect);
+ event->setAccepted(!tooltip.isEmpty());
+ break;
+ }
+diff --git a/qtbase/src/widgets/itemviews/qlistview.cpp b/qtbase/src/widgets/itemviews/qlistview.cpp
+index 2b34476642..eebfaa030e 100644
+--- a/qtbase/src/widgets/itemviews/qlistview.cpp
++++ b/qtbase/src/widgets/itemviews/qlistview.cpp
+@@ -3386,6 +3386,7 @@ void QIconModeViewBase::updateContentsSize()
+ */
+ void QListView::currentChanged(const QModelIndex ¤t, const QModelIndex &previous)
+ {
++ QAbstractItemView::currentChanged(current, previous);
+ #ifndef QT_NO_ACCESSIBILITY
+ if (QAccessible::isActive()) {
+ if (current.isValid()) {
+@@ -3396,7 +3397,6 @@ void QListView::currentChanged(const QModelIndex ¤t, const QModelIndex &pr
+ }
+ }
+ #endif
+- QAbstractItemView::currentChanged(current, previous);
+ }
+
+ /*!
+diff --git a/qtbase/src/widgets/itemviews/qtableview.cpp b/qtbase/src/widgets/itemviews/qtableview.cpp
+index 934ac581b2..f79bb24249 100644
+--- a/qtbase/src/widgets/itemviews/qtableview.cpp
++++ b/qtbase/src/widgets/itemviews/qtableview.cpp
+@@ -1013,6 +1013,7 @@ void QTableViewPrivate::drawCell(QPainter *painter, const QStyleOptionViewItem &
+ int QTableViewPrivate::widthHintForIndex(const QModelIndex &index, int hint, const QStyleOptionViewItem &option) const
+ {
+ Q_Q(const QTableView);
++ const int oldHint = hint;
+ QWidget *editor = editorForIndex(index).widget.data();
+ if (editor && persistent.contains(editor)) {
+ hint = qMax(hint, editor->sizeHint().width());
+@@ -1021,6 +1022,17 @@ int QTableViewPrivate::widthHintForIndex(const QModelIndex &index, int hint, con
+ hint = qBound(min, hint, max);
+ }
+ hint = qMax(hint, q->itemDelegate(index)->sizeHint(option, index).width());
++
++ if (hasSpans()) {
++ auto span = spans.spanAt(index.column(), index.row());
++ if (span && span->m_left == index.column() && span->m_top == index.row()) {
++ // spans are screwed up when sections are moved
++ const auto left = logicalColumn(span->m_left);
++ for (int i = 1; i <= span->width(); ++i)
++ hint -= q->columnWidth(visualColumn(left + i));
++ }
++ hint = std::max(hint, oldHint);
++ }
+ return hint;
+ }
+
+@@ -1053,6 +1065,11 @@ int QTableViewPrivate::heightHintForIndex(const QModelIndex &index, int hint, QS
+ option.rect.setHeight(height);
+ option.rect.setX(q->columnViewportPosition(index.column()));
+ option.rect.setWidth(q->columnWidth(index.column()));
++ if (hasSpans()) {
++ auto span = spans.spanAt(index.column(), index.row());
++ if (span && span->m_left == index.column() && span->m_top == index.row())
++ option.rect.setWidth(std::max(option.rect.width(), visualSpanRect(*span).width()));
++ }
+ // 1px less space when grid is shown (see drawCell)
+ if (showGrid)
+ option.rect.setWidth(option.rect.width() - 1);
+diff --git a/qtbase/src/widgets/kernel/qaction.h b/qtbase/src/widgets/kernel/qaction.h
+index 258a1ea0a0..737c1e8285 100644
+--- a/qtbase/src/widgets/kernel/qaction.h
++++ b/qtbase/src/widgets/kernel/qaction.h
+@@ -81,7 +81,7 @@ class Q_WIDGETS_EXPORT QAction : public QObject
+ Q_PROPERTY(MenuRole menuRole READ menuRole WRITE setMenuRole NOTIFY changed)
+ Q_PROPERTY(bool iconVisibleInMenu READ isIconVisibleInMenu WRITE setIconVisibleInMenu NOTIFY changed)
+ Q_PROPERTY(bool shortcutVisibleInContextMenu READ isShortcutVisibleInContextMenu WRITE setShortcutVisibleInContextMenu NOTIFY changed)
+- Q_PROPERTY(Priority priority READ priority WRITE setPriority)
++ Q_PROPERTY(Priority priority READ priority WRITE setPriority NOTIFY changed)
+
+ public:
+ // note this is copied into qplatformmenu.h, which must stay in sync
+diff --git a/qtbase/src/widgets/kernel/qwidget.cpp b/qtbase/src/widgets/kernel/qwidget.cpp
+index 9eba1e001e..26f6d27e18 100644
+--- a/qtbase/src/widgets/kernel/qwidget.cpp
++++ b/qtbase/src/widgets/kernel/qwidget.cpp
+@@ -5296,7 +5296,7 @@ void QWidgetPrivate::drawWidget(QPaintDevice *pdev, const QRegion &rgn, const QP
+ QWidgetEffectSourcePrivate *sourced = static_cast<QWidgetEffectSourcePrivate *>
+ (source->d_func());
+ if (!sourced->context) {
+- const QRegion effectRgn(rgn.boundingRect());
++ const QRegion effectRgn((flags & UseEffectRegionBounds) ? rgn.boundingRect() : rgn);
+ QWidgetPaintContext context(pdev, effectRgn, offset, flags, sharedPainter, repaintManager);
+ sourced->context = &context;
+ if (!sharedPainter) {
+@@ -5328,6 +5328,7 @@ void QWidgetPrivate::drawWidget(QPaintDevice *pdev, const QRegion &rgn, const QP
+ }
+ }
+ #endif // QT_CONFIG(graphicseffect)
++ flags = flags & ~UseEffectRegionBounds;
+
+ const bool alsoOnScreen = flags & DrawPaintOnScreen;
+ const bool recursive = flags & DrawRecursive;
+diff --git a/qtbase/src/widgets/kernel/qwidget_p.h b/qtbase/src/widgets/kernel/qwidget_p.h
+index eef6b8fa2c..c432f4b5d5 100644
+--- a/qtbase/src/widgets/kernel/qwidget_p.h
++++ b/qtbase/src/widgets/kernel/qwidget_p.h
+@@ -229,7 +229,8 @@ public:
+ DontSubtractOpaqueChildren = 0x10,
+ DontDrawOpaqueChildren = 0x20,
+ DontDrawNativeChildren = 0x40,
+- DontSetCompositionMode = 0x80
++ DontSetCompositionMode = 0x80,
++ UseEffectRegionBounds = 0x100
+ };
+ Q_DECLARE_FLAGS(DrawWidgetFlags, DrawWidgetFlag)
+ Q_FLAG(DrawWidgetFlags)
+diff --git a/qtbase/src/widgets/kernel/qwidgetrepaintmanager.cpp b/qtbase/src/widgets/kernel/qwidgetrepaintmanager.cpp
+index 02880b34da..0d44e1326d 100644
+--- a/qtbase/src/widgets/kernel/qwidgetrepaintmanager.cpp
++++ b/qtbase/src/widgets/kernel/qwidgetrepaintmanager.cpp
+@@ -1018,7 +1018,8 @@ void QWidgetRepaintManager::paintAndFlush()
+
+ // Paint the rest with composition.
+ if (repaintAllWidgets || !dirtyCopy.isEmpty()) {
+- QWidgetPrivate::DrawWidgetFlags flags = QWidgetPrivate::DrawAsRoot | QWidgetPrivate::DrawRecursive;
++ QWidgetPrivate::DrawWidgetFlags flags = QWidgetPrivate::DrawAsRoot | QWidgetPrivate::DrawRecursive
++ | QWidgetPrivate::UseEffectRegionBounds;
+ tlw->d_func()->drawWidget(store->paintDevice(), dirtyCopy, QPoint(), flags, nullptr, this);
+ }
+
+diff --git a/qtbase/src/widgets/styles/qfusionstyle.cpp b/qtbase/src/widgets/styles/qfusionstyle.cpp
+index f4345d97c4..962912c838 100644
+--- a/qtbase/src/widgets/styles/qfusionstyle.cpp
++++ b/qtbase/src/widgets/styles/qfusionstyle.cpp
+@@ -1772,14 +1772,6 @@ void QFusionStyle::drawControl(ControlElement element, const QStyleOption *optio
+ proxy()->drawControl(CE_PushButtonLabel, &subopt, painter, widget);
+ }
+ break;
+- case CE_PushButtonLabel:
+- if (const QStyleOptionButton *button = qstyleoption_cast<const QStyleOptionButton *>(option)) {
+- QStyleOptionButton b(*button);
+- // no PM_ButtonShiftHorizontal and PM_ButtonShiftVertical for fusion style
+- b.state &= ~(State_On | State_Sunken);
+- QCommonStyle::drawControl(element, &b, painter, widget);
+- }
+- break;
+ case CE_MenuBarEmptyArea:
+ painter->save();
+ {
+diff --git a/qtbase/src/widgets/util/qcompleter.cpp b/qtbase/src/widgets/util/qcompleter.cpp
+index 18b24063d8..ef7207a8a3 100644
+--- a/qtbase/src/widgets/util/qcompleter.cpp
++++ b/qtbase/src/widgets/util/qcompleter.cpp
+@@ -1120,6 +1120,8 @@ void QCompleter::setModel(QAbstractItemModel *model)
+ {
+ Q_D(QCompleter);
+ QAbstractItemModel *oldModel = d->proxy->sourceModel();
++ if (oldModel == model)
++ return;
+ #if QT_CONFIG(filesystemmodel)
+ if (qobject_cast<const QFileSystemModel *>(oldModel))
+ setCompletionRole(Qt::EditRole); // QTBUG-54642, clear FileNameRole set by QFileSystemModel
+diff --git a/qtbase/src/widgets/widgets/qabstractbutton.cpp b/qtbase/src/widgets/widgets/qabstractbutton.cpp
+index a128b23950..dc40bf62fb 100644
+--- a/qtbase/src/widgets/widgets/qabstractbutton.cpp
++++ b/qtbase/src/widgets/widgets/qabstractbutton.cpp
+@@ -56,6 +56,7 @@
+ #ifndef QT_NO_ACCESSIBILITY
+ #include "qaccessible.h"
+ #endif
++#include <qpa/qplatformtheme.h>
+
+ #include <algorithm>
+
+@@ -1076,19 +1077,19 @@ void QAbstractButton::keyPressEvent(QKeyEvent *e)
+ {
+ Q_D(QAbstractButton);
+ bool next = true;
+- switch (e->key()) {
+- case Qt::Key_Enter:
+- case Qt::Key_Return:
+- e->ignore();
+- break;
+- case Qt::Key_Select:
+- case Qt::Key_Space:
+- if (!e->isAutoRepeat()) {
+- setDown(true);
+- repaint();
+- d->emitPressed();
+- }
+- break;
++
++ const auto key = static_cast<Qt::Key>(e->key());
++ const auto buttonPressKeys = QGuiApplicationPrivate::platformTheme()
++ ->themeHint(QPlatformTheme::ButtonPressKeys)
++ .value<QList<Qt::Key>>();
++ if (buttonPressKeys.contains(key) && !e->isAutoRepeat()) {
++ setDown(true);
++ repaint();
++ d->emitPressed();
++ return;
++ }
++
++ switch (key) {
+ case Qt::Key_Up:
+ next = false;
+ Q_FALLTHROUGH();
+@@ -1153,15 +1154,15 @@ void QAbstractButton::keyReleaseEvent(QKeyEvent *e)
+ if (!e->isAutoRepeat())
+ d->repeatTimer.stop();
+
+- switch (e->key()) {
+- case Qt::Key_Select:
+- case Qt::Key_Space:
+- if (!e->isAutoRepeat() && d->down)
+- d->click();
+- break;
+- default:
+- e->ignore();
++ const auto buttonPressKeys = QGuiApplicationPrivate::platformTheme()
++ ->themeHint(QPlatformTheme::ButtonPressKeys)
++ .value<QList<Qt::Key>>();
++ if (buttonPressKeys.contains(static_cast<Qt::Key>(e->key())) && !e->isAutoRepeat() && d->down) {
++ d->click();
++ return;
+ }
++
++ e->ignore();
+ }
+
+ /*!\reimp
+diff --git a/qtbase/src/widgets/widgets/qcombobox.cpp b/qtbase/src/widgets/widgets/qcombobox.cpp
+index 7a496c27e0..0a3d96647b 100644
+--- a/qtbase/src/widgets/widgets/qcombobox.cpp
++++ b/qtbase/src/widgets/widgets/qcombobox.cpp
+@@ -3352,7 +3352,23 @@ void QComboBox::keyPressEvent(QKeyEvent *e)
+
+ Move move = NoMove;
+ int newIndex = currentIndex();
+- switch (e->key()) {
++
++ bool pressLikeButton = !d->lineEdit;
++#ifdef QT_KEYPAD_NAVIGATION
++ pressLikeButton |= QApplicationPrivate::keypadNavigationEnabled() && !hasEditFocus();
++#endif
++ auto key = static_cast<Qt::Key>(e->key());
++ if (pressLikeButton) {
++ const auto buttonPressKeys = QGuiApplicationPrivate::platformTheme()
++ ->themeHint(QPlatformTheme::ButtonPressKeys)
++ .value<QList<Qt::Key>>();
++ if (buttonPressKeys.contains(key)) {
++ showPopup();
++ return;
++ }
++ }
++
++ switch (key) {
+ case Qt::Key_Up:
+ if (e->modifiers() & Qt::ControlModifier)
+ break; // pass to line edit for auto completion
+@@ -3394,26 +3410,11 @@ void QComboBox::keyPressEvent(QKeyEvent *e)
+ return;
+ }
+ break;
+- case Qt::Key_Space:
+- if (!d->lineEdit) {
+- showPopup();
+- return;
+- }
+- break;
+- case Qt::Key_Enter:
+- case Qt::Key_Return:
+ case Qt::Key_Escape:
+ if (!d->lineEdit)
+ e->ignore();
+ break;
+ #ifdef QT_KEYPAD_NAVIGATION
+- case Qt::Key_Select:
+- if (QApplicationPrivate::keypadNavigationEnabled()
+- && (!hasEditFocus() || !d->lineEdit)) {
+- showPopup();
+- return;
+- }
+- break;
+ case Qt::Key_Left:
+ case Qt::Key_Right:
+ if (QApplicationPrivate::keypadNavigationEnabled() && !hasEditFocus())
+diff --git a/qtbase/src/widgets/widgets/qdatetimeedit_p.h b/qtbase/src/widgets/widgets/qdatetimeedit_p.h
+index d36b6f8f9a..e0df5b5158 100644
+--- a/qtbase/src/widgets/widgets/qdatetimeedit_p.h
++++ b/qtbase/src/widgets/widgets/qdatetimeedit_p.h
+@@ -1,6 +1,6 @@
+ /****************************************************************************
+ **
+-** Copyright (C) 2018 The Qt Company Ltd.
++** Copyright (C) 2021 The Qt Company Ltd.
+ ** Contact: https://www.qt.io/licensing/
+ **
+ ** This file is part of the QtWidgets module of the Qt Toolkit.
+diff --git a/qtbase/src/widgets/widgets/qgroupbox.cpp b/qtbase/src/widgets/widgets/qgroupbox.cpp
+index 02a0bed325..3f3eccc370 100644
+--- a/qtbase/src/widgets/widgets/qgroupbox.cpp
++++ b/qtbase/src/widgets/widgets/qgroupbox.cpp
+@@ -54,6 +54,8 @@
+ #include "qaccessible.h"
+ #endif
+ #include <private/qwidget_p.h>
++#include <private/qguiapplication_p.h>
++#include <qpa/qplatformtheme.h>
+
+ #include "qdebug.h"
+
+@@ -360,7 +362,10 @@ bool QGroupBox::event(QEvent *e)
+ return true;
+ case QEvent::KeyPress: {
+ QKeyEvent *k = static_cast<QKeyEvent*>(e);
+- if (!k->isAutoRepeat() && (k->key() == Qt::Key_Select || k->key() == Qt::Key_Space)) {
++ const auto buttonPressKeys = QGuiApplicationPrivate::platformTheme()
++ ->themeHint(QPlatformTheme::ButtonPressKeys)
++ .value<QList<Qt::Key>>();
++ if (!k->isAutoRepeat() && buttonPressKeys.contains(static_cast<Qt::Key>(k->key()))) {
+ d->pressedControl = QStyle::SC_GroupBoxCheckBox;
+ update(style()->subControlRect(QStyle::CC_GroupBox, &box, QStyle::SC_GroupBoxCheckBox, this));
+ return true;
+@@ -369,7 +374,10 @@ bool QGroupBox::event(QEvent *e)
+ }
+ case QEvent::KeyRelease: {
+ QKeyEvent *k = static_cast<QKeyEvent*>(e);
+- if (!k->isAutoRepeat() && (k->key() == Qt::Key_Select || k->key() == Qt::Key_Space)) {
++ const auto buttonPressKeys = QGuiApplicationPrivate::platformTheme()
++ ->themeHint(QPlatformTheme::ButtonPressKeys)
++ .value<QList<Qt::Key>>();
++ if (!k->isAutoRepeat() && buttonPressKeys.contains(static_cast<Qt::Key>(k->key()))) {
+ bool toggle = (d->pressedControl == QStyle::SC_GroupBoxLabel
+ || d->pressedControl == QStyle::SC_GroupBoxCheckBox);
+ d->pressedControl = QStyle::SC_None;
+diff --git a/qtbase/src/widgets/widgets/qlabel.cpp b/qtbase/src/widgets/widgets/qlabel.cpp
+index 30ff80cbb0..cf2605c17c 100644
+--- a/qtbase/src/widgets/widgets/qlabel.cpp
++++ b/qtbase/src/widgets/widgets/qlabel.cpp
+@@ -421,9 +421,6 @@ void QLabel::setPixmap(const QPixmap &pixmap)
+ d->pixmap = new QPixmap(pixmap);
+ }
+
+- if (d->pixmap->depth() == 1 && !d->pixmap->mask())
+- d->pixmap->setMask(*((QBitmap *)d->pixmap));
+-
+ d->updateLabel();
+ }
+
+diff --git a/qtbase/src/widgets/widgets/qtoolbararealayout.cpp b/qtbase/src/widgets/widgets/qtoolbararealayout.cpp
+index 493c094cc1..d5f4b59017 100644
+--- a/qtbase/src/widgets/widgets/qtoolbararealayout.cpp
++++ b/qtbase/src/widgets/widgets/qtoolbararealayout.cpp
+@@ -1367,7 +1367,7 @@ bool QToolBarAreaLayout::restoreState(QDataStream &stream, const QList<QToolBar*
+ item.widgetItem = new QWidgetItemV2(toolBar);
+ toolBar->setOrientation(floating ? ((shown & 2) ? Qt::Vertical : Qt::Horizontal) : dock.o);
+ toolBar->setVisible(shown & 1);
+- toolBar->d_func()->setWindowState(floating, true, rect);
++ toolBar->d_func()->setWindowState(floating, false, rect);
+
+ item.preferredSize = item.size;
+ line.toolBarItems.append(item);
+diff --git a/qtbase/tests/auto/concurrent/qtconcurrentiteratekernel/tst_qtconcurrentiteratekernel.cpp b/qtbase/tests/auto/concurrent/qtconcurrentiteratekernel/tst_qtconcurrentiteratekernel.cpp
+index 212c0a2e13..3c77b1ba0b 100644
+--- a/qtbase/tests/auto/concurrent/qtconcurrentiteratekernel/tst_qtconcurrentiteratekernel.cpp
++++ b/qtbase/tests/auto/concurrent/qtconcurrentiteratekernel/tst_qtconcurrentiteratekernel.cpp
+@@ -126,8 +126,7 @@ public:
+
+ void tst_QtConcurrentIterateKernel::instantiate()
+ {
+- auto future = startThreadEngine(new PrintFor(0, 40)).startAsynchronously();
+- future.waitForFinished();
++ startThreadEngine(new PrintFor(0, 40)).startBlocking();
+ QCOMPARE(iterations.loadRelaxed(), 40);
+ }
+
+@@ -166,10 +165,8 @@ void tst_QtConcurrentIterateKernel::stresstest()
+ const int times = 50;
+ for (int i = 0; i < times; ++i) {
+ counter.storeRelaxed(0);
+- // ThreadEngine will delete f when it finishes
+- auto f = new CountFor(0, iterations);
+- auto future = f->startAsynchronously();
+- future.waitForFinished();
++ CountFor f(0, iterations);
++ f.startBlocking();
+ QCOMPARE(counter.loadRelaxed(), iterations);
+ }
+ }
+@@ -177,11 +174,8 @@ void tst_QtConcurrentIterateKernel::stresstest()
+ void tst_QtConcurrentIterateKernel::noIterations()
+ {
+ const int times = 20000;
+- for (int i = 0; i < times; ++i) {
+- auto future = startThreadEngine(new IterateKernel<TestIterator, void>(0, 0))
+- .startAsynchronously();
+- future.waitForFinished();
+- }
++ for (int i = 0; i < times; ++i)
++ startThreadEngine(new IterateKernel<TestIterator, void>(0, 0)).startBlocking();
+ }
+
+ QMutex threadsMutex;
+@@ -236,10 +230,8 @@ void tst_QtConcurrentIterateKernel::throttling()
+
+ threads.clear();
+
+- // ThreadEngine will delete f when it finishes
+- auto f = new ThrottleFor(0, totalIterations);
+- auto future = f->startAsynchronously();
+- future.waitForFinished();
++ ThrottleFor f(0, totalIterations);
++ f.startBlocking();
+
+ QCOMPARE(iterations.loadRelaxed(), totalIterations);
+
+diff --git a/qtbase/tests/auto/concurrent/qtconcurrentthreadengine/tst_qtconcurrentthreadengine.cpp b/qtbase/tests/auto/concurrent/qtconcurrentthreadengine/tst_qtconcurrentthreadengine.cpp
+index ac7be7acdd..81bc64c8d9 100644
+--- a/qtbase/tests/auto/concurrent/qtconcurrentthreadengine/tst_qtconcurrentthreadengine.cpp
++++ b/qtbase/tests/auto/concurrent/qtconcurrentthreadengine/tst_qtconcurrentthreadengine.cpp
+@@ -65,9 +65,16 @@ public:
+
+ void tst_QtConcurrentThreadEngine::runDirectly()
+ {
+- PrintUser *engine = new PrintUser();
+- QFuture<void> f = engine->startAsynchronously();
+- f.waitForFinished();
++ {
++ PrintUser engine;
++ engine.startSingleThreaded();
++ engine.startBlocking();
++ }
++ {
++ PrintUser *engine = new PrintUser();
++ QFuture<void> f = engine->startAsynchronously();
++ f.waitForFinished();
++ }
+ }
+
+ class StringResultUser : public ThreadEngine<QString>
+@@ -99,10 +106,8 @@ public:
+
+ void tst_QtConcurrentThreadEngine::result()
+ {
+- // ThreadEngine will delete 'engine' when it finishes
+- auto engine = new StringResultUser();
+- auto future = engine->startAsynchronously();
+- QCOMPARE(future.result(), QString("Foo"));
++ StringResultUser engine;
++ QCOMPARE(*engine.startBlocking(), QString("Foo"));
+ }
+
+ class VoidResultUser : public ThreadEngine<void>
+@@ -128,9 +133,17 @@ public:
+
+ void tst_QtConcurrentThreadEngine::runThroughStarter()
+ {
+- ThreadEngineStarter<QString> starter = startThreadEngine(new StringResultUser());
+- QFuture<QString> f = starter.startAsynchronously();
+- QCOMPARE(f.result(), QString("Foo"));
++ {
++ ThreadEngineStarter<QString> starter = startThreadEngine(new StringResultUser());
++ QFuture<QString> f = starter.startAsynchronously();
++ QCOMPARE(f.result(), QString("Foo"));
++ }
++
++ {
++ ThreadEngineStarter<QString> starter = startThreadEngine(new StringResultUser());
++ QString str = starter.startBlocking();
++ QCOMPARE(str, QString("Foo"));
++ }
+ }
+
+ class CancelUser : public ThreadEngine<void>
+@@ -213,6 +226,12 @@ void tst_QtConcurrentThreadEngine::throttle()
+ f.waitForFinished();
+ QCOMPARE(count.loadRelaxed(), 0);
+ }
++
++ for (int i = 0; i < repeats; ++i) {
++ ThrottleAlwaysUser t;
++ t.startBlocking();
++ QCOMPARE(count.loadRelaxed(), 0);
++ }
+ }
+
+ QSet<QThread *> threads;
+@@ -249,17 +268,35 @@ void tst_QtConcurrentThreadEngine::threadCount()
+ {
+ const int repeats = 10;
+ for (int i = 0; i < repeats; ++i) {
++ ThreadCountUser t;
++ t.startBlocking();
++ int count = threads.count();
++ int count_expected = QThreadPool::globalInstance()->maxThreadCount() + 1; // +1 for the main thread.
++ if (count != count_expected)
++ QEXPECT_FAIL("", "QTBUG-23333", Abort);
++ QCOMPARE(count, count_expected);
++
+ (new ThreadCountUser())->startAsynchronously().waitForFinished();
+- const auto count = threads.count();
+- const auto maxThreadCount = QThreadPool::globalInstance()->maxThreadCount();
+- QVERIFY(count <= maxThreadCount);
+- QVERIFY(!threads.contains(QThread::currentThread()));
++ count = threads.count();
++ count_expected = QThreadPool::globalInstance()->maxThreadCount();
++ if (count != count_expected)
++ QEXPECT_FAIL("", "QTBUG-23333", Abort);
++ QCOMPARE(count, count_expected);
+ }
+
+ // Set the finish flag immediately, this should give us one thread only.
+ for (int i = 0; i < repeats; ++i) {
++ ThreadCountUser t(true /*finishImmediately*/);
++ t.startBlocking();
++ int count = threads.count();
++ if (count != 1)
++ QEXPECT_FAIL("", "QTBUG-23333", Abort);
++ QCOMPARE(count, 1);
++
+ (new ThreadCountUser(true /*finishImmediately*/))->startAsynchronously().waitForFinished();
+- const auto count = threads.count();
++ count = threads.count();
++ if (count != 1)
++ QEXPECT_FAIL("", "QTBUG-23333", Abort);
+ QCOMPARE(count, 1);
+ QVERIFY(!threads.contains(QThread::currentThread()));
+ }
+@@ -400,6 +437,7 @@ public:
+
+ void tst_QtConcurrentThreadEngine::exceptions()
+ {
++ // Asynchronous mode:
+ {
+ bool caught = false;
+ try {
+@@ -412,6 +450,32 @@ void tst_QtConcurrentThreadEngine::exceptions()
+ QVERIFY2(caught, "did not get exception");
+ }
+
++ // Blocking mode:
++ // test throwing the exception from a worker thread.
++ {
++ bool caught = false;
++ try {
++ QtConcurrentExceptionThrower e(QThread::currentThread());
++ e.startBlocking();
++ } catch (const QException &) {
++ caught = true;
++ }
++ QVERIFY2(caught, "did not get exception");
++ }
++
++ // test throwing the exception from the main thread (different code path)
++ {
++ bool caught = false;
++ try {
++ QtConcurrentExceptionThrower e(0);
++ e.startBlocking();
++ } catch (const QException &) {
++ caught = true;
++ }
++ QVERIFY2(caught, "did not get exception");
++ }
++
++ // Asynchronous mode:
+ {
+ bool caught = false;
+ try {
+@@ -423,6 +487,31 @@ void tst_QtConcurrentThreadEngine::exceptions()
+ }
+ QVERIFY2(caught, "did not get exception");
+ }
++
++ // Blocking mode:
++ // test throwing the exception from a worker thread.
++ {
++ bool caught = false;
++ try {
++ UnrelatedExceptionThrower e(QThread::currentThread());
++ e.startBlocking();
++ } catch (const QUnhandledException &) {
++ caught = true;
++ }
++ QVERIFY2(caught, "did not get exception");
++ }
++
++ // test throwing the exception from the main thread (different code path)
++ {
++ bool caught = false;
++ try {
++ UnrelatedExceptionThrower e(0);
++ e.startBlocking();
++ } catch (const QUnhandledException &) {
++ caught = true;
++ }
++ QVERIFY2(caught, "did not get exception");
++ }
+ }
+
+ #endif
+diff --git a/qtbase/tests/auto/corelib/io/qbuffer/tst_qbuffer.cpp b/qtbase/tests/auto/corelib/io/qbuffer/tst_qbuffer.cpp
+index 4968742110..f4c3fb711d 100644
+--- a/qtbase/tests/auto/corelib/io/qbuffer/tst_qbuffer.cpp
++++ b/qtbase/tests/auto/corelib/io/qbuffer/tst_qbuffer.cpp
+@@ -42,6 +42,7 @@ private slots:
+ void writeBlock_data();
+ void writeBlock();
+ void seek();
++ void invalidSeeks();
+ void seekTest_data();
+ void seekTest();
+ void read_rawdata();
+@@ -286,6 +287,29 @@ void tst_QBuffer::seek()
+ QCOMPARE(buffer.size(), pos);
+ }
+
++void tst_QBuffer::invalidSeeks()
++{
++ if constexpr (sizeof(qsizetype) == sizeof(qint64)) {
++ // sizeof(qsizetype) == sizeof(qint64), so +1 would overflow
++ QSKIP("This is a 32-bit-only test.");
++ } else {
++ QBuffer buffer;
++ buffer.open(QIODevice::WriteOnly);
++ QCOMPARE(buffer.buffer().size(), qsizetype(0));
++ QCOMPARE(buffer.pos(), qint64(0));
++ constexpr qint64 MaxQByteArrayCapacity = (std::numeric_limits<qsizetype>::max)();
++ // this should fail fast, not after trying to allocate nearly 2 GiB of data,
++ // potentially crashing in the process:
++ QVERIFY(!buffer.seek(2 * MaxQByteArrayCapacity - 1));
++ QCOMPARE(buffer.buffer().size(), qsizetype(0));
++ QCOMPARE(buffer.pos(), qint64(0));
++ // ditto:
++ QVERIFY(!buffer.seek(MaxQByteArrayCapacity + 1));
++ QCOMPARE(buffer.buffer().size(), qsizetype(0));
++ QCOMPARE(buffer.pos(), qint64(0));
++ }
++}
++
+ void tst_QBuffer::seekTest_data()
+ {
+ writeBlock_data();
+diff --git a/qtbase/tests/auto/corelib/io/qiodevice/tst_qiodevice.cpp b/qtbase/tests/auto/corelib/io/qiodevice/tst_qiodevice.cpp
+index da5327594c..4a04e0f7c6 100644
+--- a/qtbase/tests/auto/corelib/io/qiodevice/tst_qiodevice.cpp
++++ b/qtbase/tests/auto/corelib/io/qiodevice/tst_qiodevice.cpp
+@@ -561,7 +561,8 @@ protected:
+ qint64 readData(char *data, qint64 maxSize) override
+ {
+ maxSize = qMin(maxSize, qint64(buf->size() - offset));
+- memcpy(data, buf->constData() + offset, maxSize);
++ if (maxSize > 0)
++ memcpy(data, buf->constData() + offset, maxSize);
+ offset += maxSize;
+ return maxSize;
+ }
+@@ -604,13 +605,15 @@ protected:
+ qint64 readData(char *data, qint64 maxSize) override
+ {
+ maxSize = qMin(maxSize, qint64(buf.size() - pos()));
+- memcpy(data, buf.constData() + pos(), maxSize);
++ if (maxSize > 0)
++ memcpy(data, buf.constData() + pos(), maxSize);
+ return maxSize;
+ }
+ qint64 writeData(const char *data, qint64 maxSize) override
+ {
+ maxSize = qMin(maxSize, qint64(buf.size() - pos()));
+- memcpy(buf.data() + pos(), data, maxSize);
++ if (maxSize > 0)
++ memcpy(buf.data() + pos(), data, maxSize);
+ return maxSize;
+ }
+
+diff --git a/qtbase/tests/auto/corelib/io/qprocess/tst_qprocess.cpp b/qtbase/tests/auto/corelib/io/qprocess/tst_qprocess.cpp
+index db60bead64..f345a44414 100644
+--- a/qtbase/tests/auto/corelib/io/qprocess/tst_qprocess.cpp
++++ b/qtbase/tests/auto/corelib/io/qprocess/tst_qprocess.cpp
+@@ -1,7 +1,8 @@
+ /****************************************************************************
+ **
+ ** Copyright (C) 2021 The Qt Company Ltd.
+-** Copyright (C) 2020 Intel Corporation.
++** Copyright (C) 2020 The Qt Company Ltd.
++** Copyright (C) 2022 Intel Corporation.
+ ** Contact: https://www.qt.io/licensing/
+ **
+ ** This file is part of the test suite of the Qt Toolkit.
+@@ -150,6 +151,8 @@ private slots:
+ void startStopStartStopBuffers();
+ void processEventsInAReadyReadSlot_data();
+ void processEventsInAReadyReadSlot();
++ void startFromCurrentWorkingDir_data();
++ void startFromCurrentWorkingDir();
+
+ // keep these at the end, since they use lots of processes and sometimes
+ // caused obscure failures to occur in tests that followed them (esp. on the Mac)
+@@ -2731,5 +2734,94 @@ void tst_QProcess::finishProcessBeforeReadingDone_deprecated()
+
+ #endif
+
++enum class ChdirMode {
++ None = 0,
++ InParent,
++ InChild
++};
++Q_DECLARE_METATYPE(ChdirMode)
++
++void tst_QProcess::startFromCurrentWorkingDir_data()
++{
++ qRegisterMetaType<ChdirMode>();
++ QTest::addColumn<QString>("programPrefix");
++ QTest::addColumn<ChdirMode>("chdirMode");
++ QTest::addColumn<bool>("success");
++
++ constexpr bool IsWindows = true
++#ifdef Q_OS_UNIX
++ && false
++#endif
++ ;
++
++ // baseline: trying to execute the directory, this can't possibly succeed!
++ QTest::newRow("plain-same-cwd") << QString() << ChdirMode::None << false;
++
++ // cross-platform behavior: neither OS searches the setWorkingDirectory()
++ // dir without "./"
++ QTest::newRow("plain-child-chdir") << QString() << ChdirMode::InChild << false;
++
++ // cross-platform behavior: both OSes search the parent's CWD with "./"
++ QTest::newRow("prefixed-parent-chdir") << "./" << ChdirMode::InParent << true;
++
++ // opposite behaviors: Windows searches the parent's CWD and Unix searches
++ // the child's with "./"
++ QTest::newRow("prefixed-child-chdir") << "./" << ChdirMode::InChild << !IsWindows;
++
++ // Windows searches the parent's CWD without "./"
++ QTest::newRow("plain-parent-chdir") << QString() << ChdirMode::InParent << IsWindows;
++}
++
++void tst_QProcess::startFromCurrentWorkingDir()
++{
++ QFETCH(QString, programPrefix);
++ QFETCH(ChdirMode, chdirMode);
++ QFETCH(bool, success);
++
++ QProcess process;
++ qRegisterMetaType<QProcess::ProcessError>();
++ QSignalSpy errorSpy(&process, &QProcess::errorOccurred);
++ QVERIFY(errorSpy.isValid());
++
++ // both the dir name and the executable name
++ const QString target = QStringLiteral("testProcessNormal");
++ process.setProgram(programPrefix + target);
++
++#ifdef Q_OS_UNIX
++ // Reset PATH, to be sure it doesn't contain . or the empty path.
++ // We can't do this on Windows because DLLs are searched in PATH
++ // and Windows always searches "." anyway.
++ auto restoreEnv = qScopeGuard([old = qgetenv("PATH")] {
++ qputenv("PATH", old);
++ });
++ qputenv("PATH", "/");
++#endif
++
++ switch (chdirMode) {
++ case ChdirMode::InParent: {
++ auto restoreCwd = qScopeGuard([old = QDir::currentPath()] {
++ QDir::setCurrent(old);
++ });
++ QVERIFY(QDir::setCurrent(target));
++ process.start();
++ break;
++ }
++ case ChdirMode::InChild:
++ process.setWorkingDirectory(target);
++ Q_FALLTHROUGH();
++ case ChdirMode::None:
++ process.start();
++ break;
++ }
++
++ QCOMPARE(process.waitForStarted(), success);
++ QCOMPARE(errorSpy.count(), int(!success));
++ if (success) {
++ QVERIFY(process.waitForFinished());
++ } else {
++ QCOMPARE(process.error(), QProcess::FailedToStart);
++ }
++}
++
+ QTEST_MAIN(tst_QProcess)
+ #include "tst_qprocess.moc"
+diff --git a/qtbase/tests/auto/corelib/itemmodels/qconcatenatetablesproxymodel/tst_qconcatenatetablesproxymodel.cpp b/qtbase/tests/auto/corelib/itemmodels/qconcatenatetablesproxymodel/tst_qconcatenatetablesproxymodel.cpp
+index e1ea7a4552..90972caa57 100644
+--- a/qtbase/tests/auto/corelib/itemmodels/qconcatenatetablesproxymodel/tst_qconcatenatetablesproxymodel.cpp
++++ b/qtbase/tests/auto/corelib/itemmodels/qconcatenatetablesproxymodel/tst_qconcatenatetablesproxymodel.cpp
+@@ -117,6 +117,7 @@ private Q_SLOTS:
+ void shouldPropagateDropAfterLastRow_data();
+ void shouldPropagateDropAfterLastRow();
+ void qtbug91788();
++ void qtbug91878();
+
+ private:
+ QStandardItemModel mod;
+@@ -843,6 +844,22 @@ void tst_QConcatenateTablesProxyModel::qtbug91788()
+ QCOMPARE(proxyConcat.columnCount(), 0);
+ }
+
++void tst_QConcatenateTablesProxyModel::qtbug91878()
++{
++ QStandardItemModel m;
++ m.setRowCount(4);
++ m.setColumnCount(4);
++
++ QConcatenateTablesProxyModel pm;
++ QSortFilterProxyModel proxyFilter;
++ proxyFilter.setSourceModel(&pm);
++ proxyFilter.setFilterFixedString("something");
++ pm.addSourceModel(&m); // This should not assert
++
++ QCOMPARE(pm.columnCount(), 4);
++ QCOMPARE(pm.rowCount(), 4);
++}
++
+ QTEST_GUILESS_MAIN(tst_QConcatenateTablesProxyModel)
+
+ #include "tst_qconcatenatetablesproxymodel.moc"
+diff --git a/qtbase/tests/auto/corelib/kernel/qobject/tst_qobject.cpp b/qtbase/tests/auto/corelib/kernel/qobject/tst_qobject.cpp
+index 9bd66c0835..ed4a0bae5d 100644
+--- a/qtbase/tests/auto/corelib/kernel/qobject/tst_qobject.cpp
++++ b/qtbase/tests/auto/corelib/kernel/qobject/tst_qobject.cpp
+@@ -158,6 +158,7 @@ private slots:
+ void nullReceiver();
+ void functorReferencesConnection();
+ void disconnectDisconnects();
++ void declarativeData();
+ };
+
+ struct QObjectCreatedOnShutdown
+@@ -7679,5 +7680,81 @@ void tst_QObject::disconnectDisconnects()
+ Q_STATIC_ASSERT(QtPrivate::HasQ_OBJECT_Macro<tst_QObject>::Value);
+ Q_STATIC_ASSERT(!QtPrivate::HasQ_OBJECT_Macro<SiblingDeleter>::Value);
+
++#ifdef QT_BUILD_INTERNAL
++/*
++ Since QObjectPrivate stores the declarativeData pointer in a union with the pointer
++ to the currently destroyed child, calls to the QtDeclarative handlers need to be
++ correctly guarded. QTBUG-105286
++*/
++namespace QtDeclarative {
++static QAbstractDeclarativeData *theData;
++
++static void destroyed(QAbstractDeclarativeData *data, QObject *)
++{
++ QCOMPARE(data, theData);
++}
++static void signalEmitted(QAbstractDeclarativeData *data, QObject *, int, void **)
++{
++ QCOMPARE(data, theData);
++}
++// we can't use QCOMPARE in the next two functions, as they don't return void
++static int receivers(QAbstractDeclarativeData *data, const QObject *, int)
++{
++ QTest::qCompare(data, theData, "data", "theData", __FILE__, __LINE__);
++ return 0;
++}
++static bool isSignalConnected(QAbstractDeclarativeData *data, const QObject *, int)
++{
++ QTest::qCompare(data, theData, "data", "theData", __FILE__, __LINE__);
++ return true;
++}
++
++class Object : public QObject
++{
++ Q_OBJECT
++public:
++ using QObject::QObject;
++ ~Object()
++ {
++ if (Object *p = static_cast<Object *>(parent()))
++ p->emitSignal();
++ }
++
++ void emitSignal()
++ {
++ emit theSignal();
++ }
++
++signals:
++ void theSignal();
++};
++
++}
++#endif
++
++void tst_QObject::declarativeData()
++{
++#ifdef QT_BUILD_INTERNAL
++ QScopedValueRollback destroyed(QAbstractDeclarativeData::destroyed,
++ QtDeclarative::destroyed);
++ QScopedValueRollback signalEmitted(QAbstractDeclarativeData::signalEmitted,
++ QtDeclarative::signalEmitted);
++ QScopedValueRollback receivers(QAbstractDeclarativeData::receivers,
++ QtDeclarative::receivers);
++ QScopedValueRollback isSignalConnected(QAbstractDeclarativeData::isSignalConnected,
++ QtDeclarative::isSignalConnected);
++
++ QtDeclarative::Object p;
++ QObjectPrivate *priv = QObjectPrivate::get(&p);
++ priv->declarativeData = QtDeclarative::theData = new QAbstractDeclarativeData;
++
++ connect(&p, &QtDeclarative::Object::theSignal, &p, []{
++ });
++
++ QtDeclarative::Object *child = new QtDeclarative::Object;
++ child->setParent(&p);
++#endif
++}
++
+ QTEST_MAIN(tst_QObject)
+ #include "tst_qobject.moc"
+diff --git a/qtbase/tests/auto/corelib/mimetypes/qmimedatabase/tst_qmimedatabase.cpp b/qtbase/tests/auto/corelib/mimetypes/qmimedatabase/tst_qmimedatabase.cpp
+index 0ea422ecbc..1a3256534b 100644
+--- a/qtbase/tests/auto/corelib/mimetypes/qmimedatabase/tst_qmimedatabase.cpp
++++ b/qtbase/tests/auto/corelib/mimetypes/qmimedatabase/tst_qmimedatabase.cpp
+@@ -70,15 +70,15 @@ static inline QString testSuiteWarning()
+
+ QString result;
+ QTextStream str(&result);
+- str << "\nCannot find the shared-mime-info test suite\nstarting from: "
++ str << "\nCannot find the shared-mime-info test suite\nin the parent of: "
+ << QDir::toNativeSeparators(QDir::currentPath()) << "\n"
+ "cd " << QDir::toNativeSeparators(QStringLiteral("tests/auto/corelib/mimetypes/qmimedatabase")) << "\n"
+- "wget http://cgit.freedesktop.org/xdg/shared-mime-info/snapshot/Release-1-10.zip\n"
+- "unzip Release-1-10.zip\n";
++ "wget https://gitlab.freedesktop.org/xdg/shared-mime-info/-/archive/2.1/shared-mime-info-2.1.zip\n"
++ "unzip shared-mime-info-2.1.zip\n";
+ #ifdef Q_OS_WIN
+- str << "mkdir testfiles\nxcopy /s Release-1-10 s-m-i\n";
++ str << "mkdir testfiles\nxcopy /s shared-mime-info-2.1 s-m-i\n";
+ #else
+- str << "ln -s Release-1-10 s-m-i\n";
++ str << "ln -s shared-mime-info-2.1 s-m-i\n";
+ #endif
+ return result;
+ }
+@@ -154,7 +154,7 @@ void tst_QMimeDatabase::initTestCase()
+ QVERIFY2(copyResourceFile(xmlFileName, xmlTargetFileName, &errorMessage), qPrintable(errorMessage));
+ #endif
+
+- m_testSuite = QFINDTESTDATA("s-m-i/tests");
++ m_testSuite = QFINDTESTDATA("s-m-i/tests/mime-detection");
+ if (m_testSuite.isEmpty())
+ qWarning("%s", qPrintable(testSuiteWarning()));
+
+@@ -611,7 +611,7 @@ void tst_QMimeDatabase::allMimeTypes()
+ QVERIFY(!lst.isEmpty());
+
+ // Hardcoding this is the only way to check both providers find the same number of mimetypes.
+- QCOMPARE(lst.count(), 779);
++ QCOMPARE(lst.count(), 811);
+
+ foreach (const QMimeType &mime, lst) {
+ const QString name = mime.name();
+@@ -631,10 +631,9 @@ void tst_QMimeDatabase::suffixes_data()
+
+ QTest::newRow("mimetype with a single pattern") << "application/pdf" << "*.pdf" << "pdf";
+ QTest::newRow("mimetype with multiple patterns") << "application/x-kpresenter" << "*.kpr;*.kpt" << "kpr";
+- QTest::newRow("jpeg") << "image/jpeg" << "*.jpe;*.jpg;*.jpeg" << "jpeg";
+- //if (KMimeType::sharedMimeInfoVersion() > KDE_MAKE_VERSION(0, 60, 0)) {
+- QTest::newRow("mimetype with many patterns") << "application/vnd.wordperfect" << "*.wp;*.wp4;*.wp5;*.wp6;*.wpd;*.wpp" << "wp";
+- //}
++ // The preferred suffix for image/jpeg is *.jpg, as per https://bugs.kde.org/show_bug.cgi?id=176737
++ QTest::newRow("jpeg") << "image/jpeg" << "*.jpe;*.jpg;*.jpeg" << "jpg";
++ QTest::newRow("mimetype with many patterns") << "application/vnd.wordperfect" << "*.wp;*.wp4;*.wp5;*.wp6;*.wpd;*.wpp" << "wp";
+ QTest::newRow("oasis text mimetype") << "application/vnd.oasis.opendocument.text" << "*.odt" << "odt";
+ QTest::newRow("oasis presentation mimetype") << "application/vnd.oasis.opendocument.presentation" << "*.odp" << "odp";
+ QTest::newRow("mimetype with multiple patterns") << "text/plain" << "*.asc;*.txt;*,v" << "txt";
+diff --git a/qtbase/tests/auto/corelib/serialization/json/tst_qtjson.cpp b/qtbase/tests/auto/corelib/serialization/json/tst_qtjson.cpp
+index 3e58dd03cc..c8f82ef5d5 100644
+--- a/qtbase/tests/auto/corelib/serialization/json/tst_qtjson.cpp
++++ b/qtbase/tests/auto/corelib/serialization/json/tst_qtjson.cpp
+@@ -176,6 +176,8 @@ private Q_SLOTS:
+ void fromToVariantConversions_data();
+ void fromToVariantConversions();
+
++ void noLeakOnNameClash();
++
+ private:
+ QString testDataDir;
+ };
+@@ -3685,5 +3687,23 @@ void tst_QtJson::fromToVariantConversions()
+ }
+ }
+
++void tst_QtJson::noLeakOnNameClash()
++{
++ QJsonDocument doc = QJsonDocument::fromJson("{\"\":{\"\":0},\"\":0}");
++ QVERIFY(!doc.isNull());
++ const QJsonObject obj = doc.object();
++
++ // Removed the duplicate key.
++ QCOMPARE(obj.length(), 1);
++
++ // Retained the last of the duplicates.
++ const QJsonValue val = obj.begin().value();
++ QVERIFY(val.isDouble());
++ QCOMPARE(val.toDouble(), 0.0);
++
++ // It should not leak.
++ // In particular it should not forget to deref the container for the inner object.
++}
++
+ QTEST_MAIN(tst_QtJson)
+ #include "tst_qtjson.moc"
+diff --git a/qtbase/tests/auto/corelib/time/qtimezone/tst_qtimezone.cpp b/qtbase/tests/auto/corelib/time/qtimezone/tst_qtimezone.cpp
+index a59b58d57f..241c3e84ac 100644
+--- a/qtbase/tests/auto/corelib/time/qtimezone/tst_qtimezone.cpp
++++ b/qtbase/tests/auto/corelib/time/qtimezone/tst_qtimezone.cpp
+@@ -63,6 +63,7 @@ private slots:
+ void isValidId_data();
+ void isValidId();
+ void malformed();
++ void serialize();
+ // Backend tests
+ void utcTest();
+ void icuTest();
+@@ -947,6 +948,33 @@ void tst_QTimeZone::malformed()
+ barf.offsetFromUtc(now);
+ }
+
++void tst_QTimeZone::serialize()
++{
++ int parts = 0;
++#ifndef QT_NO_DEBUG_STREAM
++ qDebug() << QTimeZone(); // to verify no crash
++ parts++;
++#endif
++#ifndef QT_NO_DATASTREAM
++ QByteArray blob;
++ {
++ QDataStream stream(&blob, QIODevice::WriteOnly);
++ stream << QTimeZone("Europe/Oslo") << QTimeZone(420) << QTimeZone() << qint64(-1);
++ }
++ QDataStream stream(&blob, QIODevice::ReadOnly);
++ QTimeZone invalid, offset, oslo;
++ qint64 minusone;
++ stream >> oslo >> offset >> invalid >> minusone;
++ QCOMPARE(oslo, QTimeZone("Europe/Oslo"));
++ QCOMPARE(offset, QTimeZone(420));
++ QVERIFY(!invalid.isValid());
++ QCOMPARE(minusone, qint64(-1));
++ parts++;
++#endif
++ if (!parts)
++ QSKIP("No serialization enabled");
++}
++
+ void tst_QTimeZone::utcTest()
+ {
+ #ifdef QT_BUILD_INTERNAL
+diff --git a/qtbase/tests/auto/dbus/qdbusinterface/tst_qdbusinterface.cpp b/qtbase/tests/auto/dbus/qdbusinterface/tst_qdbusinterface.cpp
+index 05480c6dd2..70f4c75756 100644
+--- a/qtbase/tests/auto/dbus/qdbusinterface/tst_qdbusinterface.cpp
++++ b/qtbase/tests/auto/dbus/qdbusinterface/tst_qdbusinterface.cpp
+@@ -324,6 +324,13 @@ void tst_QDBusInterface::notValid()
+
+ QVERIFY(!interface.isValid());
+ QVERIFY(!QMetaObject::invokeMethod(&interface, "ListNames", Qt::DirectConnection));
++
++ // With a connection, but empty/null service and path specified
++ QDBusConnection con = QDBusConnection::sessionBus();
++ QVERIFY(con.isConnected());
++ QDBusInterface iface({}, {}, {}, con);
++ QVERIFY(!iface.isValid());
++ QVERIFY(!QMetaObject::invokeMethod(&interface, "ListNames", Qt::DirectConnection));
+ }
+
+ void tst_QDBusInterface::notValidDerived()
+diff --git a/qtbase/tests/auto/gui/kernel/qkeysequence/tst_qkeysequence.cpp b/qtbase/tests/auto/gui/kernel/qkeysequence/tst_qkeysequence.cpp
+index 874468c954..04ceb4ab65 100644
+--- a/qtbase/tests/auto/gui/kernel/qkeysequence/tst_qkeysequence.cpp
++++ b/qtbase/tests/auto/gui/kernel/qkeysequence/tst_qkeysequence.cpp
+@@ -507,6 +507,10 @@ void tst_QKeySequence::toStringFromKeycode_data()
+ QTest::newRow("Ctrl+Alt+Num+Del") << QKeySequence(Qt::ControlModifier | Qt::AltModifier | Qt::KeypadModifier | Qt::Key_Delete) << "Ctrl+Alt+Num+Del";
+ QTest::newRow("Ctrl+Ins") << QKeySequence(Qt::ControlModifier | Qt::Key_Insert) << "Ctrl+Ins";
+ QTest::newRow("Ctrl+Num+Ins(1)") << QKeySequence(Qt::Key_Insert | Qt::KeypadModifier | Qt::ControlModifier) << "Ctrl+Num+Ins";
++ QTest::newRow("Ctrl") << QKeySequence(Qt::Key_Control) << "Control";
++ QTest::newRow("Alt") << QKeySequence(Qt::Key_Alt) << "Alt";
++ QTest::newRow("Shift") << QKeySequence(Qt::Key_Shift) << "Shift";
++ QTest::newRow("Meta") << QKeySequence(Qt::Key_Meta) << "Meta";
+ }
+
+ void tst_QKeySequence::toStringFromKeycode()
+diff --git a/qtbase/tests/auto/gui/text/qfontdatabase/tst_qfontdatabase.cpp b/qtbase/tests/auto/gui/text/qfontdatabase/tst_qfontdatabase.cpp
+index 15e0ecadaa..b4eca74283 100644
+--- a/qtbase/tests/auto/gui/text/qfontdatabase/tst_qfontdatabase.cpp
++++ b/qtbase/tests/auto/gui/text/qfontdatabase/tst_qfontdatabase.cpp
+@@ -81,6 +81,8 @@ private slots:
+ void registerOpenTypePreferredNamesSystem();
+ void registerOpenTypePreferredNamesApplication();
+
++ void stretchRespected();
++
+ private:
+ QString m_ledFont;
+ QString m_testFont;
+@@ -355,6 +357,28 @@ static QString testString()
+ return QStringLiteral("foo bar");
+ }
+
++void tst_QFontDatabase::stretchRespected()
++{
++ int italicId = QFontDatabase::addApplicationFont(m_testFontItalic);
++ QVERIFY(italicId != -1);
++
++ QVERIFY(!QFontDatabase::applicationFontFamilies(italicId).isEmpty());
++
++ QString italicFontName = QFontDatabase::applicationFontFamilies(italicId).first();
++
++ QFont italicFont = QFontDatabase().font(italicFontName,
++ QString::fromLatin1("Italic"), 14);
++ QVERIFY(italicFont.italic());
++
++ QFont italicStretchedFont = italicFont;
++ italicStretchedFont.setStretch( 400 );
++
++ QVERIFY(QFontMetricsF(italicFont).horizontalAdvance(QStringLiteral("foobar")) <
++ QFontMetricsF(italicStretchedFont).horizontalAdvance(QStringLiteral("foobar")));
++
++ QFontDatabase::removeApplicationFont(italicId);
++}
++
+ void tst_QFontDatabase::condensedFontWidthNoFontMerging()
+ {
+ int regularFontId = QFontDatabase::addApplicationFont(m_testFont);
+diff --git a/qtbase/tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp b/qtbase/tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp
+index 3d4a094c43..b423e11a99 100644
+--- a/qtbase/tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp
++++ b/qtbase/tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp
+@@ -281,6 +281,7 @@ private Q_SLOTS:
+ void ioGetFromFileSpecial();
+ void ioGetFromFile_data();
+ void ioGetFromFile();
++ void ioGetFromFileUrl();
+ void ioGetFromFtp_data();
+ void ioGetFromFtp();
+ void ioGetFromFtpWithReuse();
+@@ -3300,6 +3301,18 @@ void tst_QNetworkReply::ioGetFromFile()
+ QCOMPARE(reader.data, data);
+ }
+
++void tst_QNetworkReply::ioGetFromFileUrl()
++{
++ // This immediately fails on non-windows platforms:
++ QNetworkRequest request(QUrl("file://unc-server/some/path"));
++ QNetworkReplyPtr reply(manager.get(request));
++ QSignalSpy finishedSpy(reply.get(), &QNetworkReply::finished);
++ // QTBUG-105618: This would, on non-Windows platforms, never happen because the signal
++ // was emitted before the constructor finished, leaving no chance at all to connect to the
++ // signal
++ QVERIFY(finishedSpy.wait());
++}
++
+ void tst_QNetworkReply::ioGetFromFtp_data()
+ {
+ QTest::addColumn<QString>("fileName");
+diff --git a/qtbase/tests/auto/network/ssl/qsslsocket/certs/fluke.cert b/qtbase/tests/auto/network/ssl/qsslsocket/certs/fluke.cert
+index 069fa6b341..4cc4d9a5ea 100644
+--- a/qtbase/tests/auto/network/ssl/qsslsocket/certs/fluke.cert
++++ b/qtbase/tests/auto/network/ssl/qsslsocket/certs/fluke.cert
+@@ -1,75 +1,34 @@
+-Certificate:
+- Data:
+- Version: 3 (0x2)
+- Serial Number: 0 (0x0)
+- Signature Algorithm: sha1WithRSAEncryption
+- Issuer: C=NO, ST=Oslo, L=Nydalen, O=Nokia Corporation and/or its subsidiary(-ies), OU=Development, CN=fluke.troll.no/emailAddress=ahanssen@trolltech.com
+- Validity
+- Not Before: Dec 4 01:10:32 2007 GMT
+- Not After : Apr 21 01:10:32 2035 GMT
+- Subject: C=NO, ST=Oslo, O=Nokia Corporation and/or its subsidiary(-ies), OU=Development, CN=fluke.troll.no
+- Subject Public Key Info:
+- Public Key Algorithm: rsaEncryption
+- RSA Public Key: (1024 bit)
+- Modulus (1024 bit):
+- 00:a7:c8:a0:4a:c4:19:05:1b:66:ba:32:e2:d2:f1:
+- 1c:6f:17:82:e4:39:2e:01:51:90:db:04:34:32:11:
+- 21:c2:0d:6f:59:d8:53:90:54:3f:83:8f:a9:d3:b3:
+- d5:ee:1a:9b:80:ae:c3:25:c9:5e:a5:af:4b:60:05:
+- aa:a0:d1:91:01:1f:ca:04:83:e3:58:1c:99:32:45:
+- 84:70:72:58:03:98:4a:63:8b:41:f5:08:49:d2:91:
+- 02:60:6b:e4:64:fe:dd:a0:aa:74:08:e9:34:4c:91:
+- 5f:12:3d:37:4d:54:2c:ad:7f:5b:98:60:36:02:8c:
+- 3b:f6:45:f3:27:6a:9b:94:9d
+- Exponent: 65537 (0x10001)
+- X509v3 extensions:
+- X509v3 Basic Constraints:
+- CA:FALSE
+- Netscape Comment:
+- OpenSSL Generated Certificate
+- X509v3 Subject Key Identifier:
+- 21:85:04:3D:23:01:66:E5:F7:9F:1A:84:24:8A:AF:0A:79:F4:E5:AC
+- X509v3 Authority Key Identifier:
+- DirName:/C=NO/ST=Oslo/L=Nydalen/O=Nokia Corporation and/or its subsidiary(-ies)/OU=Development/CN=fluke.troll.no/emailAddress=ahanssen@trolltech.com
+- serial:8E:A8:B4:E8:91:B7:54:2E
+-
+- Signature Algorithm: sha1WithRSAEncryption
+- 6d:57:5f:d1:05:43:f0:62:05:ec:2a:71:a5:dc:19:08:f2:c4:
+- a6:bd:bb:25:d9:ca:89:01:0e:e4:cf:1f:c1:8c:c8:24:18:35:
+- 53:59:7b:c0:43:b4:32:e6:98:b2:a6:ef:15:05:0b:48:5f:e1:
+- a0:0c:97:a9:a1:77:d8:35:18:30:bc:a9:8f:d3:b7:54:c7:f1:
+- a9:9e:5d:e6:19:bf:f6:3c:5b:2b:d8:e4:3e:62:18:88:8b:d3:
+- 24:e1:40:9b:0c:e6:29:16:62:ab:ea:05:24:70:36:aa:55:93:
+- ef:02:81:1b:23:10:a2:04:eb:56:95:75:fc:f8:94:b1:5d:42:
+- c5:3f:36:44:85:5d:3a:2e:90:46:8a:a2:b9:6f:87:ae:0c:15:
+- 40:19:31:90:fc:3b:25:bb:ae:f1:66:13:0d:85:90:d9:49:34:
+- 8f:f2:5d:f9:7a:db:4d:5d:27:f6:76:9d:35:8c:06:a6:4c:a3:
+- b1:b2:b6:6f:1d:d7:a3:00:fd:72:eb:9e:ea:44:a1:af:21:34:
+- 7d:c7:42:e2:49:91:19:8b:c0:ad:ba:82:80:a8:71:70:f4:35:
+- 31:91:63:84:20:95:e9:60:af:64:8b:cc:ff:3d:8a:76:74:3d:
+- c8:55:6d:e4:8e:c3:2b:1c:e8:42:18:ae:9f:e6:6b:9c:34:06:
+- ec:6a:f2:c3
+ -----BEGIN CERTIFICATE-----
+-MIIEEzCCAvugAwIBAgIBADANBgkqhkiG9w0BAQUFADCBnDELMAkGA1UEBhMCTk8x
+-DTALBgNVBAgTBE9zbG8xEDAOBgNVBAcTB055ZGFsZW4xFjAUBgNVBAoTDVRyb2xs
+-dGVjaCBBU0ExFDASBgNVBAsTC0RldmVsb3BtZW50MRcwFQYDVQQDEw5mbHVrZS50
+-cm9sbC5ubzElMCMGCSqGSIb3DQEJARYWYWhhbnNzZW5AdHJvbGx0ZWNoLmNvbTAe
+-Fw0wNzEyMDQwMTEwMzJaFw0zNTA0MjEwMTEwMzJaMGMxCzAJBgNVBAYTAk5PMQ0w
+-CwYDVQQIEwRPc2xvMRYwFAYDVQQKEw1Ucm9sbHRlY2ggQVNBMRQwEgYDVQQLEwtE
+-ZXZlbG9wbWVudDEXMBUGA1UEAxMOZmx1a2UudHJvbGwubm8wgZ8wDQYJKoZIhvcN
+-AQEBBQADgY0AMIGJAoGBAKfIoErEGQUbZroy4tLxHG8XguQ5LgFRkNsENDIRIcIN
+-b1nYU5BUP4OPqdOz1e4am4CuwyXJXqWvS2AFqqDRkQEfygSD41gcmTJFhHByWAOY
+-SmOLQfUISdKRAmBr5GT+3aCqdAjpNEyRXxI9N01ULK1/W5hgNgKMO/ZF8ydqm5Sd
+-AgMBAAGjggEaMIIBFjAJBgNVHRMEAjAAMCwGCWCGSAGG+EIBDQQfFh1PcGVuU1NM
+-IEdlbmVyYXRlZCBDZXJ0aWZpY2F0ZTAdBgNVHQ4EFgQUIYUEPSMBZuX3nxqEJIqv
+-Cnn05awwgbsGA1UdIwSBszCBsKGBoqSBnzCBnDELMAkGA1UEBhMCTk8xDTALBgNV
+-BAgTBE9zbG8xEDAOBgNVBAcTB055ZGFsZW4xFjAUBgNVBAoTDVRyb2xsdGVjaCBB
+-U0ExFDASBgNVBAsTC0RldmVsb3BtZW50MRcwFQYDVQQDEw5mbHVrZS50cm9sbC5u
+-bzElMCMGCSqGSIb3DQEJARYWYWhhbnNzZW5AdHJvbGx0ZWNoLmNvbYIJAI6otOiR
+-t1QuMA0GCSqGSIb3DQEBBQUAA4IBAQBtV1/RBUPwYgXsKnGl3BkI8sSmvbsl2cqJ
+-AQ7kzx/BjMgkGDVTWXvAQ7Qy5piypu8VBQtIX+GgDJepoXfYNRgwvKmP07dUx/Gp
+-nl3mGb/2PFsr2OQ+YhiIi9Mk4UCbDOYpFmKr6gUkcDaqVZPvAoEbIxCiBOtWlXX8
+-+JSxXULFPzZEhV06LpBGiqK5b4euDBVAGTGQ/Dslu67xZhMNhZDZSTSP8l35ettN
+-XSf2dp01jAamTKOxsrZvHdejAP1y657qRKGvITR9x0LiSZEZi8CtuoKAqHFw9DUx
+-kWOEIJXpYK9ki8z/PYp2dD3IVW3kjsMrHOhCGK6f5mucNAbsavLD
++MIIF6zCCA9OgAwIBAgIUfo9amJtJGWqWE6f+SkAO85zkGr4wDQYJKoZIhvcNAQEL
++BQAwgYMxCzAJBgNVBAYTAk5PMQ0wCwYDVQQIDARPc2xvMQ0wCwYDVQQHDARPc2xv
++MRcwFQYDVQQKDA5UaGUgUXQgQ29tcGFueTEMMAoGA1UECwwDUiZEMRIwEAYDVQQD
++DAlIMiBUZXN0ZXIxGzAZBgkqhkiG9w0BCQEWDG1pbmltaUBxdC5pbzAgFw0yMDEw
++MjYxMjAxMzFaGA8yMTIwMTAwMjEyMDEzMVowgYMxCzAJBgNVBAYTAk5PMQ0wCwYD
++VQQIDARPc2xvMQ0wCwYDVQQHDARPc2xvMRcwFQYDVQQKDA5UaGUgUXQgQ29tcGFu
++eTEMMAoGA1UECwwDUiZEMRIwEAYDVQQDDAlIMiBUZXN0ZXIxGzAZBgkqhkiG9w0B
++CQEWDG1pbmltaUBxdC5pbzCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIB
++AOiUp5+E4blouKH7q+rVNR8NoYX2XkBW+q+rpy1zu5ssRSzbqxAjDx9dkht7Qlnf
++VlDT00JvpOWdeuPon5915edQRsY4Unl6mKH29ra3OtUa1/yCJXsGVJTKCj7k4Bxb
++5mZzb/fTlZntMLdTIBMfUbw62FKir1WjKIcJ9fCoG8JaGeKVO4Rh5p0ezd4UUUId
++r1BXl5Nqdqy2vTMsEDnjOsD3egkv8I2SKN4O6n/C3wWYpMOWYZkGoZiKz7rJs/i/
++ez7bsV7JlwdzTlhpJzkcOSVFBP6JlEOxTNNxZ1wtKy7PtZGmsSSATq2e6+bw38Ae
++Op0XnzzqcGjtDDofBmT7OFzZWjS9VZS6+DOOe2QHWle1nCHcHyH4ku6IRlsr9xkR
++NAIlOfnvHHxqJUenoeaZ4oQDjCBKS1KXygJO/tL7BLTQVn/xK1EmPvKNnjzWk4tR
++PnibUhhs5635qpOU/YPqFBh1JjVruZbsWcDAhRcew0uxONXOa9E+4lttQ9ySYa1A
++LvWqJuAX7gu2BsBMLyqfm811YnA7CIFMyO+HlqmkLFfv5L/xIRAXR7l26YGO0VwX
++CGjMfz4NVPMMke4nB7qa9NkpXQBQKMms3Qzd5JW0Hy9Ruj5O8GPcFZmV0twjd1uJ
++PD/cAjkWLaXjdNsJ16QWc2nghQRS6HYqKRX6j+CXOxupAgMBAAGjUzBRMB0GA1Ud
++DgQWBBRSCOU58j9NJZkMamt623qyCrhN3TAfBgNVHSMEGDAWgBRSCOU58j9NJZkM
++amt623qyCrhN3TAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEBCwUAA4ICAQCq
++q4jxsWeNDv5Nq14hJtF9HB+ZL64zcZtRjJP1YgNs0QppKICmjPOL2nIMGmI/jKrs
++0eGAL/9XXNVHPxm1OPOncvimMMmU6emZfpMdEtTfKP43+Pg9HgKRjLoQp406vGeQ
++8ki/mbBhrItVPgEm3tu2AFA02XTYi+YxCI9kRZLGkM3FbgtOuTLPl0Z9y+kiPc9F
++uCSC03anBEqv+vDSI8+wODymQ/IJ3Jyz1lxIRDfp4qAekmy0jU2c91VOHHEmOmqq
++kqygGFRdwbe99m9yP63r6q0b5K3X2UnJ6bns0hmTwThYwpVPXLU8jdaTddbMukN2
++/Ef96Tsw8nWOEOPMySHOTIPgwyZRp26b0kA9EmhLwOP401SxXVQCmSRmtwNagmtg
++jJKmZoYBN+//D45ibK8z6Q0oOm9P+Whf/uUXehcRxBxyV3xz7k0wKGQbHj/ddwcy
++IUoIN4lrAlib+lK170kTKN352PDmrpo2gmIzPEsfurKAIMSelDl6H+kih16BtZ8y
++Nz6fh9Soqrg3OSAware8pxV7k51crBMoPLN78KoRV8MFCK4K7Fddq4rRISq6hiXq
++r1nsjoEPuKM9huprmZVZe9t5YcDa2I+wb3IiE3uwpZbAdaLDyQ5n6F/qpsiIkZXn
++gtcF7oqpG5oYrwCcZ53y/ezUgUg7PlSz2XwAGvQtgg==
+ -----END CERTIFICATE-----
+diff --git a/qtbase/tests/auto/network/ssl/qsslsocket/certs/fluke.key b/qtbase/tests/auto/network/ssl/qsslsocket/certs/fluke.key
+index 9d1664d609..337ce541a6 100644
+--- a/qtbase/tests/auto/network/ssl/qsslsocket/certs/fluke.key
++++ b/qtbase/tests/auto/network/ssl/qsslsocket/certs/fluke.key
+@@ -1,15 +1,52 @@
+------BEGIN RSA PRIVATE KEY-----
+-MIICXAIBAAKBgQCnyKBKxBkFG2a6MuLS8RxvF4LkOS4BUZDbBDQyESHCDW9Z2FOQ
+-VD+Dj6nTs9XuGpuArsMlyV6lr0tgBaqg0ZEBH8oEg+NYHJkyRYRwclgDmEpji0H1
+-CEnSkQJga+Rk/t2gqnQI6TRMkV8SPTdNVCytf1uYYDYCjDv2RfMnapuUnQIDAQAB
+-AoGANFzLkanTeSGNFM0uttBipFT9F4a00dqHz6JnO7zXAT26I5r8sU1pqQBb6uLz
+-/+Qz5Zwk8RUAQcsMRgJetuPQUb0JZjF6Duv24hNazqXBCu7AZzUenjafwmKC/8ri
+-KpX3fTwqzfzi//FKGgbXQ80yykSSliDL3kn/drATxsLCgQECQQDXhEFWLJ0vVZ1s
+-1Ekf+3NITE+DR16X+LQ4W6vyEHAjTbaNWtcTKdAWLA2l6N4WAAPYSi6awm+zMxx4
+-VomVTsjdAkEAx0z+e7natLeFcrrq8pbU+wa6SAP1VfhQWKitxL1e7u/QO90NCpxE
+-oQYKzMkmmpOOFjQwEMAy1dvFMbm4LHlewQJAC/ksDBaUcQHHqjktCtrUb8rVjAyW
+-A8lscckeB2fEYyG5J6dJVaY4ClNOOs5yMDS2Afk1F6H/xKvtQ/5CzInA/QJATDub
+-K+BPU8jO9q+gpuIi3VIZdupssVGmCgObVCHLakG4uO04y9IyPhV9lA9tALtoIf4c
+-VIvv5fWGXBrZ48kZAQJBAJmVCdzQxd9LZI5vxijUCj5EI4e+x5DRqVUvyP8KCZrC
+-AiNyoDP85T+hBZaSXK3aYGpVwelyj3bvo1GrTNwNWLw=
+------END RSA PRIVATE KEY-----
++-----BEGIN PRIVATE KEY-----
++MIIJQgIBADANBgkqhkiG9w0BAQEFAASCCSwwggkoAgEAAoICAQDolKefhOG5aLih
+++6vq1TUfDaGF9l5AVvqvq6ctc7ubLEUs26sQIw8fXZIbe0JZ31ZQ09NCb6TlnXrj
++6J+fdeXnUEbGOFJ5epih9va2tzrVGtf8giV7BlSUygo+5OAcW+Zmc2/305WZ7TC3
++UyATH1G8OthSoq9VoyiHCfXwqBvCWhnilTuEYeadHs3eFFFCHa9QV5eTanastr0z
++LBA54zrA93oJL/CNkijeDup/wt8FmKTDlmGZBqGYis+6ybP4v3s+27FeyZcHc05Y
++aSc5HDklRQT+iZRDsUzTcWdcLSsuz7WRprEkgE6tnuvm8N/AHjqdF5886nBo7Qw6
++HwZk+zhc2Vo0vVWUuvgzjntkB1pXtZwh3B8h+JLuiEZbK/cZETQCJTn57xx8aiVH
++p6HmmeKEA4wgSktSl8oCTv7S+wS00FZ/8StRJj7yjZ481pOLUT54m1IYbOet+aqT
++lP2D6hQYdSY1a7mW7FnAwIUXHsNLsTjVzmvRPuJbbUPckmGtQC71qibgF+4LtgbA
++TC8qn5vNdWJwOwiBTMjvh5appCxX7+S/8SEQF0e5dumBjtFcFwhozH8+DVTzDJHu
++Jwe6mvTZKV0AUCjJrN0M3eSVtB8vUbo+TvBj3BWZldLcI3dbiTw/3AI5Fi2l43Tb
++CdekFnNp4IUEUuh2KikV+o/glzsbqQIDAQABAoICAFw1q6tr5I48vY7DF+rXsuLn
++5ZUWE1IQ6fzB4lr72nJv/9EEGnMgYzt9PpMUsD6vdCpBgS2C0+6RHArFzJtNA+RM
++iHLIG7K7702veyr/xBx/MwiSlMeMv/XpkFxVI6E6skMGG2s3AMXxKvJTy5CpRx+I
++eQFyLG+Ya1X2lgJes/q+/CpAHkOjCOpcLySQC5NZ74q734V7nSdmn+Zs3tYEh+O/
++eiuwTP/j5b38Te5vVTqDxTciJPmljmXLCwa0N100lWlbcpvw8qbqiTI2Jm3XCbUE
++AzHjW9vmrF3cRS1fXxKFGShw3SRqlkbxjfeWoi8qDPUBS4m8LOr8qG9Wo5Nfon0z
++zLP4bci3zHDvVcaaZrrsUBs/yZbg+Dgka1DmX7ekmeccr2yTdKDFgPupYUyxVbTl
++a9ZLJysjFD7rgBv1ZclHonLp6Vbm+ZoTqvteo4ikAy6L9RtBWJ23XEK34PkP/+c5
++2vWZaOrnjSeBHbFce8cdJSxqWpP+eSCI5I9XbDrYFIsQ/gqKgtzDKy2ihJ2Y8STL
++yO4hyFPFjxc+Gg4/P2PpmT5CY2ty44M0BWs+JGW96CJPrrplf2lmQUQJj5LZY66X
++Z/4C9L7ZYtKZ+bs5SvU46yWugAvQZX22Xm9xLXWyVXRdx3bj+3M3fDnF9di/zdbh
++CgLx7oWPNrXc7FCajnn9AoIBAQD5FMYwRpw9NWT9WDxQwx+cSI4Icbd88ByTW63S
++LzeRwZA0J9/SfwO+aBRupzc9GkGXCiZcGMw3AGsCtig8yFlw8E5KnzN7KlftDMnM
++9NUxxzlR8VwKyLnZfG7sDTl057ZlUujnqhmt/F8F7dIy7FVO1dE/8nngA+FYTCOG
++UZdGjwyBDlDM0JJdUWGY3xslutcpCDN5mzSTKjy9drMvImAshRawxRF6WBpn7vr2
++nC6vciqfx1Mzx1vyk0Jm0ilaydDdLMADjt/iL4Nkr0BEs4k+UzQiKDwp8gu7abQ1
++eBfxd9Iar4htQa2I1Ewl6P01G/q+ZYwgHhJ9RVn4AxQXefILAoIBAQDvCouORdQX
++C8wsyp7MwXlF/3NQeNN5/+B2mhbxrBOf7PmMCXLnkRWcjwJtzypWFqJ0sqai/2+0
++bqbMcjX5maT8stT2shl3zXe/Ejt2e3TBYpc1tyuses8Kb5BMU8hu6tTd3G2CMXpD
++dT6DVemJZCTtwj9aBNIxSizvlgMolJnCpzhPnlfHSI6E+g3m/LTTo3HwbjMSw/Uq
++irgjOpI2wSBB6LZPSgjvfcYPRyWUk16L4A5uSX0cADnovDFLa5/h0wJvN/OoCSQg
++rLCXG5E18EyL5Wc58BCY1ZvxmjG3lQtgPxYu2Jwc36R/y/JKlxW5suER5ZNpbbD4
++uOyTt2VxMQ2bAoIBAQC5+MzRFqdo/AjfL5Y5JrbfVTzXCTDa09xCGd16ZU60QTWN
+++4ed/r+o1sUKqUcRFB2MzEM/2DQBjQpZB/CbEWvWa1XJWXxypXbowveZU+QqOnmN
++uQvj8WLyA3o+PNF9e9QvauwCrHpn8VpxbtPWuaYoKnUFreFZZQxHhPGxRBIS2JOZ
++eDrT8ZaWnkCkh1AZp5smQ71LOprSlmKrg4jd1GjCVMxQR5N5KXbtyv0OTCZ/UFqK
++2aRBsMPyJgkaBChkZPLRcKwc+/wlQRx1fHQb14DNTApMxoXFO7eOwqmOkpAt9iyl
++SBIwoS0UUI5ab88+bBmXNvKcuFdNuQ4nowTJUn9pAoIBADMNkILBXSvS5DeIyuO2
++Sp1tkoZUV+5NfPY3sMDK3KIibaW/+t+EOBZo4L7tKQCb8vRzl21mmsfxfgRaPDbj
++3r3tv9g0b4YLxxBy52pFscj/soXRai17SS7UZwA2QK+XzgDYbDcLNC6mIsTQG4Gx
++dsWk3/zs3KuUSQaehmwrWK+fIUK38c1pLK8v7LoxrLkqxlHwZ04RthHw8KTthH7X
++Pnl1J0LF8CSeOyfWLSuPUfkT0GEzptnNHpEbaHfQM6R6eaGhVJPF6AZme4y6YYgg
++m2ihhSt1n0XVEWpHYWjxFy3mK2mz75unFC4LM+NEY2p2zuUQoCw7NjnY3QYrfCnx
++rRMCggEAXeXsMSLFjjyuoL7iKbAxo52HD/P0fBoy58LyRcwfNVr0lvYan4pYEx+o
++KijIh9K16PqXZXKMA9v003B+ulmF8bJ7SddCZ5NGvnFhUTDe4DdTKgp2RuwQ3Bsc
++3skPIDbhVETyOLCtys34USHrq8U/0DlGY3eLRfxw9GnbKxSBGa/KEu/qQLPNUo50
++7xHZDg7GKeC3kqNJeqKM9rkp0VzIGkEnaD9127LeNDmERDfftxJzFoC/THvUBLfU
++6Sus2ZYwRE8VFvKC30Q45t/c54X3IuhYvAuiCuTmyfE4ruyzyOwKzhUkeeLq1APX
++g0veFbyfzlJ0q8qzD/iffqqIa2ZSmQ==
++-----END PRIVATE KEY-----
+diff --git a/qtbase/tests/auto/other/qaccessibilitylinux/tst_qaccessibilitylinux.cpp b/qtbase/tests/auto/other/qaccessibilitylinux/tst_qaccessibilitylinux.cpp
+index 7ba3715e13..752aa122f6 100644
+--- a/qtbase/tests/auto/other/qaccessibilitylinux/tst_qaccessibilitylinux.cpp
++++ b/qtbase/tests/auto/other/qaccessibilitylinux/tst_qaccessibilitylinux.cpp
+@@ -179,6 +179,7 @@ void tst_QAccessibilityLinux::initTestCase()
+ QVERIFY(!address.isEmpty());
+
+ m_window = new AccessibleTestWindow();
++ m_window->setObjectName("mainWindow"_L1);
+ m_window->show();
+
+ QVERIFY(QTest::qWaitForWindowExposed(m_window));
+@@ -236,8 +237,11 @@ bool hasState(QDBusInterface *interface, AtspiStateType state)
+ void tst_QAccessibilityLinux::testLabel()
+ {
+ QLabel *l = new QLabel(m_window);
++ l->setObjectName("theObjectName"_L1);
+ l->setText("Hello A11y");
+ m_window->addWidget(l);
++ auto a11yEmpty = new QLabel(m_window);
++ m_window->addWidget(l);
+
+ // Application
+ QCOMPARE(getParent(mainWindow), QLatin1String(ATSPI_DBUS_PATH_ROOT));
+@@ -249,6 +253,8 @@ void tst_QAccessibilityLinux::testLabel()
+ QCOMPARE(getChildren(labelInterface).count(), 0);
+ QCOMPARE(labelInterface->call(QDBus::Block, "GetRoleName").arguments().first().toString(), QLatin1String("label"));
+ QCOMPARE(labelInterface->call(QDBus::Block, "GetRole").arguments().first().toUInt(), 29u);
++ QCOMPARE(labelInterface->call(QDBus::Block, "GetAccessibleId").arguments().first().toString(),
++ QLatin1String("mainWindow.theObjectName"));
+ QCOMPARE(getParent(labelInterface), mainWindow->path());
+ QVERIFY(!hasState(labelInterface, ATSPI_STATE_EDITABLE));
+ QVERIFY(hasState(labelInterface, ATSPI_STATE_READ_ONLY));
+@@ -256,7 +262,12 @@ void tst_QAccessibilityLinux::testLabel()
+ l->setText("New text");
+ QCOMPARE(labelInterface->property("Name").toString(), l->text());
+
++ auto *a11yEmptyInterface = getInterface(children.at(1), "org.a11y.atspi.Accessible");
++ QCOMPARE(a11yEmptyInterface->call(QDBus::Block, "GetAccessibleId").arguments().first().toString(),
++ QLatin1String("mainWindow.QLabel"));
++
+ m_window->clearChildren();
++ delete a11yEmptyInterface;
+ delete labelInterface;
+ }
+
+diff --git a/qtbase/tests/auto/sql/kernel/qsqlquery/tst_qsqlquery.cpp b/qtbase/tests/auto/sql/kernel/qsqlquery/tst_qsqlquery.cpp
+index 76df61c892..6d6d65b791 100644
+--- a/qtbase/tests/auto/sql/kernel/qsqlquery/tst_qsqlquery.cpp
++++ b/qtbase/tests/auto/sql/kernel/qsqlquery/tst_qsqlquery.cpp
+@@ -1,6 +1,6 @@
+ /****************************************************************************
+ **
+-** Copyright (C) 2016 The Qt Company Ltd.
++** Copyright (C) 2022 The Qt Company Ltd.
+ ** Contact: https://www.qt.io/licensing/
+ **
+ ** This file is part of the test suite of the Qt Toolkit.
+@@ -68,6 +68,8 @@ private slots:
+ void query_exec();
+ void execErrorRecovery_data() { generic_data(); }
+ void execErrorRecovery();
++ void prematureExec_data() { generic_data(); }
++ void prematureExec();
+ void first_data() { generic_data(); }
+ void first();
+ void next_data() { generic_data(); }
+@@ -2770,6 +2772,35 @@ void tst_QSqlQuery::execErrorRecovery()
+ QVERIFY_SQL( q, exec() );
+ }
+
++void tst_QSqlQuery::prematureExec()
++{
++ QFETCH(QString, dbName);
++ // We only want the engine name, for addDatabase():
++ int cut = dbName.indexOf(QChar('@'));
++ if (cut < 0)
++ QSKIP("Failed to parse database type out of name");
++ dbName.truncate(cut);
++ cut = dbName.indexOf(QChar('_'));
++ if (cut >= 0)
++ dbName = dbName.mid(cut + 1);
++
++ auto db = QSqlDatabase::addDatabase(dbName);
++ QSqlQuery q(db);
++
++ QTest::ignoreMessage(QtWarningMsg,
++ "QSqlDatabasePrivate::removeDatabase: connection "
++ "'qt_sql_default_connection' is still in use, all "
++ "queries will cease to work.");
++ QTest::ignoreMessage(QtWarningMsg,
++ "QSqlDatabasePrivate::addDatabase: duplicate connection name "
++ "'qt_sql_default_connection', old connection removed.");
++ auto otherDb = QSqlDatabase::addDatabase(dbName);
++
++ QTest::ignoreMessage(QtWarningMsg, "QSqlQuery::exec: called before driver has been set up");
++ // QTBUG-100037: shouldn't crash !
++ QVERIFY(!q.exec("select stuff from TheVoid"));
++}
++
+ void tst_QSqlQuery::lastInsertId()
+ {
+ QFETCH( QString, dbName );
+diff --git a/qtbase/tests/auto/testlib/qabstractitemmodeltester/tst_qabstractitemmodeltester.cpp b/qtbase/tests/auto/testlib/qabstractitemmodeltester/tst_qabstractitemmodeltester.cpp
+index 4aa3f8d60b..d2050a61aa 100644
+--- a/qtbase/tests/auto/testlib/qabstractitemmodeltester/tst_qabstractitemmodeltester.cpp
++++ b/qtbase/tests/auto/testlib/qabstractitemmodeltester/tst_qabstractitemmodeltester.cpp
+@@ -115,6 +115,10 @@ void tst_QAbstractItemModelTester::standardItemModelZeroColumns()
+ // QTBUG-92886
+ model.insertRows(0, 5);
+ model.removeRows(1, 2);
++
++ const QModelIndex parentIndex = model.index(0, 0);
++ model.insertRows(0, 5, parentIndex);
++ model.removeRows(1, 2, parentIndex);
+ }
+
+ void tst_QAbstractItemModelTester::testInsertThroughProxy()
+diff --git a/qtbase/tests/auto/tools/moc/allmocs_baseline_in.json b/qtbase/tests/auto/tools/moc/allmocs_baseline_in.json
+index 12a4a22a19..ce518e78fb 100644
+--- a/qtbase/tests/auto/tools/moc/allmocs_baseline_in.json
++++ b/qtbase/tests/auto/tools/moc/allmocs_baseline_in.json
+@@ -668,50 +668,6 @@
+ "inputFile": "task192552.h",
+ "outputRevision": 67
+ },
+- {
+- "classes": [
+- {
+- "className": "InlineSlotsWithThrowDeclaration",
+- "object": true,
+- "qualifiedClassName": "InlineSlotsWithThrowDeclaration",
+- "slots": [
+- {
+- "access": "public",
+- "name": "a",
+- "returnType": "void"
+- },
+- {
+- "access": "public",
+- "name": "b",
+- "returnType": "void"
+- },
+- {
+- "access": "public",
+- "name": "c",
+- "returnType": "void"
+- },
+- {
+- "access": "public",
+- "name": "d",
+- "returnType": "void"
+- },
+- {
+- "access": "public",
+- "name": "e",
+- "returnType": "void"
+- }
+- ],
+- "superClasses": [
+- {
+- "access": "public",
+- "name": "QObject"
+- }
+- ]
+- }
+- ],
+- "inputFile": "task189996.h",
+- "outputRevision": 67
+- },
+ {
+ "classes": [
+ {
+diff --git a/qtbase/tests/auto/tools/moc/moc.pro b/qtbase/tests/auto/tools/moc/moc.pro
+index c324b3a8cd..4aceb78dc0 100644
+--- a/qtbase/tests/auto/tools/moc/moc.pro
++++ b/qtbase/tests/auto/tools/moc/moc.pro
+@@ -15,7 +15,7 @@ cross_compile: DEFINES += MOC_CROSS_COMPILED
+ HEADERS += using-namespaces.h no-keywords.h task87883.h c-comments.h backslash-newlines.h oldstyle-casts.h \
+ slots-with-void-template.h qinvokable.h namespaced-flags.h trigraphs.h \
+ escapes-in-string-literals.h cstyle-enums.h qprivateslots.h gadgetwithnoenums.h \
+- dir-in-include-path.h single_function_keyword.h task192552.h task189996.h \
++ dir-in-include-path.h single_function_keyword.h task192552.h \
+ task234909.h task240368.h pure-virtual-signals.h cxx11-enums.h \
+ cxx11-final-classes.h \
+ cxx11-explicit-override-control.h \
+diff --git a/qtbase/tests/auto/tools/moc/task189996.h b/qtbase/tests/auto/tools/moc/task189996.h
+deleted file mode 100644
+index f94a051b3a..0000000000
+--- a/qtbase/tests/auto/tools/moc/task189996.h
++++ /dev/null
+@@ -1,47 +0,0 @@
+-/****************************************************************************
+-**
+-** Copyright (C) 2016 The Qt Company Ltd.
+-** Contact: https://www.qt.io/licensing/
+-**
+-** This file is part of the test suite of the Qt Toolkit.
+-**
+-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+-** Commercial License Usage
+-** Licensees holding valid commercial Qt licenses may use this file in
+-** accordance with the commercial license agreement provided with the
+-** Software or, alternatively, in accordance with the terms contained in
+-** a written agreement between you and The Qt Company. For licensing terms
+-** and conditions see https://www.qt.io/terms-conditions. For further
+-** information use the contact form at https://www.qt.io/contact-us.
+-**
+-** GNU General Public License Usage
+-** Alternatively, this file may be used under the terms of the GNU
+-** General Public License version 3 as published by the Free Software
+-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+-** included in the packaging of this file. Please review the following
+-** information to ensure the GNU General Public License requirements will
+-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+-**
+-** $QT_END_LICENSE$
+-**
+-****************************************************************************/
+-// inline functions can have throw declarations
+-
+-#ifndef TASK189996_H
+-#define TASK189996_H
+-
+-#include <QObject>
+-
+-class InlineSlotsWithThrowDeclaration : public QObject
+-{
+- Q_OBJECT
+-
+-public slots:
+- void a() throw() { }
+- void b() const throw() { }
+- void c() throw();
+- void d() throw(int) { }
+- void e() const throw(int,double) { }
+-};
+-
+-#endif
+diff --git a/qtbase/tests/auto/tools/moc/tst_moc.cpp b/qtbase/tests/auto/tools/moc/tst_moc.cpp
+index c716aead21..15dd9e41e5 100644
+--- a/qtbase/tests/auto/tools/moc/tst_moc.cpp
++++ b/qtbase/tests/auto/tools/moc/tst_moc.cpp
+@@ -631,7 +631,6 @@ public:
+ private slots:
+ void initTestCase();
+
+- void slotWithException() throw(MyStruct);
+ void dontStripNamespaces();
+ void oldStyleCasts();
+ void warnOnExtraSignalSlotQualifiaction();
+@@ -673,7 +672,6 @@ private slots:
+ void templateGtGt();
+ void qprivateslots();
+ void qprivateproperties();
+- void inlineSlotsWithThrowDeclaration();
+ void warnOnPropertyWithoutREAD();
+ void constructors();
+ void typenameWithUnsigned();
+@@ -784,12 +782,6 @@ void tst_Moc::initTestCase()
+ #endif
+ }
+
+-void tst_Moc::slotWithException() throw(MyStruct)
+-{
+- // be happy
+- QVERIFY(true);
+-}
+-
+ void tst_Moc::dontStripNamespaces()
+ {
+ Sender sender;
+@@ -824,7 +816,7 @@ void tst_Moc::oldStyleCasts()
+
+ QStringList args;
+ args << "-c" << "-x" << "c++" << "-Wold-style-cast" << "-I" << "."
+- << "-I" << qtIncludePath << "-o" << "/dev/null" << "-fPIC" << "-std=c++11" << "-";
++ << "-I" << qtIncludePath << "-o" << "/dev/null" << "-fPIC" << "-std=c++1z" << "-";
+ proc.start("gcc", args);
+ QVERIFY(proc.waitForStarted());
+ proc.write(mocOut);
+@@ -894,7 +886,7 @@ void tst_Moc::inputFileNameWithDotsButNoExtension()
+
+ QStringList args;
+ args << "-c" << "-x" << "c++" << "-I" << ".."
+- << "-I" << qtIncludePath << "-o" << "/dev/null" << "-fPIC" << "-std=c++11" << "-";
++ << "-I" << qtIncludePath << "-o" << "/dev/null" << "-fPIC" << "-std=c++1z" << "-";
+ proc.start("gcc", args);
+ QVERIFY(proc.waitForStarted());
+ proc.write(mocOut);
+@@ -1174,7 +1166,7 @@ void tst_Moc::ignoreOptionClashes()
+ QStringList gccArgs;
+ gccArgs << "-c" << "-x" << "c++" << "-I" << ".."
+ << "-I" << qtIncludePath << "-I" << includeDir << "-o" << "/dev/null"
+- << "-fPIC" << "-std=c++11" << "-";
++ << "-fPIC" << "-std=c++1z" << "-";
+ proc.start("gcc", gccArgs);
+ QVERIFY(proc.waitForStarted());
+ proc.write(mocOut);
+@@ -1593,21 +1585,6 @@ void tst_Moc::qprivateproperties()
+
+ }
+
+-#include "task189996.h"
+-
+-void InlineSlotsWithThrowDeclaration::c() throw() {}
+-
+-void tst_Moc::inlineSlotsWithThrowDeclaration()
+-{
+- InlineSlotsWithThrowDeclaration tst;
+- const QMetaObject *mobj = tst.metaObject();
+- QVERIFY(mobj->indexOfSlot("a()") != -1);
+- QVERIFY(mobj->indexOfSlot("b()") != -1);
+- QVERIFY(mobj->indexOfSlot("c()") != -1);
+- QVERIFY(mobj->indexOfSlot("d()") != -1);
+- QVERIFY(mobj->indexOfSlot("e()") != -1);
+-}
+-
+ void tst_Moc::warnOnPropertyWithoutREAD()
+ {
+ #ifdef MOC_CROSS_COMPILED
+@@ -1869,7 +1846,7 @@ void tst_Moc::notifyError()
+
+ QStringList args;
+ args << "-c" << "-x" << "c++" << "-I" << "."
+- << "-I" << qtIncludePath << "-o" << "/dev/null" << "-fPIC" << "-std=c++11" << "-";
++ << "-I" << qtIncludePath << "-o" << "/dev/null" << "-fPIC" << "-std=c++1z" << "-";
+ proc.start("gcc", args);
+ QVERIFY(proc.waitForStarted());
+ proc.write(mocOut);
+diff --git a/qtbase/tests/auto/widgets/itemviews/qheaderview/tst_qheaderview.cpp b/qtbase/tests/auto/widgets/itemviews/qheaderview/tst_qheaderview.cpp
+index c355ee9665..88c09de8e0 100644
+--- a/qtbase/tests/auto/widgets/itemviews/qheaderview/tst_qheaderview.cpp
++++ b/qtbase/tests/auto/widgets/itemviews/qheaderview/tst_qheaderview.cpp
+@@ -251,6 +251,7 @@ private slots:
+ void testResetCachedSizeHint();
+ void statusTips();
+ void testRemovingColumnsViaLayoutChanged();
++ void testModelMovingColumns();
+
+ protected:
+ void setupTestData(bool use_reset_model = false);
+@@ -360,6 +361,12 @@ public:
+ endRemoveColumns();
+ }
+
++ void moveColumn(int from, int to)
++ {
++ beginMoveColumns(QModelIndex(), from, from, QModelIndex(), to);
++ endMoveColumns();
++ }
++
+ void cleanup()
+ {
+ emit layoutAboutToBeChanged();
+@@ -3627,5 +3634,18 @@ void tst_QHeaderView::testRemovingColumnsViaLayoutChanged()
+ // The main point of this test is that the section-size restoring code didn't go out of bounds.
+ }
+
++void tst_QHeaderView::testModelMovingColumns()
++{
++ QtTestModel model(10, 10);
++ QHeaderView hv(Qt::Horizontal);
++ hv.setModel(&model);
++ hv.resizeSections(QHeaderView::ResizeToContents);
++ hv.show();
++
++ QPersistentModelIndex index3 = model.index(0, 3);
++ model.moveColumn(3, 1);
++ QCOMPARE(index3.column(), 1);
++}
++
+ QTEST_MAIN(tst_QHeaderView)
+ #include "tst_qheaderview.moc"
+diff --git a/qtbase/tests/auto/widgets/itemviews/qtableview/tst_qtableview.cpp b/qtbase/tests/auto/widgets/itemviews/qtableview/tst_qtableview.cpp
+index 761357b252..06bb706074 100644
+--- a/qtbase/tests/auto/widgets/itemviews/qtableview/tst_qtableview.cpp
++++ b/qtbase/tests/auto/widgets/itemviews/qtableview/tst_qtableview.cpp
+@@ -397,6 +397,7 @@ private slots:
+ void checkHeaderMinSize();
+
+ void resizeToContents();
++ void resizeToContentsSpans();
+
+ void tabFocus();
+ void bigModel();
+@@ -3721,6 +3722,70 @@ void tst_QTableView::resizeToContents()
+
+ }
+
++
++class SpanModel : public QAbstractTableModel
++{
++public:
++ SpanModel(bool sectionsMoved)
++ : _sectionsMoved(sectionsMoved)
++ {}
++ int columnCount(const QModelIndex & = {}) const override { return 2; }
++ int rowCount(const QModelIndex & = {}) const override { return 1; }
++ QVariant data(const QModelIndex &idx, int role = Qt::DisplayRole) const override
++ {
++ if (role != Qt::DisplayRole)
++ return QVariant();
++ const int col = _sectionsMoved ? 1 - idx.column() : idx.column();
++ if (col == 0)
++ return "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.";
++ return QVariant();
++ }
++private:
++ bool _sectionsMoved;
++};
++
++
++void tst_QTableView::resizeToContentsSpans()
++{
++ SpanModel model1(false);
++ SpanModel model2(true);
++ QTableView view1, view2, view3;
++ view1.setModel(&model1);
++ view2.setModel(&model2);
++ view2.horizontalHeader()->moveSection(0, 1);
++ view3.setModel(&model1);
++
++ view1.setSpan(0, 0, 1, 2);
++ view2.setSpan(0, 1, 1, 2);
++ view1.show();
++ view2.show();
++ view3.show();
++ QVERIFY(QTest::qWaitForWindowExposed(&view1));
++ QVERIFY(QTest::qWaitForWindowExposed(&view2));
++ QVERIFY(QTest::qWaitForWindowExposed(&view3));
++ view1.setColumnWidth(0, 100);
++ view1.setColumnWidth(1, 100);
++ view2.setColumnWidth(0, 100);
++ view2.setColumnWidth(1, 100);
++ view3.setColumnWidth(0, 200);
++
++ view1.resizeRowToContents(0);
++ view2.resizeRowToContents(0);
++ view3.resizeRowToContents(0);
++ QCOMPARE(view1.rowHeight(0), view3.rowHeight(0));
++ QCOMPARE(view2.rowHeight(0), view3.rowHeight(0));
++
++ view3.resizeColumnToContents(0);
++ view3.resizeRowToContents(0);
++ // height should be only 1 text line for easy testing
++ view1.setRowHeight(0, view3.verticalHeader()->sectionSize(0));
++ view2.setRowHeight(0, view3.verticalHeader()->sectionSize(0));
++ view1.resizeColumnToContents(0);
++ view2.resizeColumnToContents(1);
++ QCOMPARE(view1.columnWidth(0), view3.columnWidth(0) - view1.columnWidth(1));
++ QCOMPARE(view2.columnWidth(0), view3.columnWidth(0) - view2.columnWidth(1));
++}
++
+ QT_BEGIN_NAMESPACE
+ extern bool Q_WIDGETS_EXPORT qt_tab_all_widgets(); // qapplication.cpp
+ QT_END_NAMESPACE
+diff --git a/qtbase/tests/auto/widgets/kernel/qapplication/tst_qapplication.cpp b/qtbase/tests/auto/widgets/kernel/qapplication/tst_qapplication.cpp
+index a3b8ef78d8..4955cebd5d 100644
+--- a/qtbase/tests/auto/widgets/kernel/qapplication/tst_qapplication.cpp
++++ b/qtbase/tests/auto/widgets/kernel/qapplication/tst_qapplication.cpp
+@@ -1498,7 +1498,7 @@ void tst_QApplication::desktopSettingsAware()
+ environment += QLatin1String("QT_MAC_DISABLE_FOREGROUND_APPLICATION_TRANSFORM=1");
+ testProcess.setEnvironment(environment);
+ #endif
+- testProcess.start("desktopsettingsaware_helper");
++ testProcess.start("./desktopsettingsaware_helper");
+ QVERIFY2(testProcess.waitForStarted(),
+ qPrintable(QString::fromLatin1("Cannot start 'desktopsettingsaware_helper': %1").arg(testProcess.errorString())));
+ QVERIFY(testProcess.waitForFinished(10000));
+@@ -2452,7 +2452,7 @@ void tst_QApplication::qtbug_12673()
+ #if QT_CONFIG(process)
+ QProcess testProcess;
+ QStringList arguments;
+- testProcess.start("modal_helper", arguments);
++ testProcess.start("./modal_helper", arguments);
+ QVERIFY2(testProcess.waitForStarted(),
+ qPrintable(QString::fromLatin1("Cannot start 'modal_helper': %1").arg(testProcess.errorString())));
+ QVERIFY(testProcess.waitForFinished(20000));
+diff --git a/qtbase/tests/auto/widgets/widgets/qabstractbutton/tst_qabstractbutton.cpp b/qtbase/tests/auto/widgets/widgets/qabstractbutton/tst_qabstractbutton.cpp
+index eb108a40de..dca5528c1b 100644
+--- a/qtbase/tests/auto/widgets/widgets/qabstractbutton/tst_qabstractbutton.cpp
++++ b/qtbase/tests/auto/widgets/widgets/qabstractbutton/tst_qabstractbutton.cpp
+@@ -41,6 +41,7 @@
+
+ #include <private/qguiapplication_p.h>
+ #include <qpa/qplatformintegration.h>
++#include <qpa/qplatformtheme.h>
+
+ class tst_QAbstractButton : public QObject
+ {
+@@ -76,6 +77,8 @@ private slots:
+ void keyNavigation();
+ #endif
+
++ void buttonPressKeys();
++
+ protected slots:
+ void onClicked();
+ void onToggled( bool on );
+@@ -269,7 +272,13 @@ void tst_QAbstractButton::setAutoRepeat()
+ QCOMPARE(press_count, click_count);
+ QVERIFY(click_count > 1);
+ break;
+- case 4:
++ case 4: {
++ const auto buttonPressKeys = QGuiApplicationPrivate::platformTheme()
++ ->themeHint(QPlatformTheme::ButtonPressKeys)
++ .value<QList<Qt::Key>>();
++ if (buttonPressKeys.contains(Qt::Key_Enter)) {
++ QSKIP("platform theme has Key_Enter in ButtonPressKeys");
++ }
+ // check that pressing ENTER has no effect when autorepeat is false
+ testWidget->setDown( false );
+ testWidget->setAutoRepeat( false );
+@@ -286,7 +295,14 @@ void tst_QAbstractButton::setAutoRepeat()
+
+ QVERIFY( click_count == 0 );
+ break;
+- case 5:
++ }
++ case 5: {
++ const auto buttonPressKeys = QGuiApplicationPrivate::platformTheme()
++ ->themeHint(QPlatformTheme::ButtonPressKeys)
++ .value<QList<Qt::Key>>();
++ if (buttonPressKeys.contains(Qt::Key_Enter)) {
++ QSKIP("platform theme has Key_Enter in ButtonPressKeys");
++ }
+ // check that pressing ENTER has no effect when autorepeat is true
+ testWidget->setDown( false );
+ testWidget->setAutoRepeat( true );
+@@ -304,6 +320,7 @@ void tst_QAbstractButton::setAutoRepeat()
+
+ QVERIFY( click_count == 0 );
+ break;
++ }
+ case 6:
+ // verify autorepeat is off by default.
+ MyButton tmp( 0);
+@@ -651,5 +668,16 @@ void tst_QAbstractButton::keyNavigation()
+ }
+ #endif
+
++void tst_QAbstractButton::buttonPressKeys()
++{
++ const auto buttonPressKeys = QGuiApplicationPrivate::platformTheme()
++ ->themeHint(QPlatformTheme::ButtonPressKeys)
++ .value<QList<Qt::Key>>();
++ for (int i = 0; i < buttonPressKeys.length(); ++i) {
++ QTest::keyClick(testWidget, buttonPressKeys[i]);
++ QCOMPARE(click_count, i + 1);
++ }
++}
++
+ QTEST_MAIN(tst_QAbstractButton)
+ #include "tst_qabstractbutton.moc"
+diff --git a/qtbase/tests/auto/widgets/widgets/qcombobox/tst_qcombobox.cpp b/qtbase/tests/auto/widgets/widgets/qcombobox/tst_qcombobox.cpp
+index 32437050f5..46b5af6d63 100644
+--- a/qtbase/tests/auto/widgets/widgets/qcombobox/tst_qcombobox.cpp
++++ b/qtbase/tests/auto/widgets/widgets/qcombobox/tst_qcombobox.cpp
+@@ -168,6 +168,7 @@ private slots:
+ void checkMenuItemPosWhenStyleSheetIsSet();
+ void checkEmbeddedLineEditWhenStyleSheetIsSet();
+ void propagateStyleChanges();
++ void buttonPressKeys();
+
+ private:
+ PlatformInputContext m_platformInputContext;
+@@ -1682,6 +1683,16 @@ void tst_QComboBox::setModel()
+ QCOMPARE(box.rootModelIndex(), rootModelIndex);
+ box.setModel(box.model());
+ QCOMPARE(box.rootModelIndex(), rootModelIndex);
++
++ // check that setting the same model as the completer's doesn't crash
++ QCompleter *completer = new QCompleter(&box);
++ box.setEditable(true);
++ box.setCompleter(completer);
++ auto *listModel = new QStringListModel({ "one", "two" }, completer);
++ completer->setModel(listModel);
++ QCOMPARE(listModel->rowCount(), 2); // make sure it wasn't deleted
++ box.setModel(listModel);
++ QCOMPARE(listModel->rowCount(), 2); // make sure it wasn't deleted
+ }
+
+ void tst_QComboBox::setCustomModelAndView()
+@@ -3632,5 +3643,24 @@ void tst_QComboBox::propagateStyleChanges()
+ QVERIFY(frameStyle.inquired);
+ }
+
++void tst_QComboBox::buttonPressKeys()
++{
++ QComboBox comboBox;
++ comboBox.setEditable(false);
++ comboBox.addItem(QString::number(1));
++ comboBox.addItem(QString::number(2));
++ const auto buttonPressKeys = QGuiApplicationPrivate::platformTheme()
++ ->themeHint(QPlatformTheme::ButtonPressKeys)
++ .value<QList<Qt::Key>>();
++ for (int i = 0; i < buttonPressKeys.length(); ++i) {
++ QTest::keyClick(&comboBox, buttonPressKeys[i]);
++ // On some platforms, a window will not be immediately visible,
++ // but take some event-loop iterations to complete.
++ // Using QTRY_VERIFY to deal with that.
++ QTRY_VERIFY(comboBox.view()->isVisible());
++ comboBox.hidePopup();
++ }
++}
++
+ QTEST_MAIN(tst_QComboBox)
+ #include "tst_qcombobox.moc"
+diff --git a/qtbase/tests/auto/widgets/widgets/qcommandlinkbutton/qcommandlinkbutton.pro b/qtbase/tests/auto/widgets/widgets/qcommandlinkbutton/qcommandlinkbutton.pro
+index be3cfcd104..c228fdfcca 100644
+--- a/qtbase/tests/auto/widgets/widgets/qcommandlinkbutton/qcommandlinkbutton.pro
++++ b/qtbase/tests/auto/widgets/widgets/qcommandlinkbutton/qcommandlinkbutton.pro
+@@ -1,6 +1,6 @@
+ CONFIG += testcase
+ TARGET = tst_qcommandlinkbutton
+-QT += widgets testlib
++QT += widgets testlib gui-private
+ SOURCES += tst_qcommandlinkbutton.cpp
+
+
+diff --git a/qtbase/tests/auto/widgets/widgets/qcommandlinkbutton/tst_qcommandlinkbutton.cpp b/qtbase/tests/auto/widgets/widgets/qcommandlinkbutton/tst_qcommandlinkbutton.cpp
+index 0044d33c66..4cf06296e4 100644
+--- a/qtbase/tests/auto/widgets/widgets/qcommandlinkbutton/tst_qcommandlinkbutton.cpp
++++ b/qtbase/tests/auto/widgets/widgets/qcommandlinkbutton/tst_qcommandlinkbutton.cpp
+@@ -40,6 +40,9 @@
+ #include <QGridLayout>
+ #include <QPainter>
+
++#include <private/qguiapplication_p.h>
++#include <qpa/qplatformtheme.h>
++
+ class tst_QCommandLinkButton : public QObject
+ {
+ Q_OBJECT
+@@ -223,6 +226,13 @@ void tst_QCommandLinkButton::setAutoRepeat()
+ // check that pressing ENTER has no effect
+ resetCounters();
+ testWidget->setDown( false );
++ // Skip after reset if ButtonPressKeys has Key_Enter
++ const auto buttonPressKeys = QGuiApplicationPrivate::platformTheme()
++ ->themeHint(QPlatformTheme::ButtonPressKeys)
++ .value<QList<Qt::Key>>();
++ if (buttonPressKeys.contains(Qt::Key_Enter)) {
++ return;
++ }
+ testWidget->setAutoRepeat( false );
+ QTest::keyPress( testWidget, Qt::Key_Enter );
+
+@@ -255,6 +265,14 @@ void tst_QCommandLinkButton::pressed()
+ QCOMPARE( press_count, (uint)1 );
+ QCOMPARE( release_count, (uint)1 );
+
++ // Skip if ButtonPressKeys has Key_Enter
++ const auto buttonPressKeys = QGuiApplicationPrivate::platformTheme()
++ ->themeHint(QPlatformTheme::ButtonPressKeys)
++ .value<QList<Qt::Key>>();
++ if (buttonPressKeys.contains(Qt::Key_Enter)) {
++ return;
++ }
++
+ QTest::keyPress( testWidget,Qt::Key_Enter );
+ QCOMPARE( press_count, (uint)1 );
+ QCOMPARE( release_count, (uint)1 );
+diff --git a/qtbase/tests/auto/widgets/widgets/qgroupbox/qgroupbox.pro b/qtbase/tests/auto/widgets/widgets/qgroupbox/qgroupbox.pro
+index 4a5e76ff65..a235fa1fac 100644
+--- a/qtbase/tests/auto/widgets/widgets/qgroupbox/qgroupbox.pro
++++ b/qtbase/tests/auto/widgets/widgets/qgroupbox/qgroupbox.pro
+@@ -1,6 +1,6 @@
+ CONFIG += testcase
+ TARGET = tst_qgroupbox
+-QT += widgets testlib
++QT += widgets testlib gui-private
+ SOURCES += tst_qgroupbox.cpp
+
+
+diff --git a/qtbase/tests/auto/widgets/widgets/qgroupbox/tst_qgroupbox.cpp b/qtbase/tests/auto/widgets/widgets/qgroupbox/tst_qgroupbox.cpp
+index 4fb5d262ca..d8d7562b73 100644
+--- a/qtbase/tests/auto/widgets/widgets/qgroupbox/tst_qgroupbox.cpp
++++ b/qtbase/tests/auto/widgets/widgets/qgroupbox/tst_qgroupbox.cpp
+@@ -35,6 +35,9 @@
+ #include <QRadioButton>
+ #include <QDialog>
+
++#include <private/qguiapplication_p.h>
++#include <qpa/qplatformtheme.h>
++
+ #include "qgroupbox.h"
+
+ class tst_QGroupBox : public QObject
+@@ -69,6 +72,7 @@ private slots:
+ void propagateFocus();
+ void task_QTBUG_19170_ignoreMouseReleaseEvent();
+ void task_QTBUG_15519_propagateMouseEvents();
++ void buttonPressKeys();
+
+ private:
+ bool checked;
+@@ -610,6 +614,20 @@ void tst_QGroupBox::task_QTBUG_15519_propagateMouseEvents()
+ QCOMPARE(parent.mouseMoved, true);
+ }
+
++void tst_QGroupBox::buttonPressKeys()
++{
++ QGroupBox groupBox;
++ groupBox.setCheckable(true);
++ QSignalSpy clickedSpy(&groupBox, &QGroupBox::clicked);
++ const auto buttonPressKeys = QGuiApplicationPrivate::platformTheme()
++ ->themeHint(QPlatformTheme::ButtonPressKeys)
++ .value<QList<Qt::Key>>();
++ for (int i = 0; i < buttonPressKeys.length(); ++i) {
++ QTest::keyClick(&groupBox, buttonPressKeys[i]);
++ QCOMPARE(clickedSpy.length(), i + 1);
++ }
++}
++
+ void tst_QGroupBox::sendMouseMoveEvent(QWidget *widget, const QPoint &localPos)
+ {
+ // Send a MouseMove event without actually moving the pointer
+diff --git a/qtbase/tests/auto/widgets/widgets/qpushbutton/qpushbutton.pro b/qtbase/tests/auto/widgets/widgets/qpushbutton/qpushbutton.pro
+index 353ad06ca2..e55f6148f2 100644
+--- a/qtbase/tests/auto/widgets/widgets/qpushbutton/qpushbutton.pro
++++ b/qtbase/tests/auto/widgets/widgets/qpushbutton/qpushbutton.pro
+@@ -1,6 +1,6 @@
+ CONFIG += testcase
+ TARGET = tst_qpushbutton
+-QT += widgets testlib
++QT += widgets testlib gui-private
+ SOURCES += tst_qpushbutton.cpp
+
+
+diff --git a/qtbase/tests/auto/widgets/widgets/qpushbutton/tst_qpushbutton.cpp b/qtbase/tests/auto/widgets/widgets/qpushbutton/tst_qpushbutton.cpp
+index e818514a79..4043e9326a 100644
+--- a/qtbase/tests/auto/widgets/widgets/qpushbutton/tst_qpushbutton.cpp
++++ b/qtbase/tests/auto/widgets/widgets/qpushbutton/tst_qpushbutton.cpp
+@@ -41,6 +41,9 @@
+ #include <QStyleFactory>
+ #include <QTabWidget>
+
++#include <private/qguiapplication_p.h>
++#include <qpa/qplatformtheme.h>
++
+ class tst_QPushButton : public QObject
+ {
+ Q_OBJECT
+@@ -212,6 +215,13 @@ void tst_QPushButton::autoRepeat()
+ // check that pressing ENTER has no effect
+ resetCounters();
+ testWidget->setDown( false );
++ // Skip after reset if ButtonPressKeys has Key_Enter
++ const auto buttonPressKeys = QGuiApplicationPrivate::platformTheme()
++ ->themeHint(QPlatformTheme::ButtonPressKeys)
++ .value<QList<Qt::Key>>();
++ if (buttonPressKeys.contains(Qt::Key_Enter)) {
++ return;
++ }
+ testWidget->setAutoRepeat( false );
+ QTest::keyPress( testWidget, Qt::Key_Enter );
+
+@@ -247,6 +257,14 @@ void tst_QPushButton::pressed()
+ QCOMPARE( press_count, (uint)1 );
+ QCOMPARE( release_count, (uint)1 );
+
++ // Skip if ButtonPressKeys has Key_Enter
++ const auto buttonPressKeys = QGuiApplicationPrivate::platformTheme()
++ ->themeHint(QPlatformTheme::ButtonPressKeys)
++ .value<QList<Qt::Key>>();
++ if (buttonPressKeys.contains(Qt::Key_Enter)) {
++ return;
++ }
++
+ QTest::keyPress( testWidget,Qt::Key_Enter );
+ QCOMPARE( press_count, (uint)1 );
+ QCOMPARE( release_count, (uint)1 );
+diff --git a/qtbase/tests/manual/rhi/cubemap_render/buildshader.bat b/qtbase/tests/manual/rhi/cubemap_render/buildshader.bat
+old mode 100755
+new mode 100644
+Submodule qtconnectivity e957d481..056294c0:
+diff --git a/qtconnectivity/src/bluetooth/bluez/hcimanager.cpp b/qtconnectivity/src/bluetooth/bluez/hcimanager.cpp
+index e2635fae..a8b8e3b9 100644
+--- a/qtconnectivity/src/bluetooth/bluez/hcimanager.cpp
++++ b/qtconnectivity/src/bluetooth/bluez/hcimanager.cpp
+@@ -563,9 +563,11 @@ void HciManager::handleHciAclPacket(const quint8 *data, int size)
+
+ void HciManager::handleLeMetaEvent(const quint8 *data)
+ {
+- // Spec v4.2, Vol 2, part E, 7.7.65ff
++ // Spec v5.3, Vol 4, part E, 7.7.65.*
+ switch (*data) {
+- case 0x1: {
++ case 0x1: // HCI_LE_Connection_Complete
++ case 0xA: // HCI_LE_Enhanced_Connection_Complete
++ {
+ const quint16 handle = bt_get_le16(data + 2);
+ emit connectionComplete(handle);
+ break;
+diff --git a/qtconnectivity/src/bluetooth/qbluetoothservicediscoveryagent_bluez.cpp b/qtconnectivity/src/bluetooth/qbluetoothservicediscoveryagent_bluez.cpp
+index 6a93143b..4a18cfc7 100644
+--- a/qtconnectivity/src/bluetooth/qbluetoothservicediscoveryagent_bluez.cpp
++++ b/qtconnectivity/src/bluetooth/qbluetoothservicediscoveryagent_bluez.cpp
+@@ -320,7 +320,10 @@ void QBluetoothServiceDiscoveryAgentPrivate::_q_finishSdpScan(QBluetoothServiceD
+ for (const QBluetoothUuid &id : serviceClassUuids) {
+ if (id.minimumSize() == 16) {
+ serviceInfo.setServiceUuid(id);
+- serviceInfo.setServiceName(QBluetoothServiceDiscoveryAgent::tr("Custom Service"));
++ if (serviceInfo.serviceName().isEmpty()) {
++ serviceInfo.setServiceName(
++ QBluetoothServiceDiscoveryAgent::tr("Custom Service"));
++ }
+ QBluetoothServiceInfo::Sequence modSeq =
+ serviceInfo.attribute(QBluetoothServiceInfo::ServiceClassIds).value<QBluetoothServiceInfo::Sequence>();
+ modSeq.removeOne(QVariant::fromValue(id));
+@@ -334,8 +337,10 @@ void QBluetoothServiceDiscoveryAgentPrivate::_q_finishSdpScan(QBluetoothServiceD
+ qCDebug(QT_BT_BLUEZ) << "Discovered services" << discoveredDevices.at(0).address().toString()
+ << serviceInfo.serviceName() << serviceInfo.serviceUuid()
+ << ">>>" << serviceInfo.serviceClassUuids();
+-
+- emit q->serviceDiscovered(serviceInfo);
++ // Use queued connection to allow us finish the service looping; the application
++ // might call stop() when it has detected the service-of-interest.
++ QMetaObject::invokeMethod(q, "serviceDiscovered", Qt::QueuedConnection,
++ Q_ARG(QBluetoothServiceInfo, serviceInfo));
+ }
+ }
+ }
+diff --git a/qtconnectivity/src/bluetooth/qbluetoothsocket.cpp b/qtconnectivity/src/bluetooth/qbluetoothsocket.cpp
+index e4d85447..aadd4755 100644
+--- a/qtconnectivity/src/bluetooth/qbluetoothsocket.cpp
++++ b/qtconnectivity/src/bluetooth/qbluetoothsocket.cpp
+@@ -593,7 +593,7 @@ void QBluetoothSocket::setSocketState(QBluetoothSocket::SocketState state)
+ bool QBluetoothSocket::canReadLine() const
+ {
+ Q_D(const QBluetoothSocketBase);
+- return d->canReadLine();
++ return d->canReadLine() || QIODevice::canReadLine();
+ }
+
+ /*!
+diff --git a/qtconnectivity/src/bluetooth/qbluetoothsocket_bluezdbus.cpp b/qtconnectivity/src/bluetooth/qbluetoothsocket_bluezdbus.cpp
+index 084aa958..d6aa17a7 100644
+--- a/qtconnectivity/src/bluetooth/qbluetoothsocket_bluezdbus.cpp
++++ b/qtconnectivity/src/bluetooth/qbluetoothsocket_bluezdbus.cpp
+@@ -284,6 +284,10 @@ void QBluetoothSocketPrivateBluezDBus::connectToService(
+ return;
+ }
+
++ if (service.socketProtocol() != QBluetoothServiceInfo::Protocol::UnknownProtocol)
++ socketType = service.socketProtocol();
++ qCDebug(QT_BT_BLUEZ) << "Socket protocol used:" << socketType;
++
+ connectToService(service.device().address(), targetService, openMode);
+ }
+
+diff --git a/qtconnectivity/tests/auto/qbluetoothsocket/tst_qbluetoothsocket.cpp b/qtconnectivity/tests/auto/qbluetoothsocket/tst_qbluetoothsocket.cpp
+index 05bc1a0f..a7b5ef1f 100644
+--- a/qtconnectivity/tests/auto/qbluetoothsocket/tst_qbluetoothsocket.cpp
++++ b/qtconnectivity/tests/auto/qbluetoothsocket/tst_qbluetoothsocket.cpp
+@@ -142,7 +142,7 @@ void tst_QBluetoothSocket::initTestCase()
+ qDebug() << "Starting discovery";
+
+ sda->setUuidFilter(QBluetoothUuid(QString(TEST_SERVICE_UUID)));
+- sda->start(QBluetoothServiceDiscoveryAgent::MinimalDiscovery);
++ sda->start(QBluetoothServiceDiscoveryAgent::FullDiscovery);
+
+ for (int connectTime = MaxConnectTime; !done_discovery && connectTime > 0; connectTime -= 1000)
+ QTest::qWait(1000);
+Submodule qtdeclarative f5701f0d..8defe7bf:
+diff --git a/qtdeclarative/src/qml/common/qqmljsfixedpoolarray_p.h b/qtdeclarative/src/qml/common/qqmljsfixedpoolarray_p.h
+index b65b994d6c..15a8cd6878 100644
+--- a/qtdeclarative/src/qml/common/qqmljsfixedpoolarray_p.h
++++ b/qtdeclarative/src/qml/common/qqmljsfixedpoolarray_p.h
+@@ -86,7 +86,7 @@ public:
+ if (QTypeInfo<T>::isComplex) {
+ for (int i = 0; i < count; ++i)
+ new (data + i) T(vector.at(i));
+- } else {
++ } else if (count) {
+ memcpy(data, static_cast<const void*>(vector.constData()), count * sizeof(T));
+ }
+ }
+diff --git a/qtdeclarative/src/qml/jsruntime/qv4qobjectwrapper.cpp b/qtdeclarative/src/qml/jsruntime/qv4qobjectwrapper.cpp
+index e57cdd8278..94613598af 100644
+--- a/qtdeclarative/src/qml/jsruntime/qv4qobjectwrapper.cpp
++++ b/qtdeclarative/src/qml/jsruntime/qv4qobjectwrapper.cpp
+@@ -1145,8 +1145,7 @@ void Heap::QObjectWrapper::markObjects(Heap::Base *that, QV4::MarkStack *markSta
+ void QObjectWrapper::destroyObject(bool lastCall)
+ {
+ Heap::QObjectWrapper *h = d();
+- if (!h->internalClass)
+- return; // destroyObject already got called
++ Q_ASSERT(h->internalClass);
+
+ if (h->object()) {
+ QQmlData *ddata = QQmlData::get(h->object(), false);
+@@ -1176,7 +1175,7 @@ void QObjectWrapper::destroyObject(bool lastCall)
+ }
+ }
+
+- h->~Data();
++ h->destroy();
+ }
+
+
+diff --git a/qtdeclarative/src/qml/memory/qv4mm.cpp b/qtdeclarative/src/qml/memory/qv4mm.cpp
+index 06caf04e5a..da149a67c4 100644
+--- a/qtdeclarative/src/qml/memory/qv4mm.cpp
++++ b/qtdeclarative/src/qml/memory/qv4mm.cpp
+@@ -981,7 +981,7 @@ void MemoryManager::sweep(bool lastSweep, ClassDestroyStatsCallback classCountPt
+
+ if (MultiplyWrappedQObjectMap *multiplyWrappedQObjects = engine->m_multiplyWrappedQObjects) {
+ for (MultiplyWrappedQObjectMap::Iterator it = multiplyWrappedQObjects->begin(); it != multiplyWrappedQObjects->end();) {
+- if (!it.value().isNullOrUndefined())
++ if (it.value().isNullOrUndefined())
+ it = multiplyWrappedQObjects->erase(it);
+ else
+ ++it;
+diff --git a/qtdeclarative/src/qmlmodels/qqmldelegatemodel.cpp b/qtdeclarative/src/qmlmodels/qqmldelegatemodel.cpp
+index 2079a8ed04..a577cb2351 100644
+--- a/qtdeclarative/src/qmlmodels/qqmldelegatemodel.cpp
++++ b/qtdeclarative/src/qmlmodels/qqmldelegatemodel.cpp
+@@ -389,6 +389,12 @@ void QQmlDelegateModelPrivate::connectToAbstractItemModel()
+ q, QQmlDelegateModel, SLOT(_q_rowsRemoved(QModelIndex,int,int)));
+ qmlobject_connect(aim, QAbstractItemModel, SIGNAL(rowsAboutToBeRemoved(QModelIndex,int,int)),
+ q, QQmlDelegateModel, SLOT(_q_rowsAboutToBeRemoved(QModelIndex,int,int)));
++ qmlobject_connect(aim, QAbstractItemModel, SIGNAL(columnsInserted(QModelIndex,int,int)),
++ q, QQmlDelegateModel, SLOT(_q_columnsInserted(QModelIndex,int,int)));
++ qmlobject_connect(aim, QAbstractItemModel, SIGNAL(columnsRemoved(QModelIndex,int,int)),
++ q, QQmlDelegateModel, SLOT(_q_columnsRemoved(QModelIndex,int,int)));
++ qmlobject_connect(aim, QAbstractItemModel, SIGNAL(columnsMoved(QModelIndex,int,int,QModelIndex,int)),
++ q, QQmlDelegateModel, SLOT(_q_columnsMoved(QModelIndex,int,int,QModelIndex,int)));
+ qmlobject_connect(aim, QAbstractItemModel, SIGNAL(dataChanged(QModelIndex,QModelIndex,QVector<int>)),
+ q, QQmlDelegateModel, SLOT(_q_dataChanged(QModelIndex,QModelIndex,QVector<int>)));
+ qmlobject_connect(aim, QAbstractItemModel, SIGNAL(rowsMoved(QModelIndex,int,int,QModelIndex,int)),
+@@ -413,6 +419,12 @@ void QQmlDelegateModelPrivate::disconnectFromAbstractItemModel()
+ q, SLOT(_q_rowsAboutToBeRemoved(QModelIndex,int,int)));
+ QObject::disconnect(aim, SIGNAL(rowsRemoved(QModelIndex,int,int)),
+ q, SLOT(_q_rowsRemoved(QModelIndex,int,int)));
++ QObject::disconnect(aim, SIGNAL(columnsInserted(QModelIndex,int,int)), q,
++ SLOT(_q_columnsInserted(QModelIndex,int,int)));
++ QObject::disconnect(aim, SIGNAL(columnsRemoved(QModelIndex,int,int)), q,
++ SLOT(_q_columnsRemoved(QModelIndex,int,int)));
++ QObject::disconnect(aim, SIGNAL(columnsMoved(QModelIndex,int,int,QModelIndex,int)), q,
++ SLOT(_q_columnsMoved(QModelIndex,int,int,QModelIndex,int)));
+ QObject::disconnect(aim, SIGNAL(dataChanged(QModelIndex,QModelIndex,QVector<int>)),
+ q, SLOT(_q_dataChanged(QModelIndex,QModelIndex,QVector<int>)));
+ QObject::disconnect(aim, SIGNAL(rowsMoved(QModelIndex,int,int,QModelIndex,int)),
+@@ -1973,6 +1985,38 @@ void QQmlDelegateModel::_q_rowsMoved(
+ }
+ }
+
++void QQmlDelegateModel::_q_columnsInserted(const QModelIndex &parent, int begin, int end)
++{
++ Q_D(QQmlDelegateModel);
++ Q_UNUSED(end);
++ if (parent == d->m_adaptorModel.rootIndex && begin == 0) {
++ // mark all items as changed
++ _q_itemsChanged(0, d->m_count, QVector<int>());
++ }
++}
++
++void QQmlDelegateModel::_q_columnsRemoved(const QModelIndex &parent, int begin, int end)
++{
++ Q_D(QQmlDelegateModel);
++ Q_UNUSED(end);
++ if (parent == d->m_adaptorModel.rootIndex && begin == 0) {
++ // mark all items as changed
++ _q_itemsChanged(0, d->m_count, QVector<int>());
++ }
++}
++
++void QQmlDelegateModel::_q_columnsMoved(const QModelIndex &parent, int start, int end,
++ const QModelIndex &destination, int column)
++{
++ Q_D(QQmlDelegateModel);
++ Q_UNUSED(end);
++ if ((parent == d->m_adaptorModel.rootIndex && start == 0)
++ || (destination == d->m_adaptorModel.rootIndex && column == 0)) {
++ // mark all items as changed
++ _q_itemsChanged(0, d->m_count, QVector<int>());
++ }
++}
++
+ void QQmlDelegateModel::_q_dataChanged(const QModelIndex &begin, const QModelIndex &end, const QVector<int> &roles)
+ {
+ Q_D(QQmlDelegateModel);
+diff --git a/qtdeclarative/src/qmlmodels/qqmldelegatemodel_p.h b/qtdeclarative/src/qmlmodels/qqmldelegatemodel_p.h
+index 8aab4badca..d140bfbaaf 100644
+--- a/qtdeclarative/src/qmlmodels/qqmldelegatemodel_p.h
++++ b/qtdeclarative/src/qmlmodels/qqmldelegatemodel_p.h
+@@ -152,6 +152,9 @@ private Q_SLOTS:
+ void _q_itemsMoved(int from, int to, int count);
+ void _q_modelReset();
+ void _q_rowsInserted(const QModelIndex &,int,int);
++ void _q_columnsInserted(const QModelIndex &, int, int);
++ void _q_columnsRemoved(const QModelIndex &, int, int);
++ void _q_columnsMoved(const QModelIndex &, int, int, const QModelIndex &, int);
+ void _q_rowsAboutToBeRemoved(const QModelIndex &parent, int begin, int end);
+ void _q_rowsRemoved(const QModelIndex &,int,int);
+ void _q_rowsMoved(const QModelIndex &, int, int, const QModelIndex &, int);
+diff --git a/qtdeclarative/src/quick/accessible/qaccessiblequickitem.cpp b/qtdeclarative/src/quick/accessible/qaccessiblequickitem.cpp
+index 85719fdc80..78e2ab302c 100644
+--- a/qtdeclarative/src/quick/accessible/qaccessiblequickitem.cpp
++++ b/qtdeclarative/src/quick/accessible/qaccessiblequickitem.cpp
+@@ -46,6 +46,7 @@
+ #include "QtQuick/private/qquicktextinput_p.h"
+ #include "QtQuick/private/qquickaccessibleattached_p.h"
+ #include "QtQuick/qquicktextdocument.h"
++#include "QtQuick/qquickrendercontrol.h"
+ QT_BEGIN_NAMESPACE
+
+ #if QT_CONFIG(accessibility)
+@@ -57,7 +58,19 @@ QAccessibleQuickItem::QAccessibleQuickItem(QQuickItem *item)
+
+ QWindow *QAccessibleQuickItem::window() const
+ {
+- return item()->window();
++ QQuickWindow *window = item()->window();
++
++ // For QQuickWidget the above window will be the offscreen QQuickWindow,
++ // which is not a part of the accessibility tree. Detect this case and
++ // return the window for the QQuickWidget instead.
++ if (window && !window->handle()) {
++ if (QQuickRenderControl *renderControl = QQuickWindowPrivate::get(window)->renderControl) {
++ if (QWindow *renderWindow = renderControl->renderWindow(nullptr))
++ return renderWindow;
++ }
++ }
++
++ return window;
+ }
+
+ int QAccessibleQuickItem::childCount() const
+@@ -113,19 +126,15 @@ QAccessibleInterface *QAccessibleQuickItem::childAt(int x, int y) const
+ QAccessibleInterface *QAccessibleQuickItem::parent() const
+ {
+ QQuickItem *parent = item()->parentItem();
+- QQuickWindow *window = item()->window();
+- QQuickItem *ci = window ? window->contentItem() : nullptr;
++ QQuickWindow *itemWindow = item()->window();
++ QQuickItem *ci = itemWindow ? itemWindow->contentItem() : nullptr;
+ while (parent && !QQuickItemPrivate::get(parent)->isAccessible && parent != ci)
+ parent = parent->parentItem();
+
+ if (parent) {
+ if (parent == ci) {
+- // Jump out to the scene widget if the parent is the root item.
+- // There are two root items, QQuickWindow::rootItem and
+- // QQuickView::declarativeRoot. The former is the true root item,
+- // but is not a part of the accessibility tree. Check if we hit
+- // it here and return an interface for the scene instead.
+- return QAccessible::queryAccessibleInterface(window);
++ // Jump out to the window if the parent is the root item
++ return QAccessible::queryAccessibleInterface(window());
+ } else {
+ while (parent && !parent->d_func()->isAccessible)
+ parent = parent->parentItem();
+@@ -188,7 +197,7 @@ QAccessible::State QAccessibleQuickItem::state() const
+ QRect viewRect_ = viewRect();
+ QRect itemRect = rect();
+
+- if (viewRect_.isNull() || itemRect.isNull() || !item()->window() || !item()->window()->isVisible() ||!item()->isVisible() || qFuzzyIsNull(item()->opacity()))
++ if (viewRect_.isNull() || itemRect.isNull() || !window() || !window()->isVisible() ||!item()->isVisible() || qFuzzyIsNull(item()->opacity()))
+ state.invisible = true;
+ if (!viewRect_.intersects(itemRect))
+ state.offscreen = true;
+@@ -201,6 +210,10 @@ QAccessible::State QAccessibleQuickItem::state() const
+ if (role() == QAccessible::EditableText)
+ if (auto ti = qobject_cast<QQuickTextInput *>(item()))
+ state.passwordEdit = ti->echoMode() != QQuickTextInput::Normal;
++ if (!item()->isEnabled()) {
++ state.focusable = false;
++ state.disabled = true;
++ }
+ return state;
+ }
+
+diff --git a/qtdeclarative/src/quick/accessible/qaccessiblequickview_p.h b/qtdeclarative/src/quick/accessible/qaccessiblequickview_p.h
+index 39ffcaf39c..8baa01330c 100644
+--- a/qtdeclarative/src/quick/accessible/qaccessiblequickview_p.h
++++ b/qtdeclarative/src/quick/accessible/qaccessiblequickview_p.h
+@@ -58,7 +58,7 @@ QT_BEGIN_NAMESPACE
+
+ #if QT_CONFIG(accessibility)
+
+-class QAccessibleQuickWindow : public QAccessibleObject
++class Q_QUICK_EXPORT QAccessibleQuickWindow : public QAccessibleObject
+ {
+ public:
+ QAccessibleQuickWindow(QQuickWindow *object);
+diff --git a/qtdeclarative/src/quick/items/qquickdrag.cpp b/qtdeclarative/src/quick/items/qquickdrag.cpp
+index 8321fcfeed..383078b3b9 100644
+--- a/qtdeclarative/src/quick/items/qquickdrag.cpp
++++ b/qtdeclarative/src/quick/items/qquickdrag.cpp
+@@ -481,7 +481,9 @@ void QQuickDragAttached::setKeys(const QStringList &keys)
+ \qmlattachedproperty stringlist QtQuick::Drag::mimeData
+ \since 5.2
+
+- This property holds a map of mimeData that is used during startDrag.
++ This property holds a map from mime type to data that is used during startDrag.
++ The mime data needs to be a \c string, or an \c ArrayBuffer with the data encoded
++ according to the mime type.
+ */
+
+ QVariantMap QQuickDragAttached::mimeData() const
+@@ -766,8 +768,12 @@ Qt::DropAction QQuickDragAttachedPrivate::startDrag(Qt::DropActions supportedAct
+ QDrag *drag = new QDrag(source ? source : q);
+ QMimeData *mimeData = new QMimeData();
+
+- for (auto it = externalMimeData.cbegin(), end = externalMimeData.cend(); it != end; ++it)
+- mimeData->setData(it.key(), it.value().toString().toUtf8());
++ for (auto it = externalMimeData.cbegin(), end = externalMimeData.cend(); it != end; ++it) {
++ if (static_cast<QMetaType::Type>(it.value().type()) == QMetaType::QByteArray)
++ mimeData->setData(it.key(), it.value().toByteArray());
++ else
++ mimeData->setData(it.key(), it.value().toString().toUtf8());
++ }
+
+ drag->setMimeData(mimeData);
+ if (pixmapLoader.isReady()) {
+diff --git a/qtdeclarative/src/quick/items/qquickitem.cpp b/qtdeclarative/src/quick/items/qquickitem.cpp
+index 75f1457816..dec0ae19ae 100644
+--- a/qtdeclarative/src/quick/items/qquickitem.cpp
++++ b/qtdeclarative/src/quick/items/qquickitem.cpp
+@@ -59,6 +59,7 @@
+ #include <QtCore/private/qnumeric_p.h>
+ #include <QtGui/qpa/qplatformtheme.h>
+ #include <QtCore/qloggingcategory.h>
++#include <QtCore/private/qduplicatetracker_p.h>
+
+ #include <private/qqmlglobal_p.h>
+ #include <private/qqmlengine_p.h>
+@@ -2326,6 +2327,7 @@ QQuickItem::QQuickItem(QQuickItemPrivate &dd, QQuickItem *parent)
+ QQuickItem::~QQuickItem()
+ {
+ Q_D(QQuickItem);
++ d->inDestructor = true;
+
+ if (d->windowRefCount > 1)
+ d->windowRefCount = 1; // Make sure window is set to null in next call to derefWindow().
+@@ -2526,6 +2528,7 @@ QQuickItem* QQuickItemPrivate::nextPrevItemInTabFocusChain(QQuickItem *item, boo
+ QQuickItem *current = item;
+ qCDebug(DBG_FOCUS) << "QQuickItemPrivate::nextPrevItemInTabFocusChain: startItem:" << startItem;
+ qCDebug(DBG_FOCUS) << "QQuickItemPrivate::nextPrevItemInTabFocusChain: firstFromItem:" << firstFromItem;
++ QDuplicateTracker<QQuickItem *> cycleDetector;
+ do {
+ qCDebug(DBG_FOCUS) << "QQuickItemPrivate::nextPrevItemInTabFocusChain: current:" << current;
+ qCDebug(DBG_FOCUS) << "QQuickItemPrivate::nextPrevItemInTabFocusChain: from:" << from;
+@@ -2592,7 +2595,10 @@ QQuickItem* QQuickItemPrivate::nextPrevItemInTabFocusChain(QQuickItem *item, boo
+ // traversed all of the chain (by compare the [current] item with [startItem])
+ // Since the [startItem] might be promoted to its parent if it is invisible,
+ // we still have to check [current] item with original start item
+- if ((current == startItem || current == originalStartItem) && from == firstFromItem) {
++ // We might also run into a cycle before we reach firstFromItem again
++ // but note that we have to ignore current if we are meant to skip it
++ if (((current == startItem || current == originalStartItem) && from == firstFromItem) ||
++ (!skip && cycleDetector.hasSeen(current))) {
+ // wrapped around, avoid endless loops
+ if (item == contentItem) {
+ qCDebug(DBG_FOCUS) << "QQuickItemPrivate::nextPrevItemInTabFocusChain: looped, return contentItem";
+@@ -2689,9 +2695,8 @@ void QQuickItem::setParentItem(QQuickItem *parentItem)
+
+ const bool wasVisible = isVisible();
+ op->removeChild(this);
+- if (wasVisible) {
++ if (wasVisible && !op->inDestructor)
+ emit oldParentItem->visibleChildrenChanged();
+- }
+ } else if (d->window) {
+ QQuickWindowPrivate::get(d->window)->parentlessItems.remove(this);
+ }
+@@ -2768,8 +2773,9 @@ void QQuickItem::setParentItem(QQuickItem *parentItem)
+
+ d->itemChange(ItemParentHasChanged, d->parentItem);
+
+- emit parentChanged(d->parentItem);
+- if (isVisible() && d->parentItem)
++ if (!d->inDestructor)
++ emit parentChanged(d->parentItem);
++ if (isVisible() && d->parentItem && !QQuickItemPrivate::get(d->parentItem)->inDestructor)
+ emit d->parentItem->visibleChildrenChanged();
+ }
+
+@@ -2965,7 +2971,8 @@ void QQuickItemPrivate::removeChild(QQuickItem *child)
+
+ itemChange(QQuickItem::ItemChildRemovedChange, child);
+
+- emit q->childrenChanged();
++ if (!inDestructor)
++ emit q->childrenChanged();
+ }
+
+ void QQuickItemPrivate::refWindow(QQuickWindow *c)
+@@ -3194,6 +3201,7 @@ QQuickItemPrivate::QQuickItemPrivate()
+ , touchEnabled(false)
+ #endif
+ , hasCursorHandler(false)
++ , inDestructor(false)
+ , dirtyAttributes(0)
+ , nextDirtyItem(nullptr)
+ , prevDirtyItem(nullptr)
+@@ -5120,6 +5128,13 @@ void QQuickItem::componentComplete()
+ d->addToDirtyList();
+ QQuickWindowPrivate::get(d->window)->dirtyItem(this);
+ }
++
++#if QT_CONFIG(accessibility)
++ if (d->isAccessible && d->effectiveVisible) {
++ QAccessibleEvent ev(this, QAccessible::ObjectShow);
++ QAccessible::updateAccessibility(&ev);
++ }
++#endif
+ }
+
+ QQuickStateGroup *QQuickItemPrivate::_states()
+@@ -6106,9 +6121,11 @@ bool QQuickItemPrivate::setEffectiveVisibleRecur(bool newEffectiveVisible)
+ QAccessible::updateAccessibility(&ev);
+ }
+ #endif
+- emit q->visibleChanged();
+- if (childVisibilityChanged)
+- emit q->visibleChildrenChanged();
++ if (!inDestructor) {
++ emit q->visibleChanged();
++ if (childVisibilityChanged)
++ emit q->visibleChildrenChanged();
++ }
+
+ return true; // effective visibility DID change
+ }
+@@ -6157,6 +6174,15 @@ void QQuickItemPrivate::setEffectiveEnableRecur(QQuickItem *scope, bool newEffec
+ }
+
+ itemChange(QQuickItem::ItemEnabledHasChanged, effectiveEnable);
++#if QT_CONFIG(accessibility)
++ if (isAccessible) {
++ QAccessible::State changedState;
++ changedState.disabled = true;
++ changedState.focusable = true;
++ QAccessibleStateChangeEvent ev(q, changedState);
++ QAccessible::updateAccessibility(&ev);
++ }
++#endif
+ emit q->enabledChanged();
+ }
+
+diff --git a/qtdeclarative/src/quick/items/qquickitem_p.h b/qtdeclarative/src/quick/items/qquickitem_p.h
+index 841d91bb40..ade8fb61f2 100644
+--- a/qtdeclarative/src/quick/items/qquickitem_p.h
++++ b/qtdeclarative/src/quick/items/qquickitem_p.h
+@@ -472,6 +472,7 @@ public:
+ bool replayingPressEvent:1;
+ bool touchEnabled:1;
+ bool hasCursorHandler:1;
++ quint32 inDestructor:1; // has entered ~QQuickItem
+
+ enum DirtyType {
+ TransformOrigin = 0x00000001,
+diff --git a/qtdeclarative/src/quick/items/qquickitemview.cpp b/qtdeclarative/src/quick/items/qquickitemview.cpp
+index 010a0152e1..f8ad168a17 100644
+--- a/qtdeclarative/src/quick/items/qquickitemview.cpp
++++ b/qtdeclarative/src/quick/items/qquickitemview.cpp
+@@ -1785,7 +1785,7 @@ void QQuickItemViewPrivate::refill(qreal from, qreal to)
+
+ do {
+ bufferPause.stop();
+- if (currentChanges.hasPendingChanges() || bufferedChanges.hasPendingChanges()) {
++ if (currentChanges.hasPendingChanges() || bufferedChanges.hasPendingChanges() || currentChanges.active) {
+ currentChanges.reset();
+ bufferedChanges.reset();
+ releaseVisibleItems(reusableFlag);
+diff --git a/qtdeclarative/src/quick/items/qquickmousearea_p_p.h b/qtdeclarative/src/quick/items/qquickmousearea_p_p.h
+index fba383e268..0d63618622 100644
+--- a/qtdeclarative/src/quick/items/qquickmousearea_p_p.h
++++ b/qtdeclarative/src/quick/items/qquickmousearea_p_p.h
+@@ -61,7 +61,6 @@ QT_BEGIN_NAMESPACE
+
+ class QQuickMouseEvent;
+ class QQuickMouseArea;
+-class QQuickPointerMask;
+ class QQuickMouseAreaPrivate : public QQuickItemPrivate
+ {
+ Q_DECLARE_PUBLIC(QQuickMouseArea)
+@@ -100,7 +99,6 @@ public:
+ #if QT_CONFIG(quick_draganddrop)
+ QQuickDrag *drag;
+ #endif
+- QPointer<QQuickPointerMask> mask;
+ QPointF startScene;
+ QPointF targetStartPos;
+ QPointF lastPos;
+diff --git a/qtdeclarative/src/quick/items/qquicktext.cpp b/qtdeclarative/src/quick/items/qquicktext.cpp
+index 6230186933..e823ca1095 100644
+--- a/qtdeclarative/src/quick/items/qquicktext.cpp
++++ b/qtdeclarative/src/quick/items/qquicktext.cpp
+@@ -2168,7 +2168,7 @@ void QQuickText::resetMaximumLineCount()
+ <img src="" align="top,middle,bottom" width="" height=""> - inline images
+ <ol type="">, <ul type=""> and <li> - ordered and unordered lists
+ <pre></pre> - preformatted
+- > < &
++ > < & " '
+ \endcode
+
+ \c Text.StyledText parser is strict, requiring tags to be correctly nested.
+diff --git a/qtdeclarative/src/quick/scenegraph/qsgrhidistancefieldglyphcache.cpp b/qtdeclarative/src/quick/scenegraph/qsgrhidistancefieldglyphcache.cpp
+index eb4db0f85e..2325a2665b 100644
+--- a/qtdeclarative/src/quick/scenegraph/qsgrhidistancefieldglyphcache.cpp
++++ b/qtdeclarative/src/quick/scenegraph/qsgrhidistancefieldglyphcache.cpp
+@@ -446,7 +446,7 @@ bool QSGRhiDistanceFieldGlyphCache::loadPregeneratedCache(const QRawFont &font)
+
+ const char *textureRecord = allocatorData;
+ for (int i = 0; i < textureCount; ++i, textureRecord += Qtdf::TextureRecordSize) {
+- if (textureRecord + Qtdf::TextureRecordSize > qtdfTableEnd) {
++ if (qtdfTableEnd - textureRecord < Qtdf::TextureRecordSize) {
+ qWarning("qtdf table too small in font '%s'.",
+ qPrintable(font.familyName()));
+ return false;
+@@ -462,7 +462,7 @@ bool QSGRhiDistanceFieldGlyphCache::loadPregeneratedCache(const QRawFont &font)
+
+ const char *glyphRecord = textureRecord;
+ for (quint32 i = 0; i < glyphCount; ++i, glyphRecord += Qtdf::GlyphRecordSize) {
+- if (glyphRecord + Qtdf::GlyphRecordSize > qtdfTableEnd) {
++ if (qtdfTableEnd - glyphRecord < Qtdf:: GlyphRecordSize) {
+ qWarning("qtdf table too small in font '%s'.",
+ qPrintable(font.familyName()));
+ return false;
+@@ -512,8 +512,8 @@ bool QSGRhiDistanceFieldGlyphCache::loadPregeneratedCache(const QRawFont &font)
+
+ int width = texInfo->allocatedArea.width();
+ int height = texInfo->allocatedArea.height();
+- qint64 size = width * height;
+- if (reinterpret_cast<const char *>(textureData + size) > qtdfTableEnd) {
++ qint64 size = qint64(width) * height;
++ if (qtdfTableEnd - reinterpret_cast<const char *>(textureData) < size) {
+ qWarning("qtdf table too small in font '%s'.",
+ qPrintable(font.familyName()));
+ return false;
+diff --git a/qtdeclarative/src/quick/util/qquickstyledtext.cpp b/qtdeclarative/src/quick/util/qquickstyledtext.cpp
+index d531fc9205..a25af90414 100644
+--- a/qtdeclarative/src/quick/util/qquickstyledtext.cpp
++++ b/qtdeclarative/src/quick/util/qquickstyledtext.cpp
+@@ -564,6 +564,8 @@ void QQuickStyledTextPrivate::parseEntity(const QChar *&ch, const QString &textI
+ textOut += QChar(60);
+ else if (entity == QLatin1String("amp"))
+ textOut += QChar(38);
++ else if (entity == QLatin1String("apos"))
++ textOut += QChar(39);
+ else if (entity == QLatin1String("quot"))
+ textOut += QChar(34);
+ else if (entity == QLatin1String("nbsp"))
+diff --git a/qtdeclarative/src/quickwidgets/qaccessiblequickwidget.cpp b/qtdeclarative/src/quickwidgets/qaccessiblequickwidget.cpp
+new file mode 100644
+index 0000000000..8a1c901880
+--- /dev/null
++++ b/qtdeclarative/src/quickwidgets/qaccessiblequickwidget.cpp
+@@ -0,0 +1,110 @@
++/****************************************************************************
++**
++** Copyright (C) 2021 The Qt Company Ltd.
++** Contact: https://www.qt.io/licensing/
++**
++** This file is part of the QtQuick module of the Qt Toolkit.
++**
++** $QT_BEGIN_LICENSE:LGPL$
++** Commercial License Usage
++** Licensees holding valid commercial Qt licenses may use this file in
++** accordance with the commercial license agreement provided with the
++** Software or, alternatively, in accordance with the terms contained in
++** a written agreement between you and The Qt Company. For licensing terms
++** and conditions see https://www.qt.io/terms-conditions. For further
++** information use the contact form at https://www.qt.io/contact-us.
++**
++** GNU Lesser General Public License Usage
++** Alternatively, this file may be used under the terms of the GNU Lesser
++** General Public License version 3 as published by the Free Software
++** Foundation and appearing in the file LICENSE.LGPL3 included in the
++** packaging of this file. Please review the following information to
++** ensure the GNU Lesser General Public License version 3 requirements
++** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
++**
++** GNU General Public License Usage
++** Alternatively, this file may be used under the terms of the GNU
++** General Public License version 2.0 or (at your option) the GNU General
++** Public license version 3 or any later version approved by the KDE Free
++** Qt Foundation. The licenses are as published by the Free Software
++** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
++** included in the packaging of this file. Please review the following
++** information to ensure the GNU General Public License requirements will
++** be met: https://www.gnu.org/licenses/gpl-2.0.html and
++** https://www.gnu.org/licenses/gpl-3.0.html.
++**
++** $QT_END_LICENSE$
++**
++****************************************************************************/
++
++#include "qaccessiblequickwidget_p.h"
++
++#include "qquickwidget_p.h"
++
++QT_BEGIN_NAMESPACE
++
++#if QT_CONFIG(accessibility)
++
++QAccessibleQuickWidget::QAccessibleQuickWidget(QQuickWidget* widget)
++: QAccessibleWidget(widget)
++, m_accessibleWindow(QQuickWidgetPrivate::get(widget)->offscreenWindow)
++{
++ // NOTE: m_accessibleWindow is a QAccessibleQuickWindow, and not a
++ // QAccessibleQuickWidgetOffscreenWindow (defined below). This means
++ // it will return the Quick item child interfaces, which is what's needed here
++ // (unlike QAccessibleQuickWidgetOffscreenWindow, which will report 0 children).
++}
++
++QAccessibleInterface *QAccessibleQuickWidget::child(int index) const
++{
++ return m_accessibleWindow.child(index);
++}
++
++int QAccessibleQuickWidget::childCount() const
++{
++ return m_accessibleWindow.childCount();
++}
++
++int QAccessibleQuickWidget::indexOfChild(const QAccessibleInterface *iface) const
++{
++ return m_accessibleWindow.indexOfChild(iface);
++}
++
++QAccessibleInterface *QAccessibleQuickWidget::childAt(int x, int y) const
++{
++ return m_accessibleWindow.childAt(x, y);
++}
++
++QAccessibleQuickWidgetOffscreenWindow::QAccessibleQuickWidgetOffscreenWindow(QQuickWindow *window)
++:QAccessibleQuickWindow(window)
++{
++
++}
++
++QAccessibleInterface *QAccessibleQuickWidgetOffscreenWindow::child(int index) const
++{
++ Q_UNUSED(index);
++ return nullptr;
++}
++
++int QAccessibleQuickWidgetOffscreenWindow::childCount() const
++{
++ return 0;
++}
++
++int QAccessibleQuickWidgetOffscreenWindow::indexOfChild(const QAccessibleInterface *iface) const
++{
++ Q_UNUSED(iface);
++ return -1;
++}
++
++QAccessibleInterface *QAccessibleQuickWidgetOffscreenWindow::QAccessibleQuickWidgetOffscreenWindow::childAt(int x, int y) const
++{
++ Q_UNUSED(x);
++ Q_UNUSED(y);
++ return nullptr;
++}
++
++#endif // accessibility
++
++QT_END_NAMESPACE
+diff --git a/qtdeclarative/src/quickwidgets/qaccessiblequickwidget_p.h b/qtdeclarative/src/quickwidgets/qaccessiblequickwidget_p.h
+new file mode 100644
+index 0000000000..7c2ab930e0
+--- /dev/null
++++ b/qtdeclarative/src/quickwidgets/qaccessiblequickwidget_p.h
+@@ -0,0 +1,95 @@
++/****************************************************************************
++**
++** Copyright (C) 2021 The Qt Company Ltd.
++** Contact: https://www.qt.io/licensing/
++**
++** This file is part of the QtQuick module of the Qt Toolkit.
++**
++** $QT_BEGIN_LICENSE:LGPL$
++** Commercial License Usage
++** Licensees holding valid commercial Qt licenses may use this file in
++** accordance with the commercial license agreement provided with the
++** Software or, alternatively, in accordance with the terms contained in
++** a written agreement between you and The Qt Company. For licensing terms
++** and conditions see https://www.qt.io/terms-conditions. For further
++** information use the contact form at https://www.qt.io/contact-us.
++**
++** GNU Lesser General Public License Usage
++** Alternatively, this file may be used under the terms of the GNU Lesser
++** General Public License version 3 as published by the Free Software
++** Foundation and appearing in the file LICENSE.LGPL3 included in the
++** packaging of this file. Please review the following information to
++** ensure the GNU Lesser General Public License version 3 requirements
++** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
++**
++** GNU General Public License Usage
++** Alternatively, this file may be used under the terms of the GNU
++** General Public License version 2.0 or (at your option) the GNU General
++** Public license version 3 or any later version approved by the KDE Free
++** Qt Foundation. The licenses are as published by the Free Software
++** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
++** included in the packaging of this file. Please review the following
++** information to ensure the GNU General Public License requirements will
++** be met: https://www.gnu.org/licenses/gpl-2.0.html and
++** https://www.gnu.org/licenses/gpl-3.0.html.
++**
++** $QT_END_LICENSE$
++**
++****************************************************************************/
++
++#ifndef QACCESSIBLEQUICKWIDGET_H
++#define QACCESSIBLEQUICKWIDGET_H
++
++//
++// W A R N I N G
++// -------------
++//
++// This file is not part of the Qt API. It exists purely as an
++// implementation detail. This header file may change from version to
++// version without notice, or even be removed.
++//
++// We mean it.
++//
++
++#include "qquickwidget.h"
++#include <QtWidgets/qaccessiblewidget.h>
++
++#include <private/qaccessiblequickview_p.h>
++
++QT_BEGIN_NAMESPACE
++
++#if QT_CONFIG(accessibility)
++
++// These classes implement the QQuickWiget accessibility switcharoo,
++// where the child items of the QQuickWidgetOffscreenWindow are reported
++// as child accessible interfaces of the QAccessibleQuickWidget.
++class QAccessibleQuickWidget: public QAccessibleWidget
++{
++public:
++ QAccessibleQuickWidget(QQuickWidget* widget);
++
++ QAccessibleInterface *child(int index) const override;
++ int childCount() const override;
++ int indexOfChild(const QAccessibleInterface *iface) const override;
++ QAccessibleInterface *childAt(int x, int y) const override;
++
++private:
++ QAccessibleQuickWindow m_accessibleWindow;
++ Q_DISABLE_COPY(QAccessibleQuickWidget)
++};
++
++class QAccessibleQuickWidgetOffscreenWindow: public QAccessibleQuickWindow
++{
++public:
++ QAccessibleQuickWidgetOffscreenWindow(QQuickWindow *window);
++ QAccessibleInterface *child(int index) const override;
++ int childCount() const override;
++ int indexOfChild(const QAccessibleInterface *iface) const override;
++ QAccessibleInterface *childAt(int x, int y) const override;
++};
++
++#endif // accessibility
++
++QT_END_NAMESPACE
++
++#endif
+diff --git a/qtdeclarative/src/quickwidgets/qaccessiblequickwidgetfactory.cpp b/qtdeclarative/src/quickwidgets/qaccessiblequickwidgetfactory.cpp
+new file mode 100644
+index 0000000000..7ba88a1769
+--- /dev/null
++++ b/qtdeclarative/src/quickwidgets/qaccessiblequickwidgetfactory.cpp
+@@ -0,0 +1,60 @@
++/****************************************************************************
++**
++** Copyright (C) 2021 The Qt Company Ltd.
++** Contact: https://www.qt.io/licensing/
++**
++** This file is part of the QtQuick module of the Qt Toolkit.
++**
++** $QT_BEGIN_LICENSE:LGPL$
++** Commercial License Usage
++** Licensees holding valid commercial Qt licenses may use this file in
++** accordance with the commercial license agreement provided with the
++** Software or, alternatively, in accordance with the terms contained in
++** a written agreement between you and The Qt Company. For licensing terms
++** and conditions see https://www.qt.io/terms-conditions. For further
++** information use the contact form at https://www.qt.io/contact-us.
++**
++** GNU Lesser General Public License Usage
++** Alternatively, this file may be used under the terms of the GNU Lesser
++** General Public License version 3 as published by the Free Software
++** Foundation and appearing in the file LICENSE.LGPL3 included in the
++** packaging of this file. Please review the following information to
++** ensure the GNU Lesser General Public License version 3 requirements
++** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
++**
++** GNU General Public License Usage
++** Alternatively, this file may be used under the terms of the GNU
++** General Public License version 2.0 or (at your option) the GNU General
++** Public license version 3 or any later version approved by the KDE Free
++** Qt Foundation. The licenses are as published by the Free Software
++** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
++** included in the packaging of this file. Please review the following
++** information to ensure the GNU General Public License requirements will
++** be met: https://www.gnu.org/licenses/gpl-2.0.html and
++** https://www.gnu.org/licenses/gpl-3.0.html.
++**
++** $QT_END_LICENSE$
++**
++****************************************************************************/
++
++#include "qaccessiblequickwidgetfactory_p.h"
++#include "qaccessiblequickwidget_p.h"
++
++QT_BEGIN_NAMESPACE
++
++#if QT_CONFIG(accessibility)
++
++QAccessibleInterface *qAccessibleQuickWidgetFactory(const QString &classname, QObject *object)
++{
++ if (classname == QLatin1String("QQuickWidget")) {
++ return new QAccessibleQuickWidget(qobject_cast<QQuickWidget *>(object));
++ } else if (classname == QLatin1String("QQuickWidgetOffscreenWindow")) {
++ return new QAccessibleQuickWidgetOffscreenWindow(qobject_cast<QQuickWindow *>(object));
++ }
++ return 0;
++}
++
++#endif // accessibility
++
++QT_END_NAMESPACE
++
+diff --git a/qtdeclarative/src/quickwidgets/qaccessiblequickwidgetfactory_p.h b/qtdeclarative/src/quickwidgets/qaccessiblequickwidgetfactory_p.h
+new file mode 100644
+index 0000000000..8c63b09f81
+--- /dev/null
++++ b/qtdeclarative/src/quickwidgets/qaccessiblequickwidgetfactory_p.h
+@@ -0,0 +1,66 @@
++/****************************************************************************
++**
++** Copyright (C) 2021 The Qt Company Ltd.
++** Contact: https://www.qt.io/licensing/
++**
++** This file is part of the QtQuick module of the Qt Toolkit.
++**
++** $QT_BEGIN_LICENSE:LGPL$
++** Commercial License Usage
++** Licensees holding valid commercial Qt licenses may use this file in
++** accordance with the commercial license agreement provided with the
++** Software or, alternatively, in accordance with the terms contained in
++** a written agreement between you and The Qt Company. For licensing terms
++** and conditions see https://www.qt.io/terms-conditions. For further
++** information use the contact form at https://www.qt.io/contact-us.
++**
++** GNU Lesser General Public License Usage
++** Alternatively, this file may be used under the terms of the GNU Lesser
++** General Public License version 3 as published by the Free Software
++** Foundation and appearing in the file LICENSE.LGPL3 included in the
++** packaging of this file. Please review the following information to
++** ensure the GNU Lesser General Public License version 3 requirements
++** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
++**
++** GNU General Public License Usage
++** Alternatively, this file may be used under the terms of the GNU
++** General Public License version 2.0 or (at your option) the GNU General
++** Public license version 3 or any later version approved by the KDE Free
++** Qt Foundation. The licenses are as published by the Free Software
++** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
++** included in the packaging of this file. Please review the following
++** information to ensure the GNU General Public License requirements will
++** be met: https://www.gnu.org/licenses/gpl-2.0.html and
++** https://www.gnu.org/licenses/gpl-3.0.html.
++**
++** $QT_END_LICENSE$
++**
++****************************************************************************/
++
++#include <QtGui/qaccessible.h>
++
++#ifndef QACCESSIBLEQUICKWIDGETFACTORY_H
++#define QACCESSIBLEQUICKWIDGETFACTORY_H
++
++//
++// W A R N I N G
++// -------------
++//
++// This file is not part of the Qt API. It exists purely as an
++// implementation detail. This header file may change from version to
++// version without notice, or even be removed.
++//
++// We mean it.
++//
++
++QT_BEGIN_NAMESPACE
++
++#if QT_CONFIG(accessibility)
++
++QAccessibleInterface *qAccessibleQuickWidgetFactory(const QString &classname, QObject *object);
++
++#endif
++
++QT_END_NAMESPACE
++
++#endif
+diff --git a/qtdeclarative/src/quickwidgets/qquickwidget.cpp b/qtdeclarative/src/quickwidgets/qquickwidget.cpp
+index 39780f8de3..9c97b43518 100644
+--- a/qtdeclarative/src/quickwidgets/qquickwidget.cpp
++++ b/qtdeclarative/src/quickwidgets/qquickwidget.cpp
+@@ -39,6 +39,7 @@
+
+ #include "qquickwidget.h"
+ #include "qquickwidget_p.h"
++#include "qaccessiblequickwidgetfactory_p.h"
+
+ #include "private/qquickwindow_p.h"
+ #include "private/qquickitem_p.h"
+@@ -75,9 +76,16 @@
+
+ QT_BEGIN_NAMESPACE
+
++QQuickWidgetOffscreenWindow::QQuickWidgetOffscreenWindow(QQuickWindowPrivate &dd, QQuickRenderControl *control)
++:QQuickWindow(dd, control)
++{
++ setTitle(QString::fromLatin1("Offscreen"));
++ setObjectName(QString::fromLatin1("QQuickOffScreenWindow"));
++}
++
+ // override setVisble to prevent accidental offscreen window being created
+ // by base class.
+-class QQuickOffcreenWindowPrivate: public QQuickWindowPrivate {
++class QQuickWidgetOffscreenWindowPrivate: public QQuickWindowPrivate {
+ public:
+ void setVisible(bool visible) override {
+ Q_Q(QWindow);
+@@ -105,9 +113,8 @@ void QQuickWidgetPrivate::init(QQmlEngine* e)
+ Q_Q(QQuickWidget);
+
+ renderControl = new QQuickWidgetRenderControl(q);
+- offscreenWindow = new QQuickWindow(*new QQuickOffcreenWindowPrivate(),renderControl);
+- offscreenWindow->setTitle(QString::fromLatin1("Offscreen"));
+- offscreenWindow->setObjectName(QString::fromLatin1("QQuickOffScreenWindow"));
++ offscreenWindow = new QQuickWidgetOffscreenWindow(*new QQuickWidgetOffscreenWindowPrivate(), renderControl);
++ offscreenWindow->setScreen(q->screen());
+ // Do not call create() on offscreenWindow.
+
+ // Check if the Software Adaptation is being used
+@@ -138,6 +145,10 @@ void QQuickWidgetPrivate::init(QQmlEngine* e)
+ QWidget::connect(offscreenWindow, &QQuickWindow::focusObjectChanged, q, &QQuickWidget::propagateFocusObjectChanged);
+ QObject::connect(renderControl, SIGNAL(renderRequested()), q, SLOT(triggerUpdate()));
+ QObject::connect(renderControl, SIGNAL(sceneChanged()), q, SLOT(triggerUpdate()));
++
++#if QT_CONFIG(accessibility)
++ QAccessible::installFactory(&qAccessibleQuickWidgetFactory);
++#endif
+ }
+
+ void QQuickWidgetPrivate::ensureEngine() const
+@@ -901,9 +912,7 @@ void QQuickWidgetPrivate::createContext()
+
+ context = new QOpenGLContext;
+ context->setFormat(offscreenWindow->requestedFormat());
+- const QWindow *win = q->window()->windowHandle();
+- if (win && win->screen())
+- context->setScreen(win->screen());
++ context->setScreen(q->screen());
+ QOpenGLContext *shareContext = qt_gl_global_share_context();
+ if (!shareContext)
+ shareContext = QWidgetPrivate::get(q->window())->shareContext();
+@@ -1520,19 +1529,16 @@ bool QQuickWidget::event(QEvent *e)
+ d->handleWindowChange();
+ break;
+
+- case QEvent::ScreenChangeInternal:
+- if (QWindow *window = this->window()->windowHandle()) {
+- QScreen *newScreen = window->screen();
+-
+- if (d->offscreenWindow)
+- d->offscreenWindow->setScreen(newScreen);
+- if (d->offscreenSurface)
+- d->offscreenSurface->setScreen(newScreen);
++ case QEvent::ScreenChangeInternal: {
++ QScreen *newScreen = screen();
++ if (d->offscreenWindow)
++ d->offscreenWindow->setScreen(newScreen);
++ if (d->offscreenSurface)
++ d->offscreenSurface->setScreen(newScreen);
+ #if QT_CONFIG(opengl)
+- if (d->context)
+- d->context->setScreen(newScreen);
++ if (d->context)
++ d->context->setScreen(newScreen);
+ #endif
+- }
+
+ if (d->useSoftwareRenderer
+ #if QT_CONFIG(opengl)
+@@ -1545,7 +1551,7 @@ bool QQuickWidget::event(QEvent *e)
+ d->render(true);
+ }
+ break;
+-
++ }
+ case QEvent::Show:
+ case QEvent::Move:
+ d->updatePosition();
+diff --git a/qtdeclarative/src/quickwidgets/qquickwidget_p.h b/qtdeclarative/src/quickwidgets/qquickwidget_p.h
+index 881f7f9220..1a946bcc71 100644
+--- a/qtdeclarative/src/quickwidgets/qquickwidget_p.h
++++ b/qtdeclarative/src/quickwidgets/qquickwidget_p.h
+@@ -148,6 +148,14 @@ public:
+ bool forceFullUpdate;
+ };
+
++class QQuickWidgetOffscreenWindow: public QQuickWindow
++{
++ Q_OBJECT
++
++public:
++ QQuickWidgetOffscreenWindow(QQuickWindowPrivate &dd, QQuickRenderControl *control);
++};
++
+ QT_END_NAMESPACE
+
+ #endif // QQuickWidget_P_H
+diff --git a/qtdeclarative/src/quickwidgets/quickwidgets.pro b/qtdeclarative/src/quickwidgets/quickwidgets.pro
+index 2438e577ae..85d156b8a3 100644
+--- a/qtdeclarative/src/quickwidgets/quickwidgets.pro
++++ b/qtdeclarative/src/quickwidgets/quickwidgets.pro
+@@ -7,9 +7,13 @@ DEFINES += QT_NO_URL_CAST_FROM_STRING QT_NO_INTEGER_EVENT_COORDINATES QT_NO_FO
+ HEADERS += \
+ qquickwidget.h \
+ qquickwidget_p.h \
+- qtquickwidgetsglobal.h
++ qtquickwidgetsglobal.h \
++ qaccessiblequickwidget_p.h \
++ qaccessiblequickwidgetfactory_p.h
+
+ SOURCES += \
+- qquickwidget.cpp
++ qquickwidget.cpp \
++ qaccessiblequickwidget.cpp \
++ qaccessiblequickwidgetfactory.cpp
+
+ load(qt_module)
+diff --git a/qtdeclarative/tests/auto/qml/qjsengine/tst_qjsengine.cpp b/qtdeclarative/tests/auto/qml/qjsengine/tst_qjsengine.cpp
+index 3b7d74df63..b75bf820d5 100644
+--- a/qtdeclarative/tests/auto/qml/qjsengine/tst_qjsengine.cpp
++++ b/qtdeclarative/tests/auto/qml/qjsengine/tst_qjsengine.cpp
+@@ -102,6 +102,7 @@ private slots:
+ void valueConversion_RegularExpression();
+ void castWithMultipleInheritance();
+ void collectGarbage();
++ void collectGarbageNestedWrappersTwoEngines();
+ void gcWithNestedDataStructure();
+ void stacktrace();
+ void numberParsing_data();
+@@ -1809,6 +1810,44 @@ void tst_QJSEngine::collectGarbage()
+ QVERIFY(ptr.isNull());
+ }
+
++class TestObjectContainer : public QObject
++{
++ Q_OBJECT
++ Q_PROPERTY(QObject *dummy MEMBER m_dummy CONSTANT)
++
++public:
++ TestObjectContainer() : m_dummy(new QObject(this)) {}
++
++private:
++ QObject *m_dummy;
++};
++
++void tst_QJSEngine::collectGarbageNestedWrappersTwoEngines()
++{
++ QJSEngine engine1;
++ QJSEngine engine2;
++
++ TestObjectContainer container;
++ QQmlEngine::setObjectOwnership(&container, QQmlEngine::CppOwnership);
++
++ engine1.globalObject().setProperty("foobar", engine1.newQObject(&container));
++ engine2.globalObject().setProperty("foobar", engine2.newQObject(&container));
++
++ engine1.evaluate("foobar.dummy.baz = 42");
++ engine2.evaluate("foobar.dummy.baz = 43");
++
++ QCOMPARE(engine1.evaluate("foobar.dummy.baz").toInt(), 42);
++ QCOMPARE(engine2.evaluate("foobar.dummy.baz").toInt(), 43);
++
++ engine1.collectGarbage();
++ engine2.collectGarbage();
++
++ // The GC should not collect dummy object wrappers neither in engine1 nor engine2, we
++ // verify that by checking whether the baz property still has its previous value.
++ QCOMPARE(engine1.evaluate("foobar.dummy.baz").toInt(), 42);
++ QCOMPARE(engine2.evaluate("foobar.dummy.baz").toInt(), 43);
++}
++
+ void tst_QJSEngine::gcWithNestedDataStructure()
+ {
+ // The GC must be able to traverse deeply nested objects, otherwise this
+diff --git a/qtdeclarative/tests/auto/qml/qqmldelegatemodel/data/redrawUponColumnChange.qml b/qtdeclarative/tests/auto/qml/qqmldelegatemodel/data/redrawUponColumnChange.qml
+new file mode 100644
+index 0000000000..206133bb39
+--- /dev/null
++++ b/qtdeclarative/tests/auto/qml/qqmldelegatemodel/data/redrawUponColumnChange.qml
+@@ -0,0 +1,11 @@
++import QtQuick 2.8
++
++ListView {
++ id: root
++ width: 200
++ height: 200
++
++ delegate: Text {
++ text: display
++ }
++}
+diff --git a/qtdeclarative/tests/auto/qml/qqmldelegatemodel/tst_qqmldelegatemodel.cpp b/qtdeclarative/tests/auto/qml/qqmldelegatemodel/tst_qqmldelegatemodel.cpp
+index 35f1e2c94d..1722447830 100644
+--- a/qtdeclarative/tests/auto/qml/qqmldelegatemodel/tst_qqmldelegatemodel.cpp
++++ b/qtdeclarative/tests/auto/qml/qqmldelegatemodel/tst_qqmldelegatemodel.cpp
+@@ -27,6 +27,8 @@
+ ****************************************************************************/
+
+ #include <QtTest/qtest.h>
++#include <QtCore/QConcatenateTablesProxyModel>
++#include <QtGui/QStandardItemModel>
+ #include <QtQml/qqmlcomponent.h>
+ #include <QtQmlModels/private/qqmldelegatemodel_p.h>
+ #include <QtQuick/qquickview.h>
+@@ -47,6 +49,7 @@ private slots:
+ void filterOnGroup_removeWhenCompleted();
+ void qtbug_86017();
+ void contextAccessedByHandler();
++ void redrawUponColumnChange();
+ };
+
+ class AbstractItemModel : public QAbstractItemModel
+@@ -186,6 +189,30 @@ void tst_QQmlDelegateModel::contextAccessedByHandler()
+ QVERIFY(root->property("works").toBool());
+ }
+
++void tst_QQmlDelegateModel::redrawUponColumnChange()
++{
++ QStandardItemModel m1;
++ m1.appendRow({
++ new QStandardItem("Banana"),
++ new QStandardItem("Coconut"),
++ });
++
++ QQuickView view(testFileUrl("redrawUponColumnChange.qml"));
++ QCOMPARE(view.status(), QQuickView::Ready);
++ view.show();
++ QQuickItem *root = view.rootObject();
++ root->setProperty("model", QVariant::fromValue<QObject *>(&m1));
++
++ QObject *item = root->property("currentItem").value<QObject *>();
++ QVERIFY(item);
++ QCOMPARE(item->property("text").toString(), "Banana");
++
++ QVERIFY(root);
++ m1.removeColumn(0);
++
++ QCOMPARE(item->property("text").toString(), "Coconut");
++}
++
+ QTEST_MAIN(tst_QQmlDelegateModel)
+
+ #include "tst_qqmldelegatemodel.moc"
+diff --git a/qtdeclarative/tests/auto/qml/qv4mm/tst_qv4mm.cpp b/qtdeclarative/tests/auto/qml/qv4mm/tst_qv4mm.cpp
+index 5d635aa63b..824fd89e5b 100644
+--- a/qtdeclarative/tests/auto/qml/qv4mm/tst_qv4mm.cpp
++++ b/qtdeclarative/tests/auto/qml/qv4mm/tst_qv4mm.cpp
+@@ -76,10 +76,10 @@ void tst_qv4mm::multiWrappedQObjects()
+ QCOMPARE(engine1.memoryManager->m_pendingFreedObjectWrapperValue.size(), 1);
+ QCOMPARE(engine2.memoryManager->m_pendingFreedObjectWrapperValue.size(), 0);
+
+- // Moves the additional WeakValue from m_multiplyWrappedQObjects to
+- // m_pendingFreedObjectWrapperValue. It's still alive after all.
++ // The additional WeakValue from m_multiplyWrappedQObjects hasn't been moved
++ // to m_pendingFreedObjectWrapperValue yet. It's still alive after all.
+ engine1.memoryManager->runGC();
+- QCOMPARE(engine1.memoryManager->m_pendingFreedObjectWrapperValue.size(), 2);
++ QCOMPARE(engine1.memoryManager->m_pendingFreedObjectWrapperValue.size(), 1);
+
+ // engine2 doesn't own the object as engine1 was the first to wrap it above.
+ // Therefore, no effect here.
+diff --git a/qtdeclarative/tests/auto/quick/qquickitem2/data/activeFocusOnTab_infiniteLoop3.qml b/qtdeclarative/tests/auto/quick/qquickitem2/data/activeFocusOnTab_infiniteLoop3.qml
+new file mode 100644
+index 0000000000..889e480f3b
+--- /dev/null
++++ b/qtdeclarative/tests/auto/quick/qquickitem2/data/activeFocusOnTab_infiniteLoop3.qml
+@@ -0,0 +1,13 @@
++import QtQuick 2.6
++
++Item {
++ visible: true
++ Item {
++ visible: false
++ Item {
++ objectName: "hiddenChild"
++ activeFocusOnTab: true
++ focus: true
++ }
++ }
++}
+diff --git a/qtdeclarative/tests/auto/quick/qquickitem2/tst_qquickitem.cpp b/qtdeclarative/tests/auto/quick/qquickitem2/tst_qquickitem.cpp
+index c8f251dbe1..c8ef36ee68 100644
+--- a/qtdeclarative/tests/auto/quick/qquickitem2/tst_qquickitem.cpp
++++ b/qtdeclarative/tests/auto/quick/qquickitem2/tst_qquickitem.cpp
+@@ -67,6 +67,7 @@ private slots:
+ void activeFocusOnTab10();
+ void activeFocusOnTab_infiniteLoop_data();
+ void activeFocusOnTab_infiniteLoop();
++ void activeFocusOnTab_infiniteLoopControls();
+
+ void nextItemInFocusChain();
+ void nextItemInFocusChain2();
+@@ -1057,6 +1058,17 @@ void tst_QQuickItem::activeFocusOnTab_infiniteLoop()
+ QCOMPARE(item, window->rootObject());
+ }
+
++
++void tst_QQuickItem::activeFocusOnTab_infiniteLoopControls()
++{
++ auto source = testFileUrl("activeFocusOnTab_infiniteLoop3.qml");
++ QScopedPointer<QQuickView>window(new QQuickView());
++ window->setSource(source);
++ window->show();
++ QVERIFY(window->errors().isEmpty());
++ QTest::keyClick(window.get(), Qt::Key_Tab); // should not hang
++}
++
+ void tst_QQuickItem::nextItemInFocusChain()
+ {
+ if (!qt_tab_all_widgets())
+Submodule qtdoc c0c7bf07...79d6ef69:
+Submodule qtimageformats 2dcf2899..abe44c0f:
+diff --git a/qtimageformats/src/plugins/imageformats/icns/qicnshandler.cpp b/qtimageformats/src/plugins/imageformats/icns/qicnshandler.cpp
+index dde783c..1bf9074 100644
+--- a/qtimageformats/src/plugins/imageformats/icns/qicnshandler.cpp
++++ b/qtimageformats/src/plugins/imageformats/icns/qicnshandler.cpp
+@@ -462,8 +462,12 @@ static bool parseIconEntryInfo(ICNSEntry &icon)
+ if (isIconCompressed(icon))
+ return true;
+ // Icon depth:
+- if (!depth.isEmpty())
+- icon.depth = ICNSEntry::Depth(depth.toUInt());
++ if (!depth.isEmpty()) {
++ const uint depthUInt = depth.toUInt();
++ if (depthUInt > 32)
++ return false;
++ icon.depth = ICNSEntry::Depth(depthUInt);
++ }
+ // Try mono if depth not found
+ if (icon.depth == ICNSEntry::DepthUnknown)
+ icon.depth = ICNSEntry::DepthMono;
+@@ -515,6 +519,9 @@ static bool parseIconEntryInfo(ICNSEntry &icon)
+ }
+ icon.height = icon.width;
+ }
++ // Sanity check
++ if (icon.width == 0 || icon.width > 4096)
++ return false;
+ return true;
+ }
+
+@@ -685,7 +692,7 @@ bool QICNSHandler::canRead() const
+ bool QICNSHandler::read(QImage *outImage)
+ {
+ QImage img;
+- if (!ensureScanned()) {
++ if (!ensureScanned() || m_currentIconIndex >= m_icons.size()) {
+ qWarning("QICNSHandler::read(): The device wasn't parsed properly!");
+ return false;
+ }
+@@ -892,7 +899,7 @@ bool QICNSHandler::scanDevice()
+ return false;
+
+ const qint64 blockDataOffset = device()->pos();
+- if (!isBlockHeaderValid(blockHeader)) {
++ if (!isBlockHeaderValid(blockHeader, ICNSBlockHeaderSize + filelength - blockDataOffset)) {
+ qWarning("QICNSHandler::scanDevice(): Failed, bad header at pos %s. OSType \"%s\", length %u",
+ QByteArray::number(blockDataOffset).constData(),
+ nameFromOSType(blockHeader.ostype).constData(), blockHeader.length);
+@@ -927,11 +934,14 @@ bool QICNSHandler::scanDevice()
+ case ICNSBlockHeader::TypeOdrp:
+ // Icns container seems to have an embedded icon variant container
+ // Let's start a scan for entries
+- while (device()->pos() < nextBlockOffset) {
++ while (!stream.atEnd() && device()->pos() < nextBlockOffset) {
+ ICNSBlockHeader icon;
+ stream >> icon;
++ if (stream.status() != QDataStream::Ok)
++ return false;
+ // Check for incorrect variant entry header and stop scan
+- if (!isBlockHeaderValid(icon, blockDataLength))
++ quint64 remaining = blockDataLength - (device()->pos() - blockDataOffset);
++ if (!isBlockHeaderValid(icon, ICNSBlockHeaderSize + remaining))
+ break;
+ if (!addEntry(icon, device()->pos(), blockHeader.ostype))
+ return false;
+@@ -1003,7 +1013,7 @@ bool QICNSHandler::scanDevice()
+ break;
+ }
+ }
+- return true;
++ return (m_icons.size() > 0);
+ }
+
+ const ICNSEntry &QICNSHandler::getIconMask(const ICNSEntry &icon) const
+diff --git a/qtimageformats/src/plugins/imageformats/jp2/qjp2handler.cpp b/qtimageformats/src/plugins/imageformats/jp2/qjp2handler.cpp
+index 5082023..cb34374 100644
+--- a/qtimageformats/src/plugins/imageformats/jp2/qjp2handler.cpp
++++ b/qtimageformats/src/plugins/imageformats/jp2/qjp2handler.cpp
+@@ -43,6 +43,7 @@
+ #include "qimage.h"
+ #include "qvariant.h"
+ #include "qcolor.h"
++#include "qimagereader.h"
+
+ #include <jasper/jasper.h>
+ #include <math.h> // for pow
+@@ -333,16 +334,46 @@ private:
+ Jpeg2000JasperReader::Jpeg2000JasperReader(QIODevice *iod, SubFormat format)
+ : jasperOk(true), ioDevice(iod), format(format), hasAlpha(false)
+ {
++#if JAS_VERSION_MAJOR < 3
+ if (jas_init()) {
+ jasperOk = false;
+ qDebug("Jasper Library initialization failed");
+ }
++#else
++ jas_conf_clear();
++#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
++ jas_conf_set_max_mem_usage(QImageReader::allocationLimit() * 1024 * 1024);
++#else
++ // 128MB seems to be enough.
++ jas_conf_set_max_mem_usage(128 * 1024 * 1024);
++#endif
++ if (jas_init_library()) {
++ jasperOk = false;
++ qDebug("Jasper library initialization failed");
++ }
++ if (jas_init_thread()) {
++ jas_cleanup_library();
++ jasperOk = false;
++ qDebug("Jasper thread initialization failed");
++ }
++#endif
+ }
+
+ Jpeg2000JasperReader::~Jpeg2000JasperReader()
+ {
++#if JAS_VERSION_MAJOR < 3
+ if (jasperOk)
+ jas_cleanup();
++#else
++ if (jasperOk) {
++ if (jas_cleanup_thread()) {
++ qDebug("Jasper thread cleanup failed");
++ }
++ if (jas_cleanup_library()) {
++ qDebug("Jasper library cleanup failed");
++ }
++ }
++#endif
+ }
+
+ /*! \internal
+@@ -857,7 +888,7 @@ bool Jpeg2000JasperReader::write(const QImage &image, int quality)
+ }
+
+ // Open an empty jasper stream that grows automatically
+- jas_stream_t * memory_stream = jas_stream_memopen(0, -1);
++ jas_stream_t * memory_stream = jas_stream_memopen(0, 0);
+
+ // Jasper wants a non-const string.
+ char *str = qstrdup(jasperFormatString.toLatin1().constData());
+diff --git a/qtimageformats/src/plugins/imageformats/tiff/qtiffhandler.cpp b/qtimageformats/src/plugins/imageformats/tiff/qtiffhandler.cpp
+index 1386750..ac8956c 100644
+--- a/qtimageformats/src/plugins/imageformats/tiff/qtiffhandler.cpp
++++ b/qtimageformats/src/plugins/imageformats/tiff/qtiffhandler.cpp
+@@ -361,6 +361,8 @@ bool QTiffHandler::read(QImage *image)
+ }
+
+ TIFF *const tiff = d->tiff;
++ if (TIFFIsTiled(tiff) && TIFFTileSize64(tiff) > uint64_t(image->sizeInBytes())) // Corrupt image
++ return false;
+ const quint32 width = d->size.width();
+ const quint32 height = d->size.height();
+
+diff --git a/qtimageformats/src/plugins/imageformats/webp/qwebphandler.cpp b/qtimageformats/src/plugins/imageformats/webp/qwebphandler.cpp
+index 82d38cb..d02eb05 100644
+--- a/qtimageformats/src/plugins/imageformats/webp/qwebphandler.cpp
++++ b/qtimageformats/src/plugins/imageformats/webp/qwebphandler.cpp
+@@ -45,6 +45,7 @@
+ #include <qdebug.h>
+ #include <qpainter.h>
+ #include <qvariant.h>
++#include <QtEndian>
+
+ static const int riffHeaderSize = 12; // RIFF_HEADER_SIZE from webp/format_constants.h
+
+@@ -102,21 +103,23 @@ bool QWebpHandler::ensureScanned() const
+
+ m_scanState = ScanError;
+
+- if (device()->isSequential()) {
+- qWarning() << "Sequential devices are not supported";
++ QWebpHandler *that = const_cast<QWebpHandler *>(this);
++ const int headerBytesNeeded = sizeof(WebPBitstreamFeatures);
++ QByteArray header = device()->peek(headerBytesNeeded);
++ if (header.size() < headerBytesNeeded)
+ return false;
+- }
+
+- qint64 oldPos = device()->pos();
+- device()->seek(0);
+-
+- QWebpHandler *that = const_cast<QWebpHandler *>(this);
+- QByteArray header = device()->peek(sizeof(WebPBitstreamFeatures));
++ // We do no random access during decoding, just a readAll() of the whole image file. So if
++ // if it is all available already, we can accept a sequential device. The riff header contains
++ // the file size minus 8 bytes header
++ qint64 byteSize = qFromLittleEndian<quint32>(header.constData() + 4);
++ if (device()->isSequential() && device()->bytesAvailable() < byteSize + 8) {
++ qWarning() << "QWebpHandler: Insufficient data available in sequential device";
++ return false;
++ }
+ if (WebPGetFeatures((const uint8_t*)header.constData(), header.size(), &(that->m_features)) == VP8_STATUS_OK) {
+ if (m_features.has_animation) {
+ // For animation, we have to read and scan whole file to determine loop count and images count
+- device()->seek(oldPos);
+-
+ if (that->ensureDemuxer()) {
+ that->m_loop = WebPDemuxGetI(m_demuxer, WEBP_FF_LOOP_COUNT);
+ that->m_frameCount = WebPDemuxGetI(m_demuxer, WEBP_FF_FRAME_COUNT);
+@@ -126,17 +129,13 @@ bool QWebpHandler::ensureScanned() const
+ if (that->m_features.has_alpha)
+ that->m_composited->fill(Qt::transparent);
+
+- // We do not reset device position since we have read in all data
+ m_scanState = ScanSuccess;
+- return true;
+ }
+ } else {
+ m_scanState = ScanSuccess;
+ }
+ }
+
+- device()->seek(oldPos);
+-
+ return m_scanState == ScanSuccess;
+ }
+
+@@ -159,7 +158,7 @@ bool QWebpHandler::ensureDemuxer()
+
+ bool QWebpHandler::read(QImage *image)
+ {
+- if (!ensureScanned() || device()->isSequential() || !ensureDemuxer())
++ if (!ensureScanned() || !ensureDemuxer())
+ return false;
+
+ QRect prevFrameRect;
+Submodule qtlocation 98a5c511..f991e28c:
+diff --git a/qtlocation/src/location/configure.json b/qtlocation/src/location/configure.json
+index 6d01a9a3..d1e623a1 100644
+--- a/qtlocation/src/location/configure.json
++++ b/qtlocation/src/location/configure.json
+@@ -9,7 +9,7 @@
+ "label": "Qt.labs.location experimental QML plugin",
+ "purpose": "Provides experimental QtLocation QML types",
+ "section": "Location",
+- "condition": "config.opengl",
++ "condition": "features.opengl",
+ "output": [ "privateFeature" ]
+ },
+ "geoservices_osm": {
+diff --git a/qtlocation/src/location/labs/qsg/qgeomapobjectqsgsupport.cpp b/qtlocation/src/location/labs/qsg/qgeomapobjectqsgsupport.cpp
+index a978573d..11e1466f 100644
+--- a/qtlocation/src/location/labs/qsg/qgeomapobjectqsgsupport.cpp
++++ b/qtlocation/src/location/labs/qsg/qgeomapobjectqsgsupport.cpp
+@@ -158,7 +158,7 @@ void QGeoMapObjectQSGSupport::updateMapObjects(QSGNode *root, QQuickWindow *wind
+ if (!root)
+ return;
+
+- if (m_mapObjectsRootNode && m_mapObjectsRootNode->parent())
++ if (m_mapObjectsRootNode && !m_mapObjectsRootNode->parent())
+ root->appendChildNode(m_mapObjectsRootNode.get());
+
+ if (!m_mapObjectsRootNode) {
+diff --git a/qtlocation/src/plugins/geoservices/esri/geocodingmanagerengine_esri.cpp b/qtlocation/src/plugins/geoservices/esri/geocodingmanagerengine_esri.cpp
+index 5a40467e..d123c6a8 100644
+--- a/qtlocation/src/plugins/geoservices/esri/geocodingmanagerengine_esri.cpp
++++ b/qtlocation/src/plugins/geoservices/esri/geocodingmanagerengine_esri.cpp
+@@ -59,8 +59,10 @@ QT_BEGIN_NAMESPACE
+ static const QString kPrefixEsri(QStringLiteral("esri."));
+ static const QString kParamUserAgent(kPrefixEsri + QStringLiteral("useragent"));
+
+-static const QString kUrlGeocode(QStringLiteral("http://geocode.arcgis.com/arcgis/rest/services/World/GeocodeServer/findAddressCandidates"));
+-static const QString kUrlReverseGeocode(QStringLiteral("http://geocode.arcgis.com/arcgis/rest/services/World/GeocodeServer/reverseGeocode"));
++static const QString kUrlGeocode(QStringLiteral("https://geocode.arcgis.com/arcgis/rest/services/"
++ "World/GeocodeServer/findAddressCandidates"));
++static const QString kUrlReverseGeocode(QStringLiteral(
++ "https://geocode.arcgis.com/arcgis/rest/services/World/GeocodeServer/reverseGeocode"));
+
+ static QString addressToQuery(const QGeoAddress &address)
+ {
+diff --git a/qtlocation/src/plugins/geoservices/esri/georoutejsonparser_esri.cpp b/qtlocation/src/plugins/geoservices/esri/georoutejsonparser_esri.cpp
+index 17492d94..96c12b1b 100644
+--- a/qtlocation/src/plugins/geoservices/esri/georoutejsonparser_esri.cpp
++++ b/qtlocation/src/plugins/geoservices/esri/georoutejsonparser_esri.cpp
+@@ -46,7 +46,8 @@
+
+ QT_BEGIN_NAMESPACE
+
+-// JSON reference: http://resources.arcgis.com/en/help/arcgis-rest-api/#/Route_service_with_synchronous_execution/02r300000036000000/
++// JSON reference:
++// https://resources.arcgis.com/en/help/arcgis-rest-api/#/Route_service_with_synchronous_execution/02r300000036000000/
+
+ static const QString kErrorMessage(QStringLiteral("Error %1: %2."));
+ static const QString kErrorJson(QStringLiteral("Error: invalide JSON document."));
+diff --git a/qtlocation/src/plugins/geoservices/esri/georoutereply_esri.cpp b/qtlocation/src/plugins/geoservices/esri/georoutereply_esri.cpp
+index 8cadfb29..92b6bb13 100644
+--- a/qtlocation/src/plugins/geoservices/esri/georoutereply_esri.cpp
++++ b/qtlocation/src/plugins/geoservices/esri/georoutereply_esri.cpp
+@@ -44,7 +44,8 @@
+
+ QT_BEGIN_NAMESPACE
+
+-// JSON reference: http://resources.arcgis.com/en/help/arcgis-rest-api/#/Route_service_with_synchronous_execution/02r300000036000000/
++// JSON reference:
++// https://resources.arcgis.com/en/help/arcgis-rest-api/#/Route_service_with_synchronous_execution/02r300000036000000/
+
+ GeoRouteReplyEsri::GeoRouteReplyEsri(QNetworkReply *reply, const QGeoRouteRequest &request,
+ QObject *parent) :
+diff --git a/qtlocation/src/plugins/geoservices/esri/georoutingmanagerengine_esri.cpp b/qtlocation/src/plugins/geoservices/esri/georoutingmanagerengine_esri.cpp
+index 0e6bc2c7..ed613f4b 100644
+--- a/qtlocation/src/plugins/geoservices/esri/georoutingmanagerengine_esri.cpp
++++ b/qtlocation/src/plugins/geoservices/esri/georoutingmanagerengine_esri.cpp
+@@ -48,7 +48,8 @@ static const QString kPrefixEsri(QStringLiteral("esri."));
+ static const QString kParamUserAgent(kPrefixEsri + QStringLiteral("useragent"));
+ static const QString kParamToken(kPrefixEsri + QStringLiteral("token"));
+
+-static const QString kUrlRouting(QStringLiteral("http://route.arcgis.com/arcgis/rest/services/World/Route/NAServer/Route_World/solve"));
++static const QString kUrlRouting(QStringLiteral(
++ "https://route.arcgis.com/arcgis/rest/services/World/Route/NAServer/Route_World/solve"));
+
+ GeoRoutingManagerEngineEsri::GeoRoutingManagerEngineEsri(const QVariantMap ¶meters,
+ QGeoServiceProvider::Error *error,
+@@ -70,7 +71,8 @@ GeoRoutingManagerEngineEsri::~GeoRoutingManagerEngineEsri()
+ {
+ }
+
+-// REST reference: http://resources.arcgis.com/en/help/arcgis-rest-api/index.html#//02r300000036000000
++// REST reference:
++// https://resources.arcgis.com/en/help/arcgis-rest-api/index.html#//02r300000036000000
+
+ QGeoRouteReply *GeoRoutingManagerEngineEsri::calculateRoute(const QGeoRouteRequest &request)
+ {
+@@ -125,7 +127,7 @@ void GeoRoutingManagerEngineEsri::replyError(QGeoRouteReply::Error errorCode, co
+ QString GeoRoutingManagerEngineEsri::preferedDirectionLangage()
+ {
+ // list of supported langages is defined in:
+- // http://resources.arcgis.com/en/help/arcgis-rest-api/index.html#//02r300000036000000
++ // https://resources.arcgis.com/en/help/arcgis-rest-api/index.html#//02r300000036000000
+ const QStringList supportedLanguages = {
+ "ar", // Generate directions in Arabic
+ "cs", // Generate directions in Czech
+diff --git a/qtlocation/src/plugins/geoservices/esri/geotiledmappingmanagerengine_esri.cpp b/qtlocation/src/plugins/geoservices/esri/geotiledmappingmanagerengine_esri.cpp
+index 5d15835d..24148f95 100644
+--- a/qtlocation/src/plugins/geoservices/esri/geotiledmappingmanagerengine_esri.cpp
++++ b/qtlocation/src/plugins/geoservices/esri/geotiledmappingmanagerengine_esri.cpp
+@@ -230,7 +230,8 @@ QGeoMap *GeoTiledMappingManagerEngineEsri::createMap()
+ // ${y} = Y
+ // ${token} = Token
+
+-// template = 'http://services.arcgisonline.com/ArcGIS/rest/services/World_Topo_Map/MapServer/tile/{{z}}/{{y}}/{{x}}.png'
++// template =
++// 'https://services.arcgisonline.com/ArcGIS/rest/services/World_Topo_Map/MapServer/tile/{{z}}/{{y}}/{{x}}.png'
+
+ bool GeoTiledMappingManagerEngineEsri::initializeMapSources(QGeoServiceProvider::Error *error,
+ QString *errorString,
+diff --git a/qtlocation/src/plugins/geoservices/esri/maps.json b/qtlocation/src/plugins/geoservices/esri/maps.json
+index 8167ae7d..862e087d 100644
+--- a/qtlocation/src/plugins/geoservices/esri/maps.json
++++ b/qtlocation/src/plugins/geoservices/esri/maps.json
+@@ -6,8 +6,8 @@
+ "description": "ArcGIS Online World Street Map",
+ "mobile": true,
+ "night": false,
+- "url": "http://services.arcgisonline.com/ArcGIS/rest/services/World_Street_Map/MapServer",
+- "copyrightText": "© <a href='http://www.arcgis.com/home/item.html?id=3b93337983e9436f8db950e38a8629af'>Esri</a> contributors"
++ "url": "https://services.arcgisonline.com/ArcGIS/rest/services/World_Street_Map/MapServer",
++ "copyrightText": "© <a href='https://www.arcgis.com/home/item.html?id=3b93337983e9436f8db950e38a8629af'>Esri</a> contributors"
+ },
+
+ {
+@@ -16,8 +16,8 @@
+ "": "ArcGIS Online World Imagery",
+ "mobile": true,
+ "night": false,
+- "url": "http://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer",
+- "copyrightText": "© <a href='http://www.arcgis.com/home/item.html?id=10df2279f9684e4a9f6a7f08febac2a9'>Esri</a> contributors"
++ "url": "https://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer",
++ "copyrightText": "© <a href='https://www.arcgis.com/home/item.html?id=10df2279f9684e4a9f6a7f08febac2a9'>Esri</a> contributors"
+ },
+
+ {
+@@ -26,8 +26,8 @@
+ "description": "ArcGIS Online World Terrain Base",
+ "mobile": false,
+ "night": false,
+- "url": "http://server.arcgisonline.com/ArcGIS/rest/services/World_Terrain_Base/MapServer",
+- "copyrightText": "© <a href='http://www.arcgis.com/home/item.html?id=c61ad8ab017d49e1a82f580ee1298931'>Esri</a> contributors"
++ "url": "https://server.arcgisonline.com/ArcGIS/rest/services/World_Terrain_Base/MapServer",
++ "copyrightText": "© <a href='https://www.arcgis.com/home/item.html?id=c61ad8ab017d49e1a82f580ee1298931'>Esri</a> contributors"
+ },
+
+ {
+@@ -36,8 +36,8 @@
+ "description": "ArcGIS Online World Topography",
+ "mobile": true,
+ "night": false,
+- "url": "http://server.arcgisonline.com/ArcGIS/rest/services/World_Topo_Map/MapServer",
+- "copyrightText": "© <a href='http://www.arcgis.com/home/item.html?id=30e5fe3149c34df1ba922e6f5bbf808f'>Esri</a> contributors"
++ "url": "https://server.arcgisonline.com/ArcGIS/rest/services/World_Topo_Map/MapServer",
++ "copyrightText": "© <a href='https://www.arcgis.com/home/item.html?id=30e5fe3149c34df1ba922e6f5bbf808f'>Esri</a> contributors"
+ },
+
+ {
+@@ -46,8 +46,8 @@
+ "description": "This map presents land cover and detailed topographic maps for the United States.",
+ "mobile": true,
+ "night": false,
+- "url": "http://services.arcgisonline.com/ArcGIS/rest/services/USA_Topo_Maps/MapServer",
+- "copyrightText": "© <a href='http://www.arcgis.com/home/item.html?id=99cd5fbd98934028802b4f797c4b1732'>Esri</a> contributors"
++ "url": "https://services.arcgisonline.com/ArcGIS/rest/services/USA_Topo_Maps/MapServer",
++ "copyrightText": "© <a href='https://www.arcgis.com/home/item.html?id=99cd5fbd98934028802b4f797c4b1732'>Esri</a> contributors"
+ },
+
+ {
+@@ -56,8 +56,8 @@
+ "description": "National Geographic World Map",
+ "mobile": false,
+ "night": false,
+- "url": "http://services.arcgisonline.com/ArcGIS/rest/services/NatGeo_World_Map/MapServer",
+- "copyrightText": "© <a href='http://www.arcgis.com/home/item.html?id=b9b1b422198944fbbd5250b3241691b6'>Esri</a> contributors"
++ "url": "https://services.arcgisonline.com/ArcGIS/rest/services/NatGeo_World_Map/MapServer",
++ "copyrightText": "© <a href='https://www.arcgis.com/home/item.html?id=b9b1b422198944fbbd5250b3241691b6'>Esri</a> contributors"
+ },
+
+ {
+@@ -66,8 +66,8 @@
+ "description": "Thematic content providing a neutral background with minimal colors",
+ "mobile": true,
+ "night": false,
+- "url": "http://services.arcgisonline.com/ArcGIS/rest/services/Canvas/World_Light_Gray_Base/MapServer",
+- "copyrightText": "© <a href='http://www.arcgis.com/home/item.html?id=ed712cb1db3e4bae9e85329040fb9a49'>Esri</a> contributors"
++ "url": "https://services.arcgisonline.com/ArcGIS/rest/services/Canvas/World_Light_Gray_Base/MapServer",
++ "copyrightText": "© <a href='https://www.arcgis.com/home/item.html?id=ed712cb1db3e4bae9e85329040fb9a49'>Esri</a> contributors"
+ },
+
+ {
+@@ -76,8 +76,8 @@
+ "description": "Natural Earth physical map for the world",
+ "mobile": false,
+ "night": false,
+- "url": "http://server.arcgisonline.com/ArcGIS/rest/services/World_Physical_Map/MapServer",
+- "copyrightText": "© <a href='http://www.arcgis.com/home/item.html?id=c4ec722a1cd34cf0a23904aadf8923a0'>Esri</a> contributors"
++ "url": "https://server.arcgisonline.com/ArcGIS/rest/services/World_Physical_Map/MapServer",
++ "copyrightText": "© <a href='https://www.arcgis.com/home/item.html?id=c4ec722a1cd34cf0a23904aadf8923a0'>Esri</a> contributors"
+ },
+
+ {
+@@ -86,8 +86,8 @@
+ "description": "Portrays surface elevation as shaded relief",
+ "mobile": false,
+ "night": false,
+- "url": "http://server.arcgisonline.com/ArcGIS/rest/services/World_Shaded_Relief/MapServer",
+- "copyrightText": "© <a href='http://www.arcgis.com/home/item.html?id=9c5370d0b54f4de1b48a3792d7377ff2'>Esri</a> contributors"
++ "url": "https://server.arcgisonline.com/ArcGIS/rest/services/World_Shaded_Relief/MapServer",
++ "copyrightText": "© <a href='https://www.arcgis.com/home/item.html?id=9c5370d0b54f4de1b48a3792d7377ff2'>Esri</a> contributors"
+ },
+
+ {
+@@ -96,8 +96,8 @@
+ "description": "This map is designed to be used as a basemap by marine GIS professionals and as a reference map by anyone interested in ocean data",
+ "mobile": false,
+ "night": false,
+- "url": "http://server.arcgisonline.com/arcgis/rest/services/Ocean/World_Ocean_Base/MapServer",
+- "copyrightText": "© <a href='http://www.arcgis.com/home/item.html?id=1e126e7520f9466c9ca28b8f28b5e500'>Esri</a> contributors"
++ "url": "https://server.arcgisonline.com/arcgis/rest/services/Ocean/World_Ocean_Base/MapServer",
++ "copyrightText": "© <a href='https://www.arcgis.com/home/item.html?id=1e126e7520f9466c9ca28b8f28b5e500'>Esri</a> contributors"
+ },
+
+ {
+@@ -106,8 +106,8 @@
+ "description": "Thematic content providing a neutral background with minimal colors",
+ "mobile": false,
+ "night": true,
+- "url": "http://services.arcgisonline.com/ArcGIS/rest/services/Canvas/World_Dark_Gray_Base/MapServer",
+- "copyrightText": "© <a href='http://www.arcgis.com/home/item.html?id=a284a9b99b3446a3910d4144a50990f6'>Esri</a> contributors"
++ "url": "https://services.arcgisonline.com/ArcGIS/rest/services/Canvas/World_Dark_Gray_Base/MapServer",
++ "copyrightText": "© <a href='https://www.arcgis.com/home/item.html?id=a284a9b99b3446a3910d4144a50990f6'>Esri</a> contributors"
+ },
+
+ {
+@@ -116,8 +116,8 @@
+ "description": "DeLorme’s topographic basemap is a seamless global data set that portrays transportation, hydrography, jurisdiction boundaries, and major geographic features",
+ "mobile": false,
+ "night": false,
+- "url": "http://server.arcgisonline.com/ArcGIS/rest/services/Specialty/DeLorme_World_Base_Map/MapServer",
+- "copyrightText": "© <a href='http://www.arcgis.com/home/item.html?id=b165c3df453e4be6b5ac4fdb241effbe'>Esri</a> contributors"
++ "url": "https://server.arcgisonline.com/ArcGIS/rest/services/Specialty/DeLorme_World_Base_Map/MapServer",
++ "copyrightText": "© <a href='https://www.arcgis.com/home/item.html?id=b165c3df453e4be6b5ac4fdb241effbe'>Esri</a> contributors"
+ }
+ ]
+ }
+diff --git a/qtlocation/src/plugins/geoservices/esri/placemanagerengine_esri.cpp b/qtlocation/src/plugins/geoservices/esri/placemanagerengine_esri.cpp
+index 3858ddf5..af66f28e 100644
+--- a/qtlocation/src/plugins/geoservices/esri/placemanagerengine_esri.cpp
++++ b/qtlocation/src/plugins/geoservices/esri/placemanagerengine_esri.cpp
+@@ -63,8 +63,10 @@ static const QString kCountriesKey(QStringLiteral("detailedCountries"));
+ static const QString kLocalizedNamesKey(QStringLiteral("localizedNames"));
+ static const QString kMaxLocationsKey(QStringLiteral("maxLocations"));
+
+-static const QUrl kUrlGeocodeServer("http://geocode.arcgis.com/arcgis/rest/services/World/GeocodeServer?f=pjson");
+-static const QUrl kUrlFindAddressCandidates("http://geocode.arcgis.com/arcgis/rest/services/World/GeocodeServer/findAddressCandidates");
++static const QUrl kUrlGeocodeServer(
++ "https://geocode.arcgis.com/arcgis/rest/services/World/GeocodeServer?f=pjson");
++static const QUrl kUrlFindAddressCandidates("https://geocode.arcgis.com/arcgis/rest/services/World/"
++ "GeocodeServer/findAddressCandidates");
+
+ PlaceManagerEngineEsri::PlaceManagerEngineEsri(const QVariantMap ¶meters, QGeoServiceProvider::Error *error,
+ QString *errorString) :
+Submodule qtmultimedia f0344079..0d7cc33a:
+diff --git a/qtmultimedia/src/plugins/pulseaudio/qaudioinput_pulse.cpp b/qtmultimedia/src/plugins/pulseaudio/qaudioinput_pulse.cpp
+index 2b5325132..b68b4af1b 100644
+--- a/qtmultimedia/src/plugins/pulseaudio/qaudioinput_pulse.cpp
++++ b/qtmultimedia/src/plugins/pulseaudio/qaudioinput_pulse.cpp
+@@ -402,6 +402,8 @@ int QPulseAudioInput::bytesReady() const
+
+ qint64 QPulseAudioInput::read(char *data, qint64 len)
+ {
++ Q_ASSERT(data != nullptr || len == 0);
++
+ m_bytesAvailable = checkBytesReady();
+
+ setError(QAudio::NoError);
+@@ -411,7 +413,8 @@ qint64 QPulseAudioInput::read(char *data, qint64 len)
+
+ if (!m_pullMode && !m_tempBuffer.isEmpty()) {
+ readBytes = qMin(static_cast<int>(len), m_tempBuffer.size());
+- memcpy(data, m_tempBuffer.constData(), readBytes);
++ if (readBytes)
++ memcpy(data, m_tempBuffer.constData(), readBytes);
+ m_totalTimeValue += readBytes;
+
+ if (readBytes < m_tempBuffer.size()) {
+@@ -502,9 +505,10 @@ qint64 QPulseAudioInput::read(char *data, qint64 len)
+
+ void QPulseAudioInput::applyVolume(const void *src, void *dest, int len)
+ {
++ Q_ASSERT((src && dest) || len == 0);
+ if (m_volume < 1.f)
+ QAudioHelperInternal::qMultiplySamples(m_volume, m_format, src, dest, len);
+- else
++ else if (len)
+ memcpy(dest, src, len);
+ }
+
+Submodule qtpim 02efef5e...f9a8f0fc (commits not present)
+Submodule qtquick3d b85cf622..47defc8b:
+diff --git a/qtquick3d/src/plugins/assetimporters/assimp/assimp.pro b/qtquick3d/src/plugins/assetimporters/assimp/assimp.pro
+index ca5c499e..174a075b 100644
+--- a/qtquick3d/src/plugins/assetimporters/assimp/assimp.pro
++++ b/qtquick3d/src/plugins/assetimporters/assimp/assimp.pro
+@@ -10,7 +10,7 @@ QT_FOR_CONFIG += assetimporters-private
+ include($$OUT_PWD/../qtassetimporters-config.pri)
+
+ qtConfig(system-assimp):!if(cross_compile:host_build) {
+- QMAKE_USE_PRIVATE += assimp
++ QMAKE_USE_PRIVATE += quick3d-assimp
+ } else {
+ include(../../../3rdparty/assimp/assimp.pri)
+ }
+Submodule qtquickcontrols2 3a657dc0..56ce8233:
+diff --git a/qtquickcontrols2/src/imports/platform/widgets/qwidgetplatformmenu.cpp b/qtquickcontrols2/src/imports/platform/widgets/qwidgetplatformmenu.cpp
+index e5fe734f7..e36922775 100644
+--- a/qtquickcontrols2/src/imports/platform/widgets/qwidgetplatformmenu.cpp
++++ b/qtquickcontrols2/src/imports/platform/widgets/qwidgetplatformmenu.cpp
+@@ -38,6 +38,7 @@
+ #include "qwidgetplatformmenuitem_p.h"
+
+ #include <QtGui/qwindow.h>
++#include <QtGui/private/qhighdpiscaling_p.h>
+ #include <QtWidgets/qmenu.h>
+ #include <QtWidgets/qaction.h>
+
+@@ -145,7 +146,7 @@ void QWidgetPlatformMenu::showPopup(const QWindow *window, const QRect &targetRe
+
+ QPoint targetPos = targetRect.bottomLeft();
+ if (window)
+- targetPos = window->mapToGlobal(targetPos);
++ targetPos = window->mapToGlobal(QHighDpi::fromNativeLocalPosition(targetPos, window));
+
+ const QWidgetPlatformMenuItem *widgetItem = qobject_cast<const QWidgetPlatformMenuItem *>(item);
+ m_menu->popup(targetPos, widgetItem ? widgetItem->action() : nullptr);
+diff --git a/qtquickcontrols2/src/quicktemplates2/qquickabstractbutton.cpp b/qtquickcontrols2/src/quicktemplates2/qquickabstractbutton.cpp
+index 950e4e099..b81fbea0b 100644
+--- a/qtquickcontrols2/src/quicktemplates2/qquickabstractbutton.cpp
++++ b/qtquickcontrols2/src/quicktemplates2/qquickabstractbutton.cpp
+@@ -387,6 +387,17 @@ void QQuickAbstractButtonPrivate::itemImplicitHeightChanged(QQuickItem *item)
+ emit q->implicitIndicatorHeightChanged();
+ }
+
++void QQuickAbstractButtonPrivate::itemDestroyed(QQuickItem *item)
++{
++ Q_Q(QQuickAbstractButton);
++ QQuickControlPrivate::itemDestroyed(item);
++ if (item == indicator) {
++ indicator = nullptr;
++ emit q->implicitIndicatorWidthChanged();
++ emit q->implicitIndicatorHeightChanged();
++ }
++}
++
+ QQuickAbstractButton *QQuickAbstractButtonPrivate::findCheckedButton() const
+ {
+ Q_Q(const QQuickAbstractButton);
+@@ -1176,6 +1187,12 @@ QAccessible::Role QQuickAbstractButton::accessibleRole() const
+ }
+ return QAccessible::Button;
+ }
++
++void QQuickAbstractButton::accessiblePressAction()
++{
++ Q_D(QQuickAbstractButton);
++ d->trigger();
++}
+ #endif
+
+ QT_END_NAMESPACE
+diff --git a/qtquickcontrols2/src/quicktemplates2/qquickabstractbutton_p.h b/qtquickcontrols2/src/quicktemplates2/qquickabstractbutton_p.h
+index 0fa48980e..ab66220d0 100644
+--- a/qtquickcontrols2/src/quicktemplates2/qquickabstractbutton_p.h
++++ b/qtquickcontrols2/src/quicktemplates2/qquickabstractbutton_p.h
+@@ -209,6 +209,7 @@ protected:
+ #if QT_CONFIG(accessibility)
+ void accessibilityActiveChanged(bool active) override;
+ QAccessible::Role accessibleRole() const override;
++ Q_INVOKABLE void accessiblePressAction();
+ #endif
+
+ private:
+diff --git a/qtquickcontrols2/src/quicktemplates2/qquickabstractbutton_p_p.h b/qtquickcontrols2/src/quicktemplates2/qquickabstractbutton_p_p.h
+index 9291c1a87..b729720f2 100644
+--- a/qtquickcontrols2/src/quicktemplates2/qquickabstractbutton_p_p.h
++++ b/qtquickcontrols2/src/quicktemplates2/qquickabstractbutton_p_p.h
+@@ -109,6 +109,7 @@ public:
+
+ void itemImplicitWidthChanged(QQuickItem *item) override;
+ void itemImplicitHeightChanged(QQuickItem *item) override;
++ void itemDestroyed(QQuickItem *item) override;
+
+ // copied from qabstractbutton.cpp
+ static const int AUTO_REPEAT_DELAY = 300;
+diff --git a/qtquickcontrols2/src/quicktemplates2/qquickaction.cpp b/qtquickcontrols2/src/quicktemplates2/qquickaction.cpp
+index 2041e7741..8610cdfae 100644
+--- a/qtquickcontrols2/src/quicktemplates2/qquickaction.cpp
++++ b/qtquickcontrols2/src/quicktemplates2/qquickaction.cpp
+@@ -145,7 +145,7 @@ int QQuickActionPrivate::ShortcutEntry::shortcutId() const
+
+ void QQuickActionPrivate::ShortcutEntry::grab(const QKeySequence &shortcut, bool enabled)
+ {
+- if (shortcut.isEmpty())
++ if (shortcut.isEmpty() || m_shortcutId)
+ return;
+
+ Qt::ShortcutContext context = Qt::WindowShortcut; // TODO
+diff --git a/qtquickcontrols2/src/quicktemplates2/qquickcontainer.cpp b/qtquickcontrols2/src/quicktemplates2/qquickcontainer.cpp
+index f38c2b09c..6eed2a024 100644
+--- a/qtquickcontrols2/src/quicktemplates2/qquickcontainer.cpp
++++ b/qtquickcontrols2/src/quicktemplates2/qquickcontainer.cpp
+@@ -225,6 +225,7 @@ void QQuickContainerPrivate::cleanup()
+ QObject::disconnect(contentModel, &QQmlObjectModel::countChanged, q, &QQuickContainer::countChanged);
+ QObject::disconnect(contentModel, &QQmlObjectModel::childrenChanged, q, &QQuickContainer::contentChildrenChanged);
+ delete contentModel;
++ contentModel = nullptr;
+ }
+
+ QQuickItem *QQuickContainerPrivate::itemAt(int index) const
+@@ -436,7 +437,7 @@ void QQuickContainerPrivate::contentChildren_clear(QQmlListProperty<QQuickItem>
+ void QQuickContainerPrivate::updateContentWidth()
+ {
+ Q_Q(QQuickContainer);
+- if (hasContentWidth || qFuzzyCompare(contentWidth, implicitContentWidth))
++ if (hasContentWidth || qFuzzyCompare(contentWidth, implicitContentWidth) || !contentModel)
+ return;
+
+ contentWidth = implicitContentWidth;
+@@ -446,7 +447,7 @@ void QQuickContainerPrivate::updateContentWidth()
+ void QQuickContainerPrivate::updateContentHeight()
+ {
+ Q_Q(QQuickContainer);
+- if (hasContentHeight || qFuzzyCompare(contentHeight, implicitContentHeight))
++ if (hasContentHeight || qFuzzyCompare(contentHeight, implicitContentHeight) || !contentModel)
+ return;
+
+ contentHeight = implicitContentHeight;
+diff --git a/qtquickcontrols2/src/quicktemplates2/qquickcontrol.cpp b/qtquickcontrols2/src/quicktemplates2/qquickcontrol.cpp
+index bbbd0e622..1f4b47343 100644
+--- a/qtquickcontrols2/src/quicktemplates2/qquickcontrol.cpp
++++ b/qtquickcontrols2/src/quicktemplates2/qquickcontrol.cpp
+@@ -845,6 +845,13 @@ void QQuickControlPrivate::executeBackground(bool complete)
+ quickCompleteDeferred(q, backgroundName(), background);
+ }
+
++/*
++ \internal
++
++ Hides an item that was replaced by a newer one, rather than
++ deleting it, as the item is typically created in QML and hence
++ we don't own it.
++*/
+ void QQuickControlPrivate::hideOldItem(QQuickItem *item)
+ {
+ if (!item)
+@@ -863,6 +870,29 @@ void QQuickControlPrivate::hideOldItem(QQuickItem *item)
+ #endif
+ }
+
++/*
++ \internal
++
++ Named "unhide" because it's used for cases where an item
++ that was previously hidden by \l hideOldItem() wants to be
++ shown by a control again, such as a ScrollBar in ScrollView.
++*/
++void QQuickControlPrivate::unhideOldItem(QQuickControl *control, QQuickItem *item)
++{
++ Q_ASSERT(item);
++ qCDebug(lcItemManagement) << "unhiding old item" << item;
++
++ item->setVisible(true);
++ item->setParentItem(control);
++
++#if QT_CONFIG(accessibility)
++ // Add the item back in to the accessibility tree.
++ QQuickAccessibleAttached *accessible = accessibleAttached(item);
++ if (accessible)
++ accessible->setIgnored(false);
++#endif
++}
++
+ void QQuickControlPrivate::updateBaselineOffset()
+ {
+ Q_Q(QQuickControl);
+diff --git a/qtquickcontrols2/src/quicktemplates2/qquickcontrol_p_p.h b/qtquickcontrols2/src/quicktemplates2/qquickcontrol_p_p.h
+index 8e979079e..a6e624c91 100644
+--- a/qtquickcontrols2/src/quicktemplates2/qquickcontrol_p_p.h
++++ b/qtquickcontrols2/src/quicktemplates2/qquickcontrol_p_p.h
+@@ -173,6 +173,7 @@ public:
+ virtual void executeBackground(bool complete = false);
+
+ static void hideOldItem(QQuickItem *item);
++ static void unhideOldItem(QQuickControl *control, QQuickItem *item);
+
+ void updateBaselineOffset();
+
+diff --git a/qtquickcontrols2/src/quicktemplates2/qquickdialogbuttonbox.cpp b/qtquickcontrols2/src/quicktemplates2/qquickdialogbuttonbox.cpp
+index e6db14eb5..6197d1547 100644
+--- a/qtquickcontrols2/src/quicktemplates2/qquickdialogbuttonbox.cpp
++++ b/qtquickcontrols2/src/quicktemplates2/qquickdialogbuttonbox.cpp
+@@ -237,7 +237,7 @@ static QRectF alignedRect(Qt::LayoutDirection direction, Qt::Alignment alignment
+ void QQuickDialogButtonBoxPrivate::resizeContent()
+ {
+ Q_Q(QQuickDialogButtonBox);
+- if (!contentItem)
++ if (!contentItem || !contentModel)
+ return;
+
+ QRectF geometry = q->boundingRect().adjusted(q->leftPadding(), q->topPadding(), -q->rightPadding(), -q->bottomPadding());
+@@ -322,6 +322,9 @@ void QQuickDialogButtonBoxPrivate::updateLayout()
+ qreal QQuickDialogButtonBoxPrivate::getContentWidth() const
+ {
+ Q_Q(const QQuickDialogButtonBox);
++ if (!contentModel)
++ return 0;
++
+ const int count = contentModel->count();
+ const qreal totalSpacing = qMax(0, count - 1) * spacing;
+ qreal totalWidth = totalSpacing;
+@@ -341,6 +344,9 @@ qreal QQuickDialogButtonBoxPrivate::getContentWidth() const
+ qreal QQuickDialogButtonBoxPrivate::getContentHeight() const
+ {
+ Q_Q(const QQuickDialogButtonBox);
++ if (!contentModel)
++ return 0;
++
+ const int count = contentModel->count();
+ qreal maxHeight = 0;
+ for (int i = 0; i < count; ++i) {
+diff --git a/qtquickcontrols2/src/quicktemplates2/qquickoverlay.cpp b/qtquickcontrols2/src/quicktemplates2/qquickoverlay.cpp
+index 91bd59184..0ce518f84 100644
+--- a/qtquickcontrols2/src/quicktemplates2/qquickoverlay.cpp
++++ b/qtquickcontrols2/src/quicktemplates2/qquickoverlay.cpp
+@@ -399,8 +399,11 @@ void QQuickOverlay::itemChange(ItemChange change, const ItemChangeData &data)
+ Q_D(QQuickOverlay);
+ QQuickItem::itemChange(change, data);
+
+- if (change == ItemChildAddedChange || change == ItemChildRemovedChange)
++ if (change == ItemChildAddedChange || change == ItemChildRemovedChange) {
+ setVisible(!d->allDrawers.isEmpty() || !childItems().isEmpty());
++ if (data.item->parent() == d->mouseGrabberPopup)
++ d->setMouseGrabberPopup(nullptr);
++ }
+ }
+
+ void QQuickOverlay::geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry)
+diff --git a/qtquickcontrols2/src/quicktemplates2/qquickscrollbar.cpp b/qtquickcontrols2/src/quicktemplates2/qquickscrollbar.cpp
+index 4e2f509db..1c4b308cd 100644
+--- a/qtquickcontrols2/src/quicktemplates2/qquickscrollbar.cpp
++++ b/qtquickcontrols2/src/quicktemplates2/qquickscrollbar.cpp
+@@ -797,6 +797,14 @@ void QQuickScrollBarAttachedPrivate::initHorizontal()
+ if (parent && parent == flickable->parentItem())
+ horizontal->stackAfter(flickable);
+
++ // If a scroll bar was previously hidden (due to e.g. setting a new contentItem
++ // on a ScrollView), we need to make sure that we un-hide it.
++ // We don't bother checking if the item is actually the old one, because
++ // if it's not, all of the things the function does (setting parent, visibility, etc.)
++ // should be no-ops anyway.
++ if (auto control = qobject_cast<QQuickControl*>(q_ptr->parent()))
++ QQuickControlPrivate::unhideOldItem(control, horizontal);
++
+ layoutHorizontal();
+ horizontal->setSize(area->property("widthRatio").toReal());
+ horizontal->setPosition(area->property("xPosition").toReal());
+@@ -818,6 +826,9 @@ void QQuickScrollBarAttachedPrivate::initVertical()
+ if (parent && parent == flickable->parentItem())
+ vertical->stackAfter(flickable);
+
++ if (auto control = qobject_cast<QQuickControl*>(q_ptr->parent()))
++ QQuickControlPrivate::unhideOldItem(control, vertical);
++
+ layoutVertical();
+ vertical->setSize(area->property("heightRatio").toReal());
+ vertical->setPosition(area->property("yPosition").toReal());
+diff --git a/qtquickcontrols2/tests/auto/controls/data/tst_scrollview.qml b/qtquickcontrols2/tests/auto/controls/data/tst_scrollview.qml
+index 0e8b08352..cd4931184 100644
+--- a/qtquickcontrols2/tests/auto/controls/data/tst_scrollview.qml
++++ b/qtquickcontrols2/tests/auto/controls/data/tst_scrollview.qml
+@@ -576,4 +576,51 @@ TestCase {
+ verify(newHorizontalScrollBar.visible)
+ verify(!oldHorizontalScrollBar.visible)
+ }
++
++ Component {
++ id: bindingToContentItemAndStandaloneFlickable
++
++ Item {
++ width: 200
++ height: 200
++
++ property alias scrollView: scrollView
++
++ ScrollView {
++ id: scrollView
++ anchors.fill: parent
++ contentItem: listView
++
++ property Item someBinding: contentItem
++ }
++ ListView {
++ id: listView
++ model: 10
++ delegate: ItemDelegate {
++ text: modelData
++ width: listView.width
++ }
++ }
++ }
++ }
++
++ // Tests that scroll bars show up for a ScrollView where
++ // - its contentItem is declared as a standalone, separate item
++ // - there is a binding to contentItem (which causes a default Flickable to be created)
++ function test_bindingToContentItemAndStandaloneFlickable() {
++ let root = createTemporaryObject(bindingToContentItemAndStandaloneFlickable, testCase)
++ verify(root)
++
++ let control = root.scrollView
++ let verticalScrollBar = control.ScrollBar.vertical
++ let horizontalScrollBar = control.ScrollBar.horizontal
++ compare(verticalScrollBar.parent, control)
++ compare(horizontalScrollBar.parent, control)
++ verify(verticalScrollBar.visible)
++ verify(horizontalScrollBar.visible)
++
++ mouseDrag(verticalScrollBar, verticalScrollBar.width / 2, verticalScrollBar.height / 2, 0, 50)
++ verify(verticalScrollBar.active)
++ verify(horizontalScrollBar.active)
++ }
+ }
+diff --git a/qtquickcontrols2/tests/auto/controls/data/tst_switch.qml b/qtquickcontrols2/tests/auto/controls/data/tst_switch.qml
+index b3fab41ca..10b6baa02 100644
+--- a/qtquickcontrols2/tests/auto/controls/data/tst_switch.qml
++++ b/qtquickcontrols2/tests/auto/controls/data/tst_switch.qml
+@@ -608,4 +608,27 @@ TestCase {
+ mouseClick(control.indicator)
+ verify(control.activeFocus)
+ }
++
++ Component {
++ id: deletionOrder1
++ Item {
++ Image { id: innerImage }
++ Switch { indicator: innerImage }
++ }
++ }
++
++ Component {
++ id: deletionOrder2
++ Item {
++ Switch { indicator: innerImage }
++ Image { id: innerImage }
++ }
++ }
++
++ function test_deletionOrder() {
++ var control1 = createTemporaryObject(deletionOrder1, testCase)
++ verify(control1)
++ var control2 = createTemporaryObject(deletionOrder2, testCase)
++ verify(control2)
++ }
+ }
+diff --git a/qtquickcontrols2/tests/auto/qquickpopup/data/releaseAfterExitTransition.qml b/qtquickcontrols2/tests/auto/qquickpopup/data/releaseAfterExitTransition.qml
+new file mode 100644
+index 000000000..9e4598b9f
+--- /dev/null
++++ b/qtquickcontrols2/tests/auto/qquickpopup/data/releaseAfterExitTransition.qml
+@@ -0,0 +1,78 @@
++/****************************************************************************
++**
++** Copyright (C) 2021 The Qt Company Ltd.
++** Contact: https://www.qt.io/licensing/
++**
++** This file is part of the test suite of the Qt Toolkit.
++**
++** $QT_BEGIN_LICENSE:BSD$
++** Commercial License Usage
++** Licensees holding valid commercial Qt licenses may use this file in
++** accordance with the commercial license agreement provided with the
++** Software or, alternatively, in accordance with the terms contained in
++** a written agreement between you and The Qt Company. For licensing terms
++** and conditions see https://www.qt.io/terms-conditions. For further
++** information use the contact form at https://www.qt.io/contact-us.
++**
++** BSD License Usage
++** Alternatively, you may use this file under the terms of the BSD license
++** as follows:
++**
++** "Redistribution and use in source and binary forms, with or without
++** modification, are permitted provided that the following conditions are
++** met:
++** * Redistributions of source code must retain the above copyright
++** notice, this list of conditions and the following disclaimer.
++** * Redistributions in binary form must reproduce the above copyright
++** notice, this list of conditions and the following disclaimer in
++** the documentation and/or other materials provided with the
++** distribution.
++** * Neither the name of The Qt Company Ltd nor the names of its
++** contributors may be used to endorse or promote products derived
++** from this software without specific prior written permission.
++**
++**
++** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
++** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
++** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
++** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
++** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
++** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
++** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
++** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
++** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
++** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
++** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
++**
++** $QT_END_LICENSE$
++**
++****************************************************************************/
++
++import QtQuick 2.15
++import QtQuick.Controls 2.15
++
++ApplicationWindow {
++ id: window
++ width: 400
++ height: 400
++ title: "releaseAfterExitTransition"
++
++ property alias popup: popup
++ property alias modalPopup: modalPopup
++
++ Popup {
++ id: popup
++ y: parent.height - height
++ width: 50
++ height: 50
++ }
++
++ Popup {
++ id: modalPopup
++ modal: true
++ y: parent.height - height
++ width: 50
++ height: 50
++ exit: Transition { PauseAnimation { duration: 100 } }
++ }
++}
+diff --git a/qtquickcontrols2/tests/auto/qquickpopup/tst_qquickpopup.cpp b/qtquickcontrols2/tests/auto/qquickpopup/tst_qquickpopup.cpp
+index 54952d128..3d50e2dd4 100644
+--- a/qtquickcontrols2/tests/auto/qquickpopup/tst_qquickpopup.cpp
++++ b/qtquickcontrols2/tests/auto/qquickpopup/tst_qquickpopup.cpp
+@@ -100,6 +100,7 @@ private slots:
+ void invisibleToolTipOpen();
+ void centerInOverlayWithinStackViewItem();
+ void destroyDuringExitTransition();
++ void releaseAfterExitTransition();
+ };
+
+ void tst_QQuickPopup::initTestCase()
+@@ -1575,6 +1576,34 @@ void tst_QQuickPopup::destroyDuringExitTransition()
+ QVERIFY(!button->isDown());
+ }
+
++void tst_QQuickPopup::releaseAfterExitTransition()
++{
++ QQuickApplicationHelper helper(this, "releaseAfterExitTransition.qml");
++ QVERIFY2(helper.ready, helper.failureMessage());
++
++ QQuickWindow *window = helper.window;
++ window->show();
++ QVERIFY(QTest::qWaitForWindowActive(window));
++
++ QQuickOverlay *overlay = QQuickOverlay::overlay(window);
++ QQuickPopup *modalPopup = window->property("modalPopup").value<QQuickPopup *>();
++ QQuickPopup *popup = window->property("popup").value<QQuickPopup *>();
++
++ modalPopup->open();
++ QTRY_VERIFY(modalPopup->isOpened());
++
++ QTest::mousePress(window, Qt::LeftButton, Qt::NoModifier, QPoint(1, 1));
++ // wait until the transition is finished and the overlay hides itself
++ QTRY_VERIFY(!overlay->isVisible());
++ QTest::mouseRelease(window, Qt::LeftButton, Qt::NoModifier, QPoint(1, 1));
++
++ popup->open();
++ QTRY_VERIFY(popup->isOpened());
++ QTest::mouseClick(window, Qt::LeftButton, Qt::NoModifier, QPoint(1, 1));
++ QTRY_VERIFY(!popup->isOpened());
++}
++
++
+ QTEST_QUICKCONTROLS_MAIN(tst_QQuickPopup)
+
+ #include "tst_qquickpopup.moc"
+Submodule qtscript 5be95f96...4d8e4bd2 (commits not present)
+Submodule qtspeech 17fc9fde..255845e2:
+diff --git a/qtspeech/src/plugins/tts/speechdispatcher/qtexttospeech_speechd.cpp b/qtspeech/src/plugins/tts/speechdispatcher/qtexttospeech_speechd.cpp
+index 6eb74b8..bcc7dd1 100644
+--- a/qtspeech/src/plugins/tts/speechdispatcher/qtexttospeech_speechd.cpp
++++ b/qtspeech/src/plugins/tts/speechdispatcher/qtexttospeech_speechd.cpp
+@@ -357,7 +357,9 @@ QVector<QLocale> QTextToSpeechEngineSpeechd::availableLocales() const
+
+ QVector<QVoice> QTextToSpeechEngineSpeechd::availableVoices() const
+ {
+- return m_voices.values(m_currentLocale.name()).toVector();
++ QList<QVoice> resultList = m_voices.values(m_currentLocale.name());
++ std::reverse(resultList.begin(), resultList.end());
++ return resultList.toVector();
+ }
+
+ // We have no way of knowing our own client_id since speech-dispatcher seems to be incomplete
+Submodule qtsvg 0c05780e..a7a0f249:
+diff --git a/qtsvg/src/plugins/imageformats/svg/qsvgiohandler.cpp b/qtsvg/src/plugins/imageformats/svg/qsvgiohandler.cpp
+index 561e77e..12e0574 100644
+--- a/qtsvg/src/plugins/imageformats/svg/qsvgiohandler.cpp
++++ b/qtsvg/src/plugins/imageformats/svg/qsvgiohandler.cpp
+@@ -191,6 +191,8 @@ bool QSvgIOHandler::read(QImage *image)
+ }
+ }
+ if (!finalSize.isEmpty()) {
++ if (qMax(finalSize.width(), finalSize.height()) > 0xffff)
++ return false; // Assume corrupted file
+ image->fill(d->backColor.rgba());
+ QPainter p(image);
+ d->r.render(&p, bounds);
+diff --git a/qtsvg/src/svg/qsvghandler.cpp b/qtsvg/src/svg/qsvghandler.cpp
+index a5f877f..8dda563 100644
+--- a/qtsvg/src/svg/qsvghandler.cpp
++++ b/qtsvg/src/svg/qsvghandler.cpp
+@@ -1393,9 +1393,10 @@ static void parseFont(QSvgNode *node,
+ case FontSizeNone:
+ break;
+ case FontSizeValue: {
+- QSvgHandler::LengthType dummy; // should always be pixel size
+- fontStyle->setSize(qMin(parseLength(attributes.fontSize, dummy, handler),
+- qreal(0xffff)));
++ QSvgHandler::LengthType type;
++ qreal fs = parseLength(attributes.fontSize, type, handler);
++ fs = convertToPixels(fs, true, type);
++ fontStyle->setSize(qMin(fs, qreal(0xffff)));
+ }
+ break;
+ default:
+@@ -2513,6 +2514,8 @@ static bool parseAnimateTransformNode(QSvgNode *parent,
+ ++s;
+ }
+ }
++ if (vals.count() % 3 != 0)
++ return false;
+
+ bool ok = true;
+ int begin = parseClockValue(beginStr, &ok);
+@@ -2576,6 +2579,8 @@ static QSvgNode *createCircleNode(QSvgNode *parent,
+ qreal ncx = toDouble(cx);
+ qreal ncy = toDouble(cy);
+ qreal nr = toDouble(r);
++ if (nr < 0.0)
++ return nullptr;
+
+ QRectF rect(ncx-nr, ncy-nr, nr*2, nr*2);
+ QSvgNode *circle = new QSvgCircle(parent, rect);
+@@ -3046,15 +3051,16 @@ static QSvgStyleProperty *createRadialGradientNode(QSvgNode *node,
+
+ qreal ncx = 0.5;
+ qreal ncy = 0.5;
+- qreal nr = 0.5;
+ if (!cx.isEmpty())
+ ncx = toDouble(cx);
+ if (!cy.isEmpty())
+ ncy = toDouble(cy);
++
++ qreal nr = 0.0;
+ if (!r.isEmpty())
+ nr = toDouble(r);
+- if (nr < 0.5)
+- nr = 0.5;
++ if (nr <= 0.0)
++ return nullptr;
+
+ qreal nfx = ncx;
+ if (!fx.isEmpty())
+@@ -3350,7 +3356,9 @@ static QSvgNode *createTextNode(QSvgNode *parent,
+ //### editable and rotate not handled
+ QSvgHandler::LengthType type;
+ qreal nx = parseLength(x, type, handler);
++ nx = convertToPixels(nx, true, type);
+ qreal ny = parseLength(y, type, handler);
++ ny = convertToPixels(ny, true, type);
+
+ QSvgNode *text = new QSvgText(parent, QPointF(nx, ny));
+ return text;
+@@ -3691,9 +3699,7 @@ void QSvgHandler::parse()
+ case QXmlStreamReader::EndElement:
+ endElement(xml->name());
+ ++remainingUnfinishedElements;
+- // if we are using somebody else's qxmlstreamreader
+- // we should not read until the end of the stream
+- done = !m_ownsReader && (xml->name() == QLatin1String("svg"));
++ done = (xml->name() == QLatin1String("svg"));
+ break;
+ case QXmlStreamReader::Characters:
+ characters(xml->text());
+diff --git a/qtsvg/src/svg/qsvgstructure.cpp b/qtsvg/src/svg/qsvgstructure.cpp
+index b89608b..89c9e4e 100644
+--- a/qtsvg/src/svg/qsvgstructure.cpp
++++ b/qtsvg/src/svg/qsvgstructure.cpp
+@@ -255,9 +255,13 @@ inline static bool isSupportedSvgFeature(const QString &str)
+ };
+
+ if (str.length() <= MAX_WORD_LENGTH && str.length() >= MIN_WORD_LENGTH) {
++ const char16_t unicode44 = str.at(44).unicode();
++ const char16_t unicode45 = str.at(45).unicode();
++ if (unicode44 >= sizeof(asso_values) || unicode45 >= sizeof(asso_values))
++ return false;
+ const int key = str.length()
+- + asso_values[str.at(45).unicode()]
+- + asso_values[str.at(44).unicode()];
++ + asso_values[unicode45]
++ + asso_values[unicode44];
+ if (key <= MAX_HASH_VALUE && key >= 0)
+ return str == QLatin1String(wordlist[key]);
+ }
+diff --git a/qtsvg/src/svg/qsvgtinydocument.cpp b/qtsvg/src/svg/qsvgtinydocument.cpp
+index 63d0797..19e7154 100644
+--- a/qtsvg/src/svg/qsvgtinydocument.cpp
++++ b/qtsvg/src/svg/qsvgtinydocument.cpp
+@@ -433,8 +433,16 @@ void QSvgTinyDocument::draw(QPainter *p, QSvgExtraStates &)
+ draw(p);
+ }
+
++static bool isValidMatrix(const QTransform &transform)
++{
++ qreal determinant = transform.determinant();
++ return qIsFinite(determinant);
++}
++
+ void QSvgTinyDocument::mapSourceToTarget(QPainter *p, const QRectF &targetRect, const QRectF &sourceRect)
+ {
++ QTransform oldTransform = p->worldTransform();
++
+ QRectF target = targetRect;
+ if (target.isEmpty()) {
+ QPaintDevice *dev = p->device();
+@@ -487,6 +495,9 @@ void QSvgTinyDocument::mapSourceToTarget(QPainter *p, const QRectF &targetRect,
+ }
+ #endif
+ }
++
++ if (!isValidMatrix(p->worldTransform()))
++ p->setWorldTransform(oldTransform);
+ }
+
+ QRectF QSvgTinyDocument::boundsOnElement(const QString &id) const
+diff --git a/qtsvg/tests/auto/qsvgrenderer/tst_qsvgrenderer.cpp b/qtsvg/tests/auto/qsvgrenderer/tst_qsvgrenderer.cpp
+index 36c76ec..db71e02 100644
+--- a/qtsvg/tests/auto/qsvgrenderer/tst_qsvgrenderer.cpp
++++ b/qtsvg/tests/auto/qsvgrenderer/tst_qsvgrenderer.cpp
+@@ -86,6 +86,8 @@ private slots:
+ void oss_fuzz_23731();
+ void oss_fuzz_24131();
+ void oss_fuzz_24738();
++ void illegalAnimateTransform_data();
++ void illegalAnimateTransform();
+
+ #ifndef QT_NO_COMPRESS
+ void testGzLoading();
+@@ -1646,5 +1648,22 @@ void tst_QSvgRenderer::oss_fuzz_24738()
+ QSvgRenderer().load(QByteArray("<svg><path d=\"a 2 1e-212.....\">"));
+ }
+
++void tst_QSvgRenderer::illegalAnimateTransform_data()
++{
++ QTest::addColumn<QByteArray>("svg");
++
++ QTest::newRow("case1") << QByteArray("<svg><animateTransform type=\"rotate\" begin=\"1\" dur=\"2\" values=\"8,0,5,0\">");
++ QTest::newRow("case2") << QByteArray("<svg><animateTransform type=\"rotate\" begin=\"1\" dur=\"2\" values=\"1,2\">");
++ QTest::newRow("case3") << QByteArray("<svg><animateTransform type=\"rotate\" begin=\"1\" dur=\"2\" from=\".. 5 2\" to=\"f\">");
++ QTest::newRow("case4") << QByteArray("<svg><animateTransform type=\"scale\" begin=\"1\" dur=\"2\" by=\"--,..\">");
++}
++
++void tst_QSvgRenderer::illegalAnimateTransform()
++{
++ QFETCH(QByteArray, svg);
++ QSvgRenderer renderer;
++ QVERIFY(!renderer.load(svg)); // also shouldn't assert
++}
++
+ QTEST_MAIN(tst_QSvgRenderer)
+ #include "tst_qsvgrenderer.moc"
+Submodule qttools 6914f7c8..090e526e:
+diff --git a/qttools/src/assistant/qhelpgenerator/helpgenerator.cpp b/qttools/src/assistant/qhelpgenerator/helpgenerator.cpp
+index feab1e2d5..cbfb82507 100644
+--- a/qttools/src/assistant/qhelpgenerator/helpgenerator.cpp
++++ b/qttools/src/assistant/qhelpgenerator/helpgenerator.cpp
+@@ -445,7 +445,9 @@ bool HelpGeneratorPrivate::insertFiles(const QStringList &files, const QString &
+ if (filterSetId < 0)
+ return false;
+ ++filterSetId;
+- for (int attId : qAsConst(filterAtts)) {
++ QList<int> attValues = filterAtts.values();
++ std::sort(attValues.begin(), attValues.end());
++ for (int attId : qAsConst(attValues)) {
+ m_query->prepare(QLatin1String("INSERT INTO FileAttributeSetTable "
+ "VALUES(?, ?)"));
+ m_query->bindValue(0, filterSetId);
+Submodule qtwayland dfb0129c..2904e1b3:
+diff --git a/qtwayland/src/client/configure.json b/qtwayland/src/client/configure.json
+index 2f424580..29222357 100644
+--- a/qtwayland/src/client/configure.json
++++ b/qtwayland/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/qtwayland/src/client/global/qwaylandclientextension.cpp b/qtwayland/src/client/global/qwaylandclientextension.cpp
+index 125b1e19..edccfe63 100644
+--- a/qtwayland/src/client/global/qwaylandclientextension.cpp
++++ b/qtwayland/src/client/global/qwaylandclientextension.cpp
+@@ -74,7 +74,10 @@ void QWaylandClientExtensionPrivate::handleRegistryGlobal(void *data, ::wl_regis
+ void QWaylandClientExtension::addRegistryListener()
+ {
+ Q_D(QWaylandClientExtension);
+- d->waylandIntegration->display()->addRegistryListener(&QWaylandClientExtensionPrivate::handleRegistryGlobal, this);
++ if (!d->registered) {
++ d->waylandIntegration->display()->addRegistryListener(&QWaylandClientExtensionPrivate::handleRegistryGlobal, this);
++ d->registered = true;
++ }
+ }
+
+ QWaylandClientExtension::QWaylandClientExtension(const int ver)
+@@ -88,6 +91,13 @@ QWaylandClientExtension::QWaylandClientExtension(const int ver)
+ QMetaObject::invokeMethod(this, "addRegistryListener", Qt::QueuedConnection);
+ }
+
++QWaylandClientExtension::~QWaylandClientExtension()
++{
++ Q_D(QWaylandClientExtension);
++ if (d->registered && !QCoreApplication::closingDown())
++ d->waylandIntegration->display()->removeListener(&QWaylandClientExtensionPrivate::handleRegistryGlobal, this);
++}
++
+ QtWaylandClient::QWaylandIntegration *QWaylandClientExtension::integration() const
+ {
+ Q_D(const QWaylandClientExtension);
+diff --git a/qtwayland/src/client/global/qwaylandclientextension.h b/qtwayland/src/client/global/qwaylandclientextension.h
+index 98272e57..5bd28398 100644
+--- a/qtwayland/src/client/global/qwaylandclientextension.h
++++ b/qtwayland/src/client/global/qwaylandclientextension.h
+@@ -63,6 +63,7 @@ class Q_WAYLAND_CLIENT_EXPORT QWaylandClientExtension : public QObject
+ Q_PROPERTY(bool active READ isActive NOTIFY activeChanged)
+ public:
+ QWaylandClientExtension(const int version);
++ ~QWaylandClientExtension();
+
+ QtWaylandClient::QWaylandIntegration *integration() const;
+ int version() const;
+diff --git a/qtwayland/src/client/global/qwaylandclientextension_p.h b/qtwayland/src/client/global/qwaylandclientextension_p.h
+index 69cc46a0..9091efbe 100644
+--- a/qtwayland/src/client/global/qwaylandclientextension_p.h
++++ b/qtwayland/src/client/global/qwaylandclientextension_p.h
+@@ -68,6 +68,7 @@ public:
+ QtWaylandClient::QWaylandIntegration *waylandIntegration = nullptr;
+ int version = -1;
+ bool active = false;
++ bool registered = false;
+ };
+
+ class Q_WAYLAND_CLIENT_EXPORT QWaylandClientExtensionTemplatePrivate : public QWaylandClientExtensionPrivate
+diff --git a/qtwayland/src/client/qwaylanddatadevice.cpp b/qtwayland/src/client/qwaylanddatadevice.cpp
+index 7e2e3308..e3e60ed5 100644
+--- a/qtwayland/src/client/qwaylanddatadevice.cpp
++++ b/qtwayland/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,7 +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::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;
+@@ -152,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;
+ }
+@@ -162,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();
+ }
+ }
+
+@@ -186,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,
+@@ -197,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()
+@@ -235,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());
+
+@@ -246,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)
+
+@@ -277,14 +296,10 @@ void QWaylandDataDevice::selectionSourceCancelled()
+ #if QT_CONFIG(draganddrop)
+ void QWaylandDataDevice::dragSourceCancelled()
+ {
++ static_cast<QWaylandDrag *>(QGuiApplicationPrivate::platformIntegration()->drag())->finishDrag();
+ 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));
+@@ -297,6 +312,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/qtwayland/src/client/qwaylanddatadevice_p.h b/qtwayland/src/client/qwaylanddatadevice_p.h
+index 16c3ad28..801dcc2c 100644
+--- a/qtwayland/src/client/qwaylanddatadevice_p.h
++++ b/qtwayland/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/qtwayland/src/client/qwaylanddatadevicemanager.cpp b/qtwayland/src/client/qwaylanddatadevicemanager.cpp
+index 35d67307..6dc4f77f 100644
+--- a/qtwayland/src/client/qwaylanddatadevicemanager.cpp
++++ b/qtwayland/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/qtwayland/src/client/qwaylanddatadevicemanager_p.h b/qtwayland/src/client/qwaylanddatadevicemanager_p.h
+index bd05c0fb..510d9be4 100644
+--- a/qtwayland/src/client/qwaylanddatadevicemanager_p.h
++++ b/qtwayland/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/qtwayland/src/client/qwaylanddataoffer.cpp b/qtwayland/src/client/qwaylanddataoffer.cpp
+index 2297e8a1..fe0ea8c9 100644
+--- a/qtwayland/src/client/qwaylanddataoffer.cpp
++++ b/qtwayland/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)
+ {
+@@ -163,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");
+diff --git a/qtwayland/src/client/qwaylanddataoffer_p.h b/qtwayland/src/client/qwaylanddataoffer_p.h
+index 9cf1483c..6f667398 100644
+--- a/qtwayland/src/client/qwaylanddataoffer_p.h
++++ b/qtwayland/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/qtwayland/src/client/qwaylanddatasource.cpp b/qtwayland/src/client/qwaylanddatasource.cpp
+index f45122fb..5599cbd4 100644
+--- a/qtwayland/src/client/qwaylanddatasource.cpp
++++ b/qtwayland/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/qtwayland/src/client/qwaylanddatasource_p.h b/qtwayland/src/client/qwaylanddatasource_p.h
+index 25afff79..96f07bc3 100644
+--- a/qtwayland/src/client/qwaylanddatasource_p.h
++++ b/qtwayland/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/qtwayland/src/client/qwaylanddisplay.cpp b/qtwayland/src/client/qwaylanddisplay.cpp
+index f10c1f79..c01e238b 100644
+--- a/qtwayland/src/client/qwaylanddisplay.cpp
++++ b/qtwayland/src/client/qwaylanddisplay.cpp
+@@ -85,10 +85,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)
+@@ -158,17 +351,16 @@ 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)
+ {
++ if (m_eventThread)
++ m_eventThread->stop();
++
++ if (m_frameEventQueueThread)
++ m_frameEventQueueThread->stop();
++
+ if (mSyncCallback)
+ wl_callback_destroy(mSyncCallback);
+
+@@ -187,6 +379,21 @@ 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
++// 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()
+@@ -203,98 +410,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
+@@ -345,7 +491,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));
+@@ -354,7 +500,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));
+@@ -369,6 +515,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));
+@@ -427,6 +575,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;
+ }
+@@ -452,9 +607,10 @@ void QWaylandDisplay::addRegistryListener(RegistryListener listener, void *data)
+
+ void QWaylandDisplay::removeListener(RegistryListener listener, void *data)
+ {
+- std::remove_if(mRegistryListeners.begin(), mRegistryListeners.end(), [=](Listener l){
++ auto iter = std::remove_if(mRegistryListeners.begin(), mRegistryListeners.end(), [=](Listener l){
+ return (l.listener == listener && l.data == data);
+ });
++ mRegistryListeners.erase(iter, mRegistryListeners.end());
+ }
+
+ uint32_t QWaylandDisplay::currentTimeMillisec()
+@@ -467,50 +623,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
+@@ -574,14 +689,10 @@ void QWaylandDisplay::handleKeyboardFocusChanged(QWaylandInputDevice *inputDevic
+ if (mLastKeyboardFocus == keyboardFocus)
+ return;
+
+- if (mWaylandIntegration->mShellIntegration) {
+- mWaylandIntegration->mShellIntegration->handleKeyboardFocusChanged(keyboardFocus, mLastKeyboardFocus);
+- } else {
+- if (keyboardFocus)
+- handleWindowActivated(keyboardFocus);
+- if (mLastKeyboardFocus)
+- handleWindowDeactivated(mLastKeyboardFocus);
+- }
++ if (keyboardFocus)
++ handleWindowActivated(keyboardFocus);
++ if (mLastKeyboardFocus)
++ handleWindowDeactivated(mLastKeyboardFocus);
+
+ mLastKeyboardFocus = keyboardFocus;
+ }
+@@ -600,6 +711,19 @@ void QWaylandDisplay::handleWaylandSync()
+ QWindow *activeWindow = mActiveWindows.empty() ? nullptr : mActiveWindows.last()->window();
+ if (activeWindow != QGuiApplication::focusWindow())
+ QWindowSystemInterface::handleWindowActivated(activeWindow);
++
++ if (!activeWindow) {
++ if (lastInputDevice()) {
++#if QT_CONFIG(clipboard)
++ if (auto *dataDevice = lastInputDevice()->dataDevice())
++ dataDevice->invalidateSelectionOffer();
++#endif
++#if QT_CONFIG(wayland_client_primary_selection)
++ if (auto *device = lastInputDevice()->primarySelectionDevice())
++ device->invalidateSelectionOffer();
++#endif
++ }
++ }
+ }
+
+ const wl_callback_listener QWaylandDisplay::syncCallbackListener = {
+@@ -626,6 +750,13 @@ QWaylandInputDevice *QWaylandDisplay::defaultInputDevice() const
+ return mInputDevices.isEmpty() ? 0 : mInputDevices.first();
+ }
+
++bool QWaylandDisplay::isKeyboardAvailable() const
++{
++ return std::any_of(
++ mInputDevices.constBegin(), mInputDevices.constEnd(),
++ [this](const QWaylandInputDevice *device) { return device->keyboard() != nullptr; });
++}
++
+ #if QT_CONFIG(cursor)
+
+ QWaylandCursor *QWaylandDisplay::waylandCursor()
+@@ -652,4 +783,6 @@ QWaylandCursorTheme *QWaylandDisplay::loadCursorTheme(const QString &name, int p
+
+ } // namespace QtWaylandClient
+
++#include "qwaylanddisplay.moc"
++
+ QT_END_NAMESPACE
+diff --git a/qtwayland/src/client/qwaylanddisplay_p.h b/qtwayland/src/client/qwaylanddisplay_p.h
+index 3b092bc8..42bc661d 100644
+--- a/qtwayland/src/client/qwaylanddisplay_p.h
++++ b/qtwayland/src/client/qwaylanddisplay_p.h
+@@ -109,6 +109,7 @@ class QWaylandSurface;
+ class QWaylandShellIntegration;
+ class QWaylandCursor;
+ class QWaylandCursorTheme;
++class EventThread;
+
+ typedef void (*RegistryListener)(void *data,
+ struct wl_registry *registry,
+@@ -120,15 +121,11 @@ 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;
+
++ void initialize();
++
+ #if QT_CONFIG(xkbcommon)
+ struct xkb_context *xkbContext() const { return mXkbContext.get(); }
+ #endif
+@@ -210,11 +207,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();
+@@ -237,6 +234,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;
+@@ -273,11 +273,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/qtwayland/src/client/qwaylanddnd.cpp b/qtwayland/src/client/qwaylanddnd.cpp
+index 6535aa16..7c53f5fa 100644
+--- a/qtwayland/src/client/qwaylanddnd.cpp
++++ b/qtwayland/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
+@@ -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)
+@@ -103,33 +106,41 @@ 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);
++
++ if (drag())
++ drag()->deleteLater();
++}
++
++bool QWaylandDrag::ownsDragObject() const
++{
++ return true;
+ }
+
+ }
+diff --git a/qtwayland/src/client/qwaylanddnd_p.h b/qtwayland/src/client/qwaylanddnd_p.h
+index 474fe2ab..46f629ac 100644
+--- a/qtwayland/src/client/qwaylanddnd_p.h
++++ b/qtwayland/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;
+@@ -82,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;
+diff --git a/qtwayland/src/client/qwaylandinputdevice.cpp b/qtwayland/src/client/qwaylandinputdevice.cpp
+index 613fe862..4b90de84 100644
+--- a/qtwayland/src/client/qwaylandinputdevice.cpp
++++ b/qtwayland/src/client/qwaylandinputdevice.cpp
+@@ -685,6 +685,11 @@ public:
+
+ void QWaylandInputDevice::Pointer::pointer_leave(uint32_t time, struct wl_surface *surface)
+ {
++ invalidateFocus();
++ mButtons = Qt::NoButton;
++
++ mParent->mTime = time;
++
+ // The event may arrive after destroying the window, indicated by
+ // a null surface.
+ if (!surface)
+@@ -696,11 +701,6 @@ void QWaylandInputDevice::Pointer::pointer_leave(uint32_t time, struct wl_surfac
+
+ if (!QWaylandWindow::mouseGrab())
+ setFrameEvent(new LeaveEvent(window, mSurfacePos, mGlobalPos));
+-
+- invalidateFocus();
+- mButtons = Qt::NoButton;
+-
+- mParent->mTime = time;
+ }
+
+ class MotionEvent : public QWaylandPointerEvent
+@@ -1300,14 +1300,6 @@ void QWaylandInputDevice::Keyboard::handleFocusDestroyed()
+ void QWaylandInputDevice::Keyboard::handleFocusLost()
+ {
+ mFocus = nullptr;
+-#if QT_CONFIG(clipboard)
+- if (auto *dataDevice = mParent->dataDevice())
+- dataDevice->invalidateSelectionOffer();
+-#endif
+-#if QT_CONFIG(wayland_client_primary_selection)
+- if (auto *device = mParent->primarySelectionDevice())
+- device->invalidateSelectionOffer();
+-#endif
+ mParent->mQDisplay->handleKeyboardFocusChanged(mParent);
+ mRepeatTimer.stop();
+ }
+@@ -1396,6 +1388,7 @@ void QWaylandInputDevice::Touch::touch_cancel()
+ if (touchExt)
+ touchExt->touchCanceled();
+
++ mFocus = nullptr;
+ QWindowSystemInterface::handleTouchCancelEvent(nullptr, mParent->mTouchDevice);
+ }
+
+diff --git a/qtwayland/src/client/qwaylandintegration.cpp b/qtwayland/src/client/qwaylandintegration.cpp
+index c53ccb78..54861600 100644
+--- a/qtwayland/src/client/qwaylandintegration.cpp
++++ b/qtwayland/src/client/qwaylandintegration.cpp
+@@ -125,6 +125,9 @@ QWaylandIntegration::QWaylandIntegration()
+ #endif
+
+ reconfigureInputContext();
++
++ QWaylandWindow::fixedToplevelPositions =
++ !qEnvironmentVariableIsSet("QT_WAYLAND_DISABLE_FIXED_POSITIONS");
+ }
+
+ QWaylandIntegration::~QWaylandIntegration()
+@@ -192,14 +195,18 @@ QAbstractEventDispatcher *QWaylandIntegration::createEventDispatcher() const
+
+ void QWaylandIntegration::initialize()
+ {
++ mDisplay->initEventThread();
++
++ // 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()));
+
+- 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()));
+-
+ // Qt does not support running with no screens
+ mDisplay->ensureScreen();
+ }
+@@ -262,6 +269,14 @@ QWaylandDisplay *QWaylandIntegration::display() const
+ return mDisplay.data();
+ }
+
++Qt::KeyboardModifiers QWaylandIntegration::queryKeyboardModifiers() const
++{
++ if (auto *seat = mDisplay->currentInputDevice()) {
++ return seat->modifiers();
++ }
++ return Qt::NoModifier;
++}
++
+ QList<int> QWaylandIntegration::possibleKeys(const QKeyEvent *event) const
+ {
+ if (auto *seat = mDisplay->currentInputDevice())
+@@ -479,7 +494,7 @@ void QWaylandIntegration::reconfigureInputContext()
+ }
+ #endif
+
+- qCDebug(lcQpaWayland) << "using input method:" << inputContext()->metaObject()->className();
++ qCDebug(lcQpaWayland) << "using input method:" << (inputContext() ? inputContext()->metaObject()->className() : "<none>");
+ }
+
+ QWaylandShellIntegration *QWaylandIntegration::createShellIntegration(const QString &integrationName)
+diff --git a/qtwayland/src/client/qwaylandintegration_p.h b/qtwayland/src/client/qwaylandintegration_p.h
+index ff70ae25..73b80658 100644
+--- a/qtwayland/src/client/qwaylandintegration_p.h
++++ b/qtwayland/src/client/qwaylandintegration_p.h
+@@ -107,6 +107,8 @@ public:
+
+ QWaylandDisplay *display() const;
+
++ Qt::KeyboardModifiers queryKeyboardModifiers() const override;
++
+ QList<int> possibleKeys(const QKeyEvent *event) const override;
+
+ QStringList themeNames() const override;
+diff --git a/qtwayland/src/client/qwaylandprimaryselectionv1.cpp b/qtwayland/src/client/qwaylandprimaryselectionv1.cpp
+index 832f9678..ea508771 100644
+--- a/qtwayland/src/client/qwaylandprimaryselectionv1.cpp
++++ b/qtwayland/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)
+diff --git a/qtwayland/src/client/qwaylandscreen.cpp b/qtwayland/src/client/qwaylandscreen.cpp
+index 6cb337de..5537dafd 100644
+--- a/qtwayland/src/client/qwaylandscreen.cpp
++++ b/qtwayland/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))
+@@ -72,7 +72,7 @@ QWaylandScreen::QWaylandScreen(QWaylandDisplay *waylandDisplay, int version, uin
+ qCWarning(lcQpaWayland) << "wl_output done event not supported by compositor,"
+ << "QScreen may not work correctly";
+ mWaylandDisplay->forceRoundTrip(); // Give the compositor a chance to send geometry etc.
+- mOutputDone = true; // Fake the done event
++ mProcessedEvents |= OutputDoneEvent; // Fake the done event
+ maybeInitialize();
+ }
+ }
+@@ -81,16 +81,29 @@ 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
++{
++ uint ret = OutputDoneEvent;
++
++ if (mWaylandDisplay->xdgOutputManager()) {
++ ret |= XdgOutputNameEvent;
++
++ if (mWaylandDisplay->xdgOutputManager()->version() < 3)
++ ret |= XdgOutputDoneEvent;
++ }
++ return ret;
+ }
+
+ void QWaylandScreen::maybeInitialize()
+ {
+ Q_ASSERT(!mInitialized);
+
+- if (!mOutputDone)
+- return;
+-
+- if (mWaylandDisplay->xdgOutputManager() && !mXdgOutputDone)
++ const uint requiredEvents = this->requiredEvents();
++ if ((mProcessedEvents & requiredEvents) != requiredEvents)
+ return;
+
+ mInitialized = true;
+@@ -276,9 +289,8 @@ void QWaylandScreen::output_scale(int32_t factor)
+
+ void QWaylandScreen::output_done()
+ {
+- mOutputDone = true;
+- if (zxdg_output_v1::isInitialized() && mWaylandDisplay->xdgOutputManager()->version() >= 3)
+- mXdgOutputDone = true;
++ mProcessedEvents |= OutputDoneEvent;
++
+ if (mInitialized) {
+ updateOutputProperties();
+ if (zxdg_output_v1::isInitialized())
+@@ -339,7 +351,7 @@ void QWaylandScreen::zxdg_output_v1_done()
+ if (Q_UNLIKELY(mWaylandDisplay->xdgOutputManager()->version() >= 3))
+ qWarning(lcQpaWayland) << "zxdg_output_v1.done received on version 3 or newer, this is most likely a bug in the compositor";
+
+- mXdgOutputDone = true;
++ mProcessedEvents |= XdgOutputDoneEvent;
+ if (mInitialized)
+ updateXdgOutputProperties();
+ else
+@@ -348,7 +360,11 @@ void QWaylandScreen::zxdg_output_v1_done()
+
+ void QWaylandScreen::zxdg_output_v1_name(const QString &name)
+ {
++ if (Q_UNLIKELY(mInitialized))
++ qWarning(lcQpaWayland) << "zxdg_output_v1.name received after output has been initialized, this is most likely a bug in the compositor";
++
+ mOutputName = name;
++ mProcessedEvents |= XdgOutputNameEvent;
+ }
+
+ void QWaylandScreen::updateXdgOutputProperties()
+diff --git a/qtwayland/src/client/qwaylandscreen_p.h b/qtwayland/src/client/qwaylandscreen_p.h
+index df1c94f2..050cfdc0 100644
+--- a/qtwayland/src/client/qwaylandscreen_p.h
++++ b/qtwayland/src/client/qwaylandscreen_p.h
+@@ -116,6 +116,13 @@ public:
+ static QWaylandScreen *fromWlOutput(::wl_output *output);
+
+ private:
++ enum Event : uint {
++ XdgOutputDoneEvent = 0x1,
++ OutputDoneEvent = 0x2,
++ XdgOutputNameEvent = 0x4,
++ };
++ uint requiredEvents() const;
++
+ void output_mode(uint32_t flags, int width, int height, int refresh) override;
+ void output_geometry(int32_t x, int32_t y,
+ int32_t width, int32_t height,
+@@ -148,8 +155,7 @@ private:
+ QSize mPhysicalSize;
+ QString mOutputName;
+ Qt::ScreenOrientation m_orientation = Qt::PrimaryOrientation;
+- bool mOutputDone = false;
+- bool mXdgOutputDone = false;
++ uint mProcessedEvents = 0;
+ bool mInitialized = false;
+
+ #if QT_CONFIG(cursor)
+diff --git a/qtwayland/src/client/qwaylandshmbackingstore.cpp b/qtwayland/src/client/qwaylandshmbackingstore.cpp
+index dc7ff670..41cffdf7 100644
+--- a/qtwayland/src/client/qwaylandshmbackingstore.cpp
++++ b/qtwayland/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
+@@ -74,8 +78,10 @@ QWaylandShmBuffer::QWaylandShmBuffer(QWaylandDisplay *display,
+ int alloc = stride * size.height();
+ int fd = -1;
+
+-#ifdef SYS_memfd_create
+- fd = syscall(SYS_memfd_create, "wayland-shm", MFD_CLOEXEC);
++#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);
+ #endif
+
+ QScopedPointer<QFile> filePointer;
+diff --git a/qtwayland/src/client/qwaylandwindow.cpp b/qtwayland/src/client/qwaylandwindow.cpp
+index cb82857a..fb2c59dc 100644
+--- a/qtwayland/src/client/qwaylandwindow.cpp
++++ b/qtwayland/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,9 +94,6 @@ QWaylandWindow::QWaylandWindow(QWindow *window, QWaylandDisplay *display)
+
+ QWaylandWindow::~QWaylandWindow()
+ {
+- mDisplay->destroyFrameQueue(mFrameQueue);
+- mDisplay->handleWindowDestroyed(this);
+-
+ delete mWindowDecoration;
+
+ if (mSurface)
+@@ -243,6 +239,7 @@ bool QWaylandWindow::shouldCreateSubSurface() const
+
+ void QWaylandWindow::reset()
+ {
++ closeChildPopups();
+ delete mShellSurface;
+ mShellSurface = nullptr;
+ delete mSubSurfaceWindow;
+@@ -255,17 +252,22 @@ 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();
+ mQueuedBuffer = nullptr;
++
++ mDisplay->handleWindowDestroyed(this);
+ }
+
+ QWaylandWindow *QWaylandWindow::fromWlSurface(::wl_surface *surface)
+@@ -351,19 +353,25 @@ 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()) {
+ 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());
+@@ -374,7 +382,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)
+@@ -399,21 +407,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);
+@@ -433,10 +426,7 @@ void QWaylandWindow::setVisible(bool visible)
+ lastVisible = visible;
+
+ if (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
+@@ -444,7 +434,6 @@ void QWaylandWindow::setVisible(bool visible)
+ // QWaylandShmBackingStore::beginPaint().
+ } else {
+ sendExposeEvent(QRect());
+- closePopups(this);
+ reset();
+ }
+ }
+@@ -556,12 +545,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();
+
+@@ -583,7 +572,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)
+@@ -619,8 +612,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();
+@@ -635,42 +634,53 @@ 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);
+- 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();
+
+ // 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;
+- };
++ 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();
++ };
+
++ 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();
+ }
+
+ 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";
+@@ -868,6 +878,17 @@ bool QWaylandWindow::createDecoration()
+ subsurf->set_position(pos.x() + m.left(), pos.y() + m.top());
+ }
+ sendExposeEvent(QRect(QPoint(), geometry().size()));
++
++ // This is a special case where the buffer is recreated, but since
++ // the content rect remains the same, the widgets remain the same
++ // size and are not redrawn, leaving the new buffer empty. As a simple
++ // work-around, we trigger a full extra update whenever the client-side
++ // window decorations are toggled while the window is showing.
++ // Note: createDecoration() is sometimes called from the render thread
++ // of Qt Quick. This is essentially wrong and could potentially cause problems,
++ // but until the underlying issue has been fixed, we have to use invokeMethod()
++ // here to avoid asserts.
++ QMetaObject::invokeMethod(window(), &QWindow::requestUpdate);
+ }
+
+ return mWindowDecoration;
+@@ -1023,6 +1044,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) {
+@@ -1094,10 +1122,18 @@ bool QWaylandWindow::setMouseGrabEnabled(bool grab)
+ return true;
+ }
+
++Qt::WindowStates QWaylandWindow::windowStates() const
++{
++ return mLastReportedWindowStates;
++}
++
+ void QWaylandWindow::handleWindowStatesChanged(Qt::WindowStates states)
+ {
+ createDecoration();
+- QWindowSystemInterface::handleWindowStateChanged(window(), states, mLastReportedWindowStates);
++ Qt::WindowStates statesWithoutActive = states & ~Qt::WindowActive;
++ Qt::WindowStates lastStatesWithoutActive = mLastReportedWindowStates & ~Qt::WindowActive;
++ QWindowSystemInterface::handleWindowStateChanged(window(), statesWithoutActive,
++ lastStatesWithoutActive);
+ mLastReportedWindowStates = states;
+ }
+
+@@ -1139,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()
+@@ -1160,8 +1201,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
+@@ -1174,7 +1218,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);
+ }
+@@ -1185,19 +1234,18 @@ void QWaylandWindow::requestUpdate()
+ void QWaylandWindow::handleUpdate()
+ {
+ qCDebug(lcWaylandBackingstore) << "handleUpdate" << QThread::currentThread();
++
+ // TODO: Should sync subsurfaces avoid requesting frame callbacks?
+ QReadLocker lock(&mSurfaceLock);
+ if (!mSurface)
+ return;
+
+- if (mFrameCallback) {
+- wl_callback_destroy(mFrameCallback);
+- mFrameCallback = nullptr;
+- }
++ QMutexLocker locker(&mFrameSyncMutex);
++ if (mWaitingForFrameCallback)
++ return;
+
+- 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);
++ 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);
+@@ -1207,6 +1255,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);
+@@ -1267,6 +1317,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/qtwayland/src/client/qwaylandwindow_p.h b/qtwayland/src/client/qwaylandwindow_p.h
+index 01337cff..2f219d8c 100644
+--- a/qtwayland/src/client/qwaylandwindow_p.h
++++ b/qtwayland/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;
+@@ -148,6 +151,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;
+@@ -206,6 +210,10 @@ public:
+ void handleUpdate();
+ void deliverUpdateRequest() override;
+
++ void addChildPopup(QWaylandWindow* child);
++ void removeChildPopup(QWaylandWindow* child);
++ void closeChildPopups();
++
+ public slots:
+ void applyConfigure();
+
+@@ -215,7 +223,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;
+@@ -225,13 +237,14 @@ protected:
+ Qt::MouseButtons mMousePressedInContentArea = Qt::NoButton;
+
+ 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;
+- QWaylandDisplay::FrameQueue mFrameQueue;
++ 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;
+
+ // True when we have called deliverRequestUpdate, but the client has not yet attached a new buffer
+@@ -261,6 +274,8 @@ protected:
+ QWaylandBuffer *mQueuedBuffer = nullptr;
+ QRegion mQueuedBufferDamage;
+
++ QList<QPointer<QWaylandWindow>> mChildPopups;
++
+ private:
+ void setGeometry_helper(const QRect &rect);
+ void initWindow();
+@@ -283,12 +298,10 @@ private:
+ QRect mLastExposeGeometry;
+
+ static const wl_callback_listener callbackListener;
+- void handleFrameCallback();
++ void handleFrameCallback(struct ::wl_callback* callback);
+
+ static QWaylandWindow *mMouseGrab;
+
+- mutable QReadWriteLock mSurfaceLock;
+-
+ friend class QWaylandSubSurface;
+ };
+
+diff --git a/qtwayland/src/client/shellintegration/qwaylandshellintegration_p.h b/qtwayland/src/client/shellintegration/qwaylandshellintegration_p.h
+index ccad0048..4cc9b3b8 100644
+--- a/qtwayland/src/client/shellintegration/qwaylandshellintegration_p.h
++++ b/qtwayland/src/client/shellintegration/qwaylandshellintegration_p.h
+@@ -73,11 +73,10 @@ public:
+ return true;
+ }
+ virtual QWaylandShellSurface *createShellSurface(QWaylandWindow *window) = 0;
++ // kept for binary compat with layer-shell-qt
+ virtual void handleKeyboardFocusChanged(QWaylandWindow *newFocus, QWaylandWindow *oldFocus) {
+- if (newFocus)
+- m_display->handleWindowActivated(newFocus);
+- if (oldFocus)
+- m_display->handleWindowDeactivated(oldFocus);
++ Q_UNUSED(newFocus);
++ Q_UNUSED(oldFocus);
+ }
+ virtual void *nativeResourceForWindow(const QByteArray &resource, QWindow *window) {
+ Q_UNUSED(resource);
+diff --git a/qtwayland/src/compositor/configure.json b/qtwayland/src/compositor/configure.json
+index bcfd5215..da95d07b 100644
+--- a/qtwayland/src/compositor/configure.json
++++ b/qtwayland/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"
+ }
+ },
+
+diff --git a/qtwayland/src/hardwareintegration/client/wayland-egl/qwaylandeglwindow.cpp b/qtwayland/src/hardwareintegration/client/wayland-egl/qwaylandeglwindow.cpp
+index 7889f575..64140672 100644
+--- a/qtwayland/src/hardwareintegration/client/wayland-egl/qwaylandeglwindow.cpp
++++ b/qtwayland/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>
+@@ -124,6 +125,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();
+@@ -131,14 +133,16 @@ void QWaylandEglWindow::updateSurface(bool create)
+ if (!disableResizeCheck) {
+ wl_egl_window_get_attached_size(m_waylandEglWindow, ¤t_width, ¤t_height);
+ }
+- if (disableResizeCheck || (current_width != sizeWithMargins.width() || current_height != sizeWithMargins.height())) {
++ if (disableResizeCheck || (current_width != sizeWithMargins.width() || current_height != sizeWithMargins.height()) || m_requestedSize != sizeWithMargins) {
+ wl_egl_window_resize(m_waylandEglWindow, sizeWithMargins.width(), sizeWithMargins.height(), mOffset.x(), mOffset.y());
++ m_requestedSize = sizeWithMargins;
+ mOffset = QPoint();
+
+ 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;
+ }
+
+ if (!m_eglSurface && m_waylandEglWindow && create) {
+diff --git a/qtwayland/src/hardwareintegration/client/wayland-egl/qwaylandeglwindow.h b/qtwayland/src/hardwareintegration/client/wayland-egl/qwaylandeglwindow.h
+index 5b1f4d56..0079dfef 100644
+--- a/qtwayland/src/hardwareintegration/client/wayland-egl/qwaylandeglwindow.h
++++ b/qtwayland/src/hardwareintegration/client/wayland-egl/qwaylandeglwindow.h
+@@ -88,6 +88,7 @@ private:
+ mutable QOpenGLFramebufferObject *m_contentFBO = nullptr;
+
+ QSurfaceFormat m_format;
++ QSize m_requestedSize;
+ };
+
+ }
+diff --git a/qtwayland/src/hardwareintegration/compositor/linux-dmabuf-unstable-v1/linuxdmabuf.h b/qtwayland/src/hardwareintegration/compositor/linux-dmabuf-unstable-v1/linuxdmabuf.h
+index 56a710c3..c6a8b6c6 100644
+--- a/qtwayland/src/hardwareintegration/compositor/linux-dmabuf-unstable-v1/linuxdmabuf.h
++++ b/qtwayland/src/hardwareintegration/compositor/linux-dmabuf-unstable-v1/linuxdmabuf.h
+@@ -41,6 +41,8 @@
+ #include <QtCore/QTextStream>
+ #include <QtGui/QOpenGLTexture>
+
++#include <array>
++
+ #include <EGL/egl.h>
+ #include <EGL/eglext.h>
+
+diff --git a/qtwayland/src/plugins/decorations/bradient/main.cpp b/qtwayland/src/plugins/decorations/bradient/main.cpp
+index e75fda3c..fa885143 100644
+--- a/qtwayland/src/plugins/decorations/bradient/main.cpp
++++ b/qtwayland/src/plugins/decorations/bradient/main.cpp
+@@ -164,13 +164,10 @@ void QWaylandBradientDecoration::paint(QPaintDevice *device)
+ // Window icon
+ QIcon icon = waylandWindow()->windowIcon();
+ if (!icon.isNull()) {
+- QPixmap pixmap = icon.pixmap(QSize(128, 128));
+- QPixmap scaled = pixmap.scaled(22, 22, Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
+-
+ QRectF iconRect(0, 0, 22, 22);
+- p.drawPixmap(iconRect.adjusted(margins().left() + BUTTON_SPACING, 4,
+- margins().left() + BUTTON_SPACING, 4),
+- scaled, iconRect);
++ iconRect.adjust(margins().left() + BUTTON_SPACING, 4,
++ margins().left() + BUTTON_SPACING, 4),
++ icon.paint(&p, iconRect.toRect());
+ }
+
+ // Window title
+diff --git a/qtwayland/src/plugins/shellintegration/xdg-shell-v5/qwaylandxdgpopupv5.cpp b/qtwayland/src/plugins/shellintegration/xdg-shell-v5/qwaylandxdgpopupv5.cpp
+index 85d25e3c..60bdd491 100644
+--- a/qtwayland/src/plugins/shellintegration/xdg-shell-v5/qwaylandxdgpopupv5.cpp
++++ b/qtwayland/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/qtwayland/src/plugins/shellintegration/xdg-shell-v5/qwaylandxdgpopupv5_p.h b/qtwayland/src/plugins/shellintegration/xdg-shell-v5/qwaylandxdgpopupv5_p.h
+index 7494f6a6..d85f130b 100644
+--- a/qtwayland/src/plugins/shellintegration/xdg-shell-v5/qwaylandxdgpopupv5_p.h
++++ b/qtwayland/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/qtwayland/src/plugins/shellintegration/xdg-shell-v5/qwaylandxdgshellv5.cpp b/qtwayland/src/plugins/shellintegration/xdg-shell-v5/qwaylandxdgshellv5.cpp
+index 7e242c4a..def8452a 100644
+--- a/qtwayland/src/plugins/shellintegration/xdg-shell-v5/qwaylandxdgshellv5.cpp
++++ b/qtwayland/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/qtwayland/src/plugins/shellintegration/xdg-shell-v5/qwaylandxdgshellv5integration.cpp b/qtwayland/src/plugins/shellintegration/xdg-shell-v5/qwaylandxdgshellv5integration.cpp
+index 4e25949f..cfc60939 100644
+--- a/qtwayland/src/plugins/shellintegration/xdg-shell-v5/qwaylandxdgshellv5integration.cpp
++++ b/qtwayland/src/plugins/shellintegration/xdg-shell-v5/qwaylandxdgshellv5integration.cpp
+@@ -85,13 +85,6 @@ QWaylandShellSurface *QWaylandXdgShellV5Integration::createShellSurface(QWayland
+ return m_xdgShell->createXdgSurface(window);
+ }
+
+-void QWaylandXdgShellV5Integration::handleKeyboardFocusChanged(QWaylandWindow *newFocus, QWaylandWindow *oldFocus) {
+- if (newFocus && qobject_cast<QWaylandXdgPopupV5 *>(newFocus->shellSurface()))
+- m_display->handleWindowActivated(newFocus);
+- if (oldFocus && qobject_cast<QWaylandXdgPopupV5 *>(oldFocus->shellSurface()))
+- m_display->handleWindowDeactivated(oldFocus);
+-}
+-
+ }
+
+ QT_END_NAMESPACE
+diff --git a/qtwayland/src/plugins/shellintegration/xdg-shell-v5/qwaylandxdgshellv5integration_p.h b/qtwayland/src/plugins/shellintegration/xdg-shell-v5/qwaylandxdgshellv5integration_p.h
+index ce6bdb9e..aed88670 100644
+--- a/qtwayland/src/plugins/shellintegration/xdg-shell-v5/qwaylandxdgshellv5integration_p.h
++++ b/qtwayland/src/plugins/shellintegration/xdg-shell-v5/qwaylandxdgshellv5integration_p.h
+@@ -67,7 +67,6 @@ public:
+ QWaylandXdgShellV5Integration() {}
+ bool initialize(QWaylandDisplay *display) override;
+ QWaylandShellSurface *createShellSurface(QWaylandWindow *window) override;
+- void handleKeyboardFocusChanged(QWaylandWindow *newFocus, QWaylandWindow *oldFocus) override;
+
+ private:
+ QScopedPointer<QWaylandXdgShellV5> m_xdgShell;
+diff --git a/qtwayland/src/plugins/shellintegration/xdg-shell-v6/qwaylandxdgshellv6.cpp b/qtwayland/src/plugins/shellintegration/xdg-shell-v6/qwaylandxdgshellv6.cpp
+index 8c371661..151c78e3 100644
+--- a/qtwayland/src/plugins/shellintegration/xdg-shell-v6/qwaylandxdgshellv6.cpp
++++ b/qtwayland/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/qtwayland/src/plugins/shellintegration/xdg-shell-v6/qwaylandxdgshellv6integration.cpp b/qtwayland/src/plugins/shellintegration/xdg-shell-v6/qwaylandxdgshellv6integration.cpp
+index 03164316..e8da8ba1 100644
+--- a/qtwayland/src/plugins/shellintegration/xdg-shell-v6/qwaylandxdgshellv6integration.cpp
++++ b/qtwayland/src/plugins/shellintegration/xdg-shell-v6/qwaylandxdgshellv6integration.cpp
+@@ -68,20 +68,6 @@ QWaylandShellSurface *QWaylandXdgShellV6Integration::createShellSurface(QWayland
+ return m_xdgShell->getXdgSurface(window);
+ }
+
+-void QWaylandXdgShellV6Integration::handleKeyboardFocusChanged(QWaylandWindow *newFocus, QWaylandWindow *oldFocus)
+-{
+- if (newFocus) {
+- auto *xdgSurface = qobject_cast<QWaylandXdgSurfaceV6 *>(newFocus->shellSurface());
+- if (xdgSurface && !xdgSurface->handlesActiveState())
+- m_display->handleWindowActivated(newFocus);
+- }
+- if (oldFocus && qobject_cast<QWaylandXdgSurfaceV6 *>(oldFocus->shellSurface())) {
+- auto *xdgSurface = qobject_cast<QWaylandXdgSurfaceV6 *>(oldFocus->shellSurface());
+- if (xdgSurface && !xdgSurface->handlesActiveState())
+- m_display->handleWindowDeactivated(oldFocus);
+- }
+-}
+-
+ }
+
+ QT_END_NAMESPACE
+diff --git a/qtwayland/src/plugins/shellintegration/xdg-shell-v6/qwaylandxdgshellv6integration_p.h b/qtwayland/src/plugins/shellintegration/xdg-shell-v6/qwaylandxdgshellv6integration_p.h
+index 261f8cbb..c1bcd5c6 100644
+--- a/qtwayland/src/plugins/shellintegration/xdg-shell-v6/qwaylandxdgshellv6integration_p.h
++++ b/qtwayland/src/plugins/shellintegration/xdg-shell-v6/qwaylandxdgshellv6integration_p.h
+@@ -65,7 +65,6 @@ public:
+ QWaylandXdgShellV6Integration() {}
+ bool initialize(QWaylandDisplay *display) override;
+ QWaylandShellSurface *createShellSurface(QWaylandWindow *window) override;
+- void handleKeyboardFocusChanged(QWaylandWindow *newFocus, QWaylandWindow *oldFocus) override;
+
+ private:
+ QScopedPointer<QWaylandXdgShellV6> m_xdgShell;
+diff --git a/qtwayland/src/plugins/shellintegration/xdg-shell/qwaylandxdgshell.cpp b/qtwayland/src/plugins/shellintegration/xdg-shell/qwaylandxdgshell.cpp
+index f3e3c330..fa6d5808 100644
+--- a/qtwayland/src/plugins/shellintegration/xdg-shell/qwaylandxdgshell.cpp
++++ b/qtwayland/src/plugins/shellintegration/xdg-shell/qwaylandxdgshell.cpp
+@@ -67,11 +67,6 @@ QWaylandXdgSurface::Toplevel::Toplevel(QWaylandXdgSurface *xdgSurface)
+
+ QWaylandXdgSurface::Toplevel::~Toplevel()
+ {
+- if (m_applied.states & Qt::WindowActive) {
+- QWaylandWindow *window = m_xdgSurface->window();
+- window->display()->handleWindowDeactivated(window);
+- }
+-
+ // The protocol spec requires that the decoration object is deleted before xdg_toplevel.
+ delete m_decoration;
+ m_decoration = nullptr;
+@@ -85,16 +80,15 @@ void QWaylandXdgSurface::Toplevel::applyConfigure()
+ if (!(m_applied.states & (Qt::WindowMaximized|Qt::WindowFullScreen)))
+ 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)
++ && !m_xdgSurface->m_window->display()->isKeyboardAvailable())
+ 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)
++ && !m_xdgSurface->m_window->display()->isKeyboardAvailable())
+ m_xdgSurface->m_window->display()->handleWindowDeactivated(m_xdgSurface->m_window);
+
+- // TODO: none of the other plugins send WindowActive either, but is it on purpose?
+- Qt::WindowStates statesWithoutActive = m_pending.states & ~Qt::WindowActive;
+-
+- m_xdgSurface->m_window->handleWindowStatesChanged(statesWithoutActive);
++ m_xdgSurface->m_window->handleWindowStatesChanged(m_pending.states);
+
+ if (m_pending.size.isEmpty()) {
+ // An empty size in the configure means it's up to the client to choose the size
+@@ -105,8 +99,6 @@ void QWaylandXdgSurface::Toplevel::applyConfigure()
+ m_xdgSurface->m_window->resizeFromApplyConfigure(m_pending.size);
+ }
+
+- m_xdgSurface->setSizeHints();
+-
+ m_applied = m_pending;
+ qCDebug(lcQpaWayland) << "Applied pending xdg_toplevel configure event:" << m_applied.size << m_applied.states;
+ }
+@@ -203,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()
+@@ -216,10 +213,24 @@ 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
++ QWindow *leave = nullptr;
++ if (m_xdgSurface && m_xdgSurface->window())
++ leave = m_xdgSurface->window()->window();
++ QWindowSystemInterface::handleLeaveEvent(leave);
++
++ if (QWindow *enter = QGuiApplication::topLevelAt(QCursor::pos()))
++ QWindowSystemInterface::handleEnterEvent(enter, enter->mapFromGlobal(QCursor::pos()), QCursor::pos());
+ }
+ }
+
+@@ -257,6 +268,7 @@ QWaylandXdgSurface::QWaylandXdgSurface(QWaylandXdgShell *shell, ::xdg_surface *s
+ m_toplevel->set_parent(parentXdgSurface->m_toplevel->object());
+ }
+ }
++ setSizeHints();
+ }
+
+ QWaylandXdgSurface::~QWaylandXdgSurface()
+@@ -400,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
+@@ -414,8 +424,9 @@ void QWaylandXdgSurface::setPopup(QWaylandWindow *parent)
+ positioner->set_anchor(QtWayland::xdg_positioner::anchor_top_left);
+ positioner->set_gravity(QtWayland::xdg_positioner::gravity_bottom_right);
+ positioner->set_size(m_window->geometry().width(), m_window->geometry().height());
+- m_popup = new Popup(this, parentXdgSurface, positioner);
++ m_popup = new Popup(this, parent, positioner);
+ positioner->destroy();
++
+ delete positioner;
+ }
+
+@@ -437,6 +448,23 @@ void QWaylandXdgSurface::setGrabPopup(QWaylandWindow *parent, QWaylandInputDevic
+ }
+ setPopup(parent);
+ m_popup->grab(device, serial);
++
++ // Synthesize Qt enter/leave events for popup
++ if (!parent)
++ return;
++ QWindow *current = QGuiApplication::topLevelAt(QCursor::pos());
++ QWindow *leave = parent->window();
++ if (current != leave)
++ return;
++
++ QWindowSystemInterface::handleLeaveEvent(leave);
++
++ QWindow *enter = nullptr;
++ if (m_popup && m_popup->m_xdgSurface && m_popup->m_xdgSurface->window())
++ enter = m_popup->m_xdgSurface->window()->window();
++
++ if (enter)
++ QWindowSystemInterface::handleEnterEvent(enter, enter->mapFromGlobal(QCursor::pos()), QCursor::pos());
+ }
+
+ void QWaylandXdgSurface::xdg_surface_configure(uint32_t serial)
+diff --git a/qtwayland/src/plugins/shellintegration/xdg-shell/qwaylandxdgshell_p.h b/qtwayland/src/plugins/shellintegration/xdg-shell/qwaylandxdgshell_p.h
+index 96785205..4b518f0a 100644
+--- a/qtwayland/src/plugins/shellintegration/xdg-shell/qwaylandxdgshell_p.h
++++ b/qtwayland/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/qtwayland/src/plugins/shellintegration/xdg-shell/qwaylandxdgshellintegration.cpp b/qtwayland/src/plugins/shellintegration/xdg-shell/qwaylandxdgshellintegration.cpp
+index 8769d971..da0dd6a7 100644
+--- a/qtwayland/src/plugins/shellintegration/xdg-shell/qwaylandxdgshellintegration.cpp
++++ b/qtwayland/src/plugins/shellintegration/xdg-shell/qwaylandxdgshellintegration.cpp
+@@ -69,20 +69,6 @@ QWaylandShellSurface *QWaylandXdgShellIntegration::createShellSurface(QWaylandWi
+ return m_xdgShell->getXdgSurface(window);
+ }
+
+-void QWaylandXdgShellIntegration::handleKeyboardFocusChanged(QWaylandWindow *newFocus, QWaylandWindow *oldFocus)
+-{
+- if (newFocus) {
+- auto *xdgSurface = qobject_cast<QWaylandXdgSurface *>(newFocus->shellSurface());
+- if (xdgSurface && !xdgSurface->handlesActiveState())
+- m_display->handleWindowActivated(newFocus);
+- }
+- if (oldFocus && qobject_cast<QWaylandXdgSurface *>(oldFocus->shellSurface())) {
+- auto *xdgSurface = qobject_cast<QWaylandXdgSurface *>(oldFocus->shellSurface());
+- if (xdgSurface && !xdgSurface->handlesActiveState())
+- m_display->handleWindowDeactivated(oldFocus);
+- }
+-}
+-
+ }
+
+ QT_END_NAMESPACE
+diff --git a/qtwayland/src/plugins/shellintegration/xdg-shell/qwaylandxdgshellintegration_p.h b/qtwayland/src/plugins/shellintegration/xdg-shell/qwaylandxdgshellintegration_p.h
+index b6caa6c9..2f929f98 100644
+--- a/qtwayland/src/plugins/shellintegration/xdg-shell/qwaylandxdgshellintegration_p.h
++++ b/qtwayland/src/plugins/shellintegration/xdg-shell/qwaylandxdgshellintegration_p.h
+@@ -65,7 +65,6 @@ public:
+ QWaylandXdgShellIntegration() {}
+ bool initialize(QWaylandDisplay *display) override;
+ QWaylandShellSurface *createShellSurface(QWaylandWindow *window) override;
+- void handleKeyboardFocusChanged(QWaylandWindow *newFocus, QWaylandWindow *oldFocus) override;
+
+ private:
+ QScopedPointer<QWaylandXdgShell> m_xdgShell;
+diff --git a/qtwayland/src/shared/qwaylandinputmethodeventbuilder.cpp b/qtwayland/src/shared/qwaylandinputmethodeventbuilder.cpp
+index 526d0ef4..f50ccf30 100644
+--- a/qtwayland/src/shared/qwaylandinputmethodeventbuilder.cpp
++++ b/qtwayland/src/shared/qwaylandinputmethodeventbuilder.cpp
+@@ -39,7 +39,10 @@
+
+ #include "qwaylandinputmethodeventbuilder_p.h"
+
++#include <QBrush>
++#include <QGuiApplication>
+ #include <QInputMethod>
++#include <QPalette>
+ #include <QTextCharFormat>
+
+ #ifdef QT_BUILD_WAYLANDCOMPOSITOR_LIB
+@@ -81,32 +84,38 @@ void QWaylandInputMethodEventBuilder::addPreeditStyling(uint32_t index, uint32_t
+ QTextCharFormat format;
+
+ switch (style) {
+- case 0:
+- case 1:
++ case ZWP_TEXT_INPUT_V2_PREEDIT_STYLE_NONE:
++ break;
++ case ZWP_TEXT_INPUT_V2_PREEDIT_STYLE_DEFAULT:
++ case ZWP_TEXT_INPUT_V2_PREEDIT_STYLE_UNDERLINE:
+ format.setFontUnderline(true);
+ format.setUnderlineStyle(QTextCharFormat::SingleUnderline);
+ m_preeditStyles.append(QInputMethodEvent::Attribute(QInputMethodEvent::TextFormat, index, length, format));
+ break;
+- case 2:
+- case 3:
++ case ZWP_TEXT_INPUT_V2_PREEDIT_STYLE_ACTIVE:
++ case ZWP_TEXT_INPUT_V2_PREEDIT_STYLE_INACTIVE:
+ format.setFontWeight(QFont::Bold);
+ format.setFontUnderline(true);
+ format.setUnderlineStyle(QTextCharFormat::SingleUnderline);
+ m_preeditStyles.append(QInputMethodEvent::Attribute(QInputMethodEvent::TextFormat, index, length, format));
+ break;
+- case 4:
+- format.setFontUnderline(true);
+- format.setUnderlineStyle(QTextCharFormat::SingleUnderline);
+- m_preeditStyles.append(QInputMethodEvent::Attribute(QInputMethodEvent::TextFormat, index, length, format));
++ case ZWP_TEXT_INPUT_V2_PREEDIT_STYLE_HIGHLIGHT:
++ case ZWP_TEXT_INPUT_V2_PREEDIT_STYLE_SELECTION:
++ {
++ format.setFontUnderline(true);
++ format.setUnderlineStyle(QTextCharFormat::SingleUnderline);
++ QPalette palette = qApp->palette();
++ format.setBackground(QBrush(palette.color(QPalette::Active, QPalette::Highlight)));
++ format.setForeground(QBrush(palette.color(QPalette::Active, QPalette::HighlightedText)));
++ m_preeditStyles.append(QInputMethodEvent::Attribute(QInputMethodEvent::TextFormat, index, length, format));
++ }
+ break;
+- case 5:
++ case ZWP_TEXT_INPUT_V2_PREEDIT_STYLE_INCORRECT:
+ format.setFontUnderline(true);
+ format.setUnderlineStyle(QTextCharFormat::WaveUnderline);
+ format.setUnderlineColor(QColor(Qt::red));
+ m_preeditStyles.append(QInputMethodEvent::Attribute(QInputMethodEvent::TextFormat, index, length, format));
+ break;
+-// case QtWayland::wl_text_input::preedit_style_selection:
+-// case QtWayland::wl_text_input::preedit_style_none:
+ default:
+ break;
+ }
+@@ -153,7 +162,7 @@ QInputMethodEvent QWaylandInputMethodEventBuilder::buildPreedit(const QString &t
+
+ if (m_preeditCursor < 0) {
+ attributes.append(QInputMethodEvent::Attribute(QInputMethodEvent::Cursor, 0, 0, QVariant()));
+- } else if (m_preeditCursor > 0) {
++ } else {
+ attributes.append(QInputMethodEvent::Attribute(QInputMethodEvent::Cursor, indexFromWayland(text, m_preeditCursor), 1, QVariant()));
+ }
+
+diff --git a/qtwayland/src/shared/qwaylandmimehelper.cpp b/qtwayland/src/shared/qwaylandmimehelper.cpp
+index a5fdd34d..e2fe1928 100644
+--- a/qtwayland/src/shared/qwaylandmimehelper.cpp
++++ b/qtwayland/src/shared/qwaylandmimehelper.cpp
+@@ -60,7 +60,7 @@ QByteArray QWaylandMimeHelper::getByteArray(QMimeData *mimeData, const QString &
+ buf.open(QIODevice::ReadWrite);
+ QByteArray fmt = "BMP";
+ if (mimeType.startsWith(QLatin1String("image/"))) {
+- QByteArray imgFmt = mimeType.mid(6).toUpper().toLatin1();
++ QByteArray imgFmt = mimeType.mid(6).toLower().toLatin1();
+ if (QImageWriter::supportedImageFormats().contains(imgFmt))
+ fmt = imgFmt;
+ }
+@@ -74,7 +74,7 @@ QByteArray QWaylandMimeHelper::getByteArray(QMimeData *mimeData, const QString &
+ QList<QUrl> urls = mimeData->urls();
+ for (int i = 0; i < urls.count(); ++i) {
+ content.append(urls.at(i).toEncoded());
+- content.append('\n');
++ content.append("\r\n");
+ }
+ } else {
+ content = mimeData->data(mimeType);
+diff --git a/qtwayland/tests/auto/client/datadevicev1/tst_datadevicev1.cpp b/qtwayland/tests/auto/client/datadevicev1/tst_datadevicev1.cpp
+index 1568b3b9..067410d0 100644
+--- a/qtwayland/tests/auto/client/datadevicev1/tst_datadevicev1.cpp
++++ b/qtwayland/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:
+diff --git a/qtwayland/tests/auto/client/seatv5/tst_seatv5.cpp b/qtwayland/tests/auto/client/seatv5/tst_seatv5.cpp
+index 9312c2e5..2ea382f1 100644
+--- a/qtwayland/tests/auto/client/seatv5/tst_seatv5.cpp
++++ b/qtwayland/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, Qt::TouchPointPressed);
++ QCOMPARE(e.touchPoints.length(), 1);
++ QCOMPARE(e.touchPoints.first().pos(), 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/qtwayland/tests/auto/client/shared/corecompositor.cpp b/qtwayland/tests/auto/client/shared/corecompositor.cpp
+index 5c6c83ba..fa9b7662 100644
+--- a/qtwayland/tests/auto/client/shared/corecompositor.cpp
++++ b/qtwayland/tests/auto/client/shared/corecompositor.cpp
+@@ -27,6 +27,7 @@
+ ****************************************************************************/
+
+ #include "corecompositor.h"
++#include <thread>
+
+ namespace MockCompositor {
+
+diff --git a/qtwayland/tests/auto/client/shared/coreprotocol.cpp b/qtwayland/tests/auto/client/shared/coreprotocol.cpp
+index 0d988521..d1a2e7cb 100644
+--- a/qtwayland/tests/auto/client/shared/coreprotocol.cpp
++++ b/qtwayland/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/qtwayland/tests/auto/client/shared/coreprotocol.h b/qtwayland/tests/auto/client/shared/coreprotocol.h
+index a1af137a..210d8ddb 100644
+--- a/qtwayland/tests/auto/client/shared/coreprotocol.h
++++ b/qtwayland/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)
+ {}
+@@ -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;
+ };
+diff --git a/qtwayland/tests/auto/client/shared_old/mockcompositor.cpp b/qtwayland/tests/auto/client/shared_old/mockcompositor.cpp
+index a415cbf5..b1d3d07d 100644
+--- a/qtwayland/tests/auto/client/shared_old/mockcompositor.cpp
++++ b/qtwayland/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/qtwayland/tests/auto/client/shared_old/mocksurface.cpp b/qtwayland/tests/auto/client/shared_old/mocksurface.cpp
+index e9df5f90..c3246e4a 100644
+--- a/qtwayland/tests/auto/client/shared_old/mocksurface.cpp
++++ b/qtwayland/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/qtwayland/tests/auto/client/shared_old/mocksurface.h b/qtwayland/tests/auto/client/shared_old/mocksurface.h
+index 949dc23d..d176837e 100644
+--- a/qtwayland/tests/auto/client/shared_old/mocksurface.h
++++ b/qtwayland/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;
+diff --git a/qtwayland/tests/auto/client/surface/tst_surface.cpp b/qtwayland/tests/auto/client/surface/tst_surface.cpp
+index 95e4e609..60c672ce 100644
+--- a/qtwayland/tests/auto/client/surface/tst_surface.cpp
++++ b/qtwayland/tests/auto/client/surface/tst_surface.cpp
+@@ -129,6 +129,10 @@ void tst_surface::waitForFrameCallbackGl()
+ // Make sure we follow frame callbacks for some frames
+ for (int i = 0; i < 5; ++i) {
+ xdgPingAndWaitForPong(); // Make sure things have happened on the client
++ if (!qEnvironmentVariableIntValue("QT_WAYLAND_DISABLE_WINDOWDECORATION") && i == 0) {
++ QCOMPARE(bufferSpy.count(), 1);
++ bufferSpy.removeFirst();
++ }
+ exec([&] {
+ QVERIFY(bufferSpy.empty()); // Make sure no extra buffers have arrived
+ QVERIFY(!xdgToplevel()->surface()->m_waitingFrameCallbacks.empty());
+diff --git a/qtwayland/tests/auto/client/xdgshell/tst_xdgshell.cpp b/qtwayland/tests/auto/client/xdgshell/tst_xdgshell.cpp
+index 2277bbb8..747875b4 100644
+--- a/qtwayland/tests/auto/client/xdgshell/tst_xdgshell.cpp
++++ b/qtwayland/tests/auto/client/xdgshell/tst_xdgshell.cpp
+@@ -31,6 +31,7 @@
+ #include <QtGui/QOpenGLWindow>
+ #include <QtGui/qpa/qplatformnativeinterface.h>
+ #include <QtWaylandClient/private/wayland-wayland-client-protocol.h>
++#include <QtWaylandClient/private/qwaylandwindow_p.h>
+
+ using namespace MockCompositor;
+
+@@ -45,6 +46,7 @@ private slots:
+ void configureStates();
+ void popup();
+ void tooltipOnPopup();
++ void tooltipAndSiblingPopup();
+ void switchPopups();
+ void hidePopupParent();
+ void pongs();
+@@ -138,6 +140,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();
+@@ -154,9 +157,12 @@ void tst_xdgshell::configureStates()
+ // 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
+
+-// QEXPECT_FAIL("", "configure has already been acked, we shouldn't have to wait for isActive", Continue);
+-// QVERIFY(window.isActive());
+- QTRY_VERIFY(window.isActive()); // Just make sure it eventually get's set correctly
++ // window.windowstate() is driven by keyboard focus, however for decorations we want to follow
++ // XDGShell this is internal to QtWayland so it is queried directly
++ auto waylandWindow = static_cast<QtWaylandClient::QWaylandWindow *>(window.handle());
++ Q_ASSERT(waylandWindow);
++ QTRY_VERIFY(waylandWindow->windowStates().testFlag(
++ Qt::WindowActive)); // Just make sure it eventually get's set correctly
+
+ const QSize screenSize(640, 480);
+ const uint maximizedSerial = exec([=] {
+@@ -186,6 +192,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()
+@@ -340,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()
+ {
+@@ -505,7 +598,7 @@ void tst_xdgshell::minMaxSize()
+ window.show();
+ QCOMPOSITOR_TRY_VERIFY(xdgToplevel());
+
+- exec([=] { xdgToplevel()->sendCompleteConfigure(); });
++ // we don't roundtrip with our configuration the initial commit should be correct
+
+ QCOMPOSITOR_TRY_COMPARE(xdgToplevel()->m_committed.minSize, QSize(100, 100));
+ QCOMPOSITOR_TRY_COMPARE(xdgToplevel()->m_committed.maxSize, QSize(1000, 1000));
+Submodule qtwebchannel 618422ee..f8949655:
+diff --git a/qtwebchannel/src/webchannel/qmetaobjectpublisher.cpp b/qtwebchannel/src/webchannel/qmetaobjectpublisher.cpp
+index 536eb5c..898d769 100644
+--- a/qtwebchannel/src/webchannel/qmetaobjectpublisher.cpp
++++ b/qtwebchannel/src/webchannel/qmetaobjectpublisher.cpp
+@@ -186,8 +186,6 @@ Q_DECLARE_TYPEINFO(OverloadResolutionCandidate, Q_MOVABLE_TYPE);
+ QMetaObjectPublisher::QMetaObjectPublisher(QWebChannel *webChannel)
+ : QObject(webChannel)
+ , webChannel(webChannel)
+- , signalHandler(this)
+- , clientIsIdle(false)
+ , blockUpdates(false)
+ , propertyUpdatesInitialized(false)
+ {
+@@ -301,17 +299,17 @@ QJsonObject QMetaObjectPublisher::classInfoForObject(const QObject *object, QWeb
+ return data;
+ }
+
+-void QMetaObjectPublisher::setClientIsIdle(bool isIdle)
++void QMetaObjectPublisher::setClientIsIdle(bool isIdle, QWebChannelAbstractTransport *transport)
+ {
+- if (clientIsIdle == isIdle) {
+- return;
+- }
+- clientIsIdle = isIdle;
+- if (!isIdle && timer.isActive()) {
+- timer.stop();
+- } else if (isIdle && !timer.isActive()) {
+- timer.start(PROPERTY_UPDATE_INTERVAL, this);
+- }
++ transportState[transport].clientIsIdle = isIdle;
++ if (isIdle)
++ sendEnqueuedPropertyUpdates(transport);
++}
++
++bool QMetaObjectPublisher::isClientIdle(QWebChannelAbstractTransport *transport)
++{
++ auto found = transportState.find(transport);
++ return found != transportState.end() && found.value().clientIsIdle;
+ }
+
+ QJsonObject QMetaObjectPublisher::initializeClient(QWebChannelAbstractTransport *transport)
+@@ -333,6 +331,7 @@ QJsonObject QMetaObjectPublisher::initializeClient(QWebChannelAbstractTransport
+
+ void QMetaObjectPublisher::initializePropertyUpdates(const QObject *const object, const QJsonObject &objectInfo)
+ {
++ auto *signalHandler = signalHandlerFor(object);
+ foreach (const QJsonValue &propertyInfoVar, objectInfo[KEY_PROPERTIES].toArray()) {
+ const QJsonArray &propertyInfo = propertyInfoVar.toArray();
+ if (propertyInfo.size() < 2) {
+@@ -353,19 +352,19 @@ void QMetaObjectPublisher::initializePropertyUpdates(const QObject *const object
+
+ // Only connect for a property update once
+ if (connectedProperties.isEmpty()) {
+- signalHandler.connectTo(object, signalIndex);
++ signalHandler->connectTo(object, signalIndex);
+ }
+
+ connectedProperties.insert(propertyIndex);
+ }
+
+ // also always connect to destroyed signal
+- signalHandler.connectTo(object, s_destroyedSignalIndex);
++ signalHandler->connectTo(object, s_destroyedSignalIndex);
+ }
+
+ void QMetaObjectPublisher::sendPendingPropertyUpdates()
+ {
+- if (blockUpdates || !clientIsIdle || pendingPropertyUpdates.isEmpty()) {
++ if (blockUpdates) {
+ return;
+ }
+
+@@ -415,18 +414,19 @@ void QMetaObjectPublisher::sendPendingPropertyUpdates()
+
+ // data does not contain specific updates
+ if (!data.isEmpty()) {
+- setClientIsIdle(false);
+-
+ message[KEY_DATA] = data;
+- broadcastMessage(message);
++ enqueueBroadcastMessage(message);
+ }
+
+ // send every property update which is not supposed to be broadcasted
+ const QHash<QWebChannelAbstractTransport*, QJsonArray>::const_iterator suend = specificUpdates.constEnd();
+ for (QHash<QWebChannelAbstractTransport*, QJsonArray>::const_iterator it = specificUpdates.constBegin(); it != suend; ++it) {
+ message[KEY_DATA] = it.value();
+- it.key()->sendMessage(message);
++ enqueueMessage(message, it.key());
+ }
++
++ for (auto state = transportState.begin(); state != transportState.end(); ++state)
++ sendEnqueuedPropertyUpdates(state.key());
+ }
+
+ QVariant QMetaObjectPublisher::invokeMethod(QObject *const object, const QMetaMethod &method,
+@@ -572,7 +572,7 @@ void QMetaObjectPublisher::signalEmitted(const QObject *object, const int signal
+ }
+ } else {
+ pendingPropertyUpdates[object][signalIndex] = arguments;
+- if (clientIsIdle && !blockUpdates && !timer.isActive()) {
++ if (!blockUpdates && !timer.isActive()) {
+ timer.start(PROPERTY_UPDATE_INTERVAL, this);
+ }
+ }
+@@ -590,7 +590,7 @@ void QMetaObjectPublisher::objectDestroyed(const QObject *object)
+ // only remove from handler when we initialized the property updates
+ // cf: https://bugreports.qt.io/browse/QTBUG-60250
+ if (propertyUpdatesInitialized) {
+- signalHandler.remove(object);
++ signalHandlerFor(object)->remove(object);
+ signalToPropertyMap.remove(object);
+ }
+ pendingPropertyUpdates.remove(object);
+@@ -852,6 +852,52 @@ void QMetaObjectPublisher::broadcastMessage(const QJsonObject &message) const
+ }
+ }
+
++void QMetaObjectPublisher::enqueueBroadcastMessage(const QJsonObject &message)
++{
++ if (webChannel->d_func()->transports.isEmpty()) {
++ qWarning("QWebChannel is not connected to any transports, cannot send message: %s",
++ QJsonDocument(message).toJson().constData());
++ return;
++ }
++
++ for (auto *transport : webChannel->d_func()->transports) {
++ auto &state = transportState[transport];
++ state.queuedMessages.append(message);
++ }
++}
++
++void QMetaObjectPublisher::enqueueMessage(const QJsonObject &message,
++ QWebChannelAbstractTransport *transport)
++{
++ auto &state = transportState[transport];
++ state.queuedMessages.append(message);
++}
++
++void QMetaObjectPublisher::sendEnqueuedPropertyUpdates(QWebChannelAbstractTransport *transport)
++{
++ auto found = transportState.find(transport);
++ if (found != transportState.end() && found.value().clientIsIdle
++ && !found.value().queuedMessages.isEmpty()) {
++
++ // If the client is connected with an in-process transport, it can
++ // happen that a message triggers a subsequent property change. In
++ // that case, we need to ensure that the queued messages have already
++ // been cleared; otherwise the recursive call will send everythig again.
++ // Case in point: The qmlwebchannel tests fail if we don't clear the
++ // queued messages before sending them out.
++ // For that same reason set the client to "busy" (aka non-idle) just
++ // right before sending out the messages; otherwise a potential
++ // "Idle" type message will not correctly restore the Idle state.
++ const auto messages = std::move(found.value().queuedMessages);
++ Q_ASSERT(found.value().queuedMessages.isEmpty());
++ found.value().clientIsIdle = false;
++
++ for (const auto &message : messages) {
++ transport->sendMessage(message);
++ }
++ }
++}
++
+ void QMetaObjectPublisher::handleMessage(const QJsonObject &message, QWebChannelAbstractTransport *transport)
+ {
+ if (!webChannel->d_func()->transports.contains(transport)) {
+@@ -866,7 +912,7 @@ void QMetaObjectPublisher::handleMessage(const QJsonObject &message, QWebChannel
+
+ const MessageType type = toType(message.value(KEY_TYPE));
+ if (type == TypeIdle) {
+- setClientIsIdle(true);
++ setClientIsIdle(true, transport);
+ } else if (type == TypeInit) {
+ if (!message.contains(KEY_ID)) {
+ qWarning("JSON message object is missing the id property: %s",
+@@ -913,9 +959,9 @@ void QMetaObjectPublisher::handleMessage(const QJsonObject &message, QWebChannel
+ return;
+ transport->sendMessage(createResponse(message.value(KEY_ID), wrapResult(result, transport)));
+ } else if (type == TypeConnectToSignal) {
+- signalHandler.connectTo(object, message.value(KEY_SIGNAL).toInt(-1));
++ signalHandlerFor(object)->connectTo(object, message.value(KEY_SIGNAL).toInt(-1));
+ } else if (type == TypeDisconnectFromSignal) {
+- signalHandler.disconnectFrom(object, message.value(KEY_SIGNAL).toInt(-1));
++ signalHandlerFor(object)->disconnectFrom(object, message.value(KEY_SIGNAL).toInt(-1));
+ } else if (type == TypeSetProperty) {
+ setProperty(object, message.value(KEY_PROPERTY).toInt(-1),
+ message.value(KEY_VALUE));
+@@ -931,6 +977,7 @@ void QMetaObjectPublisher::setBlockUpdates(bool block)
+ blockUpdates = block;
+
+ if (!blockUpdates) {
++ timer.start(PROPERTY_UPDATE_INTERVAL, this);
+ sendPendingPropertyUpdates();
+ } else if (timer.isActive()) {
+ timer.stop();
+@@ -948,4 +995,15 @@ void QMetaObjectPublisher::timerEvent(QTimerEvent *event)
+ }
+ }
+
++SignalHandler<QMetaObjectPublisher> *QMetaObjectPublisher::signalHandlerFor(const QObject *object)
++{
++ auto thread = object->thread();
++ auto it = signalHandlers.find(thread);
++ if (it == signalHandlers.end()) {
++ it = signalHandlers.emplace(thread, this).first;
++ it->second.moveToThread(thread);
++ }
++ return &it->second;
++}
++
+ QT_END_NAMESPACE
+diff --git a/qtwebchannel/src/webchannel/qmetaobjectpublisher_p.h b/qtwebchannel/src/webchannel/qmetaobjectpublisher_p.h
+index bbd9875..4713ef1 100644
+--- a/qtwebchannel/src/webchannel/qmetaobjectpublisher_p.h
++++ b/qtwebchannel/src/webchannel/qmetaobjectpublisher_p.h
+@@ -59,6 +59,9 @@
+ #include <QBasicTimer>
+ #include <QPointer>
+ #include <QJsonObject>
++#include <QQueue>
++
++#include <unordered_map>
+
+ #include "qwebchannelglobal.h"
+
+@@ -109,17 +112,36 @@ public:
+ */
+ void broadcastMessage(const QJsonObject &message) const;
+
++ /**
++ * Enqueue the given @p message to all known transports.
++ */
++ void enqueueBroadcastMessage(const QJsonObject &message);
++
++ /**
++ * Enqueue the given @p message to @p transport.
++ */
++ void enqueueMessage(const QJsonObject &message, QWebChannelAbstractTransport *transport);
++
++ /**
++ * If client for given @p transport is idle, send queued messaged to @p transport and then mark
++ * the client as not idle.
++ */
++ void sendEnqueuedPropertyUpdates(QWebChannelAbstractTransport *transport);
++
+ /**
+ * Serialize the QMetaObject of @p object and return it in JSON form.
+ */
+ QJsonObject classInfoForObject(const QObject *object, QWebChannelAbstractTransport *transport);
+
+ /**
+- * Set the client to idle or busy, based on the value of @p isIdle.
+- *
+- * When the value changed, start/stop the property update timer accordingly.
++ * Set the client to idle or busy for a single @p transport, based on the value of @p isIdle.
++ */
++ void setClientIsIdle(bool isIdle, QWebChannelAbstractTransport *transport);
++
++ /**
++ * Check that client is idle for @p transport.
+ */
+- void setClientIsIdle(bool isIdle);
++ bool isClientIdle(QWebChannelAbstractTransport *transport);
+
+ /**
+ * Initialize clients by sending them the class information of the registered objects.
+@@ -272,10 +294,18 @@ private:
+ friend class TestWebChannel;
+
+ QWebChannel *webChannel;
+- SignalHandler<QMetaObjectPublisher> signalHandler;
++ std::unordered_map<const QThread*, SignalHandler<QMetaObjectPublisher>> signalHandlers;
++ SignalHandler<QMetaObjectPublisher> *signalHandlerFor(const QObject *object);
+
+- // true when the client is idle, false otherwise
+- bool clientIsIdle;
++ struct TransportState
++ {
++ TransportState() : clientIsIdle(false) { }
++ // true when the client is idle, false otherwise
++ bool clientIsIdle;
++ // messages to send
++ QQueue<QJsonObject> queuedMessages;
++ };
++ QHash<QWebChannelAbstractTransport *, TransportState> transportState;
+
+ // true when no property updates should be sent, false otherwise
+ bool blockUpdates;
+diff --git a/qtwebchannel/src/webchannel/signalhandler_p.h b/qtwebchannel/src/webchannel/signalhandler_p.h
+index 27afadb..d77373c 100644
+--- a/qtwebchannel/src/webchannel/signalhandler_p.h
++++ b/qtwebchannel/src/webchannel/signalhandler_p.h
+@@ -56,6 +56,7 @@
+ #include <QVector>
+ #include <QMetaMethod>
+ #include <QDebug>
++#include <QThread>
+
+ QT_BEGIN_NAMESPACE
+
+@@ -71,6 +72,7 @@ static const int s_destroyedSignalIndex = QObject::staticMetaObject.indexOfMetho
+ template<class Receiver>
+ class SignalHandler : public QObject
+ {
++ Q_DISABLE_COPY(SignalHandler)
+ public:
+ SignalHandler(Receiver *receiver, QObject *parent = 0);
+
+@@ -268,6 +270,7 @@ int SignalHandler<Receiver>::qt_metacall(QMetaObject::Call call, int methodId, v
+ if (call == QMetaObject::InvokeMetaMethod) {
+ const QObject *object = sender();
+ Q_ASSERT(object);
++ Q_ASSERT(QThread::currentThread() == object->thread());
+ Q_ASSERT(senderSignalIndex() == methodId);
+ Q_ASSERT(m_connectionsCounter.contains(object));
+ Q_ASSERT(m_connectionsCounter.value(object).contains(methodId));
+diff --git a/qtwebchannel/tests/auto/qml/testwebchannel.cpp b/qtwebchannel/tests/auto/qml/testwebchannel.cpp
+index 9891687..3ca81c2 100644
+--- a/qtwebchannel/tests/auto/qml/testwebchannel.cpp
++++ b/qtwebchannel/tests/auto/qml/testwebchannel.cpp
+@@ -46,7 +46,11 @@ TestWebChannel::~TestWebChannel()
+
+ bool TestWebChannel::clientIsIdle() const
+ {
+- return QWebChannel::d_func()->publisher->clientIsIdle;
++ for (auto *transport : QWebChannel::d_func()->transports) {
++ if (QWebChannel::d_func()->publisher->isClientIdle(transport))
++ return true;
++ }
++ return false;
+ }
+
+ QT_END_NAMESPACE
+diff --git a/qtwebchannel/tests/auto/webchannel/tst_webchannel.cpp b/qtwebchannel/tests/auto/webchannel/tst_webchannel.cpp
+index 181da9e..37f989a 100644
+--- a/qtwebchannel/tests/auto/webchannel/tst_webchannel.cpp
++++ b/qtwebchannel/tests/auto/webchannel/tst_webchannel.cpp
+@@ -785,7 +785,7 @@ void TestWebChannel::testTransportWrapObjectProperties()
+ DummyTransport *dummyTransport = new DummyTransport(this);
+ channel.connectTo(dummyTransport);
+ channel.d_func()->publisher->initializeClient(dummyTransport);
+- channel.d_func()->publisher->setClientIsIdle(true);
++ channel.d_func()->publisher->setClientIsIdle(true, dummyTransport);
+
+ QCOMPARE(channel.d_func()->publisher->transportedWrappedObjects.size(), 0);
+
+@@ -943,8 +943,6 @@ void TestWebChannel::testInfiniteRecursion()
+
+ void TestWebChannel::testAsyncObject()
+ {
+- QSKIP("This test is broken. See QTBUG-80729");
+-
+ QWebChannel channel;
+ channel.connectTo(m_dummyTransport);
+
+@@ -990,6 +988,50 @@ void TestWebChannel::testAsyncObject()
+ thread.wait();
+ }
+
++void TestWebChannel::testPropertyMultipleTransports()
++{
++ DummyTransport transport1;
++ DummyTransport transport2;
++
++ QWebChannel channel;
++ QMetaObjectPublisher *publisher = channel.d_func()->publisher;
++
++ TestObject testObj;
++ testObj.setObjectName("testObject");
++ channel.registerObject(testObj.objectName(), &testObj);
++ channel.connectTo(&transport1);
++ channel.connectTo(&transport2);
++
++ testObj.setProp("Hello");
++
++ publisher->initializeClient(&transport1);
++ publisher->initializeClient(&transport2);
++ publisher->setClientIsIdle(true, &transport1);
++ QCOMPARE(publisher->isClientIdle(&transport1), true);
++ QCOMPARE(publisher->isClientIdle(&transport2), false);
++ QVERIFY(transport1.messagesSent().isEmpty());
++ QVERIFY(transport2.messagesSent().isEmpty());
++
++ testObj.setProp("World");
++ QTRY_COMPARE_WITH_TIMEOUT(transport1.messagesSent().size(), 1u, 2000);
++ QCOMPARE(transport2.messagesSent().size(), 0u);
++ publisher->setClientIsIdle(true, &transport2);
++ QTRY_COMPARE_WITH_TIMEOUT(transport2.messagesSent().size(), 1u, 2000);
++ QCOMPARE(publisher->isClientIdle(&transport1), false);
++ QCOMPARE(publisher->isClientIdle(&transport2), false);
++
++ testObj.setProp("!!!");
++ publisher->setClientIsIdle(true, &transport2);
++ QCOMPARE(publisher->isClientIdle(&transport2), true);
++ QCOMPARE(publisher->isClientIdle(&transport1), false);
++ QTRY_COMPARE_WITH_TIMEOUT(transport2.messagesSent().size(), 2u, 2000);
++ QCOMPARE(transport1.messagesSent().size(), 1u);
++ publisher->setClientIsIdle(true, &transport1);
++ QTRY_COMPARE_WITH_TIMEOUT(transport1.messagesSent().size(), 2u, 2000);
++ QCOMPARE(publisher->isClientIdle(&transport1), false);
++ QCOMPARE(publisher->isClientIdle(&transport2), false);
++}
++
+ class FunctionWrapper : public QObject
+ {
+ Q_OBJECT
+@@ -1082,7 +1124,7 @@ void TestWebChannel::benchInitializeClients()
+
+ publisher->propertyUpdatesInitialized = false;
+ publisher->signalToPropertyMap.clear();
+- publisher->signalHandler.clear();
++ publisher->signalHandlers.clear();
+ }
+ }
+
+@@ -1107,7 +1149,7 @@ void TestWebChannel::benchPropertyUpdates()
+ obj->change();
+ }
+
+- channel.d_func()->publisher->clientIsIdle = true;
++ channel.d_func()->publisher->setClientIsIdle(true, m_dummyTransport);
+ channel.d_func()->publisher->sendPendingPropertyUpdates();
+ }
+ }
+diff --git a/qtwebchannel/tests/auto/webchannel/tst_webchannel.h b/qtwebchannel/tests/auto/webchannel/tst_webchannel.h
+index eae21f4..dd4e690 100644
+--- a/qtwebchannel/tests/auto/webchannel/tst_webchannel.h
++++ b/qtwebchannel/tests/auto/webchannel/tst_webchannel.h
+@@ -348,6 +348,7 @@ private slots:
+ void testJsonToVariant();
+ void testInfiniteRecursion();
+ void testAsyncObject();
++ void testPropertyMultipleTransports();
+ void testDeletionDuringMethodInvocation_data();
+ void testDeletionDuringMethodInvocation();
+
+Submodule qtwebengine f328054d...38e0df6c (commits not present)
+Submodule qtwebsockets 65850954..63fb8da1:
+diff --git a/qtwebsockets/src/websockets/qwebsocketdataprocessor.cpp b/qtwebsockets/src/websockets/qwebsocketdataprocessor.cpp
+index 2affdd5..95f1194 100644
+--- a/qtwebsockets/src/websockets/qwebsocketdataprocessor.cpp
++++ b/qtwebsockets/src/websockets/qwebsocketdataprocessor.cpp
+@@ -273,6 +273,7 @@ void QWebSocketDataProcessor::clear()
+ if (!m_pConverterState)
+ m_pConverterState = new QTextCodec::ConverterState(QTextCodec::ConvertInvalidToNull |
+ QTextCodec::IgnoreHeader);
++ frame.clear();
+ }
+
+ /*!
+diff --git a/qtwebsockets/src/websockets/qwebsocketprotocol.cpp b/qtwebsockets/src/websockets/qwebsocketprotocol.cpp
+index df87a93..d0465f1 100644
+--- a/qtwebsockets/src/websockets/qwebsocketprotocol.cpp
++++ b/qtwebsockets/src/websockets/qwebsocketprotocol.cpp
+@@ -210,7 +210,7 @@ void QWebSocketProtocol::mask(char *payload, quint64 size, quint32 maskingKey)
+ quint8((maskingKey & 0x0000FF00u) >> 8),
+ quint8((maskingKey & 0x000000FFu))
+ };
+- int i = 0;
++ quint64 i = 0;
+ while (size-- > 0)
+ *payload++ ^= mask[i++ % 4];
+ }
diff --git a/srcpkgs/qt5/template b/srcpkgs/qt5/template
index a79d25e69da8..6dddce7f3e46 100644
--- a/srcpkgs/qt5/template
+++ b/srcpkgs/qt5/template
@@ -2,11 +2,11 @@
#
# revbump libqtxdg after bumping patch version
pkgname=qt5
-version=5.15.7+20221119
+version=5.15.8
+revision=1
+build_style=meta
# commit f8c9fb304bc3e53b3aa07f962cd74e9160decccc
# base repo: https://invent.kde.org/qt/qt/qt5
-revision=5
-build_style=meta
hostmakedepends="cmake clang flex perl glib-devel pkg-config
python re2c ruby which"
makedepends="SDL2-devel Vulkan-Headers alsa-lib-devel double-conversion-devel
@@ -29,8 +29,9 @@ homepage="https://qt.io/"
# tarball is generated