Github messages for voidlinux
 help / color / mirror / Atom feed
From: zlice <zlice@users.noreply.github.com>
To: ml@inbox.vuxu.org
Subject: Re: [PR PATCH] [Updated] ffmpeg6 split
Date: Tue, 17 Oct 2023 14:58:26 +0200	[thread overview]
Message-ID: <20231017125826.wVNPX1WoUgzSJVKIYcdJc5D7NgZEuuuBagC9Hk_x3dM@z> (raw)
In-Reply-To: <gh-mailinglist-notifications-41a7ca26-5023-4802-975b-f1789d68868e-void-packages-43761@inbox.vuxu.org>

[-- Attachment #1: Type: text/plain, Size: 3573 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 (https://github.com/audacity/audacity/issues/2305 and https://sourceforge.net/p/portmedia/wiki/portsmf/ is 'beta')
- 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

- ~~[shotcut 23.05.14](https://github.com/void-linux/void-packages/pull/44260)~~

- https://github.com/void-linux/void-packages/pull/44781 will remove from this PR

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: 788049 bytes --]

From ed3ee32214a7527d2050841a1befc63390738e1b Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Sun, 15 Oct 2023 21:16:56 -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 ------
 ...h-libavcodec-libsvtav1-ten_bit_format.diff | 40 -------------
 .../workaround-mesa-readeon-vaapi-bug.patch   | 28 ---------
 srcpkgs/ffmpeg/template                       | 38 ++++++------
 6 files changed, 37 insertions(+), 173 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/patch-libavcodec-libsvtav1-ten_bit_format.diff
 delete mode 100644 srcpkgs/ffmpeg/patches/workaround-mesa-readeon-vaapi-bug.patch

diff --git a/common/shlibs b/common/shlibs
index 67ecffb1effa3..2fecdb6e90491 100644
--- a/common/shlibs
+++ b/common/shlibs
@@ -385,15 +385,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 9c57200463320..0000000000000
--- 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 9a55178c74f0f..0000000000000
--- 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/patch-libavcodec-libsvtav1-ten_bit_format.diff b/srcpkgs/ffmpeg/patches/patch-libavcodec-libsvtav1-ten_bit_format.diff
deleted file mode 100644
index aa948f7a8a2df..0000000000000
--- a/srcpkgs/ffmpeg/patches/patch-libavcodec-libsvtav1-ten_bit_format.diff
+++ /dev/null
@@ -1,40 +0,0 @@
-#==================================================================================================
-# From 031f1561cd286596cdb374da32f8aa816ce3b135 Mon Sep 17 00:00:00 2001
-# From: Christopher Degawa <christopher.degawa@intel.com>
-# Date: Thu, 20 Oct 2022 22:55:27 -0500
-# Subject: [PATCH] avcodec/libsvtav1: remove compressed_ten_bit_format and simplify alloc_buffer
-#
-# compressed_ten_bit_format has been deprecated upstream and has no effect
-# and can be removed. Plus, technically it was never used in the first place
-# since it would require the app (ffmpeg) to set it and do additional
-# processing of the input frames.
-#
-# Also simplify alloc_buffer by removing calculations relating to the non-existant processing.
-#
-# Signed-off-by: Christopher Degawa <christopher.degawa@intel.com>
-#==================================================================================================
---- a/libavcodec/libsvtav1.c
-+++ b/libavcodec/libsvtav1.c
-@@ -124,16 +124,12 @@ static int svt_print_error(void *log_ctx, EbErrorType err,
- 
- static int alloc_buffer(EbSvtAv1EncConfiguration *config, SvtContext *svt_enc)
- {
--    const int    pack_mode_10bit =
--        (config->encoder_bit_depth > 8) && (config->compressed_ten_bit_format == 0) ? 1 : 0;
--    const size_t luma_size_8bit  =
--        config->source_width * config->source_height * (1 << pack_mode_10bit);
--    const size_t luma_size_10bit =
--        (config->encoder_bit_depth > 8 && pack_mode_10bit == 0) ? luma_size_8bit : 0;
-+    const size_t luma_size = config->source_width * config->source_height *
-+        (config->encoder_bit_depth > 8 ? 2 : 1);
- 
-     EbSvtIOFormat *in_data;
- 
--    svt_enc->raw_size = (luma_size_8bit + luma_size_10bit) * 3 / 2;
-+    svt_enc->raw_size = luma_size * 3 / 2;
- 
-     // allocate buffer for in and out
-     svt_enc->in_buf           = av_mallocz(sizeof(*svt_enc->in_buf));
--- 
-GitLab
-
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 00e3f68a415b8..0000000000000
--- 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 d2f8def0e25f7..c1f9b7efe40e3 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.4
-revision=3
+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=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,9 +40,13 @@ 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"
+	i686*)
 		build_options_default+=" vaapi vdpau nvenc nvdec"
+		hostmakedepends+=" nasm"
+		;;
+	x86_64*)
+		hostmakedepends+=" nasm"
+		build_options_default+=" vaapi vdpau nvenc nvdec onevpl"
 		;;
 	ppc64*) build_options_default+=" vaapi vdpau";;
 	mips*) CFLAGS="-mnan=legacy";;
@@ -115,18 +120,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() {
@@ -153,10 +159,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() {
@@ -210,15 +214,13 @@ 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"
 	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

From 834c394f3fecc46e4916b38fff8edfe700b20c4b Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Sun, 15 Oct 2023 21:17:26 -0400
Subject: [PATCH 002/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 b21e22334316e..16a1b98304790 100644
--- a/srcpkgs/baresip/template
+++ b/srcpkgs/baresip/template
@@ -1,7 +1,7 @@
 # Template file for 'baresip'
 pkgname=baresip
 version=2.10.0
-revision=2
+revision=3
 build_style=cmake
 hostmakedepends="pkg-config glib-devel"
 makedepends="libgsm-devel libpng-devel openssl-devel libsndfile-devel

From e98a68f35e5fd9b9528926850645413b5c3d3aa0 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Sun, 15 Oct 2023 21:18:14 -0400
Subject: [PATCH 003/115] openshot: revbump for ffmpeg6.0

---
 srcpkgs/openshot/template | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/srcpkgs/openshot/template b/srcpkgs/openshot/template
index 8f47851eef354..affb652a9d500 100644
--- a/srcpkgs/openshot/template
+++ b/srcpkgs/openshot/template
@@ -1,7 +1,7 @@
 # Template file for 'openshot'
 pkgname=openshot
 version=3.0.0
-revision=2
+revision=3
 build_style=python3-module
 hostmakedepends="python3 python3-setuptools"
 makedepends="ffmpeg-devel python3-PyQt5"

From 59ac1f84dc81330ceea08b6c6fe0c155f3806c18 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Sun, 15 Oct 2023 21:18:36 -0400
Subject: [PATCH 004/115] sumo: revbump for ffmpeg6.0

---
 srcpkgs/sumo/template | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/srcpkgs/sumo/template b/srcpkgs/sumo/template
index a3fe134aa5acc..a730afa9fafa9 100644
--- a/srcpkgs/sumo/template
+++ b/srcpkgs/sumo/template
@@ -1,7 +1,7 @@
 # Template file for 'sumo'
 pkgname=sumo
 version=1.12.0
-revision=6
+revision=7
 build_style=cmake
 hostmakedepends="libgdal-tools pkg-config swig python3-setuptools"
 makedepends="python3-devel ffmpeg-devel fox-devel gl2ps-devel libgdal-devel

From 53204644690a3947a6405b3a353c69d657cf048e Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 19:56:22 -0400
Subject: [PATCH 005/115] New package: ffmpeg4-4.4.4.

---
 srcpkgs/ffmpeg4-devel                         |   1 +
 srcpkgs/ffmpeg4/files/altivec.patch           |  60 +++++
 .../patches/armv5tel-floating-point.patch     |  18 ++
 ...h-libavcodec-libsvtav1-ten_bit_format.diff |  40 +++
 .../workaround-mesa-readeon-vaapi-bug.patch   |  28 ++
 srcpkgs/ffmpeg4/template                      | 240 ++++++++++++++++++
 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 +
 15 files changed, 396 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/patch-libavcodec-libsvtav1-ten_bit_format.diff
 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 0000000000000..887f354e7c6be
--- /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 0000000000000..9c57200463320
--- /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 0000000000000..9a55178c74f0f
--- /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/patch-libavcodec-libsvtav1-ten_bit_format.diff b/srcpkgs/ffmpeg4/patches/patch-libavcodec-libsvtav1-ten_bit_format.diff
new file mode 100644
index 0000000000000..aa948f7a8a2df
--- /dev/null
+++ b/srcpkgs/ffmpeg4/patches/patch-libavcodec-libsvtav1-ten_bit_format.diff
@@ -0,0 +1,40 @@
+#==================================================================================================
+# From 031f1561cd286596cdb374da32f8aa816ce3b135 Mon Sep 17 00:00:00 2001
+# From: Christopher Degawa <christopher.degawa@intel.com>
+# Date: Thu, 20 Oct 2022 22:55:27 -0500
+# Subject: [PATCH] avcodec/libsvtav1: remove compressed_ten_bit_format and simplify alloc_buffer
+#
+# compressed_ten_bit_format has been deprecated upstream and has no effect
+# and can be removed. Plus, technically it was never used in the first place
+# since it would require the app (ffmpeg) to set it and do additional
+# processing of the input frames.
+#
+# Also simplify alloc_buffer by removing calculations relating to the non-existant processing.
+#
+# Signed-off-by: Christopher Degawa <christopher.degawa@intel.com>
+#==================================================================================================
+--- a/libavcodec/libsvtav1.c
++++ b/libavcodec/libsvtav1.c
+@@ -124,16 +124,12 @@ static int svt_print_error(void *log_ctx, EbErrorType err,
+ 
+ static int alloc_buffer(EbSvtAv1EncConfiguration *config, SvtContext *svt_enc)
+ {
+-    const int    pack_mode_10bit =
+-        (config->encoder_bit_depth > 8) && (config->compressed_ten_bit_format == 0) ? 1 : 0;
+-    const size_t luma_size_8bit  =
+-        config->source_width * config->source_height * (1 << pack_mode_10bit);
+-    const size_t luma_size_10bit =
+-        (config->encoder_bit_depth > 8 && pack_mode_10bit == 0) ? luma_size_8bit : 0;
++    const size_t luma_size = config->source_width * config->source_height *
++        (config->encoder_bit_depth > 8 ? 2 : 1);
+ 
+     EbSvtIOFormat *in_data;
+ 
+-    svt_enc->raw_size = (luma_size_8bit + luma_size_10bit) * 3 / 2;
++    svt_enc->raw_size = luma_size * 3 / 2;
+ 
+     // allocate buffer for in and out
+     svt_enc->in_buf           = av_mallocz(sizeof(*svt_enc->in_buf));
+-- 
+GitLab
+
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 0000000000000..00e3f68a415b8
--- /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 0000000000000..f2c851693d367
--- /dev/null
+++ b/srcpkgs/ffmpeg4/template
@@ -0,0 +1,240 @@
+# 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 vmaf-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
+
+	vsed -i libavfilter/vf_libvmaf.c -e 's!/usr/local/share/model/\(vmaf_v0.6.1\).pkl!/usr/share/vmaf/\1.json!'
+}
+
+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} --enable-libvmaf ${_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 0000000000000..887f354e7c6be
--- /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 0000000000000..887f354e7c6be
--- /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 0000000000000..887f354e7c6be
--- /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 0000000000000..887f354e7c6be
--- /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 0000000000000..887f354e7c6be
--- /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 0000000000000..887f354e7c6be
--- /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 0000000000000..887f354e7c6be
--- /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 0000000000000..887f354e7c6be
--- /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 0000000000000..887f354e7c6be
--- /dev/null
+++ b/srcpkgs/libswscale4
@@ -0,0 +1 @@
+ffmpeg4
\ No newline at end of file

From 42dd38b3a6d675cd2a2347fd8daa228574f7bbca Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 19:59:04 -0400
Subject: [PATCH 006/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 2fecdb6e90491..b1ba1497c8295 100644
--- a/common/shlibs
+++ b/common/shlibs
@@ -2085,58 +2085,58 @@ libcapstone.so.5 capstone-5.0.1_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 8a7eb6a5ddc5b..ce94de9424d18 100644
--- a/srcpkgs/opencv/template
+++ b/srcpkgs/opencv/template
@@ -1,7 +1,7 @@
 # Template file for 'opencv'
 pkgname=opencv
-version=4.6.0
-revision=5
+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 41c7c9bbe6807562561012951eea22f6a19ee367 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 19:59:45 -0400
Subject: [PATCH 007/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 cf5f0b7a2ae61..0d899311e6df7 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 f28db043f12a9565b568045ac29a382ca104735d 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] 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 7eb30db33992c..dd341dfe1bfce 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 a9da5030f2716284f4dfdb4b686e8b67916b22fe 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] 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 bb17569277a7f..49e2c1cbe8a53 100644
--- a/srcpkgs/retroshare/template
+++ b/srcpkgs/retroshare/template
@@ -1,7 +1,7 @@
 # Template file for 'retroshare'
 pkgname=retroshare
 version=0.6.6
-revision=3
+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 39ba2f409885c895cb55d3c86d653de86eb58f3c Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 19:59:46 -0400
Subject: [PATCH 010/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 361b8a23b9497..c5ac17eb54ea4 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 87300e7d4c4be3eb5468c86123dad5a16b28bb5b Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:00:38 -0400
Subject: [PATCH 011/115] vlc: revbump for ffmpeg4-4.4.3

---
 srcpkgs/vlc/template | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/srcpkgs/vlc/template b/srcpkgs/vlc/template
index be579ce38fe37..3974289947401 100644
--- a/srcpkgs/vlc/template
+++ b/srcpkgs/vlc/template
@@ -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 660e31eb40c2d97a77b743a34bc81f6daebd283e Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:00:55 -0400
Subject: [PATCH 012/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 a9ebbd287933b..755793f7e11bf 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 8c1e4eae456d1a0ffc9c249f57da237669063aa2 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:13 -0400
Subject: [PATCH 013/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 f713eff49b07c..ed6194c17d11e 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 caab744d220142b187e333753320a009d4f9e3ae 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] 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 a63e271ef83b8..5ee04171b51e8 100644
--- a/srcpkgs/QMPlay2/template
+++ b/srcpkgs/QMPlay2/template
@@ -1,7 +1,7 @@
 # Template file for 'QMPlay2'
 pkgname=QMPlay2
 version=23.09.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 d718b662bfa37c8c4befd6a76fc1fd9f5fd23b75 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] 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 0bfa6d9fd2643..a5708a7d82a8f 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 c3b9c60b3c69745acc077b4245fba86c599b8013 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] 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 efd0afe10576d..b91e6900d42a1 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 91505beaf9c1f000e0c73d718266dfd02f873be1 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] 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 26144e931a3c7..e760bf0d18aec 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 b3b622e55d8724157b2aea332e226fdcf7e8d55b 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] 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 0000000000000..aace41a6e6d9a
--- /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 ad1c4b2569917..7d875cc02541a 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 38131cbbe30cdd9e8e025ceb1dc6e8ba01b7a0d9 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] 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 0000000000000..4e5e34099d71c
--- /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 88cbc1671fc6a..beebfae59ed44 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 16fa6d09bee3865b9b4ea03b7715b7ba1d5763ac 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] audacity: revbump for ffmpeg4-4.4.3

---
 srcpkgs/audacity/template | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/srcpkgs/audacity/template b/srcpkgs/audacity/template
index 73314e6232bd6..df26db1c15873 100644
--- a/srcpkgs/audacity/template
+++ b/srcpkgs/audacity/template
@@ -1,7 +1,7 @@
 # Template file for 'audacity'
 pkgname=audacity
 version=3.3.3
-revision=1
+revision=2
 build_style=cmake
 build_helper="cmake-wxWidgets-gtk3 qemu"
 configure_args="-Daudacity_use_ffmpeg=loaded -Daudacity_lib_preference=system
@@ -10,7 +10,7 @@ configure_args="-Daudacity_use_ffmpeg=loaded -Daudacity_lib_preference=system
  -Daudacity_has_vst3=no"
 hostmakedepends="pkg-config gettext python3"
 makedepends="wxWidgets-gtk3-devel gtk+3-devel expat-devel lame-devel
- libsoxr-devel portaudio-devel sqlite-devel libcurl-devel ffmpeg-devel
+ libsoxr-devel portaudio-devel sqlite-devel libcurl-devel ffmpeg4-devel
  libid3tag-devel libmad-devel vamp-plugin-sdk-devel libogg-devel
  libvorbis-devel libflac-devel lilv-devel lv2 serd-devel sord-devel
  sratom-devel suil-devel portmidi-devel soundtouch-devel twolame-devel

From ce998bb6f3f08d8dd8c43e5b1555c56e43218190 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] 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 253a0243e2259..557285982d2b8 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 75ad5f359879a752012caa99f6a46c44f386e787 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

---
 srcpkgs/blender/template | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/srcpkgs/blender/template b/srcpkgs/blender/template
index fc6bd5fe25ce0..eea897d828a74 100644
--- a/srcpkgs/blender/template
+++ b/srcpkgs/blender/template
@@ -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 7254f69d992cb0a3c1dd593f8a19b6407298af5b 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 4b417d80d5c2d..8a90aaa4c07a2 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 85cf437e4bb04a97eb0eafe47dba76272508997a 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 9abcd82852b27..6eccad5885af9 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 b6ebe1d35cdf91cf63af6c17ae8fd6a44451f67f 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 0000000000000..a9fd307a23c8a
--- /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 7ef7838949f3a..1f7bbc70a22c8 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 0cc399cf9c7d10c2072dcb21ef3131d344d129c5 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-118-ffmpeg-4.4.patch     | 22 ---------
 srcpkgs/chromium/patches/ffmpeg5.patch        | 47 +++++++++++++++++++
 srcpkgs/chromium/template                     |  2 +-
 3 files changed, 48 insertions(+), 23 deletions(-)
 delete mode 100644 srcpkgs/chromium/patches/chromium-118-ffmpeg-4.4.patch
 create mode 100644 srcpkgs/chromium/patches/ffmpeg5.patch

diff --git a/srcpkgs/chromium/patches/chromium-118-ffmpeg-4.4.patch b/srcpkgs/chromium/patches/chromium-118-ffmpeg-4.4.patch
deleted file mode 100644
index 556c734d4e02e..0000000000000
--- a/srcpkgs/chromium/patches/chromium-118-ffmpeg-4.4.patch
+++ /dev/null
@@ -1,22 +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
-@@ -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 0000000000000..24e2da38e34ca
--- /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 cc36911cd338d..c63eb330d1da8 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=118.0.5993.70
-revision=1
+revision=2
 archs="i686* x86_64* aarch64* armv7l*"
 hostmakedepends="
  $(vopt_if clang "clang lld llvm15")

From fcf5777fbdd19b6d4b59ffb6c93f94170d04699a 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 0000000000000..ffa95ab811101
--- /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 dc8a5e5d434cd..f664076170960 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 2e856fc70a555867f00de489106c799a05ab28dc 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 9796e3461601a..5db30e020d17e 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 146c11b9e5d0800f8dafcebdd1f67767d3d415ec 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 b664bb1b9bd9f..165b3c7b9cad8 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 442c0b5441e6787059ea76477f55c7812e86ba00 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 b4c8b64368a4b..070993aac31d2 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.19368
-revision=1
+revision=2
 _dolphin_commit=dadbeb4bae7e7fa23af2b46e0add4143094dc107
 _mgba_commit=44e074a15e9651481f7f652ac006a7c9d58cbeb9
 _googletest_commit=be03d00f5f0cc3a997d1a368bee8a1fe93651f48

From b7c2d2f5fbe24b79dc701b3d8d0e17b2f05120a0 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 fc9c9bf6b9d54..fb0480754df4d 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 116d3ae7ef1d551dae6d21c4b82c1cc56a512f30 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 1c3f1b8b1fc67..32a9220b79a4d 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 ef4bedf70c5f64ae02a0d161be69cf5e576b56e7 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:47 -0400
Subject: [PATCH 033/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 0000000000000..363ff35a28419
--- /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 039eea7622b39..35d546018d12a 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 bea2a911cf13d01c6250edf60cf802f8f3e427eb 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] 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 5f0b9414dadaf..11b88193528f4 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 bb3e0b1237fc53a8624ff8b91af4f45d780a7cee 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] 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 0000000000000..1479fabcafcb4
--- /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 365f64d10cbab..1641ecf43be5b 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 77532a95c17cef5e8e9e88545cbd4d33b93daa7b 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] freerdp: revbump for ffmpeg-6.0

---
 .../freerdp/patches/ffmpeg6_aa2cb9aa.patch    | 42 +++++++++++++++++++
 1 file changed, 42 insertions(+)
 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 0000000000000..a4324da3a8822
--- /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
+ 

From c0079489eea9d97e2acbcf95a8003a2289a7f049 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] 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 ae14f35c767c0..2dc0ac0ce03b5 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 e08e7866b7f3def5d5e40b37e3a6df9a15fc6358 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] goldendict: revbump for ffmpeg-6.0

---
 srcpkgs/goldendict/template | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/srcpkgs/goldendict/template b/srcpkgs/goldendict/template
index f4a05759f693d..97f44347b03a6 100644
--- a/srcpkgs/goldendict/template
+++ b/srcpkgs/goldendict/template
@@ -1,7 +1,7 @@
 # Template file for 'goldendict'
 pkgname=goldendict
 version=1.5.0
-revision=1
+revision=2
 build_style=qmake
 configure_args="CONFIG+=zim_support goldendict.pro"
 hostmakedepends="qt5-qmake pkg-config qt5-host-tools"
@@ -10,7 +10,7 @@ makedepends="tiff-devel qt5-devel libvorbis-devel zlib-devel
  qt5-webkit-devel lzo-devel bzip2-devel libao-devel qt5-svg-devel
  libeb-devel qt5-x11extras-devel ffmpeg-devel liblzma-devel
  qt5-multimedia-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 93620d833621b895bc7a833201fa5532e9a9cd28 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] 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 37485f6f6a9e8..f610e966f23cd 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.5
-revision=1
+revision=2
 build_style=meson
 hostmakedepends="pkg-config yasm"
 makedepends="orc-devel gst-plugins-base1-devel ffmpeg-devel"

From 6193a5120a20e693627384f8ff5ad031f019edc8 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-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 f266f4777b3ea..011444eb26739 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.22.5
-revision=1
+revision=2
 build_style=meson
 hostmakedepends="pkg-config python3"
 makedepends="glib-devel gst-plugins-bad1-devel gobject-introspection

From a913441ac44e7c934bea488a9998bbc7aa0f86e7 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] 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 0000000000000..503c2af3b78c1
--- /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 345cf6006f246..86a7fd619612c 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 c9c9189fa25f5b33aaa1113d1e0d02d6709d9a2f Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:48 -0400
Subject: [PATCH 042/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 26db03867a0c8..d6bb2eda627a3 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 0000000000000..298f9f4ab28f2
--- /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 ca5e4571e49c3..c32cb1bfa31f4 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 8da3ada09f919d81a857b797ed79cfdaef873c3d Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:48 -0400
Subject: [PATCH 043/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 15a1df6d8861d..d1b7290bfdc19 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 aefabb8a5c33c4f839b2c0f54dda0546ac4a0c32 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] idjc: revbump for ffmpeg4-4.4.3

---
 srcpkgs/idjc/template | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/srcpkgs/idjc/template b/srcpkgs/idjc/template
index b205e74745fe1..36a75baf597c5 100644
--- a/srcpkgs/idjc/template
+++ b/srcpkgs/idjc/template
@@ -5,7 +5,7 @@ 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 1d867e5ccc5d5d6d0875f3e82e5a78178a8e0122 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] 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 c034d62deec8f..e6e9fe11aa55d 100644
--- a/srcpkgs/kfilemetadata5/template
+++ b/srcpkgs/kfilemetadata5/template
@@ -1,7 +1,7 @@
 # Template file for 'kfilemetadata5'
 pkgname=kfilemetadata5
 version=5.110.0
-revision=1
+revision=2
 build_style=cmake
 hostmakedepends="kcoreaddons extra-cmake-modules pkg-config qt5-host-tools qt5-qmake
  gettext kcoreaddons python3"

From db091b5866d46f17351c987cbfcc512e6469ad7f 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] 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 0000000000000..135fc50e07c9b
--- /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 456206d90e16a..f32f9decb0e7f 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 c88d709b62f36601bda42395a2c4a2fbcfc83e38 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] kodi: revbump for ffmpeg4-4.4.3

---
 srcpkgs/kodi/template | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/srcpkgs/kodi/template b/srcpkgs/kodi/template
index 8ef6bc85ed3b4..788a0ac978af8 100644
--- a/srcpkgs/kodi/template
+++ b/srcpkgs/kodi/template
@@ -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 1a0e9d75eaa6074d3ac88f0678a8a469b0ffe669 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] 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 216069507f54b..1173d36348d16 100644
--- a/srcpkgs/kpipewire/template
+++ b/srcpkgs/kpipewire/template
@@ -1,7 +1,7 @@
 # Template file for 'kpipewire'
 pkgname=kpipewire
 version=5.27.8
-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 ce76c1d5b0ab2a63233176fde0f1fa15e3a5c03d 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] 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 ddd4790f93e88..1fb9ca56a96ae 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 0f191f3e47b894a60c78ae92f18184276ee4d924 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] 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 77218f9e539df..3f49ed75a1fdc 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 4730a179a4362839afd1ac6e1607027e196d3b95 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] 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 0000000000000..16d4510ee98fa
--- /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 da4f2d56e94c3..4d6bf29efb4fd 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 7db538c2d7a27c2e3551f658d268c67b7600408e 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] mediastreamer: revbump for ffmpeg4-4.4.3

---
 srcpkgs/mediastreamer/template | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/srcpkgs/mediastreamer/template b/srcpkgs/mediastreamer/template
index d29210c1bf9c7..1bde031443a59 100644
--- a/srcpkgs/mediastreamer/template
+++ b/srcpkgs/mediastreamer/template
@@ -5,7 +5,7 @@ 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 5f911de852675eb68c1a926625fc1f3ec3e4828f 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] 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 5513e3fd16f3f..f5c87a4893002 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 c28ac3180d19b2ccbe980b10d702c91f7e912bfb 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] 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 d551e49ed4653..5fa929f3a0c12 100644
--- a/srcpkgs/minidlna/template
+++ b/srcpkgs/minidlna/template
@@ -1,7 +1,7 @@
 # Template file for 'minidlna'
 pkgname=minidlna
 version=1.3.3
-revision=1
+revision=2
 build_style=gnu-configure
 configure_args="
  --sbindir=/usr/bin

From 86942d94c9ccaec7cbe7dbe79ef570d39f79307d Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:49 -0400
Subject: [PATCH 055/115] mlt: revbump for ffmpeg4-4.4.3

---
 srcpkgs/mlt/template | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/srcpkgs/mlt/template b/srcpkgs/mlt/template
index f14dd85d1c9dc..f0b3af193db2c 100644
--- a/srcpkgs/mlt/template
+++ b/srcpkgs/mlt/template
@@ -8,7 +8,7 @@ configure_args="--prefix=/usr --libdir=/usr/lib$XBPS_TARGET_WORDSIZE
  --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"

From aae43732ec52321baf775252329cd2539e0d0804 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:49 -0400
Subject: [PATCH 056/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 5aed5d36558d3..d8de816026b64 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 911caa49f693495f08a8c646138f22bc2fc9761e Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:49 -0400
Subject: [PATCH 057/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 3cf3c3035c5b7..7dca12d851e33 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 93872105690a713d87109ab3eb935583d0641275 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] 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 6dd8a091319f7..3110c30c9aff2 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 1543174e871324dde5b23ff48a9701973dbe21ae 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] 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 12a46936c9900..5c2917b9c5124 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 5f779f0d9593c1a64084049067c70b1f6b10bcab 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] omxplayer: revbump for ffmpeg4-4.4.3

---
 srcpkgs/omxplayer/template | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/srcpkgs/omxplayer/template b/srcpkgs/omxplayer/template
index 9a66690c83ebb..a21b878878037 100644
--- a/srcpkgs/omxplayer/template
+++ b/srcpkgs/omxplayer/template
@@ -1,7 +1,7 @@
 # Template file for 'omxplayer'
 pkgname=omxplayer
 version=20190102
-revision=2
+revision=3
 short_desc="Commandline OMX player for the Raspberry Pi"
 maintainer="Orphaned <orphan@voidlinux.org>"
 license="GPL-2.0-or-later"
@@ -15,7 +15,7 @@ checksum=af2d9450f8947842ea8c401fe9f71eec444013ebbdee29f2ac828c9c493c1329
 archs="armv6l* armv7l*"
 build_style=gnu-makefile
 hostmakedepends="ruby-ronn 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 d90b5802546404d4b1b14cdeeeb6391cf3564738 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:50 -0400
Subject: [PATCH 061/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 ee9f7603f55fd..3e81834ca0edd 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 4fdb202b2d03b37921de5857b6954be0f3ccb33e Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:50 -0400
Subject: [PATCH 062/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 e3febb821a451..1e3dc1bf9308e 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 097a91011b27e75c62b2659d2621f9b0e1e9b35f Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:50 -0400
Subject: [PATCH 063/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 2c0ded496eb98..1294ef3ae669c 100644
--- a/srcpkgs/ppsspp/template
+++ b/srcpkgs/ppsspp/template
@@ -1,7 +1,7 @@
 # Template file for 'ppsspp'
 pkgname=ppsspp
 version=1.16.6
-revision=1
+revision=2
 _glslang_commit=b34f619e1c85810dcb3c578107d2e48ba4ee2b37
 _SPIRV_Cross_commit=4212eef67ed0ca048cb726a6767185504e7695e5
 _armips_commit=7bd1ec93d4586985ba1ef420b43b5e620f68695e
@@ -15,7 +15,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_ttf-devel SDL2-devel') $(vopt_if wayland wayland-devel)
  $(vopt_if qt 'qt5-devel qt5-multimedia-devel')"
@@ -72,7 +72,7 @@ post_extract() {
         mv ${wrksrc}/rcheevos-${_rcheevos_commit} ${wrksrc}/ext/rcheevos
 }
 
-post_patch(){
+post_patch() {
 	# disable git versioning
 	vsed -e 's|find_package(Git)|# &|' -i git-version.cmake
 }
@@ -85,7 +85,6 @@ post_configure() {
 }
 
 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 3cdb7568197278b468535e655ad73e1d415c3cb9 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:50 -0400
Subject: [PATCH 064/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 542fc27a2d32a..9308d949b6a1c 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 2b6ef237ad50ffc51e9e7985f568149979a4da64 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:50 -0400
Subject: [PATCH 065/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 26c661ed16bea..a150d7441c7a6 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 a5c4585cb4f5800e4c6c9e29fcb91a0e603ce606 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:50 -0400
Subject: [PATCH 066/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 0000000000000..04adc540f2cbc
--- /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 0000000000000..ac55e1634423a
--- /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 84de5b12ecdda..b89fe4c1ad50a 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=5
+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 e1efeea029f95d3d92cddb4a2932321823fc2437 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:51 -0400
Subject: [PATCH 067/115] qt5: update to 5.15.8

---
 ...erywhere-opensource-src-5.15.8-kf5-1.patch | 12913 ++++++++++++++++
 srcpkgs/qt5/template                          |    13 +-
 2 files changed, 12919 insertions(+), 7 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 0000000000000..966c98bcd3bb1
--- /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 &current, 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 &current, 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
+-    &gt; &lt; &amp;
++    &gt; &lt; &amp; &quot; &nbsp; &apos;
+     \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 &parameters,
+                                                          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": "&copy; <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": "&copy; <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": "&copy; <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": "&copy; <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": "&copy; <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": "&copy; <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": "&copy; <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": "&copy; <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": "&copy; <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": "&copy; <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": "&copy; <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": "&copy; <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": "&copy; <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": "&copy; <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": "&copy; <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": "&copy; <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": "&copy; <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": "&copy; <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": "&copy; <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": "&copy; <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": "&copy; <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": "&copy; <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": "&copy; <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": "&copy; <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 &parameters, 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, &current_width, &current_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 b6612dffeb1b9..a0d3036af79a4 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=7
-build_style=meta
 hostmakedepends="cmake clang flex perl glib-devel pkg-config
  python3 re2c ruby which"
 makedepends="SDL2-devel Vulkan-Headers alsa-lib-devel double-conversion-devel
@@ -29,9 +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
-python_version=3
+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"
 lib32mode=full
@@ -246,7 +246,6 @@ do_configure() {
 	# opts+=" -v"
 	opts+=" -skip qtwebengine"
 	opts+=" -skip qtwebview"
-	opts+=" -skip qtdocgallery"
 	opts+=" -skip qtpim"
 	opts+=" -skip qtsystems"
 	opts+=" -skip qtspeech"

From 2a6d6bfaf0a4fc2a22639bf9a8dfad78dde48aa4 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:51 -0400
Subject: [PATCH 068/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 34c30b2c0c78f..2d00ad104355e 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 54d32c6255a15f54042b3d64b3e92bcc5ccc705d Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:51 -0400
Subject: [PATCH 069/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 39c643fecdb5a..bb70e7f51240a 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 2afbe792788a326c9638492b1b9c374cef60f3cf Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:51 -0400
Subject: [PATCH 070/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 45b02597de41a..507805ea8d819 100644
--- a/srcpkgs/retroarch/template
+++ b/srcpkgs/retroarch/template
@@ -1,7 +1,7 @@
 # Template file for 'retroarch'
 pkgname=retroarch
 version=1.15.0
-revision=4
+revision=5
 build_style=configure
 configure_args="--prefix=/usr --sysconfdir=/etc --enable-networking
  --enable-udev --disable-builtinflac --disable-builtinglslang

From cdd78db632d5dccf0e8733dc2e729fa6dcc271e0 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:51 -0400
Subject: [PATCH 071/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 ac18bc03418ce..f39a7f678ab35 100644
--- a/srcpkgs/scrcpy/template
+++ b/srcpkgs/scrcpy/template
@@ -1,7 +1,7 @@
 # Template file for 'scrcpy'
 pkgname=scrcpy
 version=2.1.1
-revision=1
+revision=2
 build_style=meson
 configure_args="-Dcompile_server=false
  -Dprebuilt_server=/usr/share/scrcpy/scrcpy-server-v${version}"

From e4143effa1a62f92027bfa869633eea99333788d Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Tue, 17 Oct 2023 08:54:11 -0400
Subject: [PATCH 072/115] New package: spex-x replaces spek-alternative for
 ffmpeg-6.0

---
 srcpkgs/spek-alternative                      |  1 +
 srcpkgs/{spek-alternative => spek-x}/template | 22 ++++++++++++-------
 2 files changed, 15 insertions(+), 8 deletions(-)
 create mode 120000 srcpkgs/spek-alternative
 rename srcpkgs/{spek-alternative => spek-x}/template (52%)

diff --git a/srcpkgs/spek-alternative b/srcpkgs/spek-alternative
new file mode 120000
index 0000000000000..76648236da701
--- /dev/null
+++ b/srcpkgs/spek-alternative
@@ -0,0 +1 @@
+spek-x
\ No newline at end of file
diff --git a/srcpkgs/spek-alternative/template b/srcpkgs/spek-x/template
similarity index 52%
rename from srcpkgs/spek-alternative/template
rename to srcpkgs/spek-x/template
index d7b55c776b1d4..3ded6c2c323e4 100644
--- a/srcpkgs/spek-alternative/template
+++ b/srcpkgs/spek-x/template
@@ -1,18 +1,18 @@
-# Template file for 'spek-alternative'
-pkgname=spek-alternative
-version=0.8.2.3
-revision=2
+# Template file for 'spek-x'
+pkgname=spek-x
+version=0.9.3
+revision=1
 build_style=gnu-configure
 hostmakedepends="automake gettext-devel intltool libtool pkg-config
  wxWidgets-common wxWidgets-gtk3-devel"
 makedepends="ffmpeg-devel wxWidgets-gtk3-devel"
 depends="ffmpeg"
 short_desc="Acoustic spectrum analyser"
-maintainer="Kartik Singh <kartik.ynwa@gmail.com>"
+maintainer="zlice <zlice555@gmail.com>"
 license="GPL-3.0-or-later"
-homepage="https://github.com/withmorten/spek-alternative"
-distfiles="https://github.com/withmorten/spek-alternative/archive/${version}.tar.gz"
-checksum="007ba4b84a310b078e378aa84c8e80783db5821437a757a488c3ecec377e6b2a"
+homepage="https://github.com/MikeWang000000/spek-x"
+distfiles="https://github.com/MikeWang000000/spek-x/archive/v${version}.tar.gz"
+checksum="7f4b109903333cdd310ab2b9176f0dc49a565891376e281a233d342cedf90ef7"
 
 CXXFLAGS="-D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64"
 
@@ -22,3 +22,9 @@ export WX_CONFIG_NAME="wx-config-gtk3"
 pre_configure() {
 	NOCONFIGURE=1 ./autogen.sh
 }
+
+spek-alternative_package() {
+	depends="spek-x"
+	short_desc+=" - transitional dummy package"
+	build_style=meta
+}

From f2c8bbfe21848329a5ac3dafd5a96c5fc4b6dd83 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:51 -0400
Subject: [PATCH 073/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 b055b9ec0774a..3448ca110eb0c 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 e952f55573b2b875a0c6e1d19ec2260a262e3d9f Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:52 -0400
Subject: [PATCH 074/115] synfig: revbump for ffmpeg-6.0 and mlt7

---
 srcpkgs/synfig/patches/ffmpeg6.patch | 71 ++++++++++++++++++++++++++++
 srcpkgs/synfig/template              |  6 +--
 2 files changed, 74 insertions(+), 3 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 0000000000000..10780b42782f4
--- /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 30109541ec4fc..703cfd7ebac84 100644
--- a/srcpkgs/synfig/template
+++ b/srcpkgs/synfig/template
@@ -2,11 +2,11 @@
 # Should be kept in sync with 'synfigstudio' and 'ETL'
 pkgname=synfig
 version=1.4.4
-revision=3
+revision=4
 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 3a6c7eff6d7a8ca6130c411102c4e808bb7b8aab Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:52 -0400
Subject: [PATCH 075/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 2a2ab763d2fdd..8fb4327535ef9 100644
--- a/srcpkgs/timg/template
+++ b/srcpkgs/timg/template
@@ -1,7 +1,7 @@
 # Template file for 'timg'
 pkgname=timg
 version=1.4.5
-revision=1
+revision=2
 build_style=cmake
 configure_args="-DWITH_OPENSLIDE_SUPPORT=off -Wno-dev"
 hostmakedepends="pkg-config git"

From eaf29fb2d77e00ad65dd1f789018aff65c514963 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:52 -0400
Subject: [PATCH 076/115] tvheadend: revbump for ffmpeg4-4.4.3

---
 srcpkgs/tvheadend/template | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/srcpkgs/tvheadend/template b/srcpkgs/tvheadend/template
index 9aea7de4ec705..012d31c4879ff 100644
--- a/srcpkgs/tvheadend/template
+++ b/srcpkgs/tvheadend/template
@@ -8,7 +8,7 @@ configure_args="--enable-dvbscan --disable-ffmpeg_static
 --disable-libx265_static --disable-libvpx_static --disable-libtheora_static
 --disable-libvorbis_static --disable-libfdkaac_static"
 hostmakedepends="gettext pkg-config python3 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 e5004758d7fb1474c034928d01aaefabaab134d0 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:52 -0400
Subject: [PATCH 077/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 38ed47a584016..1ff910e722afc 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 605a167ec1531b03fadf779870d9c8ee1f655dd4 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:52 -0400
Subject: [PATCH 078/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 9c71cefe3f8dd..2223d297c31f5 100644
--- a/srcpkgs/vba-m/template
+++ b/srcpkgs/vba-m/template
@@ -2,7 +2,7 @@
 pkgname=vba-m
 reverts=1292_2
 version=2.1.7
-revision=2
+revision=3
 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 a0188e5d69191a8e9177a2d524da92f777384322 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:52 -0400
Subject: [PATCH 079/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 fe9d33a811947..4beab2c5f9ebd 100644
--- a/srcpkgs/vice/template
+++ b/srcpkgs/vice/template
@@ -1,7 +1,7 @@
 # Template file for 'vice'
 pkgname=vice
 version=3.7.1
-revision=1
+revision=2
 build_style=gnu-configure
 configure_args="
 	$(vopt_enable sdl2 sdlui2)
@@ -26,7 +26,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 6636821b603e6384a2832cdf3378174d357023dc Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:52 -0400
Subject: [PATCH 080/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 6da88b21bf2a1..4da8058400b58 100644
--- a/srcpkgs/waypipe/template
+++ b/srcpkgs/waypipe/template
@@ -1,7 +1,7 @@
 # Template file for 'waypipe'
 pkgname=waypipe
 version=0.8.6
-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 b1788ffde3d5468150bf0b23053f4f560f74ba7f Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:52 -0400
Subject: [PATCH 081/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 cdf8d26dcb8e1..08f986b031006 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.4.1
-revision=1
+revision=2
 build_style=meson
 hostmakedepends="pkg-config scdoc wayland-devel"
 makedepends="wayland-protocols wayland-devel ffmpeg-devel libgbm-devel x264-devel

From e41809891f3df52265083881d0c2ec35b4ea1470 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 22 Mar 2023 20:01:52 -0400
Subject: [PATCH 082/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 394718b56f686..34fbff9b2f1ae 100644
--- a/srcpkgs/xpra/template
+++ b/srcpkgs/xpra/template
@@ -1,7 +1,7 @@
 # Template file for 'xpra'
 pkgname=xpra
 version=5.0.3
-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 71fa1e9da44285b80d9205f02c25dfba3dbb1790 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Fri, 31 Mar 2023 09:07:40 -0400
Subject: [PATCH 083/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 3d422a61e4891..251e057f826fb 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 a10d9848224850285561c0d5bdb8aa19f708897c Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Fri, 31 Mar 2023 09:08:40 -0400
Subject: [PATCH 084/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 b792813dba7c2..109deb171c3f7 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 422329d3821e25013d48a9f4544a2b8bbdb081c3 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Mon, 3 Apr 2023 23:31:45 -0400
Subject: [PATCH 085/115] shotcut: revbump for ffmpeg-6.0

---
 srcpkgs/shotcut/template | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/srcpkgs/shotcut/template b/srcpkgs/shotcut/template
index 7d2af7b0470b5..c416c906ff734 100644
--- a/srcpkgs/shotcut/template
+++ b/srcpkgs/shotcut/template
@@ -1,7 +1,7 @@
 # Template file for 'shotcut'
 pkgname=shotcut
 version=23.05.14
-revision=1
+revision=2
 build_style=cmake
 configure_args="-DSHOTCUT_VERSION=${version}"
 hostmakedepends="pkg-config qt6-tools-devel"

From 51f78db9f7e1810be3a08377fbb66c4bb3835251 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Mon, 3 Apr 2023 23:33:30 -0400
Subject: [PATCH 086/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 0000000000000..efcf3249bd885
--- /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 883d6a084d868..f3c06ec245a1f 100644
--- a/srcpkgs/shiboken2/template
+++ b/srcpkgs/shiboken2/template
@@ -1,7 +1,7 @@
 # Template file for 'shiboken2'
 pkgname=shiboken2
 version=5.15.10
-revision=1
+revision=2
 _pkgname="pyside-setup-opensource-src-${version}"
 build_wrksrc="sources/shiboken2"
 build_style=cmake

From f45cea2a149c5321859ccd3bd20d0c07cbadd866 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Mon, 3 Apr 2023 23:33:53 -0400
Subject: [PATCH 087/115] python3-pyside2: revbump for qt5-5.15.8

---
 .../patches/importlib-machinery-bypass.patch      | 15 +++++++++++++++
 srcpkgs/python3-pyside2/template                  |  2 +-
 2 files changed, 16 insertions(+), 1 deletion(-)
 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 0000000000000..64c429584776b
--- /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 249efa9098842..52626436ce75f 100644
--- a/srcpkgs/python3-pyside2/template
+++ b/srcpkgs/python3-pyside2/template
@@ -1,7 +1,7 @@
 # Template file for 'python3-pyside2'
 pkgname=python3-pyside2
 version=5.15.10
-revision=1
+revision=2
 _pkgname="pyside-setup-opensource-src-${version}"
 build_wrksrc="sources/pyside2"
 build_style=cmake

From deb52dd8eac9505b9b9ae7d251f0d186687cdc21 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Tue, 4 Apr 2023 11:14:35 -0400
Subject: [PATCH 088/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 abfa59e6b7ded..3cc29c12dc1db 100644
--- a/srcpkgs/konqueror/template
+++ b/srcpkgs/konqueror/template
@@ -1,11 +1,11 @@
 # Template file for 'konqueror'
 pkgname=konqueror
 version=23.08.2
-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 e3c6d504119a51c9f0ebfca087e6ad8387bc5a7e Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Tue, 4 Apr 2023 11:14:58 -0400
Subject: [PATCH 089/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 3ecd10d50650c..2d7d4d4d24535 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 4cd32e338ee9dd1c28f908e94b4707420ae6ea49 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Tue, 4 Apr 2023 18:38:50 -0400
Subject: [PATCH 090/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 96ed97d12cd24..30d93660a2a4e 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 65e9675548546971da2f8864cf96f8ace0f28cd0 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Sun, 7 May 2023 20:15:03 -0400
Subject: [PATCH 091/115] qt6-webengine: revbump for ffmpeg-6.0

---
 srcpkgs/qt6-webengine/template | 1 +
 1 file changed, 1 insertion(+)

diff --git a/srcpkgs/qt6-webengine/template b/srcpkgs/qt6-webengine/template
index a92b06c6f0cca..14a9bfc082935 100644
--- a/srcpkgs/qt6-webengine/template
+++ b/srcpkgs/qt6-webengine/template
@@ -146,6 +146,7 @@ pre_install() {
 }
 
 post_install() {
+	vlicense LICENSES/BSD-3-Clause.txt
 	local _file
 	find "${DESTDIR}"/usr/lib/qt6/examples \
 		-path '*/lib/qt6/**/lib/qt6/*' -type f |

From a01d4ec81d9fae33cd68ece32d8a6138a99d1723 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Sun, 21 May 2023 12:44:11 -0400
Subject: [PATCH 092/115] electron24: revbump for ffmpeg-6.0

---
 srcpkgs/electron24/template | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/srcpkgs/electron24/template b/srcpkgs/electron24/template
index 59e078a7b47cb..a9c865c19c989 100644
--- a/srcpkgs/electron24/template
+++ b/srcpkgs/electron24/template
@@ -1,7 +1,7 @@
 # Template file for 'electron24'
 pkgname=electron24
 version=24.3.0
-revision=1
+revision=2
 _nodever=18.14.0
 _chromiumver=112.0.5615.165
 archs="x86_64* aarch64*"

From 8e5dce12892e45e014f54fab16cba20925274161 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Sat, 3 Jun 2023 08:20:22 -0400
Subject: [PATCH 093/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 6a4e20357a86f..ec0c13d2cc5b0 100644
--- a/srcpkgs/gtk4/template
+++ b/srcpkgs/gtk4/template
@@ -1,7 +1,7 @@
 # Template file for 'gtk4'
 pkgname=gtk4
 version=4.12.3
-revision=1
+revision=2
 build_style=meson
 build_helper="gir"
 configure_args="-Dman-pages=true -Ddocumentation=true -Dbuild-tests=false

From 1bb28c17b7756170379430731551037c45293619 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Sun, 4 Jun 2023 11:25:50 -0400
Subject: [PATCH 094/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 4b40de20a3fe2..b18bc792c8221 100644
--- a/srcpkgs/electron19/template
+++ b/srcpkgs/electron19/template
@@ -1,7 +1,7 @@
 # Template file for 'electron19'
 pkgname=electron19
 version=19.0.8
-revision=3
+revision=4
 _nodever=16.14.2
 _chromiumver=102.0.5005.125
 archs="x86_64* aarch64* ppc64le*"

From eead3c551ec013149ab3d2f990e86d8b83038bd5 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Sun, 4 Jun 2023 11:28:26 -0400
Subject: [PATCH 095/115] siril: revbump for ffmpeg-6.0

---
 srcpkgs/siril/template | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/srcpkgs/siril/template b/srcpkgs/siril/template
index 84332f79d060d..62750dd247548 100644
--- a/srcpkgs/siril/template
+++ b/srcpkgs/siril/template
@@ -1,7 +1,7 @@
 # Template file for 'siril'
 pkgname=siril
 version=0.9.12
-revision=10
+revision=11
 build_style=gnu-configure
 hostmakedepends="pkg-config intltool autoconf automake gettext-devel"
 makedepends="fftw-devel libconfig-devel libopencv-devel libffms2-devel

From 60cdf27d87a994cc0a574847420df51a945e0608 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Sat, 10 Jun 2023 00:57:09 -0400
Subject: [PATCH 096/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 2cf997b227a45..ca39534afb7f3 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.5.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 5081fbe710a54a562631192ccbcddf885432e95e Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Thu, 22 Jun 2023 10:25:02 -0400
Subject: [PATCH 097/115] kdenlive: revbump for ffmpeg-6.0

---
 srcpkgs/kdenlive/template | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/srcpkgs/kdenlive/template b/srcpkgs/kdenlive/template
index ec5fe75860948..e69ecff31f272 100644
--- a/srcpkgs/kdenlive/template
+++ b/srcpkgs/kdenlive/template
@@ -1,7 +1,7 @@
 # Template file for 'kdenlive'
 pkgname=kdenlive
 version=23.08.2
-revision=1
+revision=2
 build_style=cmake
 hostmakedepends="
  extra-cmake-modules kconfig kcoreaddons kdoctools pkg-config python3

From 78837a74a39b9452792ad883f637d13b3e404c31 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Tue, 4 Jul 2023 09:18:23 -0400
Subject: [PATCH 098/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 0bb4034d5cc86..808953e9b543c 100644
--- a/srcpkgs/gmic/template
+++ b/srcpkgs/gmic/template
@@ -1,7 +1,7 @@
 # Template file for 'gmic'
 pkgname=gmic
 version=3.1.6
-revision=4
+revision=5
 _zart_hash=34ebf6cce0bafb98abe57cec83c4a02cd1abeca0
 create_wrksrc=yes
 build_wrksrc="src"

From f95810837325661337b477563f0613a5bb2be15d Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Tue, 4 Jul 2023 09:29:52 -0400
Subject: [PATCH 099/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 af1c5a296ef0f..09e442da9a680 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=3
+revision=4
 build_style=gnu-configure
 configure_args="--disable-update-mimedb"
 hostmakedepends="pkg-config intltool gettext synfig"

From 3dfb5dbc32fdc9df7f201fcbb02a529c1c2cfe48 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Tue, 4 Jul 2023 11:17:37 -0400
Subject: [PATCH 100/115] DELETE: intel_packages

---
 common/shlibs                                 |   2 +
 srcpkgs/intel-gmmlib/template                 |   6 +-
 ...mmon-Enable-MMC-in-free-kernel-build.patch | 125 ++++++++++++++++++
 srcpkgs/intel-media-driver/template           |   6 +-
 srcpkgs/intel-media-sdk/patches/musl.patch    |  14 ++
 srcpkgs/intel-media-sdk/template              |  37 ++++++
 srcpkgs/intel-media-sdk/update                |   1 +
 srcpkgs/libmfx                                |   1 +
 srcpkgs/libmfx-devel                          |   1 +
 srcpkgs/onevpl-devel                          |   1 +
 srcpkgs/onevpl-intel-gpu-devel                |   1 +
 srcpkgs/onevpl-intel-gpu/template             |  27 ++++
 srcpkgs/onevpl/template                       |  34 +++++
 13 files changed, 250 insertions(+), 6 deletions(-)
 create mode 100644 srcpkgs/intel-media-driver/patches/0001-Media-Common-Enable-MMC-in-free-kernel-build.patch
 create mode 100644 srcpkgs/intel-media-sdk/patches/musl.patch
 create mode 100644 srcpkgs/intel-media-sdk/template
 create mode 100644 srcpkgs/intel-media-sdk/update
 create mode 120000 srcpkgs/libmfx
 create mode 120000 srcpkgs/libmfx-devel
 create mode 120000 srcpkgs/onevpl-devel
 create mode 120000 srcpkgs/onevpl-intel-gpu-devel
 create mode 100644 srcpkgs/onevpl-intel-gpu/template
 create mode 100644 srcpkgs/onevpl/template

diff --git a/common/shlibs b/common/shlibs
index b1ba1497c8295..24c8dc4b2354d 100644
--- a/common/shlibs
+++ b/common/shlibs
@@ -4253,6 +4253,8 @@ libgsoapssl++-2.8.124.so gsoap-2.8.124_1
 libjxl.so.0.8 libjxl-0.8.2_1
 libjxl_dec.so.0.8 libjxl-0.8.2_1
 libjxl_threads.so.0.8 libjxl-0.8.2_1
+libmfx.so.1 libmfx-22.6.4_1
+libvpl.so.2 onevpl-2023.1.2_1
 libtext-engine-0.1.so.0 text-engine-0.1.1_1
 libvmaf.so.1 vmaf-2.3.1_1
 liblc3.so.1 liblc3-1.0.3_1
diff --git a/srcpkgs/intel-gmmlib/template b/srcpkgs/intel-gmmlib/template
index 04e407b1de4d3..2605226152e5d 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
@@ -14,11 +14,11 @@ build_style=cmake
 # compilers flag in use.
 configure_args="-Wno-dev"
 short_desc="Intel Graphics Memory Management Library"
-maintainer="Orphaned <orphan@voidlinux.org>"
+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
 
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 0000000000000..525fb688722c8
--- /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/template b/srcpkgs/intel-media-driver/template
index a5bab06ac9476..1735b90c65ce5 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
@@ -8,11 +8,11 @@ configure_args="-Wno-dev -DENABLE_NONFREE_KERNELS=$(vopt_if nonfree ON OFF)"
 hostmakedepends="pkg-config"
 makedepends="libva-devel libX11-devel intel-gmmlib-devel libpciaccess-devel"
 short_desc="Intel Media Driver for VAAPI (Broadwell+)"
-maintainer="Orphaned <orphan@voidlinux.org>"
+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"
diff --git a/srcpkgs/intel-media-sdk/patches/musl.patch b/srcpkgs/intel-media-sdk/patches/musl.patch
new file mode 100644
index 0000000000000..4ae70924b744f
--- /dev/null
+++ b/srcpkgs/intel-media-sdk/patches/musl.patch
@@ -0,0 +1,14 @@
+--- a/tools/tracer/tracer/tracer_linux.cpp	2022-11-18 03:02:59.000000000 -0500
++++ b/tools/tracer/tracer/tracer_linux.cpp	2022-12-18 01:44:51.341542572 -0500
+@@ -32,6 +32,11 @@
+ #include <dlfcn.h>
+ #include "tracer.h"
+
++#ifndef RTLD_DEEPBIND
++// musl neither defines nor can use RTLD_DEEPBIND
++#define RTLD_DEEPBIND 0
++#endif
++
+ #if defined(__i386__)
+     #define LIBMFXHW "libmfxhw32.so.1"
+ #elif defined(__x86_64__)
diff --git a/srcpkgs/intel-media-sdk/template b/srcpkgs/intel-media-sdk/template
new file mode 100644
index 0000000000000..7aeab51802f8e
--- /dev/null
+++ b/srcpkgs/intel-media-sdk/template
@@ -0,0 +1,37 @@
+# Template file for 'intel-media-sdk'
+pkgname=intel-media-sdk
+version=22.6.4
+revision=1
+archs="x86_64*"
+build_style=cmake
+configure_args="-Wno-dev -DBUILD_SAMPLES=OFF -DBUILD_TESTS=ON"
+hostmakedepends="pkg-config"
+makedepends="libva-devel libdrm-devel intel-gmmlib-devel"
+short_desc="Intel Media SDK"
+maintainer="Stefano Ragni <st3r4g@protonmail.com>"
+license="MIT, BSD-3-Clause"
+homepage="https://github.com/Intel-Media-SDK/MediaSDK"
+distfiles="https://github.com/Intel-Media-SDK/MediaSDK/archive/refs/tags/intel-mediasdk-${version}.tar.gz"
+checksum=197acd056f81e9ff1c27068d50e8c84c2014d94c7ac17cad69d5c2d61e445fd3
+
+post_install() {
+	vlicense LICENSE
+}
+
+libmfx_package() {
+	depends="${makedepends} ${sourcepkg}-${version}_${revision}"
+	short_desc="Intel MediaSDK mfx lib"
+	pkg_install() {
+		vmove usr/lib/mfx
+		vmove "usr/lib/libmfx*.so*"
+	}
+}
+
+libmfx-devel_package() {
+	depends="${makedepends} ${sourcepkg}-${version}_${revision}"
+	short_desc+=" - development files"
+	pkg_install() {
+		vmove usr/include
+		vmove usr/lib/pkgconfig
+	}
+}
diff --git a/srcpkgs/intel-media-sdk/update b/srcpkgs/intel-media-sdk/update
new file mode 100644
index 0000000000000..434a2bc67f7a1
--- /dev/null
+++ b/srcpkgs/intel-media-sdk/update
@@ -0,0 +1 @@
+pkgname=intel-media
diff --git a/srcpkgs/libmfx b/srcpkgs/libmfx
new file mode 120000
index 0000000000000..8ffc7099c2272
--- /dev/null
+++ b/srcpkgs/libmfx
@@ -0,0 +1 @@
+intel-media-sdk
\ No newline at end of file
diff --git a/srcpkgs/libmfx-devel b/srcpkgs/libmfx-devel
new file mode 120000
index 0000000000000..8ffc7099c2272
--- /dev/null
+++ b/srcpkgs/libmfx-devel
@@ -0,0 +1 @@
+intel-media-sdk
\ No newline at end of file
diff --git a/srcpkgs/onevpl-devel b/srcpkgs/onevpl-devel
new file mode 120000
index 0000000000000..e2306500b4871
--- /dev/null
+++ b/srcpkgs/onevpl-devel
@@ -0,0 +1 @@
+onevpl
\ No newline at end of file
diff --git a/srcpkgs/onevpl-intel-gpu-devel b/srcpkgs/onevpl-intel-gpu-devel
new file mode 120000
index 0000000000000..47920ceecf919
--- /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 0000000000000..f14acb728a54d
--- /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
+	}
+}
diff --git a/srcpkgs/onevpl/template b/srcpkgs/onevpl/template
new file mode 100644
index 0000000000000..85c7c2da85ce9
--- /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 ef55538ec33a372fbf585795511cf3fd4d461ce5 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Sat, 8 Jul 2023 20:20:59 -0400
Subject: [PATCH 101/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 0b97f47489f81..f196d2bf9e4a4 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.6.1
-revision=1
+revision=2
 build_style=meson
 build_helper=qemu
 # missing libgrss for miner_rss

From 6d00709fe7f688060fe2ee45ef77d2e3cab36502 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Sat, 8 Jul 2023 20:21:21 -0400
Subject: [PATCH 102/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 abbeb423a1002..1bca2e877a380 100644
--- a/srcpkgs/mpd/template
+++ b/srcpkgs/mpd/template
@@ -1,7 +1,7 @@
 # Template file for 'mpd'
 pkgname=mpd
 version=0.23.14
-revision=1
+revision=2
 build_style=meson
 configure_args="-Dopus=enabled -Dmikmod=enabled -Dneighbor=true
  -Dsoundcloud=enabled -Dpipe=true -Dtwolame=enabled -Dbzip2=enabled

From 47b24c9575150fe4dea6398e27a3ae3e565371e3 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Mon, 17 Jul 2023 15:37:44 -0400
Subject: [PATCH 103/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 23800676bfd09..6921996e4e77b 100644
--- a/srcpkgs/mixxx/template
+++ b/srcpkgs/mixxx/template
@@ -1,7 +1,7 @@
 # Template file for 'mixxx'
 pkgname=mixxx
 version=2.3.3
-revision=5
+revision=6
 build_style=cmake
 configure_args="-DCMAKE_BUILD_TYPE=Release"
 hostmakedepends="extra-cmake-modules pkg-config protobuf qt5-host-tools qt5-qmake"

From f8d936b82dacfce66c36646b5e9bfbb6079af519 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 30 Aug 2023 09:09:36 -0400
Subject: [PATCH 104/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 1f78ada1451b6..d9e6186e6697b 100644
--- a/srcpkgs/musikcube/template
+++ b/srcpkgs/musikcube/template
@@ -1,7 +1,7 @@
 # Template file for 'musikcube'
 pkgname=musikcube
 version=3.0.0
-revision=2
+revision=3
 build_style=cmake
 make_cmd=make
 configure_args="-DNO_NCURSESW=1"

From 4e1f814be598a3e70906f18f0acc7fd9ddcb8e94 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 30 Aug 2023 09:10:02 -0400
Subject: [PATCH 105/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 50bc8310b8859..c93262d5c5de6 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.20230921
-revision=1
+revision=2
 _commit=3bb3d757681e6cc5135aec6529a753dc3dcdcfb9
 _libyuv_commit=04821d1e7d60845525e8db55c7bcd41ef5be9406
 _abseil_commit=8c0b94e793a66495e0b1f34a5eb26bd7dc672db0

From 2bea773cfa8a48715406c565cca9472ae7ef6553 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 30 Aug 2023 09:10:44 -0400
Subject: [PATCH 106/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 26a167befd980..5b093861e96e8 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.10.1
-revision=2
+revision=3
 build_style=cmake
 build_helper="qemu gir"
 configure_args="-DTDESKTOP_API_ID=209235

From 7ff29afec92056686a0c86b2ca34dfaf59bdbfc2 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 30 Aug 2023 09:11:13 -0400
Subject: [PATCH 107/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 933c22bae2ed2..301a77ad22971 100644
--- a/srcpkgs/mpv/template
+++ b/srcpkgs/mpv/template
@@ -1,7 +1,7 @@
 # Template file for 'mpv'
 pkgname=mpv
 version=0.36.0
-revision=2
+revision=3
 build_style=meson
 configure_args="-Dcdda=enabled -Ddvbin=enabled -Ddvdnav=enabled
  -Dlibmpv=true -Dcplugins=enabled

From cf0d22dfef9ca456e09eaa2ebd7ffa60abce6782 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 30 Aug 2023 09:11:45 -0400
Subject: [PATCH 108/115] gst-plugins-bad1: revbump for ffmpeg-6.0

---
 srcpkgs/gst-plugins-bad1/template | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/srcpkgs/gst-plugins-bad1/template b/srcpkgs/gst-plugins-bad1/template
index 2bf2f4b0642fe..0fafcb6555395 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.5
-revision=1
+revision=2
 build_helper="gir"
 build_style=meson
 configure_args="-Dpackage-origin=https://voidlinux.org -Ddoc=disabled

From 1a1384cd129ac5d1eb820e8d0922b08313d87a29 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 30 Aug 2023 09:12:09 -0400
Subject: [PATCH 109/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 0abf5ff7cdbec..b57180f1a4446 100644
--- a/srcpkgs/openmw/template
+++ b/srcpkgs/openmw/template
@@ -1,7 +1,7 @@
 # Template file for 'openmw'
 pkgname=openmw
 version=0.48.0
-revision=2
+revision=3
 build_style=cmake
 _recast_commit=e75adf86f91eb3082220085e42dda62679f9a3ea
 _bullet_tag=3.17

From e38dfc3af8d4468d7f0942eb82af06a876916b70 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 30 Aug 2023 09:14:53 -0400
Subject: [PATCH 110/115] lms: revbump for ffmpeg-6.0

---
 srcpkgs/lms/template | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/srcpkgs/lms/template b/srcpkgs/lms/template
index 39d34f62965c8..eb91d2ca275f3 100644
--- a/srcpkgs/lms/template
+++ b/srcpkgs/lms/template
@@ -1,7 +1,7 @@
 # Template file for 'lms'
 pkgname=lms
 version=3.40.0
-revision=2
+revision=3
 build_style=cmake
 hostmakedepends="pkg-config"
 makedepends="wt-devel ffmpeg-devel boost-devel libconfig++-devel taglib-devel pam-devel libgraphicsmagick-devel gtest-devel libarchive-devel"

From 41a5059efb952e99a410f660cc221cceca3ecf7f Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 30 Aug 2023 09:15:14 -0400
Subject: [PATCH 111/115] openimageio: revbump for ffmpeg-6.0

---
 srcpkgs/openimageio/template | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/srcpkgs/openimageio/template b/srcpkgs/openimageio/template
index d8a6ba56efd11..d7ad79563a2af 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=6
+revision=7
 build_style=cmake
 build_helper=qemu
 configure_args="-DUSE_QT=0 -DUSE_PYTHON=0 -DOIIO_BUILD_TESTS=0

From d18a58b63f0c03b3bbf6dd32b459566d2bd3524b Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Wed, 30 Aug 2023 09:18:18 -0400
Subject: [PATCH 112/115] freecad: revbump for ffmpeg-6.0

---
 srcpkgs/freecad/template | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/srcpkgs/freecad/template b/srcpkgs/freecad/template
index c135701e38b9a..705499e9972a6 100644
--- a/srcpkgs/freecad/template
+++ b/srcpkgs/freecad/template
@@ -1,7 +1,7 @@
 # Template file for 'freecad'
 pkgname=freecad
 version=0.20.2
-revision=7
+revision=8
 build_wrksrc="FreeCAD-${version}"
 build_style=cmake
 pycompile_dirs="usr/lib/${pkgname}/Mod"

From 7abcb227e55f610be841b336729a4f1d8151158b Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Sun, 15 Oct 2023 21:40:39 -0400
Subject: [PATCH 113/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 b43b10ef935e9..5d1d5e887409e 100644
--- a/srcpkgs/obs/template
+++ b/srcpkgs/obs/template
@@ -1,7 +1,7 @@
 # Template file for 'obs'
 pkgname=obs
 version=29.1.3
-revision=2
+revision=3
 archs="i686* x86_64* ppc64le* aarch64*"
 build_style=cmake
 configure_args="-DOBS_VERSION_OVERRIDE=${version} -DENABLE_JACK=ON

From b1a524c4a0a22bca87f1596b2589698e342f86cb Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Sun, 15 Oct 2023 21:46:47 -0400
Subject: [PATCH 114/115] mlt7: revbump for ffmpeg-6.0

---
 srcpkgs/mlt7/template | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/srcpkgs/mlt7/template b/srcpkgs/mlt7/template
index 77579fbf6b634..0a2a2702544fe 100644
--- a/srcpkgs/mlt7/template
+++ b/srcpkgs/mlt7/template
@@ -1,7 +1,7 @@
 # Template file for 'mlt7'
 pkgname=mlt7
 version=7.14.0
-revision=2
+revision=3
 build_style=cmake
 configure_args="-DSWIG_PYTHON=ON"
 hostmakedepends="doxygen pkg-config ladspa-sdk swig python3 which

From ad4988e81edce57b5364c8e8ced46c4ef4981f72 Mon Sep 17 00:00:00 2001
From: zlice <zlice555@gmail.com>
Date: Sun, 15 Oct 2023 21:47:18 -0400
Subject: [PATCH 115/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 8e57c5f592169..7a8f4520e7892 100644
--- a/srcpkgs/libopenshot/template
+++ b/srcpkgs/libopenshot/template
@@ -1,7 +1,7 @@
 # Template file for 'libopenshot'
 pkgname=libopenshot
 version=0.3.0
-revision=3
+revision=4
 build_style=cmake
 # Builds fail with Ruby-2.4.1
 configure_args="-DENABLE_RUBY=OFF -DUSE_SYSTEM_JSONCPP=ON"

  parent reply	other threads:[~2023-10-17 12:58 UTC|newest]

Thread overview: 106+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-05-05 13:20 [PR PATCH] " 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
2023-05-07 19:26 ` paper42
2023-05-07 22:00 ` zlice
2023-05-07 22:00 ` [PR PATCH] [Updated] " zlice
2023-05-08  0:23 ` zlice
2023-05-29  1:43 ` zlice
2023-06-04 15:47 ` zlice
2023-06-10  5:04 ` zlice
2023-06-17 19:17 ` zlice
2023-06-17 19:28 ` zlice
2023-06-19 20:19 ` zlice
2023-06-22 14:28 ` zlice
2023-06-23 20:37 ` [PR PATCH] [Updated] " zlice
2023-07-04 13:30 ` zlice
2023-07-04 14:18 ` zlice
2023-07-04 14:19 ` zlice
2023-07-09 14:54 ` zlice
2023-07-09 14:58 ` zlice
2023-07-17 19:52 ` [PR PATCH] [Updated] " zlice
2023-08-02 14:18 ` zlice
2023-08-30 13:18 ` zlice
2023-10-02  0:04 ` yoshiyoshyosh
2023-10-11 12:27 ` zlice
2023-10-11 17:06 ` SpidFightFR
2023-10-11 17:07 ` SpidFightFR
2023-10-16 12:11 ` [PR PATCH] [Updated] " zlice
2023-10-16 12:12 ` zlice
2023-10-16 12:19 ` SpidFightFR
2023-10-16 12:19 ` SpidFightFR
2023-10-16 12:26 ` SpidFightFR
2023-10-16 12:27 ` SpidFightFR
2023-10-16 12:27 ` SpidFightFR
2023-10-17 12:58 ` zlice [this message]
2023-10-17 12:59 ` zlice
2023-11-08 15:12 ` [PR PATCH] [Updated] " zlice
2023-11-10 20:08 ` zlice
2023-11-14 13:43 ` zlice
2023-11-20 23:00 ` zlice
2023-12-03 16:39 ` mhmdanas
2023-12-03 16:45 ` [PR PATCH] [Updated] " zlice
2023-12-03 16:59 ` zlice
2023-12-05 16:30 ` mhmdanas
2023-12-09 17:37 ` [PR PATCH] [Updated] " zlice
2023-12-09 17:39 ` zlice
2023-12-14 18:28 ` [PR PATCH] [Updated] " zlice
2023-12-19 20:48 ` zlice
2023-12-29 17:30 ` zlice
2023-12-29 17:30 ` zlice
2023-12-29 17:47 ` [PR PATCH] [Updated] " zlice
2024-01-05 13:07 ` zlice
2024-01-11 16:52 ` zlice
2024-01-17 22:35 ` zlice
2024-01-17 22:50 ` zlice
2024-01-28 18:46 ` zlice
2024-02-02 22:44 ` zlice
2024-02-02 22:46 ` zlice
2024-02-02 22:48 ` zlice
2024-02-03 20:31 ` [PR PATCH] [Updated] " zlice
2024-02-03 20:38 ` zlice
2024-02-03 22:46 ` [PR PATCH] [Updated] " zlice
2024-02-06  5:34 ` Luciogi
2024-02-11 17:28 ` [PR PATCH] [Updated] " zlice
2024-02-11 22:49 ` zlice
2024-02-15 19:52 ` zlice
2024-02-20 18:21 ` zlice
2024-02-22 17:25 ` yoshiyoshyosh
2024-02-22 17:34 ` zlice
2024-02-24  2:34 ` yoshiyoshyosh
2024-02-24  2:34 ` yoshiyoshyosh
2024-02-25 17:32 ` [PR PATCH] [Updated] " zlice
2024-02-25 17:33 ` zlice
2024-02-25 19:08 ` yoshiyoshyosh
2024-02-25 19:08 ` yoshiyoshyosh
2024-02-25 19:09 ` yoshiyoshyosh
2024-02-25 19:09 ` yoshiyoshyosh
2024-02-25 19:28 ` yoshiyoshyosh
2024-02-25 19:28 ` zlice
2024-02-25 19:32 ` yoshiyoshyosh
2024-02-25 19:33 ` yoshiyoshyosh
2024-02-25 20:20 ` yoshiyoshyosh
2024-02-25 21:45 ` yoshiyoshyosh
2024-02-25 21:58 ` yoshiyoshyosh
2024-03-01 15:58 ` [PR PATCH] [Updated] " zlice
2024-03-06 21:24 ` zlice
2024-03-09 22:24 ` yoshiyoshyosh
2024-03-09 22:41 ` [PR PATCH] [Updated] " zlice
2024-03-09 22:43 ` zlice
2024-03-09 22:56 ` yoshiyoshyosh
2024-03-10  0:03 ` zlice
2024-03-12 17:08 ` [PR PATCH] [Updated] " zlice
2024-03-18 20:07 ` zlice
2024-03-21 21:29 ` zlice
2024-03-21 21:51 ` zlice
2024-03-28 17:21 ` zlice
2024-04-13 14:47 ` zlice
2024-04-26 12:45 ` zlice
2024-05-09 13:32 ` zlice
2024-05-13 17:56 ` zlice
2024-05-16 16:36 ` zlice
2024-05-17 13:38 ` Luciogi
2024-05-17 13:40 ` zlice
2024-05-17 13:48 ` zlice
2024-05-17 13:49 ` zlice

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20231017125826.wVNPX1WoUgzSJVKIYcdJc5D7NgZEuuuBagC9Hk_x3dM@z \
    --to=zlice@users.noreply.github.com \
    --cc=ml@inbox.vuxu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).