summaryrefslogtreecommitdiffstats
path: root/src/plugins
diff options
context:
space:
mode:
Diffstat (limited to 'src/plugins')
-rw-r--r--src/plugins/platforms/android/CMakeLists.txt3
-rw-r--r--src/plugins/platforms/android/androidbackendregister.cpp52
-rw-r--r--src/plugins/platforms/android/androidbackendregister.h67
-rw-r--r--src/plugins/platforms/android/androidcontentfileengine.h1
-rw-r--r--src/plugins/platforms/android/androidjniaccessibility.cpp8
-rw-r--r--src/plugins/platforms/android/androidjniaccessibility.h1
-rw-r--r--src/plugins/platforms/android/androidjniinput.cpp138
-rw-r--r--src/plugins/platforms/android/androidjnimain.cpp84
-rw-r--r--src/plugins/platforms/android/androidjnimain.h7
-rw-r--r--src/plugins/platforms/android/androidjnimenu.cpp18
-rw-r--r--src/plugins/platforms/android/androidwindowembedding.cpp17
-rw-r--r--src/plugins/platforms/android/qandroidassetsfileenginehandler.h1
-rw-r--r--src/plugins/platforms/android/qandroidplatformaccessibility.cpp2
-rw-r--r--src/plugins/platforms/android/qandroidplatformintegration.cpp21
-rw-r--r--src/plugins/platforms/android/qandroidplatformintegration.h2
-rw-r--r--src/plugins/platforms/android/qandroidplatformscreen.cpp20
-rw-r--r--src/plugins/platforms/android/qandroidplatformservices.cpp21
-rw-r--r--src/plugins/platforms/android/qandroidplatformtheme.cpp15
-rw-r--r--src/plugins/platforms/android/qandroidplatformtheme.h3
-rw-r--r--src/plugins/platforms/android/qandroidplatformwindow.cpp30
-rw-r--r--src/plugins/platforms/cocoa/CMakeLists.txt2
-rw-r--r--src/plugins/platforms/cocoa/qcocoaaccessibility.mm17
-rw-r--r--src/plugins/platforms/cocoa/qcocoaapplicationdelegate.mm36
-rw-r--r--src/plugins/platforms/cocoa/qcocoamenu.mm4
-rw-r--r--src/plugins/platforms/cocoa/qcocoaservices.h6
-rw-r--r--src/plugins/platforms/cocoa/qcocoaservices.mm17
-rw-r--r--src/plugins/platforms/cocoa/qcocoatheme.h1
-rw-r--r--src/plugins/platforms/cocoa/qcocoatheme.mm17
-rw-r--r--src/plugins/platforms/cocoa/qcocoawindow.mm2
-rw-r--r--src/plugins/platforms/direct2d/CMakeLists.txt1
-rw-r--r--src/plugins/platforms/eglfs/CMakeLists.txt2
-rw-r--r--src/plugins/platforms/ios/CMakeLists.txt19
-rw-r--r--src/plugins/platforms/ios/SwiftIntegration.cmake78
-rw-r--r--src/plugins/platforms/ios/module.modulemap4
-rw-r--r--src/plugins/platforms/ios/optional/nsphotolibrarysupport/qiosfileenginefactory.h3
-rw-r--r--src/plugins/platforms/ios/qiosapplication.swift82
-rw-r--r--src/plugins/platforms/ios/qiosapplicationdelegate.h5
-rw-r--r--src/plugins/platforms/ios/qiosapplicationdelegate.mm45
-rw-r--r--src/plugins/platforms/ios/qiosdocumentpickercontroller.mm8
-rw-r--r--src/plugins/platforms/ios/qioseventdispatcher.h2
-rw-r--r--src/plugins/platforms/ios/qioseventdispatcher.mm21
-rw-r--r--src/plugins/platforms/ios/qiosglobal.h3
-rw-r--r--src/plugins/platforms/ios/qiosglobal.mm41
-rw-r--r--src/plugins/platforms/ios/qiosintegration.h30
-rw-r--r--src/plugins/platforms/ios/qiosintegration.mm37
-rw-r--r--src/plugins/platforms/ios/qiosscreen.h3
-rw-r--r--src/plugins/platforms/ios/qiosscreen.mm132
-rw-r--r--src/plugins/platforms/ios/qiostextinputoverlay.mm2
-rw-r--r--src/plugins/platforms/ios/qiostheme.h5
-rw-r--r--src/plugins/platforms/ios/qiostheme.mm35
-rw-r--r--src/plugins/platforms/ios/qiosviewcontroller.h4
-rw-r--r--src/plugins/platforms/ios/qiosviewcontroller.mm104
-rw-r--r--src/plugins/platforms/ios/qioswindow.h1
-rw-r--r--src/plugins/platforms/ios/qioswindow.mm29
-rw-r--r--src/plugins/platforms/ios/quiwindow.mm9
-rw-r--r--src/plugins/platforms/linuxfb/CMakeLists.txt2
-rw-r--r--src/plugins/platforms/minimal/CMakeLists.txt2
-rw-r--r--src/plugins/platforms/minimalegl/CMakeLists.txt2
-rw-r--r--src/plugins/platforms/offscreen/CMakeLists.txt2
-rw-r--r--src/plugins/platforms/qnx/CMakeLists.txt2
-rw-r--r--src/plugins/platforms/qnx/qqnxabstractnavigator.cpp10
-rw-r--r--src/plugins/platforms/qnx/qqnxabstractnavigator.h3
-rw-r--r--src/plugins/platforms/qnx/qqnxbuffer.cpp24
-rw-r--r--src/plugins/platforms/qnx/qqnxbuffer.h3
-rw-r--r--src/plugins/platforms/qnx/qqnxbuttoneventnotifier.cpp24
-rw-r--r--src/plugins/platforms/qnx/qqnxbuttoneventnotifier.h3
-rw-r--r--src/plugins/platforms/qnx/qqnxclipboard.cpp22
-rw-r--r--src/plugins/platforms/qnx/qqnxclipboard.h2
-rw-r--r--src/plugins/platforms/qnx/qqnxcursor.cpp12
-rw-r--r--src/plugins/platforms/qnx/qqnxcursor.h3
-rw-r--r--src/plugins/platforms/qnx/qqnxeglwindow.cpp12
-rw-r--r--src/plugins/platforms/qnx/qqnxeglwindow.h3
-rw-r--r--src/plugins/platforms/qnx/qqnxglcontext.cpp12
-rw-r--r--src/plugins/platforms/qnx/qqnxglobal.cpp2
-rw-r--r--src/plugins/platforms/qnx/qqnxinputcontext_imf.cpp116
-rw-r--r--src/plugins/platforms/qnx/qqnxinputcontext_noimf.cpp22
-rw-r--r--src/plugins/platforms/qnx/qqnxintegration.cpp66
-rw-r--r--src/plugins/platforms/qnx/qqnxintegration.h4
-rw-r--r--src/plugins/platforms/qnx/qqnxnavigatoreventhandler.cpp20
-rw-r--r--src/plugins/platforms/qnx/qqnxnavigatoreventhandler.h3
-rw-r--r--src/plugins/platforms/qnx/qqnxnavigatoreventnotifier.cpp27
-rw-r--r--src/plugins/platforms/qnx/qqnxnavigatorpps.cpp19
-rw-r--r--src/plugins/platforms/qnx/qqnxnavigatorpps.h3
-rw-r--r--src/plugins/platforms/qnx/qqnxrasterbackingstore.cpp20
-rw-r--r--src/plugins/platforms/qnx/qqnxrasterwindow.cpp14
-rw-r--r--src/plugins/platforms/qnx/qqnxscreen.cpp56
-rw-r--r--src/plugins/platforms/qnx/qqnxscreen.h4
-rw-r--r--src/plugins/platforms/qnx/qqnxscreeneventhandler.cpp49
-rw-r--r--src/plugins/platforms/qnx/qqnxscreeneventhandler.h3
-rw-r--r--src/plugins/platforms/qnx/qqnxscreeneventthread.cpp14
-rw-r--r--src/plugins/platforms/qnx/qqnxvirtualkeyboardpps.cpp24
-rw-r--r--src/plugins/platforms/qnx/qqnxvirtualkeyboardpps.h2
-rw-r--r--src/plugins/platforms/qnx/qqnxwindow.cpp56
-rw-r--r--src/plugins/platforms/qnx/qqnxwindow.h3
-rw-r--r--src/plugins/platforms/vkkhrdisplay/CMakeLists.txt2
-rw-r--r--src/plugins/platforms/vnc/CMakeLists.txt2
-rw-r--r--src/plugins/platforms/wasm/CMakeLists.txt3
-rw-r--r--src/plugins/platforms/wasm/qtloader.js12
-rw-r--r--src/plugins/platforms/wasm/qwasmscreen.cpp12
-rw-r--r--src/plugins/platforms/wasm/wasm_shell.html5
-rw-r--r--src/plugins/platforms/windows/CMakeLists.txt3
-rw-r--r--src/plugins/platforms/windows/qwindowsapplication.cpp5
-rw-r--r--src/plugins/platforms/windows/qwindowsapplication.h1
-rw-r--r--src/plugins/platforms/windows/qwindowscombase.h52
-rw-r--r--src/plugins/platforms/windows/qwindowscontext.cpp26
-rw-r--r--src/plugins/platforms/windows/qwindowscontext.h2
-rw-r--r--src/plugins/platforms/windows/qwindowsintegration.cpp19
-rw-r--r--src/plugins/platforms/windows/qwindowsscreen.cpp6
-rw-r--r--src/plugins/platforms/windows/qwindowsscreen.h1
-rw-r--r--src/plugins/platforms/windows/qwindowstheme.cpp120
-rw-r--r--src/plugins/platforms/windows/qwindowstheme.h16
-rw-r--r--src/plugins/platforms/windows/qwindowswindow.cpp29
-rw-r--r--src/plugins/platforms/windows/uiautomation/qwindowsuiaaccessibility.cpp3
-rw-r--r--src/plugins/platforms/windows/uiautomation/qwindowsuiamainprovider.cpp18
-rw-r--r--src/plugins/platforms/windows/uiautomation/qwindowsuiamainprovider.h1
-rw-r--r--src/plugins/platforms/windows/uiautomation/qwindowsuiautomation.cpp8
-rw-r--r--src/plugins/platforms/xcb/CMakeLists.txt2
-rw-r--r--src/plugins/platforms/xcb/qxcbwindow.cpp4
-rw-r--r--src/plugins/platformthemes/gtk3/CMakeLists.txt7
-rw-r--r--src/plugins/platformthemes/gtk3/qgtk3portalinterface.cpp123
-rw-r--r--src/plugins/platformthemes/gtk3/qgtk3portalinterface_p.h49
-rw-r--r--src/plugins/platformthemes/gtk3/qgtk3storage.cpp29
-rw-r--r--src/plugins/platformthemes/gtk3/qgtk3storage_p.h7
-rw-r--r--src/plugins/platformthemes/xdgdesktopportal/qxdgdesktopportaltheme.cpp25
-rw-r--r--src/plugins/sqldrivers/ibase/qsql_ibase.cpp96
-rw-r--r--src/plugins/styles/modernwindows/qwindows11style.cpp374
-rw-r--r--src/plugins/styles/modernwindows/qwindows11style_p.h1
-rw-r--r--src/plugins/styles/modernwindows/qwindowsvistastyle.cpp2
128 files changed, 1944 insertions, 1109 deletions
diff --git a/src/plugins/platforms/android/CMakeLists.txt b/src/plugins/platforms/android/CMakeLists.txt
index d5a275a76c..aaf62dd7e7 100644
--- a/src/plugins/platforms/android/CMakeLists.txt
+++ b/src/plugins/platforms/android/CMakeLists.txt
@@ -9,7 +9,7 @@ qt_find_package(EGL)
qt_internal_add_plugin(QAndroidIntegrationPlugin
OUTPUT_NAME qtforandroid
PLUGIN_TYPE platforms
- DEFAULT_IF ${QT_QPA_DEFAULT_PLATFORM} MATCHES android
+ DEFAULT_IF "android" IN_LIST QT_QPA_PLATFORMS
SOURCES
androidcontentfileengine.cpp androidcontentfileengine.h
androiddeadlockprotector.h
@@ -41,6 +41,7 @@ qt_internal_add_plugin(QAndroidIntegrationPlugin
qandroidplatformwindow.cpp qandroidplatformwindow.h
qandroidsystemlocale.cpp qandroidsystemlocale.h
androidwindowembedding.cpp androidwindowembedding.h
+ androidbackendregister.cpp androidbackendregister.h
NO_UNITY_BUILD_SOURCES
# Conflicting symbols and macros with androidjnimain.cpp
# TODO: Unify the usage of FIND_AND_CHECK_CLASS, and similar
diff --git a/src/plugins/platforms/android/androidbackendregister.cpp b/src/plugins/platforms/android/androidbackendregister.cpp
new file mode 100644
index 0000000000..bfd86138aa
--- /dev/null
+++ b/src/plugins/platforms/android/androidbackendregister.cpp
@@ -0,0 +1,52 @@
+// Copyright (C) 2024 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#include "androidbackendregister.h"
+
+#include "androidjnimain.h"
+
+QT_BEGIN_NAMESPACE
+
+Q_LOGGING_CATEGORY(lcAndroidBackendRegister, "qt.qpa.androidbackendregister")
+
+Q_DECLARE_JNI_CLASS(BackendRegister, "org/qtproject/qt/android/BackendRegister");
+
+bool AndroidBackendRegister::registerNatives()
+{
+ return QtJniTypes::BackendRegister::registerNativeMethods(
+ { Q_JNI_NATIVE_SCOPED_METHOD(registerBackend, AndroidBackendRegister),
+ Q_JNI_NATIVE_SCOPED_METHOD(unregisterBackend, AndroidBackendRegister) });
+}
+
+void AndroidBackendRegister::registerBackend(JNIEnv *, jclass, jclass interfaceClass,
+ jobject interface)
+{
+ if (AndroidBackendRegister *reg = QtAndroid::backendRegister()) {
+ const QJniObject classObject(static_cast<jobject>(interfaceClass));
+ QString name = classObject.callMethod<jstring>("getName").toString();
+ name.replace('.', '/');
+
+ QMutexLocker lock(&reg->m_registerMutex);
+ reg->m_register[name] = QJniObject(interface);
+ } else {
+ qCWarning(lcAndroidBackendRegister)
+ << "AndroidBackendRegister pointer is null, cannot register functionality";
+ }
+}
+
+void AndroidBackendRegister::unregisterBackend(JNIEnv *, jclass, jclass interfaceClass)
+{
+ if (AndroidBackendRegister *reg = QtAndroid::backendRegister()) {
+ const QJniObject classObject(static_cast<jobject>(interfaceClass));
+ QString name = classObject.callMethod<jstring>("getName").toString();
+ name.replace('.', '/');
+
+ QMutexLocker lock(&reg->m_registerMutex);
+ reg->m_register.remove(name);
+ } else {
+ qCWarning(lcAndroidBackendRegister)
+ << "AndroidBackendRegister pointer is null, cannot unregister functionality";
+ }
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/platforms/android/androidbackendregister.h b/src/plugins/platforms/android/androidbackendregister.h
new file mode 100644
index 0000000000..c186f7e107
--- /dev/null
+++ b/src/plugins/platforms/android/androidbackendregister.h
@@ -0,0 +1,67 @@
+// Copyright (C) 2024 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#ifndef ANDROIDBACKENDREGISTER_H
+#define ANDROIDBACKENDREGISTER_H
+
+#include <type_traits>
+
+#include <QtCore/qjnienvironment.h>
+#include <QtCore/qjnitypes.h>
+#include <QtCore/qjniobject.h>
+
+#include <QtCore/qstring.h>
+#include <QtCore/qmap.h>
+#include <QtCore/qmutex.h>
+#include <QtCore/qloggingcategory.h>
+
+QT_BEGIN_NAMESPACE
+
+Q_DECLARE_LOGGING_CATEGORY(lcAndroidBackendRegister)
+
+template <typename T>
+using ValidInterfaceType = std::enable_if_t<std::is_base_of_v<QtJniTypes::JObjectBase, T>, bool>;
+
+class AndroidBackendRegister
+{
+public:
+ static bool registerNatives();
+
+ template <typename T, ValidInterfaceType<T> = true>
+ [[nodiscard]] T getInterface()
+ {
+ QMutexLocker lock(&m_registerMutex);
+ return m_register.value(QString(QtJniTypes::Traits<T>::className().data()));
+ }
+
+ template <typename Object>
+ using IsObjectType =
+ typename std::disjunction<std::is_base_of<QJniObject, Object>,
+ std::is_base_of<QtJniTypes::JObjectBase, Object>>;
+
+ template <typename Interface, typename Ret, typename... Args,
+ ValidInterfaceType<Interface> = true>
+ auto callInterface(const char *func, Args... args)
+ {
+ if (const auto obj = getInterface<Interface>(); obj.isValid())
+ return obj.template callMethod<Ret, Args...>(func, std::forward<Args>(args)...);
+
+ if constexpr (IsObjectType<Ret>::value)
+ return Ret(QJniObject());
+ if constexpr (!std::is_same_v<Ret, void>)
+ return Ret{};
+ }
+
+private:
+ QMutex m_registerMutex;
+ QMap<QString, QJniObject> m_register;
+
+ static void registerBackend(JNIEnv *, jclass, jclass interfaceClass, jobject interface);
+ Q_DECLARE_JNI_NATIVE_METHOD_IN_CURRENT_SCOPE(registerBackend)
+ static void unregisterBackend(JNIEnv *, jclass, jclass interfaceClass);
+ Q_DECLARE_JNI_NATIVE_METHOD_IN_CURRENT_SCOPE(unregisterBackend)
+};
+
+QT_END_NAMESPACE
+
+#endif // ANDROIDBACKENDREGISTER_H
diff --git a/src/plugins/platforms/android/androidcontentfileengine.h b/src/plugins/platforms/android/androidcontentfileengine.h
index 11d0cd7201..a5dd1b30f3 100644
--- a/src/plugins/platforms/android/androidcontentfileengine.h
+++ b/src/plugins/platforms/android/androidcontentfileengine.h
@@ -43,6 +43,7 @@ private:
class AndroidContentFileEngineHandler : public QAbstractFileEngineHandler
{
+ Q_DISABLE_COPY_MOVE(AndroidContentFileEngineHandler)
public:
AndroidContentFileEngineHandler();
~AndroidContentFileEngineHandler();
diff --git a/src/plugins/platforms/android/androidjniaccessibility.cpp b/src/plugins/platforms/android/androidjniaccessibility.cpp
index 8f1c76ca26..805616e481 100644
--- a/src/plugins/platforms/android/androidjniaccessibility.cpp
+++ b/src/plugins/platforms/android/androidjniaccessibility.cpp
@@ -82,7 +82,7 @@ namespace QtAndroidAccessibility
void initialize()
{
- QtAndroid::qtActivityDelegate().callMethod<void>("initializeAccessibility");
+ QtAndroid::initializeAccessibility();
}
bool isActive()
@@ -127,6 +127,12 @@ namespace QtAndroidAccessibility
QtAndroid::notifyObjectHide(accessibilityObjectId, parentObjectId);
}
+ void notifyObjectShow(uint accessibilityObjectId)
+ {
+ const auto parentObjectId = parentId_helper(accessibilityObjectId);
+ QtAndroid::notifyObjectShow(parentObjectId);
+ }
+
void notifyObjectFocus(uint accessibilityObjectId)
{
QtAndroid::notifyObjectFocus(accessibilityObjectId);
diff --git a/src/plugins/platforms/android/androidjniaccessibility.h b/src/plugins/platforms/android/androidjniaccessibility.h
index d967dde3ff..6e8e059334 100644
--- a/src/plugins/platforms/android/androidjniaccessibility.h
+++ b/src/plugins/platforms/android/androidjniaccessibility.h
@@ -18,6 +18,7 @@ namespace QtAndroidAccessibility
bool registerNatives(QJniEnvironment &env);
void notifyLocationChange(uint accessibilityObjectId);
void notifyObjectHide(uint accessibilityObjectId);
+ void notifyObjectShow(uint accessibilityObjectId);
void notifyObjectFocus(uint accessibilityObjectId);
void notifyValueChanged(uint accessibilityObjectId);
void notifyScrolledEvent(uint accessibilityObjectId);
diff --git a/src/plugins/platforms/android/androidjniinput.cpp b/src/plugins/platforms/android/androidjniinput.cpp
index 00e6b7ca51..266d027b3c 100644
--- a/src/plugins/platforms/android/androidjniinput.cpp
+++ b/src/plugins/platforms/android/androidjniinput.cpp
@@ -24,10 +24,14 @@ Q_LOGGING_CATEGORY(lcQpaInputMethods, "qt.qpa.input.methods");
using namespace QtAndroid;
Q_DECLARE_JNI_CLASS(QtLayout, "org/qtproject/qt/android/QtLayout")
+Q_DECLARE_JNI_CLASS(QtLayoutInterface, "org/qtproject/qt/android/QtLayoutInterface")
+Q_DECLARE_JNI_CLASS(QtInputInterface, "org/qtproject/qt/android/QtInputInterface")
namespace QtAndroidInput
{
static bool m_ignoreMouseEvents = false;
+ static Qt::MouseButtons m_buttons = Qt::NoButton;
+
static QRect m_softwareKeyboardRect;
static QList<QWindowSystemInterface::TouchPoint> m_touchPoints;
@@ -96,48 +100,48 @@ namespace QtAndroidInput
QJniObject qtLayout()
{
- return qtActivityDelegate().callMethod<QtJniTypes::QtLayout>("getQtLayout");
+ AndroidBackendRegister *reg = QtAndroid::backendRegister();
+ return reg->callInterface<QtJniTypes::QtLayoutInterface, QtJniTypes::QtLayout>(
+ "getQtLayout");
}
void updateSelection(int selStart, int selEnd, int candidatesStart, int candidatesEnd)
{
qCDebug(lcQpaInputMethods) << ">>> UPDATESELECTION" << selStart << selEnd << candidatesStart << candidatesEnd;
- qtInputDelegate().callMethod<void>("updateSelection",
- selStart,
- selEnd,
- candidatesStart,
- candidatesEnd);
+ AndroidBackendRegister *reg = QtAndroid::backendRegister();
+ reg->callInterface<QtJniTypes::QtInputInterface, void>("updateSelection", selStart, selEnd,
+ candidatesStart, candidatesEnd);
}
void showSoftwareKeyboard(int left, int top, int width, int height, int inputHints, int enterKeyType)
{
- qtInputDelegate().callMethod<void>("showSoftwareKeyboard",
- QtAndroidPrivate::activity(),
- qtLayout().object<QtJniTypes::QtLayout>(),
- left,
- top,
- width,
- height,
- inputHints,
- enterKeyType);
+ AndroidBackendRegister *reg = QtAndroid::backendRegister();
+ reg->callInterface<QtJniTypes::QtInputInterface, void>(
+ "showSoftwareKeyboard", QtAndroidPrivate::activity(),
+ qtLayout().object<QtJniTypes::QtLayout>(), left, top, width, height, inputHints,
+ enterKeyType);
qCDebug(lcQpaInputMethods) << "@@@ SHOWSOFTWAREKEYBOARD" << left << top << width << height << inputHints << enterKeyType;
}
void resetSoftwareKeyboard()
{
- qtInputDelegate().callMethod<void>("resetSoftwareKeyboard");
+ AndroidBackendRegister *reg = QtAndroid::backendRegister();
+ reg->callInterface<QtJniTypes::QtInputInterface, void>("resetSoftwareKeyboard");
qCDebug(lcQpaInputMethods) << "@@@ RESETSOFTWAREKEYBOARD";
}
void hideSoftwareKeyboard()
{
- qtInputDelegate().callMethod<void>("hideSoftwareKeyboard");
+ AndroidBackendRegister *reg = QtAndroid::backendRegister();
+ reg->callInterface<QtJniTypes::QtInputInterface, void>("hideSoftwareKeyboard");
qCDebug(lcQpaInputMethods) << "@@@ HIDESOFTWAREKEYBOARD";
}
bool isSoftwareKeyboardVisible()
{
- return qtInputDelegate().callMethod<jboolean>("isSoftwareKeyboardVisible");
+ AndroidBackendRegister *reg = QtAndroid::backendRegister();
+ return reg->callInterface<QtJniTypes::QtInputInterface, jboolean>(
+ "isSoftwareKeyboardVisible");
}
QRect softwareKeyboardRect()
@@ -147,20 +151,85 @@ namespace QtAndroidInput
int getSelectHandleWidth()
{
- return qtInputDelegate().callMethod<jint>("getSelectHandleWidth");
+ AndroidBackendRegister *reg = QtAndroid::backendRegister();
+ return reg->callInterface<QtJniTypes::QtInputInterface, jint>("getSelectHandleWidth");
}
void updateHandles(int mode, QPoint editMenuPos, uint32_t editButtons, QPoint cursor, QPoint anchor, bool rtl)
{
- qtInputDelegate().callMethod<void>("updateHandles",
- QtAndroidPrivate::activity(),
- qtLayout().object<QtJniTypes::QtLayout>(),
- mode, editMenuPos.x(), editMenuPos.y(), editButtons,
- cursor.x(), cursor.y(),
- anchor.x(), anchor.y(), rtl);
+ AndroidBackendRegister *reg = QtAndroid::backendRegister();
+ reg->callInterface<QtJniTypes::QtInputInterface, void>(
+ "updateHandles", QtAndroidPrivate::activity(),
+ qtLayout().object<QtJniTypes::QtLayout>(), mode, editMenuPos.x(), editMenuPos.y(),
+ editButtons, cursor.x(), cursor.y(), anchor.x(), anchor.y(), rtl);
+ }
+
+ // from https://developer.android.com/reference/android/view/MotionEvent#getButtonState()
+ enum AndroidMouseButton {
+ BUTTON_PRIMARY = 0x00000001,
+ BUTTON_SECONDARY = 0x00000002,
+ BUTTON_TERTIARY = 0x00000004,
+ BUTTON_BACK = 0x00000008,
+ BUTTON_FORWARD = 0x00000010,
+ BUTTON_STYLUS_PRIMARY = 0x00000020,
+ BUTTON_STYLUS_SECONDARY = 0x00000040,
+ };
+ Q_DECLARE_FLAGS(AndroidMouseButtons, AndroidMouseButton)
+
+ static Qt::MouseButtons toMouseButtons(jint j_buttons)
+ {
+ const auto buttons = static_cast<AndroidMouseButtons>(j_buttons);
+ Qt::MouseButtons mouseButtons;
+ if (buttons.testFlag(BUTTON_PRIMARY))
+ mouseButtons.setFlag(Qt::LeftButton);
+
+ if (buttons.testFlag(BUTTON_SECONDARY))
+ mouseButtons.setFlag(Qt::RightButton);
+
+ if (buttons.testFlag(BUTTON_TERTIARY))
+ mouseButtons.setFlag(Qt::MiddleButton);
+
+ if (buttons.testFlag(BUTTON_BACK))
+ mouseButtons.setFlag(Qt::BackButton);
+
+ if (buttons.testFlag(BUTTON_FORWARD))
+ mouseButtons.setFlag(Qt::ForwardButton);
+
+ if (buttons.testFlag(BUTTON_STYLUS_PRIMARY))
+ mouseButtons.setFlag(Qt::LeftButton);
+
+ if (buttons.testFlag(BUTTON_STYLUS_SECONDARY))
+ mouseButtons.setFlag(Qt::RightButton);
+
+ // Fall back to left button
+ if (Q_UNLIKELY(buttons != 0 && mouseButtons == Qt::NoButton)) {
+ qWarning() << "Unhandled button value:" << buttons << "Falling back to Qt::LeftButton";
+ mouseButtons = Qt::LeftButton;
+ }
+ return mouseButtons;
}
- static void mouseDown(JNIEnv */*env*/, jobject /*thiz*/, jint winId, jint x, jint y)
+ static void sendMouseButtonEvents(QWindow *topLevel, QPoint localPos, QPoint globalPos,
+ jint mouseButtonState, QEvent::Type type)
+ {
+ const Qt::MouseButtons mouseButtons = toMouseButtons(mouseButtonState);
+ const Qt::MouseButtons changedButtons = mouseButtons & ~m_buttons;
+
+ if (changedButtons == Qt::NoButton)
+ return;
+
+ static_assert (sizeof(changedButtons) <= sizeof(uint), "Qt::MouseButtons size changed. Adapt code.");
+
+ for (uint buttonInt = 0x1; static_cast<uint>(changedButtons) >= buttonInt; buttonInt <<= 1) {
+ const auto button = static_cast<Qt::MouseButton>(buttonInt);
+ if (changedButtons.testFlag(button)) {
+ QWindowSystemInterface::handleMouseEvent(topLevel, localPos, globalPos,
+ mouseButtons, button, type);
+ }
+ }
+ }
+
+ static void mouseDown(JNIEnv */*env*/, jobject /*thiz*/, jint winId, jint x, jint y, jint mouseButtonState)
{
if (m_ignoreMouseEvents)
return;
@@ -169,13 +238,11 @@ namespace QtAndroidInput
QWindow *window = windowFromId(winId);
m_mouseGrabber = window;
const QPoint localPos = window && window->handle() ?
- window->handle()->mapFromGlobal(globalPos) : globalPos;
- QWindowSystemInterface::handleMouseEvent(window, localPos, globalPos,
- Qt::MouseButtons(Qt::LeftButton),
- Qt::LeftButton, QEvent::MouseButtonPress);
+ window->handle()->mapFromGlobal(globalPos) : globalPos;
+ sendMouseButtonEvents(window, localPos, globalPos, mouseButtonState, QEvent::MouseButtonPress);
}
- static void mouseUp(JNIEnv */*env*/, jobject /*thiz*/, jint winId, jint x, jint y)
+ static void mouseUp(JNIEnv */*env*/, jobject /*thiz*/, jint winId, jint x, jint y, jint mouseButtonState)
{
const QPoint globalPos(x,y);
QWindow *window = m_mouseGrabber.data();
@@ -184,9 +251,8 @@ namespace QtAndroidInput
const QPoint localPos = window && window->handle() ?
window->handle()->mapFromGlobal(globalPos) : globalPos;
- QWindowSystemInterface::handleMouseEvent(window, localPos, globalPos,
- Qt::MouseButtons(Qt::NoButton),
- Qt::LeftButton, QEvent::MouseButtonRelease);
+
+ sendMouseButtonEvents(window, localPos, globalPos, mouseButtonState, QEvent::MouseButtonRelease);
m_ignoreMouseEvents = false;
m_mouseGrabber.clear();
}
@@ -900,8 +966,8 @@ namespace QtAndroidInput
{"touchAdd","(IIIZIIFFFF)V",(void*)touchAdd},
{"touchEnd","(II)V",(void*)touchEnd},
{"touchCancel", "(I)V", (void *)touchCancel},
- {"mouseDown", "(III)V", (void *)mouseDown},
- {"mouseUp", "(III)V", (void *)mouseUp},
+ {"mouseDown", "(IIII)V", (void *)mouseDown},
+ {"mouseUp", "(IIII)V", (void *)mouseUp},
{"mouseMove", "(III)V", (void *)mouseMove},
{"mouseWheel", "(IIIFF)V", (void *)mouseWheel},
{"longPress", "(III)V", (void *)longPress},
diff --git a/src/plugins/platforms/android/androidjnimain.cpp b/src/plugins/platforms/android/androidjnimain.cpp
index 206bbd03d6..5bd2b924fc 100644
--- a/src/plugins/platforms/android/androidjnimain.cpp
+++ b/src/plugins/platforms/android/androidjnimain.cpp
@@ -54,9 +54,6 @@ static jobject m_resourcesObj = nullptr;
static jclass m_qtActivityClass = nullptr;
static jclass m_qtServiceClass = nullptr;
-static QtJniTypes::QtActivityDelegateBase m_activityDelegate = nullptr;
-static QtJniTypes::QtInputDelegate m_inputDelegate = nullptr;
-
static int m_pendingApplicationState = -1;
static QBasicMutex m_platformMutex;
@@ -85,7 +82,7 @@ static double m_density = 1.0;
static AndroidAssetsFileEngineHandler *m_androidAssetsFileEngineHandler = nullptr;
static AndroidContentFileEngineHandler *m_androidContentFileEngineHandler = nullptr;
-
+static AndroidBackendRegister *m_backendRegister = nullptr;
static const char m_qtTag[] = "Qt";
static const char m_classErrorMsg[] = "Can't find class \"%s\"";
@@ -93,7 +90,8 @@ static const char m_methodErrorMsg[] = "Can't find method \"%s%s\"";
Q_CONSTINIT static QBasicAtomicInt startQtAndroidPluginCalled = Q_BASIC_ATOMIC_INITIALIZER(0);
-Q_DECLARE_JNI_CLASS(QtEmbeddedDelegateFactory, "org/qtproject/qt/android/QtEmbeddedDelegateFactory")
+Q_DECLARE_JNI_CLASS(QtWindowInterface, "org/qtproject/qt/android/QtWindowInterface")
+Q_DECLARE_JNI_CLASS(QtAccessibilityInterface, "org/qtproject/qt/android/QtAccessibilityInterface");
namespace QtAndroid
{
@@ -184,36 +182,9 @@ namespace QtAndroid
// TODO move calls from here to where they logically belong
void setSystemUiVisibility(SystemUiVisibility uiVisibility)
{
- qtActivityDelegate().callMethod<void>("setSystemUiVisibility", jint(uiVisibility));
- }
-
- // FIXME: avoid direct access to QtActivityDelegate
- QtJniTypes::QtActivityDelegateBase qtActivityDelegate()
- {
- using namespace QtJniTypes;
- if (!m_activityDelegate.isValid()) {
- if (isQtApplication()) {
- auto context = QtAndroidPrivate::activity();
- m_activityDelegate = context.callMethod<QtActivityDelegateBase>("getActivityDelegate");
- } else {
- m_activityDelegate = QJniObject::callStaticMethod<QtActivityDelegateBase>(
- Traits<QtEmbeddedDelegateFactory>::className(),
- "getActivityDelegate",
- QtAndroidPrivate::activity());
- }
- }
-
- return m_activityDelegate;
- }
-
- QtJniTypes::QtInputDelegate qtInputDelegate()
- {
- if (!m_inputDelegate.isValid()) {
- m_inputDelegate = qtActivityDelegate().callMethod<QtJniTypes::QtInputDelegate>(
- "getInputDelegate");
- }
-
- return m_inputDelegate;
+ AndroidBackendRegister *reg = QtAndroid::backendRegister();
+ reg->callInterface<QtJniTypes::QtWindowInterface, void>("setSystemUiVisibility",
+ jint(uiVisibility));
}
bool isQtApplication()
@@ -234,30 +205,46 @@ namespace QtAndroid
return true;
}
+ void initializeAccessibility()
+ {
+ m_backendRegister->callInterface<QtJniTypes::QtAccessibilityInterface, void>(
+ "initializeAccessibility");
+ }
+
void notifyAccessibilityLocationChange(uint accessibilityObjectId)
{
- qtActivityDelegate().callMethod<void>("notifyLocationChange", accessibilityObjectId);
+ m_backendRegister->callInterface<QtJniTypes::QtAccessibilityInterface, void>(
+ "notifyLocationChange", accessibilityObjectId);
}
void notifyObjectHide(uint accessibilityObjectId, uint parentObjectId)
{
- qtActivityDelegate().callMethod<void>("notifyObjectHide",
- accessibilityObjectId, parentObjectId);
+ m_backendRegister->callInterface<QtJniTypes::QtAccessibilityInterface, void>(
+ "notifyObjectHide", accessibilityObjectId, parentObjectId);
+ }
+
+ void notifyObjectShow(uint parentObjectId)
+ {
+ m_backendRegister->callInterface<QtJniTypes::QtAccessibilityInterface, void>(
+ "notifyObjectShow", parentObjectId);
}
void notifyObjectFocus(uint accessibilityObjectId)
{
- qtActivityDelegate().callMethod<void>("notifyObjectFocus", accessibilityObjectId);
+ m_backendRegister->callInterface<QtJniTypes::QtAccessibilityInterface, void>(
+ "notifyObjectFocus", accessibilityObjectId);
}
void notifyValueChanged(uint accessibilityObjectId, jstring value)
{
- qtActivityDelegate().callMethod<void>("notifyValueChanged", accessibilityObjectId, value);
+ m_backendRegister->callInterface<QtJniTypes::QtAccessibilityInterface, void>(
+ "notifyValueChanged", accessibilityObjectId, value);
}
void notifyScrolledEvent(uint accessibilityObjectId)
{
- qtActivityDelegate().callMethod<void>("notifyScrolledEvent", accessibilityObjectId);
+ m_backendRegister->callInterface<QtJniTypes::QtAccessibilityInterface, void>(
+ "notifyScrolledEvent", accessibilityObjectId);
}
void notifyNativePluginIntegrationReady(bool ready)
@@ -381,6 +368,11 @@ namespace QtAndroid
return m_assets;
}
+ AndroidBackendRegister *backendRegister()
+ {
+ return m_backendRegister;
+ }
+
} // namespace QtAndroid
static jboolean startQtAndroidPlugin(JNIEnv *env, jobject /*object*/, jstring paramsString)
@@ -391,6 +383,7 @@ static jboolean startQtAndroidPlugin(JNIEnv *env, jobject /*object*/, jstring pa
m_androidAssetsFileEngineHandler = new AndroidAssetsFileEngineHandler();
m_androidContentFileEngineHandler = new AndroidContentFileEngineHandler();
m_mainLibraryHnd = nullptr;
+ m_backendRegister = new AndroidBackendRegister();
const QStringList argsList = QProcess::splitCommand(QJniObject(paramsString).toString());
@@ -435,7 +428,7 @@ static void waitForServiceSetup(JNIEnv *env, jclass /*clazz*/)
Q_UNUSED(env);
// The service must wait until the QCoreApplication starts otherwise onBind will be
// called too early
- if (QtAndroidPrivate::service().isValid())
+ if (QtAndroidPrivate::service().isValid() && QtAndroid::isQtApplication())
QtAndroidPrivate::waitForServiceSetup();
}
@@ -538,6 +531,8 @@ static void terminateQt(JNIEnv *env, jclass /*clazz*/)
m_androidPlatformIntegration = nullptr;
delete m_androidAssetsFileEngineHandler;
m_androidAssetsFileEngineHandler = nullptr;
+ delete m_backendRegister;
+ m_backendRegister = nullptr;
sem_post(&m_exitSemaphore);
}
@@ -703,7 +698,7 @@ Q_DECLARE_JNI_NATIVE_METHOD(handleScreenRemoved)
static void handleUiDarkModeChanged(JNIEnv */*env*/, jobject /*thiz*/, jint newUiMode)
{
- QAndroidPlatformIntegration::setColorScheme(
+ QAndroidPlatformIntegration::updateColorScheme(
(newUiMode == 1 ) ? Qt::ColorScheme::Dark : Qt::ColorScheme::Light);
}
Q_DECLARE_JNI_NATIVE_METHOD(handleUiDarkModeChanged)
@@ -885,7 +880,8 @@ Q_DECL_EXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void */*reserved*/)
|| !QtAndroidDialogHelpers::registerNatives(env)
|| !QAndroidPlatformClipboard::registerNatives(env)
|| !QAndroidPlatformWindow::registerNatives(env)
- || !QtAndroidWindowEmbedding::registerNatives(env)) {
+ || !QtAndroidWindowEmbedding::registerNatives(env)
+ || !AndroidBackendRegister::registerNatives()) {
__android_log_print(ANDROID_LOG_FATAL, "Qt", "registerNatives failed");
return -1;
}
diff --git a/src/plugins/platforms/android/androidjnimain.h b/src/plugins/platforms/android/androidjnimain.h
index 57a71a8650..9d616b18fb 100644
--- a/src/plugins/platforms/android/androidjnimain.h
+++ b/src/plugins/platforms/android/androidjnimain.h
@@ -13,6 +13,7 @@
#include <QImage>
#include <private/qjnihelpers_p.h>
#include <QtCore/QJniObject>
+#include <androidbackendregister.h>
QT_BEGIN_NAMESPACE
@@ -33,6 +34,7 @@ namespace QtAndroid
{
QBasicMutex *platformInterfaceMutex();
QAndroidPlatformIntegration *androidPlatformIntegration();
+ AndroidBackendRegister *backendRegister();
void setAndroidPlatformIntegration(QAndroidPlatformIntegration *androidPlatformIntegration);
void setQtThread(QThread *thread);
void setViewVisibility(jobject view, bool visible);
@@ -48,9 +50,6 @@ namespace QtAndroid
AAssetManager *assetManager();
jclass applicationClass();
- QtJniTypes::QtActivityDelegateBase qtActivityDelegate();
- QtJniTypes::QtInputDelegate qtInputDelegate();
-
// Keep synchronized with flags in ActivityDelegate.java
enum SystemUiVisibility {
SYSTEM_UI_VISIBILITY_NORMAL = 0,
@@ -63,8 +62,10 @@ namespace QtAndroid
jobject createBitmap(int width, int height, QImage::Format format, JNIEnv *env);
jobject createBitmapDrawable(jobject bitmap, JNIEnv *env = nullptr);
+ void initializeAccessibility();
void notifyAccessibilityLocationChange(uint accessibilityObjectId);
void notifyObjectHide(uint accessibilityObjectId, uint parentObjectId);
+ void notifyObjectShow(uint parentObjectId);
void notifyObjectFocus(uint accessibilityObjectId);
void notifyValueChanged(uint accessibilityObjectId, jstring value);
void notifyScrolledEvent(uint accessibilityObjectId);
diff --git a/src/plugins/platforms/android/androidjnimenu.cpp b/src/plugins/platforms/android/androidjnimenu.cpp
index 8bf37d1af2..5f8a0b92e9 100644
--- a/src/plugins/platforms/android/androidjnimenu.cpp
+++ b/src/plugins/platforms/android/androidjnimenu.cpp
@@ -20,6 +20,8 @@ QT_BEGIN_NAMESPACE
using namespace QtAndroid;
+Q_DECLARE_JNI_CLASS(QtMenuInterface, "org/qtproject/qt/android/QtMenuInterface");
+
namespace QtAndroidMenu
{
static QList<QAndroidPlatformMenu *> pendingContextMenus;
@@ -44,12 +46,14 @@ namespace QtAndroidMenu
void resetMenuBar()
{
- qtActivityDelegate().callMethod<void>("resetOptionsMenu");
+ AndroidBackendRegister *reg = QtAndroid::backendRegister();
+ reg->callInterface<QtJniTypes::QtMenuInterface, void>("resetOptionsMenu");
}
void openOptionsMenu()
{
- qtActivityDelegate().callMethod<void>("openOptionsMenu");
+ AndroidBackendRegister *reg = QtAndroid::backendRegister();
+ reg->callInterface<QtJniTypes::QtMenuInterface, void>("openOptionsMenu");
}
void showContextMenu(QAndroidPlatformMenu *menu, const QRect &anchorRect)
@@ -59,16 +63,18 @@ namespace QtAndroidMenu
pendingContextMenus.append(visibleMenu);
visibleMenu = menu;
menu->aboutToShow();
- qtActivityDelegate().callMethod<void>("openContextMenu",
- anchorRect.x(), anchorRect.y(),
- anchorRect.width(), anchorRect.height());
+ AndroidBackendRegister *reg = QtAndroid::backendRegister();
+ reg->callInterface<QtJniTypes::QtMenuInterface, void>("openContextMenu", anchorRect.x(),
+ anchorRect.y(), anchorRect.width(),
+ anchorRect.height());
}
void hideContextMenu(QAndroidPlatformMenu *menu)
{
QMutexLocker lock(&visibleMenuMutex);
if (visibleMenu == menu) {
- qtActivityDelegate().callMethod<void>("closeContextMenu");
+ AndroidBackendRegister *reg = QtAndroid::backendRegister();
+ reg->callInterface<QtJniTypes::QtMenuInterface, void>("closeContextMenu");
pendingContextMenus.clear();
} else {
pendingContextMenus.removeOne(menu);
diff --git a/src/plugins/platforms/android/androidwindowembedding.cpp b/src/plugins/platforms/android/androidwindowembedding.cpp
index 230776f571..65dabcac66 100644
--- a/src/plugins/platforms/android/androidwindowembedding.cpp
+++ b/src/plugins/platforms/android/androidwindowembedding.cpp
@@ -12,7 +12,6 @@
QT_BEGIN_NAMESPACE
Q_DECLARE_JNI_CLASS(QtView, "org/qtproject/qt/android/QtView");
-Q_DECLARE_JNI_CLASS(QtEmbeddedDelegate, "org/qtproject/qt/android/QtEmbeddedDelegate");
namespace QtAndroidWindowEmbedding {
void createRootWindow(JNIEnv *, jclass, QtJniTypes::View rootView,
@@ -59,16 +58,12 @@ namespace QtAndroidWindowEmbedding {
}
bool registerNatives(QJniEnvironment& env) {
- using namespace QtJniTypes;
- bool success = env.registerNativeMethods(Traits<QtEmbeddedDelegate>::className(),
- {Q_JNI_NATIVE_SCOPED_METHOD(createRootWindow, QtAndroidWindowEmbedding),
- Q_JNI_NATIVE_SCOPED_METHOD(deleteWindow, QtAndroidWindowEmbedding)});
-
- success &= env.registerNativeMethods(Traits<QtView>::className(),
- {Q_JNI_NATIVE_SCOPED_METHOD(setWindowVisible, QtAndroidWindowEmbedding),
- Q_JNI_NATIVE_SCOPED_METHOD(resizeWindow, QtAndroidWindowEmbedding)});
- return success;
-
+ return env.registerNativeMethods(
+ QtJniTypes::Traits<QtJniTypes::QtView>::className(),
+ { Q_JNI_NATIVE_SCOPED_METHOD(createRootWindow, QtAndroidWindowEmbedding),
+ Q_JNI_NATIVE_SCOPED_METHOD(deleteWindow, QtAndroidWindowEmbedding),
+ Q_JNI_NATIVE_SCOPED_METHOD(setWindowVisible, QtAndroidWindowEmbedding),
+ Q_JNI_NATIVE_SCOPED_METHOD(resizeWindow, QtAndroidWindowEmbedding) });
}
}
diff --git a/src/plugins/platforms/android/qandroidassetsfileenginehandler.h b/src/plugins/platforms/android/qandroidassetsfileenginehandler.h
index 8e5f87a51a..973a61fbfa 100644
--- a/src/plugins/platforms/android/qandroidassetsfileenginehandler.h
+++ b/src/plugins/platforms/android/qandroidassetsfileenginehandler.h
@@ -15,6 +15,7 @@ QT_BEGIN_NAMESPACE
class AndroidAssetsFileEngineHandler: public QAbstractFileEngineHandler
{
+ Q_DISABLE_COPY_MOVE(AndroidAssetsFileEngineHandler)
public:
AndroidAssetsFileEngineHandler();
std::unique_ptr<QAbstractFileEngine> create(const QString &fileName) const override;
diff --git a/src/plugins/platforms/android/qandroidplatformaccessibility.cpp b/src/plugins/platforms/android/qandroidplatformaccessibility.cpp
index 61fc21a6bc..ea7f22295d 100644
--- a/src/plugins/platforms/android/qandroidplatformaccessibility.cpp
+++ b/src/plugins/platforms/android/qandroidplatformaccessibility.cpp
@@ -28,6 +28,8 @@ void QAndroidPlatformAccessibility::notifyAccessibilityUpdate(QAccessibleEvent *
QtAndroidAccessibility::notifyLocationChange(event->uniqueId());
} else if (event->type() == QAccessible::ObjectHide) {
QtAndroidAccessibility::notifyObjectHide(event->uniqueId());
+ } else if (event->type() == QAccessible::ObjectShow) {
+ QtAndroidAccessibility::notifyObjectShow(event->uniqueId());
} else if (event->type() == QAccessible::Focus) {
QtAndroidAccessibility::notifyObjectFocus(event->uniqueId());
} else if (event->type() == QAccessible::ValueChanged) {
diff --git a/src/plugins/platforms/android/qandroidplatformintegration.cpp b/src/plugins/platforms/android/qandroidplatformintegration.cpp
index 038fe5172a..6efd3fc631 100644
--- a/src/plugins/platforms/android/qandroidplatformintegration.cpp
+++ b/src/plugins/platforms/android/qandroidplatformintegration.cpp
@@ -72,6 +72,12 @@ QAndroidPlatformScreen* createScreenForDisplayId(int displayId)
return new QAndroidPlatformScreen(display);
}
+static bool isValidAndroidContextForRendering()
+{
+ return QtAndroid::isQtApplication() ? QtAndroidPrivate::activity().isValid()
+ : QtAndroidPrivate::context().isValid();
+}
+
} // anonymous namespace
void *QAndroidPlatformNativeInterface::nativeResourceForIntegration(const QByteArray &resource)
@@ -317,9 +323,12 @@ bool QAndroidPlatformIntegration::hasCapability(Capability cap) const
case ApplicationState: return true;
case ThreadedPixmaps: return true;
case NativeWidgets: return QtAndroidPrivate::activity().isValid();
- case OpenGL: return QtAndroidPrivate::activity().isValid();
- case ForeignWindows: return QtAndroidPrivate::activity().isValid();
- case ThreadedOpenGL: return !needsBasicRenderloopWorkaround() && QtAndroidPrivate::activity().isValid();
+ case OpenGL:
+ return isValidAndroidContextForRendering();
+ case ForeignWindows:
+ return isValidAndroidContextForRendering();
+ case ThreadedOpenGL:
+ return !needsBasicRenderloopWorkaround() && isValidAndroidContextForRendering();
case RasterGLSurface: return QtAndroidPrivate::activity().isValid();
case TopStackedNativeChildWindows: return false;
case MaximizeUsingFullscreenGeometry: return true;
@@ -341,7 +350,7 @@ QPlatformBackingStore *QAndroidPlatformIntegration::createPlatformBackingStore(Q
QPlatformOpenGLContext *QAndroidPlatformIntegration::createPlatformOpenGLContext(QOpenGLContext *context) const
{
- if (!QtAndroidPrivate::activity().isValid())
+ if (!isValidAndroidContextForRendering())
return nullptr;
QSurfaceFormat format(context->format());
format.setAlphaBufferSize(8);
@@ -384,7 +393,7 @@ QOffscreenSurface *QAndroidPlatformIntegration::createOffscreenSurface(ANativeWi
QPlatformWindow *QAndroidPlatformIntegration::createPlatformWindow(QWindow *window) const
{
- if (!QtAndroidPrivate::activity().isValid())
+ if (!isValidAndroidContextForRendering())
return nullptr;
#if QT_CONFIG(vulkan)
@@ -537,7 +546,7 @@ void QAndroidPlatformIntegration::setScreenSize(int width, int height)
Qt::ColorScheme QAndroidPlatformIntegration::m_colorScheme = Qt::ColorScheme::Light;
-void QAndroidPlatformIntegration::setColorScheme(Qt::ColorScheme colorScheme)
+void QAndroidPlatformIntegration::updateColorScheme(Qt::ColorScheme colorScheme)
{
if (m_colorScheme == colorScheme)
return;
diff --git a/src/plugins/platforms/android/qandroidplatformintegration.h b/src/plugins/platforms/android/qandroidplatformintegration.h
index 5f1126fafc..b7bfb58d1d 100644
--- a/src/plugins/platforms/android/qandroidplatformintegration.h
+++ b/src/plugins/platforms/android/qandroidplatformintegration.h
@@ -110,7 +110,7 @@ public:
void flushPendingUpdates();
- static void setColorScheme(Qt::ColorScheme colorScheme);
+ static void updateColorScheme(Qt::ColorScheme colorScheme);
static Qt::ColorScheme colorScheme() { return m_colorScheme; }
#if QT_CONFIG(vulkan)
QPlatformVulkanInstance *createPlatformVulkanInstance(QVulkanInstance *instance) const override;
diff --git a/src/plugins/platforms/android/qandroidplatformscreen.cpp b/src/plugins/platforms/android/qandroidplatformscreen.cpp
index 9e20b7ac4b..4d752a3cc3 100644
--- a/src/plugins/platforms/android/qandroidplatformscreen.cpp
+++ b/src/plugins/platforms/android/qandroidplatformscreen.cpp
@@ -57,6 +57,7 @@ Q_DECLARE_JNI_CLASS(Resources, "android/content/res/Resources")
Q_DECLARE_JNI_CLASS(Size, "android/util/Size")
Q_DECLARE_JNI_CLASS(QtNative, "org/qtproject/qt/android/QtNative")
Q_DECLARE_JNI_CLASS(QtDisplayManager, "org/qtproject/qt/android/QtDisplayManager")
+Q_DECLARE_JNI_CLASS(QtWindowInterface, "org/qtproject/qt/android/QtWindowInterface")
Q_DECLARE_JNI_CLASS(DisplayMode, "android/view/Display$Mode")
@@ -162,7 +163,10 @@ void QAndroidPlatformScreen::addWindow(QAndroidPlatformWindow *window)
return;
m_windowStack.prepend(window);
- QtAndroid::qtActivityDelegate().callMethod<void>("addTopLevelWindow", window->nativeWindow());
+
+ AndroidBackendRegister *reg = QtAndroid::backendRegister();
+ reg->callInterface<QtJniTypes::QtWindowInterface, void>("addTopLevelWindow",
+ window->nativeWindow());
if (window->window()->isVisible())
topVisibleWindowChanged();
@@ -175,7 +179,9 @@ void QAndroidPlatformScreen::removeWindow(QAndroidPlatformWindow *window)
if (m_windowStack.contains(window))
qWarning() << "Failed to remove window";
- QtAndroid::qtActivityDelegate().callMethod<void>("removeTopLevelWindow", window->nativeViewId());
+ AndroidBackendRegister *reg = QtAndroid::backendRegister();
+ reg->callInterface<QtJniTypes::QtWindowInterface, void>("removeTopLevelWindow",
+ window->nativeViewId());
topVisibleWindowChanged();
}
@@ -187,7 +193,10 @@ void QAndroidPlatformScreen::raise(QAndroidPlatformWindow *window)
return;
if (index > 0) {
m_windowStack.move(index, 0);
- QtAndroid::qtActivityDelegate().callMethod<void>("bringChildToFront", window->nativeViewId());
+
+ AndroidBackendRegister *reg = QtAndroid::backendRegister();
+ reg->callInterface<QtJniTypes::QtWindowInterface, void>("bringChildToFront",
+ window->nativeViewId());
}
topVisibleWindowChanged();
}
@@ -198,7 +207,10 @@ void QAndroidPlatformScreen::lower(QAndroidPlatformWindow *window)
if (index == -1 || index == (m_windowStack.size() - 1))
return;
m_windowStack.move(index, m_windowStack.size() - 1);
- QtAndroid::qtActivityDelegate().callMethod<void>("bringChildToBack", window->nativeViewId());
+
+ AndroidBackendRegister *reg = QtAndroid::backendRegister();
+ reg->callInterface<QtJniTypes::QtWindowInterface, void>("bringChildToBack",
+ window->nativeViewId());
topVisibleWindowChanged();
}
diff --git a/src/plugins/platforms/android/qandroidplatformservices.cpp b/src/plugins/platforms/android/qandroidplatformservices.cpp
index f43e7cdd6a..39287aa905 100644
--- a/src/plugins/platforms/android/qandroidplatformservices.cpp
+++ b/src/plugins/platforms/android/qandroidplatformservices.cpp
@@ -24,15 +24,18 @@ QAndroidPlatformServices::QAndroidPlatformServices()
QtAndroidPrivate::registerNewIntentListener(this);
- QMetaObject::invokeMethod(
- this,
- [this] {
- QJniObject context = QJniObject(QtAndroidPrivate::context());
- QJniObject intent =
- context.callObjectMethod("getIntent", "()Landroid/content/Intent;");
- handleNewIntent(nullptr, intent.object());
- },
- Qt::QueuedConnection);
+ // Qt applications without Activity contexts cannot retrieve intents from the Activity.
+ if (QNativeInterface::QAndroidApplication::isActivityContext()) {
+ QMetaObject::invokeMethod(
+ this,
+ [this] {
+ QJniObject context = QJniObject(QtAndroidPrivate::context());
+ QJniObject intent =
+ context.callObjectMethod("getIntent", "()Landroid/content/Intent;");
+ handleNewIntent(nullptr, intent.object());
+ },
+ Qt::QueuedConnection);
+ }
}
Q_DECLARE_JNI_CLASS(UriType, "android/net/Uri")
diff --git a/src/plugins/platforms/android/qandroidplatformtheme.cpp b/src/plugins/platforms/android/qandroidplatformtheme.cpp
index 7b9072df69..99eeabac1d 100644
--- a/src/plugins/platforms/android/qandroidplatformtheme.cpp
+++ b/src/plugins/platforms/android/qandroidplatformtheme.cpp
@@ -161,7 +161,10 @@ QJsonObject AndroidStyle::loadStyleData()
if (!stylePath.isEmpty() && !stylePath.endsWith(slashChar))
stylePath += slashChar;
- if (QAndroidPlatformIntegration::colorScheme() == Qt::ColorScheme::Dark)
+ const Qt::ColorScheme colorScheme = QAndroidPlatformTheme::instance()
+ ? QAndroidPlatformTheme::instance()->colorScheme()
+ : QAndroidPlatformIntegration::colorScheme();
+ if (colorScheme == Qt::ColorScheme::Dark)
stylePath += "darkUiMode/"_L1;
Q_ASSERT(!stylePath.isEmpty());
@@ -423,9 +426,19 @@ void QAndroidPlatformTheme::showPlatformMenuBar()
Qt::ColorScheme QAndroidPlatformTheme::colorScheme() const
{
+ if (m_colorSchemeOverride != Qt::ColorScheme::Unknown)
+ return m_colorSchemeOverride;
return QAndroidPlatformIntegration::colorScheme();
}
+void QAndroidPlatformTheme::requestColorScheme(Qt::ColorScheme scheme)
+{
+ m_colorSchemeOverride = scheme;
+ QMetaObject::invokeMethod(qGuiApp, [this]{
+ updateColorScheme();
+ });
+}
+
static inline int paletteType(QPlatformTheme::Palette type)
{
switch (type) {
diff --git a/src/plugins/platforms/android/qandroidplatformtheme.h b/src/plugins/platforms/android/qandroidplatformtheme.h
index ce3d6d5f73..1b4ab5664d 100644
--- a/src/plugins/platforms/android/qandroidplatformtheme.h
+++ b/src/plugins/platforms/android/qandroidplatformtheme.h
@@ -40,6 +40,8 @@ public:
QPlatformMenuItem *createPlatformMenuItem() const override;
void showPlatformMenuBar() override;
Qt::ColorScheme colorScheme() const override;
+ void requestColorScheme(Qt::ColorScheme scheme) override;
+
const QPalette *palette(Palette type = SystemPalette) const override;
const QFont *font(Font type = SystemFont) const override;
QIconEngine *createIconEngine(const QString &iconName) const override;
@@ -57,6 +59,7 @@ private:
std::shared_ptr<AndroidStyle> m_androidStyleData;
QPalette m_defaultPalette;
QFont m_systemFont;
+ Qt::ColorScheme m_colorSchemeOverride = Qt::ColorScheme::Unknown;
};
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/android/qandroidplatformwindow.cpp b/src/plugins/platforms/android/qandroidplatformwindow.cpp
index e47281664d..2482160573 100644
--- a/src/plugins/platforms/android/qandroidplatformwindow.cpp
+++ b/src/plugins/platforms/android/qandroidplatformwindow.cpp
@@ -16,6 +16,10 @@ QT_BEGIN_NAMESPACE
Q_LOGGING_CATEGORY(lcQpaWindow, "qt.qpa.window")
+Q_DECLARE_JNI_CLASS(QtInputInterface, "org/qtproject/qt/android/QtInputInterface")
+Q_DECLARE_JNI_CLASS(QtInputConnectionListener,
+ "org/qtproject/qt/android/QtInputConnection$QtInputConnectionListener")
+
QAndroidPlatformWindow::QAndroidPlatformWindow(QWindow *window)
: QPlatformWindow(window), m_nativeQtWindow(nullptr),
m_surfaceContainerType(SurfaceContainer::TextureView), m_nativeParentQtWindow(nullptr),
@@ -55,20 +59,32 @@ QAndroidPlatformWindow::QAndroidPlatformWindow(QWindow *window)
m_nativeParentQtWindow = androidParent->nativeWindow();
}
+ AndroidBackendRegister *reg = QtAndroid::backendRegister();
+ QtJniTypes::QtInputConnectionListener listener =
+ reg->callInterface<QtJniTypes::QtInputInterface, QtJniTypes::QtInputConnectionListener>(
+ "getInputConnectionListener");
+
m_nativeQtWindow = QJniObject::construct<QtJniTypes::QtWindow>(
- QNativeInterface::QAndroidApplication::context(),
- m_nativeParentQtWindow,
- QtAndroid::qtInputDelegate());
+ QNativeInterface::QAndroidApplication::context(), m_nativeParentQtWindow, listener);
m_nativeViewId = m_nativeQtWindow.callMethod<jint>("getId");
if (window->isTopLevel())
platformScreen()->addWindow(this);
- // TODO should handle case where this changes at runtime -> need to change existing window
- // into TextureView (or perhaps not, if the parent window would be SurfaceView, as long as
- // onTop was false it would stay below the children)
- if (platformScreen()->windows().size() <= 1)
+ static bool ok = false;
+ static const int value = qEnvironmentVariableIntValue("QT_ANDROID_SURFACE_CONTAINER_TYPE", &ok);
+ if (ok) {
+ static const SurfaceContainer type = static_cast<SurfaceContainer>(value);
+ if (type == SurfaceContainer::SurfaceView || type == SurfaceContainer::TextureView)
+ m_surfaceContainerType = type;
+ } else if (platformScreen()->windows().size() <= 1) {
+ // TODO should handle case where this changes at runtime -> need to change existing window
+ // into TextureView (or perhaps not, if the parent window would be SurfaceView, as long as
+ // onTop was false it would stay below the children)
m_surfaceContainerType = SurfaceContainer::SurfaceView;
+ }
+ qCDebug(lcQpaWindow) << "Window" << m_nativeViewId << "using surface container type"
+ << static_cast<int>(m_surfaceContainerType);
}
QAndroidPlatformWindow::~QAndroidPlatformWindow()
diff --git a/src/plugins/platforms/cocoa/CMakeLists.txt b/src/plugins/platforms/cocoa/CMakeLists.txt
index 92e681d8fb..491c61703f 100644
--- a/src/plugins/platforms/cocoa/CMakeLists.txt
+++ b/src/plugins/platforms/cocoa/CMakeLists.txt
@@ -7,7 +7,7 @@
qt_internal_add_plugin(QCocoaIntegrationPlugin
OUTPUT_NAME qcocoa
- DEFAULT_IF ${QT_QPA_DEFAULT_PLATFORM} MATCHES cocoa
+ DEFAULT_IF "cocoa" IN_LIST QT_QPA_PLATFORMS
PLUGIN_TYPE platforms
SOURCES
main.mm
diff --git a/src/plugins/platforms/cocoa/qcocoaaccessibility.mm b/src/plugins/platforms/cocoa/qcocoaaccessibility.mm
index c5e40a4087..40c1e90511 100644
--- a/src/plugins/platforms/cocoa/qcocoaaccessibility.mm
+++ b/src/plugins/platforms/cocoa/qcocoaaccessibility.mm
@@ -36,6 +36,23 @@ void QCocoaAccessibility::notifyAccessibilityUpdate(QAccessibleEvent *event)
}
switch (event->type()) {
+ case QAccessible::Announcement: {
+ auto *announcementEvent = static_cast<QAccessibleAnnouncementEvent *>(event);
+ auto priorityLevel = (announcementEvent->priority() == QAccessible::AnnouncementPriority::Assertive)
+ ? NSAccessibilityPriorityHigh
+ : NSAccessibilityPriorityMedium;
+ NSDictionary *announcementInfo = @{
+ NSAccessibilityPriorityKey: [NSNumber numberWithInt:priorityLevel],
+ NSAccessibilityAnnouncementKey: announcementEvent->message().toNSString()
+ };
+ // post event for application element, as the comment for
+ // NSAccessibilityAnnouncementRequestedNotification in the
+ // NSAccessibilityConstants.h header says
+ NSAccessibilityPostNotificationWithUserInfo(NSApp,
+ NSAccessibilityAnnouncementRequestedNotification,
+ announcementInfo);
+ break;
+ }
case QAccessible::Focus: {
NSAccessibilityPostNotification(element, NSAccessibilityFocusedUIElementChangedNotification);
break;
diff --git a/src/plugins/platforms/cocoa/qcocoaapplicationdelegate.mm b/src/plugins/platforms/cocoa/qcocoaapplicationdelegate.mm
index d7f8a1665e..d642115926 100644
--- a/src/plugins/platforms/cocoa/qcocoaapplicationdelegate.mm
+++ b/src/plugins/platforms/cocoa/qcocoaapplicationdelegate.mm
@@ -334,16 +334,50 @@ QT_USE_NAMESPACE
[self doesNotRecognizeSelector:invocationSelector];
}
+- (BOOL)application:(NSApplication *)application continueUserActivity:(NSUserActivity *)userActivity
+ restorationHandler:(void(^)(NSArray<id<NSUserActivityRestoring>> *restorableObjects))restorationHandler
+{
+ // Check if eg. user has installed an app delegate capable of handling this
+ if ([reflectionDelegate respondsToSelector:_cmd]
+ && [reflectionDelegate application:application continueUserActivity:userActivity
+ restorationHandler:restorationHandler] == YES) {
+ return YES;
+ }
+
+ if (!QGuiApplication::instance())
+ return NO;
+
+ if ([userActivity.activityType isEqualToString:NSUserActivityTypeBrowsingWeb]) {
+ QCocoaIntegration *cocoaIntegration = QCocoaIntegration::instance();
+ Q_ASSERT(cocoaIntegration);
+ return cocoaIntegration->services()->handleUrl(QUrl::fromNSURL(userActivity.webpageURL));
+ }
+
+ return NO;
+}
+
- (void)getUrl:(NSAppleEventDescriptor *)event withReplyEvent:(NSAppleEventDescriptor *)replyEvent
{
Q_UNUSED(replyEvent);
+
NSString *urlString = [[event paramDescriptorForKeyword:keyDirectObject] stringValue];
+ const QString qurlString = QString::fromNSString(urlString);
+
+ if (event.eventClass == kInternetEventClass && event.eventID == kAEGetURL) {
+ // 'GURL' (Get URL) event this application should handle
+ if (!QGuiApplication::instance())
+ return;
+ QCocoaIntegration *cocoaIntegration = QCocoaIntegration::instance();
+ Q_ASSERT(cocoaIntegration);
+ cocoaIntegration->services()->handleUrl(QUrl(qurlString));
+ return;
+ }
+
// The string we get from the requesting application might not necessarily meet
// QUrl's requirement for a IDN-compliant host. So if we can't parse into a QUrl,
// then we pass the string on to the application as the name of a file (and
// QFileOpenEvent::file is not guaranteed to be the path to a local, open'able
// file anyway).
- const QString qurlString = QString::fromNSString(urlString);
if (const QUrl url(qurlString); url.isValid())
QWindowSystemInterface::handleFileOpenEvent(url);
else
diff --git a/src/plugins/platforms/cocoa/qcocoamenu.mm b/src/plugins/platforms/cocoa/qcocoamenu.mm
index 7a6999c2cc..fa88a19d45 100644
--- a/src/plugins/platforms/cocoa/qcocoamenu.mm
+++ b/src/plugins/platforms/cocoa/qcocoamenu.mm
@@ -326,7 +326,9 @@ void QCocoaMenu::showPopup(const QWindow *parentWindow, const QRect &targetRect,
QPointer<QCocoaMenu> guard = this;
QPoint pos = QPoint(targetRect.left(), targetRect.top() + targetRect.height());
- QCocoaWindow *cocoaWindow = parentWindow ? static_cast<QCocoaWindow *>(parentWindow->handle()) : nullptr;
+ // If the app quits while the menu is open (e.g. through a timer that starts before the menu was opened),
+ // then the window will have been destroyed before this function finishes executing. Account for that with QPointer.
+ QPointer<QCocoaWindow> cocoaWindow = parentWindow ? static_cast<QCocoaWindow *>(parentWindow->handle()) : nullptr;
NSView *view = cocoaWindow ? cocoaWindow->view() : nil;
NSMenuItem *nsItem = item ? ((QCocoaMenuItem *)item)->nsItem() : nil;
diff --git a/src/plugins/platforms/cocoa/qcocoaservices.h b/src/plugins/platforms/cocoa/qcocoaservices.h
index a0aec6f16b..b6299570e8 100644
--- a/src/plugins/platforms/cocoa/qcocoaservices.h
+++ b/src/plugins/platforms/cocoa/qcocoaservices.h
@@ -4,6 +4,8 @@
#ifndef QCOCOADESKTOPSERVICES_H
#define QCOCOADESKTOPSERVICES_H
+#include <QtCore/qurl.h>
+
#include <qpa/qplatformservices.h>
QT_BEGIN_NAMESPACE
@@ -15,8 +17,12 @@ public:
bool openUrl(const QUrl &url) override;
bool openDocument(const QUrl &url) override;
+ bool handleUrl(const QUrl &url);
QPlatformServiceColorPicker *colorPicker(QWindow *parent) override;
+
+private:
+ QUrl m_handlingUrl;
};
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/cocoa/qcocoaservices.mm b/src/plugins/platforms/cocoa/qcocoaservices.mm
index 4566cbb8f7..87212c265c 100644
--- a/src/plugins/platforms/cocoa/qcocoaservices.mm
+++ b/src/plugins/platforms/cocoa/qcocoaservices.mm
@@ -8,12 +8,19 @@
#include <Foundation/NSURL.h>
#include <QtCore/QUrl>
+#include <QtCore/qscopedvaluerollback.h>
+
+#include <QtGui/qdesktopservices.h>
#include <QtGui/private/qcoregraphics_p.h>
QT_BEGIN_NAMESPACE
bool QCocoaServices::openUrl(const QUrl &url)
{
+ // avoid recursing back into self
+ if (url == m_handlingUrl)
+ return false;
+
return [[NSWorkspace sharedWorkspace] openURL:url.toNSURL()];
}
@@ -22,6 +29,16 @@ bool QCocoaServices::openDocument(const QUrl &url)
return openUrl(url);
}
+/* Callback from macOS that the application should handle a URL */
+bool QCocoaServices::handleUrl(const QUrl &url)
+{
+ QScopedValueRollback<QUrl> rollback(m_handlingUrl, url);
+ // FIXME: Add platform services callback from QDesktopServices::setUrlHandler
+ // so that we can warn the user if calling setUrlHandler without also setting
+ // up the matching keys in the Info.plist file (CFBundleURLTypes and friends).
+ return QDesktopServices::openUrl(url);
+}
+
class QCocoaColorPicker : public QPlatformServiceColorPicker
{
public:
diff --git a/src/plugins/platforms/cocoa/qcocoatheme.h b/src/plugins/platforms/cocoa/qcocoatheme.h
index c49d83feae..97e0f633a7 100644
--- a/src/plugins/platforms/cocoa/qcocoatheme.h
+++ b/src/plugins/platforms/cocoa/qcocoatheme.h
@@ -44,6 +44,7 @@ public:
static const char *name;
+ void requestColorScheme(Qt::ColorScheme scheme) override;
void handleSystemThemeChange();
#ifndef QT_NO_SHORTCUT
diff --git a/src/plugins/platforms/cocoa/qcocoatheme.mm b/src/plugins/platforms/cocoa/qcocoatheme.mm
index f4fbfadbe4..d9135c76c8 100644
--- a/src/plugins/platforms/cocoa/qcocoatheme.mm
+++ b/src/plugins/platforms/cocoa/qcocoatheme.mm
@@ -478,6 +478,23 @@ Qt::ColorScheme QCocoaTheme::colorScheme() const
return m_colorScheme;
}
+void QCocoaTheme::requestColorScheme(Qt::ColorScheme scheme)
+{
+ NSAppearance *appearance = nil;
+ switch (scheme) {
+ case Qt::ColorScheme::Dark:
+ appearance = [NSAppearance appearanceNamed:NSAppearanceNameDarkAqua];
+ break;
+ case Qt::ColorScheme::Light:
+ appearance = [NSAppearance appearanceNamed:NSAppearanceNameAqua];
+ break;
+ case Qt::ColorScheme::Unknown:
+ break;
+ }
+ if (appearance != NSApp.effectiveAppearance)
+ NSApplication.sharedApplication.appearance = appearance;
+}
+
/*
Update the theme's color scheme based on the current appearance.
diff --git a/src/plugins/platforms/cocoa/qcocoawindow.mm b/src/plugins/platforms/cocoa/qcocoawindow.mm
index 4a245a0f8a..d2c9bb0196 100644
--- a/src/plugins/platforms/cocoa/qcocoawindow.mm
+++ b/src/plugins/platforms/cocoa/qcocoawindow.mm
@@ -514,7 +514,7 @@ NSInteger QCocoaWindow::windowLevel(Qt::WindowFlags flags)
auto *nsWindow = transientCocoaWindow->nativeWindow();
// We only upgrade the window level for "special" windows, to work
- // around Qt Designer parenting the designer windows to the widget
+ // around Qt Widgets Designer parenting the designer windows to the widget
// palette window (QTBUG-31779). This should be fixed in designer.
if (type != Qt::Window)
windowLevel = qMax(windowLevel, nsWindow.level);
diff --git a/src/plugins/platforms/direct2d/CMakeLists.txt b/src/plugins/platforms/direct2d/CMakeLists.txt
index 271104b71e..54e96b09e5 100644
--- a/src/plugins/platforms/direct2d/CMakeLists.txt
+++ b/src/plugins/platforms/direct2d/CMakeLists.txt
@@ -12,7 +12,6 @@ qt_internal_add_plugin(QWindowsDirect2DIntegrationPlugin
../windows/qtwindowsglobal.h
../windows/qwin10helpers.cpp ../windows/qwin10helpers.h
../windows/qwindowsapplication.cpp ../windows/qwindowsapplication.h
- ../windows/qwindowscombase.h
../windows/qwindowscontext.cpp ../windows/qwindowscontext.h
../windows/qwindowscursor.cpp ../windows/qwindowscursor.h
../windows/qwindowsdialoghelpers.cpp ../windows/qwindowsdialoghelpers.h
diff --git a/src/plugins/platforms/eglfs/CMakeLists.txt b/src/plugins/platforms/eglfs/CMakeLists.txt
index a0a6116a45..cb4b5d1eb9 100644
--- a/src/plugins/platforms/eglfs/CMakeLists.txt
+++ b/src/plugins/platforms/eglfs/CMakeLists.txt
@@ -92,7 +92,7 @@ endif()
qt_internal_add_plugin(QEglFSIntegrationPlugin
OUTPUT_NAME qeglfs
PLUGIN_TYPE platforms
- DEFAULT_IF ${QT_QPA_DEFAULT_PLATFORM} MATCHES eglfs
+ DEFAULT_IF "eglfs" IN_LIST QT_QPA_PLATFORMS
SOURCES
qeglfsmain.cpp
DEFINES
diff --git a/src/plugins/platforms/ios/CMakeLists.txt b/src/plugins/platforms/ios/CMakeLists.txt
index 4cc3efc91e..51c1b52cf3 100644
--- a/src/plugins/platforms/ios/CMakeLists.txt
+++ b/src/plugins/platforms/ios/CMakeLists.txt
@@ -5,10 +5,23 @@
## QIOSIntegrationPlugin Plugin:
#####################################################################
+if(VISIONOS)
+ include(SwiftIntegration.cmake)
+
+ qt_install(TARGETS QIOSIntegrationPluginSwift
+ EXPORT "${INSTALL_CMAKE_NAMESPACE}QIOSIntegrationPluginTargets"
+ DESTINATION "${INSTALL_LIBDIR}"
+ )
+ qt_internal_add_targets_to_additional_targets_export_file(
+ TARGETS QIOSIntegrationPluginSwift
+ EXPORT_NAME_PREFIX "${INSTALL_CMAKE_NAMESPACE}QIOSIntegrationPlugin"
+ )
+endif()
+
qt_internal_add_plugin(QIOSIntegrationPlugin
OUTPUT_NAME qios
STATIC # Force static, even in shared builds
- DEFAULT_IF ${QT_QPA_DEFAULT_PLATFORM} MATCHES ios
+ DEFAULT_IF "ios" IN_LIST QT_QPA_PLATFORMS
PLUGIN_TYPE platforms
SOURCES
plugin.mm
@@ -86,3 +99,7 @@ qt_internal_extend_target(QIOSIntegrationPlugin CONDITION NOT (TVOS OR VISIONOS)
)
add_subdirectory(optional)
+
+if(VISIONOS)
+ target_link_libraries(QIOSIntegrationPlugin PRIVATE QIOSIntegrationPluginSwift)
+endif()
diff --git a/src/plugins/platforms/ios/SwiftIntegration.cmake b/src/plugins/platforms/ios/SwiftIntegration.cmake
new file mode 100644
index 0000000000..d52edb3ad2
--- /dev/null
+++ b/src/plugins/platforms/ios/SwiftIntegration.cmake
@@ -0,0 +1,78 @@
+# Copyright (C) 2024 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+set(CMAKE_Swift_COMPILER_TARGET arm64-apple-xros)
+if($CACHE{CMAKE_OSX_SYSROOT} MATCHES "^[a-z]+simulator$")
+ set(CMAKE_Swift_COMPILER_TARGET "${CMAKE_Swift_COMPILER_TARGET}-simulator")
+endif()
+
+cmake_policy(SET CMP0157 NEW)
+enable_language(Swift)
+
+# Verify that we have a new enough compiler
+if("${CMAKE_Swift_COMPILER_VERSION}" VERSION_LESS 5.9)
+ message(FATAL_ERROR "Swift 5.9 required for C++ interoperability")
+endif()
+
+get_target_property(QT_CORE_INCLUDES Qt6::Core INTERFACE_INCLUDE_DIRECTORIES)
+get_target_property(QT_GUI_INCLUDES Qt6::Gui INTERFACE_INCLUDE_DIRECTORIES)
+get_target_property(QT_CORE_PRIVATE_INCLUDES Qt6::CorePrivate INTERFACE_INCLUDE_DIRECTORIES)
+get_target_property(QT_GUI_PRIVATE_INCLUDES Qt6::GuiPrivate INTERFACE_INCLUDE_DIRECTORIES)
+
+set(target QIOSIntegrationPluginSwift)
+# Swift library
+set(SWIFT_SOURCES
+ "${CMAKE_CURRENT_SOURCE_DIR}/qiosapplication.swift"
+)
+add_library(${target} STATIC ${SWIFT_SOURCES})
+set_target_properties(${target} PROPERTIES
+ Swift_MODULE_NAME ${target})
+target_include_directories(${target} PUBLIC
+ "${CMAKE_CURRENT_SOURCE_DIR}"
+ "${QT_CORE_INCLUDES}"
+ "${QT_GUI_INCLUDES}"
+ "${QT_CORE_PRIVATE_INCLUDES}"
+ "${QT_GUI_PRIVATE_INCLUDES}"
+
+)
+target_compile_options(${target} PUBLIC
+ $<$<COMPILE_LANGUAGE:Swift>:-cxx-interoperability-mode=default>
+ $<$<COMPILE_LANGUAGE:Swift>:-Xcc -std=c++17>)
+
+# Swift to C++ bridging header
+set(SWIFT_BRIDGING_HEADER "${CMAKE_CURRENT_BINARY_DIR}/qiosswiftintegration.h")
+list(TRANSFORM QT_CORE_INCLUDES PREPEND "-I")
+list(TRANSFORM QT_GUI_INCLUDES PREPEND "-I")
+list(TRANSFORM QT_CORE_PRIVATE_INCLUDES PREPEND "-I")
+list(TRANSFORM QT_GUI_PRIVATE_INCLUDES PREPEND "-I")
+add_custom_command(
+ COMMAND
+ ${CMAKE_Swift_COMPILER} -frontend -typecheck
+ ${SWIFT_SOURCES}
+ -I ${CMAKE_CURRENT_SOURCE_DIR}
+ ${QT_CORE_INCLUDES}
+ ${QT_GUI_INCLUDES}
+ ${QT_CORE_PRIVATE_INCLUDES}
+ ${QT_GUI_PRIVATE_INCLUDES}
+ -sdk ${CMAKE_OSX_SYSROOT}
+ -module-name ${target}
+ -cxx-interoperability-mode=default
+ -Xcc -std=c++17
+ -emit-clang-header-path "${SWIFT_BRIDGING_HEADER}"
+ -target ${CMAKE_Swift_COMPILER_TARGET}
+ OUTPUT
+ "${SWIFT_BRIDGING_HEADER}"
+ DEPENDS
+ ${SWIFT_SOURCES}
+ )
+
+set(header_target "${target}Header")
+add_custom_target(${header_target}
+ DEPENDS "${SWIFT_BRIDGING_HEADER}"
+)
+# Make sure the "'__bridge_transfer' casts have no effect when not using ARC"
+# warning doesn't break warnings-are-error builds.
+target_compile_options(${target} INTERFACE
+ -Wno-error=arc-bridge-casts-disallowed-in-nonarc)
+
+add_dependencies(${target} ${header_target})
diff --git a/src/plugins/platforms/ios/module.modulemap b/src/plugins/platforms/ios/module.modulemap
new file mode 100644
index 0000000000..af42b3e1f5
--- /dev/null
+++ b/src/plugins/platforms/ios/module.modulemap
@@ -0,0 +1,4 @@
+module QIOSIntegrationPlugin {
+ header "qiosapplicationdelegate.h"
+ header "qiosintegration.h"
+}
diff --git a/src/plugins/platforms/ios/optional/nsphotolibrarysupport/qiosfileenginefactory.h b/src/plugins/platforms/ios/optional/nsphotolibrarysupport/qiosfileenginefactory.h
index 136716f792..dfffbb8990 100644
--- a/src/plugins/platforms/ios/optional/nsphotolibrarysupport/qiosfileenginefactory.h
+++ b/src/plugins/platforms/ios/optional/nsphotolibrarysupport/qiosfileenginefactory.h
@@ -12,7 +12,10 @@ QT_BEGIN_NAMESPACE
class QIOSFileEngineFactory : public QAbstractFileEngineHandler
{
+ Q_DISABLE_COPY_MOVE(QIOSFileEngineFactory)
public:
+ QIOSFileEngineFactory() = default;
+
std::unique_ptr<QAbstractFileEngine> create(const QString &fileName) const
{
Q_CONSTINIT static QLatin1StringView assetsScheme("assets-library:");
diff --git a/src/plugins/platforms/ios/qiosapplication.swift b/src/plugins/platforms/ios/qiosapplication.swift
new file mode 100644
index 0000000000..6f75ebd0b5
--- /dev/null
+++ b/src/plugins/platforms/ios/qiosapplication.swift
@@ -0,0 +1,82 @@
+// Copyright (C) 2024 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
+
+import SwiftUI
+import CompositorServices
+import QIOSIntegrationPlugin
+import RealityKit
+
+struct QIOSSwiftApplication: App {
+ @UIApplicationDelegateAdaptor private var appDelegate: QIOSApplicationDelegate
+
+ var body: some SwiftUI.Scene {
+ WindowGroup() {
+ ImmersiveSpaceControlView()
+ }
+
+ ImmersiveSpace(id: "QIOSImmersiveSpace") {
+ CompositorLayer(configuration: QIOSLayerConfiguration()) { layerRenderer in
+ QIOSIntegration.instance().renderCompositorLayer(layerRenderer)
+ }
+ }
+ // CompositorLayer immersive spaces are always full, and should not need
+ // to set the immersion style, but lacking this we get a warning in the
+ // console about not being able to "configure an immersive space with
+ // selected style 'AutomaticImmersionStyle' since it is not in the list
+ // of supported styles for this type of content: 'FullImmersionStyle'."
+ .immersionStyle(selection: .constant(.full), in: .full)
+ }
+}
+
+public struct QIOSLayerConfiguration: CompositorLayerConfiguration {
+ public func makeConfiguration(capabilities: LayerRenderer.Capabilities,
+ configuration: inout LayerRenderer.Configuration) {
+ // Use reflection to pull out underlying C handles
+ // FIXME: Use proper bridging APIs when available
+ let capabilitiesMirror = Mirror(reflecting: capabilities)
+ let configurationMirror = Mirror(reflecting: configuration)
+ QIOSIntegration.instance().configureCompositorLayer(
+ capabilitiesMirror.descendant("c_capabilities") as? cp_layer_renderer_capabilities_t,
+ configurationMirror.descendant("box", "value") as? cp_layer_renderer_configuration_t
+ )
+ }
+}
+
+public func runSwiftAppMain() {
+ QIOSSwiftApplication.main()
+}
+
+public class ImmersiveState: ObservableObject {
+ static let shared = ImmersiveState()
+ @Published var showImmersiveSpace: Bool = false
+}
+
+struct ImmersiveSpaceControlView: View {
+ @ObservedObject private var immersiveState = ImmersiveState.shared
+
+ @Environment(\.openImmersiveSpace) var openImmersiveSpace
+ @Environment(\.dismissImmersiveSpace) var dismissImmersiveSpace
+
+ var body: some View {
+ VStack {}
+ .onChange(of: immersiveState.showImmersiveSpace) { _, newValue in
+ Task {
+ if newValue {
+ await openImmersiveSpace(id: "QIOSImmersiveSpace")
+ } else {
+ await dismissImmersiveSpace()
+ }
+ }
+ }
+ }
+}
+
+public class ImmersiveSpaceManager : NSObject {
+ @objc public static func openImmersiveSpace() {
+ ImmersiveState.shared.showImmersiveSpace = true
+ }
+
+ @objc public static func dismissImmersiveSpace() {
+ ImmersiveState.shared.showImmersiveSpace = false
+ }
+}
diff --git a/src/plugins/platforms/ios/qiosapplicationdelegate.h b/src/plugins/platforms/ios/qiosapplicationdelegate.h
index 39bb9fdedb..7e12d64cbf 100644
--- a/src/plugins/platforms/ios/qiosapplicationdelegate.h
+++ b/src/plugins/platforms/ios/qiosapplicationdelegate.h
@@ -1,6 +1,9 @@
// Copyright (C) 2016 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+#ifndef QIOSAPPLICATIONDELEGATE_H
+#define QIOSAPPLICATIONDELEGATE_H
+
#import <UIKit/UIKit.h>
#import <QtGui/QtGui>
@@ -8,3 +11,5 @@
@interface QIOSApplicationDelegate : UIResponder <UIApplicationDelegate>
@end
+
+#endif // QIOSAPPLICATIONDELEGATE_H
diff --git a/src/plugins/platforms/ios/qiosapplicationdelegate.mm b/src/plugins/platforms/ios/qiosapplicationdelegate.mm
index a017fef457..c6e5a83874 100644
--- a/src/plugins/platforms/ios/qiosapplicationdelegate.mm
+++ b/src/plugins/platforms/ios/qiosapplicationdelegate.mm
@@ -3,15 +3,21 @@
#include "qiosapplicationdelegate.h"
+#include "qiosglobal.h"
#include "qiosintegration.h"
#include "qiosservices.h"
#include "qiosviewcontroller.h"
#include "qioswindow.h"
+#include "qiosscreen.h"
+#include "quiwindow.h"
#include <qpa/qplatformintegration.h>
#include <QtCore/QtCore>
+@interface QIOSWindowSceneDelegate : NSObject<UIWindowSceneDelegate>
+@end
+
@implementation QIOSApplicationDelegate
- (BOOL)application:(UIApplication *)application continueUserActivity:(NSUserActivity *)userActivity restorationHandler:(void (^)(NSArray<id<UIUserActivityRestoring>> *restorableObjects))restorationHandler
@@ -50,5 +56,44 @@
return iosServices->handleUrl(QUrl::fromNSURL(url));
}
+- (UISceneConfiguration *)application:(UIApplication *)application
+ configurationForConnectingSceneSession:(UISceneSession *)connectingSceneSession
+ options:(UISceneConnectionOptions *)options
+{
+ qCDebug(lcQpaWindowScene) << "Configuring scene for" << connectingSceneSession
+ << "with options" << options;
+
+ auto *sceneConfig = connectingSceneSession.configuration;
+ sceneConfig.delegateClass = QIOSWindowSceneDelegate.class;
+ return sceneConfig;
+}
+
@end
+@implementation QIOSWindowSceneDelegate
+
+- (void)scene:(UIScene *)scene willConnectToSession:(UISceneSession *)session options:(UISceneConnectionOptions *)connectionOptions
+{
+ qCDebug(lcQpaWindowScene) << "Connecting" << scene << "to" << session;
+
+ Q_ASSERT([scene isKindOfClass:UIWindowScene.class]);
+ UIWindowScene *windowScene = static_cast<UIWindowScene*>(scene);
+
+ QUIWindow *window = [[QUIWindow alloc] initWithWindowScene:windowScene];
+
+ QIOSScreen *screen = [&]{
+ for (auto *screen : qGuiApp->screens()) {
+ auto *platformScreen = static_cast<QIOSScreen*>(screen->handle());
+#if !defined(Q_OS_VISIONOS)
+ if (platformScreen->uiScreen() == windowScene.screen)
+#endif
+ return platformScreen;
+ }
+ Q_UNREACHABLE();
+ }();
+
+ window.rootViewController = [[[QIOSViewController alloc]
+ initWithWindow:window andScreen:screen] autorelease];
+}
+
+@end
diff --git a/src/plugins/platforms/ios/qiosdocumentpickercontroller.mm b/src/plugins/platforms/ios/qiosdocumentpickercontroller.mm
index fca0432426..09e2f2f4c3 100644
--- a/src/plugins/platforms/ios/qiosdocumentpickercontroller.mm
+++ b/src/plugins/platforms/ios/qiosdocumentpickercontroller.mm
@@ -30,14 +30,14 @@
case QFileDialogOptions::AnyFile:
case QFileDialogOptions::ExistingFile:
case QFileDialogOptions::ExistingFiles:
- [docTypes addObject:[UTType typeWithIdentifier:(__bridge NSString *)UTTypeContent]];
- [docTypes addObject:[UTType typeWithIdentifier:(__bridge NSString *)UTTypeItem]];
- [docTypes addObject:[UTType typeWithIdentifier:(__bridge NSString *)UTTypeData]];
+ [docTypes addObject:UTTypeContent];
+ [docTypes addObject:UTTypeItem];
+ [docTypes addObject:UTTypeData];
break;
// Showing files is not supported in Directory mode in iOS
case QFileDialogOptions::Directory:
case QFileDialogOptions::DirectoryOnly:
- [docTypes addObject:[UTType typeWithIdentifier:(__bridge NSString *)UTTypeFolder]];
+ [docTypes addObject:UTTypeFolder];
break;
}
}
diff --git a/src/plugins/platforms/ios/qioseventdispatcher.h b/src/plugins/platforms/ios/qioseventdispatcher.h
index b40024ec19..5eee0556f5 100644
--- a/src/plugins/platforms/ios/qioseventdispatcher.h
+++ b/src/plugins/platforms/ios/qioseventdispatcher.h
@@ -16,6 +16,8 @@ public:
static QIOSEventDispatcher* create();
bool processPostedEvents() override;
+ static bool isQtApplication();
+
protected:
explicit QIOSEventDispatcher(QObject *parent = nullptr);
};
diff --git a/src/plugins/platforms/ios/qioseventdispatcher.mm b/src/plugins/platforms/ios/qioseventdispatcher.mm
index 24d9d88294..710a834bfd 100644
--- a/src/plugins/platforms/ios/qioseventdispatcher.mm
+++ b/src/plugins/platforms/ios/qioseventdispatcher.mm
@@ -5,6 +5,10 @@
#include "qiosapplicationdelegate.h"
#include "qiosglobal.h"
+#if defined(Q_OS_VISIONOS)
+#include "qiosswiftintegration.h"
+#endif
+
#include <QtCore/qprocessordetection.h>
#include <QtCore/private/qcoreapplication_p.h>
#include <QtCore/private/qthread_p.h>
@@ -173,12 +177,16 @@ namespace
QAppleLogActivity UIApplicationMain;
QAppleLogActivity applicationDidFinishLaunching;
} logActivity;
+
+ static bool s_isQtApplication = false;
}
using namespace QT_PREPEND_NAMESPACE(QtPrivate);
extern "C" int qt_main_wrapper(int argc, char *argv[])
{
+ s_isQtApplication = true;
+
@autoreleasepool {
size_t defaultStackSize = 512 * kBytesPerKiloByte; // Same as secondary threads
@@ -202,8 +210,16 @@ extern "C" int qt_main_wrapper(int argc, char *argv[])
logActivity.UIApplicationMain = QT_APPLE_LOG_ACTIVITY(
lcEventDispatcher().isDebugEnabled(), "UIApplicationMain").enter();
+#if defined(Q_OS_VISIONOS)
+ Q_UNUSED(argc);
+ Q_UNUSED(argv);
+ qCDebug(lcEventDispatcher) << "Starting Swift app";
+ QIOSIntegrationPluginSwift::runSwiftAppMain();
+ Q_UNREACHABLE();
+#else
qCDebug(lcEventDispatcher) << "Running UIApplicationMain";
return UIApplicationMain(argc, argv, nil, NSStringFromClass([QIOSApplicationDelegate class]));
+#endif
}
}
@@ -424,6 +440,11 @@ QIOSEventDispatcher::QIOSEventDispatcher(QObject *parent)
QWindowSystemInterface::setSynchronousWindowSystemEvents(true);
}
+bool QIOSEventDispatcher::isQtApplication()
+{
+ return s_isQtApplication;
+}
+
/*!
Override of the CoreFoundation posted events runloop source callback
so that we can send window system (QPA) events in addition to sending
diff --git a/src/plugins/platforms/ios/qiosglobal.h b/src/plugins/platforms/ios/qiosglobal.h
index 0fafbe1936..9428487a00 100644
--- a/src/plugins/platforms/ios/qiosglobal.h
+++ b/src/plugins/platforms/ios/qiosglobal.h
@@ -14,6 +14,7 @@ QT_BEGIN_NAMESPACE
Q_DECLARE_LOGGING_CATEGORY(lcQpaApplication);
Q_DECLARE_LOGGING_CATEGORY(lcQpaInputMethods);
Q_DECLARE_LOGGING_CATEGORY(lcQpaWindow);
+Q_DECLARE_LOGGING_CATEGORY(lcQpaWindowScene);
#if !defined(QT_NO_DEBUG)
#define qImDebug \
@@ -36,7 +37,9 @@ UIDeviceOrientation fromQtScreenOrientation(Qt::ScreenOrientation qtOrientation)
int infoPlistValue(NSString* key, int defaultValue);
class QWindow;
+class QScreen;
UIWindow *presentationWindow(QWindow *);
+UIView *rootViewForScreen(QScreen *);
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/ios/qiosglobal.mm b/src/plugins/platforms/ios/qiosglobal.mm
index eb9e713b0d..1722e09aaa 100644
--- a/src/plugins/platforms/ios/qiosglobal.mm
+++ b/src/plugins/platforms/ios/qiosglobal.mm
@@ -5,6 +5,8 @@
#include "qiosapplicationdelegate.h"
#include "qiosviewcontroller.h"
#include "qiosscreen.h"
+#include "quiwindow.h"
+#include "qioseventdispatcher.h"
#include <QtCore/private/qcore_mac_p.h>
@@ -13,20 +15,17 @@ QT_BEGIN_NAMESPACE
Q_LOGGING_CATEGORY(lcQpaApplication, "qt.qpa.application");
Q_LOGGING_CATEGORY(lcQpaInputMethods, "qt.qpa.input.methods");
Q_LOGGING_CATEGORY(lcQpaWindow, "qt.qpa.window");
+Q_LOGGING_CATEGORY(lcQpaWindowScene, "qt.qpa.window.scene");
bool isQtApplication()
{
- if (qt_apple_isApplicationExtension())
- return false;
-
// Returns \c true if the plugin is in full control of the whole application. This means
// that we control the application delegate and the top view controller, and can take
// actions that impacts all parts of the application. The opposite means that we are
// embedded inside a native iOS application, and should be more focused on playing along
// with native UIControls, and less inclined to change structures that lies outside the
// scope of our QWindows/UIViews.
- static bool isQt = ([qt_apple_sharedApplication().delegate isKindOfClass:[QIOSApplicationDelegate class]]);
- return isQt;
+ return QIOSEventDispatcher::isQtApplication();
}
bool isRunningOnVisionOS()
@@ -109,6 +108,38 @@ UIWindow *presentationWindow(QWindow *window)
return uiWindow;
}
+UIView *rootViewForScreen(QScreen *screen)
+{
+ const auto *iosScreen = static_cast<QIOSScreen *>(screen->handle());
+ for (UIScene *scene in [qt_apple_sharedApplication().connectedScenes allObjects]) {
+ if (![scene isKindOfClass:UIWindowScene.class])
+ continue;
+
+ auto *windowScene = static_cast<UIWindowScene*>(scene);
+
+#if !defined(Q_OS_VISIONOS)
+ if (windowScene.screen != iosScreen->uiScreen())
+ continue;
+#else
+ Q_UNUSED(iosScreen);
+#endif
+
+ UIWindow *uiWindow = qt_objc_cast<QUIWindow*>(windowScene.keyWindow);
+ if (!uiWindow) {
+ for (UIWindow *win in windowScene.windows) {
+ if (qt_objc_cast<QUIWindow*>(win)) {
+ uiWindow = win;
+ break;
+ }
+ }
+ }
+
+ return uiWindow.rootViewController.view;
+ }
+
+ return nullptr;
+}
+
QT_END_NAMESPACE
// -------------------------------------------------------------------------
diff --git a/src/plugins/platforms/ios/qiosintegration.h b/src/plugins/platforms/ios/qiosintegration.h
index 2c7d33cc94..53f64c1748 100644
--- a/src/plugins/platforms/ios/qiosintegration.h
+++ b/src/plugins/platforms/ios/qiosintegration.h
@@ -16,11 +16,24 @@
#include "qiostextinputoverlay.h"
#endif
+#if defined(Q_OS_VISIONOS)
+#include <swift/bridging>
+#endif
+
QT_BEGIN_NAMESPACE
+using namespace QNativeInterface;
+
class QIOSServices;
-class QIOSIntegration : public QPlatformNativeInterface, public QPlatformIntegration
+class
+#if defined(Q_OS_VISIONOS)
+ SWIFT_IMMORTAL_REFERENCE
+#endif
+QIOSIntegration : public QPlatformNativeInterface, public QPlatformIntegration
+#if defined(Q_OS_VISIONOS)
+ , public QVisionOSApplication
+#endif
{
Q_OBJECT
public:
@@ -77,6 +90,17 @@ public:
QIOSApplicationState applicationState;
+#if defined(Q_OS_VISIONOS)
+ void openImmersiveSpace() override;
+ void dismissImmersiveSpace() override;
+
+ using CompositorLayer = QVisionOSApplication::ImmersiveSpaceCompositorLayer;
+ void setImmersiveSpaceCompositorLayer(CompositorLayer *layer) override;
+
+ void configureCompositorLayer(cp_layer_renderer_capabilities_t, cp_layer_renderer_configuration_t);
+ void renderCompositorLayer(cp_layer_renderer_t);
+#endif
+
private:
QPlatformFontDatabase *m_fontDatabase;
#if QT_CONFIG(clipboard)
@@ -90,6 +114,10 @@ private:
#if !defined(Q_OS_TVOS) && !defined(Q_OS_VISIONOS)
QIOSTextInputOverlay m_textInputOverlay;
#endif
+
+#if defined(Q_OS_VISIONOS)
+ CompositorLayer *m_immersiveSpaceCompositorLayer = nullptr;
+#endif
};
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/ios/qiosintegration.mm b/src/plugins/platforms/ios/qiosintegration.mm
index 7cd21f83f6..2c32957c03 100644
--- a/src/plugins/platforms/ios/qiosintegration.mm
+++ b/src/plugins/platforms/ios/qiosintegration.mm
@@ -17,6 +17,10 @@
#include "qiosservices.h"
#include "qiosoptionalplugininterface.h"
+#if defined(Q_OS_VISIONOS)
+#include "qiosswiftintegration.h"
+#endif
+
#include <QtGui/qpointingdevice.h>
#include <QtGui/private/qguiapplication_p.h>
#include <QtGui/private/qrhibackingstore_p.h>
@@ -296,6 +300,39 @@ void QIOSIntegration::setApplicationBadge(qint64 number)
// ---------------------------------------------------------
+#if defined(Q_OS_VISIONOS)
+void QIOSIntegration::openImmersiveSpace()
+{
+ [ImmersiveSpaceManager openImmersiveSpace];
+}
+
+void QIOSIntegration::dismissImmersiveSpace()
+{
+ [ImmersiveSpaceManager dismissImmersiveSpace];
+}
+
+void QIOSIntegration::setImmersiveSpaceCompositorLayer(CompositorLayer *layer)
+{
+ m_immersiveSpaceCompositorLayer = layer;
+}
+
+void QIOSIntegration::configureCompositorLayer(cp_layer_renderer_capabilities_t capabilities,
+ cp_layer_renderer_configuration_t configuration)
+{
+ if (m_immersiveSpaceCompositorLayer)
+ m_immersiveSpaceCompositorLayer->configure(capabilities, configuration);
+}
+
+void QIOSIntegration::renderCompositorLayer(cp_layer_renderer_t renderer)
+{
+ if (m_immersiveSpaceCompositorLayer)
+ m_immersiveSpaceCompositorLayer->render(renderer);
+}
+
+#endif
+
+// ---------------------------------------------------------
+
void *QIOSIntegration::nativeResourceForWindow(const QByteArray &resource, QWindow *window)
{
if (!window || !window->handle())
diff --git a/src/plugins/platforms/ios/qiosscreen.h b/src/plugins/platforms/ios/qiosscreen.h
index f05a5456b3..dd69428390 100644
--- a/src/plugins/platforms/ios/qiosscreen.h
+++ b/src/plugins/platforms/ios/qiosscreen.h
@@ -43,7 +43,6 @@ public:
#if !defined(Q_OS_VISIONOS)
UIScreen *uiScreen() const;
#endif
- UIWindow *uiWindow() const;
void setUpdatesPaused(bool);
@@ -55,7 +54,6 @@ private:
#if !defined(Q_OS_VISIONOS)
UIScreen *m_uiScreen = nullptr;
#endif
- UIWindow *m_uiWindow = nullptr;
QRect m_geometry;
QRect m_availableGeometry;
int m_depth;
@@ -63,7 +61,6 @@ private:
uint m_physicalDpi;
#endif
QSizeF m_physicalSize;
- QIOSOrientationListener *m_orientationListener = nullptr;
CADisplayLink *m_displayLink = nullptr;
};
diff --git a/src/plugins/platforms/ios/qiosscreen.mm b/src/plugins/platforms/ios/qiosscreen.mm
index e7555c19ab..7559979f33 100644
--- a/src/plugins/platforms/ios/qiosscreen.mm
+++ b/src/plugins/platforms/ios/qiosscreen.mm
@@ -107,50 +107,6 @@ static QIOSScreen* qtPlatformScreenFor(UIScreen *uiScreen)
@end
-// -------------------------------------------------------------------------
-
-@interface QIOSOrientationListener : NSObject
-@end
-
-@implementation QIOSOrientationListener {
- QIOSScreen *m_screen;
-}
-
-- (instancetype)initWithQIOSScreen:(QIOSScreen *)screen
-{
- self = [super init];
- if (self) {
- m_screen = screen;
-#ifndef Q_OS_TVOS
- [[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications];
- [[NSNotificationCenter defaultCenter]
- addObserver:self
- selector:@selector(orientationChanged:)
- name:@"UIDeviceOrientationDidChangeNotification" object:nil];
-#endif
- }
- return self;
-}
-
-- (void)dealloc
-{
-#ifndef Q_OS_TVOS
- [[UIDevice currentDevice] endGeneratingDeviceOrientationNotifications];
- [[NSNotificationCenter defaultCenter]
- removeObserver:self
- name:@"UIDeviceOrientationDidChangeNotification" object:nil];
-#endif
- [super dealloc];
-}
-
-- (void)orientationChanged:(NSNotification *)notification
-{
- Q_UNUSED(notification);
- m_screen->updateProperties();
-}
-
-@end
-
#endif // !defined(Q_OS_VISIONOS)
// -------------------------------------------------------------------------
@@ -220,23 +176,6 @@ QIOSScreen::QIOSScreen(UIScreen *screen)
m_physicalDpi = 96;
}
- if (!qt_apple_isApplicationExtension()) {
- for (UIWindow *existingWindow in qt_apple_sharedApplication().windows) {
- if (existingWindow.screen == m_uiScreen) {
- m_uiWindow = [existingWindow retain];
- break;
- }
- }
-
- if (!m_uiWindow) {
- // Create a window and associated view-controller that we can use
- m_uiWindow = [[QUIWindow alloc] initWithFrame:[m_uiScreen bounds]];
- m_uiWindow.rootViewController = [[[QIOSViewController alloc] initWithQIOSScreen:this] autorelease];
- }
- }
-
- m_orientationListener = [[QIOSOrientationListener alloc] initWithQIOSScreen:this];
-
m_displayLink = [m_uiScreen displayLinkWithBlock:^(CADisplayLink *) { deliverUpdateRequests(); }];
m_displayLink.paused = YES; // Enabled when clients call QWindow::requestUpdate()
[m_displayLink addToRunLoop:[NSRunLoop mainRunLoop] forMode:NSDefaultRunLoopMode];
@@ -249,9 +188,6 @@ QIOSScreen::QIOSScreen(UIScreen *screen)
QIOSScreen::~QIOSScreen()
{
[m_displayLink invalidate];
-
- [m_orientationListener release];
- [m_uiWindow release];
}
QString QIOSScreen::name() const
@@ -278,31 +214,6 @@ void QIOSScreen::updateProperties()
#else
m_geometry = QRectF::fromCGRect(m_uiScreen.bounds).toRect();
-#ifndef Q_OS_TVOS
- if (m_uiScreen == [UIScreen mainScreen]) {
- QIOSViewController *qtViewController = [m_uiWindow.rootViewController isKindOfClass:[QIOSViewController class]] ?
- static_cast<QIOSViewController *>(m_uiWindow.rootViewController) : nil;
-
- if (qtViewController.lockedOrientation) {
- Q_ASSERT(!qt_apple_isApplicationExtension());
-
- // Setting the statusbar orientation (content orientation) on will affect the screen geometry,
- // which is not what we want. We want to reflect the screen geometry based on the locked orientation,
- // and adjust the available geometry based on the repositioned status bar for the current status
- // bar orientation.
-
- Qt::ScreenOrientation statusBarOrientation = toQtScreenOrientation(
- UIDeviceOrientation(qt_apple_sharedApplication().statusBarOrientation));
-
- Qt::ScreenOrientation lockedOrientation = toQtScreenOrientation(UIDeviceOrientation(qtViewController.lockedOrientation));
- QTransform transform = transformBetween(lockedOrientation, statusBarOrientation, m_geometry).inverted();
-
- m_geometry = transform.mapRect(m_geometry);
- m_availableGeometry = transform.mapRect(m_availableGeometry);
- }
- }
-#endif
-
if (m_geometry != previousGeometry) {
// We can't use the primaryOrientation of screen(), as we haven't reported the new geometry yet
Qt::ScreenOrientation primaryOrientation = m_geometry.width() >= m_geometry.height() ?
@@ -448,34 +359,13 @@ Qt::ScreenOrientation QIOSScreen::nativeOrientation() const
Qt::ScreenOrientation QIOSScreen::orientation() const
{
-#if defined(Q_OS_TVOS) || defined(Q_OS_VISIONOS)
- return Qt::PrimaryOrientation;
-#else
- // Auxiliary screens are always the same orientation as their primary orientation
- if (m_uiScreen != [UIScreen mainScreen])
- return Qt::PrimaryOrientation;
-
- UIDeviceOrientation deviceOrientation = [UIDevice currentDevice].orientation;
-
- // At startup, iOS will report an unknown orientation for the device, even
- // if we've asked it to begin generating device orientation notifications.
- // In this case we fall back to the status bar orientation, which reflects
- // the orientation the application was started up in (which may not match
- // the physical orientation of the device, but typically does unless the
- // application has been locked to a subset of the available orientations).
- if (deviceOrientation == UIDeviceOrientationUnknown && !qt_apple_isApplicationExtension())
- deviceOrientation = UIDeviceOrientation(qt_apple_sharedApplication().statusBarOrientation);
-
- // If the device reports face up or face down orientations, we can't map
- // them to Qt orientations, so we pretend we're in the same orientation
- // as before.
- if (deviceOrientation == UIDeviceOrientationFaceUp || deviceOrientation == UIDeviceOrientationFaceDown) {
- Q_ASSERT(screen());
- return screen()->orientation();
- }
-
- return toQtScreenOrientation(deviceOrientation);
-#endif
+ // We don't report UIDevice.currentDevice.orientation here,
+ // as that would report the actual orientation of the device,
+ // even if the orientation of the UI was locked to a subset
+ // of the possible orientations via the app's Info.plist or
+ // via [UIViewController supportedInterfaceOrientations].
+ return m_geometry.width() >= m_geometry.height() ?
+ Qt::LandscapeOrientation : Qt::PortraitOrientation;
}
QPixmap QIOSScreen::grabWindow(WId window, int x, int y, int width, int height) const
@@ -483,7 +373,8 @@ QPixmap QIOSScreen::grabWindow(WId window, int x, int y, int width, int height)
if (window && ![reinterpret_cast<id>(window) isKindOfClass:[UIView class]])
return QPixmap();
- UIView *view = window ? reinterpret_cast<UIView *>(window) : m_uiWindow.rootViewController.view;
+ UIView *view = window ? reinterpret_cast<UIView *>(window)
+ : rootViewForScreen(screen());
if (width < 0)
width = qMax(view.bounds.size.width - x, CGFloat(0));
@@ -517,11 +408,6 @@ UIScreen *QIOSScreen::uiScreen() const
}
#endif
-UIWindow *QIOSScreen::uiWindow() const
-{
- return m_uiWindow;
-}
-
QT_END_NAMESPACE
#include "moc_qiosscreen.cpp"
diff --git a/src/plugins/platforms/ios/qiostextinputoverlay.mm b/src/plugins/platforms/ios/qiostextinputoverlay.mm
index 01046334a1..83170c1851 100644
--- a/src/plugins/platforms/ios/qiostextinputoverlay.mm
+++ b/src/plugins/platforms/ios/qiostextinputoverlay.mm
@@ -434,7 +434,7 @@ static void executeBlockWithoutAnimation(Block block)
if (enabled) {
_focusView = [reinterpret_cast<UIView *>(qApp->focusWindow()->winId()) retain];
- _desktopView = [qt_apple_sharedApplication().keyWindow.rootViewController.view retain];
+ _desktopView = [presentationWindow(nullptr).rootViewController.view retain];
Q_ASSERT(_focusView && _desktopView && _desktopView.superview);
[_desktopView addGestureRecognizer:self];
} else {
diff --git a/src/plugins/platforms/ios/qiostheme.h b/src/plugins/platforms/ios/qiostheme.h
index f0a404a61a..70e2c37ff1 100644
--- a/src/plugins/platforms/ios/qiostheme.h
+++ b/src/plugins/platforms/ios/qiostheme.h
@@ -4,6 +4,8 @@
#ifndef QIOSTHEME_H
#define QIOSTHEME_H
+#import <UIKit/UIKit.h>
+
#include <QtCore/QHash>
#include <QtGui/QPalette>
#include <qpa/qplatformtheme.h>
@@ -22,6 +24,7 @@ public:
QVariant themeHint(ThemeHint hint) const override;
Qt::ColorScheme colorScheme() const override;
+ void requestColorScheme(Qt::ColorScheme scheme) override;
#if !defined(Q_OS_TVOS) && !defined(Q_OS_VISIONOS)
QPlatformMenuItem* createPlatformMenuItem() const override;
@@ -37,9 +40,11 @@ public:
static const char *name;
static void initializeSystemPalette();
+ static void applyTheme(UIWindow *window);
private:
static QPalette s_systemPalette;
+ static inline Qt::ColorScheme s_colorSchemeOverride = Qt::ColorScheme::Unknown;
QMacNotificationObserver m_contentSizeCategoryObserver;
};
diff --git a/src/plugins/platforms/ios/qiostheme.mm b/src/plugins/platforms/ios/qiostheme.mm
index 3853de9cf1..0b420a875a 100644
--- a/src/plugins/platforms/ios/qiostheme.mm
+++ b/src/plugins/platforms/ios/qiostheme.mm
@@ -154,6 +154,9 @@ Qt::ColorScheme QIOSTheme::colorScheme() const
// the OS reports itself as always being in dark mode.
return Qt::ColorScheme::Dark;
#else
+ if (s_colorSchemeOverride != Qt::ColorScheme::Unknown)
+ return s_colorSchemeOverride;
+
// Set the appearance based on the QUIWindow
// Fallback to the UIScreen if no window is created yet
UIUserInterfaceStyle appearance = UIScreen.mainScreen.traitCollection.userInterfaceStyle;
@@ -171,6 +174,38 @@ Qt::ColorScheme QIOSTheme::colorScheme() const
#endif
}
+void QIOSTheme::requestColorScheme(Qt::ColorScheme scheme)
+{
+#if defined(Q_OS_VISIONOS)
+ Q_UNUSED(scheme);
+#else
+ s_colorSchemeOverride = scheme;
+
+ const NSArray<UIWindow *> *windows = qt_apple_sharedApplication().windows;
+ for (UIWindow *window in windows) {
+ // don't apply a theme to windows we don't own
+ if (qt_objc_cast<QUIWindow*>(window))
+ applyTheme(window);
+ }
+#endif
+}
+
+void QIOSTheme::applyTheme(UIWindow *window)
+{
+ const UIUserInterfaceStyle style = []{
+ switch (s_colorSchemeOverride) {
+ case Qt::ColorScheme::Dark:
+ return UIUserInterfaceStyleDark;
+ case Qt::ColorScheme::Light:
+ return UIUserInterfaceStyleLight;
+ case Qt::ColorScheme::Unknown:
+ return UIUserInterfaceStyleUnspecified;
+ }
+ }();
+
+ window.overrideUserInterfaceStyle = style;
+}
+
const QFont *QIOSTheme::font(Font type) const
{
const auto *platformIntegration = QGuiApplicationPrivate::platformIntegration();
diff --git a/src/plugins/platforms/ios/qiosviewcontroller.h b/src/plugins/platforms/ios/qiosviewcontroller.h
index 237cd57edf..1f8da41ba4 100644
--- a/src/plugins/platforms/ios/qiosviewcontroller.h
+++ b/src/plugins/platforms/ios/qiosviewcontroller.h
@@ -12,14 +12,12 @@ QT_END_NAMESPACE
@interface QIOSViewController : UIViewController
-- (instancetype)initWithQIOSScreen:(QT_PREPEND_NAMESPACE(QIOSScreen) *)screen;
+- (instancetype)initWithWindow:(UIWindow*)window andScreen:(QT_PREPEND_NAMESPACE(QIOSScreen) *)screen;
- (void)updateProperties;
- (NSArray*)keyCommands;
- (void)handleShortcut:(UIKeyCommand*)keyCommand;
#ifndef Q_OS_TVOS
-@property (nonatomic, assign) UIInterfaceOrientation lockedOrientation;
-
// UIViewController
@property (nonatomic, assign) BOOL prefersStatusBarHidden;
@property (nonatomic, assign) UIStatusBarAnimation preferredStatusBarUpdateAnimation;
diff --git a/src/plugins/platforms/ios/qiosviewcontroller.mm b/src/plugins/platforms/ios/qiosviewcontroller.mm
index fa3fef26b6..436d1e7bed 100644
--- a/src/plugins/platforms/ios/qiosviewcontroller.mm
+++ b/src/plugins/platforms/ios/qiosviewcontroller.mm
@@ -26,6 +26,7 @@
// -------------------------------------------------------------------------
@interface QIOSViewController ()
+@property (nonatomic, assign) UIWindow *window;
@property (nonatomic, assign) QPointer<QT_PREPEND_NAMESPACE(QIOSScreen)> platformScreen;
@property (nonatomic, assign) BOOL changingOrientation;
@end
@@ -88,28 +89,25 @@
- (void)didAddSubview:(UIView *)subview
{
-#if !defined(Q_OS_VISIONOS)
Q_UNUSED(subview);
- QT_PREPEND_NAMESPACE(QIOSScreen) *screen = self.qtViewController.platformScreen;
-
- // The 'window' property of our view is not valid until the window
- // has been shown, so we have to access it through the QIOSScreen.
- UIWindow *uiWindow = screen->uiWindow();
+ // Track UIWindow via explicit property on QIOSViewController,
+ // as the window property of our own view is not valid until
+ // the window has been shown (below).
+ UIWindow *uiWindow = self.qtViewController.window;
if (uiWindow.hidden) {
- // Associate UIWindow to screen and show it the first time a QWindow
- // is mapped to the screen. For external screens this means disabling
- // mirroring mode and presenting alternate content on the screen.
- uiWindow.screen = screen->uiScreen();
+ // Show the UIWindow the first time a QWindow is mapped to the screen.
+ // For the main screen this hides the launch screen, while for external
+ // screens this disables mirroring of the main screen, so the external
+ // screen can be used for alternate content.
uiWindow.hidden = NO;
}
-#endif
}
+#if !defined(Q_OS_VISIONOS)
- (void)willRemoveSubview:(UIView *)subview
{
-#if !defined(Q_OS_VISIONOS)
Q_UNUSED(subview);
UIWindow *uiWindow = self.window;
@@ -124,11 +122,10 @@
// to ensure that we don't try to layout the view that's being removed.
dispatch_async(dispatch_get_main_queue(), ^{
uiWindow.hidden = YES;
- uiWindow.screen = [UIScreen mainScreen];
});
}
-#endif
}
+#endif
- (void)layoutSubviews
{
@@ -234,15 +231,14 @@
@synthesize preferredStatusBarStyle;
#endif
-- (instancetype)initWithQIOSScreen:(QT_PREPEND_NAMESPACE(QIOSScreen) *)screen
+- (instancetype)initWithWindow:(UIWindow*)window andScreen:(QT_PREPEND_NAMESPACE(QIOSScreen) *)screen
{
if (self = [self init]) {
+ self.window = window;
self.platformScreen = screen;
self.changingOrientation = NO;
#ifndef Q_OS_TVOS
- self.lockedOrientation = UIInterfaceOrientationUnknown;
-
// Status bar may be initially hidden at startup through Info.plist
self.prefersStatusBarHidden = infoPlistValue(@"UIStatusBarHidden", false);
self.preferredStatusBarUpdateAnimation = UIStatusBarAnimationNone;
@@ -299,6 +295,15 @@
name:UIApplicationDidChangeStatusBarOrientationNotification
object:qt_apple_sharedApplication()];
#endif
+
+ // Make sure any top level windows that have already been created
+ // for this screen are reparented into our desktop manager view.
+ for (auto *window : qGuiApp->topLevelWindows()) {
+ if (window->screen()->handle() != self.platformScreen)
+ continue;
+ if (auto *platformWindow = window->handle())
+ platformWindow->setParent(nullptr);
+ }
}
- (void)viewDidUnload
@@ -309,26 +314,6 @@
// -------------------------------------------------------------------------
-- (BOOL)shouldAutorotate
-{
-#if !defined(Q_OS_TVOS) && !defined(Q_OS_VISIONOS)
- return self.platformScreen && self.platformScreen->uiScreen() == [UIScreen mainScreen] && !self.lockedOrientation;
-#else
- return NO;
-#endif
-}
-
-- (NSUInteger)supportedInterfaceOrientations
-{
- // As documented by Apple in the iOS 6.0 release notes, setStatusBarOrientation:animated:
- // only works if the supportedInterfaceOrientations of the view controller is 0, making
- // us responsible for ensuring that the status bar orientation is consistent. We enter
- // this mode when auto-rotation is disabled due to an explicit content orientation being
- // set on the focus window. Note that this is counter to what the documentation for
- // supportedInterfaceOrientations says, which states that the method should not return 0.
- return [self shouldAutorotate] ? UIInterfaceOrientationMaskAll : 0;
-}
-
- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)orientation duration:(NSTimeInterval)duration
{
self.changingOrientation = YES;
@@ -460,51 +445,6 @@
[self setNeedsStatusBarAppearanceUpdate];
[self.view setNeedsLayout];
}
-
-
- // -------------- Content orientation ---------------
-
- UIApplication *uiApplication = qt_apple_sharedApplication();
-
- static BOOL kAnimateContentOrientationChanges = YES;
-
- Qt::ScreenOrientation contentOrientation = focusWindow->contentOrientation();
- if (contentOrientation != Qt::PrimaryOrientation) {
- // An explicit content orientation has been reported for the focus window,
- // so we keep the status bar in sync with content orientation. This will ensure
- // that the task bar (and associated gestures) are also rotated accordingly.
-
- if (!self.lockedOrientation) {
- // We are moving from Qt::PrimaryOrientation to an explicit orientation,
- // so we need to store the current statusbar orientation, as we need it
- // later when mapping screen coordinates for QScreen and for returning
- // to Qt::PrimaryOrientation.
- self.lockedOrientation = uiApplication.statusBarOrientation;
- }
-
- [uiApplication setStatusBarOrientation:
- UIInterfaceOrientation(fromQtScreenOrientation(contentOrientation))
- animated:kAnimateContentOrientationChanges];
-
- } else {
- // The content orientation is set to Qt::PrimaryOrientation, meaning
- // that auto-rotation should be enabled. But we may be coming out of
- // a state of locked orientation, which needs some cleanup before we
- // can enable auto-rotation again.
- if (self.lockedOrientation) {
- // First we need to restore the statusbar to what it was at the
- // time of locking the orientation, otherwise iOS will be very
- // confused when it starts doing auto-rotation again.
- [uiApplication setStatusBarOrientation:self.lockedOrientation
- animated:kAnimateContentOrientationChanges];
-
- // Then we can re-enable auto-rotation
- self.lockedOrientation = UIInterfaceOrientationUnknown;
-
- // And finally let iOS rotate the root view to match the device orientation
- [UIViewController attemptRotationToDeviceOrientation];
- }
- }
#endif
}
diff --git a/src/plugins/platforms/ios/qioswindow.h b/src/plugins/platforms/ios/qioswindow.h
index 02b2161202..88afee80c3 100644
--- a/src/plugins/platforms/ios/qioswindow.h
+++ b/src/plugins/platforms/ios/qioswindow.h
@@ -28,7 +28,6 @@ public:
void setWindowState(Qt::WindowStates state) override;
void setParent(const QPlatformWindow *window) override;
- void handleContentOrientationChange(Qt::ScreenOrientation orientation) override;
void setVisible(bool visible) override;
void setOpacity(qreal level) override;
diff --git a/src/plugins/platforms/ios/qioswindow.mm b/src/plugins/platforms/ios/qioswindow.mm
index 0f4a6803b3..f461a5f55b 100644
--- a/src/plugins/platforms/ios/qioswindow.mm
+++ b/src/plugins/platforms/ios/qioswindow.mm
@@ -55,6 +55,9 @@ QIOSWindow::QIOSWindow(QWindow *window, WId nativeHandle)
connect(qGuiApp, &QGuiApplication::applicationStateChanged, this, &QIOSWindow::applicationStateChanged);
+ // Always set parent, even if we don't have a parent window,
+ // as we use setParent to reparent top levels into our desktop
+ // manager view.
setParent(QPlatformWindow::parent());
if (!isForeignWindow()) {
@@ -297,14 +300,14 @@ void QIOSWindow::setWindowState(Qt::WindowStates state)
void QIOSWindow::setParent(const QPlatformWindow *parentWindow)
{
- UIView *parentView = parentWindow ?
- reinterpret_cast<UIView *>(parentWindow->winId())
- : isQtApplication() && !isForeignWindow() ?
- static_cast<QIOSScreen *>(screen())->uiWindow().rootViewController.view
- : nullptr;
-
- if (parentView)
- [parentView addSubview:m_view];
+ UIView *superview = nullptr;
+ if (parentWindow)
+ superview = reinterpret_cast<UIView *>(parentWindow->winId());
+ else if (isQtApplication() && !isForeignWindow())
+ superview = rootViewForScreen(window()->screen());
+
+ if (superview)
+ [superview addSubview:m_view];
else if (quiview_cast(m_view.superview))
[m_view removeFromSuperview];
}
@@ -382,16 +385,6 @@ void QIOSWindow::updateWindowLevel()
m_windowLevel = qMax(transientParentWindow->m_windowLevel, m_windowLevel);
}
-void QIOSWindow::handleContentOrientationChange(Qt::ScreenOrientation orientation)
-{
- // Update the QWindow representation straight away, so that
- // we can update the statusbar orientation based on the new
- // content orientation.
- qt_window_private(window())->contentOrientation = orientation;
-
- [m_view.qtViewController updateProperties];
-}
-
void QIOSWindow::applicationStateChanged(Qt::ApplicationState)
{
if (isForeignWindow())
diff --git a/src/plugins/platforms/ios/quiwindow.mm b/src/plugins/platforms/ios/quiwindow.mm
index 7c910b6d9e..783e243e10 100644
--- a/src/plugins/platforms/ios/quiwindow.mm
+++ b/src/plugins/platforms/ios/quiwindow.mm
@@ -22,6 +22,15 @@
return self;
}
+- (instancetype)initWithWindowScene:(UIWindowScene *)windowScene
+{
+ if ((self = [super initWithWindowScene:windowScene]))
+ self->_sendingEvent = NO;
+
+ QIOSTheme::applyTheme(self);
+ return self;
+}
+
- (void)sendEvent:(UIEvent *)event
{
QScopedValueRollback<BOOL> sendingEvent(self->_sendingEvent, YES);
diff --git a/src/plugins/platforms/linuxfb/CMakeLists.txt b/src/plugins/platforms/linuxfb/CMakeLists.txt
index 9f75f53828..ba18cea50c 100644
--- a/src/plugins/platforms/linuxfb/CMakeLists.txt
+++ b/src/plugins/platforms/linuxfb/CMakeLists.txt
@@ -8,7 +8,7 @@
qt_internal_add_plugin(QLinuxFbIntegrationPlugin
OUTPUT_NAME qlinuxfb
PLUGIN_TYPE platforms
- DEFAULT_IF ${QT_QPA_DEFAULT_PLATFORM} MATCHES linuxfb
+ DEFAULT_IF "linuxfb" IN_LIST QT_QPA_PLATFORMS
SOURCES
main.cpp
qlinuxfbintegration.cpp qlinuxfbintegration.h
diff --git a/src/plugins/platforms/minimal/CMakeLists.txt b/src/plugins/platforms/minimal/CMakeLists.txt
index f3683deccf..18d8828134 100644
--- a/src/plugins/platforms/minimal/CMakeLists.txt
+++ b/src/plugins/platforms/minimal/CMakeLists.txt
@@ -10,7 +10,7 @@ qt_find_package(WrapFreetype PROVIDED_TARGETS WrapFreetype::WrapFreetype)
qt_internal_add_plugin(QMinimalIntegrationPlugin
OUTPUT_NAME qminimal
PLUGIN_TYPE platforms
- DEFAULT_IF ${QT_QPA_DEFAULT_PLATFORM} MATCHES minimal
+ DEFAULT_IF "minimal" IN_LIST QT_QPA_PLATFORMS
SOURCES
main.cpp
qminimalbackingstore.cpp qminimalbackingstore.h
diff --git a/src/plugins/platforms/minimalegl/CMakeLists.txt b/src/plugins/platforms/minimalegl/CMakeLists.txt
index a6ec8be781..b93f325b8f 100644
--- a/src/plugins/platforms/minimalegl/CMakeLists.txt
+++ b/src/plugins/platforms/minimalegl/CMakeLists.txt
@@ -10,7 +10,7 @@ qt_find_package(EGL)
qt_internal_add_plugin(QMinimalEglIntegrationPlugin
OUTPUT_NAME qminimalegl
PLUGIN_TYPE platforms
- DEFAULT_IF ${QT_QPA_DEFAULT_PLATFORM} MATCHES minimalegl
+ DEFAULT_IF "minimalegl" IN_LIST QT_QPA_PLATFORMS
SOURCES
main.cpp
qminimaleglintegration.cpp qminimaleglintegration.h
diff --git a/src/plugins/platforms/offscreen/CMakeLists.txt b/src/plugins/platforms/offscreen/CMakeLists.txt
index 09ad9a384d..907c2c9cc6 100644
--- a/src/plugins/platforms/offscreen/CMakeLists.txt
+++ b/src/plugins/platforms/offscreen/CMakeLists.txt
@@ -8,7 +8,7 @@
qt_internal_add_plugin(QOffscreenIntegrationPlugin
OUTPUT_NAME qoffscreen
PLUGIN_TYPE platforms
- DEFAULT_IF ${QT_QPA_DEFAULT_PLATFORM} MATCHES offscreen
+ DEFAULT_IF "offscreen" IN_LIST QT_QPA_PLATFORMS
SOURCES
main.cpp
qoffscreencommon.cpp qoffscreencommon.h
diff --git a/src/plugins/platforms/qnx/CMakeLists.txt b/src/plugins/platforms/qnx/CMakeLists.txt
index 9fb412d8a4..0f9deaa00b 100644
--- a/src/plugins/platforms/qnx/CMakeLists.txt
+++ b/src/plugins/platforms/qnx/CMakeLists.txt
@@ -8,7 +8,7 @@
qt_internal_add_plugin(QQnxIntegrationPlugin
OUTPUT_NAME qqnx
PLUGIN_TYPE platforms
- DEFAULT_IF ${QT_QPA_DEFAULT_PLATFORM} MATCHES qnx
+ DEFAULT_IF "qnx" IN_LIST QT_QPA_PLATFORMS
SOURCES
main.cpp main.h
qqnxabstractcover.h
diff --git a/src/plugins/platforms/qnx/qqnxabstractnavigator.cpp b/src/plugins/platforms/qnx/qqnxabstractnavigator.cpp
index 05389d3ea6..9b1107b7ec 100644
--- a/src/plugins/platforms/qnx/qqnxabstractnavigator.cpp
+++ b/src/plugins/platforms/qnx/qqnxabstractnavigator.cpp
@@ -6,14 +6,10 @@
#include <QDebug>
#include <QUrl>
-#if defined(QQNXNAVIGATOR_DEBUG)
-#define qNavigatorDebug qDebug
-#else
-#define qNavigatorDebug QT_NO_QDEBUG_MACRO
-#endif
-
QT_BEGIN_NAMESPACE
+Q_LOGGING_CATEGORY(lcQpaQnxNavigator, "qt.qpa.qnx.navigator");
+
QQnxAbstractNavigator::QQnxAbstractNavigator(QObject *parent)
: QObject(parent)
{
@@ -32,7 +28,7 @@ bool QQnxAbstractNavigator::invokeUrl(const QUrl &url)
// which is not recognized by the navigator anymore
const bool result = requestInvokeUrl(url.toString().toUtf8());
- qNavigatorDebug() << "url=" << url << "result=" << result;
+ qCDebug(lcQpaQnxNavigator) << Q_FUNC_INFO << "url =" << url << "result =" << result;
return result;
}
diff --git a/src/plugins/platforms/qnx/qqnxabstractnavigator.h b/src/plugins/platforms/qnx/qqnxabstractnavigator.h
index b4e4dd9bf8..fc92592307 100644
--- a/src/plugins/platforms/qnx/qqnxabstractnavigator.h
+++ b/src/plugins/platforms/qnx/qqnxabstractnavigator.h
@@ -5,9 +5,12 @@
#define QQNXABSTRACTNAVIGATOR_H
#include <QObject>
+#include <QtCore/QLoggingCategory>
QT_BEGIN_NAMESPACE
+Q_DECLARE_LOGGING_CATEGORY(lcQpaQnxNavigator);
+
class QUrl;
class QQnxAbstractNavigator : public QObject
diff --git a/src/plugins/platforms/qnx/qqnxbuffer.cpp b/src/plugins/platforms/qnx/qqnxbuffer.cpp
index 1ea9a8b0d3..4d3b5256b2 100644
--- a/src/plugins/platforms/qnx/qqnxbuffer.cpp
+++ b/src/plugins/platforms/qnx/qqnxbuffer.cpp
@@ -10,24 +10,20 @@
#include <errno.h>
#include <sys/mman.h>
-#if defined(QQNXBUFFER_DEBUG)
-#define qBufferDebug qDebug
-#else
-#define qBufferDebug QT_NO_QDEBUG_MACRO
-#endif
-
QT_BEGIN_NAMESPACE
+Q_LOGGING_CATEGORY(lcQpaScreenBuffer, "qt.qpa.screen.buffer");
+
QQnxBuffer::QQnxBuffer()
: m_buffer(0)
{
- qBufferDebug("empty");
+ qCDebug(lcQpaScreenBuffer) << Q_FUNC_INFO << "Empty";
}
QQnxBuffer::QQnxBuffer(screen_buffer_t buffer)
: m_buffer(buffer)
{
- qBufferDebug("normal");
+ qCDebug(lcQpaScreenBuffer) << Q_FUNC_INFO << "Normal";
// Get size of buffer
int size[2];
@@ -77,7 +73,7 @@ QQnxBuffer::QQnxBuffer(screen_buffer_t buffer)
imageFormat = QImage::Format_ARGB32_Premultiplied;
break;
default:
- qFatal("QQNX: unsupported buffer format, format=%d", screenFormat);
+ qFatal(lcQpaScreenBuffer, "QQNX: unsupported buffer format, format=%d", screenFormat);
}
// wrap buffer in an image
@@ -88,27 +84,27 @@ QQnxBuffer::QQnxBuffer(const QQnxBuffer &other)
: m_buffer(other.m_buffer),
m_image(other.m_image)
{
- qBufferDebug("copy");
+ qCDebug(lcQpaScreenBuffer) << Q_FUNC_INFO << "Copy";
}
QQnxBuffer::~QQnxBuffer()
{
- qBufferDebug();
+ qCDebug(lcQpaScreenBuffer) << Q_FUNC_INFO;
}
void QQnxBuffer::invalidateInCache()
{
- qBufferDebug();
+ qCDebug(lcQpaScreenBuffer) << Q_FUNC_INFO;
// Verify native buffer exists
if (Q_UNLIKELY(!m_buffer))
- qFatal("QQNX: can't invalidate cache for null buffer");
+ qFatal(lcQpaScreenBuffer, "QQNX: can't invalidate cache for null buffer");
// Evict buffer's data from cache
errno = 0;
int result = msync(m_image.bits(), m_image.height() * m_image.bytesPerLine(), MS_INVALIDATE | MS_CACHE_ONLY);
if (Q_UNLIKELY(result != 0))
- qFatal("QQNX: failed to invalidate cache, errno=%d", errno);
+ qFatal(lcQpaScreenBuffer, "QQNX: failed to invalidate cache, errno=%d", errno);
}
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/qnx/qqnxbuffer.h b/src/plugins/platforms/qnx/qqnxbuffer.h
index b8f1443ad1..b456eb2a62 100644
--- a/src/plugins/platforms/qnx/qqnxbuffer.h
+++ b/src/plugins/platforms/qnx/qqnxbuffer.h
@@ -5,11 +5,14 @@
#define QQNXBUFFER_H
#include <QtGui/QImage>
+#include <QtCore/QLoggingCategory>
#include <screen/screen.h>
QT_BEGIN_NAMESPACE
+Q_DECLARE_LOGGING_CATEGORY(lcQpaScreenBuffer)
+
class QQnxBuffer
{
public:
diff --git a/src/plugins/platforms/qnx/qqnxbuttoneventnotifier.cpp b/src/plugins/platforms/qnx/qqnxbuttoneventnotifier.cpp
index 6497367579..788cddea87 100644
--- a/src/plugins/platforms/qnx/qqnxbuttoneventnotifier.cpp
+++ b/src/plugins/platforms/qnx/qqnxbuttoneventnotifier.cpp
@@ -13,14 +13,10 @@
#include <QtCore/QSocketNotifier>
#include <QtCore/private/qcore_unix_p.h>
-#if defined(QQNXBUTTON_DEBUG)
-#define qButtonDebug qDebug
-#else
-#define qButtonDebug QT_NO_QDEBUG_MACRO
-#endif
-
QT_BEGIN_NAMESPACE
+Q_LOGGING_CATEGORY(lcQpaInputHwButton, "qt.qpa.input.hwbutton");
+
const char *QQnxButtonEventNotifier::ppsPath = "/pps/system/buttons/status";
const size_t QQnxButtonEventNotifier::ppsBufferSize = 256;
@@ -47,7 +43,7 @@ QQnxButtonEventNotifier::~QQnxButtonEventNotifier()
void QQnxButtonEventNotifier::start()
{
- qButtonDebug("starting hardware button event processing");
+ qCDebug(lcQpaInputHwButton) << "Starting hardware button event processing";
if (m_fd != -1)
return;
@@ -64,7 +60,7 @@ void QQnxButtonEventNotifier::start()
m_readNotifier = new QSocketNotifier(m_fd, QSocketNotifier::Read);
QObject::connect(m_readNotifier, SIGNAL(activated(QSocketDescriptor)), this, SLOT(updateButtonStates()));
- qButtonDebug("successfully connected to Navigator. fd = %d", m_fd);
+ qCDebug(lcQpaInputHwButton, "successfully connected to Navigator. fd = %d", m_fd);
}
void QQnxButtonEventNotifier::updateButtonStates()
@@ -75,7 +71,8 @@ void QQnxButtonEventNotifier::updateButtonStates()
// Attempt to read pps data
errno = 0;
int bytes = qt_safe_read(m_fd, buffer, ppsBufferSize - 1);
- qButtonDebug() << "Read" << bytes << "bytes of data";
+ qCDebug(lcQpaInputHwButton) << "Read" << bytes << "bytes of data";
+
if (bytes == -1) {
qWarning("QQNX: failed to read hardware buttons pps object, errno=%d", errno);
return;
@@ -88,7 +85,7 @@ void QQnxButtonEventNotifier::updateButtonStates()
// Ensure data is null terminated
buffer[bytes] = '\0';
- qButtonDebug("received PPS message:\n%s", buffer);
+ qCDebug(lcQpaInputHwButton, "Received PPS message:\n%s", buffer);
// Process received message
QByteArray ppsData = QByteArray::fromRawData(buffer, bytes);
@@ -104,7 +101,8 @@ void QQnxButtonEventNotifier::updateButtonStates()
// If state has changed, update our state and inject a keypress event
if (m_state[buttonId] != newState) {
- qButtonDebug() << "Hardware button event: button =" << key << "state =" << fields.value(key);
+ qCDebug(lcQpaInputHwButton) << "Hardware button event: button =" << key << "state =" << fields.value(key);
+
m_state[buttonId] = newState;
// Is it a key press or key release event?
@@ -129,7 +127,7 @@ void QQnxButtonEventNotifier::updateButtonStates()
break;
default:
- qButtonDebug("Unknown hardware button");
+ qCDebug(lcQpaInputHwButton) << "Unknown hardware button";
continue;
}
@@ -170,7 +168,7 @@ bool QQnxButtonEventNotifier::parsePPS(const QByteArray &ppsData, QHash<QByteArr
// tokenize current attribute
const QByteArray &attr = lines.at(i);
- qButtonDebug() << "attr=" << attr;
+ qCDebug(lcQpaInputHwButton) << Q_FUNC_INFO << "attr =" << attr;
int doubleColon = attr.indexOf(QByteArrayLiteral("::"));
if (doubleColon == -1) {
diff --git a/src/plugins/platforms/qnx/qqnxbuttoneventnotifier.h b/src/plugins/platforms/qnx/qqnxbuttoneventnotifier.h
index 81ccf64415..476119ae27 100644
--- a/src/plugins/platforms/qnx/qqnxbuttoneventnotifier.h
+++ b/src/plugins/platforms/qnx/qqnxbuttoneventnotifier.h
@@ -5,9 +5,12 @@
#define QQNXBUTTONSEVENTNOTIFIER_H
#include <QObject>
+#include <QtCore/QLoggingCategory>
QT_BEGIN_NAMESPACE
+Q_DECLARE_LOGGING_CATEGORY(lcQpaInputHwButton);
+
class QSocketNotifier;
class QQnxButtonEventNotifier : public QObject
diff --git a/src/plugins/platforms/qnx/qqnxclipboard.cpp b/src/plugins/platforms/qnx/qqnxclipboard.cpp
index 8e42148c12..3f27ec8069 100644
--- a/src/plugins/platforms/qnx/qqnxclipboard.cpp
+++ b/src/plugins/platforms/qnx/qqnxclipboard.cpp
@@ -17,14 +17,10 @@
#include <clipboard/clipboard.h>
#include <errno.h>
-#if defined(QQNXCLIPBOARD_DEBUG)
-#define qClipboardDebug qDebug
-#else
-#define qClipboardDebug QT_NO_QDEBUG_MACRO
-#endif
-
QT_BEGIN_NAMESPACE
+Q_LOGGING_CATEGORY(lcQpaClipboard, "qt.qpa.clipboard");
+
// null terminated array
static const char *typeList[] = {"text/html", "text/plain", "image/png", "image/jpeg", "application/x-color", 0};
@@ -66,13 +62,13 @@ public:
void addFormatToCheck(const QString &format) {
m_formatsToCheck << format;
- qClipboardDebug() << "formats=" << m_formatsToCheck;
+ qCDebug(lcQpaClipboard) << "formats=" << m_formatsToCheck;
}
bool hasFormat(const QString &mimetype) const override
{
const bool result = is_clipboard_format_present(mimetype.toUtf8().constData()) == 0;
- qClipboardDebug() << "mimetype=" << mimetype << "result=" << result;
+ qCDebug(lcQpaClipboard) << "mimetype=" << mimetype << "result=" << result;
return result;
}
@@ -85,7 +81,7 @@ public:
result << format;
}
- qClipboardDebug() << "result=" << result;
+ qCDebug(lcQpaClipboard) << "result=" << result;
return result;
}
@@ -109,7 +105,7 @@ public:
protected:
QVariant retrieveData(const QString &mimetype, QMetaType preferredType) const override
{
- qClipboardDebug() << "mimetype=" << mimetype << "preferredType=" << preferredType.name();
+ qCDebug(lcQpaClipboard) << "mimetype=" << mimetype << "preferredType=" << preferredType.name();
if (is_clipboard_format_present(mimetype.toUtf8().constData()) != 0)
return QMimeData::retrieveData(mimetype, preferredType);
@@ -121,7 +117,7 @@ private Q_SLOTS:
void releaseOwnership()
{
if (m_userMimeData) {
- qClipboardDebug() << "user data formats=" << m_userMimeData->formats() << "system formats=" << formats();
+ qCDebug(lcQpaClipboard) << "user data formats=" << m_userMimeData->formats() << "system formats=" << formats();
delete m_userMimeData;
m_userMimeData = 0;
m_clipboard->emitChanged(QClipboard::Clipboard);
@@ -167,7 +163,7 @@ void QQnxClipboard::setMimeData(QMimeData *data, QClipboard::Mode mode)
}
const QStringList formats = data->formats();
- qClipboardDebug() << "formats=" << formats;
+ qCDebug(lcQpaClipboard) << "formats=" << formats;
Q_FOREACH (const QString &format, formats) {
const QByteArray buf = data->data(format);
@@ -176,7 +172,7 @@ void QQnxClipboard::setMimeData(QMimeData *data, QClipboard::Mode mode)
continue;
int ret = set_clipboard_data(format.toUtf8().data(), buf.size(), buf.data());
- qClipboardDebug() << "set " << format << "to clipboard, size=" << buf.size() << ";ret=" << ret;
+ qCDebug(lcQpaClipboard) << "set " << format << "to clipboard, size=" << buf.size() << ";ret=" << ret;
if (ret)
m_mimeData->addFormatToCheck(format);
}
diff --git a/src/plugins/platforms/qnx/qqnxclipboard.h b/src/plugins/platforms/qnx/qqnxclipboard.h
index adc70b158a..66f862f0dc 100644
--- a/src/plugins/platforms/qnx/qqnxclipboard.h
+++ b/src/plugins/platforms/qnx/qqnxclipboard.h
@@ -11,6 +11,8 @@
QT_BEGIN_NAMESPACE
+Q_DECLARE_LOGGING_CATEGORY(lcQpaClipboard);
+
class QQnxClipboard : public QPlatformClipboard
{
public:
diff --git a/src/plugins/platforms/qnx/qqnxcursor.cpp b/src/plugins/platforms/qnx/qqnxcursor.cpp
index 03c4e16401..7c55dd79b3 100644
--- a/src/plugins/platforms/qnx/qqnxcursor.cpp
+++ b/src/plugins/platforms/qnx/qqnxcursor.cpp
@@ -5,14 +5,10 @@
#include <QtCore/QDebug>
-#if defined(QQNXCURSOR_DEBUG)
-#define qCursorDebug qDebug
-#else
-#define qCursorDebug QT_NO_QDEBUG_MACRO
-#endif
-
QT_BEGIN_NAMESPACE
+Q_LOGGING_CATEGORY(lcQpaQnx, "qt.qpa.qnx");
+
QQnxCursor::QQnxCursor()
{
}
@@ -27,13 +23,13 @@ void QQnxCursor::changeCursor(QCursor *windowCursor, QWindow *window)
void QQnxCursor::setPos(const QPoint &pos)
{
- qCursorDebug() << "QQnxCursor::setPos -" << pos;
+ qCDebug(lcQpaQnx) << "QQnxCursor::setPos -" << pos;
m_pos = pos;
}
QPoint QQnxCursor::pos() const
{
- qCursorDebug() << "QQnxCursor::pos -" << m_pos;
+ qCDebug(lcQpaQnx) << "QQnxCursor::pos -" << m_pos;
return m_pos;
}
diff --git a/src/plugins/platforms/qnx/qqnxcursor.h b/src/plugins/platforms/qnx/qqnxcursor.h
index 6592e0a5ee..707bdbaaa2 100644
--- a/src/plugins/platforms/qnx/qqnxcursor.h
+++ b/src/plugins/platforms/qnx/qqnxcursor.h
@@ -5,9 +5,12 @@
#define QQNXCURSOR_H
#include <qpa/qplatformcursor.h>
+#include <QtCore/QLoggingCategory>
QT_BEGIN_NAMESPACE
+// Q_DECLARE_LOGGING_CATEGORY(lcQpaQnx);
+
class QQnxCursor : public QPlatformCursor
{
public:
diff --git a/src/plugins/platforms/qnx/qqnxeglwindow.cpp b/src/plugins/platforms/qnx/qqnxeglwindow.cpp
index ed53308216..854ad46c3d 100644
--- a/src/plugins/platforms/qnx/qqnxeglwindow.cpp
+++ b/src/plugins/platforms/qnx/qqnxeglwindow.cpp
@@ -10,14 +10,10 @@
#include <errno.h>
-#if defined(QQNXEGLWINDOW_DEBUG)
-#define qEglWindowDebug qDebug
-#else
-#define qEglWindowDebug QT_NO_QDEBUG_MACRO
-#endif
-
QT_BEGIN_NAMESPACE
+Q_LOGGING_CATEGORY(lcQpaWindowEgl, "qt.qpa.window.egl");
+
QQnxEglWindow::QQnxEglWindow(QWindow *window, screen_context_t context, bool needRootWindow) :
QQnxWindow(window, context, needRootWindow),
m_newSurfaceRequested(true),
@@ -96,8 +92,8 @@ void QQnxEglWindow::createEGLSurface(QQnxGLContext *context)
EGL_NONE
};
- qEglWindowDebug() << "Creating EGL surface from" << this << context
- << window()->surfaceType() << window()->type();
+ qCDebug(lcQpaWindowEgl) << "Creating EGL surface from" << this << context
+ << window()->surfaceType() << window()->type();
// Create EGL surface
EGLSurface eglSurface = eglCreateWindowSurface(
diff --git a/src/plugins/platforms/qnx/qqnxeglwindow.h b/src/plugins/platforms/qnx/qqnxeglwindow.h
index 909a901d3c..548d9be1ee 100644
--- a/src/plugins/platforms/qnx/qqnxeglwindow.h
+++ b/src/plugins/platforms/qnx/qqnxeglwindow.h
@@ -6,9 +6,12 @@
#include "qqnxwindow.h"
#include <QtCore/QMutex>
+#include <QtCore/QLoggingCategory>
QT_BEGIN_NAMESPACE
+Q_DECLARE_LOGGING_CATEGORY(lcQpaWindowEgl);
+
class QQnxGLContext;
class QQnxEglWindow : public QQnxWindow
diff --git a/src/plugins/platforms/qnx/qqnxglcontext.cpp b/src/plugins/platforms/qnx/qqnxglcontext.cpp
index 7b5b11b2e4..3d8fecf88b 100644
--- a/src/plugins/platforms/qnx/qqnxglcontext.cpp
+++ b/src/plugins/platforms/qnx/qqnxglcontext.cpp
@@ -14,14 +14,10 @@
#include <dlfcn.h>
-#if defined(QQNXGLCONTEXT_DEBUG)
-#define qGLContextDebug qDebug
-#else
-#define qGLContextDebug QT_NO_QDEBUG_MACRO
-#endif
-
QT_BEGIN_NAMESPACE
+Q_LOGGING_CATEGORY(lcQpaGLContext, "qt.qpa.glcontext");
+
static QEGLPlatformContext::Flags makeFlags()
{
QEGLPlatformContext::Flags result = {};
@@ -51,13 +47,13 @@ EGLSurface QQnxGLContext::eglSurfaceForPlatformSurface(QPlatformSurface *surface
bool QQnxGLContext::makeCurrent(QPlatformSurface *surface)
{
- qGLContextDebug();
+ qCDebug(lcQpaGLContext) << Q_FUNC_INFO;
return QEGLPlatformContext::makeCurrent(surface);
}
void QQnxGLContext::swapBuffers(QPlatformSurface *surface)
{
- qGLContextDebug();
+ qCDebug(lcQpaGLContext) << Q_FUNC_INFO;
QEGLPlatformContext::swapBuffers(surface);
diff --git a/src/plugins/platforms/qnx/qqnxglobal.cpp b/src/plugins/platforms/qnx/qqnxglobal.cpp
index 85642b44b3..9cfc328e8f 100644
--- a/src/plugins/platforms/qnx/qqnxglobal.cpp
+++ b/src/plugins/platforms/qnx/qqnxglobal.cpp
@@ -15,6 +15,8 @@ void qScreenCheckError(int rc, const char *funcInfo, const char *message, bool c
}
if (Q_UNLIKELY(rc)) {
+ qCDebug(lcQpaQnx, "%s - Screen: %s - Error: %s (%i)", funcInfo, message, strerror(errno), errno);
+
if (Q_UNLIKELY(critical))
qCritical("%s - Screen: %s - Error: %s (%i)", funcInfo, message, strerror(errno), errno);
else
diff --git a/src/plugins/platforms/qnx/qqnxinputcontext_imf.cpp b/src/plugins/platforms/qnx/qqnxinputcontext_imf.cpp
index a1063444d1..cd41ebb8c2 100644
--- a/src/plugins/platforms/qnx/qqnxinputcontext_imf.cpp
+++ b/src/plugins/platforms/qnx/qqnxinputcontext_imf.cpp
@@ -25,17 +25,7 @@
#include <process.h>
#include <sys/keycodes.h>
-#if defined(QQNXINPUTCONTEXT_IMF_EVENT_DEBUG)
-#define qInputContextIMFRequestDebug qDebug
-#else
-#define qInputContextIMFRequestDebug QT_NO_QDEBUG_MACRO
-#endif
-
-#if defined(QQNXINPUTCONTEXT_DEBUG)
-#define qInputContextDebug qDebug
-#else
-#define qInputContextDebug QT_NO_QDEBUG_MACRO
-#endif
+Q_LOGGING_CATEGORY(lcQpaInputMethods, "qt.qpa.input.methods");
static QQnxInputContext *sInputContextInstance;
static QColor sSelectedColor(0,0xb8,0,85);
@@ -161,7 +151,7 @@ static int32_t ic_begin_batch_edit(input_session_t *ic)
// See comment at beginning of namespace declaration for general information
static int32_t ic_commit_text(input_session_t *ic, spannable_string_t *text, int32_t new_cursor_position)
{
- qInputContextIMFRequestDebug();
+ qCDebug(lcQpaInputMethods) << Q_FUNC_INFO;
QQnxImfRequest event(ic, ImfCommitText);
event.ct.text = text;
@@ -176,7 +166,7 @@ static int32_t ic_commit_text(input_session_t *ic, spannable_string_t *text, int
// See comment at beginning of namespace declaration for general information
static int32_t ic_delete_surrounding_text(input_session_t *ic, int32_t left_length, int32_t right_length)
{
- qInputContextIMFRequestDebug();
+ qCDebug(lcQpaInputMethods) << Q_FUNC_INFO;
QQnxImfRequest event(ic, ImfDeleteSurroundingText);
event.dst.left_length = left_length;
@@ -200,7 +190,7 @@ static int32_t ic_end_batch_edit(input_session_t *ic)
// See comment at beginning of namespace declaration for general information
static int32_t ic_finish_composing_text(input_session_t *ic)
{
- qInputContextIMFRequestDebug();
+ qCDebug(lcQpaInputMethods) << Q_FUNC_INFO;
QQnxImfRequest event(ic, ImfFinishComposingText);
event.fct.result = -1;
@@ -213,7 +203,7 @@ static int32_t ic_finish_composing_text(input_session_t *ic)
// See comment at beginning of namespace declaration for general information
static int32_t ic_get_cursor_position(input_session_t *ic)
{
- qInputContextIMFRequestDebug();
+ qCDebug(lcQpaInputMethods) << Q_FUNC_INFO;
QQnxImfRequest event(ic, ImfGetCursorPosition);
event.gcp.result = -1;
@@ -226,7 +216,7 @@ static int32_t ic_get_cursor_position(input_session_t *ic)
// See comment at beginning of namespace declaration for general information
static spannable_string_t *ic_get_text_after_cursor(input_session_t *ic, int32_t n, int32_t flags)
{
- qInputContextIMFRequestDebug();
+ qCDebug(lcQpaInputMethods) << Q_FUNC_INFO;
QQnxImfRequest event(ic, ImfGetTextAfterCursor);
event.gtac.n = n;
@@ -241,7 +231,7 @@ static spannable_string_t *ic_get_text_after_cursor(input_session_t *ic, int32_t
// See comment at beginning of namespace declaration for general information
static spannable_string_t *ic_get_text_before_cursor(input_session_t *ic, int32_t n, int32_t flags)
{
- qInputContextIMFRequestDebug();
+ qCDebug(lcQpaInputMethods) << Q_FUNC_INFO;
QQnxImfRequest event(ic, ImfGetTextBeforeCursor);
event.gtac.n = n;
@@ -256,7 +246,7 @@ static spannable_string_t *ic_get_text_before_cursor(input_session_t *ic, int32_
// See comment at beginning of namespace declaration for general information
static int32_t ic_send_event(input_session_t *ic, event_t *event)
{
- qInputContextIMFRequestDebug();
+ qCDebug(lcQpaInputMethods) << Q_FUNC_INFO;
QQnxImfRequest imfEvent(ic, ImfSendEvent);
imfEvent.sae.event = event;
@@ -270,7 +260,7 @@ static int32_t ic_send_event(input_session_t *ic, event_t *event)
// See comment at beginning of namespace declaration for general information
static int32_t ic_send_async_event(input_session_t *ic, event_t *event)
{
- qInputContextIMFRequestDebug();
+ qCDebug(lcQpaInputMethods) << Q_FUNC_INFO;
// There's no difference from our point of view between ic_send_event & ic_send_async_event
QQnxImfRequest imfEvent(ic, ImfSendEvent);
@@ -285,7 +275,7 @@ static int32_t ic_send_async_event(input_session_t *ic, event_t *event)
// See comment at beginning of namespace declaration for general information
static int32_t ic_set_composing_region(input_session_t *ic, int32_t start, int32_t end)
{
- qInputContextIMFRequestDebug();
+ qCDebug(lcQpaInputMethods) << Q_FUNC_INFO;
QQnxImfRequest event(ic, ImfSetComposingRegion);
event.scr.start = start;
@@ -301,7 +291,7 @@ static int32_t ic_set_composing_region(input_session_t *ic, int32_t start, int32
// See comment at beginning of namespace declaration for general information
static int32_t ic_set_composing_text(input_session_t *ic, spannable_string_t *text, int32_t new_cursor_position)
{
- qInputContextIMFRequestDebug();
+ qCDebug(lcQpaInputMethods) << Q_FUNC_INFO;
QQnxImfRequest event(ic, ImfSetComposingText);
event.sct.text = text;
@@ -316,7 +306,7 @@ static int32_t ic_set_composing_text(input_session_t *ic, spannable_string_t *te
// See comment at beginning of namespace declaration for general information
static int32_t ic_is_text_selected(input_session_t* ic, int32_t* pIsSelected)
{
- qInputContextIMFRequestDebug();
+ qCDebug(lcQpaInputMethods) << Q_FUNC_INFO;
QQnxImfRequest event(ic, ImfIsTextSelected);
event.its.pIsSelected = pIsSelected;
@@ -330,7 +320,7 @@ static int32_t ic_is_text_selected(input_session_t* ic, int32_t* pIsSelected)
// See comment at beginning of namespace declaration for general information
static int32_t ic_is_all_text_selected(input_session_t* ic, int32_t* pIsSelected)
{
- qInputContextIMFRequestDebug();
+ qCDebug(lcQpaInputMethods) << Q_FUNC_INFO;
QQnxImfRequest event(ic, ImfIsAllTextSelected);
event.its.pIsSelected = pIsSelected;
@@ -466,7 +456,7 @@ initEvent(event_t *pEvent, const input_session_t *pSession, EventType eventType,
static spannable_string_t *toSpannableString(const QString &text)
{
- qInputContextDebug() << text;
+ qCDebug(lcQpaInputMethods) << Q_FUNC_INFO << "Text:" << text;
spannable_string_t *pString = static_cast<spannable_string_t *>(malloc(sizeof(spannable_string_t)));
pString->str = static_cast<wchar_t *>(malloc(sizeof(wchar_t) * text.length() + 1));
@@ -540,7 +530,7 @@ QQnxInputContext::QQnxInputContext(QQnxIntegration *integration, QQnxAbstractVir
m_integration(integration),
m_virtualKeyboard(keyboard)
{
- qInputContextDebug();
+ qCDebug(lcQpaInputMethods) << Q_FUNC_INFO;
if (!imfAvailable())
return;
@@ -563,7 +553,7 @@ QQnxInputContext::QQnxInputContext(QQnxIntegration *integration, QQnxAbstractVir
QQnxInputContext::~QQnxInputContext()
{
- qInputContextDebug();
+ qCDebug(lcQpaInputMethods) << Q_FUNC_INFO;
Q_ASSERT(sInputContextInstance == this);
sInputContextInstance = nullptr;
@@ -638,7 +628,7 @@ void QQnxInputContext::processImfEvent(QQnxImfRequest *imfEvent)
bool QQnxInputContext::filterEvent( const QEvent *event )
{
- qInputContextDebug() << event;
+ qCDebug(lcQpaInputMethods) << Q_FUNC_INFO << event;
switch (event->type()) {
case QEvent::CloseSoftwareInputPanel:
@@ -661,19 +651,19 @@ QRectF QQnxInputContext::keyboardRect() const
void QQnxInputContext::reset()
{
- qInputContextDebug();
+ qCDebug(lcQpaInputMethods) << Q_FUNC_INFO;
endComposition();
}
void QQnxInputContext::commit()
{
- qInputContextDebug();
+ qCDebug(lcQpaInputMethods) << Q_FUNC_INFO;
endComposition();
}
void QQnxInputContext::update(Qt::InputMethodQueries queries)
{
- qInputContextDebug() << queries;
+ qCDebug(lcQpaInputMethods) << Q_FUNC_INFO << "Queries:" << queries;
if (queries & Qt::ImCursorPosition) {
int lastCaret = m_caretPosition;
@@ -685,7 +675,8 @@ void QQnxInputContext::update(Qt::InputMethodQueries queries)
initEvent(&caretEvent.event, sInputSession, EVENT_CARET, CARET_POS_CHANGED, sizeof(caretEvent));
caretEvent.old_pos = lastCaret;
caretEvent.new_pos = m_caretPosition;
- qInputContextDebug("ictrl_dispatch_event caret changed %d %d", lastCaret, m_caretPosition);
+ qCDebug(lcQpaInputMethods, "ictrl_dispatch_event caret changed %d %d", lastCaret, m_caretPosition);
+
p_ictrl_dispatch_event(&caretEvent.event);
}
}
@@ -693,7 +684,7 @@ void QQnxInputContext::update(Qt::InputMethodQueries queries)
void QQnxInputContext::closeSession()
{
- qInputContextDebug();
+ qCDebug(lcQpaInputMethods) << Q_FUNC_INFO;
if (!imfAvailable())
return;
@@ -715,7 +706,7 @@ bool QQnxInputContext::openSession()
closeSession();
sInputSession = p_ictrl_open_session(&ic_funcs);
- qInputContextDebug();
+ qCDebug(lcQpaInputMethods) << Q_FUNC_INFO;
return sInputSession != 0;
}
@@ -739,7 +730,7 @@ bool QQnxInputContext::hasSelectedText()
bool QQnxInputContext::dispatchRequestSoftwareInputPanel()
{
- qInputContextDebug() << "requesting keyboard" << m_inputPanelVisible;
+ qCDebug(lcQpaInputMethods) << "Requesting keyboard" << m_inputPanelVisible;
m_virtualKeyboard.showKeyboard();
return true;
@@ -747,7 +738,7 @@ bool QQnxInputContext::dispatchRequestSoftwareInputPanel()
bool QQnxInputContext::dispatchCloseSoftwareInputPanel()
{
- qInputContextDebug() << "hiding keyboard" << m_inputPanelVisible;
+ qCDebug(lcQpaInputMethods) << "Hiding keyboard" << m_inputPanelVisible;
m_virtualKeyboard.hideKeyboard();
return true;
@@ -793,7 +784,7 @@ bool QQnxInputContext::dispatchFocusGainEvent(int inputHints)
focusEvent.style |= IMF_EMAIL_TYPE;
}
- qInputContextDebug() << "ictrl_dispatch_event focus gain style:" << focusEvent.style;
+ qCDebug(lcQpaInputMethods) << "ictrl_dispatch_event focus gain style:" << focusEvent.style;
p_ictrl_dispatch_event((event_t *)&focusEvent);
@@ -803,7 +794,7 @@ bool QQnxInputContext::dispatchFocusGainEvent(int inputHints)
void QQnxInputContext::dispatchFocusLossEvent()
{
if (hasSession()) {
- qInputContextDebug("ictrl_dispatch_event focus lost");
+ qCDebug(lcQpaInputMethods) << "ictrl_dispatch_event focus lost";
focus_event_t focusEvent;
initEvent(&focusEvent.event, sInputSession, EVENT_FOCUS, FOCUS_LOST, sizeof(focusEvent));
@@ -878,7 +869,7 @@ bool QQnxInputContext::handleKeyboardEvent(int flags, int sym, int mod, int scan
navigation_event_t navEvent;
initEvent(&navEvent.event, sInputSession, EVENT_NAVIGATION, key, sizeof(navEvent));
navEvent.magnitude = 1;
- qInputContextDebug("ictrl_dispatch_even navigation %d", key);
+ qCDebug(lcQpaInputMethods, "ictrl_dispatch_even navigation %d", key);
p_ictrl_dispatch_event(&navEvent.event);
}
} else {
@@ -891,7 +882,8 @@ bool QQnxInputContext::handleKeyboardEvent(int flags, int sym, int mod, int scan
keyEvent.sequence_id = sequenceId;
p_ictrl_dispatch_event(&keyEvent.event);
- qInputContextDebug("ictrl_dispatch_even key %d", key);
+ qCDebug(lcQpaInputMethods, "ictrl_dispatch_even key %d", key);
+
}
return true;
@@ -907,7 +899,7 @@ void QQnxInputContext::updateCursorPosition()
QCoreApplication::sendEvent(input, &query);
m_caretPosition = query.value(Qt::ImCursorPosition).toInt();
- qInputContextDebug("%d", m_caretPosition);
+ qCDebug(lcQpaInputMethods, "ictrl_dispatch_even key %d", key);
}
void QQnxInputContext::endComposition()
@@ -920,7 +912,7 @@ void QQnxInputContext::endComposition()
if (hasSession()) {
action_event_t actionEvent;
initEvent(&actionEvent.event, sInputSession, EVENT_ACTION, ACTION_END_COMPOSITION, sizeof(actionEvent));
- qInputContextDebug("ictrl_dispatch_even end composition");
+ qCDebug(lcQpaInputMethods, "ictrl_dispatch_even end composition");
p_ictrl_dispatch_event(&actionEvent.event);
}
}
@@ -937,7 +929,7 @@ void QQnxInputContext::updateComposition(spannable_string_t *text, int32_t new_c
m_composingText = QString::fromWCharArray(text->str, text->length);
m_isComposing = true;
- qInputContextDebug() << m_composingText << new_cursor_position;
+ qCDebug(lcQpaInputMethods) << "Text =" << m_composingText << "Cursor position =" << new_cursor_position;
QList<QInputMethodEvent::Attribute> attributes;
attributes.append(QInputMethodEvent::Attribute(QInputMethodEvent::Cursor,
@@ -967,7 +959,7 @@ void QQnxInputContext::updateComposition(spannable_string_t *text, int32_t new_c
format.setFontUnderline(true);
if (highlightColor.isValid())
format.setBackground(QBrush(highlightColor));
- qInputContextDebug() << " attrib: " << underline << highlightColor << text->spans[i].start << text->spans[i].end;
+ qCDebug(lcQpaInputMethods) << "attrib: " << underline << highlightColor << text->spans[i].start << text->spans[i].end;
attributes.append(QInputMethodEvent::Attribute(QInputMethodEvent::TextFormat, text->spans[i].start,
text->spans[i].end - text->spans[i].start + 1, QVariant(format)));
@@ -986,7 +978,7 @@ void QQnxInputContext::finishComposingText()
QObject *input = qGuiApp->focusObject();
if (input) {
- qInputContextDebug() << m_composingText;
+ qCDebug(lcQpaInputMethods) << Q_FUNC_INFO << "Text =" << m_composingText;
QInputMethodEvent event;
event.setCommitString(m_composingText);
@@ -1051,13 +1043,13 @@ int32_t QQnxInputContext::processEvent(event_t *event)
int32_t result = -1;
switch (event->event_type) {
case EVENT_SPELL_CHECK: {
- qInputContextDebug("EVENT_SPELL_CHECK");
+ qCDebug(lcQpaInputMethods) << "EVENT_SPELL_CHECK";
result = handleSpellCheck(reinterpret_cast<spell_check_event_t *>(event));
break;
}
case EVENT_NAVIGATION: {
- qInputContextDebug("EVENT_NAVIGATION");
+ qCDebug(lcQpaInputMethods) << "EVENT_NAVIGATION";
int key = event->event_id == NAVIGATE_UP ? KEYCODE_UP :
event->event_id == NAVIGATE_DOWN ? KEYCODE_DOWN :
@@ -1080,7 +1072,7 @@ int32_t QQnxInputContext::processEvent(event_t *event)
int flags = KEY_SYM_VALID | KEY_CAP_VALID;
if (event->event_id == IMF_KEY_DOWN)
flags |= KEY_DOWN;
- qInputContextDebug("EVENT_KEY %d %d", flags, keySym);
+ qCDebug(lcQpaInputMethods, "EVENT_KEY %d %d", flags, keySym);
QQnxScreenEventHandler::injectKeyboardEvent(flags, keySym, modifiers, 0, keyCap);
result = 0;
break;
@@ -1120,7 +1112,7 @@ int32_t QQnxInputContext::onCommitText(spannable_string_t *text, int32_t new_cur
int32_t QQnxInputContext::onDeleteSurroundingText(int32_t left_length, int32_t right_length)
{
- qInputContextDebug("L: %d R: %d", int(left_length), int(right_length));
+ qCDebug(lcQpaInputMethods, "L: %d R: %d", int(left_length), int(right_length));
QObject *input = qGuiApp->focusObject();
if (!input)
@@ -1151,7 +1143,7 @@ int32_t QQnxInputContext::onFinishComposingText()
int32_t QQnxInputContext::onGetCursorPosition()
{
- qInputContextDebug();
+ qCDebug(lcQpaInputMethods) << Q_FUNC_INFO;
QObject *input = qGuiApp->focusObject();
if (!input)
@@ -1165,7 +1157,7 @@ int32_t QQnxInputContext::onGetCursorPosition()
spannable_string_t *QQnxInputContext::onGetTextAfterCursor(int32_t n, int32_t flags)
{
Q_UNUSED(flags);
- qInputContextDebug();
+ qCDebug(lcQpaInputMethods) << Q_FUNC_INFO;
QObject *input = qGuiApp->focusObject();
if (!input)
@@ -1182,7 +1174,7 @@ spannable_string_t *QQnxInputContext::onGetTextAfterCursor(int32_t n, int32_t fl
spannable_string_t *QQnxInputContext::onGetTextBeforeCursor(int32_t n, int32_t flags)
{
Q_UNUSED(flags);
- qInputContextDebug();
+ qCDebug(lcQpaInputMethods) << Q_FUNC_INFO;
QObject *input = qGuiApp->focusObject();
if (!input)
@@ -1201,7 +1193,7 @@ spannable_string_t *QQnxInputContext::onGetTextBeforeCursor(int32_t n, int32_t f
int32_t QQnxInputContext::onSendEvent(event_t *event)
{
- qInputContextDebug();
+ qCDebug(lcQpaInputMethods) << Q_FUNC_INFO;
return processEvent(event);
}
@@ -1217,7 +1209,7 @@ int32_t QQnxInputContext::onSetComposingRegion(int32_t start, int32_t end)
QString text = query.value(Qt::ImSurroundingText).toString();
m_caretPosition = query.value(Qt::ImCursorPosition).toInt();
- qInputContextDebug() << text;
+ qCDebug(lcQpaInputMethods) << Q_FUNC_INFO << "Text =" << text;
m_isUpdatingText = true;
@@ -1260,7 +1252,7 @@ int32_t QQnxInputContext::onIsTextSelected(int32_t* pIsSelected)
{
*pIsSelected = hasSelectedText();
- qInputContextDebug() << *pIsSelected;
+ qCDebug(lcQpaInputMethods) << Q_FUNC_INFO << *pIsSelected;
return 0;
}
@@ -1276,20 +1268,20 @@ int32_t QQnxInputContext::onIsAllTextSelected(int32_t* pIsSelected)
*pIsSelected = query.value(Qt::ImSurroundingText).toString().length() == query.value(Qt::ImCurrentSelection).toString().length();
- qInputContextDebug() << *pIsSelected;
+ qCDebug(lcQpaInputMethods) << Q_FUNC_INFO << *pIsSelected;
return 0;
}
void QQnxInputContext::showInputPanel()
{
- qInputContextDebug();
+ qCDebug(lcQpaInputMethods) << Q_FUNC_INFO;
dispatchRequestSoftwareInputPanel();
}
void QQnxInputContext::hideInputPanel()
{
- qInputContextDebug();
+ qCDebug(lcQpaInputMethods) << Q_FUNC_INFO;
dispatchCloseSoftwareInputPanel();
}
@@ -1305,7 +1297,7 @@ QLocale QQnxInputContext::locale() const
void QQnxInputContext::keyboardVisibilityChanged(bool visible)
{
- qInputContextDebug() << "visible=" << visible;
+ qCDebug(lcQpaInputMethods) << Q_FUNC_INFO << "visible=" << visible;
if (m_inputPanelVisible != visible) {
m_inputPanelVisible = visible;
emitInputPanelVisibleChanged();
@@ -1314,7 +1306,7 @@ void QQnxInputContext::keyboardVisibilityChanged(bool visible)
void QQnxInputContext::keyboardLocaleChanged(const QLocale &locale)
{
- qInputContextDebug() << "locale=" << locale;
+ qCDebug(lcQpaInputMethods) << Q_FUNC_INFO << "locale=" << locale;
if (m_inputPanelLocale != locale) {
m_inputPanelLocale = locale;
emitLocaleChanged();
@@ -1323,7 +1315,7 @@ void QQnxInputContext::keyboardLocaleChanged(const QLocale &locale)
void QQnxInputContext::setHighlightColor(int index, const QColor &color)
{
- qInputContextDebug() << "setHighlightColor" << index << color << qGuiApp->focusObject();
+ qCDebug(lcQpaInputMethods) << "setHighlightColor" << index << color << qGuiApp->focusObject();
if (!sInputContextInstance)
return;
@@ -1342,7 +1334,7 @@ void QQnxInputContext::setHighlightColor(int index, const QColor &color)
void QQnxInputContext::setFocusObject(QObject *object)
{
- qInputContextDebug() << "input item=" << object;
+ qCDebug(lcQpaInputMethods) << Q_FUNC_INFO << "input item=" << object;
// Ensure the colors are reset if we've a change in focus object
setHighlightColor(-1, QColor());
@@ -1372,7 +1364,7 @@ void QQnxInputContext::setFocusObject(QObject *object)
bool QQnxInputContext::checkSpelling(const QString &text, void *context, void (*spellCheckDone)(void *context, const QString &text, const QList<int> &indices))
{
- qInputContextDebug() << "text" << text;
+ qCDebug(lcQpaInputMethods) << Q_FUNC_INFO << "Text =" << text;
if (!imfAvailable())
return false;
diff --git a/src/plugins/platforms/qnx/qqnxinputcontext_noimf.cpp b/src/plugins/platforms/qnx/qqnxinputcontext_noimf.cpp
index 2a4e5b509b..7789b2830a 100644
--- a/src/plugins/platforms/qnx/qqnxinputcontext_noimf.cpp
+++ b/src/plugins/platforms/qnx/qqnxinputcontext_noimf.cpp
@@ -10,14 +10,10 @@
#include <QtGui/QGuiApplication>
#include <QtGui/QInputMethodEvent>
-#if defined(QQNXINPUTCONTEXT_DEBUG)
-#define qInputContextDebug qDebug
-#else
-#define qInputContextDebug QT_NO_QDEBUG_MACRO
-#endif
-
QT_BEGIN_NAMESPACE
+Q_LOGGING_CATEGORY(lcQpaInputMethods, "qt.qpa.input.methods");
+
QQnxInputContext::QQnxInputContext(QQnxIntegration *integration, QQnxAbstractVirtualKeyboard &keyboard) :
QPlatformInputContext(),
m_inputPanelVisible(false),
@@ -58,13 +54,13 @@ bool QQnxInputContext::filterEvent( const QEvent *event )
if (event->type() == QEvent::CloseSoftwareInputPanel) {
m_virtualKeyboard.hideKeyboard();
- qInputContextDebug("hiding virtual keyboard");
+ qCDebug(lcQpaInputMethods) << "hiding virtual keyboard";
return false;
}
if (event->type() == QEvent::RequestSoftwareInputPanel) {
m_virtualKeyboard.showKeyboard();
- qInputContextDebug("requesting virtual keyboard");
+ qCDebug(lcQpaInputMethods) << "requesting virtual keyboard";
return false;
}
@@ -91,13 +87,13 @@ bool QQnxInputContext::handleKeyboardEvent(int flags, int sym, int mod, int scan
void QQnxInputContext::showInputPanel()
{
- qInputContextDebug();
+ qCDebug(lcQpaInputMethods) << Q_FUNC_INFO;
m_virtualKeyboard.showKeyboard();
}
void QQnxInputContext::hideInputPanel()
{
- qInputContextDebug();
+ qCDebug(lcQpaInputMethods) << Q_FUNC_INFO;
m_virtualKeyboard.hideKeyboard();
}
@@ -118,7 +114,7 @@ void QQnxInputContext::keyboardHeightChanged()
void QQnxInputContext::keyboardVisibilityChanged(bool visible)
{
- qInputContextDebug() << "visible=" << visible;
+ qCDebug(lcQpaInputMethods) << "visible=" << visible;
if (m_inputPanelVisible != visible) {
m_inputPanelVisible = visible;
emitInputPanelVisibleChanged();
@@ -127,7 +123,7 @@ void QQnxInputContext::keyboardVisibilityChanged(bool visible)
void QQnxInputContext::keyboardLocaleChanged(const QLocale &locale)
{
- qInputContextDebug() << "locale=" << locale;
+ qCDebug(lcQpaInputMethods) << "locale=" << locale;
if (m_inputPanelLocale != locale) {
m_inputPanelLocale = locale;
emitLocaleChanged();
@@ -136,7 +132,7 @@ void QQnxInputContext::keyboardLocaleChanged(const QLocale &locale)
void QQnxInputContext::setFocusObject(QObject *object)
{
- qInputContextDebug() << "input item=" << object;
+ qCDebug(lcQpaInputMethods) << "input item=" << object;;
if (!inputMethodAccepted()) {
if (m_inputPanelVisible)
diff --git a/src/plugins/platforms/qnx/qqnxintegration.cpp b/src/plugins/platforms/qnx/qqnxintegration.cpp
index 310d5d4c8a..b308c956f2 100644
--- a/src/plugins/platforms/qnx/qqnxintegration.cpp
+++ b/src/plugins/platforms/qnx/qqnxintegration.cpp
@@ -49,6 +49,7 @@
#include <qpa/qwindowsysteminterface.h>
#include <QtGui/private/qguiapplication_p.h>
+#include <QtGui/private/qrhibackingstore_p.h>
#if !defined(QT_NO_OPENGL)
#include "qqnxglcontext.h"
@@ -64,14 +65,10 @@
#include <QtCore/QFile>
#include <errno.h>
-#if defined(QQNXINTEGRATION_DEBUG)
-#define qIntegrationDebug qDebug
-#else
-#define qIntegrationDebug QT_NO_QDEBUG_MACRO
-#endif
-
QT_BEGIN_NAMESPACE
+// Q_LOGGING_CATEGORY(lcQpaQnx, "qt.qpa.qnx");
+
using namespace Qt::StringLiterals;
QQnxIntegration *QQnxIntegration::ms_instance;
@@ -144,7 +141,7 @@ QQnxIntegration::QQnxIntegration(const QStringList &paramList)
{
ms_instance = this;
m_options = parseOptions(paramList);
- qIntegrationDebug();
+ qCDebug(lcQpaQnx) << Q_FUNC_INFO;
// Open connection to QNX composition manager
if (screen_create_context(&m_screenContext, getContextCapabilities(paramList))) {
@@ -221,7 +218,7 @@ QQnxIntegration::QQnxIntegration(const QStringList &paramList)
QQnxIntegration::~QQnxIntegration()
{
- qIntegrationDebug("platform plugin shutdown begin");
+ qCDebug(lcQpaQnx) << "Platform plugin shutdown begin";
delete m_nativeInterface;
#if QT_CONFIG(draganddrop)
@@ -278,12 +275,12 @@ QQnxIntegration::~QQnxIntegration()
ms_instance = nullptr;
- qIntegrationDebug("platform plugin shutdown end");
+ qCDebug(lcQpaQnx) << "Platform plugin shutdown end";
}
bool QQnxIntegration::hasCapability(QPlatformIntegration::Capability cap) const
{
- qIntegrationDebug();
+ qCDebug(lcQpaQnx) << Q_FUNC_INFO;
switch (cap) {
case MultipleWindows:
case ForeignWindows:
@@ -314,7 +311,7 @@ QPlatformWindow *QQnxIntegration::createForeignWindow(QWindow *window, WId nativ
QPlatformWindow *QQnxIntegration::createPlatformWindow(QWindow *window) const
{
- qIntegrationDebug();
+ qCDebug(lcQpaQnx) << Q_FUNC_INFO;
QSurface::SurfaceType surfaceType = window->surfaceType();
const bool needRootWindow = options() & RootWindow;
switch (surfaceType) {
@@ -332,14 +329,25 @@ QPlatformWindow *QQnxIntegration::createPlatformWindow(QWindow *window) const
QPlatformBackingStore *QQnxIntegration::createPlatformBackingStore(QWindow *window) const
{
- qIntegrationDebug();
- return new QQnxRasterBackingStore(window);
+ QSurface::SurfaceType surfaceType = window->surfaceType();
+ qCDebug(lcQpaQnx) << Q_FUNC_INFO << surfaceType;
+ switch (surfaceType) {
+ case QSurface::RasterSurface:
+ return new QQnxRasterBackingStore(window);
+#if !defined(QT_NO_OPENGL)
+ // Return a QRhiBackingStore for non-raster surface windows
+ case QSurface::OpenGLSurface:
+ return new QRhiBackingStore(window);
+#endif
+ default:
+ return nullptr;
+ }
}
#if !defined(QT_NO_OPENGL)
QPlatformOpenGLContext *QQnxIntegration::createPlatformOpenGLContext(QOpenGLContext *context) const
{
- qIntegrationDebug();
+ qCDebug(lcQpaQnx) << Q_FUNC_INFO;
// Get color channel sizes from window format
QSurfaceFormat format = context->format();
@@ -398,7 +406,7 @@ QPlatformOpenGLContext *QQnxIntegration::createPlatformOpenGLContext(QOpenGLCont
#if QT_CONFIG(qqnx_pps)
QPlatformInputContext *QQnxIntegration::inputContext() const
{
- qIntegrationDebug();
+ qCDebug(lcQpaQnx) << Q_FUNC_INFO;
if (m_qpaInputContext)
return m_qpaInputContext;
return m_inputContext;
@@ -407,7 +415,7 @@ QPlatformInputContext *QQnxIntegration::inputContext() const
void QQnxIntegration::moveToScreen(QWindow *window, int screen)
{
- qIntegrationDebug() << "w =" << window << ", s =" << screen;
+ qCDebug(lcQpaQnx) << Q_FUNC_INFO << "w =" << window << ", s =" << screen;
// get platform window used by widget
QQnxWindow *platformWindow = static_cast<QQnxWindow *>(window->handle());
@@ -421,7 +429,7 @@ void QQnxIntegration::moveToScreen(QWindow *window, int screen)
QAbstractEventDispatcher *QQnxIntegration::createEventDispatcher() const
{
- qIntegrationDebug();
+ qCDebug(lcQpaQnx) << Q_FUNC_INFO;
// We transfer ownersip of the event-dispatcher to QtCoreApplication
QAbstractEventDispatcher *eventDispatcher = m_eventDispatcher;
@@ -438,7 +446,7 @@ QPlatformNativeInterface *QQnxIntegration::nativeInterface() const
#if !defined(QT_NO_CLIPBOARD)
QPlatformClipboard *QQnxIntegration::clipboard() const
{
- qIntegrationDebug();
+ qCDebug(lcQpaQnx) << Q_FUNC_INFO;
#if QT_CONFIG(qqnx_pps)
if (!m_clipboard)
@@ -457,7 +465,7 @@ QPlatformDrag *QQnxIntegration::drag() const
QVariant QQnxIntegration::styleHint(QPlatformIntegration::StyleHint hint) const
{
- qIntegrationDebug();
+ qCDebug(lcQpaQnx) << Q_FUNC_INFO;
if ((hint == ShowIsFullScreen) && (m_options & FullScreenApplication))
return true;
@@ -471,7 +479,7 @@ QPlatformServices * QQnxIntegration::services() const
QWindow *QQnxIntegration::window(screen_window_t qnxWindow) const
{
- qIntegrationDebug();
+ qCDebug(lcQpaQnx) << Q_FUNC_INFO;
QMutexLocker locker(&m_windowMapperMutex);
Q_UNUSED(locker);
return m_windowMapper.value(qnxWindow, 0);
@@ -479,7 +487,7 @@ QWindow *QQnxIntegration::window(screen_window_t qnxWindow) const
void QQnxIntegration::addWindow(screen_window_t qnxWindow, QWindow *window)
{
- qIntegrationDebug();
+ qCDebug(lcQpaQnx) << Q_FUNC_INFO;
QMutexLocker locker(&m_windowMapperMutex);
Q_UNUSED(locker);
m_windowMapper.insert(qnxWindow, window);
@@ -487,7 +495,7 @@ void QQnxIntegration::addWindow(screen_window_t qnxWindow, QWindow *window)
void QQnxIntegration::removeWindow(screen_window_t qnxWindow)
{
- qIntegrationDebug();
+ qCDebug(lcQpaQnx) << Q_FUNC_INFO;
QMutexLocker locker(&m_windowMapperMutex);
Q_UNUSED(locker);
m_windowMapper.remove(qnxWindow);
@@ -596,7 +604,7 @@ QList<screen_display_t *> QQnxIntegration::sortDisplays(screen_display_t *availa
void QQnxIntegration::createDisplays()
{
- qIntegrationDebug();
+ qCDebug(lcQpaQnx) << Q_FUNC_INFO;
// Query number of displays
int displayCount = 0;
int result = screen_get_context_property_iv(m_screenContext, SCREEN_PROPERTY_DISPLAY_COUNT,
@@ -626,11 +634,12 @@ void QQnxIntegration::createDisplays()
Q_SCREEN_CHECKERROR(result, "Failed to query display attachment");
if (!isAttached) {
- qIntegrationDebug("Skipping non-attached display %d", i);
+ qCDebug(lcQpaQnx) << "Skipping non-attached display " << i;
continue;
}
- qIntegrationDebug("Creating screen for display %d", i);
+ qCDebug(lcQpaQnx) << "Creating screen for display " << i;
+
createDisplay(*orderedDisplays[i], /*isPrimary=*/false);
} // of displays iteration
}
@@ -664,7 +673,8 @@ void QQnxIntegration::removeDisplay(QQnxScreen *screen)
void QQnxIntegration::destroyDisplays()
{
- qIntegrationDebug();
+ qCDebug(lcQpaQnx) << Q_FUNC_INFO;
+
Q_FOREACH (QQnxScreen *screen, m_screens) {
QWindowSystemInterface::handleScreenRemoved(screen);
}
@@ -715,7 +725,7 @@ bool QQnxIntegration::supportsNavigatorEvents() const
#if QT_CONFIG(opengl)
void QQnxIntegration::createEglDisplay()
{
- qIntegrationDebug();
+ qCDebug(lcQpaQnx) << Q_FUNC_INFO;
// Initialize connection to EGL
m_eglDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY);
@@ -729,7 +739,7 @@ void QQnxIntegration::createEglDisplay()
void QQnxIntegration::destroyEglDisplay()
{
- qIntegrationDebug();
+ qCDebug(lcQpaQnx) << Q_FUNC_INFO;
// Close connection to EGL
eglTerminate(m_eglDisplay);
diff --git a/src/plugins/platforms/qnx/qqnxintegration.h b/src/plugins/platforms/qnx/qqnxintegration.h
index f126300aed..8a78d54ceb 100644
--- a/src/plugins/platforms/qnx/qqnxintegration.h
+++ b/src/plugins/platforms/qnx/qqnxintegration.h
@@ -10,6 +10,7 @@
#include <QtCore/qmutex.h>
#include <screen/screen.h>
+#include <QtCore/QLoggingCategory>
#if QT_CONFIG(opengl)
#include <EGL/egl.h>
@@ -17,6 +18,9 @@
QT_BEGIN_NAMESPACE
+Q_DECLARE_LOGGING_CATEGORY(lcQpaQnx);
+Q_DECLARE_LOGGING_CATEGORY(lcQpaGLContext);
+
class QQnxScreenEventThread;
class QQnxFileDialogHelper;
class QQnxNativeInterface;
diff --git a/src/plugins/platforms/qnx/qqnxnavigatoreventhandler.cpp b/src/plugins/platforms/qnx/qqnxnavigatoreventhandler.cpp
index cee86a68a0..7580e560aa 100644
--- a/src/plugins/platforms/qnx/qqnxnavigatoreventhandler.cpp
+++ b/src/plugins/platforms/qnx/qqnxnavigatoreventhandler.cpp
@@ -10,11 +10,7 @@
#include <QGuiApplication>
#include <qpa/qwindowsysteminterface.h>
-#if defined(QQNXNAVIGATOREVENTHANDLER_DEBUG)
-#define qNavigatorEventHandlerDebug qDebug
-#else
-#define qNavigatorEventHandlerDebug QT_NO_QDEBUG_MACRO
-#endif
+Q_LOGGING_CATEGORY(lcQpaQnxNavigatorEvents, "qt.qpa.qnx.navigator.events");
QT_BEGIN_NAMESPACE
@@ -27,20 +23,20 @@ bool QQnxNavigatorEventHandler::handleOrientationCheck(int angle)
{
// reply to navigator that (any) orientation is acceptable
// TODO: check if top window flags prohibit orientation change
- qNavigatorEventHandlerDebug("angle=%d", angle);
+ qCDebug(lcQpaQnxNavigatorEvents, "angle=%d", angle);
return true;
}
void QQnxNavigatorEventHandler::handleOrientationChange(int angle)
{
// update screen geometry and reply to navigator that we're ready
- qNavigatorEventHandlerDebug("angle=%d", angle);
+ qCDebug(lcQpaQnxNavigatorEvents, "angle=%d", angle);
emit rotationChanged(angle);
}
void QQnxNavigatorEventHandler::handleSwipeDown()
{
- qNavigatorEventHandlerDebug();
+ qCDebug(lcQpaQnxNavigatorEvents) << Q_FUNC_INFO;
Q_EMIT swipeDown();
}
@@ -48,25 +44,25 @@ void QQnxNavigatorEventHandler::handleSwipeDown()
void QQnxNavigatorEventHandler::handleExit()
{
// shutdown everything
- qNavigatorEventHandlerDebug();
+ qCDebug(lcQpaQnxNavigatorEvents) << Q_FUNC_INFO;
QCoreApplication::quit();
}
void QQnxNavigatorEventHandler::handleWindowGroupActivated(const QByteArray &id)
{
- qNavigatorEventHandlerDebug() << id;
+ qCDebug(lcQpaQnxNavigatorEvents) << Q_FUNC_INFO << id;
Q_EMIT windowGroupActivated(id);
}
void QQnxNavigatorEventHandler::handleWindowGroupDeactivated(const QByteArray &id)
{
- qNavigatorEventHandlerDebug() << id;
+ qCDebug(lcQpaQnxNavigatorEvents) << Q_FUNC_INFO << id;
Q_EMIT windowGroupDeactivated(id);
}
void QQnxNavigatorEventHandler::handleWindowGroupStateChanged(const QByteArray &id, Qt::WindowState state)
{
- qNavigatorEventHandlerDebug() << id;
+ qCDebug(lcQpaQnxNavigatorEvents) << Q_FUNC_INFO << id;
Q_EMIT windowGroupStateChanged(id, state);
}
diff --git a/src/plugins/platforms/qnx/qqnxnavigatoreventhandler.h b/src/plugins/platforms/qnx/qqnxnavigatoreventhandler.h
index 342b6c3ef6..826c9a0ff9 100644
--- a/src/plugins/platforms/qnx/qqnxnavigatoreventhandler.h
+++ b/src/plugins/platforms/qnx/qqnxnavigatoreventhandler.h
@@ -5,9 +5,12 @@
#define QQNXNAVIGATOREVENTHANDLER_H
#include <QObject>
+#include <QtCore/QLoggingCategory>
QT_BEGIN_NAMESPACE
+Q_DECLARE_LOGGING_CATEGORY(lcQpaQnxNavigatorEvents);
+
class QQnxNavigatorEventHandler : public QObject
{
Q_OBJECT
diff --git a/src/plugins/platforms/qnx/qqnxnavigatoreventnotifier.cpp b/src/plugins/platforms/qnx/qqnxnavigatoreventnotifier.cpp
index 8024214e69..44c71dad52 100644
--- a/src/plugins/platforms/qnx/qqnxnavigatoreventnotifier.cpp
+++ b/src/plugins/platforms/qnx/qqnxnavigatoreventnotifier.cpp
@@ -17,14 +17,10 @@
#include <sys/types.h>
#include <sys/stat.h>
-#if defined(QQNXNAVIGATOREVENTNOTIFIER_DEBUG)
-#define qNavigatorEventNotifierDebug qDebug
-#else
-#define qNavigatorEventNotifierDebug QT_NO_QDEBUG_MACRO
-#endif
-
QT_BEGIN_NAMESPACE
+// Q_LOGGING_CATEGORY(lcQpaQnxNavigatorEvents, "qt.qpa.qnx.navigator.events");
+
const char *QQnxNavigatorEventNotifier::navigatorControlPath = "/pps/services/navigator/control";
const size_t QQnxNavigatorEventNotifier::ppsBufferSize = 4096;
@@ -44,18 +40,18 @@ QQnxNavigatorEventNotifier::~QQnxNavigatorEventNotifier()
if (m_fd != -1)
close(m_fd);
- qNavigatorEventNotifierDebug("navigator event notifier stopped");
+ qCDebug(lcQpaQnxNavigatorEvents) << "Navigator event notifier stopped";
}
void QQnxNavigatorEventNotifier::start()
{
- qNavigatorEventNotifierDebug("navigator event notifier started");
+ qCDebug(lcQpaQnxNavigatorEvents) << "Navigator event notifier started";
// open connection to navigator
errno = 0;
m_fd = open(navigatorControlPath, O_RDWR);
if (m_fd == -1) {
- qNavigatorEventNotifierDebug("failed to open navigator pps: %s", strerror(errno));
+ qCDebug(lcQpaQnxNavigatorEvents, "Failed to open navigator pps: %s", strerror(errno));
return;
}
@@ -65,7 +61,7 @@ void QQnxNavigatorEventNotifier::start()
void QQnxNavigatorEventNotifier::parsePPS(const QByteArray &ppsData, QByteArray &msg, QByteArray &dat, QByteArray &id)
{
- qNavigatorEventNotifierDebug() << "data=" << ppsData;
+ qCDebug(lcQpaQnxNavigatorEvents) << Q_FUNC_INFO << "data=" << ppsData;
// tokenize pps data into lines
QList<QByteArray> lines = ppsData.split('\n');
@@ -79,7 +75,7 @@ void QQnxNavigatorEventNotifier::parsePPS(const QByteArray &ppsData, QByteArray
// tokenize current attribute
const QByteArray &attr = lines.at(i);
- qNavigatorEventNotifierDebug() << "attr=" << attr;
+ qCDebug(lcQpaQnxNavigatorEvents) << Q_FUNC_INFO << "attr=" << attr;
int firstColon = attr.indexOf(':');
if (firstColon == -1) {
@@ -96,8 +92,7 @@ void QQnxNavigatorEventNotifier::parsePPS(const QByteArray &ppsData, QByteArray
QByteArray key = attr.left(firstColon);
QByteArray value = attr.mid(secondColon + 1);
- qNavigatorEventNotifierDebug() << "key=" << key;
- qNavigatorEventNotifierDebug() << "val=" << value;
+ qCDebug(lcQpaQnxNavigatorEvents) << Q_FUNC_INFO << "key =" << key << "value =" << value;
// save attribute value
if (key == "msg")
@@ -124,7 +119,7 @@ void QQnxNavigatorEventNotifier::replyPPS(const QByteArray &res, const QByteArra
}
ppsData += "\n";
- qNavigatorEventNotifierDebug() << "reply=" << ppsData;
+ qCDebug(lcQpaQnxNavigatorEvents) << Q_FUNC_INFO << "reply=" << ppsData;
// send pps message to navigator
errno = 0;
@@ -135,7 +130,7 @@ void QQnxNavigatorEventNotifier::replyPPS(const QByteArray &res, const QByteArra
void QQnxNavigatorEventNotifier::handleMessage(const QByteArray &msg, const QByteArray &dat, const QByteArray &id)
{
- qNavigatorEventNotifierDebug() << "msg=" << msg << ", dat=" << dat << ", id=" << id;
+ qCDebug(lcQpaQnxNavigatorEvents) << Q_FUNC_INFO << "msg=" << msg << ", dat=" << dat << ", id=" << id;
// check message type
if (msg == "orientationCheck") {
@@ -159,7 +154,7 @@ void QQnxNavigatorEventNotifier::handleMessage(const QByteArray &msg, const QByt
void QQnxNavigatorEventNotifier::readData()
{
- qNavigatorEventNotifierDebug("reading navigator data");
+ qCDebug(lcQpaQnxNavigatorEvents) << "Reading navigator data";
// allocate buffer for pps data
char buffer[ppsBufferSize];
diff --git a/src/plugins/platforms/qnx/qqnxnavigatorpps.cpp b/src/plugins/platforms/qnx/qqnxnavigatorpps.cpp
index c945f3e98a..3a2fee0afb 100644
--- a/src/plugins/platforms/qnx/qqnxnavigatorpps.cpp
+++ b/src/plugins/platforms/qnx/qqnxnavigatorpps.cpp
@@ -8,12 +8,6 @@
#include <QByteArray>
#include <private/qcore_unix_p.h>
-#if defined(QQNXNAVIGATOR_DEBUG)
-#define qNavigatorDebug qDebug
-#else
-#define qNavigatorDebug QT_NO_QDEBUG_MACRO
-#endif
-
QT_BEGIN_NAMESPACE
const char *QQnxNavigatorPps::navigatorControlPath = "/pps/services/navigator/control";
@@ -45,7 +39,7 @@ bool QQnxNavigatorPps::openPpsConnection()
return false;
}
- qNavigatorDebug("successfully connected to Navigator. fd=%d", m_fd);
+ qCDebug(lcQpaQnxNavigator) << "successfully connected to Navigator. fd=" << m_fd;
return true;
}
@@ -67,7 +61,7 @@ bool QQnxNavigatorPps::sendPpsMessage(const QByteArray &message, const QByteArra
ppsMessage += "\n";
- qNavigatorDebug() << "sending PPS message:\n" << ppsMessage;
+ qCDebug(lcQpaQnxNavigator) << "sending PPS message:\n" << ppsMessage;
// send pps message to navigator
errno = 0;
@@ -89,7 +83,7 @@ bool QQnxNavigatorPps::sendPpsMessage(const QByteArray &message, const QByteArra
// ensure data is null terminated
buffer[bytes] = '\0';
- qNavigatorDebug() << "received PPS message:\n" << buffer;
+ qCDebug(lcQpaQnxNavigator) << "received PPS message:\n" << buffer;
// process received message
QByteArray ppsData(buffer);
@@ -108,7 +102,7 @@ bool QQnxNavigatorPps::sendPpsMessage(const QByteArray &message, const QByteArra
void QQnxNavigatorPps::parsePPS(const QByteArray &ppsData, QHash<QByteArray, QByteArray> &messageFields)
{
- qNavigatorDebug() << "data=" << ppsData;
+ qCDebug(lcQpaQnxNavigator) << "data=" << ppsData;
// tokenize pps data into lines
QList<QByteArray> lines = ppsData.split('\n');
@@ -123,7 +117,7 @@ void QQnxNavigatorPps::parsePPS(const QByteArray &ppsData, QHash<QByteArray, QBy
// tokenize current attribute
const QByteArray &attr = lines.at(i);
- qNavigatorDebug() << "attr=" << attr;
+ qCDebug(lcQpaQnxNavigator) << "attr=" << attr;
int firstColon = attr.indexOf(':');
if (firstColon == -1) {
@@ -140,8 +134,7 @@ void QQnxNavigatorPps::parsePPS(const QByteArray &ppsData, QHash<QByteArray, QBy
QByteArray key = attr.left(firstColon);
QByteArray value = attr.mid(secondColon + 1);
- qNavigatorDebug() << "key=" << key;
- qNavigatorDebug() << "val=" << value;
+ qCDebug(lcQpaQnxNavigator) << "key=" << key << "value=" << value;
messageFields[key] = value;
}
}
diff --git a/src/plugins/platforms/qnx/qqnxnavigatorpps.h b/src/plugins/platforms/qnx/qqnxnavigatorpps.h
index cbe0f99621..889b9f62eb 100644
--- a/src/plugins/platforms/qnx/qqnxnavigatorpps.h
+++ b/src/plugins/platforms/qnx/qqnxnavigatorpps.h
@@ -5,9 +5,12 @@
#define QQNXNAVIGATORPPS_H
#include "qqnxabstractnavigator.h"
+#include <QtCore/QLoggingCategory>
QT_BEGIN_NAMESPACE
+Q_DECLARE_LOGGING_CATEGORY(lcQpaQnxNavigator);
+
template <typename K, typename V> class QHash;
class QQnxNavigatorPps : public QQnxAbstractNavigator
diff --git a/src/plugins/platforms/qnx/qqnxrasterbackingstore.cpp b/src/plugins/platforms/qnx/qqnxrasterbackingstore.cpp
index cf80e44f84..b94c056a79 100644
--- a/src/plugins/platforms/qnx/qqnxrasterbackingstore.cpp
+++ b/src/plugins/platforms/qnx/qqnxrasterbackingstore.cpp
@@ -10,12 +10,6 @@
#include <errno.h>
-#if defined(QQNXRASTERBACKINGSTORE_DEBUG)
-#define qRasterBackingStoreDebug qDebug
-#else
-#define qRasterBackingStoreDebug QT_NO_QDEBUG_MACRO
-#endif
-
QT_BEGIN_NAMESPACE
QQnxRasterBackingStore::QQnxRasterBackingStore(QWindow *window)
@@ -23,14 +17,14 @@ QQnxRasterBackingStore::QQnxRasterBackingStore(QWindow *window)
m_needsPosting(false),
m_scrolled(false)
{
- qRasterBackingStoreDebug() << "w =" << window;
+ qCDebug(lcQpaBackingStore) << Q_FUNC_INFO << "w =" << window;
m_window = window;
}
QQnxRasterBackingStore::~QQnxRasterBackingStore()
{
- qRasterBackingStoreDebug() << "w =" << window();
+ qCDebug(lcQpaBackingStore) << Q_FUNC_INFO << "w =" << window();
}
QPaintDevice *QQnxRasterBackingStore::paintDevice()
@@ -45,7 +39,7 @@ void QQnxRasterBackingStore::flush(QWindow *window, const QRegion &region, const
{
Q_UNUSED(offset);
- qRasterBackingStoreDebug() << "w =" << this->window();
+ qCDebug(lcQpaBackingStore) << Q_FUNC_INFO << "w =" << this->window();
// Sometimes this method is called even though there is nothing to be
// flushed (posted in "screen" parlance), for instance, after an expose
@@ -67,7 +61,7 @@ void QQnxRasterBackingStore::resize(const QSize &size, const QRegion &staticCont
{
Q_UNUSED(size);
Q_UNUSED(staticContents);
- qRasterBackingStoreDebug() << "w =" << window() << ", s =" << size;
+ qCDebug(lcQpaBackingStore) << Q_FUNC_INFO << "w =" << window() << ", s =" << size;
// NOTE: defer resizing window buffers until next paint as
// resize() can be called multiple times before a paint occurs
@@ -75,7 +69,7 @@ void QQnxRasterBackingStore::resize(const QSize &size, const QRegion &staticCont
bool QQnxRasterBackingStore::scroll(const QRegion &area, int dx, int dy)
{
- qRasterBackingStoreDebug() << "w =" << window();
+ qCDebug(lcQpaBackingStore) << Q_FUNC_INFO << "w =" << window();
m_needsPosting = true;
@@ -91,7 +85,7 @@ void QQnxRasterBackingStore::beginPaint(const QRegion &region)
{
Q_UNUSED(region);
- qRasterBackingStoreDebug() << "w =" << window();
+ qCDebug(lcQpaBackingStore) << Q_FUNC_INFO << "w =" << window();
m_needsPosting = true;
platformWindow()->adjustBufferSize();
@@ -119,7 +113,7 @@ void QQnxRasterBackingStore::beginPaint(const QRegion &region)
void QQnxRasterBackingStore::endPaint()
{
- qRasterBackingStoreDebug() << "w =" << window();
+ qCDebug(lcQpaBackingStore) << Q_FUNC_INFO << "w =" << window();
}
QQnxRasterWindow *QQnxRasterBackingStore::platformWindow() const
diff --git a/src/plugins/platforms/qnx/qqnxrasterwindow.cpp b/src/plugins/platforms/qnx/qqnxrasterwindow.cpp
index fb7a1d3fd3..303c9e7c06 100644
--- a/src/plugins/platforms/qnx/qqnxrasterwindow.cpp
+++ b/src/plugins/platforms/qnx/qqnxrasterwindow.cpp
@@ -10,12 +10,6 @@
#include <errno.h>
-#if defined(QQNXRASTERWINDOW_DEBUG)
-#define qRasterWindowDebug qDebug
-#else
-#define qRasterWindowDebug QT_NO_QDEBUG_MACRO
-#endif
-
QT_BEGIN_NAMESPACE
QQnxRasterWindow::QQnxRasterWindow(QWindow *window, screen_context_t context, bool needRootWindow) :
@@ -61,7 +55,7 @@ void QQnxRasterWindow::post(const QRegion &dirty)
// Check if render buffer exists and something was rendered
if (m_currentBufferIndex != -1 && !dirty.isEmpty()) {
- qRasterWindowDebug() << "window =" << window();
+ qCDebug(lcQpaWindow) << Q_FUNC_INFO << "window = " << window();
QQnxBuffer &currentBuffer = m_buffers[m_currentBufferIndex];
// Copy unmodified region from old render buffer to new render buffer;
@@ -94,14 +88,14 @@ void QQnxRasterWindow::post(const QRegion &dirty)
void QQnxRasterWindow::scroll(const QRegion &region, int dx, int dy, bool flush)
{
- qRasterWindowDebug() << "window =" << window();
+ qCDebug(lcQpaWindow) << Q_FUNC_INFO << "window = " << window();
blitPreviousToCurrent(region, dx, dy, flush);
m_scrolled += region;
}
QQnxBuffer &QQnxRasterWindow::renderBuffer()
{
- qRasterWindowDebug() << "window =" << window();
+ qCDebug(lcQpaWindow) << Q_FUNC_INFO << "window = " << window();
// Check if render buffer is invalid
if (m_currentBufferIndex == -1) {
@@ -162,7 +156,7 @@ void QQnxRasterWindow::resetBuffers()
void QQnxRasterWindow::blitPreviousToCurrent(const QRegion &region, int dx, int dy, bool flush)
{
- qRasterWindowDebug() << "window =" << window();
+ qCDebug(lcQpaWindow) << Q_FUNC_INFO << "window = " << window();
// Abort if previous buffer is invalid or if nothing to copy
if (m_previousBufferIndex == -1 || region.isEmpty())
diff --git a/src/plugins/platforms/qnx/qqnxscreen.cpp b/src/plugins/platforms/qnx/qqnxscreen.cpp
index 9d689da991..f2c3b3847d 100644
--- a/src/plugins/platforms/qnx/qqnxscreen.cpp
+++ b/src/plugins/platforms/qnx/qqnxscreen.cpp
@@ -15,12 +15,6 @@
#include <errno.h>
-#if defined(QQNXSCREEN_DEBUG)
-#define qScreenDebug qDebug
-#else
-#define qScreenDebug QT_NO_QDEBUG_MACRO
-#endif
-
#if defined(QQNX_PHYSICAL_SCREEN_WIDTH) && QQNX_PHYSICAL_SCREEN_WIDTH > 0 \
&& defined(QQNX_PHYSICAL_SCREEN_HEIGHT) && QQNX_PHYSICAL_SCREEN_HEIGHT > 0
#define QQNX_PHYSICAL_SCREEN_SIZE_DEFINED
@@ -34,6 +28,8 @@ static const int MAX_UNDERLAY_ZORDER = -1;
QT_BEGIN_NAMESPACE
+Q_LOGGING_CATEGORY(lcQpaScreen, "qt.qpa.screen");
+
static QSize determineScreenSize(screen_display_t display, bool primaryScreen) {
int val[2];
@@ -46,9 +42,9 @@ static QSize determineScreenSize(screen_display_t display, bool primaryScreen) {
if (val[0] > 0 && val[1] > 0)
return QSize(val[0], val[1]);
- qScreenDebug("QQnxScreen: screen_get_display_property_iv() reported an invalid "
- "physical screen size (%dx%d). Falling back to QQNX_PHYSICAL_SCREEN_SIZE "
- "environment variable.", val[0], val[1]);
+ qCDebug(lcQpaScreen, "QQnxScreen: screen_get_display_property_iv() reported an invalid "
+ "physical screen size (%dx%d). Falling back to QQNX_PHYSICAL_SCREEN_SIZE "
+ "environment variable.", val[0], val[1]);
const QString envPhySizeStr = qgetenv("QQNX_PHYSICAL_SCREEN_SIZE");
if (!envPhySizeStr.isEmpty()) {
@@ -90,7 +86,7 @@ QQnxScreen::QQnxScreen(screen_context_t screenContext, screen_display_t display,
m_coverWindow(0),
m_cursor(new QQnxCursor())
{
- qScreenDebug();
+ qCDebug(lcQpaScreen) << Q_FUNC_INFO;
// Cache initial orientation of this display
int result = screen_get_display_property_iv(m_display, SCREEN_PROPERTY_ROTATION,
&m_initialRotation);
@@ -127,7 +123,7 @@ QQnxScreen::QQnxScreen(screen_context_t screenContext, screen_display_t display,
QQnxScreen::~QQnxScreen()
{
- qScreenDebug();
+ qCDebug(lcQpaScreen) << Q_FUNC_INFO;
Q_FOREACH (QQnxWindow *childWindow, m_childWindows)
childWindow->setScreen(0);
@@ -236,7 +232,7 @@ QPixmap QQnxScreen::grabWindow(WId window, int x, int y, int width, int height)
static int defaultDepth()
{
- qScreenDebug();
+ qCDebug(lcQpaScreen) << Q_FUNC_INFO;
static int defaultDepth = 0;
if (defaultDepth == 0) {
// check if display depth was specified in environment variable;
@@ -250,7 +246,7 @@ static int defaultDepth()
QRect QQnxScreen::availableGeometry() const
{
- qScreenDebug();
+ qCDebug(lcQpaScreen) << Q_FUNC_INFO;
// available geometry = total geometry - keyboard
return QRect(m_currentGeometry.x(), m_currentGeometry.y(),
m_currentGeometry.width(), m_currentGeometry.height() - m_keyboardHeight);
@@ -270,12 +266,12 @@ qreal QQnxScreen::refreshRate() const
qWarning("QQnxScreen: Failed to query screen mode. Using default value of 60Hz");
return 60.0;
}
- qScreenDebug("screen mode:\n"
- " width = %u\n"
- " height = %u\n"
- " refresh = %u\n"
- " interlaced = %u",
- uint(displayMode.width), uint(displayMode.height), uint(displayMode.refresh), uint(displayMode.interlaced));
+ qCDebug(lcQpaScreen, "screen mode:\n"
+ " width = %u\n"
+ " height = %u\n"
+ " refresh = %u\n"
+ " interlaced = %u",
+ uint(displayMode.width), uint(displayMode.height), uint(displayMode.refresh), uint(displayMode.interlaced));
return static_cast<qreal>(displayMode.refresh);
}
@@ -309,7 +305,7 @@ Qt::ScreenOrientation QQnxScreen::orientation() const
else
orient = Qt::InvertedLandscapeOrientation;
}
- qScreenDebug() << "orientation =" << orient;
+ qCDebug(lcQpaScreen) << Q_FUNC_INFO << "Orientation =" << orient;
return orient;
}
@@ -333,7 +329,7 @@ static bool isOrthogonal(int angle1, int angle2)
void QQnxScreen::setRotation(int rotation)
{
- qScreenDebug("orientation = %d", rotation);
+ qCDebug(lcQpaScreen) << Q_FUNC_INFO << "orientation =" << rotation;
// Check if rotation changed
// We only want to rotate if we are the primary screen
if (m_currentRotation != rotation && isPrimaryScreen()) {
@@ -354,7 +350,7 @@ void QQnxScreen::setRotation(int rotation)
// Resize root window if we've rotated 90 or 270 from previous orientation
if (isOrthogonal(m_currentRotation, rotation)) {
- qScreenDebug() << "resize, size =" << m_currentGeometry.size();
+ qCDebug(lcQpaScreen) << Q_FUNC_INFO << "resize, size =" << m_currentGeometry.size();
if (rootWindow())
rootWindow()->setGeometry(QRect(QPoint(0,0), m_currentGeometry.size()));
@@ -501,7 +497,7 @@ QQnxWindow *QQnxScreen::findWindow(screen_window_t windowHandle) const
void QQnxScreen::addWindow(QQnxWindow *window)
{
- qScreenDebug() << "window =" << window;
+ qCDebug(lcQpaScreen) << Q_FUNC_INFO << "Window =" << window;
if (m_childWindows.contains(window))
return;
@@ -524,7 +520,7 @@ void QQnxScreen::addWindow(QQnxWindow *window)
void QQnxScreen::removeWindow(QQnxWindow *window)
{
- qScreenDebug() << "window =" << window;
+ qCDebug(lcQpaScreen) << Q_FUNC_INFO << "Window =" << window;
if (window != m_coverWindow) {
const int numWindowsRemoved = m_childWindows.removeAll(window);
@@ -539,7 +535,7 @@ void QQnxScreen::removeWindow(QQnxWindow *window)
void QQnxScreen::raiseWindow(QQnxWindow *window)
{
- qScreenDebug() << "window =" << window;
+ qCDebug(lcQpaScreen) << Q_FUNC_INFO << "Window =" << window;
if (window != m_coverWindow) {
removeWindow(window);
@@ -549,7 +545,7 @@ void QQnxScreen::raiseWindow(QQnxWindow *window)
void QQnxScreen::lowerWindow(QQnxWindow *window)
{
- qScreenDebug() << "window =" << window;
+ qCDebug(lcQpaScreen) << Q_FUNC_INFO << "Window =" << window;
if (window != m_coverWindow) {
removeWindow(window);
@@ -559,7 +555,7 @@ void QQnxScreen::lowerWindow(QQnxWindow *window)
void QQnxScreen::updateHierarchy()
{
- qScreenDebug();
+ qCDebug(lcQpaScreen) << Q_FUNC_INFO;
QList<QQnxWindow*>::const_iterator it;
int result;
@@ -709,7 +705,7 @@ void QQnxScreen::windowClosed(void *window)
void QQnxScreen::windowGroupStateChanged(const QByteArray &id, Qt::WindowState state)
{
- qScreenDebug();
+ qCDebug(lcQpaScreen) << Q_FUNC_INFO;
if (!rootWindow() || id != rootWindow()->groupName())
return;
@@ -724,7 +720,7 @@ void QQnxScreen::windowGroupStateChanged(const QByteArray &id, Qt::WindowState s
void QQnxScreen::activateWindowGroup(const QByteArray &id)
{
- qScreenDebug();
+ qCDebug(lcQpaScreen) << Q_FUNC_INFO;
if (!rootWindow() || id != rootWindow()->groupName())
return;
@@ -743,7 +739,7 @@ void QQnxScreen::activateWindowGroup(const QByteArray &id)
void QQnxScreen::deactivateWindowGroup(const QByteArray &id)
{
- qScreenDebug();
+ qCDebug(lcQpaScreen) << Q_FUNC_INFO;
if (!rootWindow() || id != rootWindow()->groupName())
return;
diff --git a/src/plugins/platforms/qnx/qqnxscreen.h b/src/plugins/platforms/qnx/qqnxscreen.h
index f988b42ab4..17b282bdc1 100644
--- a/src/plugins/platforms/qnx/qqnxscreen.h
+++ b/src/plugins/platforms/qnx/qqnxscreen.h
@@ -30,6 +30,10 @@ const int SCREEN_PROPERTY_SYM = SCREEN_PROPERTY_KEY_SYM;
QT_BEGIN_NAMESPACE
+Q_DECLARE_LOGGING_CATEGORY(lcQpaScreen);
+Q_DECLARE_LOGGING_CATEGORY(lcQpaScreenEvents);
+Q_DECLARE_LOGGING_CATEGORY(lcQpaScreenBuffer);
+
class QQnxWindow;
class QQnxScreen : public QObject, public QPlatformScreen
diff --git a/src/plugins/platforms/qnx/qqnxscreeneventhandler.cpp b/src/plugins/platforms/qnx/qqnxscreeneventhandler.cpp
index e93a38f62c..6d923bc3a8 100644
--- a/src/plugins/platforms/qnx/qqnxscreeneventhandler.cpp
+++ b/src/plugins/platforms/qnx/qqnxscreeneventhandler.cpp
@@ -19,11 +19,7 @@
#include <errno.h>
#include <sys/keycodes.h>
-#if defined(QQNXSCREENEVENT_DEBUG)
-#define qScreenEventDebug qDebug
-#else
-#define qScreenEventDebug QT_NO_QDEBUG_MACRO
-#endif
+Q_LOGGING_CATEGORY(lcQpaScreenEvents, "qt.qpa.screen.events");
static int qtKey(int virtualKey, QChar::Category category)
{
@@ -197,7 +193,7 @@ bool QQnxScreenEventHandler::handleEvent(screen_event_t event, int qnxType)
default:
// event ignored
- qScreenEventDebug("unknown event %d", qnxType);
+ qCDebug(lcQpaScreenEvents) << Q_FUNC_INFO << "Unknown event" << qnxType;
return false;
}
@@ -235,7 +231,7 @@ void QQnxScreenEventHandler::injectKeyboardEvent(int flags, int sym, int modifie
QWindowSystemInterface::handleExtendedKeyEvent(QGuiApplication::focusWindow(), type, key, qtMod,
scan, virtualKey, modifiers, keyStr, flags & KEY_REPEAT);
- qScreenEventDebug() << "Qt key t=" << type << ", k=" << key << ", s=" << keyStr;
+ qCDebug(lcQpaScreenEvents) << "Qt key t=" << type << ", k=" << key << ", s=" << keyStr;
}
void QQnxScreenEventHandler::setScreenEventThread(QQnxScreenEventThread *eventThread)
@@ -364,12 +360,12 @@ void QQnxScreenEventHandler::handlePointerEvent(screen_event_t event)
if (wOld) {
QWindowSystemInterface::handleLeaveEvent(wOld);
- qScreenEventDebug() << "Qt leave, w=" << wOld;
+ qCDebug(lcQpaScreenEvents) << "Qt leave, w=" << wOld;
}
if (w) {
QWindowSystemInterface::handleEnterEvent(w);
- qScreenEventDebug() << "Qt enter, w=" << w;
+ qCDebug(lcQpaScreenEvents) << "Qt enter, w=" << w;
}
}
@@ -412,8 +408,8 @@ void QQnxScreenEventHandler::handlePointerEvent(screen_event_t event)
QWindowSystemInterface::handleMouseEvent(w, timestamp, m_mouseDevice, localPoint,
globalPoint, buttons, Qt::NoButton,
QEvent::MouseMove);
- qScreenEventDebug() << "Qt mouse move, w=" << w << ", (" << localPoint.x() << ","
- << localPoint.y() << "), b=" << static_cast<int>(buttons);
+ qCDebug(lcQpaScreenEvents) << "Qt mouse move, w=" << w << ", (" << localPoint.x() << ","
+ << localPoint.y() << "), b=" << static_cast<int>(buttons);
}
if (m_lastButtonState != buttons) {
@@ -428,8 +424,8 @@ void QQnxScreenEventHandler::handlePointerEvent(screen_event_t event)
QWindowSystemInterface::handleMouseEvent(w, timestamp, m_mouseDevice,
localPoint, globalPoint, buttons,
button, QEvent::MouseButtonRelease);
- qScreenEventDebug() << "Qt mouse release, w=" << w << ", (" << localPoint.x()
- << "," << localPoint.y() << "), b=" << button;
+ qCDebug(lcQpaScreenEvents) << "Qt mouse release, w=" << w << ", (" << localPoint.x()
+ << "," << localPoint.y() << "), b=" << button;
}
}
@@ -443,8 +439,8 @@ void QQnxScreenEventHandler::handlePointerEvent(screen_event_t event)
QWindowSystemInterface::handleMouseEvent(w, timestamp, m_mouseDevice,
localPoint, globalPoint, buttons,
button, QEvent::MouseButtonPress);
- qScreenEventDebug() << "Qt mouse press, w=" << w << ", (" << localPoint.x()
- << "," << localPoint.y() << "), b=" << button;
+ qCDebug(lcQpaScreenEvents) << "Qt mouse press, w=" << w << ", (" << localPoint.x()
+ << "," << localPoint.y() << "), b=" << button;
}
}
}
@@ -455,7 +451,7 @@ void QQnxScreenEventHandler::handlePointerEvent(screen_event_t event)
QPoint angleDelta(0, wheelDelta);
QWindowSystemInterface::handleWheelEvent(w, timestamp, m_mouseDevice, localPoint,
globalPoint, QPoint(), angleDelta);
- qScreenEventDebug() << "Qt wheel, w=" << w << ", (" << localPoint.x() << ","
+ qCDebug(lcQpaScreenEvents) << "Qt wheel, w=" << w << ", (" << localPoint.x() << ","
<< localPoint.y() << "), d=" << static_cast<int>(wheelDelta);
}
}
@@ -513,12 +509,12 @@ void QQnxScreenEventHandler::handleTouchEvent(screen_event_t event, int qnxType)
if (wOld) {
QWindowSystemInterface::handleLeaveEvent(wOld);
- qScreenEventDebug() << "Qt leave, w=" << wOld;
+ qCDebug(lcQpaScreenEvents) << "Qt leave, w=" << wOld;
}
if (w) {
QWindowSystemInterface::handleEnterEvent(w);
- qScreenEventDebug() << "Qt enter, w=" << w;
+ qCDebug(lcQpaScreenEvents) << "Qt enter, w=" << w;
}
}
m_lastMouseWindow = qnxWindow;
@@ -585,9 +581,9 @@ void QQnxScreenEventHandler::handleTouchEvent(screen_event_t event, int qnxType)
// inject event into Qt
QWindowSystemInterface::handleTouchEvent(w, m_touchDevice, pointList);
- qScreenEventDebug() << "Qt touch, w =" << w
- << ", p=" << m_touchPoints[touchId].area.topLeft()
- << ", t=" << type;
+ qCDebug(lcQpaScreenEvents) << "Qt touch, w =" << w
+ << ", p=" << m_touchPoints[touchId].area.topLeft()
+ << ", t=" << type;
}
}
}
@@ -631,7 +627,8 @@ void QQnxScreenEventHandler::handleDisplayEvent(screen_event_t event)
return;
}
- qScreenEventDebug() << "display attachment is now:" << isAttached;
+ qCDebug(lcQpaScreenEvents) << "display attachment is now:" << isAttached;
+
QQnxScreen *screen = m_qnxIntegration->screenForNative(nativeDisplay);
if (!screen) {
@@ -641,7 +638,7 @@ void QQnxScreenEventHandler::handleDisplayEvent(screen_event_t event)
if (val[0] == 0 && val[1] == 0) //If screen size is invalid, wait for the next event
return;
- qScreenEventDebug("creating new QQnxScreen for newly attached display");
+ qCDebug(lcQpaScreenEvents) << "Creating new QQnxScreen for newly attached display";
m_qnxIntegration->createDisplay(nativeDisplay, false /* not primary, we assume */);
}
} else if (!isAttached) {
@@ -654,7 +651,7 @@ void QQnxScreenEventHandler::handleDisplayEvent(screen_event_t event)
if (!screen->isPrimaryScreen()) {
// libscreen display is deactivated, let's remove the QQnxScreen / QScreen
- qScreenEventDebug("removing display");
+ qCDebug(lcQpaScreenEvents) << "Removing display";
m_qnxIntegration->removeDisplay(screen);
}
}
@@ -691,7 +688,7 @@ void QQnxScreenEventHandler::handlePropertyEvent(screen_event_t event)
break;
default:
// event ignored
- qScreenEventDebug() << "Ignore property event for property: " << property;
+ qCDebug(lcQpaScreenEvents) << "Ignore property event for property: " << property;
}
}
@@ -734,7 +731,7 @@ void QQnxScreenEventHandler::handleGeometryPropertyEvent(screen_window_t window)
QWindowSystemInterface::handleGeometryChange(qtWindow, rect);
}
- qScreenEventDebug() << qtWindow << "moved to" << rect;
+ qCDebug(lcQpaScreenEvents) << qtWindow << "moved to" << rect;
}
void QQnxScreenEventHandler::timerEvent(QTimerEvent *event)
diff --git a/src/plugins/platforms/qnx/qqnxscreeneventhandler.h b/src/plugins/platforms/qnx/qqnxscreeneventhandler.h
index d27186af9e..ba3579aaf7 100644
--- a/src/plugins/platforms/qnx/qqnxscreeneventhandler.h
+++ b/src/plugins/platforms/qnx/qqnxscreeneventhandler.h
@@ -5,11 +5,14 @@
#define QQNXSCREENEVENTHANDLER_H
#include <qpa/qwindowsysteminterface.h>
+#include <QtCore/QLoggingCategory>
#include <screen/screen.h>
QT_BEGIN_NAMESPACE
+Q_DECLARE_LOGGING_CATEGORY(lcQpaScreenEvents);
+
class QQnxIntegration;
class QQnxScreenEventFilter;
class QQnxScreenEventThread;
diff --git a/src/plugins/platforms/qnx/qqnxscreeneventthread.cpp b/src/plugins/platforms/qnx/qqnxscreeneventthread.cpp
index 69997e4ba0..6b4ffc3962 100644
--- a/src/plugins/platforms/qnx/qqnxscreeneventthread.cpp
+++ b/src/plugins/platforms/qnx/qqnxscreeneventthread.cpp
@@ -14,12 +14,6 @@
#include <cctype>
-#if defined(QQNXSCREENEVENTTHREAD_DEBUG)
-#define qScreenEventThreadDebug qDebug
-#else
-#define qScreenEventThreadDebug QT_NO_QDEBUG_MACRO
-#endif
-
static const int c_screenCode = _PULSE_CODE_MINAVAIL + 0;
static const int c_armCode = _PULSE_CODE_MINAVAIL + 1;
static const int c_quitCode = _PULSE_CODE_MINAVAIL + 2;
@@ -74,7 +68,7 @@ QQnxScreenEventThread::~QQnxScreenEventThread()
void QQnxScreenEventThread::run()
{
- qScreenEventThreadDebug("screen event thread started");
+ qCDebug(lcQpaScreenEvents) << "Screen event thread started";
while (1) {
struct _pulse msg;
@@ -90,7 +84,7 @@ void QQnxScreenEventThread::run()
qWarning() << "MsgReceive error" << strerror(errno);
}
- qScreenEventThreadDebug("screen event thread stopped");
+ qCDebug(lcQpaScreenEvents) << "Screen event thread stopped";
}
void QQnxScreenEventThread::armEventsPending(int count)
@@ -134,10 +128,10 @@ void QQnxScreenEventThread::shutdown()
{
MsgSendPulse(m_connectionId, SIGEV_PULSE_PRIO_INHERIT, c_quitCode, 0);
- qScreenEventThreadDebug("screen event thread shutdown begin");
+ qCDebug(lcQpaScreenEvents) << "Screen event thread shutdown begin";
// block until thread terminates
wait();
- qScreenEventThreadDebug("screen event thread shutdown end");
+ qCDebug(lcQpaScreenEvents) << "Screen event thread shutdown end";
}
diff --git a/src/plugins/platforms/qnx/qqnxvirtualkeyboardpps.cpp b/src/plugins/platforms/qnx/qqnxvirtualkeyboardpps.cpp
index b4650de315..5eceacef95 100644
--- a/src/plugins/platforms/qnx/qqnxvirtualkeyboardpps.cpp
+++ b/src/plugins/platforms/qnx/qqnxvirtualkeyboardpps.cpp
@@ -18,14 +18,10 @@
#include <sys/types.h>
#include <unistd.h>
-#if defined(QQNXVIRTUALKEYBOARD_DEBUG)
-#define qVirtualKeyboardDebug qDebug
-#else
-#define qVirtualKeyboardDebug QT_NO_QDEBUG_MACRO
-#endif
-
QT_BEGIN_NAMESPACE
+Q_LOGGING_CATEGORY(lcQpaQnxVirtualKeyboard, "qt.qpa.qnx.virtualkeyboard");
+
const char *QQnxVirtualKeyboardPps::ms_PPSPath = "/pps/services/input/control";
const size_t QQnxVirtualKeyboardPps::ms_bufferSize = 2048;
@@ -45,7 +41,7 @@ QQnxVirtualKeyboardPps::~QQnxVirtualKeyboardPps()
void QQnxVirtualKeyboardPps::start()
{
- qVirtualKeyboardDebug("starting keyboard event processing");
+ qCDebug(lcQpaQnxVirtualKeyboard) << "Starting keyboard event processing";
if (!connect())
return;
}
@@ -90,8 +86,8 @@ bool QQnxVirtualKeyboardPps::connect()
m_fd = ::open(ms_PPSPath, O_RDWR);
if (m_fd == -1)
{
- qVirtualKeyboardDebug() << "Unable to open" << ms_PPSPath
- << ':' << strerror(errno);
+ qCDebug(lcQpaQnxVirtualKeyboard) << "Unable to open" << ms_PPSPath
+ << ':' << strerror(errno);
close();
return false;
}
@@ -128,7 +124,7 @@ void QQnxVirtualKeyboardPps::ppsDataReady()
{
qint64 nread = qt_safe_read(m_fd, m_buffer, ms_bufferSize - 1);
- qVirtualKeyboardDebug("keyboardMessage size: %lld", nread);
+ qCDebug(lcQpaQnxVirtualKeyboard, "keyboardMessage size: %lld", nread);
if (nread < 0){
connect(); // reconnect
return;
@@ -167,7 +163,7 @@ void QQnxVirtualKeyboardPps::ppsDataReady()
else if (strcmp(value, "info") == 0)
handleKeyboardInfoMessage();
else if (strcmp(value, "connect") == 0)
- qVirtualKeyboardDebug("Unhandled command 'connect'");
+ qCDebug(lcQpaQnxVirtualKeyboard, "Unhandled command 'connect'");
else
qCritical("QQnxVirtualKeyboard: Unexpected keyboard PPS msg value: %s", value ? value : "[null]");
} else if (pps_decoder_get_string(m_decoder, "res", &value) == PPS_DECODER_OK) {
@@ -194,12 +190,12 @@ void QQnxVirtualKeyboardPps::handleKeyboardInfoMessage()
}
setHeight(newHeight);
- qVirtualKeyboardDebug("size=%d", newHeight);
+ qCDebug(lcQpaQnxVirtualKeyboard, "size=%d", newHeight);
}
bool QQnxVirtualKeyboardPps::showKeyboard()
{
- qVirtualKeyboardDebug();
+ qCDebug(lcQpaQnxVirtualKeyboard) << Q_FUNC_INFO;
if (!prepareToSend())
return false;
@@ -221,7 +217,7 @@ bool QQnxVirtualKeyboardPps::showKeyboard()
bool QQnxVirtualKeyboardPps::hideKeyboard()
{
- qVirtualKeyboardDebug();
+ qCDebug(lcQpaQnxVirtualKeyboard) << Q_FUNC_INFO;
if (!prepareToSend())
return false;
diff --git a/src/plugins/platforms/qnx/qqnxvirtualkeyboardpps.h b/src/plugins/platforms/qnx/qqnxvirtualkeyboardpps.h
index 88af284db3..8f1d390760 100644
--- a/src/plugins/platforms/qnx/qqnxvirtualkeyboardpps.h
+++ b/src/plugins/platforms/qnx/qqnxvirtualkeyboardpps.h
@@ -5,11 +5,13 @@
#define VIRTUALKEYBOARDPPS_H
#include "qqnxabstractvirtualkeyboard.h"
+#include <QtCore/QLoggingCategory>
#include <sys/pps.h>
QT_BEGIN_NAMESPACE
+Q_DECLARE_LOGGING_CATEGORY(lcQpaQnxVirtualKeyboard);
class QSocketNotifier;
diff --git a/src/plugins/platforms/qnx/qqnxwindow.cpp b/src/plugins/platforms/qnx/qqnxwindow.cpp
index eed45227f6..3384932a8b 100644
--- a/src/plugins/platforms/qnx/qqnxwindow.cpp
+++ b/src/plugins/platforms/qnx/qqnxwindow.cpp
@@ -21,14 +21,10 @@
#include <errno.h>
-#if defined(QQNXWINDOW_DEBUG)
-#define qWindowDebug qDebug
-#else
-#define qWindowDebug QT_NO_QDEBUG_MACRO
-#endif
-
QT_BEGIN_NAMESPACE
+Q_LOGGING_CATEGORY(lcQpaWindow, "qt.qpa.window");
+
#define DECLARE_DEBUG_VAR(variable) \
static bool debug_ ## variable() \
{ static bool value = qgetenv("QNX_SCREEN_DEBUG").contains(QT_STRINGIFY(variable)); return value; }
@@ -125,7 +121,7 @@ QQnxWindow::QQnxWindow(QWindow *window, screen_context_t context, bool needRootW
m_windowState(Qt::WindowNoState),
m_firstActivateHandled(false)
{
- qWindowDebug() << "window =" << window << ", size =" << window->size();
+ qCDebug(lcQpaWindow) << "window =" << window << ", size =" << window->size();
QQnxScreen *platformScreen = static_cast<QQnxScreen *>(window->screen()->handle());
@@ -195,13 +191,13 @@ QQnxWindow::QQnxWindow(QWindow *window, screen_context_t context, bool needRootW
bool ok = false;
int pipeline = pipelineValue.toInt(&ok);
if (ok) {
- qWindowDebug() << "Set pipeline value to" << pipeline;
+ qCDebug(lcQpaWindow) << "Set pipeline value to" << pipeline;
Q_SCREEN_CHECKERROR(
screen_set_window_property_iv(m_window, SCREEN_PROPERTY_PIPELINE, &pipeline),
"Failed to set window pipeline");
} else {
- qWindowDebug() << "Invalid pipeline value:" << pipelineValue;
+ qCDebug(lcQpaWindow) << "Invalid pipeline value:" << pipelineValue;
}
}
@@ -231,7 +227,7 @@ QQnxWindow::QQnxWindow(QWindow *window, screen_context_t context, bool needRootW
if (debug > 0) {
Q_SCREEN_CHECKERROR(screen_set_window_property_iv(nativeHandle(), SCREEN_PROPERTY_DEBUG, &debug),
"Could not set SCREEN_PROPERTY_DEBUG");
- qWindowDebug() << "window SCREEN_PROPERTY_DEBUG= " << debug;
+ qCDebug(lcQpaWindow) << "window SCREEN_PROPERTY_DEBUG= " << debug;
}
}
@@ -248,7 +244,7 @@ QQnxWindow::QQnxWindow(QWindow *window, screen_context_t context, screen_window_
, m_parentGroupName(256, 0)
, m_isTopLevel(false)
{
- qWindowDebug() << "window =" << window << ", size =" << window->size();
+ qCDebug(lcQpaWindow) << "window =" << window << ", size =" << window->size();
collectWindowGroup();
@@ -269,7 +265,7 @@ QQnxWindow::QQnxWindow(QWindow *window, screen_context_t context, screen_window_
QQnxWindow::~QQnxWindow()
{
- qWindowDebug() << "window =" << window();
+ qCDebug(lcQpaWindow) << "window =" << window();
// Qt should have already deleted the children before deleting the parent.
Q_ASSERT(m_childWindows.size() == 0);
@@ -305,9 +301,9 @@ void QQnxWindow::setGeometry(const QRect &rect)
void QQnxWindow::setGeometryHelper(const QRect &rect)
{
- qWindowDebug() << "window =" << window()
- << ", (" << rect.x() << "," << rect.y()
- << "," << rect.width() << "," << rect.height() << ")";
+ qCDebug(lcQpaWindow) << "window =" << window()
+ << ", (" << rect.x() << "," << rect.y()
+ << "," << rect.width() << "," << rect.height() << ")";
// Call base class method
QPlatformWindow::setGeometry(rect);
@@ -335,7 +331,7 @@ void QQnxWindow::setGeometryHelper(const QRect &rect)
void QQnxWindow::setVisible(bool visible)
{
- qWindowDebug() << "window =" << window() << "visible =" << visible;
+ qCDebug(lcQpaWindow) << "window =" << window() << "visible =" << visible;
if (m_visible == visible || window()->type() == Qt::Desktop)
return;
@@ -374,7 +370,7 @@ void QQnxWindow::setVisible(bool visible)
void QQnxWindow::updateVisibility(bool parentVisible)
{
- qWindowDebug() << "parentVisible =" << parentVisible << "window =" << window();
+ qCDebug(lcQpaWindow) << "parentVisible =" << parentVisible << "window =" << window();
// Set window visibility
int val = (m_visible && parentVisible) ? 1 : 0;
Q_SCREEN_CHECKERROR(screen_set_window_property_iv(m_window, SCREEN_PROPERTY_VISIBLE, &val),
@@ -386,7 +382,7 @@ void QQnxWindow::updateVisibility(bool parentVisible)
void QQnxWindow::setOpacity(qreal level)
{
- qWindowDebug() << "window =" << window() << "opacity =" << level;
+ qCDebug(lcQpaWindow) << "window =" << window() << "opacity =" << level;
// Set window global alpha
int val = (int)(level * 255);
Q_SCREEN_CHECKERROR(screen_set_window_property_iv(m_window, SCREEN_PROPERTY_GLOBAL_ALPHA, &val),
@@ -397,7 +393,7 @@ void QQnxWindow::setOpacity(qreal level)
void QQnxWindow::setExposed(bool exposed)
{
- qWindowDebug() << "window =" << window() << "expose =" << exposed;
+ qCDebug(lcQpaWindow) << "window =" << window() << "expose =" << exposed;
if (m_exposed != exposed) {
m_exposed = exposed;
@@ -412,7 +408,7 @@ bool QQnxWindow::isExposed() const
void QQnxWindow::setBufferSize(const QSize &size)
{
- qWindowDebug() << "window =" << window() << "size =" << size;
+ qCDebug(lcQpaWindow) << "window =" << window() << "size =" << size;
// libscreen fails when creating empty buffers
const QSize nonEmptySize = size.isEmpty() ? QSize(1, 1) : size;
@@ -479,7 +475,7 @@ void QQnxWindow::setBufferSize(const QSize &size)
void QQnxWindow::setScreen(QQnxScreen *platformScreen)
{
- qWindowDebug() << "window =" << window() << "platformScreen =" << platformScreen;
+ qCDebug(lcQpaWindow) << "window =" << window() << "platformScreen =" << platformScreen;
if (platformScreen == 0) { // The screen has been destroyed
m_screen = 0;
@@ -493,7 +489,7 @@ void QQnxWindow::setScreen(QQnxScreen *platformScreen)
return;
if (m_screen) {
- qWindowDebug("Moving window to different screen");
+ qCDebug(lcQpaWindow) << "Moving window to different screen";
m_screen->removeWindow(this);
if ((QQnxIntegration::instance()->options() & QQnxIntegration::RootWindow)) {
@@ -524,7 +520,7 @@ void QQnxWindow::setScreen(QQnxScreen *platformScreen)
void QQnxWindow::removeFromParent()
{
- qWindowDebug() << "window =" << window();
+ qCDebug(lcQpaWindow) << Q_FUNC_INFO << "window =" << window();
// Remove from old Hierarchy position
if (m_parentWindow) {
if (Q_UNLIKELY(!m_parentWindow->m_childWindows.removeAll(this)))
@@ -538,7 +534,7 @@ void QQnxWindow::removeFromParent()
void QQnxWindow::setParent(const QPlatformWindow *window)
{
- qWindowDebug() << "window =" << this->window() << "platformWindow =" << window;
+ qCDebug(lcQpaWindow) << "window =" << this->window() << "platformWindow =" << window;
// Cast away the const, we need to modify the hierarchy.
QQnxWindow* const newParent = static_cast<QQnxWindow*>(const_cast<QPlatformWindow*>(window));
@@ -570,7 +566,7 @@ void QQnxWindow::setParent(const QPlatformWindow *window)
void QQnxWindow::raise()
{
- qWindowDebug() << "window =" << window();
+ qCDebug(lcQpaWindow) << Q_FUNC_INFO << "window =" << window();
if (m_parentWindow) {
m_parentWindow->m_childWindows.removeAll(this);
@@ -584,7 +580,7 @@ void QQnxWindow::raise()
void QQnxWindow::lower()
{
- qWindowDebug() << "window =" << window();
+ qCDebug(lcQpaWindow) << Q_FUNC_INFO << "window =" << window();
if (m_parentWindow) {
m_parentWindow->m_childWindows.removeAll(this);
@@ -698,7 +694,7 @@ void QQnxWindow::setFocus(screen_window_t newFocusWindow)
void QQnxWindow::setWindowState(Qt::WindowStates state)
{
- qWindowDebug() << "state =" << state;
+ qCDebug(lcQpaWindow) << Q_FUNC_INFO << "state =" << state;
// Prevent two calls with Qt::WindowFullScreen from changing m_unmaximizedGeometry
if (m_windowState == state)
@@ -713,7 +709,7 @@ void QQnxWindow::setWindowState(Qt::WindowStates state)
void QQnxWindow::propagateSizeHints()
{
// nothing to do; silence base class warning
- qWindowDebug("ignored");
+ // qWindowDebug("ignored");
}
QPlatformScreen *QQnxWindow::screen() const
@@ -742,7 +738,7 @@ void QQnxWindow::minimize()
void QQnxWindow::setRotation(int rotation)
{
- qWindowDebug() << "angle =" << rotation;
+ qCDebug(lcQpaWindow) << Q_FUNC_INFO << "angle =" << rotation;
Q_SCREEN_CHECKERROR(
screen_set_window_property_iv(m_window, SCREEN_PROPERTY_ROTATION, &rotation),
"Failed to set window rotation");
@@ -818,7 +814,7 @@ void QQnxWindow::joinWindowGroup(const QByteArray &groupName)
{
bool changed = false;
- qWindowDebug() << "group:" << groupName;
+ qCDebug(lcQpaWindow) << Q_FUNC_INFO << "group:" << groupName;
// screen has this annoying habit of generating a CLOSE/CREATE when the owner context of
// the parent group moves a foreign window to another group that it also owns. The
diff --git a/src/plugins/platforms/qnx/qqnxwindow.h b/src/plugins/platforms/qnx/qqnxwindow.h
index d302f22415..013ea342e4 100644
--- a/src/plugins/platforms/qnx/qqnxwindow.h
+++ b/src/plugins/platforms/qnx/qqnxwindow.h
@@ -8,6 +8,7 @@
#include "qqnxabstractcover.h"
#include <QtCore/QScopedPointer>
+#include <QtCore/QLoggingCategory>
#if !defined(QT_NO_OPENGL)
#include <EGL/egl.h>
@@ -17,6 +18,8 @@
QT_BEGIN_NAMESPACE
+Q_DECLARE_LOGGING_CATEGORY(lcQpaWindow);
+
// all surfaces double buffered
#define MAX_BUFFER_COUNT 2
diff --git a/src/plugins/platforms/vkkhrdisplay/CMakeLists.txt b/src/plugins/platforms/vkkhrdisplay/CMakeLists.txt
index 719e5c45e6..406487f1e9 100644
--- a/src/plugins/platforms/vkkhrdisplay/CMakeLists.txt
+++ b/src/plugins/platforms/vkkhrdisplay/CMakeLists.txt
@@ -6,7 +6,7 @@ qt_find_package(WrapFreetype PROVIDED_TARGETS WrapFreetype::WrapFreetype)
qt_internal_add_plugin(QVkKhrDisplayIntegrationPlugin
OUTPUT_NAME qvkkhrdisplay
PLUGIN_TYPE platforms
- DEFAULT_IF ${QT_QPA_DEFAULT_PLATFORM} MATCHES vkkhrdisplay
+ DEFAULT_IF "vkkhrdisplay" IN_LIST QT_QPA_PLATFORMS
SOURCES
main.cpp
qvkkhrdisplayintegration.cpp qvkkhrdisplayintegration.h
diff --git a/src/plugins/platforms/vnc/CMakeLists.txt b/src/plugins/platforms/vnc/CMakeLists.txt
index 25cb399bd0..34370807ae 100644
--- a/src/plugins/platforms/vnc/CMakeLists.txt
+++ b/src/plugins/platforms/vnc/CMakeLists.txt
@@ -8,7 +8,7 @@
qt_internal_add_plugin(QVncIntegrationPlugin
OUTPUT_NAME qvnc
PLUGIN_TYPE platforms
- DEFAULT_IF ${QT_QPA_DEFAULT_PLATFORM} MATCHES vnc
+ DEFAULT_IF "vnc" IN_LIST QT_QPA_PLATFORMS
SOURCES
main.cpp
qvnc.cpp qvnc_p.h
diff --git a/src/plugins/platforms/wasm/CMakeLists.txt b/src/plugins/platforms/wasm/CMakeLists.txt
index 185b921a4f..775946aaf9 100644
--- a/src/plugins/platforms/wasm/CMakeLists.txt
+++ b/src/plugins/platforms/wasm/CMakeLists.txt
@@ -7,9 +7,8 @@
qt_internal_add_plugin(QWasmIntegrationPlugin
OUTPUT_NAME qwasm
- DEFAULT_IF ${QT_QPA_DEFAULT_PLATFORM} MATCHES wasm
+ DEFAULT_IF "wasm" IN_LIST QT_QPA_PLATFORMS
PLUGIN_TYPE platforms
- STATIC
SOURCES
main.cpp
qwasmaccessibility.cpp qwasmaccessibility.h
diff --git a/src/plugins/platforms/wasm/qtloader.js b/src/plugins/platforms/wasm/qtloader.js
index bbc0ac68ab..8027dd8fa9 100644
--- a/src/plugins/platforms/wasm/qtloader.js
+++ b/src/plugins/platforms/wasm/qtloader.js
@@ -23,7 +23,8 @@
* - fontDpi: number
* Specifies font DPI for the instance
* - onLoaded: () => void
- * Called when the module has loaded.
+ * Called when the module has loaded, at the point in time where any loading placeholder
+ * should be hidden and the application window should be shown.
* - entryFunction: (emscriptenConfig: object) => Promise<EmscriptenModule>
* Qt always uses emscripten's MODULARIZE option. This is the MODULARIZE entry function.
* - module: Promise<WebAssembly.Module>
@@ -172,9 +173,14 @@ async function qtLoad(config)
config.preRun = [];
config.preRun.push(qtPreRun);
+ const originalOnRuntimeInitialized = config.onRuntimeInitialized;
+ config.onRuntimeInitialized = () => {
+ originalOnRuntimeInitialized?.();
+ config.qt.onLoaded?.();
+ }
+
const originalLocateFile = config.locateFile;
- config.locateFile = filename =>
- {
+ config.locateFile = filename => {
const originalLocatedFilename = originalLocateFile ? originalLocateFile(filename) : filename;
if (originalLocatedFilename.startsWith('libQt6'))
return `${config.qt.qtdir}/lib/${originalLocatedFilename}`;
diff --git a/src/plugins/platforms/wasm/qwasmscreen.cpp b/src/plugins/platforms/wasm/qwasmscreen.cpp
index ddf8140c48..0490b2bfe0 100644
--- a/src/plugins/platforms/wasm/qwasmscreen.cpp
+++ b/src/plugins/platforms/wasm/qwasmscreen.cpp
@@ -361,10 +361,14 @@ QList<QWasmWindow *> QWasmScreen::allWindows()
{
QList<QWasmWindow *> windows;
for (auto *child : childStack()) {
- QWindowList list = child->window()->findChildren<QWindow *>(Qt::FindChildrenRecursively);
- std::transform(
- list.begin(), list.end(), std::back_inserter(windows),
- [](const QWindow *window) { return static_cast<QWasmWindow *>(window->handle()); });
+ const QWindowList list = child->window()->findChildren<QWindow *>(Qt::FindChildrenRecursively);
+ for (auto child : list) {
+ auto handle = child->handle();
+ if (handle) {
+ auto wnd = static_cast<QWasmWindow *>(handle);
+ windows.push_back(wnd);
+ }
+ }
windows.push_back(child);
}
return windows;
diff --git a/src/plugins/platforms/wasm/wasm_shell.html b/src/plugins/platforms/wasm/wasm_shell.html
index 702ea1f59d..6e93955552 100644
--- a/src/plugins/platforms/wasm/wasm_shell.html
+++ b/src/plugins/platforms/wasm/wasm_shell.html
@@ -1,3 +1,8 @@
+<!--
+Copyright (C) 2024 The Qt Company Ltd.
+SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
+-->
+
<!doctype html>
<html lang="en-us">
<head>
diff --git a/src/plugins/platforms/windows/CMakeLists.txt b/src/plugins/platforms/windows/CMakeLists.txt
index fb73b70c29..8cd84e208b 100644
--- a/src/plugins/platforms/windows/CMakeLists.txt
+++ b/src/plugins/platforms/windows/CMakeLists.txt
@@ -8,14 +8,13 @@
qt_internal_add_plugin(QWindowsIntegrationPlugin
OUTPUT_NAME qwindows
PLUGIN_TYPE platforms
- DEFAULT_IF ${QT_QPA_DEFAULT_PLATFORM} MATCHES windows
+ DEFAULT_IF "windows" IN_LIST QT_QPA_PLATFORMS
SOURCES
main.cpp
qtwindowsglobal.h
qwin10helpers.cpp qwin10helpers.h
qwindowsapplication.cpp qwindowsapplication.h
qwindowsbackingstore.cpp qwindowsbackingstore.h
- qwindowscombase.h
qwindowscontext.cpp qwindowscontext.h
qwindowscursor.cpp qwindowscursor.h
qwindowsdialoghelpers.cpp qwindowsdialoghelpers.h
diff --git a/src/plugins/platforms/windows/qwindowsapplication.cpp b/src/plugins/platforms/windows/qwindowsapplication.cpp
index 60cbf1f7ba..42e34ac99f 100644
--- a/src/plugins/platforms/windows/qwindowsapplication.cpp
+++ b/src/plugins/platforms/windows/qwindowsapplication.cpp
@@ -72,11 +72,6 @@ bool QWindowsApplication::setWinTabEnabled(bool enabled)
return enabled ? ctx->initTablet() : ctx->disposeTablet();
}
-bool QWindowsApplication::isDarkMode() const
-{
- return QWindowsContext::isDarkMode();
-}
-
QWindowsApplication::DarkModeHandling QWindowsApplication::darkModeHandling() const
{
return m_darkModeHandling;
diff --git a/src/plugins/platforms/windows/qwindowsapplication.h b/src/plugins/platforms/windows/qwindowsapplication.h
index efacd74e18..0918df91af 100644
--- a/src/plugins/platforms/windows/qwindowsapplication.h
+++ b/src/plugins/platforms/windows/qwindowsapplication.h
@@ -24,7 +24,6 @@ public:
bool isWinTabEnabled() const override;
bool setWinTabEnabled(bool enabled) override;
- bool isDarkMode() const override;
DarkModeHandling darkModeHandling() const override;
void setDarkModeHandling(DarkModeHandling handling) override;
diff --git a/src/plugins/platforms/windows/qwindowscombase.h b/src/plugins/platforms/windows/qwindowscombase.h
deleted file mode 100644
index c54ff7a11f..0000000000
--- a/src/plugins/platforms/windows/qwindowscombase.h
+++ /dev/null
@@ -1,52 +0,0 @@
-// Copyright (C) 2017 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
-
-#ifndef QWINDOWSCOMBASE_H
-#define QWINDOWSCOMBASE_H
-
-#include <qt_windows.h>
-
-#include <QtCore/qglobal.h>
-
-#include <unknwn.h>
-
-QT_BEGIN_NAMESPACE
-
-// The __uuidof operator of MinGW does not work for all interfaces (for example,
-// IAccessible2). Specializations of this function can be provides to work
-// around this.
-template <class DesiredInterface>
-static IID qUuidOf() { return __uuidof(DesiredInterface); }
-
-// Helper for implementing IUnknown::QueryInterface.
-template <class DesiredInterface, class Derived>
-bool qWindowsComQueryInterface(Derived *d, REFIID id, LPVOID *iface)
-{
- if (id == qUuidOf<DesiredInterface>()) {
- *iface = static_cast<DesiredInterface *>(d);
- d->AddRef();
- return true;
- }
- return false;
-}
-
-// Helper for implementing IUnknown::QueryInterface for IUnknown
-// in the case of multiple inheritance via the first inherited class.
-template <class FirstInheritedInterface, class Derived>
-bool qWindowsComQueryUnknownInterfaceMulti(Derived *d, REFIID id, LPVOID *iface)
-{
- if (id == __uuidof(IUnknown)) {
- *iface = static_cast<FirstInheritedInterface *>(d);
- d->AddRef();
- return true;
- }
- return false;
-}
-
-// Clang does not consider __declspec(nothrow) as nothrow
-QT_WARNING_DISABLE_CLANG("-Wmicrosoft-exception-spec")
-QT_WARNING_DISABLE_CLANG("-Wmissing-exception-spec")
-
-QT_END_NAMESPACE
-
-#endif // QWINDOWSCOMBASE_H
diff --git a/src/plugins/platforms/windows/qwindowscontext.cpp b/src/plugins/platforms/windows/qwindowscontext.cpp
index c85c44d949..8c0261d568 100644
--- a/src/plugins/platforms/windows/qwindowscontext.cpp
+++ b/src/plugins/platforms/windows/qwindowscontext.cpp
@@ -154,11 +154,9 @@ struct QWindowsContextPrivate {
bool m_asyncExpose = false;
HPOWERNOTIFY m_powerNotification = nullptr;
HWND m_powerDummyWindow = nullptr;
- static bool m_darkMode;
static bool m_v2DpiAware;
};
-bool QWindowsContextPrivate::m_darkMode = false;
bool QWindowsContextPrivate::m_v2DpiAware = false;
QWindowsContextPrivate::QWindowsContextPrivate()
@@ -172,7 +170,6 @@ QWindowsContextPrivate::QWindowsContextPrivate()
m_systemInfo |= QWindowsContext::SI_RTL_Extensions;
m_keyMapper.setUseRTLExtensions(true);
}
- m_darkMode = QWindowsTheme::queryDarkMode();
if (FAILED(m_oleInitializeResult)) {
qWarning() << "QWindowsContext: OleInitialize() failed: "
<< QSystemError::windowsComString(m_oleInitializeResult);
@@ -204,6 +201,8 @@ QWindowsContext::~QWindowsContext()
if (d->m_powerDummyWindow)
DestroyWindow(d->m_powerDummyWindow);
+ d->m_screenManager.destroyWindow();
+
unregisterWindowClasses();
if (d->m_oleInitializeResult == S_OK || d->m_oleInitializeResult == S_FALSE) {
#ifdef QT_USE_FACTORY_CACHE_REGISTRATION
@@ -464,11 +463,6 @@ bool QWindowsContext::setProcessDpiAwareness(QtWindows::DpiAwareness dpiAwarenes
return true;
}
-bool QWindowsContext::isDarkMode()
-{
- return QWindowsContextPrivate::m_darkMode;
-}
-
QWindowsContext *QWindowsContext::instance()
{
return m_instance;
@@ -1093,21 +1087,7 @@ bool QWindowsContext::windowsProc(HWND hwnd, UINT message,
// Only refresh the window theme if the user changes the personalize settings.
if ((wParam == 0) && (lParam != 0) // lParam sometimes may be NULL.
&& (wcscmp(reinterpret_cast<LPCWSTR>(lParam), L"ImmersiveColorSet") == 0)) {
- const bool darkMode = QWindowsTheme::queryDarkMode();
- const bool darkModeChanged = darkMode != QWindowsContextPrivate::m_darkMode;
- QWindowsContextPrivate::m_darkMode = darkMode;
- auto integration = QWindowsIntegration::instance();
- integration->updateApplicationBadge();
- if (integration->darkModeHandling().testFlag(QWindowsApplication::DarkModeStyle)) {
- QWindowsTheme::instance()->refresh();
- QWindowSystemInterface::handleThemeChange();
- }
- if (darkModeChanged) {
- if (integration->darkModeHandling().testFlag(QWindowsApplication::DarkModeWindowFrames)) {
- for (QWindowsWindow *w : d->m_windows)
- w->setDarkBorder(QWindowsContextPrivate::m_darkMode);
- }
- }
+ QWindowsTheme::handleSettingsChanged();
}
return d->m_screenManager.handleScreenChanges();
}
diff --git a/src/plugins/platforms/windows/qwindowscontext.h b/src/plugins/platforms/windows/qwindowscontext.h
index 1089224433..0539a22afc 100644
--- a/src/plugins/platforms/windows/qwindowscontext.h
+++ b/src/plugins/platforms/windows/qwindowscontext.h
@@ -120,8 +120,6 @@ public:
static QtWindows::DpiAwareness processDpiAwareness();
static QtWindows::DpiAwareness windowDpiAwareness(HWND hwnd);
- static bool isDarkMode();
-
void setDetectAltGrModifier(bool a);
// Returns a combination of SystemInfoFlags
diff --git a/src/plugins/platforms/windows/qwindowsintegration.cpp b/src/plugins/platforms/windows/qwindowsintegration.cpp
index 6415c9ac50..aa6be266da 100644
--- a/src/plugins/platforms/windows/qwindowsintegration.cpp
+++ b/src/plugins/platforms/windows/qwindowsintegration.cpp
@@ -625,12 +625,16 @@ void QWindowsIntegration::setApplicationBadge(qint64 number)
// We prefer the native BadgeUpdater API, that allows us to set a number directly,
// but it requires that the application has a package identity, and also doesn't
// seem to work in all cases on < Windows 11.
- if (isWindows11 && qt_win_hasPackageIdentity()) {
- using namespace winrt::Windows::UI::Notifications;
- auto badgeXml = BadgeUpdateManager::GetTemplateContent(BadgeTemplateType::BadgeNumber);
- badgeXml.SelectSingleNode(L"//badge/@value").NodeValue(winrt::box_value(winrt::to_hstring(number)));
- BadgeUpdateManager::CreateBadgeUpdaterForApplication().Update(BadgeNotification(badgeXml));
- return;
+ QT_TRY {
+ if (isWindows11 && qt_win_hasPackageIdentity()) {
+ using namespace winrt::Windows::UI::Notifications;
+ auto badgeXml = BadgeUpdateManager::GetTemplateContent(BadgeTemplateType::BadgeNumber);
+ badgeXml.SelectSingleNode(L"//badge/@value").NodeValue(winrt::box_value(winrt::to_hstring(number)));
+ BadgeUpdateManager::CreateBadgeUpdaterForApplication().Update(BadgeNotification(badgeXml));
+ return;
+ }
+ } QT_CATCH(...) {
+ // fall back to win32 implementation
}
#endif
@@ -642,7 +646,8 @@ void QWindowsIntegration::setApplicationBadge(qint64 number)
return;
}
- const bool isDarkMode = QWindowsContext::isDarkMode();
+ const bool isDarkMode = QWindowsTheme::instance()->colorScheme()
+ == Qt::ColorScheme::Dark;
QColor badgeColor;
QColor textColor;
diff --git a/src/plugins/platforms/windows/qwindowsscreen.cpp b/src/plugins/platforms/windows/qwindowsscreen.cpp
index a50f9fd4b0..1f22fb4f60 100644
--- a/src/plugins/platforms/windows/qwindowsscreen.cpp
+++ b/src/plugins/platforms/windows/qwindowsscreen.cpp
@@ -698,11 +698,15 @@ void QWindowsScreenManager::initialize()
handleScreenChanges();
}
-QWindowsScreenManager::~QWindowsScreenManager()
+void QWindowsScreenManager::destroyWindow()
{
+ qCDebug(lcQpaScreen) << "Destroying display change observer" << m_displayChangeObserver;
DestroyWindow(m_displayChangeObserver);
+ m_displayChangeObserver = nullptr;
}
+QWindowsScreenManager::~QWindowsScreenManager() = default;
+
bool QWindowsScreenManager::isSingleScreen()
{
return QWindowsContext::instance()->screenManager().screens().size() < 2;
diff --git a/src/plugins/platforms/windows/qwindowsscreen.h b/src/plugins/platforms/windows/qwindowsscreen.h
index 0467ab2a0c..ea6a29efe3 100644
--- a/src/plugins/platforms/windows/qwindowsscreen.h
+++ b/src/plugins/platforms/windows/qwindowsscreen.h
@@ -105,6 +105,7 @@ public:
QWindowsScreenManager();
void initialize();
+ void destroyWindow();
~QWindowsScreenManager();
void clearScreens();
diff --git a/src/plugins/platforms/windows/qwindowstheme.cpp b/src/plugins/platforms/windows/qwindowstheme.cpp
index b0b6672487..b6017c7692 100644
--- a/src/plugins/platforms/windows/qwindowstheme.cpp
+++ b/src/plugins/platforms/windows/qwindowstheme.cpp
@@ -13,6 +13,7 @@
# include "qwindowssystemtrayicon.h"
#endif
#include "qwindowsscreen.h"
+#include "qwindowswindow.h"
#include <commctrl.h>
#include <objbase.h>
#include <commoncontrols.h>
@@ -258,7 +259,7 @@ static QColor placeHolderColor(QColor textColor)
This is used when the theme is light mode, and when the theme is dark but the
application doesn't support dark mode. In the latter case, we need to check.
*/
-static void populateLightSystemBasePalette(QPalette &result)
+void QWindowsTheme::populateLightSystemBasePalette(QPalette &result)
{
const QColor background = getSysColor(COLOR_BTNFACE);
const QColor textColor = getSysColor(COLOR_WINDOWTEXT);
@@ -298,8 +299,11 @@ static void populateLightSystemBasePalette(QPalette &result)
result.setColor(QPalette::Midlight, result.button().color().lighter(110));
}
-static void populateDarkSystemBasePalette(QPalette &result)
+void QWindowsTheme::populateDarkSystemBasePalette(QPalette &result)
{
+ QColor foreground, background,
+ accent, accentDark, accentDarker, accentDarkest,
+ accentLight, accentLighter, accentLightest;
#if QT_CONFIG(cpp_winrt)
using namespace winrt::Windows::UI::ViewManagement;
const auto settings = UISettings();
@@ -307,32 +311,37 @@ static void populateDarkSystemBasePalette(QPalette &result)
// We have to craft a palette from these colors. The settings.UIElementColor(UIElementType) API
// returns the old system colors, not the dark mode colors. If the background is black (which it
// usually), then override it with a dark gray instead so that we can go up and down the lightness.
- const QColor foreground = getSysColor(settings.GetColorValue(UIColorType::Foreground));
- const QColor background = [&settings]() -> QColor {
- auto systemBackground = getSysColor(settings.GetColorValue(UIColorType::Background));
- if (systemBackground == Qt::black)
- systemBackground = QColor(0x1E, 0x1E, 0x1E);
- return systemBackground;
- }();
-
- const QColor accent = getSysColor(settings.GetColorValue(UIColorType::Accent));
- const QColor accentDark = getSysColor(settings.GetColorValue(UIColorType::AccentDark1));
- const QColor accentDarker = getSysColor(settings.GetColorValue(UIColorType::AccentDark2));
- const QColor accentDarkest = getSysColor(settings.GetColorValue(UIColorType::AccentDark3));
- const QColor accentLight = getSysColor(settings.GetColorValue(UIColorType::AccentLight1));
- const QColor accentLighter = getSysColor(settings.GetColorValue(UIColorType::AccentLight2));
- const QColor accentLightest = getSysColor(settings.GetColorValue(UIColorType::AccentLight3));
-#else
- const QColor foreground = Qt::white;
- const QColor background = QColor(0x1E, 0x1E, 0x1E);
- const QColor accent = qt_accentColor(AccentColorNormal);
- const QColor accentDark = accent.darker(120);
- const QColor accentDarker = accentDark.darker(120);
- const QColor accentDarkest = accentDarker.darker(120);
- const QColor accentLight = accent.lighter(120);
- const QColor accentLighter = accentLight.lighter(120);
- const QColor accentLightest = accentLighter.lighter(120);
+ if (QWindowsTheme::queryColorScheme() == Qt::ColorScheme::Dark) {
+ // the system is actually running in dark mode, so UISettings will give us dark colors
+ foreground = getSysColor(settings.GetColorValue(UIColorType::Foreground));
+ background = [&settings]() -> QColor {
+ auto systemBackground = getSysColor(settings.GetColorValue(UIColorType::Background));
+ if (systemBackground == Qt::black)
+ systemBackground = QColor(0x1E, 0x1E, 0x1E);
+ return systemBackground;
+ }();
+
+ accent = getSysColor(settings.GetColorValue(UIColorType::Accent));
+ accentDark = getSysColor(settings.GetColorValue(UIColorType::AccentDark1));
+ accentDarker = getSysColor(settings.GetColorValue(UIColorType::AccentDark2));
+ accentDarkest = getSysColor(settings.GetColorValue(UIColorType::AccentDark3));
+ accentLight = getSysColor(settings.GetColorValue(UIColorType::AccentLight1));
+ accentLighter = getSysColor(settings.GetColorValue(UIColorType::AccentLight2));
+ accentLightest = getSysColor(settings.GetColorValue(UIColorType::AccentLight3));
+ } else
#endif
+ {
+ // If the system is running in light mode, then we need to make up our own dark palette
+ foreground = Qt::white;
+ background = QColor(0x1E, 0x1E, 0x1E);
+ accent = qt_accentColor(AccentColorNormal);
+ accentDark = accent.darker(120);
+ accentDarker = accentDark.darker(120);
+ accentDarkest = accentDarker.darker(120);
+ accentLight = accent.lighter(120);
+ accentLighter = accentLight.lighter(120);
+ accentLightest = accentLighter.lighter(120);
+ }
const QColor linkColor = accent;
const QColor buttonColor = background.lighter(200);
@@ -451,6 +460,7 @@ QWindowsTheme *QWindowsTheme::m_instance = nullptr;
QWindowsTheme::QWindowsTheme()
{
m_instance = this;
+ s_colorScheme = QWindowsTheme::queryColorScheme();
std::fill(m_fonts, m_fonts + NFonts, nullptr);
std::fill(m_palettes, m_palettes + NPalettes, nullptr);
refresh();
@@ -540,9 +550,43 @@ QVariant QWindowsTheme::themeHint(ThemeHint hint) const
Qt::ColorScheme QWindowsTheme::colorScheme() const
{
+ return QWindowsTheme::effectiveColorScheme();
+}
+
+Qt::ColorScheme QWindowsTheme::effectiveColorScheme()
+{
if (queryHighContrast())
return Qt::ColorScheme::Unknown;
- return QWindowsContext::isDarkMode() ? Qt::ColorScheme::Dark : Qt::ColorScheme::Light;
+ if (s_colorSchemeOverride != Qt::ColorScheme::Unknown)
+ return s_colorSchemeOverride;
+ if (s_colorScheme != Qt::ColorScheme::Unknown)
+ return s_colorScheme;
+ return queryColorScheme();
+}
+
+void QWindowsTheme::requestColorScheme(Qt::ColorScheme scheme)
+{
+ s_colorSchemeOverride = scheme;
+ handleSettingsChanged();
+}
+
+void QWindowsTheme::handleSettingsChanged()
+{
+ const auto oldColorScheme = s_colorScheme;
+ s_colorScheme = Qt::ColorScheme::Unknown; // make effectiveColorScheme() query registry
+ const auto newColorScheme = effectiveColorScheme();
+ const bool colorSchemeChanged = newColorScheme != oldColorScheme;
+ s_colorScheme = newColorScheme;
+ auto integration = QWindowsIntegration::instance();
+ integration->updateApplicationBadge();
+ if (integration->darkModeHandling().testFlag(QWindowsApplication::DarkModeStyle)) {
+ QWindowsTheme::instance()->refresh();
+ QWindowSystemInterface::handleThemeChange<QWindowSystemInterface::SynchronousDelivery>();
+ }
+ if (colorSchemeChanged) {
+ for (QWindowsWindow *w : std::as_const(QWindowsContext::instance()->windows()))
+ w->setDarkBorder(s_colorScheme == Qt::ColorScheme::Dark);
+ }
}
void QWindowsTheme::clearPalettes()
@@ -556,10 +600,10 @@ void QWindowsTheme::refreshPalettes()
if (!QGuiApplication::desktopSettingsAware())
return;
const bool light =
- !QWindowsContext::isDarkMode()
+ effectiveColorScheme() != Qt::ColorScheme::Dark
|| !QWindowsIntegration::instance()->darkModeHandling().testFlag(QWindowsApplication::DarkModeStyle);
clearPalettes();
- m_palettes[SystemPalette] = new QPalette(QWindowsTheme::systemPalette(light ? Qt::ColorScheme::Light : Qt::ColorScheme::Dark));
+ m_palettes[SystemPalette] = new QPalette(QWindowsTheme::systemPalette(s_colorScheme));
m_palettes[ToolTipPalette] = new QPalette(toolTipPalette(*m_palettes[SystemPalette], light));
m_palettes[MenuPalette] = new QPalette(menuPalette(*m_palettes[SystemPalette], light));
m_palettes[MenuBarPalette] = menuBarPalette(*m_palettes[MenuPalette], light);
@@ -577,15 +621,15 @@ QPalette QWindowsTheme::systemPalette(Qt::ColorScheme colorScheme)
QPalette result = standardPalette();
switch (colorScheme) {
+ case Qt::ColorScheme::Unknown:
+ // when a high-contrast theme is active or when we fail to read, assume light
+ Q_FALLTHROUGH();
case Qt::ColorScheme::Light:
populateLightSystemBasePalette(result);
break;
case Qt::ColorScheme::Dark:
populateDarkSystemBasePalette(result);
break;
- default:
- qFatal("Unknown color scheme");
- break;
}
if (result.window() != result.base()) {
@@ -1091,14 +1135,14 @@ bool QWindowsTheme::useNativeMenus()
return result;
}
-bool QWindowsTheme::queryDarkMode()
+Qt::ColorScheme QWindowsTheme::queryColorScheme()
{
- if (queryHighContrast()) {
- return false;
- }
+ if (queryHighContrast())
+ return Qt::ColorScheme::Unknown;
+
const auto setting = QWinRegistryKey(HKEY_CURRENT_USER, LR"(Software\Microsoft\Windows\CurrentVersion\Themes\Personalize)")
.dwordValue(L"AppsUseLightTheme");
- return setting.second && setting.first == 0;
+ return setting.second && setting.first == 0 ? Qt::ColorScheme::Dark : Qt::ColorScheme::Light;
}
bool QWindowsTheme::queryHighContrast()
diff --git a/src/plugins/platforms/windows/qwindowstheme.h b/src/plugins/platforms/windows/qwindowstheme.h
index bc16a9619e..96ae6197b4 100644
--- a/src/plugins/platforms/windows/qwindowstheme.h
+++ b/src/plugins/platforms/windows/qwindowstheme.h
@@ -32,6 +32,10 @@ public:
QVariant themeHint(ThemeHint) const override;
Qt::ColorScheme colorScheme() const override;
+ void requestColorScheme(Qt::ColorScheme scheme) override;
+ Qt::ColorScheme requestedColorScheme() const { return s_colorSchemeOverride; }
+
+ static void handleSettingsChanged();
const QPalette *palette(Palette type = SystemPalette) const override
{ return m_palettes[type]; }
@@ -54,8 +58,6 @@ public:
void showPlatformMenuBar() override;
static bool useNativeMenus();
- static bool queryDarkMode();
- static bool queryHighContrast();
void refreshFonts();
void refresh();
@@ -70,7 +72,17 @@ private:
void clearFonts();
void refreshIconPixmapSizes();
+ static void populateLightSystemBasePalette(QPalette &result);
+ static void populateDarkSystemBasePalette(QPalette &result);
+
+ static Qt::ColorScheme queryColorScheme();
+ static Qt::ColorScheme effectiveColorScheme();
+ static bool queryHighContrast();
+
static QWindowsTheme *m_instance;
+ static inline Qt::ColorScheme s_colorScheme = Qt::ColorScheme::Unknown;
+ static inline Qt::ColorScheme s_colorSchemeOverride = Qt::ColorScheme::Unknown;
+
QPalette *m_palettes[NPalettes];
QFont *m_fonts[NFonts];
QList<QSize> m_fileIconSizes;
diff --git a/src/plugins/platforms/windows/qwindowswindow.cpp b/src/plugins/platforms/windows/qwindowswindow.cpp
index 220c36cc19..ee0b88ba54 100644
--- a/src/plugins/platforms/windows/qwindowswindow.cpp
+++ b/src/plugins/platforms/windows/qwindowswindow.cpp
@@ -5,6 +5,7 @@
#include "qwindowswindow.h"
#include "qwindowscontext.h"
+#include "qwindowstheme.h"
#if QT_CONFIG(draganddrop)
# include "qwindowsdrag.h"
#endif
@@ -849,10 +850,17 @@ static inline bool shouldApplyDarkFrame(const QWindow *w)
{
if (!w->isTopLevel() || w->flags().testFlag(Qt::FramelessWindowHint))
return false;
- // the application has explicitly opted out of dark frames
+
+ // the user of the application has explicitly opted out of dark frames
if (!QWindowsIntegration::instance()->darkModeHandling().testFlag(QWindowsApplication::DarkModeWindowFrames))
return false;
+ // the application explicitly overrides the color scheme
+ if (const auto requestedColorScheme = QWindowsTheme::instance()->requestedColorScheme();
+ requestedColorScheme != Qt::ColorScheme::Unknown) {
+ return requestedColorScheme == Qt::ColorScheme::Dark;
+ }
+
// if the application supports a dark border, and the palette is dark (window background color
// is darker than the text), then turn dark-border support on, otherwise use a light border.
auto *dWindow = QWindowPrivate::get(const_cast<QWindow*>(w));
@@ -929,7 +937,7 @@ QWindowsWindowData
return result;
}
- if (QWindowsContext::isDarkMode() && shouldApplyDarkFrame(w))
+ if (QWindowsTheme::instance()->colorScheme() == Qt::ColorScheme::Dark && shouldApplyDarkFrame(w))
QWindowsWindow::setDarkBorderToWindow(result.hwnd, true);
if (mirrorParentWidth != 0) {
@@ -1357,6 +1365,8 @@ QWindowsForeignWindow::QWindowsForeignWindow(QWindow *window, HWND hwnd)
, m_hwnd(hwnd)
, m_topLevelStyle(0)
{
+ if (QPlatformWindow::parent())
+ setParent(QPlatformWindow::parent());
}
void QWindowsForeignWindow::setParent(const QPlatformWindow *newParentWindow)
@@ -2687,7 +2697,7 @@ bool QWindowsWindow::windowEvent(QEvent *event)
{
switch (event->type()) {
case QEvent::ApplicationPaletteChange:
- setDarkBorder(QWindowsContext::isDarkMode());
+ setDarkBorder(QWindowsTheme::instance()->colorScheme() == Qt::ColorScheme::Dark);
break;
case QEvent::WindowBlocked: // Blocked by another modal window.
setEnabled(false);
@@ -3283,17 +3293,6 @@ enum : WORD {
DwmwaUseImmersiveDarkModeBefore20h1 = 19
};
-static bool queryDarkBorder(HWND hwnd)
-{
- BOOL result = FALSE;
- const bool ok =
- SUCCEEDED(DwmGetWindowAttribute(hwnd, DwmwaUseImmersiveDarkMode, &result, sizeof(result)))
- || SUCCEEDED(DwmGetWindowAttribute(hwnd, DwmwaUseImmersiveDarkModeBefore20h1, &result, sizeof(result)));
- if (!ok)
- qCWarning(lcQpaWindow, "%s: Unable to retrieve dark window border setting.", __FUNCTION__);
- return result == TRUE;
-}
-
bool QWindowsWindow::setDarkBorderToWindow(HWND hwnd, bool d)
{
const BOOL darkBorder = d ? TRUE : FALSE;
@@ -3309,8 +3308,6 @@ void QWindowsWindow::setDarkBorder(bool d)
{
// respect explicit opt-out and incompatible palettes or styles
d = d && shouldApplyDarkFrame(window());
- if (queryDarkBorder(m_data.hwnd) == d)
- return;
setDarkBorderToWindow(m_data.hwnd, d);
}
diff --git a/src/plugins/platforms/windows/uiautomation/qwindowsuiaaccessibility.cpp b/src/plugins/platforms/windows/uiautomation/qwindowsuiaaccessibility.cpp
index 1abb412ccd..5892493281 100644
--- a/src/plugins/platforms/windows/uiautomation/qwindowsuiaaccessibility.cpp
+++ b/src/plugins/platforms/windows/uiautomation/qwindowsuiaaccessibility.cpp
@@ -127,6 +127,9 @@ void QWindowsUiaAccessibility::notifyAccessibilityUpdate(QAccessibleEvent *event
return;
switch (event->type()) {
+ case QAccessible::Announcement:
+ QWindowsUiaMainProvider::raiseNotification(static_cast<QAccessibleAnnouncementEvent *>(event));
+ break;
case QAccessible::Focus:
QWindowsUiaMainProvider::notifyFocusChange(event);
break;
diff --git a/src/plugins/platforms/windows/uiautomation/qwindowsuiamainprovider.cpp b/src/plugins/platforms/windows/uiautomation/qwindowsuiamainprovider.cpp
index 95ddbcced6..b8f2d0eadd 100644
--- a/src/plugins/platforms/windows/uiautomation/qwindowsuiamainprovider.cpp
+++ b/src/plugins/platforms/windows/uiautomation/qwindowsuiamainprovider.cpp
@@ -204,6 +204,24 @@ void QWindowsUiaMainProvider::notifyTextChange(QAccessibleEvent *event)
}
}
+void QWindowsUiaMainProvider::raiseNotification(QAccessibleAnnouncementEvent *event)
+{
+ if (QAccessibleInterface *accessible = event->accessibleInterface()) {
+ if (QWindowsUiaMainProvider *provider = providerForAccessible(accessible)) {
+ BSTR message = bStrFromQString(event->message());
+ QAccessible::AnnouncementPriority prio = event->priority();
+ NotificationProcessing processing = (prio == QAccessible::AnnouncementPriority::Assertive)
+ ? NotificationProcessing_ImportantAll
+ : NotificationProcessing_All;
+ BSTR activityId = bStrFromQString(QString::fromLatin1(""));
+ UiaRaiseNotificationEvent(provider, NotificationKind_Other, processing, message, activityId);
+
+ ::SysFreeString(message);
+ ::SysFreeString(activityId);
+ }
+ }
+}
+
HRESULT STDMETHODCALLTYPE QWindowsUiaMainProvider::QueryInterface(REFIID iid, LPVOID *iface)
{
HRESULT result = QComObject::QueryInterface(iid, iface);
diff --git a/src/plugins/platforms/windows/uiautomation/qwindowsuiamainprovider.h b/src/plugins/platforms/windows/uiautomation/qwindowsuiamainprovider.h
index 99db0ed318..b24f4a6cc3 100644
--- a/src/plugins/platforms/windows/uiautomation/qwindowsuiamainprovider.h
+++ b/src/plugins/platforms/windows/uiautomation/qwindowsuiamainprovider.h
@@ -34,6 +34,7 @@ public:
static void notifyNameChange(QAccessibleEvent *event);
static void notifySelectionChange(QAccessibleEvent *event);
static void notifyTextChange(QAccessibleEvent *event);
+ static void raiseNotification(QAccessibleAnnouncementEvent *event);
// IUnknown
HRESULT STDMETHODCALLTYPE QueryInterface(REFIID id, LPVOID *iface) override;
diff --git a/src/plugins/platforms/windows/uiautomation/qwindowsuiautomation.cpp b/src/plugins/platforms/windows/uiautomation/qwindowsuiautomation.cpp
index 1593a07202..6954a881d0 100644
--- a/src/plugins/platforms/windows/uiautomation/qwindowsuiautomation.cpp
+++ b/src/plugins/platforms/windows/uiautomation/qwindowsuiautomation.cpp
@@ -69,6 +69,14 @@ HRESULT WINAPI UiaRaiseAutomationEvent(IRawElementProviderSimple *pProvider, EVE
return func.invoke(pProvider, id);
}
+HRESULT WINAPI UiaRaiseNotificationEvent(
+ IRawElementProviderSimple *pProvider, NotificationKind notificationKind,
+ NotificationProcessing notificationProcessing, BSTR displayString, BSTR activityId)
+{
+ static auto func = winapi_func("uiautomationcore", FN(UiaRaiseNotificationEvent));
+ return func.invoke(pProvider, notificationKind, notificationProcessing, displayString, activityId);
+}
+
#endif // defined(__MINGW32__) || defined(__MINGW64__)
#endif // QT_CONFIG(accessibility)
diff --git a/src/plugins/platforms/xcb/CMakeLists.txt b/src/plugins/platforms/xcb/CMakeLists.txt
index e8fb442dd4..96758e7181 100644
--- a/src/plugins/platforms/xcb/CMakeLists.txt
+++ b/src/plugins/platforms/xcb/CMakeLists.txt
@@ -164,7 +164,7 @@ endif()
qt_internal_add_plugin(QXcbIntegrationPlugin
OUTPUT_NAME qxcb
PLUGIN_TYPE platforms
- DEFAULT_IF ${QT_QPA_DEFAULT_PLATFORM} MATCHES xcb
+ DEFAULT_IF "xcb" IN_LIST QT_QPA_PLATFORMS
SOURCES
qxcbmain.cpp
DEFINES
diff --git a/src/plugins/platforms/xcb/qxcbwindow.cpp b/src/plugins/platforms/xcb/qxcbwindow.cpp
index 09d4cd9833..d3e4fa9548 100644
--- a/src/plugins/platforms/xcb/qxcbwindow.cpp
+++ b/src/plugins/platforms/xcb/qxcbwindow.cpp
@@ -522,6 +522,10 @@ QXcbForeignWindow::QXcbForeignWindow(QWindow *window, WId nativeHandle)
QRect nativeGeometry(geometry->x, geometry->y, geometry->width, geometry->height);
QPlatformWindow::setGeometry(nativeGeometry);
}
+
+ // And reparent, if we have a parent already
+ if (QPlatformWindow::parent())
+ setParent(QPlatformWindow::parent());
}
QXcbForeignWindow::~QXcbForeignWindow()
diff --git a/src/plugins/platformthemes/gtk3/CMakeLists.txt b/src/plugins/platformthemes/gtk3/CMakeLists.txt
index becfcccd35..6d3c7bf3a2 100644
--- a/src/plugins/platformthemes/gtk3/CMakeLists.txt
+++ b/src/plugins/platformthemes/gtk3/CMakeLists.txt
@@ -35,6 +35,13 @@ qt_internal_add_plugin(QGtk3ThemePlugin
Qt::GuiPrivate
)
+qt_internal_extend_target(QGtk3ThemePlugin CONDITION QT_FEATURE_dbus
+ SOURCES
+ qgtk3portalinterface.cpp
+ LIBRARIES
+ Qt::DBus
+)
+
qt_internal_extend_target(QGtk3ThemePlugin CONDITION QT_FEATURE_xlib
LIBRARIES
X11::X11
diff --git a/src/plugins/platformthemes/gtk3/qgtk3portalinterface.cpp b/src/plugins/platformthemes/gtk3/qgtk3portalinterface.cpp
new file mode 100644
index 0000000000..1ffdda74fa
--- /dev/null
+++ b/src/plugins/platformthemes/gtk3/qgtk3portalinterface.cpp
@@ -0,0 +1,123 @@
+// Copyright (C) 2024 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+//
+// 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 "qgtk3portalinterface_p.h"
+#include "qgtk3storage_p.h"
+
+#include <QtDBus/QDBusArgument>
+#include <QtDBus/QDBusConnection>
+#include <QtDBus/QDBusMessage>
+#include <QtDBus/QDBusPendingCall>
+#include <QtDBus/QDBusPendingCallWatcher>
+#include <QtDBus/QDBusPendingReply>
+#include <QtDBus/QDBusVariant>
+#include <QtDBus/QtDBus>
+
+QT_BEGIN_NAMESPACE
+
+Q_LOGGING_CATEGORY(lcQGtk3PortalInterface, "qt.qpa.gtk");
+
+using namespace Qt::StringLiterals;
+
+static constexpr QLatin1StringView appearanceInterface("org.freedesktop.appearance");
+static constexpr QLatin1StringView colorSchemeKey("color-scheme");
+
+const QDBusArgument &operator>>(const QDBusArgument &argument, QMap<QString, QVariantMap> &map)
+{
+ argument.beginMap();
+ map.clear();
+
+ while (!argument.atEnd()) {
+ QString key;
+ QVariantMap value;
+ argument.beginMapEntry();
+ argument >> key >> value;
+ argument.endMapEntry();
+ map.insert(key, value);
+ }
+
+ argument.endMap();
+ return argument;
+}
+
+QGtk3PortalInterface::QGtk3PortalInterface(QGtk3Storage *s)
+ : m_storage(s) {
+ qRegisterMetaType<QDBusVariant>();
+ qDBusRegisterMetaType<QMap<QString, QVariantMap>>();
+
+ queryColorScheme();
+
+ if (!s) {
+ qCDebug(lcQGtk3PortalInterface) << "QGtk3PortalInterface instantiated without QGtk3Storage."
+ << "No reaction to runtime theme changes.";
+ }
+}
+
+Qt::ColorScheme QGtk3PortalInterface::colorScheme() const
+{
+ return m_colorScheme;
+}
+
+void QGtk3PortalInterface::queryColorScheme() {
+ QDBusConnection connection = QDBusConnection::sessionBus();
+ QDBusMessage message = QDBusMessage::createMethodCall(
+ "org.freedesktop.portal.Desktop"_L1,
+ "/org/freedesktop/portal/desktop"_L1,
+ "org.freedesktop.portal.Settings"_L1, "ReadAll"_L1);
+ message << QStringList{ appearanceInterface };
+
+ QDBusPendingCall pendingCall = connection.asyncCall(message);
+ QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(pendingCall, this);
+ QObject::connect(
+ watcher, &QDBusPendingCallWatcher::finished, this,
+ [this](QDBusPendingCallWatcher *watcher) {
+ QDBusPendingReply<QMap<QString, QVariantMap>> reply = *watcher;
+ if (reply.isValid()) {
+ QMap<QString, QVariantMap> settings = reply.value();
+ if (!settings.isEmpty()) {
+ settingChanged(appearanceInterface, colorSchemeKey,
+ QDBusVariant(settings.value(appearanceInterface).value(colorSchemeKey)));
+ }
+ } else {
+ qCDebug(lcQGtk3PortalInterface) << "Failed to query org.freedesktop.portal.Settings: "
+ << reply.error().message();
+ }
+ watcher->deleteLater();
+ });
+
+ QDBusConnection::sessionBus().connect(
+ "org.freedesktop.portal.Desktop"_L1, "/org/freedesktop/portal/desktop"_L1,
+ "org.freedesktop.portal.Settings"_L1, "SettingChanged"_L1, this,
+ SLOT(settingChanged(QString, QString, QDBusVariant)));
+}
+
+void QGtk3PortalInterface::settingChanged(const QString &group, const QString &key,
+ const QDBusVariant &value)
+{
+ if (group == appearanceInterface && key == colorSchemeKey) {
+ const uint colorScheme = value.variant().toUInt();
+ // From org.freedesktop.portal.Settings.xml
+ // "1" - Prefer dark appearance
+ Qt::ColorScheme newColorScheme = colorScheme == 1 ? Qt::ColorScheme::Dark : Qt::ColorScheme::Light;
+ if (m_colorScheme != newColorScheme) {
+ m_colorScheme = newColorScheme;
+ if (m_storage)
+ m_storage->handleThemeChange();
+ }
+ }
+}
+
+QT_END_NAMESPACE
+
+#include "moc_qgtk3portalinterface_p.cpp"
diff --git a/src/plugins/platformthemes/gtk3/qgtk3portalinterface_p.h b/src/plugins/platformthemes/gtk3/qgtk3portalinterface_p.h
new file mode 100644
index 0000000000..25a5f58ab1
--- /dev/null
+++ b/src/plugins/platformthemes/gtk3/qgtk3portalinterface_p.h
@@ -0,0 +1,49 @@
+// Copyright (C) 2024 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#ifndef QGTK3PORTALINTERFACE_H
+#define QGTK3PORTALINTERFACE_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 <QtCore/QObject>
+#include <QtCore/QLoggingCategory>
+
+QT_BEGIN_NAMESPACE
+
+class QDBusVariant;
+class QGtk3Storage;
+
+Q_DECLARE_LOGGING_CATEGORY(lcQGtk3PortalInterface);
+
+class QGtk3PortalInterface : public QObject
+{
+ Q_OBJECT
+public:
+ QGtk3PortalInterface(QGtk3Storage *s);
+ ~QGtk3PortalInterface() = default;
+
+ Qt::ColorScheme colorScheme() const;
+
+private Q_SLOTS:
+ void settingChanged(const QString &group, const QString &key,
+ const QDBusVariant &value);
+private:
+ void queryColorScheme();
+
+ Qt::ColorScheme m_colorScheme = Qt::ColorScheme::Unknown;
+ QGtk3Storage *m_storage = nullptr;
+};
+
+QT_END_NAMESPACE
+
+#endif // QGTK3PORTALINTERFACE_H
diff --git a/src/plugins/platformthemes/gtk3/qgtk3storage.cpp b/src/plugins/platformthemes/gtk3/qgtk3storage.cpp
index 90c0282651..2877b28590 100644
--- a/src/plugins/platformthemes/gtk3/qgtk3storage.cpp
+++ b/src/plugins/platformthemes/gtk3/qgtk3storage.cpp
@@ -21,6 +21,9 @@ QT_BEGIN_NAMESPACE
QGtk3Storage::QGtk3Storage()
{
m_interface.reset(new QGtk3Interface(this));
+#if QT_CONFIG(dbus)
+ m_portalInterface.reset(new QGtk3PortalInterface(this));
+#endif
populateMap();
}
@@ -273,7 +276,6 @@ void QGtk3Storage::clear()
*/
void QGtk3Storage::handleThemeChange()
{
- clear();
populateMap();
QWindowSystemInterface::handleThemeChange();
}
@@ -331,21 +333,32 @@ void QGtk3Storage::populateMap()
static QString m_themeName;
// Distiguish initialization, theme change or call without theme change
+ Qt::ColorScheme newColorScheme = Qt::ColorScheme::Unknown;
const QString newThemeName = themeName();
- if (m_themeName == newThemeName)
+
+#if QT_CONFIG(dbus)
+ // Prefer color scheme we get from xdg-desktop-portal as this is what GNOME
+ // relies on these days
+ newColorScheme = m_portalInterface->colorScheme();
+#endif
+
+ if (newColorScheme == Qt::ColorScheme::Unknown) {
+ // Derive color scheme from theme name
+ newColorScheme = newThemeName.contains("dark"_L1, Qt::CaseInsensitive)
+ ? Qt::ColorScheme::Dark : m_interface->colorSchemeByColors();
+ }
+
+ if (m_themeName == newThemeName && m_colorScheme == newColorScheme)
return;
clear();
- // Derive color scheme from theme name
- m_colorScheme = newThemeName.contains("dark"_L1, Qt::CaseInsensitive)
- ? Qt::ColorScheme::Dark : m_interface->colorSchemeByColors();
-
if (m_themeName.isEmpty()) {
- qCDebug(lcQGtk3Interface) << "GTK theme initialized:" << newThemeName << m_colorScheme;
+ qCDebug(lcQGtk3Interface) << "GTK theme initialized:" << newThemeName << newColorScheme;
} else {
- qCDebug(lcQGtk3Interface) << "GTK theme changed to:" << newThemeName << m_colorScheme;
+ qCDebug(lcQGtk3Interface) << "GTK theme changed to:" << newThemeName << newColorScheme;
}
+ m_colorScheme = newColorScheme;
m_themeName = newThemeName;
// create standard mapping or load from Json file?
diff --git a/src/plugins/platformthemes/gtk3/qgtk3storage_p.h b/src/plugins/platformthemes/gtk3/qgtk3storage_p.h
index 37c5bf57ff..45192263a9 100644
--- a/src/plugins/platformthemes/gtk3/qgtk3storage_p.h
+++ b/src/plugins/platformthemes/gtk3/qgtk3storage_p.h
@@ -16,6 +16,9 @@
//
#include "qgtk3interface_p.h"
+#if QT_CONFIG(dbus)
+#include "qgtk3portalinterface_p.h"
+#endif
#include <QtCore/QJsonDocument>
#include <QtCore/QCache>
@@ -205,7 +208,9 @@ private:
PaletteMap m_palettes;
std::unique_ptr<QGtk3Interface> m_interface;
-
+#if QT_CONFIG(dbus)
+ std::unique_ptr<QGtk3PortalInterface> m_portalInterface;
+#endif
Qt::ColorScheme m_colorScheme = Qt::ColorScheme::Unknown;
diff --git a/src/plugins/platformthemes/xdgdesktopportal/qxdgdesktopportaltheme.cpp b/src/plugins/platformthemes/xdgdesktopportal/qxdgdesktopportaltheme.cpp
index 7e2a9daacb..355d3e6cc9 100644
--- a/src/plugins/platformthemes/xdgdesktopportal/qxdgdesktopportaltheme.cpp
+++ b/src/plugins/platformthemes/xdgdesktopportal/qxdgdesktopportaltheme.cpp
@@ -20,8 +20,9 @@ QT_BEGIN_NAMESPACE
using namespace Qt::StringLiterals;
-class QXdgDesktopPortalThemePrivate : public QPlatformThemePrivate
-{
+class QXdgDesktopPortalThemePrivate : public QObject
+ {
+ Q_OBJECT
public:
enum XdgColorschemePref {
None,
@@ -30,7 +31,7 @@ public:
};
QXdgDesktopPortalThemePrivate()
- : QPlatformThemePrivate()
+ : QObject()
{ }
~QXdgDesktopPortalThemePrivate()
@@ -62,6 +63,17 @@ public:
}
}
+public Q_SLOTS:
+ void settingChanged(const QString &group, const QString &key,
+ const QDBusVariant &value)
+ {
+ if (group == "org.freedesktop.appearance"_L1 && key == "color-scheme"_L1) {
+ colorScheme = colorSchemeFromXdgPref(static_cast<XdgColorschemePref>(value.variant().toUInt()));
+ QWindowSystemInterface::handleThemeChange();
+ }
+ }
+
+public:
QPlatformTheme *baseTheme = nullptr;
uint fileChooserPortalVersion = 0;
Qt::ColorScheme colorScheme = Qt::ColorScheme::Unknown;
@@ -126,6 +138,11 @@ QXdgDesktopPortalTheme::QXdgDesktopPortalTheme()
const QXdgDesktopPortalThemePrivate::XdgColorschemePref xdgPref = static_cast<QXdgDesktopPortalThemePrivate::XdgColorschemePref>(dbusVariant.variant().toUInt());
d->colorScheme = QXdgDesktopPortalThemePrivate::colorSchemeFromXdgPref(xdgPref);
}
+
+ QDBusConnection::sessionBus().connect(
+ "org.freedesktop.portal.Desktop"_L1, "/org/freedesktop/portal/desktop"_L1,
+ "org.freedesktop.portal.Settings"_L1, "SettingChanged"_L1, d_ptr.get(),
+ SLOT(settingChanged(QString, QString, QDBusVariant)));
}
QPlatformMenuItem* QXdgDesktopPortalTheme::createPlatformMenuItem() const
@@ -247,3 +264,5 @@ QString QXdgDesktopPortalTheme::standardButtonText(int button) const
}
QT_END_NAMESPACE
+
+#include "qxdgdesktopportaltheme.moc"
diff --git a/src/plugins/sqldrivers/ibase/qsql_ibase.cpp b/src/plugins/sqldrivers/ibase/qsql_ibase.cpp
index 28361e250d..f6eed5e227 100644
--- a/src/plugins/sqldrivers/ibase/qsql_ibase.cpp
+++ b/src/plugins/sqldrivers/ibase/qsql_ibase.cpp
@@ -118,6 +118,7 @@ static void initDA(XSQLDA *sqlda)
default:
// not supported - do not bind.
sqlda->sqlvar[i].sqldata = 0;
+ qCWarning(lcIbase, "initDA: unknown sqltype: %d", sqlda->sqlvar[i].sqltype & ~1);
break;
}
if (sqlda->sqlvar[i].sqltype & 1) {
@@ -208,8 +209,10 @@ static QMetaType::Type qIBaseTypeName2(int iType, bool hasScale)
case SQL_BOOLEAN:
return QMetaType::Bool;
default:
- return QMetaType::UnknownType;
+ break;
}
+ qCWarning(lcIbase, "qIBaseTypeName: unknown datatype: %d", iType);
+ return QMetaType::UnknownType;
}
static ISC_TIMESTAMP toTimeStamp(const QDateTime &dt)
@@ -403,6 +406,42 @@ protected:
int size() override;
int numRowsAffected() override;
QSqlRecord record() const override;
+
+ template<typename T>
+ QVariant applyScale(T val, int scale) const
+ {
+ if (scale >= 0)
+ return QVariant(val);
+
+ switch (numericalPrecisionPolicy()) {
+ case QSql::LowPrecisionInt32:
+ return QVariant(qint32(val * pow(10.0, scale)));
+ case QSql::LowPrecisionInt64:
+ return QVariant(qint64(val * pow(10.0, scale)));
+ case QSql::LowPrecisionDouble:
+ return QVariant(double(val * pow(10.0, scale)));
+ case QSql::HighPrecision: {
+ const bool negative = val < 0;
+ QString number;
+ if constexpr (std::is_signed_v<T> || negative)
+ number = QString::number(qAbs(val));
+ else
+ number = QString::number(val);
+ auto len = number.size();
+ scale *= -1;
+ if (scale >= len) {
+ number = QString(scale - len + 1, u'0') + number;
+ len = number.size();
+ }
+ const auto sepPos = len - scale;
+ number = number.left(sepPos) + u'.' + number.mid(sepPos);
+ if (negative)
+ number = u'-' + number;
+ return QVariant(number);
+ }
+ }
+ return QVariant(val);
+ }
};
class QIBaseResultPrivate: public QSqlCachedResultPrivate
@@ -1236,27 +1275,27 @@ bool QIBaseResult::gotoNext(QSqlCachedResult::ValueCache& row, int rowIdx)
// pascal strings - a short with a length information followed by the data
row[idx] = QString::fromUtf8(buf + sizeof(short), *(short*)buf);
break;
- case SQL_INT64:
- if (d->sqlda->sqlvar[i].sqlscale < 0)
- row[idx] = *(qint64*)buf * pow(10.0, d->sqlda->sqlvar[i].sqlscale);
- else
- row[idx] = QVariant(*(qint64*)buf);
+ case SQL_INT64: {
+ Q_ASSERT(d->sqlda->sqlvar[i].sqllen == sizeof(qint64));
+ const auto val = *(qint64 *)buf;
+ const auto scale = d->sqlda->sqlvar[i].sqlscale;
+ row[idx] = applyScale(val, scale);
break;
+ }
case SQL_LONG:
- if (d->sqlda->sqlvar[i].sqllen == 4)
- if (d->sqlda->sqlvar[i].sqlscale < 0)
- row[idx] = QVariant(*(qint32*)buf * pow(10.0, d->sqlda->sqlvar[i].sqlscale));
- else
- row[idx] = QVariant(*(qint32*)buf);
- else
+ if (d->sqlda->sqlvar[i].sqllen == 4) {
+ const auto val = *(qint32 *)buf;
+ const auto scale = d->sqlda->sqlvar[i].sqlscale;
+ row[idx] = applyScale(val, scale);
+ } else
row[idx] = QVariant(*(qint64*)buf);
break;
- case SQL_SHORT:
- if (d->sqlda->sqlvar[i].sqlscale < 0)
- row[idx] = QVariant(long((*(short*)buf)) * pow(10.0, d->sqlda->sqlvar[i].sqlscale));
- else
- row[idx] = QVariant(int((*(short*)buf)));
+ case SQL_SHORT: {
+ const auto val = *(short *)buf;
+ const auto scale = d->sqlda->sqlvar[i].sqlscale;
+ row[idx] = applyScale(val, scale);
break;
+ }
case SQL_FLOAT:
row[idx] = QVariant(double((*(float*)buf)));
break;
@@ -1291,30 +1330,11 @@ bool QIBaseResult::gotoNext(QSqlCachedResult::ValueCache& row, int rowIdx)
#endif
default:
// unknown type - don't even try to fetch
+ qCWarning(lcIbase, "gotoNext: unknown sqltype: %d",
+ d->sqlda->sqlvar[i].sqltype & ~1);
row[idx] = QVariant();
break;
}
- if (d->sqlda->sqlvar[i].sqlscale < 0) {
- QVariant v = row[idx];
- switch(numericalPrecisionPolicy()) {
- case QSql::LowPrecisionInt32:
- if (v.convert(QMetaType(QMetaType::Int)))
- row[idx]=v;
- break;
- case QSql::LowPrecisionInt64:
- if (v.convert(QMetaType(QMetaType::LongLong)))
- row[idx]=v;
- break;
- case QSql::LowPrecisionDouble:
- if (v.convert(QMetaType(QMetaType::Double)))
- row[idx]=v;
- break;
- case QSql::HighPrecision:
- if (v.convert(QMetaType(QMetaType::QString)))
- row[idx]=v;
- break;
- }
- }
}
return true;
diff --git a/src/plugins/styles/modernwindows/qwindows11style.cpp b/src/plugins/styles/modernwindows/qwindows11style.cpp
index f352b7e1af..0501e54ee0 100644
--- a/src/plugins/styles/modernwindows/qwindows11style.cpp
+++ b/src/plugins/styles/modernwindows/qwindows11style.cpp
@@ -9,6 +9,16 @@
#include <qstyleoption.h>
#include <qpainter.h>
#include <QGraphicsDropShadowEffect>
+#include <QtWidgets/qcombobox.h>
+#include <QtWidgets/qcommandlinkbutton.h>
+#include <QtWidgets/qgraphicsview.h>
+#include <QtWidgets/qlistview.h>
+#include <QtWidgets/qmenu.h>
+#if QT_CONFIG(mdiarea)
+#include <QtWidgets/qmdiarea.h>
+#endif
+#include <QtWidgets/qtextedit.h>
+#include <QtWidgets/qtreeview.h>
#include "qdrawutil.h"
#include <chrono>
@@ -126,6 +136,8 @@ static void drawArrow(const QStyle *style, const QStyleOptionToolButton *toolbut
*/
QWindows11Style::QWindows11Style() : QWindowsVistaStyle(*new QWindows11StylePrivate)
{
+ highContrastTheme = QGuiApplicationPrivate::styleHints->colorScheme() == Qt::ColorScheme::Unknown;
+ colorSchemeIndex = QGuiApplicationPrivate::styleHints->colorScheme() == Qt::ColorScheme::Light ? 0 : 1;
}
/*!
@@ -134,6 +146,8 @@ QWindows11Style::QWindows11Style() : QWindowsVistaStyle(*new QWindows11StylePriv
*/
QWindows11Style::QWindows11Style(QWindows11StylePrivate &dd) : QWindowsVistaStyle(dd)
{
+ highContrastTheme = QGuiApplicationPrivate::styleHints->colorScheme() == Qt::ColorScheme::Unknown;
+ colorSchemeIndex = QGuiApplicationPrivate::styleHints->colorScheme() == Qt::ColorScheme::Light ? 0 : 1;
}
/*!
@@ -426,12 +440,21 @@ void QWindows11Style::drawComplexControl(ComplexControl control, const QStyleOpt
#if QT_CONFIG(combobox)
case CC_ComboBox:
if (const QStyleOptionComboBox *combobox = qstyleoption_cast<const QStyleOptionComboBox *>(option)) {
- QBrush fillColor = state & State_MouseOver && !(state & State_HasFocus) ? QBrush(WINUI3Colors[colorSchemeIndex][subtleHighlightColor]) : option->palette.brush(QPalette::Base);
+ QBrush fillColor = combobox->palette.brush(QPalette::Base);
QRectF rect = option->rect.adjusted(2,2,-2,-2);
painter->setBrush(fillColor);
painter->setPen(Qt::NoPen);
painter->drawRoundedRect(rect, secondLevelRoundingRadius, secondLevelRoundingRadius);
+ // In case the QComboBox is hovered overdraw the background with a alpha mask to
+ // highlight the QComboBox.
+ if (state & State_MouseOver) {
+ fillColor = QBrush(WINUI3Colors[colorSchemeIndex][subtleHighlightColor]);
+ painter->setBrush(fillColor);
+ painter->setPen(Qt::NoPen);
+ painter->drawRoundedRect(rect, secondLevelRoundingRadius, secondLevelRoundingRadius);
+ }
+
rect.adjust(0.5,0.5,-0.5,-0.5);
painter->setBrush(Qt::NoBrush);
painter->setPen(highContrastTheme == true ? combobox->palette.buttonText().color() : WINUI3Colors[colorSchemeIndex][frameColorLight]);
@@ -897,12 +920,20 @@ void QWindows11Style::drawPrimitive(PrimitiveElement element, const QStyleOption
if (widget && widget->objectName() == "qt_spinbox_lineedit")
break;
if (const auto *panel = qstyleoption_cast<const QStyleOptionFrame *>(option)) {
- QBrush fillColor = state & State_MouseOver && !(state & State_HasFocus) ? QBrush(WINUI3Colors[colorSchemeIndex][subtleHighlightColor]) : option->palette.brush(QPalette::Base);
- painter->setBrush(fillColor);
- painter->setPen(Qt::NoPen);
QRectF frameRect = option->rect;
frameRect.adjust(0.5,0.5,-0.5,-0.5);
+ QBrush fillColor = option->palette.brush(QPalette::Base);
+ painter->setBrush(fillColor);
+ painter->setPen(Qt::NoPen);
painter->drawRoundedRect(frameRect, secondLevelRoundingRadius, secondLevelRoundingRadius);
+ // In case the QLineEdit is hovered overdraw the background with a alpha mask to
+ // highlight the QLineEdit.
+ if (state & State_MouseOver && !(state & State_HasFocus)) {
+ fillColor = QBrush(WINUI3Colors[colorSchemeIndex][subtleHighlightColor]);
+ painter->setBrush(fillColor);
+ painter->setPen(Qt::NoPen);
+ painter->drawRoundedRect(frameRect, secondLevelRoundingRadius, secondLevelRoundingRadius);
+ }
if (panel->lineWidth > 0)
proxy()->drawPrimitive(PE_FrameLineEdit, panel, painter, widget);
}
@@ -938,7 +969,7 @@ void QWindows11Style::drawPrimitive(PrimitiveElement element, const QStyleOption
painter->setPen(QPen(WINUI3Colors[colorSchemeIndex][frameColorLight]));
painter->drawRoundedRect(rect.marginsRemoved(QMarginsF(0.5,0.5,0.5,0.5)), secondLevelRoundingRadius, secondLevelRoundingRadius);
- if (widget && widget->inherits("QTextEdit")) {
+ if (qobject_cast<const QTextEdit *>(widget)) {
QRegion clipRegion = option->rect;
QColor lineColor = state & State_HasFocus ? option->palette.accent().color() : QColor(0,0,0,255);
painter->setPen(QPen(lineColor));
@@ -953,7 +984,7 @@ void QWindows11Style::drawPrimitive(PrimitiveElement element, const QStyleOption
painter->setBrush(WINUI3Colors[colorSchemeIndex][subtleHighlightColor]);
painter->setPen(Qt::NoPen);
painter->drawRoundedRect(vopt->rect.marginsRemoved(QMargins(0,2,-2,2)),2,2);
- int offset = (widget && widget->inherits("QTreeView")) ? 2 : 0;
+ const int offset = qobject_cast<const QTreeView *>(widget) ? 2 : 0;
if (vopt->viewItemPosition == QStyleOptionViewItem::Beginning && option->state & State_Selected) {
painter->setPen(QPen(option->palette.accent().color()));
painter->drawLine(option->rect.x(),option->rect.y()+offset,option->rect.x(),option->rect.y() + option->rect.height()-2);
@@ -1096,7 +1127,7 @@ void QWindows11Style::drawControl(ControlElement element, const QStyleOption *op
rect.translate(shiftX, shiftY);
painter->setFont(toolbutton->font);
const QString text = d->toolButtonElideText(toolbutton, rect, alignment);
- if (toolbutton->state & State_Raised)
+ if (toolbutton->state & State_Raised || toolbutton->palette.isBrushSet(QPalette::Current, QPalette::ButtonText))
painter->setPen(QPen(toolbutton->palette.buttonText().color()));
else
painter->setPen(QPen(WINUI3Colors[colorSchemeIndex][controlTextSecondary]));
@@ -1150,7 +1181,7 @@ void QWindows11Style::drawControl(ControlElement element, const QStyleOption *op
}
tr.translate(shiftX, shiftY);
const QString text = d->toolButtonElideText(toolbutton, tr, alignment);
- if (toolbutton->state & State_Raised)
+ if (toolbutton->state & State_Raised || toolbutton->palette.isBrushSet(QPalette::Current, QPalette::ButtonText))
painter->setPen(QPen(toolbutton->palette.buttonText().color()));
else
painter->setPen(QPen(WINUI3Colors[colorSchemeIndex][controlTextSecondary]));
@@ -1199,75 +1230,72 @@ void QWindows11Style::drawControl(ControlElement element, const QStyleOption *op
break;
case QStyle::CE_ProgressBarGroove:{
if (const QStyleOptionProgressBar* progbaropt = qstyleoption_cast<const QStyleOptionProgressBar*>(option)) {
- if (const QProgressBar* bar = qobject_cast<const QProgressBar*>(widget)) {
- QRect rect = subElementRect(SE_ProgressBarContents, progbaropt, widget);
- QPointF center = rect.center();
- if (bar->orientation() & Qt::Horizontal) {
- rect.setHeight(1);
- rect.moveTop(center.y());
- } else {
- rect.setWidth(1);
- rect.moveLeft(center.x());
- }
- painter->setPen(Qt::NoPen);
- painter->setBrush(Qt::gray);
- painter->drawRect(rect);
+ QRect rect = subElementRect(SE_ProgressBarContents, progbaropt, widget);
+ QPointF center = rect.center();
+ if (progbaropt->state & QStyle::State_Horizontal) {
+ rect.setHeight(1);
+ rect.moveTop(center.y());
+ } else {
+ rect.setWidth(1);
+ rect.moveLeft(center.x());
}
+ painter->setPen(Qt::NoPen);
+ painter->setBrush(Qt::gray);
+ painter->drawRect(rect);
}
break;
}
case QStyle::CE_ProgressBarContents:
if (const QStyleOptionProgressBar* progbaropt = qstyleoption_cast<const QStyleOptionProgressBar*>(option)) {
- if (const QProgressBar* bar = qobject_cast<const QProgressBar*>(widget)) {
- const qreal progressBarThickness = 3;
- const qreal progressBarHalfThickness = progressBarThickness / 2.0;
- QRectF rect = subElementRect(SE_ProgressBarContents, progbaropt, widget);
- QRectF originalRect = rect;
- QPointF center = rect.center();
- bool isIndeterminate = progbaropt->maximum == 0 && progbaropt->minimum == 0;
- float fillPercentage = 0;
- const qreal offset = (bar->orientation() == Qt::Horizontal && int(rect.height()) % 2 == 0)
- || (bar->orientation() == Qt::Vertical && int(rect.width()) % 2 == 0) ? 0.5 : 0.0;
-
- if (!isIndeterminate) {
- fillPercentage = ((float(progbaropt->progress) - float(progbaropt->minimum)) / (float(progbaropt->maximum) - float(progbaropt->minimum)));
- if (bar->orientation() == Qt::Horizontal) {
- rect.setHeight(progressBarThickness);
- rect.moveTop(center.y() - progressBarHalfThickness - offset);
- rect.setWidth(rect.width() * fillPercentage);
- } else {
- float oldHeight = rect.height();
- rect.setWidth(progressBarThickness);
- rect.moveLeft(center.x() - progressBarHalfThickness - offset);
- rect.moveTop(oldHeight * (1.0f - fillPercentage));
- rect.setHeight(oldHeight * fillPercentage);
- }
+ const qreal progressBarThickness = 3;
+ const qreal progressBarHalfThickness = progressBarThickness / 2.0;
+ QRectF rect = subElementRect(SE_ProgressBarContents, progbaropt, widget);
+ QRectF originalRect = rect;
+ QPointF center = rect.center();
+ bool isIndeterminate = progbaropt->maximum == 0 && progbaropt->minimum == 0;
+ float fillPercentage = 0;
+ const Qt::Orientation orientation = (progbaropt->state & QStyle::State_Horizontal) ? Qt::Horizontal : Qt::Vertical;
+ const qreal offset = (orientation == Qt::Horizontal && int(rect.height()) % 2 == 0)
+ || (orientation == Qt::Vertical && int(rect.width()) % 2 == 0) ? 0.5 : 0.0;
+
+ if (!isIndeterminate) {
+ fillPercentage = ((float(progbaropt->progress) - float(progbaropt->minimum)) / (float(progbaropt->maximum) - float(progbaropt->minimum)));
+ if (orientation == Qt::Horizontal) {
+ rect.setHeight(progressBarThickness);
+ rect.moveTop(center.y() - progressBarHalfThickness - offset);
+ rect.setWidth(rect.width() * fillPercentage);
} else {
- auto elapsedTime = std::chrono::time_point_cast<std::chrono::milliseconds>(std::chrono::system_clock::now());
- fillPercentage = (elapsedTime.time_since_epoch().count() % 5000)/(5000.0f*0.75);
- if (bar->orientation() == Qt::Horizontal) {
- float barBegin = qMin(qMax(fillPercentage-0.25,0.0) * rect.width(), float(rect.width()));
- float barEnd = qMin(fillPercentage * rect.width(), float(rect.width()));
- rect = QRect(QPoint(rect.left() + barBegin, rect.top()), QPoint(rect.left() + barEnd, rect.bottom()));
- rect.setHeight(progressBarThickness);
- rect.moveTop(center.y() - progressBarHalfThickness - offset);
- } else {
- float barBegin = qMin(qMax(fillPercentage-0.25,0.0) * rect.height(), float(rect.height()));
- float barEnd = qMin(fillPercentage * rect.height(), float(rect.height()));
- rect = QRect(QPoint(rect.left(), rect.bottom() - barEnd), QPoint(rect.right(), rect.bottom() - barBegin));
- rect.setWidth(progressBarThickness);
- rect.moveLeft(center.x() - progressBarHalfThickness - offset);
- }
- const_cast<QWidget*>(widget)->update();
+ float oldHeight = rect.height();
+ rect.setWidth(progressBarThickness);
+ rect.moveLeft(center.x() - progressBarHalfThickness - offset);
+ rect.moveTop(oldHeight * (1.0f - fillPercentage));
+ rect.setHeight(oldHeight * fillPercentage);
}
- if (progbaropt->invertedAppearance && bar->orientation() == Qt::Horizontal)
- rect.moveLeft(originalRect.width() * (1.0 - fillPercentage));
- else if (progbaropt->invertedAppearance && bar->orientation() == Qt::Vertical)
- rect.moveBottom(originalRect.height() * fillPercentage);
- painter->setPen(Qt::NoPen);
- painter->setBrush(progbaropt->palette.accent());
- painter->drawRoundedRect(rect, secondLevelRoundingRadius, secondLevelRoundingRadius);
+ } else {
+ auto elapsedTime = std::chrono::time_point_cast<std::chrono::milliseconds>(std::chrono::system_clock::now());
+ fillPercentage = (elapsedTime.time_since_epoch().count() % 5000)/(5000.0f*0.75);
+ if (orientation == Qt::Horizontal) {
+ float barBegin = qMin(qMax(fillPercentage-0.25,0.0) * rect.width(), float(rect.width()));
+ float barEnd = qMin(fillPercentage * rect.width(), float(rect.width()));
+ rect = QRect(QPoint(rect.left() + barBegin, rect.top()), QPoint(rect.left() + barEnd, rect.bottom()));
+ rect.setHeight(progressBarThickness);
+ rect.moveTop(center.y() - progressBarHalfThickness - offset);
+ } else {
+ float barBegin = qMin(qMax(fillPercentage-0.25,0.0) * rect.height(), float(rect.height()));
+ float barEnd = qMin(fillPercentage * rect.height(), float(rect.height()));
+ rect = QRect(QPoint(rect.left(), rect.bottom() - barEnd), QPoint(rect.right(), rect.bottom() - barBegin));
+ rect.setWidth(progressBarThickness);
+ rect.moveLeft(center.x() - progressBarHalfThickness - offset);
+ }
+ const_cast<QWidget*>(widget)->update();
}
+ if (progbaropt->invertedAppearance && orientation == Qt::Horizontal)
+ rect.moveLeft(originalRect.width() * (1.0 - fillPercentage));
+ else if (progbaropt->invertedAppearance && orientation == Qt::Vertical)
+ rect.moveBottom(originalRect.height() * fillPercentage);
+ painter->setPen(Qt::NoPen);
+ painter->setBrush(progbaropt->palette.accent());
+ painter->drawRoundedRect(rect, secondLevelRoundingRadius, secondLevelRoundingRadius);
}
break;
case QStyle::CE_ProgressBarLabel:
@@ -1356,13 +1384,15 @@ void QWindows11Style::drawControl(ControlElement element, const QStyleOption *op
} else {
QRectF rect = btn->rect.marginsRemoved(QMargins(2,2,2,2));
painter->setPen(Qt::NoPen);
- if (flags & (State_Sunken))
- painter->setBrush(flags & State_On ? option->palette.accent().color().lighter(120) : WINUI3Colors[colorSchemeIndex][controlFillTertiary]);
- else if (flags & State_MouseOver)
- painter->setBrush(flags & State_On ? option->palette.accent().color().lighter(110) : WINUI3Colors[colorSchemeIndex][controlFillSecondary]);
- else
- painter->setBrush(flags & State_On ? option->palette.accent() : option->palette.button());
+ painter->setBrush(flags & State_On ? option->palette.accent() : option->palette.button());
painter->drawRoundedRect(rect, secondLevelRoundingRadius, secondLevelRoundingRadius);
+ if (flags.testFlags(State_Sunken | State_MouseOver)) {
+ if (flags & (State_Sunken))
+ painter->setBrush(flags & State_On ? option->palette.accent().color().lighter(120) : WINUI3Colors[colorSchemeIndex][controlFillTertiary]);
+ else if (flags & State_MouseOver)
+ painter->setBrush(flags & State_On ? option->palette.accent().color().lighter(110) : WINUI3Colors[colorSchemeIndex][controlFillSecondary]);
+ painter->drawRoundedRect(rect, secondLevelRoundingRadius, secondLevelRoundingRadius);
+ }
rect.adjust(0.5,0.5,-0.5,-0.5);
painter->setBrush(Qt::NoBrush);
@@ -1570,7 +1600,13 @@ void QWindows11Style::drawControl(ControlElement element, const QStyleOption *op
break;
case CE_HeaderSection: {
if (const QStyleOptionHeader *header = qstyleoption_cast<const QStyleOptionHeader *>(option)) {
+ painter->setPen(Qt::NoPen);
+ painter->setBrush(header->palette.button());
+ painter->drawRect(header->rect);
+
painter->setPen(highContrastTheme == true ? header->palette.buttonText().color() : WINUI3Colors[colorSchemeIndex][frameColorLight]);
+ painter->setBrush(Qt::NoBrush);
+
if (header->position == QStyleOptionHeader::OnlyOneSection) {
break;
}
@@ -1594,7 +1630,7 @@ void QWindows11Style::drawControl(ControlElement element, const QStyleOption *op
}
case QStyle::CE_ItemViewItem: {
if (const QStyleOptionViewItem *vopt = qstyleoption_cast<const QStyleOptionViewItem *>(option)) {
- if (const QAbstractItemView *view = qobject_cast<const QAbstractItemView *>(widget)) {
+ if (const QAbstractItemView *view = qobject_cast<const QAbstractItemView *>(widget)) {
QRect checkRect = proxy()->subElementRect(SE_ItemViewItemCheckIndicator, vopt, widget);
QRect iconRect = proxy()->subElementRect(SE_ItemViewItemDecoration, vopt, widget);
QRect textRect = proxy()->subElementRect(SE_ItemViewItemText, vopt, widget);
@@ -1617,11 +1653,11 @@ void QWindows11Style::drawControl(ControlElement element, const QStyleOption *op
}
painter->setPen(QPen(option->palette.buttonText().color()));
- bool isTreeView = widget && widget->inherits("QTreeView");
+ const bool isTreeView = qobject_cast<const QTreeView *>(widget);
if ((vopt->state & State_Selected || vopt->state & State_MouseOver) && !(isTreeView && vopt->state & State_MouseOver) && vopt->showDecorationSelected) {
painter->setBrush(WINUI3Colors[colorSchemeIndex][subtleHighlightColor]);
- QWidget *editorWidget = view->indexWidget(view->currentIndex());
+ QWidget *editorWidget = view ? view->indexWidget(view->currentIndex()) : nullptr;
if (editorWidget) {
QPalette pal = editorWidget->palette();
QColor editorBgColor = vopt->backgroundBrush == Qt::NoBrush ? vopt->palette.color(widget->backgroundRole()) : vopt->backgroundBrush.color();
@@ -1674,13 +1710,19 @@ void QWindows11Style::drawControl(ControlElement element, const QStyleOption *op
vopt->icon.paint(painter, iconRect, vopt->decorationAlignment, mode, state);
painter->setPen(QPen(option->palette.buttonText().color()));
- if (!view->isPersistentEditorOpen(vopt->index))
+ if (!view || !view->isPersistentEditorOpen(vopt->index))
d->viewItemDrawText(painter, vopt, textRect);
- if (vopt->state & State_Selected && (vopt->viewItemPosition == QStyleOptionViewItem::Beginning || vopt->viewItemPosition == QStyleOptionViewItem::OnlyOne || vopt->viewItemPosition == QStyleOptionViewItem::Invalid)) {
- if (widget && widget->inherits("QListView") && qobject_cast<const QListView*>(widget)->viewMode() != QListView::IconMode) {
+ if (vopt->state & State_Selected
+ && (vopt->viewItemPosition == QStyleOptionViewItem::Beginning
+ || vopt->viewItemPosition == QStyleOptionViewItem::OnlyOne
+ || vopt->viewItemPosition == QStyleOptionViewItem::Invalid)) {
+ if (const QListView *lv = qobject_cast<const QListView *>(widget);
+ lv && lv->viewMode() != QListView::IconMode) {
painter->setPen(QPen(vopt->palette.accent().color()));
- painter->drawLine(option->rect.x(),option->rect.y()+2,option->rect.x(),option->rect.y() + option->rect.height()-2);
- painter->drawLine(option->rect.x()+1,option->rect.y()+2,option->rect.x()+1,option->rect.y() + option->rect.height()-2);
+ painter->drawLine(option->rect.x(), option->rect.y() + 2,
+ option->rect.x(),option->rect.y() + option->rect.height() - 2);
+ painter->drawLine(option->rect.x() + 1, option->rect.y() + 2,
+ option->rect.x() + 1,option->rect.y() + option->rect.height() - 2);
}
}
}
@@ -1702,6 +1744,10 @@ int QWindows11Style::styleHint(StyleHint hint, const QStyleOption *opt,
return 0;
case QStyle::SH_ItemView_ShowDecorationSelected:
return 1;
+ case QStyle::SH_Slider_AbsoluteSetButtons:
+ return Qt::LeftButton;
+ case QStyle::SH_Slider_PageSetButtons:
+ return 0;
default:
return QWindowsVistaStyle::styleHint(hint, opt, widget, returnData);
}
@@ -1718,9 +1764,9 @@ QRect QWindows11Style::subElementRect(QStyle::SubElement element, const QStyleOp
case QStyle::SE_ItemViewItemText:
if (const auto *item = qstyleoption_cast<const QStyleOptionViewItem *>(option)) {
const int decorationOffset = item->features.testFlag(QStyleOptionViewItem::HasDecoration) ? item->decorationSize.width() : 0;
- if (widget && widget->parentWidget() &&
- widget->parentWidget()->inherits("QComboBoxPrivateContainer")) {
- ret = option->rect.adjusted(decorationOffset + 5, 0, -5, 0);
+ if (widget && widget->parentWidget()
+ && widget->parentWidget()->inherits("QComboBoxPrivateContainer")) {
+ ret = option->rect.adjusted(decorationOffset + 5, 0, -5, 0);
} else {
ret = QWindowsVistaStyle::subElementRect(element, option, widget);
}
@@ -1975,7 +2021,8 @@ int QWindows11Style::pixelMetric(PixelMetric metric, const QStyleOption *option,
void QWindows11Style::polish(QWidget* widget)
{
QWindowsVistaStyle::polish(widget);
- if (widget->inherits("QScrollBar") || widget->inherits("QComboBoxPrivateContainer") || widget->inherits("QMenu")) {
+ const bool isScrollBar = qobject_cast<QScrollBar *>(widget);
+ if (isScrollBar || qobject_cast<QMenu *>(widget) || widget->inherits("QComboBoxPrivateContainer")) {
bool wasCreated = widget->testAttribute(Qt::WA_WState_Created);
bool layoutDirection = widget->testAttribute(Qt::WA_RightToLeft);
widget->setAttribute(Qt::WA_OpaquePaintEvent,false);
@@ -1987,37 +2034,36 @@ void QWindows11Style::polish(QWidget* widget)
auto pal = widget->palette();
pal.setColor(widget->backgroundRole(), Qt::transparent);
widget->setPalette(pal);
- }
- if (widget->inherits("QComboBoxPrivateContainer") || widget->inherits("QMenu")) {
- QGraphicsDropShadowEffect* dropshadow = new QGraphicsDropShadowEffect(widget);
- dropshadow->setBlurRadius(3);
- dropshadow->setXOffset(3);
- dropshadow->setYOffset(3);
- widget->setGraphicsEffect(dropshadow);
- }
- if (widget->inherits("QComboBox")) {
-
- QComboBox* cb = qobject_cast<QComboBox*>(widget);
+ if (!isScrollBar) { // for menus and combobox containers...
+ QGraphicsDropShadowEffect* dropshadow = new QGraphicsDropShadowEffect(widget);
+ dropshadow->setBlurRadius(3);
+ dropshadow->setXOffset(3);
+ dropshadow->setYOffset(3);
+ widget->setGraphicsEffect(dropshadow);
+ }
+ } else if (QComboBox* cb = qobject_cast<QComboBox*>(widget)) {
if (cb->isEditable()) {
QLineEdit *le = cb->lineEdit();
le->setFrame(false);
}
- }
- if (widget->inherits("QGraphicsView") && !widget->inherits("QTextEdit")) {
+ } else if (widget->inherits("QAbstractButton") || widget->inherits("QToolButton")) {
+ widget->setAutoFillBackground(false);
+ } else if (qobject_cast<QGraphicsView *>(widget) && !qobject_cast<QTextEdit *>(widget)) {
QPalette pal = widget->palette();
pal.setColor(QPalette::Base, pal.window().color());
widget->setPalette(pal);
- }
- else if (widget->inherits("QAbstractScrollArea") && !widget->inherits("QMdiArea")) {
- if (const auto *scrollarea = qobject_cast<QAbstractScrollArea *>(widget)) {
- QPalette pal = widget->palette();
- QColor backgroundColor = widget->palette().base().color();
- backgroundColor.setAlpha(255);
- pal.setColor(scrollarea->viewport()->backgroundRole(), backgroundColor);
- scrollarea->viewport()->setPalette(pal);
- }
- }
- if (widget->inherits("QCommandLinkButton")) {
+ } else if (const auto *scrollarea = qobject_cast<QAbstractScrollArea *>(widget);
+ scrollarea
+#if QT_CONFIG(mdiarea)
+ && !qobject_cast<QMdiArea *>(widget)
+#endif
+ ) {
+ QPalette pal = scrollarea->viewport()->palette();
+ const QPalette originalPalette = pal;
+ pal.setColor(scrollarea->viewport()->backgroundRole(), Qt::transparent);
+ scrollarea->viewport()->setPalette(pal);
+ scrollarea->viewport()->setProperty("_q_original_background_palette", originalPalette);
+ } else if (qobject_cast<QCommandLinkButton *>(widget)) {
widget->setProperty("_qt_usingVistaStyle",false);
QPalette pal = widget->palette();
pal.setColor(QPalette::ButtonText, pal.text().color());
@@ -2026,53 +2072,54 @@ void QWindows11Style::polish(QWidget* widget)
}
}
+void QWindows11Style::unpolish(QWidget *widget)
+{
+ QWindowsVistaStyle::unpolish(widget);
+ if (const auto *scrollarea = qobject_cast<QAbstractScrollArea *>(widget);
+ scrollarea
+#if QT_CONFIG(mdiarea)
+ && !qobject_cast<QMdiArea *>(widget)
+#endif
+ ) {
+ const QPalette pal = scrollarea->viewport()->property("_q_original_background_palette").value<QPalette>();
+ scrollarea->viewport()->setPalette(pal);
+ scrollarea->viewport()->setProperty("_q_original_background_palette", QVariant());
+ }
+}
/*
The colors for Windows 11 are taken from the official WinUI3 Figma style at
https://www.figma.com/community/file/1159947337437047524
*/
+#define SET_IF_UNRESOLVED(GROUP, ROLE, VALUE) \
+ if (!result.isBrushSet(QPalette::Inactive, ROLE) || styleSheetChanged) \
+ result.setColor(GROUP, ROLE, VALUE)
+
static void populateLightSystemBasePalette(QPalette &result)
{
static QString oldStyleSheet;
const bool styleSheetChanged = oldStyleSheet != qApp->styleSheet();
- QPalette standardPalette = QApplication::palette();
const QColor textColor = QColor(0x00,0x00,0x00,0xE4);
-
const QColor btnFace = QColor(0xFF,0xFF,0xFF,0xB3);
const QColor btnHighlight = result.accent().color();
const QColor btnColor = result.button().color();
- if (standardPalette.color(QPalette::Highlight) == result.color(QPalette::Highlight) || styleSheetChanged)
- result.setColor(QPalette::Highlight, btnHighlight);
- if (standardPalette.color(QPalette::WindowText) == result.color(QPalette::WindowText) || styleSheetChanged)
- result.setColor(QPalette::WindowText, textColor);
- if (standardPalette.color(QPalette::Button) == result.color(QPalette::Button) || styleSheetChanged)
- result.setColor(QPalette::Button, btnFace);
- if (standardPalette.color(QPalette::Light) == result.color(QPalette::Light) || styleSheetChanged)
- result.setColor(QPalette::Light, btnColor.lighter(150));
- if (standardPalette.color(QPalette::Dark) == result.color(QPalette::Dark) || styleSheetChanged)
- result.setColor(QPalette::Dark, btnColor.darker(200));
- if (standardPalette.color(QPalette::Mid) == result.color(QPalette::Mid) || styleSheetChanged)
- result.setColor(QPalette::Mid, btnColor.darker(150));
- if (standardPalette.color(QPalette::Text) == result.color(QPalette::Text) || styleSheetChanged)
- result.setColor(QPalette::Text, textColor);
- if (standardPalette.color(QPalette::BrightText) != result.color(QPalette::BrightText) || styleSheetChanged)
- result.setColor(QPalette::BrightText, btnHighlight);
- if (standardPalette.color(QPalette::Base) == result.color(QPalette::Base) || styleSheetChanged)
- result.setColor(QPalette::Base, btnFace);
- if (standardPalette.color(QPalette::Window) == result.color(QPalette::Window) || styleSheetChanged)
- result.setColor(QPalette::Window, QColor(0xF3,0xF3,0xF3,0xFF));
- if (standardPalette.color(QPalette::ButtonText) == result.color(QPalette::ButtonText) || styleSheetChanged)
- result.setColor(QPalette::ButtonText, textColor);
- if (standardPalette.color(QPalette::Midlight) == result.color(QPalette::Midlight) || styleSheetChanged)
- result.setColor(QPalette::Midlight, btnColor.lighter(125));
- if (standardPalette.color(QPalette::Shadow) == result.color(QPalette::Shadow) || styleSheetChanged)
- result.setColor(QPalette::Shadow, Qt::black);
- if (standardPalette.color(QPalette::ToolTipBase) == result.color(QPalette::ToolTipBase) || styleSheetChanged)
- result.setColor(QPalette::ToolTipBase, result.window().color());
- if (standardPalette.color(QPalette::ToolTipText) == result.color(QPalette::ToolTipText) || styleSheetChanged)
- result.setColor(QPalette::ToolTipText, result.windowText().color());
+ SET_IF_UNRESOLVED(QPalette::All, QPalette::Highlight, btnHighlight);
+ SET_IF_UNRESOLVED(QPalette::All, QPalette::WindowText, textColor);
+ SET_IF_UNRESOLVED(QPalette::All, QPalette::Button, btnFace);
+ SET_IF_UNRESOLVED(QPalette::All, QPalette::Light, btnColor.lighter(150));
+ SET_IF_UNRESOLVED(QPalette::All, QPalette::Dark, btnColor.darker(200));
+ SET_IF_UNRESOLVED(QPalette::All, QPalette::Mid, btnColor.darker(150));
+ SET_IF_UNRESOLVED(QPalette::All, QPalette::Text, textColor);
+ SET_IF_UNRESOLVED(QPalette::All, QPalette::BrightText, btnHighlight);
+ SET_IF_UNRESOLVED(QPalette::All, QPalette::Base, btnFace);
+ SET_IF_UNRESOLVED(QPalette::All, QPalette::Window, QColor(0xF3,0xF3,0xF3,0xFF));
+ SET_IF_UNRESOLVED(QPalette::All, QPalette::ButtonText, textColor);
+ SET_IF_UNRESOLVED(QPalette::All, QPalette::Midlight, btnColor.lighter(125));
+ SET_IF_UNRESOLVED(QPalette::All, QPalette::Shadow, Qt::black);
+ SET_IF_UNRESOLVED(QPalette::All, QPalette::ToolTipBase, result.window().color());
+ SET_IF_UNRESOLVED(QPalette::All, QPalette::ToolTipText, result.windowText().color());
if (result.midlight() == result.button())
result.setColor(QPalette::Midlight, btnColor.lighter(110));
@@ -2082,35 +2129,30 @@ static void populateLightSystemBasePalette(QPalette &result)
/*!
\internal
*/
-void QWindows11Style::polish(QPalette& pal)
+void QWindows11Style::polish(QPalette& result)
{
- highContrastTheme = QGuiApplicationPrivate::colorScheme() == Qt::ColorScheme::Unknown;
- colorSchemeIndex = QGuiApplicationPrivate::colorScheme() == Qt::ColorScheme::Light ? 0 : 1;
+ highContrastTheme = QGuiApplication::styleHints()->colorScheme() == Qt::ColorScheme::Unknown;
+ colorSchemeIndex = QGuiApplication::styleHints()->colorScheme() == Qt::ColorScheme::Light ? 0 : 1;
if (!highContrastTheme && colorSchemeIndex == 0)
- populateLightSystemBasePalette(pal);
-
- if (standardPalette().color(QPalette::Inactive, QPalette::Button) == pal.color(QPalette::Inactive, QPalette::Button))
- pal.setColor(QPalette::Inactive, QPalette::Button, pal.button().color());
- if (standardPalette().color(QPalette::Inactive, QPalette::Window) == pal.color(QPalette::Inactive, QPalette::Window))
- pal.setColor(QPalette::Inactive, QPalette::Window, pal.window().color());
- if (standardPalette().color(QPalette::Inactive, QPalette::Light) == pal.color(QPalette::Inactive, QPalette::Light))
- pal.setColor(QPalette::Inactive, QPalette::Light, pal.light().color());
- if (standardPalette().color(QPalette::Inactive, QPalette::Dark) == pal.color(QPalette::Inactive, QPalette::Dark))
- pal.setColor(QPalette::Inactive, QPalette::Dark, pal.dark().color());
- if (standardPalette().color(QPalette::Inactive, QPalette::Accent) == pal.color(QPalette::Inactive, QPalette::Accent))
- pal.setColor(QPalette::Inactive, QPalette::Accent, pal.accent().color());
- if (standardPalette().color(QPalette::Inactive, QPalette::Highlight) == pal.color(QPalette::Inactive, QPalette::Highlight))
- pal.setColor(QPalette::Inactive, QPalette::Highlight, pal.highlight().color());
- if (standardPalette().color(QPalette::Inactive, QPalette::HighlightedText) == pal.color(QPalette::Inactive, QPalette::HighlightedText))
- pal.setColor(QPalette::Inactive, QPalette::HighlightedText, pal.highlightedText().color());
- if (standardPalette().color(QPalette::Inactive, QPalette::Text) == pal.color(QPalette::Inactive, QPalette::Text))
- pal.setColor(QPalette::Inactive, QPalette::Text, pal.text().color());
- if (standardPalette().color(QPalette::Inactive, QPalette::WindowText) == pal.color(QPalette::Inactive, QPalette::WindowText))
- pal.setColor(QPalette::Inactive, QPalette::WindowText, pal.windowText().color());
+ populateLightSystemBasePalette(result);
+
+ const bool styleSheetChanged = false; // so the macro works
+
+ SET_IF_UNRESOLVED(QPalette::Inactive, QPalette::Button, result.button().color());
+ SET_IF_UNRESOLVED(QPalette::Inactive, QPalette::Window, result.window().color());
+ SET_IF_UNRESOLVED(QPalette::Inactive, QPalette::Light, result.light().color());
+ SET_IF_UNRESOLVED(QPalette::Inactive, QPalette::Dark, result.dark().color());
+ SET_IF_UNRESOLVED(QPalette::Inactive, QPalette::Accent, result.accent().color());
+ SET_IF_UNRESOLVED(QPalette::Inactive, QPalette::Highlight, result.highlight().color());
+ SET_IF_UNRESOLVED(QPalette::Inactive, QPalette::HighlightedText, result.highlightedText().color());
+ SET_IF_UNRESOLVED(QPalette::Inactive, QPalette::Text, result.text().color());
+ SET_IF_UNRESOLVED(QPalette::Inactive, QPalette::WindowText, result.windowText().color());
if (highContrastTheme)
- pal.setColor(QPalette::Active, QPalette::HighlightedText, pal.windowText().color());
+ result.setColor(QPalette::Active, QPalette::HighlightedText, result.windowText().color());
}
+#undef SET_IF_UNRESOLVED
+
QT_END_NAMESPACE
diff --git a/src/plugins/styles/modernwindows/qwindows11style_p.h b/src/plugins/styles/modernwindows/qwindows11style_p.h
index 90e368f1ea..9c54afd967 100644
--- a/src/plugins/styles/modernwindows/qwindows11style_p.h
+++ b/src/plugins/styles/modernwindows/qwindows11style_p.h
@@ -48,6 +48,7 @@ public:
int pixelMetric(PixelMetric metric, const QStyleOption *option = nullptr,
const QWidget *widget = nullptr) const override;
void polish(QPalette &pal) override;
+ void unpolish(QWidget *widget) override;
protected:
QWindows11Style(QWindows11StylePrivate &dd);
private:
diff --git a/src/plugins/styles/modernwindows/qwindowsvistastyle.cpp b/src/plugins/styles/modernwindows/qwindowsvistastyle.cpp
index 1df134b629..beee1d6f31 100644
--- a/src/plugins/styles/modernwindows/qwindowsvistastyle.cpp
+++ b/src/plugins/styles/modernwindows/qwindowsvistastyle.cpp
@@ -4755,7 +4755,7 @@ void QWindowsVistaStyle::polish(QPalette &pal)
{
Q_D(QWindowsVistaStyle);
- if (QGuiApplicationPrivate::colorScheme() == Qt::ColorScheme::Dark) {
+ if (QGuiApplication::styleHints()->colorScheme() == Qt::ColorScheme::Dark) {
// System runs in dark mode, but the Vista style cannot use a dark palette.
// Overwrite with the light system palette.
using QWindowsApplication = QNativeInterface::Private::QWindowsApplication;