diff -urN b/CMakeLists.txt a/CMakeLists.txt
--- b/CMakeLists.txt	2023-03-28 22:45:02.000000000 +0300
+++ a/CMakeLists.txt	2025-01-03 17:09:44.359065300 +0200
@@ -23,7 +23,7 @@
 
 find_package(Qt6 ${PROJECT_VERSION} CONFIG QUIET OPTIONAL_COMPONENTS
     Gui Widgets Network OpenGL Quick Qml PrintSupport
-    WebChannel Positioning QuickControls2 Test QuickWidgets QuickTest WebSockets Designer
+    WebChannel WebChannelQuick Positioning QuickControls2 Test QuickWidgets QuickTest WebSockets Designer
     JpegPrivate PngPrivate HarfbuzzPrivate FreetypePrivate ZlibPrivate
 )
 
diff -urN b/src/3rdparty/chromium/device/bluetooth/BUILD.gn a/src/3rdparty/chromium/device/bluetooth/BUILD.gn
--- b/src/3rdparty/chromium/device/bluetooth/BUILD.gn	2023-03-28 22:45:02.000000000 +0300
+++ a/src/3rdparty/chromium/device/bluetooth/BUILD.gn	2025-01-03 21:51:13.147669100 +0200
@@ -12,8 +12,6 @@
 config("bluetooth_config") {
   if (is_win) {
     ldflags = [
-      "/DELAYLOAD:BluetoothApis.dll",
-
       # Despite MSDN stating that Bthprops.dll contains the
       # symbols declared by bthprops.lib, they actually reside here:
       "/DELAYLOAD:Bthprops.cpl",
diff -urN b/src/3rdparty/chromium/device/bluetooth/bluetooth_low_energy_win.cc a/src/3rdparty/chromium/device/bluetooth/bluetooth_low_energy_win.cc
--- b/src/3rdparty/chromium/device/bluetooth/bluetooth_low_energy_win.cc	2023-03-28 22:45:02.000000000 +0300
+++ a/src/3rdparty/chromium/device/bluetooth/bluetooth_low_energy_win.cc	2025-01-03 21:36:55.406749800 +0200
@@ -373,46 +373,6 @@
     const base::FilePath& device_path,
     std::vector<std::unique_ptr<BluetoothLowEnergyServiceInfo>>* services,
     std::string* error) {
-  base::File file(device_path, base::File::FLAG_OPEN | base::File::FLAG_READ);
-  if (!file.IsValid()) {
-    *error = file.ErrorToString(file.error_details());
-    return false;
-  }
-
-  USHORT required_length;
-  HRESULT hr = BluetoothGATTGetServices(file.GetPlatformFile(),
-                                        0,
-                                        NULL,
-                                        &required_length,
-                                        BLUETOOTH_GATT_FLAG_NONE);
-  if (CheckNoData(hr, required_length))
-    return true;
-  if (!CheckMoreData(hr, kDeviceInfoError, error))
-    return false;
-
-  std::unique_ptr<BTH_LE_GATT_SERVICE[]> gatt_services(
-      new BTH_LE_GATT_SERVICE[required_length]);
-  USHORT actual_length = required_length;
-  hr = BluetoothGATTGetServices(file.GetPlatformFile(),
-                                actual_length,
-                                gatt_services.get(),
-                                &required_length,
-                                BLUETOOTH_GATT_FLAG_NONE);
-  if (!CheckHResult(hr, kDeviceInfoError, error))
-    return false;
-  if (!CheckExpectedLength(
-          actual_length, required_length, kDeviceInfoError, error)) {
-    return false;
-  }
-
-  for (USHORT i = 0; i < actual_length; ++i) {
-    BTH_LE_GATT_SERVICE& gatt_service(gatt_services.get()[i]);
-    auto service_info = std::make_unique<BluetoothLowEnergyServiceInfo>();
-    service_info->uuid = gatt_service.ServiceUuid;
-    service_info->attribute_handle = gatt_service.AttributeHandle;
-    services->push_back(std::move(service_info));
-  }
-
   return true;
 }
 
@@ -653,7 +613,7 @@
 BluetoothLowEnergyWrapper::~BluetoothLowEnergyWrapper() {}
 
 bool BluetoothLowEnergyWrapper::IsBluetoothLowEnergySupported() {
-  return base::win::GetVersion() >= base::win::Version::WIN8;
+  return false;
 }
 
 bool BluetoothLowEnergyWrapper::EnumerateKnownBluetoothLowEnergyDevices(
@@ -698,35 +658,7 @@
     const PBTH_LE_GATT_SERVICE service,
     std::unique_ptr<BTH_LE_GATT_CHARACTERISTIC>* out_included_characteristics,
     USHORT* out_counts) {
-  base::File file(service_path, base::File::FLAG_OPEN | base::File::FLAG_READ);
-  if (!file.IsValid())
-    return HRESULT_FROM_WIN32(ERROR_OPEN_FAILED);
-
-  USHORT allocated_length = 0;
-  HRESULT hr = BluetoothGATTGetCharacteristics(file.GetPlatformFile(), service,
-                                               0, NULL, &allocated_length,
-                                               BLUETOOTH_GATT_FLAG_NONE);
-  if (hr != HRESULT_FROM_WIN32(ERROR_MORE_DATA))
-    return hr;
-
-  out_included_characteristics->reset(
-      new BTH_LE_GATT_CHARACTERISTIC[allocated_length]);
-  hr = BluetoothGATTGetCharacteristics(file.GetPlatformFile(), service,
-                                       allocated_length,
-                                       out_included_characteristics->get(),
-                                       out_counts, BLUETOOTH_GATT_FLAG_NONE);
-  if (SUCCEEDED(hr) && allocated_length != *out_counts) {
-    LOG(ERROR) << "Retrieved charactersitics is not equal to expected"
-               << " allocated_length " << allocated_length << " got "
-               << *out_counts;
-    hr = HRESULT_FROM_WIN32(ERROR_INVALID_USER_BUFFER);
-  }
-
-  if (FAILED(hr)) {
-    out_included_characteristics->reset(nullptr);
-    *out_counts = 0;
-  }
-  return hr;
+  return 0;
 }
 
 HRESULT BluetoothLowEnergyWrapper::ReadDescriptorsOfACharacteristic(
@@ -734,67 +666,14 @@
     const PBTH_LE_GATT_CHARACTERISTIC characteristic,
     std::unique_ptr<BTH_LE_GATT_DESCRIPTOR>* out_included_descriptors,
     USHORT* out_counts) {
-  base::File file(service_path, base::File::FLAG_OPEN | base::File::FLAG_READ);
-  if (!file.IsValid())
-    return HRESULT_FROM_WIN32(ERROR_OPEN_FAILED);
-
-  USHORT allocated_length = 0;
-  HRESULT hr = BluetoothGATTGetDescriptors(
-      file.GetPlatformFile(), characteristic, 0, NULL, &allocated_length,
-      BLUETOOTH_GATT_FLAG_NONE);
-  if (hr != HRESULT_FROM_WIN32(ERROR_MORE_DATA))
-    return hr;
-
-  out_included_descriptors->reset(new BTH_LE_GATT_DESCRIPTOR[allocated_length]);
-  hr = BluetoothGATTGetDescriptors(
-      file.GetPlatformFile(), characteristic, allocated_length,
-      out_included_descriptors->get(), out_counts, BLUETOOTH_GATT_FLAG_NONE);
-  if (SUCCEEDED(hr) && allocated_length != *out_counts) {
-    LOG(ERROR) << "Retrieved descriptors is not equal to expected"
-               << " allocated_length " << allocated_length << " got "
-               << *out_counts;
-    hr = HRESULT_FROM_WIN32(ERROR_INVALID_USER_BUFFER);
-  }
-
-  if (FAILED(hr)) {
-    out_included_descriptors->reset(nullptr);
-    *out_counts = 0;
-  }
-  return hr;
+  return 0;
 }
 
 HRESULT BluetoothLowEnergyWrapper::ReadCharacteristicValue(
     base::FilePath& service_path,
     const PBTH_LE_GATT_CHARACTERISTIC characteristic,
     std::unique_ptr<BTH_LE_GATT_CHARACTERISTIC_VALUE>* out_value) {
-  base::File file(service_path, base::File::FLAG_OPEN | base::File::FLAG_READ);
-  if (!file.IsValid())
-    return HRESULT_FROM_WIN32(ERROR_OPEN_FAILED);
-
-  USHORT allocated_length = 0;
-  HRESULT hr = BluetoothGATTGetCharacteristicValue(
-      file.GetPlatformFile(), characteristic, 0, NULL, &allocated_length,
-      BLUETOOTH_GATT_FLAG_NONE);
-  if (hr != HRESULT_FROM_WIN32(ERROR_MORE_DATA))
-    return hr;
-
-  out_value->reset(
-      (PBTH_LE_GATT_CHARACTERISTIC_VALUE)(new UCHAR[allocated_length]));
-  USHORT out_length = 0;
-  hr = BluetoothGATTGetCharacteristicValue(
-      file.GetPlatformFile(), characteristic, (ULONG)allocated_length,
-      out_value->get(), &out_length, BLUETOOTH_GATT_FLAG_NONE);
-  if (SUCCEEDED(hr) && allocated_length != out_length) {
-    LOG(ERROR) << "Retrieved characteristic value size is not equal to expected"
-               << " allocated_length " << allocated_length << " got "
-               << out_length;
-    hr = HRESULT_FROM_WIN32(ERROR_INVALID_USER_BUFFER);
-  }
-
-  if (FAILED(hr)) {
-    out_value->reset(nullptr);
-  }
-  return hr;
+  return 0;
 }
 
 HRESULT BluetoothLowEnergyWrapper::WriteCharacteristicValue(
@@ -802,13 +681,7 @@
     const PBTH_LE_GATT_CHARACTERISTIC characteristic,
     PBTH_LE_GATT_CHARACTERISTIC_VALUE new_value,
     ULONG flags) {
-  base::File file(service_path, base::File::FLAG_OPEN | base::File::FLAG_READ |
-                                    base::File::FLAG_WRITE);
-  if (!file.IsValid())
-    return HRESULT_FROM_WIN32(ERROR_OPEN_FAILED);
-
-  return BluetoothGATTSetCharacteristicValue(
-      file.GetPlatformFile(), characteristic, new_value, {}, flags);
+  return 0;
 }
 
 HRESULT BluetoothLowEnergyWrapper::RegisterGattEvents(
@@ -818,34 +691,19 @@
     PFNBLUETOOTH_GATT_EVENT_CALLBACK_CORRECTED callback,
     PVOID context,
     BLUETOOTH_GATT_EVENT_HANDLE* out_handle) {
-  base::File file(service_path, base::File::FLAG_OPEN | base::File::FLAG_READ);
-  if (!file.IsValid())
-    return HRESULT_FROM_WIN32(ERROR_OPEN_FAILED);
-  // Cast to the official callback type for compatibility with the Windows
-  // 10.0.10586 definition, even though it is incorrect. This cast can be
-  // removed when we mandate building Chromium with the 10.0.14393 SDK or
-  // higher.
-  return BluetoothGATTRegisterEvent(
-      file.GetPlatformFile(), event_type, event_parameter,
-      reinterpret_cast<PFNBLUETOOTH_GATT_EVENT_CALLBACK>(callback), context,
-      out_handle, BLUETOOTH_GATT_FLAG_NONE);
+  return 0;
 }
 
 HRESULT BluetoothLowEnergyWrapper::UnregisterGattEvent(
     BLUETOOTH_GATT_EVENT_HANDLE event_handle) {
-  return BluetoothGATTUnregisterEvent(event_handle, BLUETOOTH_GATT_FLAG_NONE);
+  return 0;
 }
 
 HRESULT BluetoothLowEnergyWrapper::WriteDescriptorValue(
     base::FilePath& service_path,
     const PBTH_LE_GATT_DESCRIPTOR descriptor,
     PBTH_LE_GATT_DESCRIPTOR_VALUE new_value) {
-  base::File file(service_path, base::File::FLAG_OPEN | base::File::FLAG_READ |
-                                    base::File::FLAG_WRITE);
-  if (!file.IsValid())
-    return HRESULT_FROM_WIN32(ERROR_OPEN_FAILED);
-  return BluetoothGATTSetDescriptorValue(file.GetPlatformFile(), descriptor,
-                                         new_value, BLUETOOTH_GATT_FLAG_NONE);
+  return 0;
 }
 
 }  // namespace win
diff -urN b/src/core/location_provider_qt.h a/src/core/location_provider_qt.h
--- b/src/core/location_provider_qt.h	2023-03-28 22:45:02.000000000 +0300
+++ a/src/core/location_provider_qt.h	2025-01-03 17:12:26.936710100 +0200
@@ -5,6 +5,7 @@
 #define LOCATION_PROVIDER_QT_H
 
 #include <QtCore/qcompilerdetection.h>
+#include <QtCore/QThread>
 
 #include "services/device/public/cpp/geolocation/geoposition.h"
 #include "services/device/public/cpp/geolocation/location_provider.h"
diff -urN b/src/pdfquick/qquickpdfpageimage.cpp a/src/pdfquick/qquickpdfpageimage.cpp
--- b/src/pdfquick/qquickpdfpageimage.cpp	2023-03-28 22:45:02.000000000 +0300
+++ a/src/pdfquick/qquickpdfpageimage.cpp	2025-01-03 17:13:20.304987000 +0200
@@ -12,7 +12,7 @@
 
 /*!
     \qmltype PdfPageImage
-//!    \instantiates QQuickPdfPageImage
+//!    \nativetype QQuickPdfPageImage
     \inqmlmodule QtQuick.Pdf
     \ingroup pdf
     \inherits Image
@@ -42,7 +42,7 @@
 {
     Q_D(QQuickPdfPageImage);
     // cancel any async rendering job that is running on my behalf
-    d->pix.clear();
+    d->pendingPix->clear();
 }
 
 /*!
@@ -76,6 +76,18 @@
 void QQuickPdfPageImage::load()
 {
     Q_D(QQuickPdfPageImage);
+    QUrl url = source();
+    if (!d->doc || !d->doc->carrierFile()) {
+        if (!url.isEmpty()) {
+            qmlWarning(this) << "document property not set: falling back to inefficient loading of " << url;
+            QQuickImageBase::load();
+        }
+        return;
+    }
+    if (url != d->doc->resolvedSource()) {
+        url = d->doc->resolvedSource();
+        qmlWarning(this) << "document and source properties in conflict: preferring document source " << url;
+    }
     auto carrierFile = d->doc->carrierFile();
     static int thisRequestProgress = -1;
     static int thisRequestFinished = -1;
@@ -85,21 +97,23 @@
         thisRequestFinished =
             QQuickImageBase::staticMetaObject.indexOfSlot("requestFinished()");
     }
+    static QMetaMethod requestFinishedSlot = staticMetaObject.method(thisRequestFinished);
 
-    d->pix.loadImageFromDevice(qmlEngine(this), carrierFile, d->url,
+    d->pendingPix->loadImageFromDevice(qmlEngine(this), carrierFile, url,
                                d->sourceClipRect.toRect(), d->sourcesize * d->devicePixelRatio,
                                QQuickImageProviderOptions(), d->currentFrame, d->frameCount);
 
     qCDebug(qLcImg) << "loading page" << d->currentFrame << "of" << d->frameCount
-                    << "from" << carrierFile->fileName() << "status" << d->pix.status();
+                    << "from" << carrierFile->fileName() << "status" << d->pendingPix->status();
 
-    switch (d->pix.status()) {
+    switch (d->pendingPix->status()) {
     case QQuickPixmap::Ready:
+        requestFinishedSlot.invoke(this);
         pixmapChange();
         break;
     case QQuickPixmap::Loading:
-        d->pix.connectFinished(this, thisRequestFinished);
-        d->pix.connectDownloadProgress(this, thisRequestProgress);
+        d->pendingPix->connectFinished(this, thisRequestFinished);
+        d->pendingPix->connectDownloadProgress(this, thisRequestProgress);
         if (d->progress != 0.0) {
             d->progress = 0.0;
             emit progressChanged(d->progress);
@@ -110,7 +124,7 @@
         }
         break;
     default:
-        qCDebug(qLcImg) << "unexpected status" << d->pix.status();
+        qCDebug(qLcImg) << "unexpected status" << d->pendingPix->status();
         break;
     }
 }
diff -urN b/src/webenginequick/CMakeLists.txt a/src/webenginequick/CMakeLists.txt
--- b/src/webenginequick/CMakeLists.txt	2023-03-28 22:45:02.000000000 +0300
+++ a/src/webenginequick/CMakeLists.txt	2025-01-03 17:10:25.350770600 +0200
@@ -57,6 +57,11 @@
         Qt::WebEngineCore
 )
 
+qt_internal_extend_target(WebEngineQuick CONDITION QT_FEATURE_webengine_webchannel
+    PUBLIC_LIBRARIES
+        Qt::WebChannelQuick
+)
+
 qt_internal_extend_target(WebEngineQuick CONDITION QT_FEATURE_accessibility
     SOURCES
         qquickwebengine_accessible.cpp qquickwebengine_accessible.h
diff -urN b/src/webenginequick/api/qquickwebengineview.cpp a/src/webenginequick/api/qquickwebengineview.cpp
--- b/src/webenginequick/api/qquickwebengineview.cpp	2023-03-28 22:45:02.000000000 +0300
+++ a/src/webenginequick/api/qquickwebengineview.cpp	2025-01-03 17:11:22.178486800 +0200
@@ -71,7 +71,7 @@
 #endif
 
 #if QT_CONFIG(webengine_webchannel)
-#include <QtWebChannel/qqmlwebchannel.h>
+#include <QtWebChannelQuick/qqmlwebchannel.h>
 #endif
 
 QT_BEGIN_NAMESPACE
