summaryrefslogtreecommitdiffstats
path: root/src/plugins
diff options
context:
space:
mode:
Diffstat (limited to 'src/plugins')
-rw-r--r--src/plugins/bearer/networkmanager/qnetworkmanagerengine.cpp2
-rw-r--r--src/plugins/bearer/networkmanager/qnetworkmanagerservice.cpp16
-rw-r--r--src/plugins/bearer/qnetworksession_impl.cpp6
-rw-r--r--src/plugins/generic/tuiotouch/qtuiohandler.cpp40
-rw-r--r--src/plugins/imageformats/gif/main.cpp2
-rw-r--r--src/plugins/imageformats/gif/qgifhandler.cpp19
-rw-r--r--src/plugins/imageformats/gif/qgifhandler_p.h4
-rw-r--r--src/plugins/imageformats/ico/main.cpp4
-rw-r--r--src/plugins/imageformats/ico/qicohandler.cpp24
-rw-r--r--src/plugins/imageformats/ico/qicohandler.h4
-rw-r--r--src/plugins/imageformats/jpeg/main.cpp4
-rw-r--r--src/plugins/imageformats/jpeg/qjpeghandler.cpp50
-rw-r--r--src/plugins/imageformats/jpeg/qjpeghandler_p.h4
-rw-r--r--src/plugins/platforminputcontexts/ibus/qibusplatforminputcontext.cpp4
-rw-r--r--src/plugins/platforminputcontexts/ibus/qibusplatforminputcontext.h2
-rw-r--r--src/plugins/platforminputcontexts/ibus/qibusproxy.cpp4
-rw-r--r--src/plugins/platforminputcontexts/ibus/qibustypes.cpp6
-rw-r--r--src/plugins/platforms/android/androidcontentfileengine.cpp47
-rw-r--r--src/plugins/platforms/android/androidcontentfileengine.h6
-rw-r--r--src/plugins/platforms/android/qandroidplatformfiledialoghelper.cpp176
-rw-r--r--src/plugins/platforms/android/qandroidplatformfiledialoghelper.h36
-rw-r--r--src/plugins/platforms/android/qandroidplatformintegration.cpp13
-rw-r--r--src/plugins/platforms/android/qandroidplatformintegration.h4
-rw-r--r--src/plugins/platforms/android/qandroidplatformservices.cpp15
-rw-r--r--src/plugins/platforms/cocoa/cocoa.pro5
-rw-r--r--src/plugins/platforms/cocoa/qcocoaapplicationdelegate.mm20
-rw-r--r--src/plugins/platforms/cocoa/qcocoaclipboard.mm2
-rw-r--r--src/plugins/platforms/cocoa/qcocoacursor.mm20
-rw-r--r--src/plugins/platforms/cocoa/qcocoadrag.mm11
-rw-r--r--src/plugins/platforms/cocoa/qcocoaeventdispatcher.h1
-rw-r--r--src/plugins/platforms/cocoa/qcocoaeventdispatcher.mm94
-rw-r--r--src/plugins/platforms/cocoa/qcocoafiledialoghelper.mm61
-rw-r--r--src/plugins/platforms/cocoa/qcocoaglcontext.mm2
-rw-r--r--src/plugins/platforms/cocoa/qcocoaintegration.h4
-rw-r--r--src/plugins/platforms/cocoa/qcocoaintegration.mm19
-rw-r--r--src/plugins/platforms/cocoa/qcocoamenu.mm2
-rw-r--r--src/plugins/platforms/cocoa/qcocoamenuitem.mm8
-rw-r--r--src/plugins/platforms/cocoa/qcocoanativeinterface.mm2
-rw-r--r--src/plugins/platforms/cocoa/qcocoasessionmanager.cpp88
-rw-r--r--src/plugins/platforms/cocoa/qcocoasessionmanager.h81
-rw-r--r--src/plugins/platforms/cocoa/qcocoasystemtrayicon.h23
-rw-r--r--src/plugins/platforms/cocoa/qcocoasystemtrayicon.mm291
-rw-r--r--src/plugins/platforms/cocoa/qcocoatheme.h2
-rw-r--r--src/plugins/platforms/cocoa/qcocoavulkaninstance.h6
-rw-r--r--src/plugins/platforms/cocoa/qcocoavulkaninstance.mm9
-rw-r--r--src/plugins/platforms/cocoa/qcocoawindow.h2
-rw-r--r--src/plugins/platforms/cocoa/qcocoawindow.mm33
-rw-r--r--src/plugins/platforms/cocoa/qmacclipboard.mm8
-rw-r--r--src/plugins/platforms/cocoa/qnsview_dragging.mm4
-rw-r--r--src/plugins/platforms/cocoa/qnsview_menus.mm3
-rw-r--r--src/plugins/platforms/cocoa/qpaintengine_mac.mm21
-rw-r--r--src/plugins/platforms/eglfs/api/api.pri9
-rw-r--r--src/plugins/platforms/eglfs/api/qeglfscontext.cpp4
-rw-r--r--src/plugins/platforms/eglfs/api/qeglfscursor.cpp2
-rw-r--r--src/plugins/platforms/eglfs/api/qeglfsdeviceintegration.cpp20
-rw-r--r--src/plugins/platforms/eglfs/api/qeglfsdeviceintegration_p.h4
-rw-r--r--src/plugins/platforms/eglfs/api/qeglfsintegration.cpp39
-rw-r--r--src/plugins/platforms/eglfs/api/qeglfsintegration_p.h3
-rw-r--r--src/plugins/platforms/eglfs/api/qeglfsoffscreenwindow.cpp2
-rw-r--r--src/plugins/platforms/eglfs/api/qeglfsscreen.cpp4
-rw-r--r--src/plugins/platforms/eglfs/api/qeglfswindow.cpp13
-rw-r--r--src/plugins/platforms/eglfs/api/qeglfswindow_p.h4
-rw-r--r--src/plugins/platforms/eglfs/api/vulkan/qeglfsvulkaninstance.cpp280
-rw-r--r--src/plugins/platforms/eglfs/api/vulkan/qeglfsvulkaninstance_p.h88
-rw-r--r--src/plugins/platforms/eglfs/api/vulkan/qeglfsvulkanwindow.cpp75
-rw-r--r--src/plugins/platforms/eglfs/api/vulkan/qeglfsvulkanwindow_p.h74
-rw-r--r--src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmcursor.cpp48
-rw-r--r--src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmcursor.h2
-rw-r--r--src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmdevice.cpp14
-rw-r--r--src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmdevice.h4
-rw-r--r--src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmintegration.cpp2
-rw-r--r--src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmscreen.cpp44
-rw-r--r--src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmscreen.h16
-rw-r--r--src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldevicescreen.cpp2
-rw-r--r--src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldevicescreen.h2
-rw-r--r--src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/eglfs_kms_support.pro6
-rw-r--r--src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmsdevice.h6
-rw-r--r--src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmseventreader.cpp218
-rw-r--r--src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmseventreader.h99
-rw-r--r--src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmsintegration.cpp2
-rw-r--r--src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmsscreen.cpp4
-rw-r--r--src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmsscreen.h11
-rw-r--r--src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_vsp2/qeglfskmsvsp2screen.cpp2
-rw-r--r--src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_vsp2/qeglfskmsvsp2screen.h2
-rw-r--r--src/plugins/platforms/eglfs/deviceintegration/eglfs_viv/qeglfsvivintegration.cpp21
-rw-r--r--src/plugins/platforms/eglfs/deviceintegration/eglfs_viv/qeglfsvivintegration.h6
-rw-r--r--src/plugins/platforms/eglfs/deviceintegration/eglfs_x11/qeglfsx11integration.cpp16
-rw-r--r--src/plugins/platforms/eglfs/deviceintegration/eglfs_x11/qeglfsx11integration.h2
-rw-r--r--src/plugins/platforms/eglfs/eglfsdeviceintegration.pro3
-rw-r--r--src/plugins/platforms/eglfs/qeglfsmain.cpp2
-rw-r--r--src/plugins/platforms/ios/kernel.pro6
-rw-r--r--src/plugins/platforms/ios/optional/nsphotolibrarysupport/qiosfileengineassetslibrary.mm2
-rw-r--r--src/plugins/platforms/ios/qiosdocumentpickercontroller.h46
-rw-r--r--src/plugins/platforms/ios/qiosdocumentpickercontroller.mm103
-rw-r--r--src/plugins/platforms/ios/qiosfiledialog.h3
-rw-r--r--src/plugins/platforms/ios/qiosfiledialog.mm30
-rw-r--r--src/plugins/platforms/ios/qioswindow.mm11
-rw-r--r--src/plugins/platforms/ios/quiview.h4
-rw-r--r--src/plugins/platforms/ios/quiview.mm35
-rw-r--r--src/plugins/platforms/offscreen/main.cpp2
-rw-r--r--src/plugins/platforms/offscreen/qoffscreencommon.cpp10
-rw-r--r--src/plugins/platforms/offscreen/qoffscreenintegration.cpp2
-rw-r--r--src/plugins/platforms/offscreen/qoffscreenintegration_x11.cpp12
-rw-r--r--src/plugins/platforms/offscreen/qoffscreenwindow.cpp2
-rw-r--r--src/plugins/platforms/platforms.pro4
-rw-r--r--src/plugins/platforms/qnx/qqnxglcontext.cpp27
-rw-r--r--src/plugins/platforms/qnx/qqnxglcontext.h7
-rw-r--r--src/plugins/platforms/qnx/qqnxintegration.cpp37
-rw-r--r--src/plugins/platforms/qnx/qqnxintegration.h13
-rw-r--r--src/plugins/platforms/qnx/qqnxnativeinterface.cpp5
-rw-r--r--src/plugins/platforms/qnx/qqnxscreeneventhandler.cpp2
-rw-r--r--src/plugins/platforms/vnc/main.cpp2
-rw-r--r--src/plugins/platforms/vnc/qvnc.cpp4
-rw-r--r--src/plugins/platforms/vnc/qvncclient.cpp3
-rw-r--r--src/plugins/platforms/vnc/qvncscreen.cpp2
-rw-r--r--src/plugins/platforms/wasm/qwasmclipboard.cpp5
-rw-r--r--src/plugins/platforms/wasm/qwasmclipboard.h3
-rw-r--r--src/plugins/platforms/wasm/qwasmcursor.cpp4
-rw-r--r--src/plugins/platforms/wasm/qwasmeventdispatcher.cpp1
-rw-r--r--src/plugins/platforms/wasm/qwasmeventtranslator.cpp4
-rw-r--r--src/plugins/platforms/wasm/qwasmintegration.cpp58
-rw-r--r--src/plugins/platforms/wasm/qwasmintegration.h10
-rw-r--r--src/plugins/platforms/wasm/qwasmopenglcontext.cpp2
-rw-r--r--src/plugins/platforms/wasm/qwasmscreen.cpp29
-rw-r--r--src/plugins/platforms/wasm/qwasmscreen.h7
-rw-r--r--src/plugins/platforms/wasm/qwasmwindow.cpp5
-rw-r--r--src/plugins/platforms/windows/qwindowsclipboard.cpp6
-rw-r--r--src/plugins/platforms/windows/qwindowscontext.cpp56
-rw-r--r--src/plugins/platforms/windows/qwindowscontext.h3
-rw-r--r--src/plugins/platforms/windows/qwindowscursor.cpp14
-rw-r--r--src/plugins/platforms/windows/qwindowsdialoghelpers.cpp64
-rw-r--r--src/plugins/platforms/windows/qwindowsdropdataobject.cpp2
-rw-r--r--src/plugins/platforms/windows/qwindowseglcontext.cpp2
-rw-r--r--src/plugins/platforms/windows/qwindowsglcontext.cpp14
-rw-r--r--src/plugins/platforms/windows/qwindowsglcontext.h4
-rw-r--r--src/plugins/platforms/windows/qwindowsinputcontext.cpp3
-rw-r--r--src/plugins/platforms/windows/qwindowsintegration.cpp36
-rw-r--r--src/plugins/platforms/windows/qwindowsintegration.h4
-rw-r--r--src/plugins/platforms/windows/qwindowskeymapper.cpp6
-rw-r--r--src/plugins/platforms/windows/qwindowsmenu.cpp2
-rw-r--r--src/plugins/platforms/windows/qwindowsmime.cpp54
-rw-r--r--src/plugins/platforms/windows/qwindowsmime.h3
-rw-r--r--src/plugins/platforms/windows/qwindowsmousehandler.cpp4
-rw-r--r--src/plugins/platforms/windows/qwindowsnativeinterface.cpp12
-rw-r--r--src/plugins/platforms/windows/qwindowsnativeinterface.h8
-rw-r--r--src/plugins/platforms/windows/qwindowsopengltester.cpp4
-rw-r--r--src/plugins/platforms/windows/qwindowspointerhandler.cpp2
-rw-r--r--src/plugins/platforms/windows/qwindowsscreen.cpp8
-rw-r--r--src/plugins/platforms/windows/qwindowsscreen.h2
-rw-r--r--src/plugins/platforms/windows/qwindowsservices.cpp6
-rw-r--r--src/plugins/platforms/windows/qwindowssystemtrayicon.cpp4
-rw-r--r--src/plugins/platforms/windows/qwindowstheme.cpp152
-rw-r--r--src/plugins/platforms/windows/qwindowstheme.h6
-rw-r--r--src/plugins/platforms/windows/qwindowswindow.cpp90
-rw-r--r--src/plugins/platforms/windows/qwindowswindow.h7
-rw-r--r--src/plugins/platforms/windows/uiautomation/qwindowsuiamainprovider.cpp38
-rw-r--r--src/plugins/platforms/windows/uiautomation/qwindowsuiaselectionprovider.cpp3
-rw-r--r--src/plugins/platforms/windows/uiautomation/qwindowsuiatableitemprovider.cpp4
-rw-r--r--src/plugins/platforms/windows/uiautomation/qwindowsuiautils.cpp2
-rw-r--r--src/plugins/platforms/winrt/qwinrtfiledialoghelper.cpp10
-rw-r--r--src/plugins/platforms/xcb/gl_integrations/xcb_egl/qxcbeglcontext.h2
-rw-r--r--src/plugins/platforms/xcb/gl_integrations/xcb_egl/qxcbeglwindow.cpp2
-rw-r--r--src/plugins/platforms/xcb/gl_integrations/xcb_glx/qglxintegration.cpp54
-rw-r--r--src/plugins/platforms/xcb/gl_integrations/xcb_glx/qxcbglxintegration.cpp4
-rw-r--r--src/plugins/platforms/xcb/qxcbatom.cpp2
-rw-r--r--src/plugins/platforms/xcb/qxcbbackingstore.cpp12
-rw-r--r--src/plugins/platforms/xcb/qxcbclipboard.cpp25
-rw-r--r--src/plugins/platforms/xcb/qxcbconnection.cpp44
-rw-r--r--src/plugins/platforms/xcb/qxcbconnection.h22
-rw-r--r--src/plugins/platforms/xcb/qxcbconnection_basic.cpp23
-rw-r--r--src/plugins/platforms/xcb/qxcbconnection_basic.h6
-rw-r--r--src/plugins/platforms/xcb/qxcbconnection_xi2.cpp21
-rw-r--r--src/plugins/platforms/xcb/qxcbcursor.cpp36
-rw-r--r--src/plugins/platforms/xcb/qxcbdrag.cpp28
-rw-r--r--src/plugins/platforms/xcb/qxcbdrag.h4
-rw-r--r--src/plugins/platforms/xcb/qxcbimage.cpp8
-rw-r--r--src/plugins/platforms/xcb/qxcbintegration.cpp4
-rw-r--r--src/plugins/platforms/xcb/qxcbkeyboard.cpp29
-rw-r--r--src/plugins/platforms/xcb/qxcbkeyboard.h20
-rw-r--r--src/plugins/platforms/xcb/qxcbmime.cpp8
-rw-r--r--src/plugins/platforms/xcb/qxcbmime.h4
-rw-r--r--src/plugins/platforms/xcb/qxcbnativeinterface.cpp10
-rw-r--r--src/plugins/platforms/xcb/qxcbscreen.cpp8
-rw-r--r--src/plugins/platforms/xcb/qxcbsessionmanager.cpp24
-rw-r--r--src/plugins/platforms/xcb/qxcbsystemtraytracker.cpp4
-rw-r--r--src/plugins/platforms/xcb/qxcbvulkaninstance.cpp2
-rw-r--r--src/plugins/platforms/xcb/qxcbvulkanwindow.cpp2
-rw-r--r--src/plugins/platforms/xcb/qxcbwindow.cpp113
-rw-r--r--src/plugins/platforms/xcb/qxcbwindow.h11
-rw-r--r--src/plugins/platforms/xcb/qxcbxsettings.cpp2
-rw-r--r--src/plugins/platforms/xcb/xcb-static/xcb-static.pro80
-rw-r--r--src/plugins/platforms/xcb/xcb.pro2
-rw-r--r--src/plugins/platforms/xcb/xcb_qpa_lib.pro30
-rw-r--r--src/plugins/platformthemes/gtk3/main.cpp2
-rw-r--r--src/plugins/platformthemes/gtk3/qgtk3dialoghelpers.cpp8
-rw-r--r--src/plugins/platformthemes/gtk3/qgtk3menu.cpp4
-rw-r--r--src/plugins/platformthemes/gtk3/qgtk3theme.cpp10
-rw-r--r--src/plugins/platformthemes/xdgdesktopportal/qxdgdesktopportalfiledialog.cpp2
-rw-r--r--src/plugins/platformthemes/xdgdesktopportal/qxdgdesktopportaltheme.h2
-rw-r--r--src/plugins/printsupport/cups/qcupsprintengine.cpp4
-rw-r--r--src/plugins/sqldrivers/configure.json2
-rw-r--r--src/plugins/sqldrivers/db2/qsql_db2.cpp2
-rw-r--r--src/plugins/sqldrivers/ibase/qsql_ibase.cpp11
-rw-r--r--src/plugins/sqldrivers/mysql/main.cpp4
-rw-r--r--src/plugins/sqldrivers/mysql/mysql.json2
-rw-r--r--src/plugins/sqldrivers/mysql/qsql_mysql.cpp330
-rw-r--r--src/plugins/sqldrivers/mysql/qsql_mysql_p.h4
-rw-r--r--src/plugins/sqldrivers/oci/qsql_oci.cpp2
-rw-r--r--src/plugins/sqldrivers/odbc/qsql_odbc.cpp86
-rw-r--r--src/plugins/sqldrivers/psql/qsql_psql.cpp53
-rw-r--r--src/plugins/sqldrivers/sqlite/qsql_sqlite.cpp32
-rw-r--r--src/plugins/sqldrivers/sqlite2/qsql_sqlite2_p.h4
-rw-r--r--src/plugins/sqldrivers/tds/qsql_tds_p.h4
-rw-r--r--src/plugins/styles/mac/qmacstyle_mac.mm88
-rw-r--r--src/plugins/styles/mac/qmacstyle_mac_p_p.h2
-rw-r--r--src/plugins/styles/windowsvista/qwindowsvistastyle.cpp11
-rw-r--r--src/plugins/styles/windowsvista/qwindowsvistastyle_p_p.h2
-rw-r--r--src/plugins/styles/windowsvista/qwindowsxpstyle.cpp277
-rw-r--r--src/plugins/styles/windowsvista/qwindowsxpstyle_p_p.h4
-rw-r--r--src/plugins/styles/windowsvista/windowsvista.pro4
220 files changed, 3288 insertions, 1920 deletions
diff --git a/src/plugins/bearer/networkmanager/qnetworkmanagerengine.cpp b/src/plugins/bearer/networkmanager/qnetworkmanagerengine.cpp
index e74b1cf744..85a9f9b9e0 100644
--- a/src/plugins/bearer/networkmanager/qnetworkmanagerengine.cpp
+++ b/src/plugins/bearer/networkmanager/qnetworkmanagerengine.cpp
@@ -250,7 +250,7 @@ void QNetworkManagerEngine::interfacePropertiesChanged(const QMap<QString, QVari
if (i.key() == QLatin1String("ActiveConnections")) {
// Active connections changed, update configurations.
- const auto activeConnections = qdbus_cast<QList<QDBusObjectPath> >(i.value().value<QDBusArgument>());
+ const auto activeConnections = qdbus_cast<QList<QDBusObjectPath> >(qvariant_cast<QDBusArgument>(i.value()));
QStringList identifiers = accessPointConfigurations.keys();
QStringList priorActiveConnections = activeConnectionsList.keys();
diff --git a/src/plugins/bearer/networkmanager/qnetworkmanagerservice.cpp b/src/plugins/bearer/networkmanager/qnetworkmanagerservice.cpp
index 35199eb7a2..2d6cba1791 100644
--- a/src/plugins/bearer/networkmanager/qnetworkmanagerservice.cpp
+++ b/src/plugins/bearer/networkmanager/qnetworkmanagerservice.cpp
@@ -193,7 +193,7 @@ QList <QDBusObjectPath> QNetworkManagerInterface::activeConnections() const
{
if (propertyMap.contains("ActiveConnections")) {
- const QDBusArgument &dbusArgs = propertyMap.value("ActiveConnections").value<QDBusArgument>();
+ const QDBusArgument &dbusArgs = qvariant_cast<QDBusArgument>(propertyMap.value("ActiveConnections"));
QDBusObjectPath path;
QList <QDBusObjectPath> list;
@@ -403,7 +403,7 @@ quint32 QNetworkManagerInterfaceDevice::deviceType() const
QDBusObjectPath QNetworkManagerInterfaceDevice::ip4config() const
{
if (propertyMap.contains("Ip4Config"))
- return propertyMap.value("Ip4Config").value<QDBusObjectPath>();
+ return qvariant_cast<QDBusObjectPath>(propertyMap.value("Ip4Config"));
return QDBusObjectPath();
}
@@ -411,7 +411,7 @@ void QNetworkManagerInterfaceDevice::propertiesSwap(QMap<QString,QVariant> map)
{
for (auto i = map.cbegin(), end = map.cend(); i != end; ++i) {
if (i.key() == QLatin1String("AvailableConnections")) { //Device
- const QDBusArgument &dbusArgs = i.value().value<QDBusArgument>();
+ const QDBusArgument &dbusArgs = qvariant_cast<QDBusArgument>(i.value());
QDBusObjectPath path;
QStringList paths;
dbusArgs.beginArray();
@@ -489,7 +489,7 @@ QStringList QNetworkManagerInterfaceDeviceWired::availableConnections()
{
QStringList list;
if (propertyMap.contains("AvailableConnections")) {
- const QDBusArgument &dbusArgs = propertyMap.value("Carrier").value<QDBusArgument>();
+ const QDBusArgument &dbusArgs = qvariant_cast<QDBusArgument>(propertyMap.value("Carrier"));
QDBusObjectPath path;
dbusArgs.beginArray();
while (!dbusArgs.atEnd()) {
@@ -598,7 +598,7 @@ quint32 QNetworkManagerInterfaceDeviceWireless::bitrate() const
QDBusObjectPath QNetworkManagerInterfaceDeviceWireless::activeAccessPoint() const
{
if (propertyMap.contains("ActiveAccessPoint"))
- return propertyMap.value("ActiveAccessPoint").value<QDBusObjectPath>();
+ return qvariant_cast<QDBusObjectPath>(propertyMap.value("ActiveAccessPoint"));
return QDBusObjectPath();
}
@@ -931,14 +931,14 @@ QNetworkManagerConnectionActive::~QNetworkManagerConnectionActive()
QDBusObjectPath QNetworkManagerConnectionActive::connection() const
{
if (propertyMap.contains("Connection"))
- return propertyMap.value("Connection").value<QDBusObjectPath>();
+ return qvariant_cast<QDBusObjectPath>(propertyMap.value("Connection"));
return QDBusObjectPath();
}
QDBusObjectPath QNetworkManagerConnectionActive::specificObject() const
{
if (propertyMap.contains("SpecificObject"))
- return propertyMap.value("SpecificObject").value<QDBusObjectPath>();
+ return qvariant_cast<QDBusObjectPath>(propertyMap.value("SpecificObject"));
return QDBusObjectPath();
}
@@ -946,7 +946,7 @@ QStringList QNetworkManagerConnectionActive::devices() const
{
QStringList list;
if (propertyMap.contains("Devices")) {
- const QDBusArgument &dbusArgs = propertyMap.value("Devices").value<QDBusArgument>();
+ const QDBusArgument &dbusArgs = qvariant_cast<QDBusArgument>(propertyMap.value("Devices"));
QDBusObjectPath path;
dbusArgs.beginArray();
diff --git a/src/plugins/bearer/qnetworksession_impl.cpp b/src/plugins/bearer/qnetworksession_impl.cpp
index c6b678ab20..8eba9ccc42 100644
--- a/src/plugins/bearer/qnetworksession_impl.cpp
+++ b/src/plugins/bearer/qnetworksession_impl.cpp
@@ -65,7 +65,7 @@ static QBearerEngineImpl *getEngineFromId(const QString &id)
}
}
- return 0;
+ return nullptr;
}
class QNetworkSessionManagerPrivate : public QObject
@@ -73,7 +73,7 @@ class QNetworkSessionManagerPrivate : public QObject
Q_OBJECT
public:
- QNetworkSessionManagerPrivate(QObject *parent = 0) : QObject(parent) {}
+ QNetworkSessionManagerPrivate(QObject *parent = nullptr) : QObject(parent) {}
~QNetworkSessionManagerPrivate() {}
inline void forceSessionClose(const QNetworkConfiguration &config)
@@ -119,7 +119,7 @@ void QNetworkSessionPrivateImpl::syncStateWithInterface()
// Defer setting serviceConfig and activeConfig until open().
Q_FALLTHROUGH();
default:
- engine = 0;
+ engine = nullptr;
}
networkConfigurationsChanged();
diff --git a/src/plugins/generic/tuiotouch/qtuiohandler.cpp b/src/plugins/generic/tuiotouch/qtuiohandler.cpp
index cb82672acd..6ad4597b19 100644
--- a/src/plugins/generic/tuiotouch/qtuiohandler.cpp
+++ b/src/plugins/generic/tuiotouch/qtuiohandler.cpp
@@ -226,7 +226,7 @@ void QTuioHandler::process2DCurSource(const QOscMessage &message)
return;
}
- if (QMetaType::Type(arguments.at(1).type()) != QMetaType::QByteArray) {
+ if (QMetaType::Type(arguments.at(1).userType()) != QMetaType::QByteArray) {
qCWarning(lcTuioSource, "Ignoring malformed TUIO source message (bad argument type)");
return;
}
@@ -248,7 +248,7 @@ void QTuioHandler::process2DCurAlive(const QOscMessage &message)
QMap<int, QTuioCursor> newActiveCursors;
for (int i = 1; i < arguments.count(); ++i) {
- if (QMetaType::Type(arguments.at(i).type()) != QMetaType::Int) {
+ if (QMetaType::Type(arguments.at(i).userType()) != QMetaType::Int) {
qCWarning(lcTuioHandler) << "Ignoring malformed TUIO alive message (bad argument on position" << i << arguments << ')';
return;
}
@@ -293,12 +293,12 @@ void QTuioHandler::process2DCurSet(const QOscMessage &message)
return;
}
- if (QMetaType::Type(arguments.at(1).type()) != QMetaType::Int ||
- QMetaType::Type(arguments.at(2).type()) != QMetaType::Float ||
- QMetaType::Type(arguments.at(3).type()) != QMetaType::Float ||
- QMetaType::Type(arguments.at(4).type()) != QMetaType::Float ||
- QMetaType::Type(arguments.at(5).type()) != QMetaType::Float ||
- QMetaType::Type(arguments.at(6).type()) != QMetaType::Float
+ if (QMetaType::Type(arguments.at(1).userType()) != QMetaType::Int ||
+ QMetaType::Type(arguments.at(2).userType()) != QMetaType::Float ||
+ QMetaType::Type(arguments.at(3).userType()) != QMetaType::Float ||
+ QMetaType::Type(arguments.at(4).userType()) != QMetaType::Float ||
+ QMetaType::Type(arguments.at(5).userType()) != QMetaType::Float ||
+ QMetaType::Type(arguments.at(6).userType()) != QMetaType::Float
) {
qCWarning(lcTuioSet) << "Ignoring malformed TUIO set message with bad types: " << arguments;
return;
@@ -391,7 +391,7 @@ void QTuioHandler::process2DObjSource(const QOscMessage &message)
return;
}
- if (QMetaType::Type(arguments.at(1).type()) != QMetaType::QByteArray) {
+ if (QMetaType::Type(arguments.at(1).userType()) != QMetaType::QByteArray) {
qCWarning(lcTuioSource, "Ignoring malformed TUIO source message (bad argument type)");
return;
}
@@ -413,7 +413,7 @@ void QTuioHandler::process2DObjAlive(const QOscMessage &message)
QMap<int, QTuioToken> newActiveTokens;
for (int i = 1; i < arguments.count(); ++i) {
- if (QMetaType::Type(arguments.at(i).type()) != QMetaType::Int) {
+ if (QMetaType::Type(arguments.at(i).userType()) != QMetaType::Int) {
qCWarning(lcTuioHandler) << "Ignoring malformed TUIO alive message (bad argument on position" << i << arguments << ')';
return;
}
@@ -458,16 +458,16 @@ void QTuioHandler::process2DObjSet(const QOscMessage &message)
return;
}
- if (QMetaType::Type(arguments.at(1).type()) != QMetaType::Int ||
- QMetaType::Type(arguments.at(2).type()) != QMetaType::Int ||
- QMetaType::Type(arguments.at(3).type()) != QMetaType::Float ||
- QMetaType::Type(arguments.at(4).type()) != QMetaType::Float ||
- QMetaType::Type(arguments.at(5).type()) != QMetaType::Float ||
- QMetaType::Type(arguments.at(6).type()) != QMetaType::Float ||
- QMetaType::Type(arguments.at(7).type()) != QMetaType::Float ||
- QMetaType::Type(arguments.at(8).type()) != QMetaType::Float ||
- QMetaType::Type(arguments.at(9).type()) != QMetaType::Float ||
- QMetaType::Type(arguments.at(10).type()) != QMetaType::Float) {
+ if (QMetaType::Type(arguments.at(1).userType()) != QMetaType::Int ||
+ QMetaType::Type(arguments.at(2).userType()) != QMetaType::Int ||
+ QMetaType::Type(arguments.at(3).userType()) != QMetaType::Float ||
+ QMetaType::Type(arguments.at(4).userType()) != QMetaType::Float ||
+ QMetaType::Type(arguments.at(5).userType()) != QMetaType::Float ||
+ QMetaType::Type(arguments.at(6).userType()) != QMetaType::Float ||
+ QMetaType::Type(arguments.at(7).userType()) != QMetaType::Float ||
+ QMetaType::Type(arguments.at(8).userType()) != QMetaType::Float ||
+ QMetaType::Type(arguments.at(9).userType()) != QMetaType::Float ||
+ QMetaType::Type(arguments.at(10).userType()) != QMetaType::Float) {
qCWarning(lcTuioSet) << "Ignoring malformed TUIO set message with bad types: " << arguments;
return;
}
diff --git a/src/plugins/imageformats/gif/main.cpp b/src/plugins/imageformats/gif/main.cpp
index c171111fac..993871420c 100644
--- a/src/plugins/imageformats/gif/main.cpp
+++ b/src/plugins/imageformats/gif/main.cpp
@@ -62,7 +62,7 @@ QImageIOPlugin::Capabilities QGifPlugin::capabilities(QIODevice *device, const Q
{
if (format == "gif" || (device && device->isReadable() && QGifHandler::canRead(device)))
return Capabilities(CanRead);
- return 0;
+ return { };
}
QImageIOHandler *QGifPlugin::create(QIODevice *device, const QByteArray &format) const
diff --git a/src/plugins/imageformats/gif/qgifhandler.cpp b/src/plugins/imageformats/gif/qgifhandler.cpp
index a6029b691c..61981b305f 100644
--- a/src/plugins/imageformats/gif/qgifhandler.cpp
+++ b/src/plugins/imageformats/gif/qgifhandler.cpp
@@ -147,8 +147,8 @@ private:
*/
QGIFFormat::QGIFFormat()
{
- globalcmap = 0;
- localcmap = 0;
+ globalcmap = nullptr;
+ localcmap = nullptr;
lncols = 0;
gncols = 0;
disposal = NoDisposal;
@@ -160,9 +160,9 @@ QGIFFormat::QGIFFormat()
lcmap = false;
newFrame = false;
partialNewFrame = false;
- table[0] = 0;
- table[1] = 0;
- stack = 0;
+ table[0] = nullptr;
+ table[1] = nullptr;
+ stack = nullptr;
}
/*!
@@ -550,7 +550,7 @@ int QGIFFormat::decode(QImage *image, const uchar *buffer, int length,
}
oldcode=incode;
const int h = image->height();
- QRgb *line = 0;
+ QRgb *line = nullptr;
if (!out_of_bounds && h > y)
line = (QRgb*)FAST_SCAN_LINE(bits, bpl, y);
while (sp>stack) {
@@ -1215,11 +1215,4 @@ int QGifHandler::currentImageNumber() const
return frameNumber;
}
-#if QT_DEPRECATED_SINCE(5, 13)
-QByteArray QGifHandler::name() const
-{
- return "gif";
-}
-#endif
-
QT_END_NAMESPACE
diff --git a/src/plugins/imageformats/gif/qgifhandler_p.h b/src/plugins/imageformats/gif/qgifhandler_p.h
index c6592043ce..f19777fa18 100644
--- a/src/plugins/imageformats/gif/qgifhandler_p.h
+++ b/src/plugins/imageformats/gif/qgifhandler_p.h
@@ -73,10 +73,6 @@ public:
bool read(QImage *image) override;
bool write(const QImage &image) override;
-#if QT_DEPRECATED_SINCE(5, 13)
- QByteArray name() const override;
-#endif
-
static bool canRead(QIODevice *device);
QVariant option(ImageOption option) const override;
diff --git a/src/plugins/imageformats/ico/main.cpp b/src/plugins/imageformats/ico/main.cpp
index baaf33e1fc..b00d8c7fd3 100644
--- a/src/plugins/imageformats/ico/main.cpp
+++ b/src/plugins/imageformats/ico/main.cpp
@@ -46,9 +46,9 @@ QImageIOPlugin::Capabilities QICOPlugin::capabilities(QIODevice *device, const Q
if (format == "ico" || format == "cur")
return Capabilities(CanRead | CanWrite);
if (!format.isEmpty())
- return 0;
+ return { };
if (!device->isOpen())
- return 0;
+ return { };
Capabilities cap;
if (device->isReadable() && QtIcoHandler::canRead(device))
diff --git a/src/plugins/imageformats/ico/qicohandler.cpp b/src/plugins/imageformats/ico/qicohandler.cpp
index c8e31dceac..88ff1f8391 100644
--- a/src/plugins/imageformats/ico/qicohandler.cpp
+++ b/src/plugins/imageformats/ico/qicohandler.cpp
@@ -535,8 +535,6 @@ QImage ICOReader::iconAt(int index)
if (!mask.isNull()) {
img = image;
img.setAlphaChannel(mask);
- // (Luckily, it seems that setAlphaChannel() does not ruin the alpha values
- // of partially transparent pixels in those icons that have that)
}
}
}
@@ -615,13 +613,7 @@ bool ICOReader::write(QIODevice *device, const QVector<QImage> &images)
}
QImage maskImage(image.width(), image.height(), QImage::Format_Mono);
image = image.convertToFormat(QImage::Format_ARGB32);
-
- if (image.hasAlphaChannel()) {
- maskImage = image.createAlphaMask();
- } else {
- maskImage.fill(0xff);
- }
- maskImage = maskImage.convertToFormat(QImage::Format_Mono);
+ maskImage.fill(Qt::color1);
int nbits = 32;
int bpl_bmp = ((image.width()*nbits+31)/32)*4;
@@ -671,7 +663,7 @@ bool ICOReader::write(QIODevice *device, const QVector<QImage> &images)
*b++ = qRed(*p);
*b++ = qAlpha(*p);
if (qAlpha(*p) > 0) // Even mostly transparent pixels must not be masked away
- maskImage.setPixel(x, y, Qt::color1); // (i.e. createAlphaMask() takes away too much)
+ maskImage.setPixel(x, y, 0);
p++;
x++;
}
@@ -679,7 +671,6 @@ bool ICOReader::write(QIODevice *device, const QVector<QImage> &images)
}
delete[] buf;
- maskImage.invertPixels(); // seems as though it needs this
// NOTE! !! The mask is only flipped vertically - not horizontally !!
for (y = maskImage.height() - 1; y >= 0; y--)
buffer.write((char*)maskImage.scanLine(y), maskImage.bytesPerLine());
@@ -818,17 +809,6 @@ bool QtIcoHandler::write(const QImage &image)
return ICOReader::write(device, imgs);
}
-#if QT_DEPRECATED_SINCE(5, 13)
-/*!
- * Return the common identifier of the format.
- * For ICO format this will return "ico".
- */
-QByteArray QtIcoHandler::name() const
-{
- return "ico";
-}
-#endif
-
/*! \reimp
*/
diff --git a/src/plugins/imageformats/ico/qicohandler.h b/src/plugins/imageformats/ico/qicohandler.h
index 328dfce47e..0d44a67dfc 100644
--- a/src/plugins/imageformats/ico/qicohandler.h
+++ b/src/plugins/imageformats/ico/qicohandler.h
@@ -54,10 +54,6 @@ public:
bool read(QImage *image) override;
bool write(const QImage &image) override;
-#if QT_DEPRECATED_SINCE(5, 13)
- QByteArray name() const override;
-#endif
-
int imageCount() const override;
bool jumpToImage(int imageNumber) override;
bool jumpToNextImage() override;
diff --git a/src/plugins/imageformats/jpeg/main.cpp b/src/plugins/imageformats/jpeg/main.cpp
index 58442053a1..83f13c4a9d 100644
--- a/src/plugins/imageformats/jpeg/main.cpp
+++ b/src/plugins/imageformats/jpeg/main.cpp
@@ -51,9 +51,9 @@ QImageIOPlugin::Capabilities QJpegPlugin::capabilities(QIODevice *device, const
if (format == "jpeg" || format == "jpg")
return Capabilities(CanRead | CanWrite);
if (!format.isEmpty())
- return 0;
+ return { };
if (!device->isOpen())
- return 0;
+ return { };
Capabilities cap;
if (device->isReadable() && QJpegHandler::canRead(device))
diff --git a/src/plugins/imageformats/jpeg/qjpeghandler.cpp b/src/plugins/imageformats/jpeg/qjpeghandler.cpp
index 1f1675e490..fed585a82e 100644
--- a/src/plugins/imageformats/jpeg/qjpeghandler.cpp
+++ b/src/plugins/imageformats/jpeg/qjpeghandler.cpp
@@ -248,13 +248,12 @@ static bool ensureValidImage(QImage *dest, struct jpeg_decompress_struct *info,
static bool read_jpeg_image(QImage *outImage,
QSize scaledSize, QRect scaledClipRect,
- QRect clipRect, volatile int inQuality,
+ QRect clipRect, int quality,
Rgb888ToRgb32Converter converter,
j_decompress_ptr info, struct my_error_mgr* err )
{
if (!setjmp(err->setjmp_buffer)) {
// -1 means default quality.
- int quality = inQuality;
if (quality < 0)
quality = 75;
@@ -529,7 +528,14 @@ static inline void write_icc_profile(const QImage &image, j_compress_ptr cinfo)
}
}
-static bool write_jpeg_image(const QImage &image, QIODevice *device, volatile int sourceQuality, const QString &description, bool optimize, bool progressive)
+static bool do_write_jpeg_image(struct jpeg_compress_struct &cinfo,
+ JSAMPROW *row_pointer,
+ const QImage &image,
+ QIODevice *device,
+ int sourceQuality,
+ const QString &description,
+ bool optimize,
+ bool progressive)
{
bool success = false;
const QVector<QRgb> cmap = image.colorTable();
@@ -537,10 +543,6 @@ static bool write_jpeg_image(const QImage &image, QIODevice *device, volatile in
if (image.format() == QImage::Format_Invalid || image.format() == QImage::Format_Alpha8)
return false;
- struct jpeg_compress_struct cinfo;
- JSAMPROW row_pointer[1];
- row_pointer[0] = 0;
-
struct my_jpeg_destination_mgr *iod_dest = new my_jpeg_destination_mgr(device);
struct my_error_mgr jerr;
@@ -713,6 +715,27 @@ static bool write_jpeg_image(const QImage &image, QIODevice *device, volatile in
}
delete iod_dest;
+ return success;
+}
+
+static bool write_jpeg_image(const QImage &image,
+ QIODevice *device,
+ int sourceQuality,
+ const QString &description,
+ bool optimize,
+ bool progressive)
+{
+ // protect these objects from the setjmp/longjmp pair inside
+ // do_write_jpeg_image (by making them non-local).
+ struct jpeg_compress_struct cinfo;
+ JSAMPROW row_pointer[1];
+ row_pointer[0] = nullptr;
+
+ const bool success = do_write_jpeg_image(cinfo, row_pointer,
+ image, device,
+ sourceQuality, description,
+ optimize, progressive);
+
delete [] row_pointer[0];
return success;
}
@@ -728,7 +751,7 @@ public:
};
QJpegHandlerPrivate(QJpegHandler *qq)
- : quality(75), transformation(QImageIOHandler::TransformationNone), iod_src(0),
+ : quality(75), transformation(QImageIOHandler::TransformationNone), iod_src(nullptr),
rgb888ToRgb32ConverterPtr(qt_convert_rgb888_to_rgb32), state(Ready), optimize(false), progressive(false), q(qq)
{}
@@ -738,7 +761,7 @@ public:
{
jpeg_destroy_decompress(&info);
delete iod_src;
- iod_src = 0;
+ iod_src = nullptr;
}
}
@@ -931,7 +954,7 @@ bool QJpegHandlerPrivate::readJpegHeader(QIODevice *device)
QByteArray exifData;
- for (jpeg_saved_marker_ptr marker = info.marker_list; marker != NULL; marker = marker->next) {
+ for (jpeg_saved_marker_ptr marker = info.marker_list; marker != nullptr; marker = marker->next) {
if (marker->marker == JPEG_COM) {
QString key, value;
QString s = QString::fromUtf8((const char *)marker->data, marker->data_length);
@@ -1161,11 +1184,4 @@ void QJpegHandler::setOption(ImageOption option, const QVariant &value)
}
}
-#if QT_DEPRECATED_SINCE(5, 13)
-QByteArray QJpegHandler::name() const
-{
- return "jpeg";
-}
-#endif
-
QT_END_NAMESPACE
diff --git a/src/plugins/imageformats/jpeg/qjpeghandler_p.h b/src/plugins/imageformats/jpeg/qjpeghandler_p.h
index fafa930c11..43ca17317a 100644
--- a/src/plugins/imageformats/jpeg/qjpeghandler_p.h
+++ b/src/plugins/imageformats/jpeg/qjpeghandler_p.h
@@ -68,10 +68,6 @@ public:
bool read(QImage *image) override;
bool write(const QImage &image) override;
-#if QT_DEPRECATED_SINCE(5, 13)
- QByteArray name() const override;
-#endif
-
static bool canRead(QIODevice *device);
QVariant option(ImageOption option) const override;
diff --git a/src/plugins/platforminputcontexts/ibus/qibusplatforminputcontext.cpp b/src/plugins/platforminputcontexts/ibus/qibusplatforminputcontext.cpp
index f2429f24ff..47ac54927b 100644
--- a/src/plugins/platforminputcontexts/ibus/qibusplatforminputcontext.cpp
+++ b/src/plugins/platforminputcontexts/ibus/qibusplatforminputcontext.cpp
@@ -285,7 +285,7 @@ void QIBusPlatformInputContext::commitText(const QDBusVariant &text)
if (!input)
return;
- const QDBusArgument arg = text.variant().value<QDBusArgument>();
+ const QDBusArgument arg = qvariant_cast<QDBusArgument>(text.variant());
QIBusText t;
if (debug)
@@ -311,7 +311,7 @@ void QIBusPlatformInputContext::updatePreeditText(const QDBusVariant &text, uint
if (!input)
return;
- const QDBusArgument arg = text.variant().value<QDBusArgument>();
+ const QDBusArgument arg = qvariant_cast<QDBusArgument>(text.variant());
QIBusText t;
arg >> t;
diff --git a/src/plugins/platforminputcontexts/ibus/qibusplatforminputcontext.h b/src/plugins/platforminputcontexts/ibus/qibusplatforminputcontext.h
index 8e7b8df120..e9c9c55f6a 100644
--- a/src/plugins/platforminputcontexts/ibus/qibusplatforminputcontext.h
+++ b/src/plugins/platforminputcontexts/ibus/qibusplatforminputcontext.h
@@ -61,7 +61,7 @@ public:
explicit QIBusFilterEventWatcher(const QDBusPendingCall &call,
QObject *parent = nullptr,
QWindow *window = nullptr,
- const Qt::KeyboardModifiers modifiers = nullptr,
+ const Qt::KeyboardModifiers modifiers = { },
const QVariantList arguments = QVariantList())
: QDBusPendingCallWatcher(call, parent)
, m_window(window)
diff --git a/src/plugins/platforminputcontexts/ibus/qibusproxy.cpp b/src/plugins/platforminputcontexts/ibus/qibusproxy.cpp
index 156e9b7c90..6b46e106ab 100644
--- a/src/plugins/platforminputcontexts/ibus/qibusproxy.cpp
+++ b/src/plugins/platforminputcontexts/ibus/qibusproxy.cpp
@@ -83,10 +83,10 @@ QIBusEngineDesc QIBusProxy::getGlobalEngine()
QVariant variant = reply.value().variant();
if (!variant.isValid())
return desc;
- QVariant child = variant.value<QDBusVariant>().variant();
+ QVariant child = qvariant_cast<QDBusVariant>(variant).variant();
if (!child.isValid())
return desc;
- const QDBusArgument argument = child.value<QDBusArgument>();
+ const QDBusArgument argument = qvariant_cast<QDBusArgument>(child);
argument >> desc;
return desc;
}
diff --git a/src/plugins/platforminputcontexts/ibus/qibustypes.cpp b/src/plugins/platforminputcontexts/ibus/qibustypes.cpp
index a2551f1320..443df271a8 100644
--- a/src/plugins/platforminputcontexts/ibus/qibustypes.cpp
+++ b/src/plugins/platforminputcontexts/ibus/qibustypes.cpp
@@ -62,7 +62,7 @@ void QIBusSerializable::deserializeFrom(const QDBusArgument &argument)
argument >> key;
argument >> value;
argument.endMapEntry();
- attachments[key] = value.variant().value<QDBusArgument>();
+ attachments[key] = qvariant_cast<QDBusArgument>(value.variant());
}
argument.endMap();
}
@@ -201,7 +201,7 @@ void QIBusAttributeList::deserializeFrom(const QDBusArgument &arg)
arg >> var;
QIBusAttribute attr;
- var.variant().value<QDBusArgument>() >> attr;
+ qvariant_cast<QDBusArgument>(var.variant()) >> attr;
attributes.append(std::move(attr));
}
arg.endArray();
@@ -268,7 +268,7 @@ void QIBusText::deserializeFrom(const QDBusArgument &argument)
argument >> text;
QDBusVariant variant;
argument >> variant;
- variant.variant().value<QDBusArgument>() >> attributes;
+ qvariant_cast<QDBusArgument>(variant.variant()) >> attributes;
argument.endStructure();
}
diff --git a/src/plugins/platforms/android/androidcontentfileengine.cpp b/src/plugins/platforms/android/androidcontentfileengine.cpp
index 1444407195..3e3bdc2592 100644
--- a/src/plugins/platforms/android/androidcontentfileengine.cpp
+++ b/src/plugins/platforms/android/androidcontentfileengine.cpp
@@ -44,9 +44,10 @@
#include <QDebug>
-AndroidContentFileEngine::AndroidContentFileEngine(const QString &fileName)
- : QFSFileEngine(fileName)
+AndroidContentFileEngine::AndroidContentFileEngine(const QString &f)
+ : m_file(f)
{
+ setFileName(f);
}
bool AndroidContentFileEngine::open(QIODevice::OpenMode openMode)
@@ -78,6 +79,48 @@ bool AndroidContentFileEngine::open(QIODevice::OpenMode openMode)
return QFSFileEngine::open(openMode, fd, QFile::AutoCloseHandle);
}
+qint64 AndroidContentFileEngine::size() const
+{
+ const jlong size = QJNIObjectPrivate::callStaticMethod<jlong>(
+ "org/qtproject/qt5/android/QtNative", "getSize",
+ "(Landroid/content/Context;Ljava/lang/String;)J", QtAndroidPrivate::context(),
+ QJNIObjectPrivate::fromString(fileName(DefaultName)).object());
+ return (qint64)size;
+}
+
+AndroidContentFileEngine::FileFlags AndroidContentFileEngine::fileFlags(FileFlags type) const
+{
+ FileFlags commonFlags(ReadOwnerPerm|ReadUserPerm|ReadGroupPerm|ReadOtherPerm|ExistsFlag);
+ FileFlags flags;
+ const bool exists = QJNIObjectPrivate::callStaticMethod<jboolean>(
+ "org/qtproject/qt5/android/QtNative", "checkFileExists",
+ "(Landroid/content/Context;Ljava/lang/String;)Z", QtAndroidPrivate::context(),
+ QJNIObjectPrivate::fromString(fileName(DefaultName)).object());
+ if (!exists)
+ return flags;
+ flags = FileType | commonFlags;
+ return type & flags;
+}
+
+QString AndroidContentFileEngine::fileName(FileName f) const
+{
+ switch (f) {
+ case PathName:
+ case AbsolutePathName:
+ case CanonicalPathName:
+ case DefaultName:
+ case AbsoluteName:
+ case CanonicalName:
+ return m_file;
+ case BaseName:
+ {
+ const int pos = m_file.lastIndexOf(QChar(QLatin1Char('/')));
+ return m_file.mid(pos);
+ }
+ default:
+ return QString();
+ }
+}
AndroidContentFileEngineHandler::AndroidContentFileEngineHandler() = default;
AndroidContentFileEngineHandler::~AndroidContentFileEngineHandler() = default;
diff --git a/src/plugins/platforms/android/androidcontentfileengine.h b/src/plugins/platforms/android/androidcontentfileengine.h
index db3def03d6..09e5d77553 100644
--- a/src/plugins/platforms/android/androidcontentfileengine.h
+++ b/src/plugins/platforms/android/androidcontentfileengine.h
@@ -47,6 +47,12 @@ class AndroidContentFileEngine : public QFSFileEngine
public:
AndroidContentFileEngine(const QString &fileName);
bool open(QIODevice::OpenMode openMode) override;
+ qint64 size() const override;
+ FileFlags fileFlags(FileFlags type = FileInfoAll) const override;
+ QString fileName(FileName file = DefaultName) const override;
+private:
+ QString m_file;
+
};
class AndroidContentFileEngineHandler : public QAbstractFileEngineHandler
diff --git a/src/plugins/platforms/android/qandroidplatformfiledialoghelper.cpp b/src/plugins/platforms/android/qandroidplatformfiledialoghelper.cpp
index fb979ab6cc..7b5f2f16f8 100644
--- a/src/plugins/platforms/android/qandroidplatformfiledialoghelper.cpp
+++ b/src/plugins/platforms/android/qandroidplatformfiledialoghelper.cpp
@@ -40,7 +40,6 @@
#include "qandroidplatformfiledialoghelper.h"
#include <androidjnimain.h>
-#include <private/qjni_p.h>
#include <jni.h>
QT_BEGIN_NAMESPACE
@@ -50,9 +49,11 @@ namespace QtAndroidFileDialogHelper {
#define RESULT_OK -1
#define REQUEST_CODE 1305 // Arbitrary
+const char JniIntentClass[] = "android/content/Intent";
+
QAndroidPlatformFileDialogHelper::QAndroidPlatformFileDialogHelper()
- : QPlatformFileDialogHelper()
- , m_selectedFile()
+ : QPlatformFileDialogHelper(),
+ m_activity(QtAndroid::activity())
{
}
@@ -61,92 +62,165 @@ bool QAndroidPlatformFileDialogHelper::handleActivityResult(jint requestCode, ji
if (requestCode != REQUEST_CODE)
return false;
- if (resultCode == RESULT_OK) {
- const QJNIObjectPrivate intent = QJNIObjectPrivate::fromLocalRef(data);
- const QJNIObjectPrivate uri = intent.callObjectMethod("getData", "()Landroid/net/Uri;");
- const QString uriStr = uri.callObjectMethod("toString", "()Ljava/lang/String;").toString();
- m_selectedFile = QUrl(uriStr);
- Q_EMIT fileSelected(m_selectedFile);
- Q_EMIT accept();
- } else {
+ if (resultCode != RESULT_OK) {
Q_EMIT reject();
+ return true;
}
- return true;
-}
-
-bool QAndroidPlatformFileDialogHelper::show(Qt::WindowFlags windowFlags, Qt::WindowModality windowModality, QWindow *parent)
-{
- Q_UNUSED(windowFlags)
- Q_UNUSED(windowModality)
- Q_UNUSED(parent)
-
- if (options()->fileMode() != QFileDialogOptions::FileMode::ExistingFile)
- return false;
+ const QJNIObjectPrivate intent = QJNIObjectPrivate::fromLocalRef(data);
- QtAndroidPrivate::registerActivityResultListener(this);
+ const QJNIObjectPrivate uri = intent.callObjectMethod("getData", "()Landroid/net/Uri;");
+ if (uri.isValid()) {
+ takePersistableUriPermission(uri);
+ m_selectedFile.append(QUrl(uri.toString()));
+ Q_EMIT fileSelected(m_selectedFile.first());
+ Q_EMIT accept();
- const QJNIObjectPrivate ACTION_OPEN_DOCUMENT = QJNIObjectPrivate::getStaticObjectField("android/content/Intent", "ACTION_OPEN_DOCUMENT", "Ljava/lang/String;");
- QJNIObjectPrivate intent("android/content/Intent", "(Ljava/lang/String;)V", ACTION_OPEN_DOCUMENT.object());
- const QJNIObjectPrivate CATEGORY_OPENABLE = QJNIObjectPrivate::getStaticObjectField("android/content/Intent", "CATEGORY_OPENABLE", "Ljava/lang/String;");
- intent.callObjectMethod("addCategory", "(Ljava/lang/String;)Landroid/content/Intent;", CATEGORY_OPENABLE.object());
- intent.callObjectMethod("setType", "(Ljava/lang/String;)Landroid/content/Intent;", QJNIObjectPrivate::fromString(QStringLiteral("*/*")).object());
+ return true;
+ }
- const QJNIObjectPrivate activity(QtAndroid::activity());
- activity.callMethod<void>("startActivityForResult", "(Landroid/content/Intent;I)V", intent.object(), REQUEST_CODE);
+ const QJNIObjectPrivate uriClipData =
+ intent.callObjectMethod("getClipData", "()Landroid/content/ClipData;");
+ if (uriClipData.isValid()) {
+ const int size = uriClipData.callMethod<jint>("getItemCount");
+ for (int i = 0; i < size; ++i) {
+ QJNIObjectPrivate item = uriClipData.callObjectMethod(
+ "getItemAt", "(I)Landroid/content/ClipData$Item;", i);
+
+ QJNIObjectPrivate itemUri = item.callObjectMethod("getUri", "()Landroid/net/Uri;");
+ takePersistableUriPermission(itemUri);
+ m_selectedFile.append(itemUri.toString());
+ Q_EMIT filesSelected(m_selectedFile);
+ Q_EMIT accept();
+ }
+ }
return true;
}
-void QAndroidPlatformFileDialogHelper::exec()
+void QAndroidPlatformFileDialogHelper::takePersistableUriPermission(const QJNIObjectPrivate &uri)
{
- m_eventLoop.exec(QEventLoop::DialogExec);
+ int modeFlags = QJNIObjectPrivate::getStaticField<jint>(
+ JniIntentClass, "FLAG_GRANT_READ_URI_PERMISSION");
+
+ if (options()->acceptMode() == QFileDialogOptions::AcceptSave) {
+ modeFlags |= QJNIObjectPrivate::getStaticField<jint>(
+ JniIntentClass, "FLAG_GRANT_WRITE_URI_PERMISSION");
+ }
+
+ QJNIObjectPrivate contentResolver = m_activity.callObjectMethod(
+ "getContentResolver", "()Landroid/content/ContentResolver;");
+ contentResolver.callMethod<void>("takePersistableUriPermission", "(Landroid/net/Uri;I)V",
+ uri.object(), modeFlags);
}
-void QAndroidPlatformFileDialogHelper::hide()
+void QAndroidPlatformFileDialogHelper::setLocalFilesOnly(bool localOnly)
{
- if (m_eventLoop.isRunning())
- m_eventLoop.exit();
- QtAndroidPrivate::unregisterActivityResultListener(this);
+ const QJNIObjectPrivate extraLocalOnly = QJNIObjectPrivate::getStaticObjectField(
+ JniIntentClass, "EXTRA_LOCAL_ONLY", "Ljava/lang/String;");
+ m_intent.callObjectMethod("putExtra", "(Ljava/lang/String;Z)Landroid/content/Intent;",
+ extraLocalOnly.object(), localOnly);
}
-QString QAndroidPlatformFileDialogHelper::selectedNameFilter() const
+void QAndroidPlatformFileDialogHelper::setIntentTitle(const QString &title)
{
- return QString();
+ const QJNIObjectPrivate extraTitle = QJNIObjectPrivate::getStaticObjectField(
+ JniIntentClass, "EXTRA_TITLE", "Ljava/lang/String;");
+ m_intent.callObjectMethod("putExtra",
+ "(Ljava/lang/String;Ljava/lang/String;)Landroid/content/Intent;",
+ extraTitle.object(), QJNIObjectPrivate::fromString(title).object());
}
-void QAndroidPlatformFileDialogHelper::selectNameFilter(const QString &filter)
+void QAndroidPlatformFileDialogHelper::setOpenableCategory()
{
- Q_UNUSED(filter)
+ const QJNIObjectPrivate CATEGORY_OPENABLE = QJNIObjectPrivate::getStaticObjectField(
+ JniIntentClass, "CATEGORY_OPENABLE", "Ljava/lang/String;");
+ m_intent.callObjectMethod("addCategory", "(Ljava/lang/String;)Landroid/content/Intent;",
+ CATEGORY_OPENABLE.object());
}
-void QAndroidPlatformFileDialogHelper::setFilter()
+void QAndroidPlatformFileDialogHelper::setAllowMultipleSelections(bool allowMultiple)
{
+ const QJNIObjectPrivate allowMultipleSelections = QJNIObjectPrivate::getStaticObjectField(
+ JniIntentClass, "EXTRA_ALLOW_MULTIPLE", "Ljava/lang/String;");
+ m_intent.callObjectMethod("putExtra", "(Ljava/lang/String;Z)Landroid/content/Intent;",
+ allowMultipleSelections.object(), allowMultiple);
}
-QList<QUrl> QAndroidPlatformFileDialogHelper::selectedFiles() const
+void QAndroidPlatformFileDialogHelper::setMimeTypes()
{
- return {m_selectedFile};
+ m_intent.callObjectMethod("setType", "(Ljava/lang/String;)Landroid/content/Intent;",
+ QJNIObjectPrivate::fromString("*/*").object());
+
+ const QJNIObjectPrivate extraMimeType = QJNIObjectPrivate::getStaticObjectField(
+ JniIntentClass, "EXTRA_MIME_TYPES", "Ljava/lang/String;");
+ for (const QString &type : options()->mimeTypeFilters()) {
+ m_intent.callObjectMethod(
+ "putExtra", "(Ljava/lang/String;Ljava/lang/String;)Landroid/content/Intent;",
+ extraMimeType.object(), QJNIObjectPrivate::fromString(type).object());
+ }
}
-void QAndroidPlatformFileDialogHelper::selectFile(const QUrl &file)
+QJNIObjectPrivate QAndroidPlatformFileDialogHelper::getFileDialogIntent(const QString &intentType)
{
- Q_UNUSED(file)
+ const QJNIObjectPrivate ACTION_OPEN_DOCUMENT = QJNIObjectPrivate::getStaticObjectField(
+ JniIntentClass, intentType.toLatin1(), "Ljava/lang/String;");
+ return QJNIObjectPrivate(JniIntentClass, "(Ljava/lang/String;)V",
+ ACTION_OPEN_DOCUMENT.object());
}
-QUrl QAndroidPlatformFileDialogHelper::directory() const
+bool QAndroidPlatformFileDialogHelper::show(Qt::WindowFlags windowFlags, Qt::WindowModality windowModality, QWindow *parent)
{
- return QUrl();
+ Q_UNUSED(windowFlags)
+ Q_UNUSED(windowModality)
+ Q_UNUSED(parent)
+
+ bool isDirDialog = false;
+
+ if (options()->acceptMode() == QFileDialogOptions::AcceptSave) {
+ m_intent = getFileDialogIntent("ACTION_CREATE_DOCUMENT");
+ } else if (options()->acceptMode() == QFileDialogOptions::AcceptOpen) {
+ switch (options()->fileMode()) {
+ case QFileDialogOptions::FileMode::DirectoryOnly:
+ case QFileDialogOptions::FileMode::Directory:
+ m_intent = getFileDialogIntent("ACTION_OPEN_DOCUMENT_TREE");
+ isDirDialog = true;
+ break;
+ case QFileDialogOptions::FileMode::ExistingFiles:
+ m_intent = getFileDialogIntent("ACTION_OPEN_DOCUMENT");
+ setAllowMultipleSelections(true);
+ break;
+ case QFileDialogOptions::FileMode::AnyFile:
+ case QFileDialogOptions::FileMode::ExistingFile:
+ m_intent = getFileDialogIntent("ACTION_OPEN_DOCUMENT");
+ break;
+ }
+ }
+
+ if (!isDirDialog) {
+ setOpenableCategory();
+ setMimeTypes();
+ }
+
+ setIntentTitle(options()->windowTitle());
+ setLocalFilesOnly(true);
+
+ QtAndroidPrivate::registerActivityResultListener(this);
+ m_activity.callMethod<void>("startActivityForResult", "(Landroid/content/Intent;I)V",
+ m_intent.object(), REQUEST_CODE);
+ return true;
}
-void QAndroidPlatformFileDialogHelper::setDirectory(const QUrl &directory)
+void QAndroidPlatformFileDialogHelper::hide()
{
- Q_UNUSED(directory)
+ if (m_eventLoop.isRunning())
+ m_eventLoop.exit();
+ QtAndroidPrivate::unregisterActivityResultListener(this);
}
-bool QAndroidPlatformFileDialogHelper::defaultNameFilterDisables() const
+void QAndroidPlatformFileDialogHelper::exec()
{
- return false;
+ m_eventLoop.exec(QEventLoop::DialogExec);
}
}
diff --git a/src/plugins/platforms/android/qandroidplatformfiledialoghelper.h b/src/plugins/platforms/android/qandroidplatformfiledialoghelper.h
index 5cd26af7c9..fa9c3f47b3 100644
--- a/src/plugins/platforms/android/qandroidplatformfiledialoghelper.h
+++ b/src/plugins/platforms/android/qandroidplatformfiledialoghelper.h
@@ -44,6 +44,8 @@
#include <QEventLoop>
#include <qpa/qplatformdialoghelper.h>
#include <QtCore/private/qjnihelpers_p.h>
+#include <private/qjni_p.h>
+#include <QEventLoop>
QT_BEGIN_NAMESPACE
@@ -55,26 +57,34 @@ class QAndroidPlatformFileDialogHelper: public QPlatformFileDialogHelper, public
public:
QAndroidPlatformFileDialogHelper();
- void exec() override;
- bool show(Qt::WindowFlags windowFlags,
- Qt::WindowModality windowModality,
- QWindow *parent) override;
+ void exec() override;
+ bool show(Qt::WindowFlags windowFlags, Qt::WindowModality windowModality, QWindow *parent) override;
void hide() override;
- QString selectedNameFilter() const override;
- void selectNameFilter(const QString &filter) override;
- void setFilter() override;
- QList<QUrl> selectedFiles() const override;
- void selectFile(const QUrl &file) override;
- QUrl directory() const override;
- void setDirectory(const QUrl &directory) override;
- bool defaultNameFilterDisables() const override;
+ QString selectedNameFilter() const override { return QString(); };
+ void selectNameFilter(const QString &filter) override { Q_UNUSED(filter) };
+ void setFilter() override {};
+ QList<QUrl> selectedFiles() const override { return m_selectedFile; };
+ void selectFile(const QUrl &file) override { Q_UNUSED(file) };
+ QUrl directory() const override { return QUrl(); };
+ void setDirectory(const QUrl &directory) override { Q_UNUSED(directory) };
+ bool defaultNameFilterDisables() const override { return false; };
bool handleActivityResult(jint requestCode, jint resultCode, jobject data) override;
private:
+ QJNIObjectPrivate getFileDialogIntent(const QString &intentType);
+ void takePersistableUriPermission(const QJNIObjectPrivate &uri);
+ void setLocalFilesOnly(bool localOnly);
+ void setIntentTitle(const QString &title);
+ void setOpenableCategory();
+ void setAllowMultipleSelections(bool allowMultiple);
+ void setMimeTypes();
+
QEventLoop m_eventLoop;
- QUrl m_selectedFile;
+ QList<QUrl> m_selectedFile;
+ QJNIObjectPrivate m_intent;
+ const QJNIObjectPrivate m_activity;
};
}
diff --git a/src/plugins/platforms/android/qandroidplatformintegration.cpp b/src/plugins/platforms/android/qandroidplatformintegration.cpp
index e0c437be27..c81cc66166 100644
--- a/src/plugins/platforms/android/qandroidplatformintegration.cpp
+++ b/src/plugins/platforms/android/qandroidplatformintegration.cpp
@@ -74,6 +74,8 @@
#include "qandroidplatformvulkaninstance.h"
#endif
+#include <QtGui/qpa/qplatforminputcontextfactory_p.h>
+
QT_BEGIN_NAMESPACE
int QAndroidPlatformIntegration::m_defaultGeometryWidth = 320;
@@ -255,6 +257,15 @@ static bool needsBasicRenderloopWorkaround()
return needsWorkaround;
}
+void QAndroidPlatformIntegration::initialize()
+{
+ const QString icStr = QPlatformInputContextFactory::requested();
+ if (icStr.isNull())
+ m_inputContext.reset(new QAndroidInputContext);
+ else
+ m_inputContext.reset(QPlatformInputContextFactory::create(icStr));
+}
+
bool QAndroidPlatformIntegration::hasCapability(Capability cap) const
{
switch (cap) {
@@ -366,7 +377,7 @@ QPlatformClipboard *QAndroidPlatformIntegration::clipboard() const
QPlatformInputContext *QAndroidPlatformIntegration::inputContext() const
{
- return &m_platformInputContext;
+ return m_inputContext.data();
}
QPlatformNativeInterface *QAndroidPlatformIntegration::nativeInterface() const
diff --git a/src/plugins/platforms/android/qandroidplatformintegration.h b/src/plugins/platforms/android/qandroidplatformintegration.h
index c795c499bc..ecbde4f951 100644
--- a/src/plugins/platforms/android/qandroidplatformintegration.h
+++ b/src/plugins/platforms/android/qandroidplatformintegration.h
@@ -81,6 +81,8 @@ public:
QAndroidPlatformIntegration(const QStringList &paramList);
~QAndroidPlatformIntegration();
+ void initialize() override;
+
bool hasCapability(QPlatformIntegration::Capability cap) const override;
QPlatformWindow *createPlatformWindow(QWindow *window) const override;
@@ -167,7 +169,7 @@ private:
mutable QPlatformAccessibility *m_accessibility;
#endif
- mutable QAndroidInputContext m_platformInputContext;
+ QScopedPointer<QPlatformInputContext> m_inputContext;
};
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/android/qandroidplatformservices.cpp b/src/plugins/platforms/android/qandroidplatformservices.cpp
index 136637800b..c095613ce7 100644
--- a/src/plugins/platforms/android/qandroidplatformservices.cpp
+++ b/src/plugins/platforms/android/qandroidplatformservices.cpp
@@ -43,6 +43,7 @@
#include <QDebug>
#include <QMimeDatabase>
#include <QtCore/private/qjni_p.h>
+#include <private/qjnihelpers_p.h>
QT_BEGIN_NAMESPACE
@@ -57,20 +58,20 @@ bool QAndroidPlatformServices::openUrl(const QUrl &theUrl)
// if the file is local, we need to pass the MIME type, otherwise Android
// does not start an Intent to view this file
- if ((url.scheme().isEmpty() && QFile::exists(url.path())) || url.isLocalFile()) {
+ QLatin1String fileScheme("file");
+ if ((url.scheme().isEmpty() || url.scheme() == fileScheme) && QFile::exists(url.path())) {
// a real URL including the scheme is needed, else the Intent can not be started
- url.setScheme(QLatin1String("file"));
-
+ url.setScheme(fileScheme);
QMimeDatabase mimeDb;
mime = mimeDb.mimeTypeForUrl(url).name();
}
QJNIObjectPrivate urlString = QJNIObjectPrivate::fromString(url.toString());
QJNIObjectPrivate mimeString = QJNIObjectPrivate::fromString(mime);
- return QJNIObjectPrivate::callStaticMethod<jboolean>(QtAndroid::applicationClass(),
- "openURL",
- "(Ljava/lang/String;Ljava/lang/String;)Z",
- urlString.object(), mimeString.object());
+ return QJNIObjectPrivate::callStaticMethod<jboolean>(
+ QtAndroid::applicationClass(), "openURL",
+ "(Landroid/content/Context;Ljava/lang/String;Ljava/lang/String;)Z",
+ QtAndroidPrivate::context(), urlString.object(), mimeString.object());
}
bool QAndroidPlatformServices::openDocument(const QUrl &url)
diff --git a/src/plugins/platforms/cocoa/cocoa.pro b/src/plugins/platforms/cocoa/cocoa.pro
index 6645b6c90a..a919963cf4 100644
--- a/src/plugins/platforms/cocoa/cocoa.pro
+++ b/src/plugins/platforms/cocoa/cocoa.pro
@@ -85,6 +85,11 @@ qtConfig(accessibility) {
qcocoaaccessibility.h
}
+qtConfig(sessionmanager) {
+ SOURCES += qcocoasessionmanager.cpp
+ HEADERS += qcocoasessionmanager.h
+}
+
RESOURCES += qcocoaresources.qrc
LIBS += -framework AppKit -framework CoreServices -framework Carbon -framework IOKit -framework QuartzCore -framework CoreVideo -framework Metal -framework IOSurface -lcups
diff --git a/src/plugins/platforms/cocoa/qcocoaapplicationdelegate.mm b/src/plugins/platforms/cocoa/qcocoaapplicationdelegate.mm
index 9b0a6b1b86..3fb9e83d35 100644
--- a/src/plugins/platforms/cocoa/qcocoaapplicationdelegate.mm
+++ b/src/plugins/platforms/cocoa/qcocoaapplicationdelegate.mm
@@ -79,11 +79,14 @@
#include "qcocoamenuitem.h"
#include "qcocoansmenu.h"
+#if QT_CONFIG(sessionmanager)
+# include "qcocoasessionmanager.h"
+#endif
+
#include <qevent.h>
#include <qurl.h>
#include <qdebug.h>
#include <qguiapplication.h>
-#include <private/qguiapplication_p.h>
#include "qt_mac_p.h"
#include <qpa/qwindowsysteminterface.h>
#include <qwindowdefs.h>
@@ -149,7 +152,7 @@ QT_USE_NAMESPACE
if ([reflectionDelegate respondsToSelector:_cmd])
return [reflectionDelegate applicationShouldTerminate:sender];
- if (QGuiApplicationPrivate::instance()->threadData->eventLoops.isEmpty()) {
+ if (QGuiApplicationPrivate::instance()->threadData.loadRelaxed()->eventLoops.isEmpty()) {
// No event loop is executing. This probably means that Qt is used as a plugin,
// or as a part of a native Cocoa application. In any case it should be fine to
// terminate now.
@@ -157,6 +160,17 @@ QT_USE_NAMESPACE
return NSTerminateNow;
}
+#if QT_CONFIG(sessionmanager)
+ QCocoaSessionManager *cocoaSessionManager = QCocoaSessionManager::instance();
+ cocoaSessionManager->resetCancellation();
+ cocoaSessionManager->appCommitData();
+
+ if (cocoaSessionManager->wasCanceled()) {
+ qCDebug(lcQpaApplication) << "Session management canceled application termination";
+ return NSTerminateCancel;
+ }
+#endif
+
if (!QWindowSystemInterface::handleApplicationTermination<QWindowSystemInterface::SynchronousDelivery>()) {
qCDebug(lcQpaApplication) << "Application termination canceled";
return NSTerminateCancel;
@@ -359,7 +373,7 @@ QT_USE_NAMESPACE
if (!platformItem || platformItem->menu())
return;
- QScopedScopeLevelCounter scopeLevelCounter(QGuiApplicationPrivate::instance()->threadData);
+ QScopedScopeLevelCounter scopeLevelCounter(QGuiApplicationPrivate::instance()->threadData.loadRelaxed());
QGuiApplicationPrivate::modifier_buttons = [QNSView convertKeyModifiers:[NSEvent modifierFlags]];
static QMetaMethod activatedSignal = QMetaMethod::fromSignal(&QCocoaMenuItem::activated);
diff --git a/src/plugins/platforms/cocoa/qcocoaclipboard.mm b/src/plugins/platforms/cocoa/qcocoaclipboard.mm
index a35c153084..141940cc50 100644
--- a/src/plugins/platforms/cocoa/qcocoaclipboard.mm
+++ b/src/plugins/platforms/cocoa/qcocoaclipboard.mm
@@ -67,7 +67,7 @@ void QCocoaClipboard::setMimeData(QMimeData *data, QClipboard::Mode mode)
}
pasteBoard->sync();
- pasteBoard->setMimeData(data);
+ pasteBoard->setMimeData(data, QMacPasteboard::LazyRequest);
emitChanged(mode);
}
}
diff --git a/src/plugins/platforms/cocoa/qcocoacursor.mm b/src/plugins/platforms/cocoa/qcocoacursor.mm
index e0d623fc4c..c10ada1ada 100644
--- a/src/plugins/platforms/cocoa/qcocoacursor.mm
+++ b/src/plugins/platforms/cocoa/qcocoacursor.mm
@@ -335,24 +335,8 @@ NSCursor *QCocoaCursor::createCursorFromBitmap(const QBitmap *bitmap, const QBit
NSCursor *QCocoaCursor::createCursorFromPixmap(const QPixmap pixmap, const QPoint hotspot)
{
NSPoint hotSpot = NSMakePoint(hotspot.x(), hotspot.y());
- NSImage *nsimage;
- if (pixmap.devicePixelRatio() > 1.0) {
- QSize layoutSize = pixmap.size() / pixmap.devicePixelRatio();
- QPixmap scaledPixmap = pixmap.scaled(layoutSize, Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
- scaledPixmap.setDevicePixelRatio(1.0);
- nsimage = static_cast<NSImage *>(qt_mac_create_nsimage(scaledPixmap));
- CGImageRef cgImage = qt_mac_toCGImage(pixmap.toImage());
- NSBitmapImageRep *imageRep = [[NSBitmapImageRep alloc] initWithCGImage:cgImage];
- [nsimage addRepresentation:imageRep];
- [imageRep release];
- CGImageRelease(cgImage);
- } else {
- nsimage = static_cast<NSImage *>(qt_mac_create_nsimage(pixmap));
- }
-
- NSCursor *nsCursor = [[NSCursor alloc] initWithImage:nsimage hotSpot: hotSpot];
- [nsimage release];
- return nsCursor;
+ auto *image = [NSImage imageFromQImage:pixmap.toImage()];
+ return [[NSCursor alloc] initWithImage:image hotSpot:hotSpot];
}
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/cocoa/qcocoadrag.mm b/src/plugins/platforms/cocoa/qcocoadrag.mm
index 95808b8a11..b4a16ab912 100644
--- a/src/plugins/platforms/cocoa/qcocoadrag.mm
+++ b/src/plugins/platforms/cocoa/qcocoadrag.mm
@@ -130,9 +130,8 @@ Qt::DropAction QCocoaDrag::drag(QDrag *o)
QPoint hotSpot = m_drag->hotSpot();
QPixmap pm = dragPixmap(m_drag, hotSpot);
- QSize pmDeviceIndependentSize = pm.size() / pm.devicePixelRatio();
- NSImage *nsimage = qt_mac_create_nsimage(pm);
- [nsimage setSize:NSSizeFromCGSize(pmDeviceIndependentSize.toCGSize())];
+ NSImage *dragImage = [NSImage imageFromQImage:pm.toImage()];
+ Q_ASSERT(dragImage);
QMacPasteboard dragBoard(CFStringRef(NSPasteboardNameDrag), QMacInternalPasteboardMime::MIME_DND);
m_drag->mimeData()->setData(QLatin1String("application/x-qt-mime-type-name"), QByteArray("dummy"));
@@ -142,12 +141,12 @@ Qt::DropAction QCocoaDrag::drag(QDrag *o)
NSWindow *theWindow = [m_lastEvent window];
Q_ASSERT(theWindow);
event_location.x -= hotSpot.x();
- CGFloat flippedY = pmDeviceIndependentSize.height() - hotSpot.y();
+ CGFloat flippedY = dragImage.size.height - hotSpot.y();
event_location.y -= flippedY;
NSSize mouseOffset_unused = NSMakeSize(0.0, 0.0);
NSPasteboard *pboard = [NSPasteboard pasteboardWithName:NSPasteboardNameDrag];
- [theWindow dragImage:nsimage
+ [theWindow dragImage:dragImage
at:event_location
offset:mouseOffset_unused
event:m_lastEvent
@@ -155,8 +154,6 @@ Qt::DropAction QCocoaDrag::drag(QDrag *o)
source:m_lastView
slideBack:YES];
- [nsimage release];
-
m_drag = nullptr;
return m_executed_drop_action;
}
diff --git a/src/plugins/platforms/cocoa/qcocoaeventdispatcher.h b/src/plugins/platforms/cocoa/qcocoaeventdispatcher.h
index 69587a24be..b8d2532b8e 100644
--- a/src/plugins/platforms/cocoa/qcocoaeventdispatcher.h
+++ b/src/plugins/platforms/cocoa/qcocoaeventdispatcher.h
@@ -186,6 +186,7 @@ public:
QAtomicInt serialNumber;
int lastSerial;
bool interrupt;
+ bool propagateInterrupt = false;
static void postedEventsSourceCallback(void *info);
static void waitingObserverCallback(CFRunLoopObserverRef observer,
diff --git a/src/plugins/platforms/cocoa/qcocoaeventdispatcher.mm b/src/plugins/platforms/cocoa/qcocoaeventdispatcher.mm
index e87fc39c42..94b9e62eab 100644
--- a/src/plugins/platforms/cocoa/qcocoaeventdispatcher.mm
+++ b/src/plugins/platforms/cocoa/qcocoaeventdispatcher.mm
@@ -84,13 +84,12 @@
#include "private/qthread_p.h"
#include "private/qguiapplication_p.h"
#include <qdebug.h>
+#include <qscopeguard.h>
#include <AppKit/AppKit.h>
QT_BEGIN_NAMESPACE
-QT_USE_NAMESPACE
-
static inline CFRunLoopRef mainRunLoop()
{
return CFRunLoopGetMain();
@@ -293,46 +292,42 @@ bool QCocoaEventDispatcher::hasPendingEvents()
return qGlobalPostedEventsCount() || (qt_is_gui_used && !CFRunLoopIsWaiting(CFRunLoopGetMain()));
}
-static bool IsMouseOrKeyEvent( NSEvent* event )
+static bool isUserInputEvent(NSEvent* event)
{
- bool result = false;
-
- switch( [event type] )
- {
- case NSEventTypeLeftMouseDown:
- case NSEventTypeLeftMouseUp:
- case NSEventTypeRightMouseDown:
- case NSEventTypeRightMouseUp:
- case NSEventTypeMouseMoved: // ??
- case NSEventTypeLeftMouseDragged:
- case NSEventTypeRightMouseDragged:
- case NSEventTypeMouseEntered:
- case NSEventTypeMouseExited:
- case NSEventTypeKeyDown:
- case NSEventTypeKeyUp:
- case NSEventTypeFlagsChanged: // key modifiers changed?
- case NSEventTypeCursorUpdate: // ??
- case NSEventTypeScrollWheel:
- case NSEventTypeTabletPoint:
- case NSEventTypeTabletProximity:
- case NSEventTypeOtherMouseDown:
- case NSEventTypeOtherMouseUp:
- case NSEventTypeOtherMouseDragged:
+ switch ([event type]) {
+ case NSEventTypeLeftMouseDown:
+ case NSEventTypeLeftMouseUp:
+ case NSEventTypeRightMouseDown:
+ case NSEventTypeRightMouseUp:
+ case NSEventTypeMouseMoved: // ??
+ case NSEventTypeLeftMouseDragged:
+ case NSEventTypeRightMouseDragged:
+ case NSEventTypeMouseEntered:
+ case NSEventTypeMouseExited:
+ case NSEventTypeKeyDown:
+ case NSEventTypeKeyUp:
+ case NSEventTypeFlagsChanged: // key modifiers changed?
+ case NSEventTypeCursorUpdate: // ??
+ case NSEventTypeScrollWheel:
+ case NSEventTypeTabletPoint:
+ case NSEventTypeTabletProximity:
+ case NSEventTypeOtherMouseDown:
+ case NSEventTypeOtherMouseUp:
+ case NSEventTypeOtherMouseDragged:
#ifndef QT_NO_GESTURES
- case NSEventTypeGesture: // touch events
- case NSEventTypeMagnify:
- case NSEventTypeSwipe:
- case NSEventTypeRotate:
- case NSEventTypeBeginGesture:
- case NSEventTypeEndGesture:
+ case NSEventTypeGesture: // touch events
+ case NSEventTypeMagnify:
+ case NSEventTypeSwipe:
+ case NSEventTypeRotate:
+ case NSEventTypeBeginGesture:
+ case NSEventTypeEndGesture:
#endif // QT_NO_GESTURES
- result = true;
+ return true;
break;
-
- default:
+ default:
break;
}
- return result;
+ return false;
}
static inline void qt_mac_waitForMoreEvents(NSString *runLoopMode = NSDefaultRunLoopMode)
@@ -352,6 +347,16 @@ static inline void qt_mac_waitForMoreEvents(NSString *runLoopMode = NSDefaultRun
bool QCocoaEventDispatcher::processEvents(QEventLoop::ProcessEventsFlags flags)
{
Q_D(QCocoaEventDispatcher);
+
+ // In rare rather corner cases a user's application messes with
+ // QEventLoop::exec()/exit() and QCoreApplication::processEvents(),
+ // we have to undo what bool blocker normally does.
+ d->propagateInterrupt = false;
+ const auto boolBlockerUndo = qScopeGuard([d](){
+ if (d->propagateInterrupt)
+ d->interrupt = true;
+ d->propagateInterrupt = false;
+ });
QBoolBlocker interruptBlocker(d->interrupt, false);
bool interruptLater = false;
@@ -465,7 +470,7 @@ bool QCocoaEventDispatcher::processEvents(QEventLoop::ProcessEventsFlags flags)
dequeue: YES];
if (event) {
- if (IsMouseOrKeyEvent(event)) {
+ if (isUserInputEvent(event)) {
[event retain];
d->queuedUserInputEvents.append(event);
continue;
@@ -485,7 +490,7 @@ bool QCocoaEventDispatcher::processEvents(QEventLoop::ProcessEventsFlags flags)
if (event) {
if (flags & QEventLoop::ExcludeUserInputEvents) {
- if (IsMouseOrKeyEvent(event)) {
+ if (isUserInputEvent(event)) {
[event retain];
d->queuedUserInputEvents.append(event);
continue;
@@ -500,7 +505,16 @@ bool QCocoaEventDispatcher::processEvents(QEventLoop::ProcessEventsFlags flags)
if ((d->processEventsFlags & QEventLoop::EventLoopExec) == 0) {
// When called "manually", always process posted events and timers
+ bool oldInterrupt = d->interrupt;
d->processPostedEvents();
+ if (!oldInterrupt && d->interrupt && !d->currentModalSession()) {
+ // We had direct processEvent call, coming not from QEventLoop::exec().
+ // One of the posted events triggered an application to interrupt the loop.
+ // But bool blocker will reset d->interrupt to false, so the real event
+ // loop will never notice it was interrupted. Now we'll have to fix it by
+ // enforcing the value of d->interrupt.
+ d->propagateInterrupt = true;
+ }
retVal = d->processTimers() || retVal;
}
@@ -515,7 +529,7 @@ bool QCocoaEventDispatcher::processEvents(QEventLoop::ProcessEventsFlags flags)
if (hadModalSession && !d->currentModalSessionCached)
interruptLater = true;
}
- bool canWait = (d->threadData->canWait
+ bool canWait = (d->threadData.loadRelaxed()->canWait
&& !retVal
&& !d->interrupt
&& (d->processEventsFlags & QEventLoop::WaitForMoreEvents));
@@ -882,7 +896,7 @@ void QCocoaEventDispatcherPrivate::processPostedEvents()
}
int serial = serialNumber.loadRelaxed();
- if (!threadData->canWait || (serial != lastSerial)) {
+ if (!threadData.loadRelaxed()->canWait || (serial != lastSerial)) {
lastSerial = serial;
QCoreApplication::sendPostedEvents();
QWindowSystemInterface::sendWindowSystemEvents(QEventLoop::AllEvents);
diff --git a/src/plugins/platforms/cocoa/qcocoafiledialoghelper.mm b/src/plugins/platforms/cocoa/qcocoafiledialoghelper.mm
index 6aa21d78d1..8b76e45616 100644
--- a/src/plugins/platforms/cocoa/qcocoafiledialoghelper.mm
+++ b/src/plugins/platforms/cocoa/qcocoafiledialoghelper.mm
@@ -419,8 +419,7 @@ static QString strippedText(QString s)
[mPopUpButton setHidden:chooseDirsOnly]; // TODO hide the whole sunken pane instead?
if (mOptions->acceptMode() == QFileDialogOptions::AcceptSave) {
- const QStringList ext = [self acceptableExtensionsForSave];
- [mSavePanel setAllowedFileTypes:ext.isEmpty() ? nil : qt_mac_QStringListToNSMutableArray(ext)];
+ [self recomputeAcceptableExtensionsForSave];
} else {
[mOpenPanel setAllowedFileTypes:nil]; // delegate panel:shouldEnableURL: does the file filtering for NSOpenPanel
}
@@ -457,25 +456,49 @@ static QString strippedText(QString s)
}
/*
- Returns a list of extensions (e.g. "png", "jpg", "gif")
- for the current name filter. If a filter do not conform
- to the format *.xyz or * or *.*, an empty list
- is returned meaning accept everything.
+ Computes a list of extensions (e.g. "png", "jpg", "gif")
+ for the current name filter, and updates the save panel.
+
+ If a filter do not conform to the format *.xyz or * or *.*,
+ all files types are allowed.
+
+ Extensions with more than one part (e.g. "tar.gz") are
+ reduced to their final part, as NSSavePanel does not deal
+ well with multi-part extensions.
*/
-- (QStringList)acceptableExtensionsForSave
-{
- QStringList result;
- for (int i=0; i<mSelectedNameFilter->count(); ++i) {
- const QString &filter = mSelectedNameFilter->at(i);
- if (filter.startsWith(QLatin1String("*."))
- && !filter.contains(QLatin1Char('?'))
- && filter.count(QLatin1Char('*')) == 1) {
- result += filter.mid(2);
- } else {
- return QStringList(); // Accept everything
- }
+- (void)recomputeAcceptableExtensionsForSave
+{
+ QStringList fileTypes;
+ for (const QString &filter : *mSelectedNameFilter) {
+ if (!filter.startsWith(QLatin1String("*.")))
+ continue;
+
+ if (filter.contains(QLatin1Char('?')))
+ continue;
+
+ if (filter.count(QLatin1Char('*')) != 1)
+ continue;
+
+ auto extensions = filter.split('.', Qt::SkipEmptyParts);
+ fileTypes += extensions.last();
+
+ // Explicitly show extensions if we detect a filter
+ // that has a multi-part extension. This prevents
+ // confusing situations where the user clicks e.g.
+ // 'foo.tar.gz' and 'foo.tar' is populated in the
+ // file name box, but when then clicking save macOS
+ // will warn that the file needs to end in .gz,
+ // due to thinking the user tried to save the file
+ // as a 'tar' file instead. Unfortunately this
+ // property can only be set before the panel is
+ // shown, so it will not have any effect when
+ // swithcing filters in an already opened dialog.
+ if (extensions.size() > 2)
+ mSavePanel.extensionHidden = NO;
}
- return result;
+
+ mSavePanel.allowedFileTypes = fileTypes.isEmpty() ? nil
+ : qt_mac_QStringListToNSMutableArray(fileTypes);
}
- (QString)removeExtensions:(const QString &)filter
diff --git a/src/plugins/platforms/cocoa/qcocoaglcontext.mm b/src/plugins/platforms/cocoa/qcocoaglcontext.mm
index 6db4bdb9fd..ccb6e20071 100644
--- a/src/plugins/platforms/cocoa/qcocoaglcontext.mm
+++ b/src/plugins/platforms/cocoa/qcocoaglcontext.mm
@@ -554,7 +554,7 @@ NSOpenGLContext *QCocoaGLContext::nativeContext() const
QFunctionPointer QCocoaGLContext::getProcAddress(const char *procName)
{
- return (QFunctionPointer)dlsym(RTLD_DEFAULT, procName);
+ return (QFunctionPointer)dlsym(RTLD_NEXT, procName);
}
#ifndef QT_NO_DEBUG_STREAM
diff --git a/src/plugins/platforms/cocoa/qcocoaintegration.h b/src/plugins/platforms/cocoa/qcocoaintegration.h
index bfc3bfe9de..0c14e07551 100644
--- a/src/plugins/platforms/cocoa/qcocoaintegration.h
+++ b/src/plugins/platforms/cocoa/qcocoaintegration.h
@@ -92,6 +92,10 @@ public:
QCocoaVulkanInstance *getCocoaVulkanInstance() const;
#endif
+#if QT_CONFIG(sessionmanager)
+ QPlatformSessionManager *createPlatformSessionManager(const QString &id, const QString &key) const override;
+#endif
+
QCoreTextFontDatabase *fontDatabase() const override;
QCocoaNativeInterface *nativeInterface() const override;
QPlatformInputContext *inputContext() const override;
diff --git a/src/plugins/platforms/cocoa/qcocoaintegration.mm b/src/plugins/platforms/cocoa/qcocoaintegration.mm
index b7f15a2bf1..deddcd3f98 100644
--- a/src/plugins/platforms/cocoa/qcocoaintegration.mm
+++ b/src/plugins/platforms/cocoa/qcocoaintegration.mm
@@ -52,6 +52,9 @@
#include "qcocoamimetypes.h"
#include "qcocoaaccessibility.h"
#include "qcocoascreen.h"
+#if QT_CONFIG(sessionmanager)
+# include "qcocoasessionmanager.h"
+#endif
#include <qpa/qplatforminputcontextfactory_p.h>
#include <qpa/qplatformaccessibility.h>
@@ -245,6 +248,13 @@ QCocoaIntegration::Options QCocoaIntegration::options() const
return mOptions;
}
+#if QT_CONFIG(sessionmanager)
+QPlatformSessionManager *QCocoaIntegration::createPlatformSessionManager(const QString &id, const QString &key) const
+{
+ return new QCocoaSessionManager(id, key);
+}
+#endif
+
bool QCocoaIntegration::hasCapability(QPlatformIntegration::Capability cap) const
{
switch (cap) {
@@ -462,14 +472,7 @@ QList<QCocoaWindow *> *QCocoaIntegration::popupWindowStack()
void QCocoaIntegration::setApplicationIcon(const QIcon &icon) const
{
- NSImage *image = nil;
- if (!icon.isNull()) {
- NSSize size = [[[NSApplication sharedApplication] dockTile] size];
- QPixmap pixmap = icon.pixmap(size.width, size.height);
- image = static_cast<NSImage *>(qt_mac_create_nsimage(pixmap));
- }
- [[NSApplication sharedApplication] setApplicationIconImage:image];
- [image release];
+ NSApp.applicationIconImage = [NSImage imageFromQIcon:icon];
}
void QCocoaIntegration::beep() const
diff --git a/src/plugins/platforms/cocoa/qcocoamenu.mm b/src/plugins/platforms/cocoa/qcocoamenu.mm
index 8c4fca0d29..90d5180fed 100644
--- a/src/plugins/platforms/cocoa/qcocoamenu.mm
+++ b/src/plugins/platforms/cocoa/qcocoamenu.mm
@@ -334,7 +334,7 @@ void QCocoaMenu::setEnabled(bool enabled)
bool QCocoaMenu::isEnabled() const
{
- return m_attachedItem ? m_attachedItem.enabled : m_enabled && m_parentEnabled;
+ return m_enabled && m_parentEnabled;
}
void QCocoaMenu::setVisible(bool visible)
diff --git a/src/plugins/platforms/cocoa/qcocoamenuitem.mm b/src/plugins/platforms/cocoa/qcocoamenuitem.mm
index c35cf6d799..5aa41eeb22 100644
--- a/src/plugins/platforms/cocoa/qcocoamenuitem.mm
+++ b/src/plugins/platforms/cocoa/qcocoamenuitem.mm
@@ -341,13 +341,7 @@ NSMenuItem *QCocoaMenuItem::sync()
m_native.keyEquivalentModifierMask = NSEventModifierFlagCommand;
}
- NSImage *img = nil;
- if (!m_icon.isNull()) {
- img = qt_mac_create_nsimage(m_icon, m_iconSize);
- img.size = CGSizeMake(m_iconSize, m_iconSize);
- }
- m_native.image = img;
- [img release];
+ m_native.image = [NSImage imageFromQIcon:m_icon withSize:m_iconSize];
m_native.state = m_checked ? NSOnState : NSOffState;
return m_native;
diff --git a/src/plugins/platforms/cocoa/qcocoanativeinterface.mm b/src/plugins/platforms/cocoa/qcocoanativeinterface.mm
index d0e69bdca5..450329f569 100644
--- a/src/plugins/platforms/cocoa/qcocoanativeinterface.mm
+++ b/src/plugins/platforms/cocoa/qcocoanativeinterface.mm
@@ -107,7 +107,7 @@ void *QCocoaNativeInterface::nativeResourceForWindow(const QByteArray &resourceS
#if QT_CONFIG(vulkan)
} else if (resourceString == "vkSurface") {
if (QVulkanInstance *instance = window->vulkanInstance())
- return static_cast<QCocoaVulkanInstance *>(instance->handle())->createSurface(window);
+ return static_cast<QCocoaVulkanInstance *>(instance->handle())->surface(window);
#endif
}
return nullptr;
diff --git a/src/plugins/platforms/cocoa/qcocoasessionmanager.cpp b/src/plugins/platforms/cocoa/qcocoasessionmanager.cpp
new file mode 100644
index 0000000000..74e318b5be
--- /dev/null
+++ b/src/plugins/platforms/cocoa/qcocoasessionmanager.cpp
@@ -0,0 +1,88 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 Samuel Gaist <samuel.gaist@idiap.ch>
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QT_NO_SESSIONMANAGER
+#include <private/qsessionmanager_p.h>
+#include <private/qguiapplication_p.h>
+
+#include <qcocoasessionmanager.h>
+#include <qstring.h>
+
+QT_BEGIN_NAMESPACE
+
+QCocoaSessionManager::QCocoaSessionManager(const QString &id, const QString &key)
+ : QPlatformSessionManager(id, key),
+ m_canceled(false)
+{
+}
+
+QCocoaSessionManager::~QCocoaSessionManager()
+{
+}
+
+bool QCocoaSessionManager::allowsInteraction()
+{
+ return false;
+}
+
+void QCocoaSessionManager::resetCancellation()
+{
+ m_canceled = false;
+}
+
+void QCocoaSessionManager::cancel()
+{
+ m_canceled = true;
+}
+
+bool QCocoaSessionManager::wasCanceled() const
+{
+ return m_canceled;
+}
+
+QCocoaSessionManager *QCocoaSessionManager::instance()
+{
+ auto *qGuiAppPriv = QGuiApplicationPrivate::instance();
+ auto *managerPrivate = static_cast<QSessionManagerPrivate*>(QObjectPrivate::get(qGuiAppPriv->session_manager));
+ return static_cast<QCocoaSessionManager *>(managerPrivate->platformSessionManager);
+}
+
+QT_END_NAMESPACE
+
+#endif // QT_NO_SESSIONMANAGER
diff --git a/src/plugins/platforms/cocoa/qcocoasessionmanager.h b/src/plugins/platforms/cocoa/qcocoasessionmanager.h
new file mode 100644
index 0000000000..89ab7bd157
--- /dev/null
+++ b/src/plugins/platforms/cocoa/qcocoasessionmanager.h
@@ -0,0 +1,81 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 Samuel Gaist <samuel.gaist@idiap.ch>
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QCOCOASESSIONMANAGER_H
+#define QCOCOASESSIONMANAGER_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is part of the QPA API and is not meant to be used
+// in applications. Usage of this API may make your code
+// source and binary incompatible with future versions of Qt.
+//
+
+#ifndef QT_NO_SESSIONMANAGER
+
+#include <qpa/qplatformsessionmanager.h>
+
+QT_BEGIN_NAMESPACE
+
+class QCocoaSessionManager : public QPlatformSessionManager
+{
+public:
+ QCocoaSessionManager(const QString &id, const QString &key);
+ virtual ~QCocoaSessionManager();
+
+ bool allowsInteraction() override;
+ void cancel() override;
+ void resetCancellation();
+ bool wasCanceled() const;
+
+ static QCocoaSessionManager *instance();
+
+private:
+ bool m_canceled;
+
+ Q_DISABLE_COPY(QCocoaSessionManager)
+};
+
+QT_END_NAMESPACE
+
+#endif // QT_NO_SESSIONMANAGER
+
+#endif // QCOCOASESSIONMANAGER_H
diff --git a/src/plugins/platforms/cocoa/qcocoasystemtrayicon.h b/src/plugins/platforms/cocoa/qcocoasystemtrayicon.h
index 6779bda491..7999438ca5 100644
--- a/src/plugins/platforms/cocoa/qcocoasystemtrayicon.h
+++ b/src/plugins/platforms/cocoa/qcocoasystemtrayicon.h
@@ -49,14 +49,23 @@
#include "QtCore/qstring.h"
#include "QtGui/qpa/qplatformsystemtrayicon.h"
-QT_BEGIN_NAMESPACE
+#include "qcocoamenu.h"
+
+QT_FORWARD_DECLARE_CLASS(QCocoaSystemTrayIcon);
+
+@interface QT_MANGLE_NAMESPACE(QStatusItemDelegate) : NSObject <NSUserNotificationCenterDelegate>
+- (instancetype)initWithSysTray:(QCocoaSystemTrayIcon *)platformSystemTray;
+@property (nonatomic, assign) QCocoaSystemTrayIcon *platformSystemTray;
+@end
-class QSystemTrayIconSys;
+QT_NAMESPACE_ALIAS_OBJC_CLASS(QStatusItemDelegate);
+
+QT_BEGIN_NAMESPACE
class Q_GUI_EXPORT QCocoaSystemTrayIcon : public QPlatformSystemTrayIcon
{
public:
- QCocoaSystemTrayIcon() : m_sys(nullptr) {}
+ QCocoaSystemTrayIcon() {}
void init() override;
void cleanup() override;
@@ -65,13 +74,17 @@ public:
void updateMenu(QPlatformMenu *menu) override;
QRect geometry() const override;
void showMessage(const QString &title, const QString &msg,
- const QIcon& icon, MessageIcon iconType, int secs) override;
+ const QIcon& icon, MessageIcon iconType, int msecs) override;
bool isSystemTrayAvailable() const override;
bool supportsMessages() const override;
+ void statusItemClicked();
+
private:
- QSystemTrayIconSys *m_sys;
+ NSStatusItem *m_statusItem = nullptr;
+ QStatusItemDelegate *m_delegate = nullptr;
+ QCocoaMenu *m_menu = nullptr;
};
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/cocoa/qcocoasystemtrayicon.mm b/src/plugins/platforms/cocoa/qcocoasystemtrayicon.mm
index a5b42ac4e3..8e7c86a0ef 100644
--- a/src/plugins/platforms/cocoa/qcocoasystemtrayicon.mm
+++ b/src/plugins/platforms/cocoa/qcocoasystemtrayicon.mm
@@ -92,67 +92,46 @@
#import <AppKit/AppKit.h>
-QT_USE_NAMESPACE
-
-@interface QT_MANGLE_NAMESPACE(QNSStatusItem) : NSObject <NSUserNotificationCenterDelegate>
-@property (nonatomic, assign) QCocoaMenu *menu;
-@property (nonatomic, assign) QIcon icon;
-@property (nonatomic, readonly) NSStatusItem *item;
-@property (nonatomic, readonly) QRectF geometry;
-- (instancetype)initWithSysTray:(QCocoaSystemTrayIcon *)systray;
-- (void)triggerSelector:(id)sender button:(Qt::MouseButton)mouseButton;
-- (void)doubleClickSelector:(id)sender;
-@end
+QT_BEGIN_NAMESPACE
-QT_NAMESPACE_ALIAS_OBJC_CLASS(QNSStatusItem);
+void QCocoaSystemTrayIcon::init()
+{
+ m_statusItem = [[NSStatusBar.systemStatusBar statusItemWithLength:NSSquareStatusItemLength] retain];
-@interface QT_MANGLE_NAMESPACE(QNSImageView) : NSImageView
-@property (nonatomic, assign) BOOL down;
-@property (nonatomic, assign) QNSStatusItem *parent;
-@end
+ m_delegate = [[QStatusItemDelegate alloc] initWithSysTray:this];
-QT_NAMESPACE_ALIAS_OBJC_CLASS(QNSImageView);
+ m_statusItem.button.target = m_delegate;
+ m_statusItem.button.action = @selector(statusItemClicked);
+ [m_statusItem.button sendActionOn:NSEventMaskLeftMouseUp | NSEventMaskRightMouseUp | NSEventMaskOtherMouseUp];
+}
-QT_BEGIN_NAMESPACE
-class QSystemTrayIconSys
+void QCocoaSystemTrayIcon::cleanup()
{
-public:
- QSystemTrayIconSys(QCocoaSystemTrayIcon *sys) {
- item = [[QNSStatusItem alloc] initWithSysTray:sys];
- NSUserNotificationCenter.defaultUserNotificationCenter.delegate = item;
- }
- ~QSystemTrayIconSys() {
- [[[item item] view] setHidden: YES];
- NSUserNotificationCenter *center = NSUserNotificationCenter.defaultUserNotificationCenter;
- if (center.delegate == item)
- center.delegate = nil;
- [item release];
- }
- QNSStatusItem *item;
-};
+ NSUserNotificationCenter *center = NSUserNotificationCenter.defaultUserNotificationCenter;
+ if (center.delegate == m_delegate)
+ center.delegate = nil;
-void QCocoaSystemTrayIcon::init()
-{
- if (!m_sys)
- m_sys = new QSystemTrayIconSys(this);
+ [NSStatusBar.systemStatusBar removeStatusItem:m_statusItem];
+ [m_statusItem release];
+ m_statusItem = nil;
+
+ [m_delegate release];
+ m_delegate = nil;
+
+ m_menu = nullptr;
}
QRect QCocoaSystemTrayIcon::geometry() const
{
- if (!m_sys)
+ if (!m_statusItem)
return QRect();
- const QRectF geom = [m_sys->item geometry];
- if (!geom.isNull())
- return geom.toRect();
- else
- return QRect();
-}
+ if (NSWindow *window = m_statusItem.button.window) {
+ if (QCocoaScreen *screen = QCocoaScreen::get(window.screen))
+ return screen->mapFromNative(window.frame).toRect();
+ }
-void QCocoaSystemTrayIcon::cleanup()
-{
- delete m_sys;
- m_sys = nullptr;
+ return QRect();
}
static bool heightCompareFunction (QSize a, QSize b) { return (a.height() < b.height()); }
@@ -165,17 +144,15 @@ static QList<QSize> sortByHeight(const QList<QSize> &sizes)
void QCocoaSystemTrayIcon::updateIcon(const QIcon &icon)
{
- if (!m_sys)
+ if (!m_statusItem)
return;
- m_sys->item.icon = icon;
-
- // The reccomended maximum title bar icon height is 18 points
+ // The recommended maximum title bar icon height is 18 points
// (device independent pixels). The menu height on past and
// current OS X versions is 22 points. Provide some future-proofing
// by deriving the icon height from the menu height.
const int padding = 4;
- const int menuHeight = [[NSStatusBar systemStatusBar] thickness];
+ const int menuHeight = NSStatusBar.systemStatusBar.thickness;
const int maxImageHeight = menuHeight - padding;
// Select pixmap based on the device pixel height. Ideally we would use
@@ -228,30 +205,28 @@ void QCocoaSystemTrayIcon::updateIcon(const QIcon &icon)
p.drawPixmap(r, pixmap);
}
- NSImage *nsimage = static_cast<NSImage *>(qt_mac_create_nsimage(fullHeightPixmap));
+ auto *nsimage = [NSImage imageFromQImage:fullHeightPixmap.toImage()];
[nsimage setTemplate:icon.isMask()];
- [(NSImageView*)[[m_sys->item item] view] setImage: nsimage];
- [nsimage release];
+ m_statusItem.button.image = nsimage;
+ m_statusItem.button.imageScaling = NSImageScaleProportionallyDown;
}
void QCocoaSystemTrayIcon::updateMenu(QPlatformMenu *menu)
{
- if (!m_sys)
- return;
-
- m_sys->item.menu = static_cast<QCocoaMenu *>(menu);
- if (menu && [m_sys->item.menu->nsMenu() numberOfItems] > 0) {
- [[m_sys->item item] setHighlightMode:YES];
- } else {
- [[m_sys->item item] setHighlightMode:NO];
- }
+ // We don't set the menu property of the NSStatusItem here,
+ // as that would prevent us from receiving the action for the
+ // click, and we wouldn't be able to emit the activated signal.
+ // Instead we show the menu manually when the status item is
+ // clicked.
+ m_menu = static_cast<QCocoaMenu *>(menu);
}
void QCocoaSystemTrayIcon::updateToolTip(const QString &toolTip)
{
- if (!m_sys)
+ if (!m_statusItem)
return;
- [[[m_sys->item item] view] setToolTip:toolTip.toNSString()];
+
+ m_statusItem.button.toolTip = toolTip.toNSString();
}
bool QCocoaSystemTrayIcon::isSystemTrayAvailable() const
@@ -265,179 +240,85 @@ bool QCocoaSystemTrayIcon::supportsMessages() const
}
void QCocoaSystemTrayIcon::showMessage(const QString &title, const QString &message,
- const QIcon& icon, MessageIcon, int)
+ const QIcon& icon, MessageIcon, int msecs)
{
- if (!m_sys)
+ if (!m_statusItem)
return;
- NSUserNotification *notification = [[NSUserNotification alloc] init];
- notification.title = [NSString stringWithUTF8String:title.toUtf8().data()];
- notification.informativeText = [NSString stringWithUTF8String:message.toUtf8().data()];
-
- if (!icon.isNull()) {
- auto *nsimage = qt_mac_create_nsimage(icon);
- [nsimage setTemplate:icon.isMask()];
- notification.contentImage = [nsimage autorelease];
- }
+ auto *notification = [[NSUserNotification alloc] init];
+ notification.title = title.toNSString();
+ notification.informativeText = message.toNSString();
+ notification.contentImage = [NSImage imageFromQIcon:icon];
NSUserNotificationCenter *center = NSUserNotificationCenter.defaultUserNotificationCenter;
- center.delegate = m_sys->item;
- [center deliverNotification:notification];
- [notification release];
-}
-QT_END_NAMESPACE
+ center.delegate = m_delegate;
-@implementation NSStatusItem (Qt)
-@end
+ [center deliverNotification:[notification autorelease]];
-@implementation QNSImageView
-- (instancetype)initWithParent:(QNSStatusItem *)myParent {
- self = [super init];
- self.parent = myParent;
- self.down = NO;
- return self;
+ if (msecs) {
+ NSTimeInterval timeout = msecs / 1000.0;
+ [center performSelector:@selector(removeDeliveredNotification:) withObject:notification afterDelay:timeout];
+ }
}
-- (void)menuTrackingDone:(NSNotification *)__unused notification
+void QCocoaSystemTrayIcon::statusItemClicked()
{
- self.down = NO;
+ auto *mouseEvent = NSApp.currentEvent;
- [self setNeedsDisplay:YES];
-}
-
-- (void)mousePressed:(NSEvent *)mouseEvent
-{
- self.down = YES;
- int clickCount = [mouseEvent clickCount];
- [self setNeedsDisplay:YES];
+ auto activationReason = QPlatformSystemTrayIcon::Unknown;
- if (clickCount == 2) {
- [self menuTrackingDone:nil];
- [self.parent doubleClickSelector:self];
+ if (mouseEvent.clickCount == 2) {
+ activationReason = QPlatformSystemTrayIcon::DoubleClick;
} else {
- [self.parent triggerSelector:self button:cocoaButton2QtButton(mouseEvent)];
+ auto mouseButton = cocoaButton2QtButton(mouseEvent);
+ if (mouseButton == Qt::MidButton)
+ activationReason = QPlatformSystemTrayIcon::MiddleClick;
+ else if (mouseButton == Qt::RightButton)
+ activationReason = QPlatformSystemTrayIcon::Context;
+ else
+ activationReason = QPlatformSystemTrayIcon::Trigger;
}
-}
-- (void)mouseDown:(NSEvent *)mouseEvent
-{
- [self mousePressed:mouseEvent];
-}
+ emit activated(activationReason);
-- (void)mouseUp:(NSEvent *)mouseEvent
-{
- Q_UNUSED(mouseEvent);
- [self menuTrackingDone:nil];
+ if (NSMenu *menu = m_menu ? m_menu->nsMenu() : nil)
+ [m_statusItem popUpStatusItemMenu:menu];
}
-- (void)rightMouseDown:(NSEvent *)mouseEvent
-{
- [self mousePressed:mouseEvent];
-}
+QT_END_NAMESPACE
-- (void)rightMouseUp:(NSEvent *)mouseEvent
-{
- Q_UNUSED(mouseEvent);
- [self menuTrackingDone:nil];
-}
+@implementation QStatusItemDelegate
-- (void)otherMouseDown:(NSEvent *)mouseEvent
+- (instancetype)initWithSysTray:(QCocoaSystemTrayIcon *)platformSystemTray
{
- [self mousePressed:mouseEvent];
-}
+ if ((self = [super init]))
+ self.platformSystemTray = platformSystemTray;
-- (void)otherMouseUp:(NSEvent *)mouseEvent
-{
- Q_UNUSED(mouseEvent);
- [self menuTrackingDone:nil];
-}
-
-- (void)drawRect:(NSRect)rect {
- [[self.parent item] drawStatusBarBackgroundInRect:rect withHighlight:self.down];
- [super drawRect:rect];
-}
-@end
-
-@implementation QNSStatusItem {
- QCocoaSystemTrayIcon *systray;
- NSStatusItem *item;
- QNSImageView *imageCell;
-}
-
-@synthesize menu = menu;
-@synthesize icon = icon;
-
-- (instancetype)initWithSysTray:(QCocoaSystemTrayIcon *)sys
-{
- self = [super init];
- if (self) {
- item = [[[NSStatusBar systemStatusBar] statusItemWithLength:NSSquareStatusItemLength] retain];
- menu = nullptr;
- systray = sys;
- imageCell = [[QNSImageView alloc] initWithParent:self];
- [item setView: imageCell];
- }
return self;
}
-- (void)dealloc {
- [[NSStatusBar systemStatusBar] removeStatusItem:item];
- [[NSNotificationCenter defaultCenter] removeObserver:imageCell];
- imageCell.parent = nil;
- [imageCell release];
- [item release];
+- (void)dealloc
+{
+ self.platformSystemTray = nullptr;
[super dealloc];
}
-- (NSStatusItem *)item {
- return item;
-}
-
-- (QRectF)geometry {
- if (NSWindow *window = item.view.window) {
- if (QCocoaScreen *screen = QCocoaScreen::get(window.screen))
- return screen->mapFromNative(window.frame);
- }
- return QRectF();
-}
-
-- (void)triggerSelector:(id)sender button:(Qt::MouseButton)mouseButton {
- Q_UNUSED(sender);
- if (!systray)
- return;
-
- if (mouseButton == Qt::MidButton)
- emit systray->activated(QPlatformSystemTrayIcon::MiddleClick);
- else
- emit systray->activated(QPlatformSystemTrayIcon::Trigger);
-
- if (menu) {
- NSMenu *m = menu->nsMenu();
- [[NSNotificationCenter defaultCenter] addObserver:imageCell
- selector:@selector(menuTrackingDone:)
- name:NSMenuDidEndTrackingNotification
- object:m];
- [item popUpStatusItemMenu: m];
- }
-}
-
-- (void)doubleClickSelector:(id)sender {
- Q_UNUSED(sender);
- if (!systray)
- return;
- emit systray->activated(QPlatformSystemTrayIcon::DoubleClick);
+- (void)statusItemClicked
+{
+ self.platformSystemTray->statusItemClicked();
}
-- (BOOL)userNotificationCenter:(NSUserNotificationCenter *)center shouldPresentNotification:(NSUserNotification *)notification {
+- (BOOL)userNotificationCenter:(NSUserNotificationCenter *)center shouldPresentNotification:(NSUserNotification *)notification
+{
Q_UNUSED(center);
Q_UNUSED(notification);
return YES;
}
-- (void)userNotificationCenter:(NSUserNotificationCenter *)center didActivateNotification:(NSUserNotification *)notification {
- Q_UNUSED(center);
- Q_UNUSED(notification);
- emit systray->messageClicked();
+- (void)userNotificationCenter:(NSUserNotificationCenter *)center didActivateNotification:(NSUserNotification *)notification
+{
+ [center removeDeliveredNotification:notification];
+ emit self.platformSystemTray->messageClicked();
}
@end
diff --git a/src/plugins/platforms/cocoa/qcocoatheme.h b/src/plugins/platforms/cocoa/qcocoatheme.h
index a00cbdfea3..50e56ef1bf 100644
--- a/src/plugins/platforms/cocoa/qcocoatheme.h
+++ b/src/plugins/platforms/cocoa/qcocoatheme.h
@@ -70,7 +70,7 @@ public:
const QPalette *palette(Palette type = SystemPalette) const override;
const QFont *font(Font type = SystemFont) const override;
QPixmap standardPixmap(StandardPixmap sp, const QSizeF &size) const override;
- QIcon fileIcon(const QFileInfo &fileInfo, QPlatformTheme::IconOptions options = 0) const override;
+ QIcon fileIcon(const QFileInfo &fileInfo, QPlatformTheme::IconOptions options = {}) const override;
QVariant themeHint(ThemeHint hint) const override;
QString standardButtonText(int button) const override;
diff --git a/src/plugins/platforms/cocoa/qcocoavulkaninstance.h b/src/plugins/platforms/cocoa/qcocoavulkaninstance.h
index 5fe6a612af..2a8d04757e 100644
--- a/src/plugins/platforms/cocoa/qcocoavulkaninstance.h
+++ b/src/plugins/platforms/cocoa/qcocoavulkaninstance.h
@@ -61,9 +61,11 @@ public:
void createOrAdoptInstance() override;
- VkSurfaceKHR *createSurface(QWindow *window);
- VkSurfaceKHR createSurface(NSView *view);
+ VkSurfaceKHR *surface(QWindow *window);
+
private:
+ VkSurfaceKHR createSurface(NSView *view);
+
QVulkanInstance *m_instance = nullptr;
QLibrary m_lib;
VkSurfaceKHR m_nullSurface = nullptr;
diff --git a/src/plugins/platforms/cocoa/qcocoavulkaninstance.mm b/src/plugins/platforms/cocoa/qcocoavulkaninstance.mm
index 7ce78ee738..9e714859f2 100644
--- a/src/plugins/platforms/cocoa/qcocoavulkaninstance.mm
+++ b/src/plugins/platforms/cocoa/qcocoavulkaninstance.mm
@@ -57,12 +57,11 @@ void QCocoaVulkanInstance::createOrAdoptInstance()
initInstance(m_instance, QByteArrayList() << QByteArrayLiteral("VK_MVK_macos_surface"));
}
-VkSurfaceKHR *QCocoaVulkanInstance::createSurface(QWindow *window)
+VkSurfaceKHR *QCocoaVulkanInstance::surface(QWindow *window)
{
QCocoaWindow *cocoaWindow = static_cast<QCocoaWindow *>(window->handle());
- if (cocoaWindow->m_vulkanSurface)
- destroySurface(cocoaWindow->m_vulkanSurface);
- cocoaWindow->m_vulkanSurface = createSurface(cocoaWindow->m_view);
+ if (!cocoaWindow->m_vulkanSurface)
+ cocoaWindow->m_vulkanSurface = createSurface(cocoaWindow->m_view);
return &cocoaWindow->m_vulkanSurface;
}
@@ -81,7 +80,7 @@ VkSurfaceKHR QCocoaVulkanInstance::createSurface(NSView *view)
surfaceInfo.sType = VK_STRUCTURE_TYPE_MACOS_SURFACE_CREATE_INFO_MVK;
surfaceInfo.pNext = nullptr;
surfaceInfo.flags = 0;
- surfaceInfo.pView = view;
+ surfaceInfo.pView = view.layer;
VkSurfaceKHR surface = nullptr;
VkResult err = m_createSurface(m_vkInst, &surfaceInfo, nullptr, &surface);
diff --git a/src/plugins/platforms/cocoa/qcocoawindow.h b/src/plugins/platforms/cocoa/qcocoawindow.h
index fef72bc496..b15c0ac31c 100644
--- a/src/plugins/platforms/cocoa/qcocoawindow.h
+++ b/src/plugins/platforms/cocoa/qcocoawindow.h
@@ -218,6 +218,8 @@ protected:
void toggleFullScreen();
bool isTransitioningToFullScreen() const;
+ bool startSystemMove() override;
+
// private:
public: // for QNSView
friend class QCocoaBackingStore;
diff --git a/src/plugins/platforms/cocoa/qcocoawindow.mm b/src/plugins/platforms/cocoa/qcocoawindow.mm
index 69d192b4f5..c539afbfcd 100644
--- a/src/plugins/platforms/cocoa/qcocoawindow.mm
+++ b/src/plugins/platforms/cocoa/qcocoawindow.mm
@@ -299,6 +299,22 @@ void QCocoaWindow::setCocoaGeometry(const QRect &rect)
// will call QPlatformWindow::setGeometry(rect) during resize confirmation (see qnsview.mm)
}
+bool QCocoaWindow::startSystemMove()
+{
+ switch (NSApp.currentEvent.type) {
+ case NSEventTypeLeftMouseDown:
+ case NSEventTypeRightMouseDown:
+ case NSEventTypeOtherMouseDown:
+ case NSEventTypeMouseMoved:
+ // The documentation only describes starting a system move
+ // based on mouse down events, but move events also work.
+ [m_view.window performWindowDragWithEvent:NSApp.currentEvent];
+ return true;
+ default:
+ return false;
+ }
+}
+
void QCocoaWindow::setVisible(bool visible)
{
qCDebug(lcQpaWindow) << "QCocoaWindow::setVisible" << window() << visible;
@@ -878,14 +894,10 @@ void QCocoaWindow::setWindowIcon(const QIcon &icon)
QMacAutoReleasePool pool;
- if (icon.isNull()) {
- NSWorkspace *workspace = [NSWorkspace sharedWorkspace];
- [iconButton setImage:[workspace iconForFile:m_view.window.representedFilename]];
- } else {
- QPixmap pixmap = icon.pixmap(QSize(22, 22));
- NSImage *image = static_cast<NSImage *>(qt_mac_create_nsimage(pixmap));
- [iconButton setImage:[image autorelease]];
- }
+ if (icon.isNull())
+ iconButton.image = [NSWorkspace.sharedWorkspace iconForFile:m_view.window.representedFilename];
+ else
+ iconButton.image = [NSImage imageFromQIcon:icon];
}
void QCocoaWindow::setAlertState(bool enabled)
@@ -1224,7 +1236,9 @@ void QCocoaWindow::windowDidOrderOffScreen()
void QCocoaWindow::windowDidChangeOcclusionState()
{
- if (m_view.window.occlusionState & NSWindowOcclusionStateVisible)
+ bool visible = m_view.window.occlusionState & NSWindowOcclusionStateVisible;
+ qCDebug(lcQpaWindow) << "QCocoaWindow::windowDidChangeOcclusionState" << window() << "is now" << (visible ? "visible" : "occluded");
+ if (visible)
[m_view setNeedsDisplay:YES];
else
handleExposeEvent(QRegion());
@@ -1619,6 +1633,7 @@ QCocoaNSWindow *QCocoaWindow::createNSWindow(bool shouldBePanel)
nsWindow.restorable = NO;
nsWindow.level = windowLevel(flags);
+ nsWindow.tabbingMode = NSWindowTabbingModeDisallowed;
if (shouldBePanel) {
// Qt::Tool windows hide on app deactivation, unless Qt::WA_MacAlwaysShowToolWindow is set
diff --git a/src/plugins/platforms/cocoa/qmacclipboard.mm b/src/plugins/platforms/cocoa/qmacclipboard.mm
index 358a6b49fd..654647b35a 100644
--- a/src/plugins/platforms/cocoa/qmacclipboard.mm
+++ b/src/plugins/platforms/cocoa/qmacclipboard.mm
@@ -138,8 +138,12 @@ QMacPasteboard::QMacPasteboard(CFStringRef name, uchar mt)
QMacPasteboard::~QMacPasteboard()
{
- // commit all promises for paste after exit close
- resolvingBeforeDestruction = true;
+ /*
+ Commit all promises for paste when shutting down,
+ unless we are the stack-allocated clipboard used by QCocoaDrag.
+ */
+ if (mime_type == QMacInternalPasteboardMime::MIME_DND)
+ resolvingBeforeDestruction = true;
PasteboardResolvePromises(paste);
if (paste)
CFRelease(paste);
diff --git a/src/plugins/platforms/cocoa/qnsview_dragging.mm b/src/plugins/platforms/cocoa/qnsview_dragging.mm
index 650612e7ff..463e3c5579 100644
--- a/src/plugins/platforms/cocoa/qnsview_dragging.mm
+++ b/src/plugins/platforms/cocoa/qnsview_dragging.mm
@@ -150,10 +150,8 @@ static QPoint mapWindowCoordinates(QWindow *source, QWindow *target, QPoint poin
break;
}
} else {
- NSImage *nsimage = qt_mac_create_nsimage(pixmapCursor);
- nsimage.size = NSSizeFromCGSize((pixmapCursor.size() / pixmapCursor.devicePixelRatioF()).toCGSize());
+ auto *nsimage = [NSImage imageFromQImage:pixmapCursor.toImage()];
nativeCursor = [[NSCursor alloc] initWithImage:nsimage hotSpot:NSZeroPoint];
- [nsimage release];
}
// Change the cursor
diff --git a/src/plugins/platforms/cocoa/qnsview_menus.mm b/src/plugins/platforms/cocoa/qnsview_menus.mm
index a55fd97eb7..b6cd832282 100644
--- a/src/plugins/platforms/cocoa/qnsview_menus.mm
+++ b/src/plugins/platforms/cocoa/qnsview_menus.mm
@@ -84,7 +84,8 @@ static bool selectorIsCutCopyPaste(SEL selector)
menuParent = menuObject->menuParent();
}
- if (menubar && menubar->cocoaWindow() != self.platformWindow)
+ // we have no menubar parent for the application menu items, e.g About and Preferences
+ if (!menubar || menubar->cocoaWindow() != self.platformWindow)
return NO;
}
diff --git a/src/plugins/platforms/cocoa/qpaintengine_mac.mm b/src/plugins/platforms/cocoa/qpaintengine_mac.mm
index 00b2267f0d..df71f76644 100644
--- a/src/plugins/platforms/cocoa/qpaintengine_mac.mm
+++ b/src/plugins/platforms/cocoa/qpaintengine_mac.mm
@@ -394,16 +394,19 @@ QCoreGraphicsPaintEngine::begin(QPaintDevice *pdev)
d->cosmeticPenSize = 1;
d->current.clipEnabled = false;
d->pixelSize = QPoint(1,1);
- QMacCGContext ctx(pdev);
- d->hd = CGContextRetain(ctx);
- if (d->hd) {
- d->saveGraphicsState();
- d->orig_xform = CGContextGetCTM(d->hd);
- if (d->shading) {
- CGShadingRelease(d->shading);
- d->shading = nullptr;
+
+ if (pdev->devType() != QInternal::Printer) {
+ QMacCGContext ctx(pdev);
+ d->hd = CGContextRetain(ctx);
+ if (d->hd) {
+ d->saveGraphicsState();
+ d->orig_xform = CGContextGetCTM(d->hd);
+ if (d->shading) {
+ CGShadingRelease(d->shading);
+ d->shading = nullptr;
+ }
+ d->setClip(nullptr); //clear the context's clipping
}
- d->setClip(nullptr); //clear the context's clipping
}
setActive(true);
diff --git a/src/plugins/platforms/eglfs/api/api.pri b/src/plugins/platforms/eglfs/api/api.pri
index a6d81016b6..68965b58d8 100644
--- a/src/plugins/platforms/eglfs/api/api.pri
+++ b/src/plugins/platforms/eglfs/api/api.pri
@@ -23,4 +23,13 @@ qtConfig(opengl) {
$$PWD/qeglfscontext_p.h
}
+qtConfig(vulkan) {
+ SOURCES += \
+ $$PWD/vulkan/qeglfsvulkaninstance.cpp \
+ $$PWD/vulkan/qeglfsvulkanwindow.cpp
+ HEADERS += \
+ $$PWD/vulkan/qeglfsvulkaninstance_p.h \
+ $$PWD/vulkan/qeglfsvulkanwindow_p.h
+}
+
INCLUDEPATH += $$PWD
diff --git a/src/plugins/platforms/eglfs/api/qeglfscontext.cpp b/src/plugins/platforms/eglfs/api/qeglfscontext.cpp
index c5cef34d8e..48fafbda8d 100644
--- a/src/plugins/platforms/eglfs/api/qeglfscontext.cpp
+++ b/src/plugins/platforms/eglfs/api/qeglfscontext.cpp
@@ -52,7 +52,7 @@ QT_BEGIN_NAMESPACE
QEglFSContext::QEglFSContext(const QSurfaceFormat &format, QPlatformOpenGLContext *share, EGLDisplay display,
EGLConfig *config, const QVariant &nativeHandle)
: QEGLPlatformContext(format, share, display, config, nativeHandle,
- qt_egl_device_integration()->supportsSurfacelessContexts() ? Flags(0) : QEGLPlatformContext::NoSurfaceless),
+ qt_egl_device_integration()->supportsSurfacelessContexts() ? Flags() : QEGLPlatformContext::NoSurfaceless),
m_tempWindow(0)
{
}
@@ -78,7 +78,7 @@ EGLSurface QEglFSContext::createTemporaryOffscreenSurface()
}
}
EGLConfig config = q_configFromGLFormat(eglDisplay(), format());
- return eglCreateWindowSurface(eglDisplay(), config, m_tempWindow, 0);
+ return eglCreateWindowSurface(eglDisplay(), config, m_tempWindow, nullptr);
}
void QEglFSContext::destroyTemporaryOffscreenSurface(EGLSurface surface)
diff --git a/src/plugins/platforms/eglfs/api/qeglfscursor.cpp b/src/plugins/platforms/eglfs/api/qeglfscursor.cpp
index 22319fcc66..98e05195ee 100644
--- a/src/plugins/platforms/eglfs/api/qeglfscursor.cpp
+++ b/src/plugins/platforms/eglfs/api/qeglfscursor.cpp
@@ -62,7 +62,7 @@ QEglFSCursor::QEglFSCursor(QPlatformScreen *screen)
: m_visible(true),
m_screen(static_cast<QEglFSScreen *>(screen)),
m_activeScreen(nullptr),
- m_deviceListener(0),
+ m_deviceListener(nullptr),
m_updateRequested(false)
{
QByteArray hideCursorVal = qgetenv("QT_QPA_EGLFS_HIDECURSOR");
diff --git a/src/plugins/platforms/eglfs/api/qeglfsdeviceintegration.cpp b/src/plugins/platforms/eglfs/api/qeglfsdeviceintegration.cpp
index 81bad45cd2..b985386a4e 100644
--- a/src/plugins/platforms/eglfs/api/qeglfsdeviceintegration.cpp
+++ b/src/plugins/platforms/eglfs/api/qeglfsdeviceintegration.cpp
@@ -52,6 +52,7 @@
#include <QScreen>
#include <QDir>
#if QT_CONFIG(regularexpression)
+# include <QFileInfo>
# include <QRegularExpression>
#endif
#include <QLoggingCategory>
@@ -144,7 +145,12 @@ int QEglFSDeviceIntegration::framebufferIndex() const
int fbIndex = 0;
#if QT_CONFIG(regularexpression)
QRegularExpression fbIndexRx(QLatin1String("fb(\\d+)"));
- QRegularExpressionMatch match = fbIndexRx.match(QString::fromLocal8Bit(fbDeviceName()));
+ QFileInfo fbinfo(QString::fromLocal8Bit(fbDeviceName()));
+ QRegularExpressionMatch match;
+ if (fbinfo.isSymLink())
+ match = fbIndexRx.match(fbinfo.symLinkTarget());
+ else
+ match = fbIndexRx.match(fbinfo.fileName());
if (match.hasMatch())
fbIndex = match.captured(1).toInt();
#endif
@@ -179,7 +185,9 @@ void QEglFSDeviceIntegration::platformDestroy()
EGLNativeDisplayType QEglFSDeviceIntegration::platformDisplay() const
{
- return EGL_DEFAULT_DISPLAY;
+ bool displayOk;
+ const int defaultDisplay = qEnvironmentVariableIntValue("QT_QPA_EGLFS_DEFAULT_DISPLAY", &displayOk);
+ return displayOk ? EGLNativeDisplayType(quintptr(defaultDisplay)) : EGL_DEFAULT_DISPLAY;
}
EGLDisplay QEglFSDeviceIntegration::createDisplay(EGLNativeDisplayType nativeDisplay)
@@ -375,6 +383,14 @@ void *QEglFSDeviceIntegration::wlDisplay() const
return nullptr;
}
+#if QT_CONFIG(vulkan)
+QPlatformVulkanInstance *QEglFSDeviceIntegration::createPlatformVulkanInstance(QVulkanInstance *instance)
+{
+ Q_UNUSED(instance);
+ return nullptr;
+}
+#endif
+
EGLConfig QEglFSDeviceIntegration::chooseConfig(EGLDisplay display, const QSurfaceFormat &format)
{
class Chooser : public QEglConfigChooser {
diff --git a/src/plugins/platforms/eglfs/api/qeglfsdeviceintegration_p.h b/src/plugins/platforms/eglfs/api/qeglfsdeviceintegration_p.h
index 71ffb4c69a..08447a40ea 100644
--- a/src/plugins/platforms/eglfs/api/qeglfsdeviceintegration_p.h
+++ b/src/plugins/platforms/eglfs/api/qeglfsdeviceintegration_p.h
@@ -108,6 +108,10 @@ public:
virtual void *nativeResourceForScreen(const QByteArray &resource, QScreen *screen);
virtual void *wlDisplay() const;
+#if QT_CONFIG(vulkan)
+ virtual QPlatformVulkanInstance *createPlatformVulkanInstance(QVulkanInstance *instance);
+#endif
+
static EGLConfig chooseConfig(EGLDisplay display, const QSurfaceFormat &format);
};
diff --git a/src/plugins/platforms/eglfs/api/qeglfsintegration.cpp b/src/plugins/platforms/eglfs/api/qeglfsintegration.cpp
index 674f579b4f..e26d984cc1 100644
--- a/src/plugins/platforms/eglfs/api/qeglfsintegration.cpp
+++ b/src/plugins/platforms/eglfs/api/qeglfsintegration.cpp
@@ -109,10 +109,10 @@ QT_BEGIN_NAMESPACE
QEglFSIntegration::QEglFSIntegration()
: m_display(EGL_NO_DISPLAY),
- m_inputContext(0),
+ m_inputContext(nullptr),
m_fontDb(new QGenericUnixFontDatabase),
m_services(new QGenericUnixServices),
- m_kbdMgr(0),
+ m_kbdMgr(nullptr),
m_disableInputHandlers(false)
{
m_disableInputHandlers = qEnvironmentVariableIntValue("QT_QPA_EGLFS_DISABLE_INPUT");
@@ -223,7 +223,7 @@ QPlatformOpenGLContext *QEglFSIntegration::createPlatformOpenGLContext(QOpenGLCo
EGLConfig config = QEglFSDeviceIntegration::chooseConfig(dpy, adjustedFormat);
ctx = new QEglFSContext(adjustedFormat, share, dpy, &config, QVariant());
} else {
- ctx = new QEglFSContext(adjustedFormat, share, dpy, 0, nativeHandle);
+ ctx = new QEglFSContext(adjustedFormat, share, dpy, nullptr, nativeHandle);
}
nativeHandle = QVariant::fromValue<QEGLNativeContext>(QEGLNativeContext(ctx->eglContext(), dpy));
@@ -236,7 +236,7 @@ QPlatformOffscreenSurface *QEglFSIntegration::createPlatformOffscreenSurface(QOf
EGLDisplay dpy = surface->screen() ? static_cast<QEglFSScreen *>(surface->screen()->handle())->display() : display();
QSurfaceFormat fmt = qt_egl_device_integration()->surfaceFormatFor(surface->requestedFormat());
if (qt_egl_device_integration()->supportsPBuffers()) {
- QEGLPlatformContext::Flags flags = 0;
+ QEGLPlatformContext::Flags flags;
if (!qt_egl_device_integration()->supportsSurfacelessContexts())
flags |= QEGLPlatformContext::NoSurfaceless;
return new QEGLPbuffer(dpy, fmt, surface, flags);
@@ -247,6 +247,13 @@ QPlatformOffscreenSurface *QEglFSIntegration::createPlatformOffscreenSurface(QOf
}
#endif // QT_NO_OPENGL
+#if QT_CONFIG(vulkan)
+QPlatformVulkanInstance *QEglFSIntegration::createPlatformVulkanInstance(QVulkanInstance *instance) const
+{
+ return qt_egl_device_integration()->createPlatformVulkanInstance(instance);
+}
+#endif
+
bool QEglFSIntegration::hasCapability(QPlatformIntegration::Capability cap) const
{
// We assume that devices will have more and not less capabilities
@@ -283,7 +290,8 @@ enum ResourceType {
NativeDisplay,
XlibDisplay,
WaylandDisplay,
- EglSurface
+ EglSurface,
+ VkSurface
};
static int resourceType(const QByteArray &key)
@@ -296,7 +304,8 @@ static int resourceType(const QByteArray &key)
QByteArrayLiteral("nativedisplay"),
QByteArrayLiteral("display"),
QByteArrayLiteral("server_wl_display"),
- QByteArrayLiteral("eglsurface")
+ QByteArrayLiteral("eglsurface"),
+ QByteArrayLiteral("vksurface")
};
const QByteArray *end = names + sizeof(names) / sizeof(names[0]);
const QByteArray *result = std::find(names, end, key);
@@ -307,7 +316,7 @@ static int resourceType(const QByteArray &key)
void *QEglFSIntegration::nativeResourceForIntegration(const QByteArray &resource)
{
- void *result = 0;
+ void *result = nullptr;
switch (resourceType(resource)) {
case EglDisplay:
@@ -329,7 +338,7 @@ void *QEglFSIntegration::nativeResourceForIntegration(const QByteArray &resource
void *QEglFSIntegration::nativeResourceForScreen(const QByteArray &resource, QScreen *screen)
{
- void *result = 0;
+ void *result = nullptr;
switch (resourceType(resource)) {
case XlibDisplay:
@@ -347,7 +356,7 @@ void *QEglFSIntegration::nativeResourceForScreen(const QByteArray &resource, QSc
void *QEglFSIntegration::nativeResourceForWindow(const QByteArray &resource, QWindow *window)
{
- void *result = 0;
+ void *result = nullptr;
switch (resourceType(resource)) {
case EglDisplay:
@@ -364,6 +373,12 @@ void *QEglFSIntegration::nativeResourceForWindow(const QByteArray &resource, QWi
if (window && window->handle())
result = reinterpret_cast<void*>(static_cast<QEglFSWindow *>(window->handle())->surface());
break;
+#if QT_CONFIG(vulkan)
+ case VkSurface:
+ if (window && window->handle() && window->surfaceType() == QSurface::VulkanSurface)
+ result = static_cast<QEglFSWindow *>(window->handle())->vulkanSurfacePtr();
+ break;
+#endif
default:
break;
}
@@ -374,7 +389,7 @@ void *QEglFSIntegration::nativeResourceForWindow(const QByteArray &resource, QWi
#ifndef QT_NO_OPENGL
void *QEglFSIntegration::nativeResourceForContext(const QByteArray &resource, QOpenGLContext *context)
{
- void *result = 0;
+ void *result = nullptr;
switch (resourceType(resource)) {
case EglContext:
@@ -402,7 +417,7 @@ static void *eglContextForContext(QOpenGLContext *context)
QEglFSContext *handle = static_cast<QEglFSContext *>(context->handle());
if (!handle)
- return 0;
+ return nullptr;
return handle->eglContext();
}
@@ -416,7 +431,7 @@ QPlatformNativeInterface::NativeResourceForContextFunction QEglFSIntegration::na
#else
Q_UNUSED(resource);
#endif
- return 0;
+ return nullptr;
}
QFunctionPointer QEglFSIntegration::platformFunction(const QByteArray &function) const
diff --git a/src/plugins/platforms/eglfs/api/qeglfsintegration_p.h b/src/plugins/platforms/eglfs/api/qeglfsintegration_p.h
index 898b322834..b293651ce7 100644
--- a/src/plugins/platforms/eglfs/api/qeglfsintegration_p.h
+++ b/src/plugins/platforms/eglfs/api/qeglfsintegration_p.h
@@ -86,6 +86,9 @@ public:
QPlatformOpenGLContext *createPlatformOpenGLContext(QOpenGLContext *context) const override;
QPlatformOffscreenSurface *createPlatformOffscreenSurface(QOffscreenSurface *surface) const override;
#endif
+#if QT_CONFIG(vulkan)
+ QPlatformVulkanInstance *createPlatformVulkanInstance(QVulkanInstance *instance) const override;
+#endif
bool hasCapability(QPlatformIntegration::Capability cap) const override;
QPlatformNativeInterface *nativeInterface() const override;
diff --git a/src/plugins/platforms/eglfs/api/qeglfsoffscreenwindow.cpp b/src/plugins/platforms/eglfs/api/qeglfsoffscreenwindow.cpp
index 864271cd3a..c96e329816 100644
--- a/src/plugins/platforms/eglfs/api/qeglfsoffscreenwindow.cpp
+++ b/src/plugins/platforms/eglfs/api/qeglfsoffscreenwindow.cpp
@@ -67,7 +67,7 @@ QEglFSOffscreenWindow::QEglFSOffscreenWindow(EGLDisplay display, const QSurfaceF
return;
}
EGLConfig config = q_configFromGLFormat(m_display, m_format);
- m_surface = eglCreateWindowSurface(m_display, config, m_window, 0);
+ m_surface = eglCreateWindowSurface(m_display, config, m_window, nullptr);
if (m_surface != EGL_NO_SURFACE)
m_format = q_glFormatFromConfig(m_display, config);
}
diff --git a/src/plugins/platforms/eglfs/api/qeglfsscreen.cpp b/src/plugins/platforms/eglfs/api/qeglfsscreen.cpp
index 11b68c0589..8a8e8cd563 100644
--- a/src/plugins/platforms/eglfs/api/qeglfsscreen.cpp
+++ b/src/plugins/platforms/eglfs/api/qeglfsscreen.cpp
@@ -54,7 +54,7 @@ QT_BEGIN_NAMESPACE
QEglFSScreen::QEglFSScreen(EGLDisplay dpy)
: m_dpy(dpy),
m_surface(EGL_NO_SURFACE),
- m_cursor(0)
+ m_cursor(nullptr)
{
m_cursor = qt_egl_device_integration()->createCursor(this);
}
@@ -164,7 +164,7 @@ void QEglFSScreen::handleCursorMove(const QPoint &pos)
return;
}
- QWindow *enter = 0, *leave = 0;
+ QWindow *enter = nullptr, *leave = nullptr;
for (int i = windows.count() - 1; i >= 0; --i) {
QWindow *window = windows[i]->sourceWindow();
const QRect geom = window->geometry();
diff --git a/src/plugins/platforms/eglfs/api/qeglfswindow.cpp b/src/plugins/platforms/eglfs/api/qeglfswindow.cpp
index 1fed182882..f7e116eb88 100644
--- a/src/plugins/platforms/eglfs/api/qeglfswindow.cpp
+++ b/src/plugins/platforms/eglfs/api/qeglfswindow.cpp
@@ -61,13 +61,12 @@ QT_BEGIN_NAMESPACE
QEglFSWindow::QEglFSWindow(QWindow *w)
: QPlatformWindow(w),
#ifndef QT_NO_OPENGL
- m_backingStore(0),
- m_rasterCompositingContext(0),
+ m_backingStore(nullptr),
+ m_rasterCompositingContext(nullptr),
#endif
m_winId(0),
m_surface(EGL_NO_SURFACE),
- m_window(0),
- m_flags(0)
+ m_window(0)
{
}
@@ -186,7 +185,7 @@ void QEglFSWindow::destroy()
#endif
}
- m_flags = 0;
+ m_flags = { };
}
void QEglFSWindow::invalidateSurface()
@@ -208,7 +207,7 @@ void QEglFSWindow::resetSurface()
m_format = q_glFormatFromConfig(display, m_config, platformFormat);
const QSize surfaceSize = screen()->rawGeometry().size();
m_window = qt_egl_device_integration()->createNativeWindow(this, surfaceSize, m_format);
- m_surface = eglCreateWindowSurface(display, m_config, m_window, NULL);
+ m_surface = eglCreateWindowSurface(display, m_config, m_window, nullptr);
}
void QEglFSWindow::setVisible(bool visible)
@@ -338,7 +337,7 @@ const QPlatformTextureList *QEglFSWindow::textures() const
if (m_backingStore)
return m_backingStore->textures();
- return 0;
+ return nullptr;
}
void QEglFSWindow::endCompositing()
diff --git a/src/plugins/platforms/eglfs/api/qeglfswindow_p.h b/src/plugins/platforms/eglfs/api/qeglfswindow_p.h
index be2a0630d3..7bf74c25ee 100644
--- a/src/plugins/platforms/eglfs/api/qeglfswindow_p.h
+++ b/src/plugins/platforms/eglfs/api/qeglfswindow_p.h
@@ -64,6 +64,7 @@ QT_BEGIN_NAMESPACE
class QOpenGLCompositorBackingStore;
class QPlatformTextureList;
+
#ifndef QT_NO_OPENGL
class Q_EGLFS_EXPORT QEglFSWindow : public QPlatformWindow, public QOpenGLCompositorWindow
#else
@@ -96,6 +97,9 @@ public:
EGLNativeWindowType eglWindow() const;
EGLSurface surface() const;
QEglFSScreen *screen() const override;
+#if QT_CONFIG(vulkan)
+ virtual void *vulkanSurfacePtr() { return nullptr; }
+#endif
bool hasNativeWindow() const { return m_flags.testFlag(HasNativeWindow); }
diff --git a/src/plugins/platforms/eglfs/api/vulkan/qeglfsvulkaninstance.cpp b/src/plugins/platforms/eglfs/api/vulkan/qeglfsvulkaninstance.cpp
new file mode 100644
index 0000000000..a75251ca5f
--- /dev/null
+++ b/src/plugins/platforms/eglfs/api/vulkan/qeglfsvulkaninstance.cpp
@@ -0,0 +1,280 @@
+/****************************************************************************
+**
+** Copyright (C) 2020 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qeglfsvulkaninstance_p.h"
+#include "qeglfswindow_p.h"
+#include "qeglfshooks_p.h"
+#include <QLoggingCategory>
+
+QT_BEGIN_NAMESPACE
+
+Q_DECLARE_LOGGING_CATEGORY(qLcEglDevDebug)
+
+QEglFSVulkanInstance::QEglFSVulkanInstance(QVulkanInstance *instance)
+ : m_instance(instance)
+{
+ loadVulkanLibrary(QStringLiteral("vulkan"));
+}
+
+void QEglFSVulkanInstance::createOrAdoptInstance()
+{
+ qCDebug(qLcEglDevDebug, "Creating Vulkan instance for VK_KHR_display");
+
+ const QByteArray extName = QByteArrayLiteral("VK_KHR_display");
+ initInstance(m_instance, { extName });
+ if (!m_vkInst)
+ return;
+ if (!enabledExtensions().contains(extName)) {
+ qWarning("Failed to enable VK_KHR_display extension");
+ return;
+ }
+
+#if VK_KHR_display
+ m_getPhysicalDeviceDisplayPropertiesKHR = (PFN_vkGetPhysicalDeviceDisplayPropertiesKHR)
+ m_vkGetInstanceProcAddr(m_vkInst, "vkGetPhysicalDeviceDisplayPropertiesKHR");
+ m_getDisplayModePropertiesKHR = (PFN_vkGetDisplayModePropertiesKHR)
+ m_vkGetInstanceProcAddr(m_vkInst, "vkGetDisplayModePropertiesKHR");
+ m_getPhysicalDeviceDisplayPlanePropertiesKHR = (PFN_vkGetPhysicalDeviceDisplayPlanePropertiesKHR)
+ m_vkGetInstanceProcAddr(m_vkInst, "vkGetPhysicalDeviceDisplayPlanePropertiesKHR");
+
+ m_getDisplayPlaneSupportedDisplaysKHR = (PFN_vkGetDisplayPlaneSupportedDisplaysKHR)
+ m_vkGetInstanceProcAddr(m_vkInst, "vkGetDisplayPlaneSupportedDisplaysKHR");
+ m_getDisplayPlaneCapabilitiesKHR = (PFN_vkGetDisplayPlaneCapabilitiesKHR)
+ m_vkGetInstanceProcAddr(m_vkInst, "vkGetDisplayPlaneCapabilitiesKHR");
+
+ m_createDisplayPlaneSurfaceKHR = (PFN_vkCreateDisplayPlaneSurfaceKHR)
+ m_vkGetInstanceProcAddr(m_vkInst, "vkCreateDisplayPlaneSurfaceKHR");
+#endif
+
+ m_enumeratePhysicalDevices = (PFN_vkEnumeratePhysicalDevices)
+ m_vkGetInstanceProcAddr(m_vkInst, "vkEnumeratePhysicalDevices");
+
+ // Use for first physical device, unless overridden by QT_VK_PHYSICAL_DEVICE_INDEX.
+ // This behavior matches what the Vulkan backend of QRhi would do.
+
+ uint32_t physDevCount = 0;
+ m_enumeratePhysicalDevices(m_vkInst, &physDevCount, nullptr);
+ if (!physDevCount) {
+ qWarning("No physical devices");
+ return;
+ }
+ QVarLengthArray<VkPhysicalDevice, 4> physDevs(physDevCount);
+ VkResult err = m_enumeratePhysicalDevices(m_vkInst, &physDevCount, physDevs.data());
+ if (err != VK_SUCCESS || !physDevCount) {
+ qWarning("Failed to enumerate physical devices: %d", err);
+ return;
+ }
+
+ if (qEnvironmentVariableIsSet("QT_VK_PHYSICAL_DEVICE_INDEX")) {
+ int requestedPhysDevIndex = qEnvironmentVariableIntValue("QT_VK_PHYSICAL_DEVICE_INDEX");
+ if (requestedPhysDevIndex >= 0 && uint32_t(requestedPhysDevIndex) < physDevCount)
+ m_physDev = physDevs[requestedPhysDevIndex];
+ }
+
+ if (m_physDev == VK_NULL_HANDLE)
+ m_physDev = physDevs[0];
+}
+
+bool QEglFSVulkanInstance::supportsPresent(VkPhysicalDevice physicalDevice,
+ uint32_t queueFamilyIndex,
+ QWindow *window)
+{
+ Q_UNUSED(physicalDevice);
+ Q_UNUSED(queueFamilyIndex);
+ Q_UNUSED(window);
+ return true;
+}
+
+VkSurfaceKHR QEglFSVulkanInstance::createSurface(QEglFSWindow *window)
+{
+#if VK_KHR_display
+ qCDebug(qLcEglDevDebug, "Creating VkSurfaceKHR via VK_KHR_display for window %p", (void *) window);
+
+ if (!m_physDev) {
+ qWarning("No physical device, cannot create surface");
+ return VK_NULL_HANDLE;
+ }
+
+ uint32_t displayCount = 0;
+ VkResult err = m_getPhysicalDeviceDisplayPropertiesKHR(m_physDev, &displayCount, nullptr);
+ if (err != VK_SUCCESS) {
+ qWarning("Failed to get display properties: %d", err);
+ return VK_NULL_HANDLE;
+ }
+
+ qCDebug(qLcEglDevDebug, "Display count: %u", displayCount);
+
+ QVarLengthArray<VkDisplayPropertiesKHR, 4> displayProps(displayCount);
+ m_getPhysicalDeviceDisplayPropertiesKHR(m_physDev, &displayCount, displayProps.data());
+
+ VkDisplayKHR display = VK_NULL_HANDLE;
+ VkDisplayModeKHR displayMode = VK_NULL_HANDLE;
+ uint32_t width = 0;
+ uint32_t height = 0;
+
+ for (uint32_t i = 0; i < displayCount; ++i) {
+ const VkDisplayPropertiesKHR &disp(displayProps[i]);
+ qCDebug(qLcEglDevDebug, "Display #%u:\n display: %p\n name: %s\n dimensions: %ux%u\n resolution: %ux%u",
+ i, (void *) disp.display, disp.displayName,
+ disp.physicalDimensions.width, disp.physicalDimensions.height,
+ disp.physicalResolution.width, disp.physicalResolution.height);
+
+ // Just pick the first display and the first mode.
+ if (i == 0)
+ display = disp.display;
+
+ uint32_t modeCount = 0;
+ if (m_getDisplayModePropertiesKHR(m_physDev, disp.display, &modeCount, nullptr) != VK_SUCCESS) {
+ qWarning("Failed to get modes for display");
+ continue;
+ }
+ QVarLengthArray<VkDisplayModePropertiesKHR, 16> modeProps(modeCount);
+ m_getDisplayModePropertiesKHR(m_physDev, disp.display, &modeCount, modeProps.data());
+ for (uint32_t j = 0; j < modeCount; ++j) {
+ const VkDisplayModePropertiesKHR &mode(modeProps[j]);
+ qCDebug(qLcEglDevDebug, " Mode #%u:\n mode: %p\n visibleRegion: %ux%u\n refreshRate: %u",
+ j, (void *) mode.displayMode,
+ mode.parameters.visibleRegion.width, mode.parameters.visibleRegion.height,
+ mode.parameters.refreshRate);
+ if (j == 0) {
+ displayMode = mode.displayMode;
+ width = mode.parameters.visibleRegion.width;
+ height = mode.parameters.visibleRegion.height;
+ }
+ }
+ }
+
+ if (display == VK_NULL_HANDLE || displayMode == VK_NULL_HANDLE) {
+ qWarning("Failed to choose display and mode");
+ return VK_NULL_HANDLE;
+ }
+ uint32_t planeCount = 0;
+ err = m_getPhysicalDeviceDisplayPlanePropertiesKHR(m_physDev, &planeCount, nullptr);
+ if (err != VK_SUCCESS) {
+ qWarning("Failed to get plane properties: %d", err);
+ return VK_NULL_HANDLE;
+ }
+
+ qCDebug(qLcEglDevDebug, "Plane count: %u", planeCount);
+
+ QVarLengthArray<VkDisplayPlanePropertiesKHR, 4> planeProps(planeCount);
+ m_getPhysicalDeviceDisplayPlanePropertiesKHR(m_physDev, &planeCount, planeProps.data());
+
+ uint32_t planeIndex = UINT_MAX;
+ for (uint32_t i = 0; i < planeCount; ++i) {
+ uint32_t supportedDisplayCount = 0;
+ err = m_getDisplayPlaneSupportedDisplaysKHR(m_physDev, i, &supportedDisplayCount, nullptr);
+ if (err != VK_SUCCESS) {
+ qWarning("Failed to query supported displays for plane: %d", err);
+ return VK_NULL_HANDLE;
+ }
+
+ QVarLengthArray<VkDisplayKHR, 4> supportedDisplays(supportedDisplayCount);
+ m_getDisplayPlaneSupportedDisplaysKHR(m_physDev, i, &supportedDisplayCount, supportedDisplays.data());
+ qCDebug(qLcEglDevDebug, "Plane #%u supports %u displays, currently bound to display %p",
+ i, supportedDisplayCount, (void *) planeProps[i].currentDisplay);
+
+ VkDisplayPlaneCapabilitiesKHR caps;
+ err = m_getDisplayPlaneCapabilitiesKHR(m_physDev, displayMode, i, &caps);
+ if (err != VK_SUCCESS) {
+ qWarning("Failed to query plane capabilities: %d", err);
+ return VK_NULL_HANDLE;
+ }
+
+ qCDebug(qLcEglDevDebug, " supportedAlpha: %d (1=no, 2=global, 4=per pixel, 8=per pixel premul)\n"
+ " minSrc=%d, %d %ux%u\n"
+ " maxSrc=%d, %d %ux%u\n"
+ " minDst=%d, %d %ux%u\n"
+ " maxDst=%d, %d %ux%u",
+ int(caps.supportedAlpha),
+ caps.minSrcPosition.x, caps.minSrcPosition.y, caps.minSrcExtent.width, caps.minSrcExtent.height,
+ caps.maxSrcPosition.x, caps.maxSrcPosition.y, caps.maxSrcExtent.width, caps.maxSrcExtent.height,
+ caps.minDstPosition.x, caps.minDstPosition.y, caps.minDstExtent.width, caps.minDstExtent.height,
+ caps.maxDstPosition.x, caps.maxDstPosition.y, caps.maxDstExtent.width, caps.maxDstExtent.height);
+
+ // if the plane is not in use and supports our chosen display, use that plane
+ if (supportedDisplays.contains(display)
+ && (planeProps[i].currentDisplay == VK_NULL_HANDLE || planeProps[i].currentDisplay == display))
+ {
+ planeIndex = i;
+ }
+ }
+
+ if (planeIndex == UINT_MAX) {
+ qWarning("Failed to find a suitable plane");
+ return VK_NULL_HANDLE;
+ }
+
+ qCDebug(qLcEglDevDebug, "Using plane #%u", planeIndex);
+
+ VkDisplaySurfaceCreateInfoKHR surfaceCreateInfo = {};
+ surfaceCreateInfo.sType = VK_STRUCTURE_TYPE_DISPLAY_SURFACE_CREATE_INFO_KHR;
+ surfaceCreateInfo.displayMode = displayMode;
+ surfaceCreateInfo.planeIndex = planeIndex;
+ surfaceCreateInfo.planeStackIndex = planeProps[planeIndex].currentStackIndex;
+ surfaceCreateInfo.transform = VK_SURFACE_TRANSFORM_INHERIT_BIT_KHR;
+ surfaceCreateInfo.globalAlpha = 1.0f;
+ surfaceCreateInfo.alphaMode = VK_DISPLAY_PLANE_ALPHA_OPAQUE_BIT_KHR;
+ surfaceCreateInfo.imageExtent = { width, height };
+
+ VkSurfaceKHR surface = VK_NULL_HANDLE;
+ err = m_createDisplayPlaneSurfaceKHR(m_vkInst, &surfaceCreateInfo, nullptr, &surface);
+ if (err != VK_SUCCESS || surface == VK_NULL_HANDLE) {
+ qWarning("Failed to create surface: %d", err);
+ return VK_NULL_HANDLE;
+ }
+
+ qCDebug(qLcEglDevDebug, "Created surface %p", (void *) surface);
+
+ return surface;
+
+#else
+ Q_UNUSED(window);
+ qWarning("VK_KHR_display support was not compiled in, cannot create surface");
+ return VK_NULL_HANDLE;
+#endif
+}
+
+void QEglFSVulkanInstance::presentAboutToBeQueued(QWindow *window)
+{
+ // support QT_QPA_EGLFS_FORCEVSYNC (i.MX8 with eglfs_viv)
+ qt_egl_device_integration()->waitForVSync(window->handle());
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/platforms/eglfs/api/vulkan/qeglfsvulkaninstance_p.h b/src/plugins/platforms/eglfs/api/vulkan/qeglfsvulkaninstance_p.h
new file mode 100644
index 0000000000..9d6d47f439
--- /dev/null
+++ b/src/plugins/platforms/eglfs/api/vulkan/qeglfsvulkaninstance_p.h
@@ -0,0 +1,88 @@
+/****************************************************************************
+**
+** Copyright (C) 2020 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QEGLFSVULKANINSTANCE_H
+#define QEGLFSVULKANINSTANCE_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 "qeglfsglobal_p.h"
+#include <QtVulkanSupport/private/qbasicvulkanplatforminstance_p.h>
+
+QT_BEGIN_NAMESPACE
+
+class QEglFSWindow;
+
+class Q_EGLFS_EXPORT QEglFSVulkanInstance : public QBasicPlatformVulkanInstance
+{
+public:
+ QEglFSVulkanInstance(QVulkanInstance *instance);
+
+ void createOrAdoptInstance() override;
+ bool supportsPresent(VkPhysicalDevice physicalDevice, uint32_t queueFamilyIndex, QWindow *window) override;
+ void presentAboutToBeQueued(QWindow *window) override;
+
+ VkSurfaceKHR createSurface(QEglFSWindow *window);
+
+private:
+ QVulkanInstance *m_instance;
+ VkPhysicalDevice m_physDev = VK_NULL_HANDLE;
+ PFN_vkEnumeratePhysicalDevices m_enumeratePhysicalDevices = nullptr;
+#if VK_KHR_display
+ PFN_vkGetPhysicalDeviceDisplayPropertiesKHR m_getPhysicalDeviceDisplayPropertiesKHR = nullptr;
+ PFN_vkGetDisplayModePropertiesKHR m_getDisplayModePropertiesKHR = nullptr;
+ PFN_vkGetPhysicalDeviceDisplayPlanePropertiesKHR m_getPhysicalDeviceDisplayPlanePropertiesKHR = nullptr;
+ PFN_vkGetDisplayPlaneSupportedDisplaysKHR m_getDisplayPlaneSupportedDisplaysKHR = nullptr;
+ PFN_vkGetDisplayPlaneCapabilitiesKHR m_getDisplayPlaneCapabilitiesKHR = nullptr;
+ PFN_vkCreateDisplayPlaneSurfaceKHR m_createDisplayPlaneSurfaceKHR = nullptr;
+#endif
+};
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/plugins/platforms/eglfs/api/vulkan/qeglfsvulkanwindow.cpp b/src/plugins/platforms/eglfs/api/vulkan/qeglfsvulkanwindow.cpp
new file mode 100644
index 0000000000..ae41ca00b6
--- /dev/null
+++ b/src/plugins/platforms/eglfs/api/vulkan/qeglfsvulkanwindow.cpp
@@ -0,0 +1,75 @@
+/****************************************************************************
+**
+** Copyright (C) 2020 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qeglfsvulkanwindow_p.h"
+
+QT_BEGIN_NAMESPACE
+
+QEglFSVulkanWindow::QEglFSVulkanWindow(QWindow *window)
+ : QEglFSWindow(window),
+ m_surface(VK_NULL_HANDLE)
+{
+}
+
+QEglFSVulkanWindow::~QEglFSVulkanWindow()
+{
+ if (m_surface) {
+ QVulkanInstance *inst = window()->vulkanInstance();
+ if (inst)
+ static_cast<QEglFSVulkanInstance *>(inst->handle())->destroySurface(m_surface);
+ }
+}
+
+void *QEglFSVulkanWindow::vulkanSurfacePtr()
+{
+ if (m_surface)
+ return &m_surface;
+
+ QVulkanInstance *inst = window()->vulkanInstance();
+ if (!inst) {
+ qWarning("Attempted to create Vulkan surface without an instance; was QWindow::setVulkanInstance() called?");
+ return nullptr;
+ }
+ QEglFSVulkanInstance *eglfsInst = static_cast<QEglFSVulkanInstance *>(inst->handle());
+ m_surface = eglfsInst->createSurface(this);
+
+ return &m_surface;
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/platforms/eglfs/api/vulkan/qeglfsvulkanwindow_p.h b/src/plugins/platforms/eglfs/api/vulkan/qeglfsvulkanwindow_p.h
new file mode 100644
index 0000000000..492fb41ca4
--- /dev/null
+++ b/src/plugins/platforms/eglfs/api/vulkan/qeglfsvulkanwindow_p.h
@@ -0,0 +1,74 @@
+/****************************************************************************
+**
+** Copyright (C) 2020 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QEGLFSVULKANWINDOW_H
+#define QEGLFSVULKANWINDOW_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 "qeglfsglobal_p.h"
+#include "qeglfswindow_p.h"
+#include "qeglfsvulkaninstance_p.h"
+
+QT_BEGIN_NAMESPACE
+
+class Q_EGLFS_EXPORT QEglFSVulkanWindow : public QEglFSWindow
+{
+public:
+ QEglFSVulkanWindow(QWindow *window);
+ ~QEglFSVulkanWindow();
+
+ void *vulkanSurfacePtr() override;
+
+private:
+ VkSurfaceKHR m_surface;
+};
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmcursor.cpp b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmcursor.cpp
index 4d0cf0c47e..dc98cdce4b 100644
--- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmcursor.cpp
+++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmcursor.cpp
@@ -69,7 +69,7 @@ QEglFSKmsGbmCursor::QEglFSKmsGbmCursor(QEglFSKmsGbmScreen *screen)
: m_screen(screen)
, m_cursorSize(64, 64) // 64x64 is the old standard size, we now try to query the real size below
, m_bo(nullptr)
- , m_cursorImage(0, 0, 0, 0, 0, 0)
+ , m_cursorImage(nullptr, nullptr, 0, 0, 0, 0)
, m_state(CursorPendingVisible)
, m_deviceListener(nullptr)
{
@@ -102,7 +102,7 @@ QEglFSKmsGbmCursor::QEglFSKmsGbmCursor(QEglFSKmsGbmScreen *screen)
#ifndef QT_NO_CURSOR
QCursor cursor(Qt::ArrowCursor);
- changeCursor(&cursor, 0);
+ changeCursor(&cursor, nullptr);
#endif
setPos(QPoint(0, 0));
}
@@ -214,7 +214,8 @@ void QEglFSKmsGbmCursor::changeCursor(QCursor *windowCursor, QWindow *window)
Q_FOREACH (QPlatformScreen *screen, m_screen->virtualSiblings()) {
QEglFSKmsScreen *kmsScreen = static_cast<QEglFSKmsScreen *>(screen);
-
+ if (kmsScreen->isCursorOutOfRange())
+ continue;
int status = drmModeSetCursor(kmsScreen->device()->fd(), kmsScreen->output().crtc_id, handle,
m_cursorSize.width(), m_cursorSize.height());
if (status != 0)
@@ -232,17 +233,36 @@ void QEglFSKmsGbmCursor::setPos(const QPoint &pos)
{
Q_FOREACH (QPlatformScreen *screen, m_screen->virtualSiblings()) {
QEglFSKmsScreen *kmsScreen = static_cast<QEglFSKmsScreen *>(screen);
- QPoint origin = kmsScreen->geometry().topLeft();
- QPoint localPos = pos - origin;
- QPoint adjustedPos = localPos - m_cursorImage.hotspot();
-
- int ret = drmModeMoveCursor(kmsScreen->device()->fd(), kmsScreen->output().crtc_id, adjustedPos.x(), adjustedPos.y());
- if (ret == 0)
- m_pos = pos;
- else
- qWarning("Failed to move cursor on screen %s: %d", kmsScreen->name().toLatin1().constData(), ret);
-
- kmsScreen->handleCursorMove(pos);
+ const QRect screenGeom = kmsScreen->geometry();
+ const QPoint origin = screenGeom.topLeft();
+ const QPoint localPos = pos - origin;
+ const QPoint adjustedLocalPos = localPos - m_cursorImage.hotspot();
+
+ if (localPos.x() < 0 || localPos.y() < 0
+ || localPos.x() >= screenGeom.width() || localPos.y() >= screenGeom.height())
+ {
+ if (!kmsScreen->isCursorOutOfRange()) {
+ kmsScreen->setCursorOutOfRange(true);
+ drmModeSetCursor(kmsScreen->device()->fd(), kmsScreen->output().crtc_id, 0, 0, 0);
+ }
+ } else {
+ int ret;
+ if (kmsScreen->isCursorOutOfRange()) {
+ kmsScreen->setCursorOutOfRange(false);
+ uint32_t handle = gbm_bo_get_handle(m_bo).u32;
+ ret = drmModeSetCursor(kmsScreen->device()->fd(), kmsScreen->output().crtc_id,
+ handle, m_cursorSize.width(), m_cursorSize.height());
+ } else {
+ ret = drmModeMoveCursor(kmsScreen->device()->fd(), kmsScreen->output().crtc_id,
+ adjustedLocalPos.x(), adjustedLocalPos.y());
+ }
+ if (ret == 0)
+ m_pos = pos;
+ else
+ qWarning("Failed to move cursor on screen %s: %d", kmsScreen->name().toLatin1().constData(), ret);
+
+ kmsScreen->handleCursorMove(pos);
+ }
}
}
diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmcursor.h b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmcursor.h
index d47b579238..5d2dfedba2 100644
--- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmcursor.h
+++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmcursor.h
@@ -85,6 +85,8 @@ public:
void updateMouseStatus();
+ void reevaluateVisibilityForScreens() { setPos(pos()); }
+
private:
void initCursorAtlas();
diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmdevice.cpp b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmdevice.cpp
index 20127ae7f7..503419cf91 100644
--- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmdevice.cpp
+++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmdevice.cpp
@@ -83,6 +83,8 @@ bool QEglFSKmsGbmDevice::open()
setFd(fd);
+ m_eventReader.create(this);
+
return true;
}
@@ -90,6 +92,8 @@ void QEglFSKmsGbmDevice::close()
{
// Note: screens are gone at this stage.
+ m_eventReader.destroy();
+
if (m_gbm_device) {
gbm_device_destroy(m_gbm_device);
m_gbm_device = nullptr;
@@ -155,4 +159,14 @@ void QEglFSKmsGbmDevice::registerScreenCloning(QPlatformScreen *screen,
gbmScreen->initCloning(screenThisScreenClones, screensCloningThisScreen);
}
+void QEglFSKmsGbmDevice::registerScreen(QPlatformScreen *screen,
+ bool isPrimary,
+ const QPoint &virtualPos,
+ const QList<QPlatformScreen *> &virtualSiblings)
+{
+ QEglFSKmsDevice::registerScreen(screen, isPrimary, virtualPos, virtualSiblings);
+ if (screenConfig()->hwCursor() && m_globalCursor)
+ m_globalCursor->reevaluateVisibilityForScreens();
+}
+
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmdevice.h b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmdevice.h
index 518e2ce58b..f1476f8ffa 100644
--- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmdevice.h
+++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmdevice.h
@@ -70,6 +70,10 @@ public:
void registerScreenCloning(QPlatformScreen *screen,
QPlatformScreen *screenThisScreenClones,
const QVector<QPlatformScreen *> &screensCloningThisScreen) override;
+ void registerScreen(QPlatformScreen *screen,
+ bool isPrimary,
+ const QPoint &virtualPos,
+ const QList<QPlatformScreen *> &virtualSiblings) override;
private:
Q_DISABLE_COPY(QEglFSKmsGbmDevice)
diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmintegration.cpp b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmintegration.cpp
index f154520669..caa1187b40 100644
--- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmintegration.cpp
+++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmintegration.cpp
@@ -54,8 +54,6 @@
QT_BEGIN_NAMESPACE
-QMutex QEglFSKmsGbmScreen::m_waitForFlipMutex;
-
QEglFSKmsGbmIntegration::QEglFSKmsGbmIntegration()
{
qCDebug(qLcEglfsKmsDebug, "New DRM/KMS via GBM integration created");
diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmscreen.cpp b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmscreen.cpp
index 16dbfe1522..6f5c3b6953 100644
--- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmscreen.cpp
+++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmscreen.cpp
@@ -110,7 +110,7 @@ QEglFSKmsGbmScreen::FrameBuffer *QEglFSKmsGbmScreen::framebufferForBufferObject(
return fb.take();
}
-QEglFSKmsGbmScreen::QEglFSKmsGbmScreen(QKmsDevice *device, const QKmsOutput &output, bool headless)
+QEglFSKmsGbmScreen::QEglFSKmsGbmScreen(QEglFSKmsDevice *device, const QKmsOutput &output, bool headless)
: QEglFSKmsScreen(device, output, headless)
, m_gbm_surface(nullptr)
, m_gbm_bo_current(nullptr)
@@ -243,7 +243,7 @@ void QEglFSKmsGbmScreen::ensureModeSet(uint32_t fb)
if (device()->hasAtomicSupport()) {
#if QT_CONFIG(drm_atomic)
- drmModeAtomicReq *request = device()->atomic_request();
+ drmModeAtomicReq *request = device()->threadLocalAtomicRequest();
if (request) {
drmModeAtomicAddProperty(request, op.connector_id, op.crtcIdPropertyId, op.crtc_id);
drmModeAtomicAddProperty(request, op.crtc_id, op.modeIdPropertyId, op.mode_blob_id);
@@ -276,19 +276,15 @@ void QEglFSKmsGbmScreen::waitForFlip()
if (!m_gbm_bo_next)
return;
- QMutexLocker lock(&m_waitForFlipMutex);
- while (m_gbm_bo_next) {
- drmEventContext drmEvent;
- memset(&drmEvent, 0, sizeof(drmEvent));
- drmEvent.version = 2;
- drmEvent.vblank_handler = nullptr;
- drmEvent.page_flip_handler = pageFlipHandler;
- drmHandleEvent(device()->fd(), &drmEvent);
- }
+ m_flipMutex.lock();
+ device()->eventReader()->startWaitFlip(this, &m_flipMutex, &m_flipCond);
+ m_flipCond.wait(&m_flipMutex);
+ m_flipMutex.unlock();
+
+ flipFinished();
#if QT_CONFIG(drm_atomic)
- if (device()->hasAtomicSupport())
- device()->atomicReset();
+ device()->threadLocalAtomicReset();
#endif
}
@@ -324,16 +320,16 @@ void QEglFSKmsGbmScreen::flip()
if (device()->hasAtomicSupport()) {
#if QT_CONFIG(drm_atomic)
- drmModeAtomicReq *request = device()->atomic_request();
+ drmModeAtomicReq *request = device()->threadLocalAtomicRequest();
if (request) {
drmModeAtomicAddProperty(request, op.eglfs_plane->id, op.eglfs_plane->framebufferPropertyId, fb->fb);
drmModeAtomicAddProperty(request, op.eglfs_plane->id, op.eglfs_plane->crtcPropertyId, op.crtc_id);
drmModeAtomicAddProperty(request, op.eglfs_plane->id, op.eglfs_plane->srcwidthPropertyId,
- output().size.width() << 16);
+ op.size.width() << 16);
drmModeAtomicAddProperty(request, op.eglfs_plane->id, op.eglfs_plane->srcXPropertyId, 0);
drmModeAtomicAddProperty(request, op.eglfs_plane->id, op.eglfs_plane->srcYPropertyId, 0);
drmModeAtomicAddProperty(request, op.eglfs_plane->id, op.eglfs_plane->srcheightPropertyId,
- output().size.height() << 16);
+ op.size.height() << 16);
drmModeAtomicAddProperty(request, op.eglfs_plane->id, op.eglfs_plane->crtcXPropertyId, 0);
drmModeAtomicAddProperty(request, op.eglfs_plane->id, op.eglfs_plane->crtcYPropertyId, 0);
drmModeAtomicAddProperty(request, op.eglfs_plane->id, op.eglfs_plane->crtcwidthPropertyId,
@@ -371,7 +367,7 @@ void QEglFSKmsGbmScreen::flip()
if (device()->hasAtomicSupport()) {
#if QT_CONFIG(drm_atomic)
- drmModeAtomicReq *request = device()->atomic_request();
+ drmModeAtomicReq *request = device()->threadLocalAtomicRequest();
if (request) {
drmModeAtomicAddProperty(request, d.screen->output().eglfs_plane->id,
d.screen->output().eglfs_plane->framebufferPropertyId, fb->fb);
@@ -394,22 +390,10 @@ void QEglFSKmsGbmScreen::flip()
}
#if QT_CONFIG(drm_atomic)
- if (device()->hasAtomicSupport())
- device()->atomicCommit(this);
+ device()->threadLocalAtomicCommit(this);
#endif
}
-void QEglFSKmsGbmScreen::pageFlipHandler(int fd, unsigned int sequence, unsigned int tv_sec, unsigned int tv_usec, void *user_data)
-{
- Q_UNUSED(fd);
- Q_UNUSED(sequence);
- Q_UNUSED(tv_sec);
- Q_UNUSED(tv_usec);
-
- QEglFSKmsGbmScreen *screen = static_cast<QEglFSKmsGbmScreen *>(user_data);
- screen->flipFinished();
-}
-
void QEglFSKmsGbmScreen::flipFinished()
{
if (m_cloneSource) {
diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmscreen.h b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmscreen.h
index b94f44b7b1..69feeee703 100644
--- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmscreen.h
+++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmscreen.h
@@ -43,7 +43,8 @@
#define QEGLFSKMSGBMSCREEN_H
#include "qeglfskmsscreen.h"
-#include <QtCore/QMutex>
+#include <QMutex>
+#include <QWaitCondition>
#include <gbm.h>
@@ -54,7 +55,7 @@ class QEglFSKmsGbmCursor;
class QEglFSKmsGbmScreen : public QEglFSKmsScreen
{
public:
- QEglFSKmsGbmScreen(QKmsDevice *device, const QKmsOutput &output, bool headless);
+ QEglFSKmsGbmScreen(QEglFSKmsDevice *device, const QKmsOutput &output, bool headless);
~QEglFSKmsGbmScreen();
QPlatformCursor *cursor() const override;
@@ -75,18 +76,15 @@ private:
void cloneDestFlipFinished(QEglFSKmsGbmScreen *cloneDestScreen);
void updateFlipStatus();
- static void pageFlipHandler(int fd,
- unsigned int sequence,
- unsigned int tv_sec,
- unsigned int tv_usec,
- void *user_data);
-
gbm_surface *m_gbm_surface;
gbm_bo *m_gbm_bo_current;
gbm_bo *m_gbm_bo_next;
bool m_flipPending;
+ QMutex m_flipMutex;
+ QWaitCondition m_flipCond;
+
QScopedPointer<QEglFSKmsGbmCursor> m_cursor;
struct FrameBuffer {
@@ -101,8 +99,6 @@ private:
bool cloneFlipPending = false;
};
QVector<CloneDestination> m_cloneDests;
-
- static QMutex m_waitForFlipMutex;
};
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldevicescreen.cpp b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldevicescreen.cpp
index 1626c86239..5a62e437c4 100644
--- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldevicescreen.cpp
+++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldevicescreen.cpp
@@ -47,7 +47,7 @@ QT_BEGIN_NAMESPACE
Q_DECLARE_LOGGING_CATEGORY(qLcEglfsKmsDebug)
-QEglFSKmsEglDeviceScreen::QEglFSKmsEglDeviceScreen(QKmsDevice *device, const QKmsOutput &output)
+QEglFSKmsEglDeviceScreen::QEglFSKmsEglDeviceScreen(QEglFSKmsDevice *device, const QKmsOutput &output)
: QEglFSKmsScreen(device, output)
{
}
diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldevicescreen.h b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldevicescreen.h
index 5efe35f8b3..961398ba3e 100644
--- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldevicescreen.h
+++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldevicescreen.h
@@ -47,7 +47,7 @@ QT_BEGIN_NAMESPACE
class QEglFSKmsEglDeviceScreen : public QEglFSKmsScreen
{
public:
- QEglFSKmsEglDeviceScreen(QKmsDevice *device, const QKmsOutput &output);
+ QEglFSKmsEglDeviceScreen(QEglFSKmsDevice *device, const QKmsOutput &output);
~QEglFSKmsEglDeviceScreen();
QPlatformCursor *cursor() const override;
diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/eglfs_kms_support.pro b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/eglfs_kms_support.pro
index 40806b6a9b..e51903ed96 100644
--- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/eglfs_kms_support.pro
+++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/eglfs_kms_support.pro
@@ -14,9 +14,11 @@ CONFIG += egl
SOURCES += $$PWD/qeglfskmsintegration.cpp \
$$PWD/qeglfskmsdevice.cpp \
- $$PWD/qeglfskmsscreen.cpp
+ $$PWD/qeglfskmsscreen.cpp \
+ $$PWD/qeglfskmseventreader.cpp
HEADERS += $$PWD/qeglfskmsintegration.h \
$$PWD/qeglfskmsdevice.h \
$$PWD/qeglfskmsscreen.h \
- $$PWD/qeglfskmshelpers.h
+ $$PWD/qeglfskmshelpers.h \
+ $$PWD/qeglfskmseventreader.h
diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmsdevice.h b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmsdevice.h
index fc83a620d9..34908aa60f 100644
--- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmsdevice.h
+++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmsdevice.h
@@ -42,6 +42,7 @@
#define QEGLFSKMSDEVICE_H
#include "private/qeglfsglobal_p.h"
+#include "qeglfskmseventreader.h"
#include <QtKmsSupport/private/qkmsdevice_p.h>
QT_BEGIN_NAMESPACE
@@ -55,6 +56,11 @@ public:
bool isPrimary,
const QPoint &virtualPos,
const QList<QPlatformScreen *> &virtualSiblings) override;
+
+ QEglFSKmsEventReader *eventReader() { return &m_eventReader; }
+
+protected:
+ QEglFSKmsEventReader m_eventReader;
};
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmseventreader.cpp b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmseventreader.cpp
new file mode 100644
index 0000000000..645a0ae2e9
--- /dev/null
+++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmseventreader.cpp
@@ -0,0 +1,218 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qeglfskmseventreader.h"
+#include "qeglfskmsdevice.h"
+#include <QSocketNotifier>
+#include <QCoreApplication>
+#include <QLoggingCategory>
+
+QT_BEGIN_NAMESPACE
+
+Q_DECLARE_LOGGING_CATEGORY(qLcEglfsKmsDebug)
+
+static void pageFlipHandler(int fd, unsigned int sequence, unsigned int tv_sec, unsigned int tv_usec, void *user_data)
+{
+ Q_UNUSED(fd);
+ Q_UNUSED(sequence);
+ Q_UNUSED(tv_sec);
+ Q_UNUSED(tv_usec);
+
+ QEglFSKmsEventReaderThread *t = static_cast<QEglFSKmsEventReaderThread *>(QThread::currentThread());
+ t->eventHost()->handlePageFlipCompleted(user_data);
+}
+
+class RegisterWaitFlipEvent : public QEvent
+{
+public:
+ static const QEvent::Type TYPE = QEvent::Type(QEvent::User + 1);
+ RegisterWaitFlipEvent(void *key, QMutex *mutex, QWaitCondition *cond)
+ : QEvent(TYPE), key(key), mutex(mutex), cond(cond)
+ { }
+ void *key;
+ QMutex *mutex;
+ QWaitCondition *cond;
+};
+
+bool QEglFSKmsEventHost::event(QEvent *event)
+{
+ if (event->type() == RegisterWaitFlipEvent::TYPE) {
+ RegisterWaitFlipEvent *e = static_cast<RegisterWaitFlipEvent *>(event);
+ PendingFlipWait *p = &pendingFlipWaits[0];
+ PendingFlipWait *end = p + MAX_FLIPS;
+ while (p < end) {
+ if (!p->key) {
+ p->key = e->key;
+ p->mutex = e->mutex;
+ p->cond = e->cond;
+ updateStatus();
+ return true;
+ }
+ ++p;
+ }
+ qWarning("Cannot queue page flip wait (more than %d screens?)", MAX_FLIPS);
+ e->mutex->lock();
+ e->cond->wakeOne();
+ e->mutex->unlock();
+ return true;
+ }
+ return QObject::event(event);
+}
+
+void QEglFSKmsEventHost::updateStatus()
+{
+ void **begin = &completedFlips[0];
+ void **end = begin + MAX_FLIPS;
+
+ for (int i = 0; i < MAX_FLIPS; ++i) {
+ PendingFlipWait *w = pendingFlipWaits + i;
+ if (!w->key)
+ continue;
+
+ void **p = begin;
+ while (p < end) {
+ if (*p == w->key) {
+ *p = nullptr;
+ w->key = nullptr;
+ w->mutex->lock();
+ w->cond->wakeOne();
+ w->mutex->unlock();
+ return;
+ }
+ ++p;
+ }
+ }
+}
+
+void QEglFSKmsEventHost::handlePageFlipCompleted(void *key)
+{
+ void **begin = &completedFlips[0];
+ void **end = begin + MAX_FLIPS;
+ void **p = begin;
+ while (p < end) {
+ if (*p == key) {
+ updateStatus();
+ return;
+ }
+ ++p;
+ }
+ p = begin;
+ while (p < end) {
+ if (!*p) {
+ *p = key;
+ updateStatus();
+ return;
+ }
+ ++p;
+ }
+ qWarning("Cannot store page flip status (more than %d screens?)", MAX_FLIPS);
+}
+
+void QEglFSKmsEventReaderThread::run()
+{
+ qCDebug(qLcEglfsKmsDebug, "Event reader thread: entering event loop");
+
+ QSocketNotifier notifier(m_fd, QSocketNotifier::Read);
+ QObject::connect(&notifier, &QSocketNotifier::activated, &notifier, [this] {
+ drmEventContext drmEvent;
+ memset(&drmEvent, 0, sizeof(drmEvent));
+ drmEvent.version = 2;
+ drmEvent.vblank_handler = nullptr;
+ drmEvent.page_flip_handler = pageFlipHandler;
+ drmHandleEvent(m_fd, &drmEvent);
+ });
+
+ exec();
+
+ m_ev.moveToThread(thread()); // move back to the thread where m_ev was created
+
+ qCDebug(qLcEglfsKmsDebug, "Event reader thread: event loop stopped");
+}
+
+QEglFSKmsEventReader::~QEglFSKmsEventReader()
+{
+ destroy();
+}
+
+void QEglFSKmsEventReader::create(QEglFSKmsDevice *device)
+{
+ destroy();
+
+ if (!device)
+ return;
+
+ m_device = device;
+
+ qCDebug(qLcEglfsKmsDebug, "Initalizing event reader for device %p fd %d",
+ m_device, m_device->fd());
+
+ m_thread = new QEglFSKmsEventReaderThread(m_device->fd());
+ m_thread->start();
+
+ // Change thread affinity for the event host, so that postEvent()
+ // goes through the event reader thread's event loop for that object.
+ m_thread->eventHost()->moveToThread(m_thread);
+}
+
+void QEglFSKmsEventReader::destroy()
+{
+ if (!m_device)
+ return;
+
+ qCDebug(qLcEglfsKmsDebug, "Stopping event reader for device %p", m_device);
+
+ if (m_thread) {
+ m_thread->quit();
+ m_thread->wait();
+ delete m_thread;
+ m_thread = nullptr;
+ }
+
+ m_device = nullptr;
+}
+
+void QEglFSKmsEventReader::startWaitFlip(void *key, QMutex *mutex, QWaitCondition *cond)
+{
+ if (m_thread) {
+ QCoreApplication::postEvent(m_thread->eventHost(),
+ new RegisterWaitFlipEvent(key, mutex, cond));
+ }
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmseventreader.h b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmseventreader.h
new file mode 100644
index 0000000000..4aa285b0fe
--- /dev/null
+++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmseventreader.h
@@ -0,0 +1,99 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QEGLFSKKMSEVENTREADER_H
+#define QEGLFSKKMSEVENTREADER_H
+
+#include "private/qeglfsglobal_p.h"
+#include <QObject>
+#include <QThread>
+#include <QMutex>
+#include <QWaitCondition>
+
+QT_BEGIN_NAMESPACE
+
+class QEglFSKmsDevice;
+
+struct QEglFSKmsEventHost : public QObject
+{
+ struct PendingFlipWait {
+ void *key;
+ QMutex *mutex;
+ QWaitCondition *cond;
+ };
+
+ static const int MAX_FLIPS = 32;
+ void *completedFlips[MAX_FLIPS] = {};
+ QEglFSKmsEventHost::PendingFlipWait pendingFlipWaits[MAX_FLIPS] = {};
+
+ bool event(QEvent *event) override;
+ void updateStatus();
+ void handlePageFlipCompleted(void *key);
+};
+
+class QEglFSKmsEventReaderThread : public QThread
+{
+public:
+ QEglFSKmsEventReaderThread(int fd) : m_fd(fd) { }
+ void run() override;
+ QEglFSKmsEventHost *eventHost() { return &m_ev; }
+
+private:
+ int m_fd;
+ QEglFSKmsEventHost m_ev;
+};
+
+class Q_EGLFS_EXPORT QEglFSKmsEventReader
+{
+public:
+ ~QEglFSKmsEventReader();
+
+ void create(QEglFSKmsDevice *device);
+ void destroy();
+
+ void startWaitFlip(void *key, QMutex *mutex, QWaitCondition *cond);
+
+private:
+ QEglFSKmsDevice *m_device = nullptr;
+ QEglFSKmsEventReaderThread *m_thread = nullptr;
+};
+
+QT_END_NAMESPACE
+
+#endif // QEGLFSKKMSEVENTREADER_H
diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmsintegration.cpp b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmsintegration.cpp
index a6aac61506..28b6b7df63 100644
--- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmsintegration.cpp
+++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmsintegration.cpp
@@ -140,7 +140,7 @@ void *QEglFSKmsIntegration::nativeResourceForIntegration(const QByteArray &name)
#if QT_CONFIG(drm_atomic)
if (name == QByteArrayLiteral("dri_atomic_request") && m_device)
- return (void *) (qintptr) m_device->atomic_request();
+ return (void *) (qintptr) m_device->threadLocalAtomicRequest();
#endif
return nullptr;
}
diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmsscreen.cpp b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmsscreen.cpp
index e5354d97bd..959f17eba3 100644
--- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmsscreen.cpp
+++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmsscreen.cpp
@@ -40,6 +40,7 @@
****************************************************************************/
#include "qeglfskmsscreen.h"
+#include "qeglfskmsdevice.h"
#include "qeglfsintegration_p.h"
#include <QtCore/QLoggingCategory>
@@ -68,10 +69,11 @@ private:
QEglFSKmsScreen *m_screen;
};
-QEglFSKmsScreen::QEglFSKmsScreen(QKmsDevice *device, const QKmsOutput &output, bool headless)
+QEglFSKmsScreen::QEglFSKmsScreen(QEglFSKmsDevice *device, const QKmsOutput &output, bool headless)
: QEglFSScreen(static_cast<QEglFSIntegration *>(QGuiApplicationPrivate::platformIntegration())->display())
, m_device(device)
, m_output(output)
+ , m_cursorOutOfRange(false)
, m_powerState(PowerStateOn)
, m_interruptHandler(new QEglFSKmsInterruptHandler(this))
, m_headless(headless)
diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmsscreen.h b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmsscreen.h
index 7f395aacb7..a5c8f5b4e8 100644
--- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmsscreen.h
+++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmsscreen.h
@@ -51,12 +51,13 @@
QT_BEGIN_NAMESPACE
+class QEglFSKmsDevice;
class QEglFSKmsInterruptHandler;
class Q_EGLFS_EXPORT QEglFSKmsScreen : public QEglFSScreen
{
public:
- QEglFSKmsScreen(QKmsDevice *device, const QKmsOutput &output, bool headless = false);
+ QEglFSKmsScreen(QEglFSKmsDevice *device, const QKmsOutput &output, bool headless = false);
~QEglFSKmsScreen();
void setVirtualPosition(const QPoint &pos);
@@ -87,7 +88,7 @@ public:
int currentMode() const override;
int preferredMode() const override;
- QKmsDevice *device() const { return m_device; }
+ QEglFSKmsDevice *device() const { return m_device; }
virtual void waitForFlip();
@@ -99,12 +100,16 @@ public:
QPlatformScreen::PowerState powerState() const override;
void setPowerState(QPlatformScreen::PowerState state) override;
+ bool isCursorOutOfRange() const { return m_cursorOutOfRange; }
+ void setCursorOutOfRange(bool b) { m_cursorOutOfRange = b; }
+
protected:
- QKmsDevice *m_device;
+ QEglFSKmsDevice *m_device;
QKmsOutput m_output;
QEdidParser m_edid;
QPoint m_pos;
+ bool m_cursorOutOfRange;
QList<QPlatformScreen *> m_siblings;
diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_vsp2/qeglfskmsvsp2screen.cpp b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_vsp2/qeglfskmsvsp2screen.cpp
index 475d9d55dd..c255bc84b7 100644
--- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_vsp2/qeglfskmsvsp2screen.cpp
+++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_vsp2/qeglfskmsvsp2screen.cpp
@@ -99,7 +99,7 @@ QEglFSKmsVsp2Screen::DmaBuffer *QEglFSKmsVsp2Screen::dmaBufferForGbmBuffer(gbm_b
return fb.take();
}
-QEglFSKmsVsp2Screen::QEglFSKmsVsp2Screen(QKmsDevice *device, const QKmsOutput &output)
+QEglFSKmsVsp2Screen::QEglFSKmsVsp2Screen(QEglFSKmsDevice *device, const QKmsOutput &output)
: QEglFSKmsScreen(device, output)
, m_blender(new Blender(this))
{
diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_vsp2/qeglfskmsvsp2screen.h b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_vsp2/qeglfskmsvsp2screen.h
index 7618510333..378786643d 100644
--- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_vsp2/qeglfskmsvsp2screen.h
+++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_vsp2/qeglfskmsvsp2screen.h
@@ -53,7 +53,7 @@ QT_BEGIN_NAMESPACE
class QEglFSKmsVsp2Screen : public QEglFSKmsScreen
{
public:
- QEglFSKmsVsp2Screen(QKmsDevice *device, const QKmsOutput &output);
+ QEglFSKmsVsp2Screen(QEglFSKmsDevice *device, const QKmsOutput &output);
gbm_surface *createSurface();
void resetSurface();
diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_viv/qeglfsvivintegration.cpp b/src/plugins/platforms/eglfs/deviceintegration/eglfs_viv/qeglfsvivintegration.cpp
index 2fc076ad0c..5e1d28a353 100644
--- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_viv/qeglfsvivintegration.cpp
+++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_viv/qeglfsvivintegration.cpp
@@ -41,6 +41,11 @@
#include <EGL/eglvivante.h>
#include <QDebug>
+#if QT_CONFIG(vulkan)
+#include "private/qeglfsvulkaninstance_p.h"
+#include "private/qeglfsvulkanwindow_p.h"
+#endif
+
#ifdef Q_OS_INTEGRITY
extern "C" void VivanteInit(void);
#endif
@@ -97,4 +102,20 @@ void QEglFSVivIntegration::destroyNativeWindow(EGLNativeWindowType window)
fbDestroyWindow(window);
}
+#if QT_CONFIG(vulkan)
+
+QEglFSWindow *QEglFSVivIntegration::createWindow(QWindow *window) const
+{
+ if (window->surfaceType() == QSurface::VulkanSurface)
+ return new QEglFSVulkanWindow(window);
+ return QEglFSDeviceIntegration::createWindow(window);
+}
+
+QPlatformVulkanInstance *QEglFSVivIntegration::createPlatformVulkanInstance(QVulkanInstance *instance)
+{
+ return new QEglFSVulkanInstance(instance);
+}
+
+#endif // vulkan
+
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_viv/qeglfsvivintegration.h b/src/plugins/platforms/eglfs/deviceintegration/eglfs_viv/qeglfsvivintegration.h
index 4d1718afcf..02b59c16b5 100644
--- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_viv/qeglfsvivintegration.h
+++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_viv/qeglfsvivintegration.h
@@ -53,6 +53,12 @@ public:
void destroyNativeWindow(EGLNativeWindowType window) override;
EGLNativeDisplayType platformDisplay() const override;
+ // Vulkan support with VK_KHR_display
+#if QT_CONFIG(vulkan)
+ QEglFSWindow *createWindow(QWindow *window) const override;
+ QPlatformVulkanInstance *createPlatformVulkanInstance(QVulkanInstance *instance) override;
+#endif
+
private:
QSize mScreenSize;
EGLNativeDisplayType mNativeDisplay;
diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_x11/qeglfsx11integration.cpp b/src/plugins/platforms/eglfs/deviceintegration/eglfs_x11/qeglfsx11integration.cpp
index 07b2de7c58..ce5a721906 100644
--- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_x11/qeglfsx11integration.cpp
+++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_x11/qeglfsx11integration.cpp
@@ -75,7 +75,7 @@ void EventReader::run()
if (client->format == 32
&& client->type == atoms[Atoms::WM_PROTOCOLS]
&& client->data.data32[0] == atoms[Atoms::WM_DELETE_WINDOW]) {
- QWindow *window = m_integration->platformWindow() ? m_integration->platformWindow()->window() : 0;
+ QWindow *window = m_integration->platformWindow() ? m_integration->platformWindow()->window() : nullptr;
if (window)
QWindowSystemInterface::handleCloseEvent(window);
}
@@ -106,7 +106,7 @@ void QEglFSX11Integration::sendConnectionEvent(xcb_atom_t a)
void QEglFSX11Integration::platformInit()
{
- m_display = XOpenDisplay(0);
+ m_display = XOpenDisplay(nullptr);
if (Q_UNLIKELY(!m_display))
qFatal("Could not open display");
@@ -121,7 +121,7 @@ void QEglFSX11Integration::platformInit()
xcb_create_window(m_connection, XCB_COPY_FROM_PARENT,
m_connectionEventListener, it.data->root,
0, 0, 1, 1, 0, XCB_WINDOW_CLASS_INPUT_ONLY,
- it.data->root_visual, 0, 0);
+ it.data->root_visual, 0, nullptr);
m_eventReader = new EventReader(this);
m_eventReader->start();
@@ -135,11 +135,11 @@ void QEglFSX11Integration::platformDestroy()
m_eventReader->wait();
delete m_eventReader;
- m_eventReader = 0;
+ m_eventReader = nullptr;
XCloseDisplay(DISPLAY);
- m_display = 0;
- m_connection = 0;
+ m_display = nullptr;
+ m_connection = nullptr;
}
EGLNativeDisplayType QEglFSX11Integration::platformDisplay() const
@@ -175,7 +175,7 @@ EGLNativeWindowType QEglFSX11Integration::createNativeWindow(QPlatformWindow *pl
xcb_create_window(m_connection, XCB_COPY_FROM_PARENT, m_window, it.data->root,
0, 0, size.width(), size.height(), 0,
XCB_WINDOW_CLASS_INPUT_OUTPUT, it.data->root_visual,
- 0, 0);
+ 0, nullptr);
xcb_intern_atom_cookie_t cookies[Atoms::N_ATOMS];
static const char *atomNames[Atoms::N_ATOMS] = {
@@ -189,7 +189,7 @@ EGLNativeWindowType QEglFSX11Integration::createNativeWindow(QPlatformWindow *pl
for (int i = 0; i < Atoms::N_ATOMS; ++i) {
cookies[i] = xcb_intern_atom(m_connection, false, strlen(atomNames[i]), atomNames[i]);
- xcb_intern_atom_reply_t *reply = xcb_intern_atom_reply(m_connection, cookies[i], 0);
+ xcb_intern_atom_reply_t *reply = xcb_intern_atom_reply(m_connection, cookies[i], nullptr);
m_atoms[i] = reply->atom;
free(reply);
}
diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_x11/qeglfsx11integration.h b/src/plugins/platforms/eglfs/deviceintegration/eglfs_x11/qeglfsx11integration.h
index bf431caaac..ebcc19b682 100644
--- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_x11/qeglfsx11integration.h
+++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_x11/qeglfsx11integration.h
@@ -67,7 +67,7 @@ class EventReader;
class QEglFSX11Integration : public QEglFSDeviceIntegration
{
public:
- QEglFSX11Integration() : m_connection(0), m_window(0), m_eventReader(0) {}
+ QEglFSX11Integration() : m_connection(nullptr), m_window(0), m_eventReader(nullptr) {}
void platformInit() override;
void platformDestroy() override;
diff --git a/src/plugins/platforms/eglfs/eglfsdeviceintegration.pro b/src/plugins/platforms/eglfs/eglfsdeviceintegration.pro
index 8bb7b614f1..bd02aea4d3 100644
--- a/src/plugins/platforms/eglfs/eglfsdeviceintegration.pro
+++ b/src/plugins/platforms/eglfs/eglfsdeviceintegration.pro
@@ -20,6 +20,9 @@ qtHaveModule(input_support-private): \
qtHaveModule(platformcompositor_support-private): \
QT += platformcompositor_support-private
+qtConfig(vulkan): \
+ QT += vulkan_support-private
+
# Avoid X11 header collision, use generic EGL native types
DEFINES += QT_EGL_NO_X11
diff --git a/src/plugins/platforms/eglfs/qeglfsmain.cpp b/src/plugins/platforms/eglfs/qeglfsmain.cpp
index 4f77b7cd17..b41bbec27d 100644
--- a/src/plugins/platforms/eglfs/qeglfsmain.cpp
+++ b/src/plugins/platforms/eglfs/qeglfsmain.cpp
@@ -56,7 +56,7 @@ QPlatformIntegration* QEglFSIntegrationPlugin::create(const QString& system, con
if (!system.compare(QLatin1String("eglfs"), Qt::CaseInsensitive))
return new QEglFSIntegration;
- return 0;
+ return nullptr;
}
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/ios/kernel.pro b/src/plugins/platforms/ios/kernel.pro
index 71257d09f7..54069bee06 100644
--- a/src/plugins/platforms/ios/kernel.pro
+++ b/src/plugins/platforms/ios/kernel.pro
@@ -57,13 +57,15 @@ HEADERS = \
qiosmenu.mm \
qiosfiledialog.mm \
qiosmessagedialog.mm \
- qiostextinputoverlay.mm
+ qiostextinputoverlay.mm \
+ qiosdocumentpickercontroller.mm
HEADERS += \
qiosclipboard.h \
qiosmenu.h \
qiosfiledialog.h \
qiosmessagedialog.h \
- qiostextinputoverlay.h
+ qiostextinputoverlay.h \
+ qiosdocumentpickercontroller.h
}
OTHER_FILES = \
diff --git a/src/plugins/platforms/ios/optional/nsphotolibrarysupport/qiosfileengineassetslibrary.mm b/src/plugins/platforms/ios/optional/nsphotolibrarysupport/qiosfileengineassetslibrary.mm
index 54152aebf7..c5244a51ad 100644
--- a/src/plugins/platforms/ios/optional/nsphotolibrarysupport/qiosfileengineassetslibrary.mm
+++ b/src/plugins/platforms/ios/optional/nsphotolibrarysupport/qiosfileengineassetslibrary.mm
@@ -373,7 +373,7 @@ bool QIOSFileEngineAssetsLibrary::close()
QAbstractFileEngine::FileFlags QIOSFileEngineAssetsLibrary::fileFlags(QAbstractFileEngine::FileFlags type) const
{
- QAbstractFileEngine::FileFlags flags = 0;
+ QAbstractFileEngine::FileFlags flags;
const bool isDir = (m_assetUrl == QLatin1String("assets-library://"));
const bool exists = isDir || m_assetUrl == g_iteratorCurrentUrl.localData() || loadAsset();
diff --git a/src/plugins/platforms/ios/qiosdocumentpickercontroller.h b/src/plugins/platforms/ios/qiosdocumentpickercontroller.h
new file mode 100644
index 0000000000..dba6f24fc5
--- /dev/null
+++ b/src/plugins/platforms/ios/qiosdocumentpickercontroller.h
@@ -0,0 +1,46 @@
+/****************************************************************************
+**
+** Copyright (C) 2020 Harald Meyer.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#import <UIKit/UIKit.h>
+
+#include "qiosfiledialog.h"
+
+@interface QIOSDocumentPickerController : UIDocumentPickerViewController <UIDocumentPickerDelegate, UINavigationControllerDelegate>
+- (instancetype)initWithQIOSFileDialog:(QIOSFileDialog *)fileDialog;
+@end
diff --git a/src/plugins/platforms/ios/qiosdocumentpickercontroller.mm b/src/plugins/platforms/ios/qiosdocumentpickercontroller.mm
new file mode 100644
index 0000000000..c1b641e839
--- /dev/null
+++ b/src/plugins/platforms/ios/qiosdocumentpickercontroller.mm
@@ -0,0 +1,103 @@
+/****************************************************************************
+**
+** Copyright (C) 2020 Harald Meyer.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#import <UIKit/UIKit.h>
+#import <MobileCoreServices/MobileCoreServices.h>
+
+#include "qiosdocumentpickercontroller.h"
+
+@implementation QIOSDocumentPickerController {
+ QIOSFileDialog *m_fileDialog;
+}
+
+- (instancetype)initWithQIOSFileDialog:(QIOSFileDialog *)fileDialog
+{
+ NSMutableArray <NSString *> *docTypes = [[[NSMutableArray alloc] init] autorelease];
+ UIDocumentPickerMode importMode;
+ switch (fileDialog->options()->fileMode()) {
+ case QFileDialogOptions::AnyFile:
+ case QFileDialogOptions::ExistingFile:
+ case QFileDialogOptions::ExistingFiles:
+ [docTypes addObject:(__bridge NSString *)kUTTypeContent];
+ [docTypes addObject:(__bridge NSString *)kUTTypeItem];
+ [docTypes addObject:(__bridge NSString *)kUTTypeData];
+ importMode = UIDocumentPickerModeImport;
+ break;
+ case QFileDialogOptions::Directory:
+ case QFileDialogOptions::DirectoryOnly:
+ // Directory picking is not supported because it requires
+ // special handling not possible with the current QFilePicker
+ // implementation.
+
+ Q_UNREACHABLE();
+ }
+
+ if (self = [super initWithDocumentTypes:docTypes inMode:importMode]) {
+ m_fileDialog = fileDialog;
+ self.modalPresentationStyle = UIModalPresentationFormSheet;
+ self.delegate = self;
+
+ if (m_fileDialog->options()->fileMode() == QFileDialogOptions::ExistingFiles)
+ self.allowsMultipleSelection = YES;
+
+ if (@available(ios 13.0, *))
+ self.directoryURL = m_fileDialog->options()->initialDirectory().toNSURL();
+ }
+ return self;
+}
+
+- (void)documentPicker:(UIDocumentPickerViewController *)controller didPickDocumentsAtURLs:(NSArray <NSURL *>*)urls
+{
+ Q_UNUSED(controller);
+
+ QList<QUrl> files;
+ for (NSURL* url in urls)
+ files.append(QUrl::fromNSURL(url));
+
+ m_fileDialog->selectedFilesChanged(files);
+ emit m_fileDialog->accept();
+}
+
+- (void)documentPickerWasCancelled:(UIDocumentPickerViewController *)controller
+{
+ Q_UNUSED(controller)
+ emit m_fileDialog->reject();
+}
+
+@end
diff --git a/src/plugins/platforms/ios/qiosfiledialog.h b/src/plugins/platforms/ios/qiosfiledialog.h
index 5cb1b45e20..eab05091ef 100644
--- a/src/plugins/platforms/ios/qiosfiledialog.h
+++ b/src/plugins/platforms/ios/qiosfiledialog.h
@@ -65,7 +65,7 @@ public:
void selectNameFilter(const QString &) override {}
QString selectedNameFilter() const override { return QString(); }
- void selectedFilesChanged(QList<QUrl> selection);
+ void selectedFilesChanged(const QList<QUrl> &selection);
private:
QUrl m_directory;
@@ -74,6 +74,7 @@ private:
UIViewController *m_viewController;
bool showImagePickerDialog(QWindow *parent);
+ bool showNativeDocumentPickerDialog(QWindow *parent);
};
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/ios/qiosfiledialog.mm b/src/plugins/platforms/ios/qiosfiledialog.mm
index e8a3f5b30e..edf04016fd 100644
--- a/src/plugins/platforms/ios/qiosfiledialog.mm
+++ b/src/plugins/platforms/ios/qiosfiledialog.mm
@@ -48,6 +48,7 @@
#include "qiosfiledialog.h"
#include "qiosintegration.h"
#include "qiosoptionalplugininterface.h"
+#include "qiosdocumentpickercontroller.h"
QIOSFileDialog::QIOSFileDialog()
: m_viewController(nullptr)
@@ -72,8 +73,12 @@ bool QIOSFileDialog::show(Qt::WindowFlags windowFlags, Qt::WindowModality window
bool acceptOpen = options()->acceptMode() == QFileDialogOptions::AcceptOpen;
QString directory = options()->initialDirectory().toLocalFile();
- if (acceptOpen && directory.startsWith(QLatin1String("assets-library:")))
- return showImagePickerDialog(parent);
+ if (acceptOpen) {
+ if (directory.startsWith(QLatin1String("assets-library:")))
+ return showImagePickerDialog(parent);
+ else
+ return showNativeDocumentPickerDialog(parent);
+ }
return false;
}
@@ -102,6 +107,25 @@ bool QIOSFileDialog::showImagePickerDialog(QWindow *parent)
return true;
}
+bool QIOSFileDialog::showNativeDocumentPickerDialog(QWindow *parent)
+{
+#ifndef Q_OS_TVOS
+ if (options()->fileMode() == QFileDialogOptions::Directory ||
+ options()->fileMode() == QFileDialogOptions::DirectoryOnly)
+ return false;
+
+ m_viewController = [[QIOSDocumentPickerController alloc] initWithQIOSFileDialog:this];
+
+ UIWindow *window = parent ? reinterpret_cast<UIView *>(parent->winId()).window
+ : qt_apple_sharedApplication().keyWindow;
+ [window.rootViewController presentViewController:m_viewController animated:YES completion:nil];
+
+ return true;
+#else
+ return false;
+#endif
+}
+
void QIOSFileDialog::hide()
{
// QFileDialog will remember the last directory set, and open subsequent dialogs in the same
@@ -123,7 +147,7 @@ QList<QUrl> QIOSFileDialog::selectedFiles() const
return m_selection;
}
-void QIOSFileDialog::selectedFilesChanged(QList<QUrl> selection)
+void QIOSFileDialog::selectedFilesChanged(const QList<QUrl> &selection)
{
m_selection = selection;
emit filesSelected(m_selection);
diff --git a/src/plugins/platforms/ios/qioswindow.mm b/src/plugins/platforms/ios/qioswindow.mm
index cdec57de71..1b6a802ca2 100644
--- a/src/plugins/platforms/ios/qioswindow.mm
+++ b/src/plugins/platforms/ios/qioswindow.mm
@@ -51,6 +51,9 @@
#include <qpa/qplatformintegration.h>
#import <QuartzCore/CAEAGLLayer.h>
+#ifdef Q_OS_IOS
+#import <QuartzCore/CAMetalLayer.h>
+#endif
#include <QtDebug>
@@ -58,9 +61,15 @@ QT_BEGIN_NAMESPACE
QIOSWindow::QIOSWindow(QWindow *window)
: QPlatformWindow(window)
- , m_view([[QUIView alloc] initWithQIOSWindow:this])
, m_windowLevel(0)
{
+#ifdef Q_OS_IOS
+ if (window->surfaceType() == QSurface::MetalSurface)
+ m_view = [[QUIMetalView alloc] initWithQIOSWindow:this];
+ else
+#endif
+ m_view = [[QUIView alloc] initWithQIOSWindow:this];
+
connect(qGuiApp, &QGuiApplication::applicationStateChanged, this, &QIOSWindow::applicationStateChanged);
setParent(QPlatformWindow::parent());
diff --git a/src/plugins/platforms/ios/quiview.h b/src/plugins/platforms/ios/quiview.h
index e1d5d5af0c..1ab9481dd6 100644
--- a/src/plugins/platforms/ios/quiview.h
+++ b/src/plugins/platforms/ios/quiview.h
@@ -70,3 +70,7 @@ QT_END_NAMESPACE
@property (nonatomic, readonly) UIEdgeInsets qt_safeAreaInsets;
@end
+#ifdef Q_OS_IOS
+@interface QUIMetalView : QUIView
+@end
+#endif
diff --git a/src/plugins/platforms/ios/quiview.mm b/src/plugins/platforms/ios/quiview.mm
index 91a186bace..59eae07388 100644
--- a/src/plugins/platforms/ios/quiview.mm
+++ b/src/plugins/platforms/ios/quiview.mm
@@ -100,13 +100,15 @@ Q_LOGGING_CATEGORY(lcQpaTablet, "qt.qpa.input.tablet")
- (instancetype)initWithFrame:(CGRect)frame
{
if ((self = [super initWithFrame:frame])) {
- // Set up EAGL layer
- CAEAGLLayer *eaglLayer = static_cast<CAEAGLLayer *>(self.layer);
- eaglLayer.opaque = TRUE;
- eaglLayer.drawableProperties = @{
- kEAGLDrawablePropertyRetainedBacking: @(YES),
- kEAGLDrawablePropertyColorFormat: kEAGLColorFormatRGBA8
- };
+ if ([self.layer isKindOfClass:[CAEAGLLayer class]]) {
+ // Set up EAGL layer
+ CAEAGLLayer *eaglLayer = static_cast<CAEAGLLayer *>(self.layer);
+ eaglLayer.opaque = TRUE;
+ eaglLayer.drawableProperties = @{
+ kEAGLDrawablePropertyRetainedBacking: @(YES),
+ kEAGLDrawablePropertyColorFormat: kEAGLColorFormatRGBA8
+ };
+ }
if (isQtApplication())
self.hidden = YES;
@@ -675,6 +677,25 @@ Q_LOGGING_CATEGORY(lcQpaTablet, "qt.qpa.input.tablet")
@end
+#ifdef Q_OS_IOS
+@implementation QUIMetalView
+
++ (Class)layerClass
+{
+#ifdef TARGET_IPHONE_SIMULATOR
+ if (@available(ios 13.0, *))
+#endif
+
+ return [CAMetalLayer class];
+
+#ifdef TARGET_IPHONE_SIMULATOR
+ return nil;
+#endif
+}
+
+@end
+#endif
+
#ifndef QT_NO_ACCESSIBILITY
// Include category as an alternative to using -ObjC (Apple QA1490)
#include "quiview_accessibility.mm"
diff --git a/src/plugins/platforms/offscreen/main.cpp b/src/plugins/platforms/offscreen/main.cpp
index 207db60f3a..f364d9f004 100644
--- a/src/plugins/platforms/offscreen/main.cpp
+++ b/src/plugins/platforms/offscreen/main.cpp
@@ -57,7 +57,7 @@ QPlatformIntegration *QOffscreenIntegrationPlugin::create(const QString& system,
if (!system.compare(QLatin1String("offscreen"), Qt::CaseInsensitive))
return QOffscreenIntegration::createOffscreenIntegration();
- return 0;
+ return nullptr;
}
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/offscreen/qoffscreencommon.cpp b/src/plugins/platforms/offscreen/qoffscreencommon.cpp
index eae25012c1..de75a3e012 100644
--- a/src/plugins/platforms/offscreen/qoffscreencommon.cpp
+++ b/src/plugins/platforms/offscreen/qoffscreencommon.cpp
@@ -48,7 +48,7 @@
QT_BEGIN_NAMESPACE
-QPlatformWindow *QOffscreenScreen::windowContainingCursor = 0;
+QPlatformWindow *QOffscreenScreen::windowContainingCursor = nullptr;
class QOffscreenCursor : public QPlatformCursor
{
@@ -60,7 +60,7 @@ public:
{
m_pos = pos;
const QWindowList wl = QGuiApplication::topLevelWindows();
- QWindow *containing = 0;
+ QWindow *containing = nullptr;
for (QWindow *w : wl) {
if (w->type() != Qt::Desktop && w->isExposed() && w->geometry().contains(pos)) {
containing = w;
@@ -72,7 +72,7 @@ public:
if (containing)
local -= containing->position();
- QWindow *previous = QOffscreenScreen::windowContainingCursor ? QOffscreenScreen::windowContainingCursor->window() : 0;
+ QWindow *previous = QOffscreenScreen::windowContainingCursor ? QOffscreenScreen::windowContainingCursor->window() : nullptr;
if (containing != previous)
QWindowSystemInterface::handleEnterLeaveEvent(containing, previous, local, pos);
@@ -80,7 +80,7 @@ public:
QWindowSystemInterface::handleMouseEvent(containing, local, pos, QGuiApplication::mouseButtons(), Qt::NoButton,
QEvent::MouseMove, QGuiApplication::keyboardModifiers(), Qt::MouseEventSynthesizedByQt);
- QOffscreenScreen::windowContainingCursor = containing ? containing->handle() : 0;
+ QOffscreenScreen::windowContainingCursor = containing ? containing->handle() : nullptr;
}
#ifndef QT_NO_CURSOR
void changeCursor(QCursor *windowCursor, QWindow *window) override
@@ -106,7 +106,7 @@ QPixmap QOffscreenScreen::grabWindow(WId id, int x, int y, int width, int height
QOffscreenWindow *window = QOffscreenWindow::windowForWinId(id);
if (!window || window->window()->type() == Qt::Desktop) {
const QWindowList wl = QGuiApplication::topLevelWindows();
- QWindow *containing = 0;
+ QWindow *containing = nullptr;
for (QWindow *w : wl) {
if (w->type() != Qt::Desktop && w->isExposed() && w->geometry().contains(rect)) {
containing = w;
diff --git a/src/plugins/platforms/offscreen/qoffscreenintegration.cpp b/src/plugins/platforms/offscreen/qoffscreenintegration.cpp
index 869e9228cd..3a4494fc2e 100644
--- a/src/plugins/platforms/offscreen/qoffscreenintegration.cpp
+++ b/src/plugins/platforms/offscreen/qoffscreenintegration.cpp
@@ -79,7 +79,7 @@ template <typename BaseEventDispatcher>
class QOffscreenEventDispatcher : public BaseEventDispatcher
{
public:
- explicit QOffscreenEventDispatcher(QObject *parent = 0)
+ explicit QOffscreenEventDispatcher(QObject *parent = nullptr)
: BaseEventDispatcher(parent)
{
}
diff --git a/src/plugins/platforms/offscreen/qoffscreenintegration_x11.cpp b/src/plugins/platforms/offscreen/qoffscreenintegration_x11.cpp
index 92fc8aa57a..84991d751f 100644
--- a/src/plugins/platforms/offscreen/qoffscreenintegration_x11.cpp
+++ b/src/plugins/platforms/offscreen/qoffscreenintegration_x11.cpp
@@ -206,7 +206,7 @@ QOffscreenX11GLXContext::QOffscreenX11GLXContext(QOffscreenX11Info *x11, QOpenGL
if (d->format.renderableType() != QSurfaceFormat::OpenGL)
return;
- d->shareContext = 0;
+ d->shareContext = nullptr;
if (context->shareHandle())
d->shareContext = static_cast<QOffscreenX11GLXContext *>(context->shareHandle())->d->context;
@@ -216,9 +216,9 @@ QOffscreenX11GLXContext::QOffscreenX11GLXContext(QOffscreenX11Info *x11, QOpenGL
if (config) {
d->context = glXCreateNewContext(x11->display(), config, GLX_RGBA_TYPE, d->shareContext, true);
if (!d->context && d->shareContext) {
- d->shareContext = 0;
+ d->shareContext = nullptr;
// re-try without a shared glx context
- d->context = glXCreateNewContext(x11->display(), config, GLX_RGBA_TYPE, 0, true);
+ d->context = glXCreateNewContext(x11->display(), config, GLX_RGBA_TYPE, nullptr, true);
}
// Get the basic surface format details
@@ -234,8 +234,8 @@ QOffscreenX11GLXContext::QOffscreenX11GLXContext(QOffscreenX11Info *x11, QOpenGL
d->context = glXCreateContext(x11->display(), visualInfo, d->shareContext, true);
if (!d->context && d->shareContext) {
// re-try without a shared glx context
- d->shareContext = 0;
- d->context = glXCreateContext(x11->display(), visualInfo, 0, true);
+ d->shareContext = nullptr;
+ d->context = glXCreateContext(x11->display(), visualInfo, nullptr, true);
}
d->window = createDummyWindow(x11, visualInfo);
@@ -269,7 +269,7 @@ bool QOffscreenX11GLXContext::makeCurrent(QPlatformSurface *surface)
void QOffscreenX11GLXContext::doneCurrent()
{
- glXMakeCurrent(d->x11->display(), 0, 0);
+ glXMakeCurrent(d->x11->display(), 0, nullptr);
}
void QOffscreenX11GLXContext::swapBuffers(QPlatformSurface *)
diff --git a/src/plugins/platforms/offscreen/qoffscreenwindow.cpp b/src/plugins/platforms/offscreen/qoffscreenwindow.cpp
index 832e94034d..53880c877e 100644
--- a/src/plugins/platforms/offscreen/qoffscreenwindow.cpp
+++ b/src/plugins/platforms/offscreen/qoffscreenwindow.cpp
@@ -69,7 +69,7 @@ QOffscreenWindow::QOffscreenWindow(QWindow *window)
QOffscreenWindow::~QOffscreenWindow()
{
if (QOffscreenScreen::windowContainingCursor == this)
- QOffscreenScreen::windowContainingCursor = 0;
+ QOffscreenScreen::windowContainingCursor = nullptr;
m_windowForWinIdHash.remove(m_winId);
}
diff --git a/src/plugins/platforms/platforms.pro b/src/plugins/platforms/platforms.pro
index c4f2b30965..23f838a7fe 100644
--- a/src/plugins/platforms/platforms.pro
+++ b/src/plugins/platforms/platforms.pro
@@ -3,9 +3,9 @@ QT_FOR_CONFIG += gui-private
android:!android-embedded: SUBDIRS += android
-!android: SUBDIRS += minimal
+!wasm:!android: SUBDIRS += minimal
-!android:qtConfig(freetype): SUBDIRS += offscreen
+!wasm:!android:qtConfig(freetype): SUBDIRS += offscreen
qtConfig(xcb) {
SUBDIRS += xcb
diff --git a/src/plugins/platforms/qnx/qqnxglcontext.cpp b/src/plugins/platforms/qnx/qqnxglcontext.cpp
index 1d030ba1aa..69391c4fec 100644
--- a/src/plugins/platforms/qnx/qqnxglcontext.cpp
+++ b/src/plugins/platforms/qnx/qqnxglcontext.cpp
@@ -58,8 +58,6 @@
QT_BEGIN_NAMESPACE
-EGLDisplay QQnxGLContext::ms_eglDisplay = EGL_NO_DISPLAY;
-
static QEGLPlatformContext::Flags makeFlags()
{
QEGLPlatformContext::Flags result = 0;
@@ -71,7 +69,8 @@ static QEGLPlatformContext::Flags makeFlags()
}
QQnxGLContext::QQnxGLContext(const QSurfaceFormat &format, QPlatformOpenGLContext *share)
- : QEGLPlatformContext(format, share, ms_eglDisplay, 0, QVariant(), makeFlags())
+ : QEGLPlatformContext(format, share, QQnxIntegration::instance()->eglDisplay(), 0, QVariant(),
+ makeFlags())
{
}
@@ -79,28 +78,6 @@ QQnxGLContext::~QQnxGLContext()
{
}
-void QQnxGLContext::initializeContext()
-{
- qGLContextDebug();
-
- // Initialize connection to EGL
- ms_eglDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY);
- if (Q_UNLIKELY(ms_eglDisplay == EGL_NO_DISPLAY))
- qFatal("QQnxGLContext: failed to obtain EGL display: %x", eglGetError());
-
- EGLBoolean eglResult = eglInitialize(ms_eglDisplay, 0, 0);
- if (Q_UNLIKELY(eglResult != EGL_TRUE))
- qFatal("QQnxGLContext: failed to initialize EGL display, err=%d", eglGetError());
-}
-
-void QQnxGLContext::shutdownContext()
-{
- qGLContextDebug();
-
- // Close connection to EGL
- eglTerminate(ms_eglDisplay);
-}
-
EGLSurface QQnxGLContext::eglSurfaceForPlatformSurface(QPlatformSurface *surface)
{
QQnxEglWindow *window = static_cast<QQnxEglWindow *>(surface);
diff --git a/src/plugins/platforms/qnx/qqnxglcontext.h b/src/plugins/platforms/qnx/qqnxglcontext.h
index 19179a80e2..5d807ee9e4 100644
--- a/src/plugins/platforms/qnx/qqnxglcontext.h
+++ b/src/plugins/platforms/qnx/qqnxglcontext.h
@@ -58,19 +58,12 @@ public:
QQnxGLContext(const QSurfaceFormat &format, QPlatformOpenGLContext *share);
virtual ~QQnxGLContext();
- static void initializeContext();
- static void shutdownContext();
-
bool makeCurrent(QPlatformSurface *surface) override;
void swapBuffers(QPlatformSurface *surface) override;
void doneCurrent() override;
protected:
EGLSurface eglSurfaceForPlatformSurface(QPlatformSurface *surface) override;
-
-private:
- //Can be static because different displays returne the same handle
- static EGLDisplay ms_eglDisplay;
};
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/qnx/qqnxintegration.cpp b/src/plugins/platforms/qnx/qqnxintegration.cpp
index f479e94988..84baa6ec44 100644
--- a/src/plugins/platforms/qnx/qqnxintegration.cpp
+++ b/src/plugins/platforms/qnx/qqnxintegration.cpp
@@ -170,6 +170,9 @@ QQnxIntegration::QQnxIntegration(const QStringList &paramList)
#if QT_CONFIG(draganddrop)
, m_drag(new QSimpleDrag())
#endif
+#if QT_CONFIG(opengl)
+ , m_eglDisplay(EGL_NO_DISPLAY)
+#endif
{
ms_instance = this;
m_options = parseOptions(paramList);
@@ -195,9 +198,8 @@ QQnxIntegration::QQnxIntegration(const QStringList &paramList)
QMetaObject::invokeMethod(m_navigatorEventNotifier, "start", Qt::QueuedConnection);
#endif
-#if !defined(QT_NO_OPENGL)
- // Initialize global OpenGL resources
- QQnxGLContext::initializeContext();
+#if QT_CONFIG(opengl)
+ createEglDisplay();
#endif
// Create/start event thread
@@ -284,9 +286,8 @@ QQnxIntegration::~QQnxIntegration()
// Close connection to QNX composition manager
screen_destroy_context(m_screenContext);
-#if !defined(QT_NO_OPENGL)
- // Cleanup global OpenGL resources
- QQnxGLContext::shutdownContext();
+#if QT_CONFIG(opengl)
+ destroyEglDisplay();
#endif
#if QT_CONFIG(qqnx_pps)
@@ -741,4 +742,28 @@ bool QQnxIntegration::supportsNavigatorEvents() const
return m_navigator != 0;
}
+#if QT_CONFIG(opengl)
+void QQnxIntegration::createEglDisplay()
+{
+ qIntegrationDebug();
+
+ // Initialize connection to EGL
+ m_eglDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY);
+ if (Q_UNLIKELY(m_eglDisplay == EGL_NO_DISPLAY))
+ qFatal("QQnxiIntegration: failed to obtain EGL display: %x", eglGetError());
+
+ EGLBoolean eglResult = eglInitialize(m_eglDisplay, 0, 0);
+ if (Q_UNLIKELY(eglResult != EGL_TRUE))
+ qFatal("QQnxIntegration: failed to initialize EGL display, err=%d", eglGetError());
+}
+
+void QQnxIntegration::destroyEglDisplay()
+{
+ qIntegrationDebug();
+
+ // Close connection to EGL
+ eglTerminate(m_eglDisplay);
+}
+#endif
+
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/qnx/qqnxintegration.h b/src/plugins/platforms/qnx/qqnxintegration.h
index 0bf37880d1..2596af3c45 100644
--- a/src/plugins/platforms/qnx/qqnxintegration.h
+++ b/src/plugins/platforms/qnx/qqnxintegration.h
@@ -46,6 +46,10 @@
#include <screen/screen.h>
+#if QT_CONFIG(opengl)
+#include <EGL/egl.h>
+#endif
+
QT_BEGIN_NAMESPACE
class QQnxScreenEventThread;
@@ -96,7 +100,8 @@ public:
QPlatformWindow *createPlatformWindow(QWindow *window) const override;
QPlatformBackingStore *createPlatformBackingStore(QWindow *window) const override;
-#if !defined(QT_NO_OPENGL)
+#if QT_CONFIG(opengl)
+ EGLDisplay eglDisplay() const { return m_eglDisplay; }
QPlatformOpenGLContext *createPlatformOpenGLContext(QOpenGLContext *context) const override;
#endif
@@ -175,6 +180,12 @@ private:
Options m_options;
+#if QT_CONFIG(opengl)
+ EGLDisplay m_eglDisplay;
+ void createEglDisplay();
+ void destroyEglDisplay();
+#endif
+
static QQnxIntegration *ms_instance;
friend class QQnxWindow;
diff --git a/src/plugins/platforms/qnx/qqnxnativeinterface.cpp b/src/plugins/platforms/qnx/qqnxnativeinterface.cpp
index 3bd6a86b59..25f7b09a60 100644
--- a/src/plugins/platforms/qnx/qqnxnativeinterface.cpp
+++ b/src/plugins/platforms/qnx/qqnxnativeinterface.cpp
@@ -94,6 +94,11 @@ void *QQnxNativeInterface::nativeResourceForIntegration(const QByteArray &resour
if (resource == "screenContext")
return m_integration->screenContext();
+#if QT_CONFIG(opengl)
+ if (resource.toLower() == "egldisplay")
+ return m_integration->eglDisplay();
+#endif
+
return 0;
}
diff --git a/src/plugins/platforms/qnx/qqnxscreeneventhandler.cpp b/src/plugins/platforms/qnx/qqnxscreeneventhandler.cpp
index a9b5860187..e3a6aea99f 100644
--- a/src/plugins/platforms/qnx/qqnxscreeneventhandler.cpp
+++ b/src/plugins/platforms/qnx/qqnxscreeneventhandler.cpp
@@ -257,7 +257,7 @@ void QQnxScreenEventHandler::injectKeyboardEvent(int flags, int sym, int modifie
capKeyString(cap, modifiers, key);
QWindowSystemInterface::handleExtendedKeyEvent(QGuiApplication::focusWindow(), type, key, qtMod,
- scan, virtualKey, modifiers, keyStr);
+ scan, virtualKey, modifiers, keyStr, flags & KEY_REPEAT);
qScreenEventDebug() << "Qt key t=" << type << ", k=" << key << ", s=" << keyStr;
}
diff --git a/src/plugins/platforms/vnc/main.cpp b/src/plugins/platforms/vnc/main.cpp
index 3ec0f0b78d..ac7e18e03f 100644
--- a/src/plugins/platforms/vnc/main.cpp
+++ b/src/plugins/platforms/vnc/main.cpp
@@ -56,7 +56,7 @@ QPlatformIntegration* QVncIntegrationPlugin::create(const QString& system, const
if (!system.compare(QLatin1String("vnc"), Qt::CaseInsensitive))
return new QVncIntegration(paramList);
- return 0;
+ return nullptr;
}
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/vnc/qvnc.cpp b/src/plugins/platforms/vnc/qvnc.cpp
index 32114c6443..8390fa19cd 100644
--- a/src/plugins/platforms/vnc/qvnc.cpp
+++ b/src/plugins/platforms/vnc/qvnc.cpp
@@ -537,7 +537,7 @@ QVncClientCursor::QVncClientCursor()
{
QWindow *w = QGuiApplication::focusWindow();
QCursor c = w ? w->cursor() : QCursor(Qt::ArrowCursor);
- changeCursor(&c, 0);
+ changeCursor(&c, nullptr);
}
QVncClientCursor::~QVncClientCursor()
@@ -595,7 +595,7 @@ void QVncClientCursor::changeCursor(QCursor *widgetCursor, QWindow *window)
cursor = widgetCursor->pixmap().toImage();
} else {
// system cursor
- QPlatformCursorImage platformImage(0, 0, 0, 0, 0, 0);
+ QPlatformCursorImage platformImage(nullptr, nullptr, 0, 0, 0, 0);
platformImage.set(shape);
cursor = *platformImage.image();
hotspot = platformImage.hotspot();
diff --git a/src/plugins/platforms/vnc/qvncclient.cpp b/src/plugins/platforms/vnc/qvncclient.cpp
index 3a373a5e4b..c5caddc58d 100644
--- a/src/plugins/platforms/vnc/qvncclient.cpp
+++ b/src/plugins/platforms/vnc/qvncclient.cpp
@@ -65,7 +65,6 @@ QVncClient::QVncClient(QTcpSocket *clientSocket, QVncServer *server)
, m_cutTextPending(0)
, m_supportHextile(false)
, m_wantUpdate(false)
- , m_keymod(0)
, m_dirtyCursor(false)
, m_updatePending(false)
, m_protocolVersion(V3_3)
@@ -618,7 +617,7 @@ void QVncClient::keyEvent()
m_keymod = ev.down ? m_keymod | Qt::AltModifier :
m_keymod & ~Qt::AltModifier;
if (ev.unicode || ev.keycode)
- QWindowSystemInterface::handleKeyEvent(0, ev.down ? QEvent::KeyPress : QEvent::KeyRelease, ev.keycode, m_keymod, QString(ev.unicode));
+ QWindowSystemInterface::handleKeyEvent(nullptr, ev.down ? QEvent::KeyPress : QEvent::KeyRelease, ev.keycode, m_keymod, QString(ev.unicode));
m_handleMsg = false;
}
}
diff --git a/src/plugins/platforms/vnc/qvncscreen.cpp b/src/plugins/platforms/vnc/qvncscreen.cpp
index 2eca18fb4d..5dc3919ff5 100644
--- a/src/plugins/platforms/vnc/qvncscreen.cpp
+++ b/src/plugins/platforms/vnc/qvncscreen.cpp
@@ -101,7 +101,7 @@ bool QVncScreen::initialize()
default:
qWarning("QVNCScreen::initDevice: No support for screen depth %d",
depth());
- dirty = 0;
+ dirty = nullptr;
return false;
}
diff --git a/src/plugins/platforms/wasm/qwasmclipboard.cpp b/src/plugins/platforms/wasm/qwasmclipboard.cpp
index f02c2c6ccb..890b01fa3c 100644
--- a/src/plugins/platforms/wasm/qwasmclipboard.cpp
+++ b/src/plugins/platforms/wasm/qwasmclipboard.cpp
@@ -192,15 +192,12 @@ void QWasmClipboard::initClipboardEvents()
permissions.call<val>("query", writePermissionsMap);
}
-void QWasmClipboard::installEventHandlers(const QString &canvasId)
+void QWasmClipboard::installEventHandlers(const emscripten::val &canvas)
{
if (hasClipboardApi)
return;
// Fallback path for browsers which do not support direct clipboard access
- val document = val::global("document");
- val canvas = document.call<val>("getElementById", QWasmString::fromQString(canvasId));
-
canvas.call<void>("addEventListener", val("cut"),
val::module_property("qtClipboardCutTo"));
canvas.call<void>("addEventListener", val("copy"),
diff --git a/src/plugins/platforms/wasm/qwasmclipboard.h b/src/plugins/platforms/wasm/qwasmclipboard.h
index 00aae8fead..3b28e2c381 100644
--- a/src/plugins/platforms/wasm/qwasmclipboard.h
+++ b/src/plugins/platforms/wasm/qwasmclipboard.h
@@ -36,6 +36,7 @@
#include <QMimeData>
#include <emscripten/bind.h>
+#include <emscripten/val.h>
class QWasmClipboard : public QObject, public QPlatformClipboard
{
@@ -51,7 +52,7 @@ public:
static void qWasmClipboardPaste(QMimeData *mData);
void initClipboardEvents();
- void installEventHandlers(const QString &canvasId);
+ void installEventHandlers(const emscripten::val &canvas);
bool hasClipboardApi;
void readTextFromClipboard();
void writeTextToClipboard();
diff --git a/src/plugins/platforms/wasm/qwasmcursor.cpp b/src/plugins/platforms/wasm/qwasmcursor.cpp
index 616456b2fa..61204517ce 100644
--- a/src/plugins/platforms/wasm/qwasmcursor.cpp
+++ b/src/plugins/platforms/wasm/qwasmcursor.cpp
@@ -57,9 +57,7 @@ void QWasmCursor::changeCursor(QCursor *windowCursor, QWindow *window)
htmlCursorName = "auto";
// Set cursor on the canvas
- val jsCanvasId = QWasmString::fromQString(QWasmScreen::get(screen)->canvasId());
- val document = val::global("document");
- val canvas = document.call<val>("getElementById", jsCanvasId);
+ val canvas = QWasmScreen::get(screen)->canvas();
val canvasStyle = canvas["style"];
canvasStyle.set("cursor", val(htmlCursorName.constData()));
}
diff --git a/src/plugins/platforms/wasm/qwasmeventdispatcher.cpp b/src/plugins/platforms/wasm/qwasmeventdispatcher.cpp
index ca8db9b215..09acd37abc 100644
--- a/src/plugins/platforms/wasm/qwasmeventdispatcher.cpp
+++ b/src/plugins/platforms/wasm/qwasmeventdispatcher.cpp
@@ -194,6 +194,7 @@ void QWasmEventDispatcher::wakeUp()
{
#ifdef EMSCRIPTEN_HAS_ASYNC_RUN_IN_MAIN_RUNTIME_THREAD
if (!emscripten_is_main_runtime_thread())
+ if (m_hasMainLoop)
emscripten_async_run_in_main_runtime_thread_(EM_FUNC_SIG_VI, (void*)(&QWasmEventDispatcher::mainThreadWakeUp), this);
#endif
QEventDispatcherUNIX::wakeUp();
diff --git a/src/plugins/platforms/wasm/qwasmeventtranslator.cpp b/src/plugins/platforms/wasm/qwasmeventtranslator.cpp
index 62ada796db..3e6043b083 100644
--- a/src/plugins/platforms/wasm/qwasmeventtranslator.cpp
+++ b/src/plugins/platforms/wasm/qwasmeventtranslator.cpp
@@ -354,9 +354,7 @@ void QWasmEventTranslator::initEventHandlers()
g_useNaturalScrolling = false; // make this !default on macOS
if (emscripten::val::global("window")["safari"].isUndefined()) {
- val document = val::global("document");
- val jsCanvasId = QWasmString::fromQString(screen()->canvasId());
- val canvas = document.call<val>("getElementById", jsCanvasId);
+ val canvas = screen()->canvas();
canvas.call<void>("addEventListener",
val("wheel"),
val::module_property("qtMouseWheelEvent"));
diff --git a/src/plugins/platforms/wasm/qwasmintegration.cpp b/src/plugins/platforms/wasm/qwasmintegration.cpp
index f8eaa39f76..4b42b5788f 100644
--- a/src/plugins/platforms/wasm/qwasmintegration.cpp
+++ b/src/plugins/platforms/wasm/qwasmintegration.cpp
@@ -68,20 +68,17 @@ static void browserBeforeUnload(emscripten::val)
static void addCanvasElement(emscripten::val canvas)
{
- QString canvasId = QWasmString::toQString(canvas["id"]);
- QWasmIntegration::get()->addScreen(canvasId);
+ QWasmIntegration::get()->addScreen(canvas);
}
static void removeCanvasElement(emscripten::val canvas)
{
- QString canvasId = QWasmString::toQString(canvas["id"]);
- QWasmIntegration::get()->removeScreen(canvasId);
+ QWasmIntegration::get()->removeScreen(canvas);
}
static void resizeCanvasElement(emscripten::val canvas)
{
- QString canvasId = QWasmString::toQString(canvas["id"]);
- QWasmIntegration::get()->resizeScreen(canvasId);
+ QWasmIntegration::get()->resizeScreen(canvas);
}
static void qtUpdateDpi()
@@ -114,15 +111,12 @@ QWasmIntegration::QWasmIntegration()
if (!qtCanvaseElements.isUndefined()) {
int screenCount = qtCanvaseElements["length"].as<int>();
for (int i = 0; i < screenCount; ++i) {
- emscripten::val canvas = qtCanvaseElements[i].as<emscripten::val>();
- QString canvasId = QWasmString::toQString(canvas["id"]);
- addScreen(canvasId);
+ addScreen(qtCanvaseElements[i].as<emscripten::val>());
}
} else if (!canvas.isUndefined()) {
qWarning() << "Module.canvas is deprecated. A future version of Qt will stop reading this property. "
<< "Instead, set Module.qtCanvasElements to be an array of canvas elements, or use qtloader.js.";
- QString canvasId = QWasmString::toQString(canvas["id"]);
- addScreen(canvasId);
+ addScreen(canvas);
}
emscripten::val::global("window").set("onbeforeunload", val::module_property("qtBrowserBeforeUnload"));
@@ -148,8 +142,8 @@ QWasmIntegration::~QWasmIntegration()
delete m_fontDb;
delete m_desktopServices;
- for (auto it = m_screens.constBegin(); it != m_screens.constEnd(); ++it)
- QWindowSystemInterface::handleScreenRemoved(*it);
+ for (const auto &canvasAndScreen : m_screens)
+ QWindowSystemInterface::handleScreenRemoved(canvasAndScreen.second);
m_screens.clear();
s_instance = nullptr;
@@ -276,24 +270,37 @@ QPlatformClipboard* QWasmIntegration::clipboard() const
return m_clipboard;
}
-void QWasmIntegration::addScreen(const QString &canvasId)
+void QWasmIntegration::addScreen(const emscripten::val &canvas)
{
- QWasmScreen *screen = new QWasmScreen(canvasId);
- m_clipboard->installEventHandlers(canvasId);
- m_screens.insert(canvasId, screen);
+ QWasmScreen *screen = new QWasmScreen(canvas);
+ m_screens.append(qMakePair(canvas, screen));
+ m_clipboard->installEventHandlers(canvas);
QWindowSystemInterface::handleScreenAdded(screen);
}
-void QWasmIntegration::removeScreen(const QString &canvasId)
+void QWasmIntegration::removeScreen(const emscripten::val &canvas)
{
- QWasmScreen *exScreen = m_screens.take(canvasId);
+ auto it = std::find_if(m_screens.begin(), m_screens.end(),
+ [&] (const QPair<emscripten::val, QWasmScreen *> &candidate) { return candidate.first.equals(canvas); });
+ if (it == m_screens.end()) {
+ qWarning() << "Attempting to remove non-existing screen for canvas" << QWasmString::toQString(canvas["id"]);;
+ return;
+ }
+ QWasmScreen *exScreen = it->second;
+ m_screens.erase(it);
exScreen->destroy(); // clean up before deleting the screen
QWindowSystemInterface::handleScreenRemoved(exScreen);
}
-void QWasmIntegration::resizeScreen(const QString &canvasId)
+void QWasmIntegration::resizeScreen(const emscripten::val &canvas)
{
- m_screens.value(canvasId)->updateQScreenAndCanvasRenderSize();
+ auto it = std::find_if(m_screens.begin(), m_screens.end(),
+ [&] (const QPair<emscripten::val, QWasmScreen *> &candidate) { return candidate.first.equals(canvas); });
+ if (it == m_screens.end()) {
+ qWarning() << "Attempting to resize non-existing screen for canvas" << QWasmString::toQString(canvas["id"]);;
+ return;
+ }
+ it->second->updateQScreenAndCanvasRenderSize();
}
void QWasmIntegration::updateDpi()
@@ -302,15 +309,14 @@ void QWasmIntegration::updateDpi()
if (dpi.isUndefined())
return;
qreal dpiValue = dpi.as<qreal>();
- for (QWasmScreen *screen : m_screens)
- QWindowSystemInterface::handleScreenLogicalDotsPerInchChange(screen->screen(), dpiValue, dpiValue);
+ for (const auto &canvasAndScreen : m_screens)
+ QWindowSystemInterface::handleScreenLogicalDotsPerInchChange(canvasAndScreen.second->screen(), dpiValue, dpiValue);
}
void QWasmIntegration::resizeAllScreens()
{
- qDebug() << "resizeAllScreens";
- for (QWasmScreen *screen : m_screens)
- screen->updateQScreenAndCanvasRenderSize();
+ for (const auto &canvasAndScreen : m_screens)
+ canvasAndScreen.second->updateQScreenAndCanvasRenderSize();
}
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/wasm/qwasmintegration.h b/src/plugins/platforms/wasm/qwasmintegration.h
index 2eb64ed366..cb8639086a 100644
--- a/src/plugins/platforms/wasm/qwasmintegration.h
+++ b/src/plugins/platforms/wasm/qwasmintegration.h
@@ -40,6 +40,7 @@
#include <emscripten.h>
#include <emscripten/html5.h>
+#include <emscripten/val.h>
QT_BEGIN_NAMESPACE
@@ -83,9 +84,9 @@ public:
static QWasmIntegration *get() { return s_instance; }
static void QWasmBrowserExit();
- void addScreen(const QString &canvasId);
- void removeScreen(const QString &canvasId);
- void resizeScreen(const QString &canvasId);
+ void addScreen(const emscripten::val &canvas);
+ void removeScreen(const emscripten::val &canvas);
+ void resizeScreen(const emscripten::val &canvas);
void resizeAllScreens();
void updateDpi();
void removeBackingStore(QWindow* window);
@@ -94,8 +95,7 @@ private:
mutable QWasmFontDatabase *m_fontDb;
mutable QWasmServices *m_desktopServices;
mutable QHash<QWindow *, QWasmBackingStore *> m_backingStores;
-
- QHash<QString, QWasmScreen *> m_screens;
+ QVector<QPair<emscripten::val, QWasmScreen *>> m_screens;
mutable QWasmClipboard *m_clipboard;
qreal m_fontDpi = -1;
mutable QScopedPointer<QPlatformInputContext> m_inputContext;
diff --git a/src/plugins/platforms/wasm/qwasmopenglcontext.cpp b/src/plugins/platforms/wasm/qwasmopenglcontext.cpp
index 4ddd56fd8c..fbf700518e 100644
--- a/src/plugins/platforms/wasm/qwasmopenglcontext.cpp
+++ b/src/plugins/platforms/wasm/qwasmopenglcontext.cpp
@@ -88,7 +88,7 @@ EMSCRIPTEN_WEBGL_CONTEXT_HANDLE QWasmOpenGLContext::createEmscriptenContext(cons
EmscriptenWebGLContextAttributes attributes;
emscripten_webgl_init_context_attributes(&attributes); // Populate with default attributes
- attributes.preferLowPowerToHighPerformance = false;
+ attributes.powerPreference = EM_WEBGL_POWER_PREFERENCE_HIGH_PERFORMANCE;
attributes.failIfMajorPerformanceCaveat = false;
attributes.antialias = true;
attributes.enableExtensionsByDefault = true;
diff --git a/src/plugins/platforms/wasm/qwasmscreen.cpp b/src/plugins/platforms/wasm/qwasmscreen.cpp
index 2788f1ac19..a2bcd4fcb4 100644
--- a/src/plugins/platforms/wasm/qwasmscreen.cpp
+++ b/src/plugins/platforms/wasm/qwasmscreen.cpp
@@ -50,13 +50,13 @@ using namespace emscripten;
QT_BEGIN_NAMESPACE
-QWasmScreen::QWasmScreen(const QString &canvasId)
- : m_canvasId(canvasId)
-
+QWasmScreen::QWasmScreen(const emscripten::val &canvas)
+ : m_canvas(canvas)
{
m_compositor = new QWasmCompositor(this);
m_eventTranslator = new QWasmEventTranslator(this);
updateQScreenAndCanvasRenderSize();
+ m_canvas.call<void>("focus");
}
QWasmScreen::~QWasmScreen()
@@ -89,9 +89,14 @@ QWasmEventTranslator *QWasmScreen::eventTranslator()
return m_eventTranslator;
}
+emscripten::val QWasmScreen::canvas() const
+{
+ return m_canvas;
+}
+
QString QWasmScreen::canvasId() const
{
- return m_canvasId;
+ return QWasmString::toQString(m_canvas["id"]);
}
QRect QWasmScreen::geometry() const
@@ -132,7 +137,7 @@ qreal QWasmScreen::devicePixelRatio() const
QString QWasmScreen::name() const
{
- return m_canvasId;
+ return canvasId();
}
QPlatformCursor *QWasmScreen::cursor() const
@@ -178,24 +183,22 @@ void QWasmScreen::updateQScreenAndCanvasRenderSize()
// Setting the render size to a value larger than the CSS size enables high-dpi
// rendering.
- QByteArray canvasSelector = "#" + m_canvasId.toUtf8();
+ QByteArray canvasSelector = "#" + canvasId().toUtf8();
double css_width;
double css_height;
emscripten_get_element_css_size(canvasSelector.constData(), &css_width, &css_height);
QSizeF cssSize(css_width, css_height);
QSizeF canvasSize = cssSize * devicePixelRatio();
- val document = val::global("document");
- val canvas = document.call<val>("getElementById", QWasmString::fromQString(m_canvasId));
- canvas.set("width", canvasSize.width());
- canvas.set("height", canvasSize.height());
+ m_canvas.set("width", canvasSize.width());
+ m_canvas.set("height", canvasSize.height());
QPoint offset;
- offset.setX(canvas["offsetTop"].as<int>());
- offset.setY(canvas["offsetLeft"].as<int>());
+ offset.setX(m_canvas["offsetTop"].as<int>());
+ offset.setY(m_canvas["offsetLeft"].as<int>());
- emscripten::val rect = canvas.call<emscripten::val>("getBoundingClientRect");
+ emscripten::val rect = m_canvas.call<emscripten::val>("getBoundingClientRect");
QPoint position(rect["left"].as<int>() - offset.x(), rect["top"].as<int>() - offset.y());
setGeometry(QRect(position, cssSize.toSize()));
diff --git a/src/plugins/platforms/wasm/qwasmscreen.h b/src/plugins/platforms/wasm/qwasmscreen.h
index fcf693681c..ea7ffc4193 100644
--- a/src/plugins/platforms/wasm/qwasmscreen.h
+++ b/src/plugins/platforms/wasm/qwasmscreen.h
@@ -37,6 +37,8 @@
#include <QtCore/qscopedpointer.h>
#include <QtCore/qtextstream.h>
+#include <emscripten/val.h>
+
QT_BEGIN_NAMESPACE
class QPlatformOpenGLContext;
@@ -50,12 +52,13 @@ class QWasmScreen : public QObject, public QPlatformScreen
{
Q_OBJECT
public:
- QWasmScreen(const QString &canvasId);
+ QWasmScreen(const emscripten::val &canvas);
~QWasmScreen();
void destroy();
static QWasmScreen *get(QPlatformScreen *screen);
static QWasmScreen *get(QScreen *screen);
+ emscripten::val canvas() const;
QString canvasId() const;
QWasmCompositor *compositor();
@@ -80,7 +83,7 @@ public slots:
void setGeometry(const QRect &rect);
private:
- QString m_canvasId;
+ emscripten::val m_canvas;
QWasmCompositor *m_compositor = nullptr;
QWasmEventTranslator *m_eventTranslator = nullptr;
QRect m_geometry = QRect(0, 0, 100, 100);
diff --git a/src/plugins/platforms/wasm/qwasmwindow.cpp b/src/plugins/platforms/wasm/qwasmwindow.cpp
index 594db65cfd..f95335f891 100644
--- a/src/plugins/platforms/wasm/qwasmwindow.cpp
+++ b/src/plugins/platforms/wasm/qwasmwindow.cpp
@@ -265,6 +265,8 @@ bool QWasmWindow::isPointOnTitle(QPoint point) const
bool QWasmWindow::isPointOnResizeRegion(QPoint point) const
{
+ if (window()->flags().testFlag(Qt::Popup))
+ return false;
return resizeRegion().contains(point);
}
@@ -402,7 +404,8 @@ void QWasmWindow::requestUpdate()
bool QWasmWindow::hasTitleBar() const
{
- return !(m_windowState & Qt::WindowFullScreen) && (window()->flags().testFlag(Qt::WindowTitleHint) && m_needsCompositor);
+ return !(m_windowState & Qt::WindowFullScreen) && (window()->flags().testFlag(Qt::WindowTitleHint) && m_needsCompositor)
+ && !window()->flags().testFlag(Qt::Popup);
}
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/windows/qwindowsclipboard.cpp b/src/plugins/platforms/windows/qwindowsclipboard.cpp
index 4e6d3306e1..efcb0b6e6e 100644
--- a/src/plugins/platforms/windows/qwindowsclipboard.cpp
+++ b/src/plugins/platforms/windows/qwindowsclipboard.cpp
@@ -82,7 +82,7 @@ static QDebug operator<<(QDebug d, const QMimeData *mimeData)
d << "QMimeData(";
if (mimeData) {
const QStringList formats = mimeData->formats();
- d << "formats=" << formats.join(QLatin1String(", "));
+ d << "formats=" << formats.join(u", ");
if (mimeData->hasText())
d << ", text=" << mimeData->text();
if (mimeData->hasHtml())
@@ -190,7 +190,7 @@ void QWindowsClipboard::releaseIData()
void QWindowsClipboard::registerViewer()
{
m_clipboardViewer = QWindowsContext::instance()->
- createDummyWindow(QStringLiteral("Qt5ClipboardView"), L"Qt5ClipboardView",
+ createDummyWindow(QStringLiteral("ClipboardView"), L"QtClipboardView",
qClipboardViewerWndProc, WS_OVERLAPPED);
// Try format listener API (Vista onwards) first.
@@ -339,7 +339,7 @@ void QWindowsClipboard::setMimeData(QMimeData *mimeData, QClipboard::Mode mode)
if (src != S_OK) {
QString mimeDataFormats = mimeData ?
- mimeData->formats().join(QLatin1String(", ")) : QString(QStringLiteral("NULL"));
+ mimeData->formats().join(u", ") : QString(QStringLiteral("NULL"));
qErrnoWarning("OleSetClipboard: Failed to set mime data (%s) on clipboard: %s",
qPrintable(mimeDataFormats),
QWindowsContext::comErrorString(src).constData());
diff --git a/src/plugins/platforms/windows/qwindowscontext.cpp b/src/plugins/platforms/windows/qwindowscontext.cpp
index 293faf8a53..820f00560a 100644
--- a/src/plugins/platforms/windows/qwindowscontext.cpp
+++ b/src/plugins/platforms/windows/qwindowscontext.cpp
@@ -42,6 +42,7 @@
#include "qwindowsintegration.h"
#include "qwindowswindow.h"
#include "qwindowskeymapper.h"
+#include "qwindowsnativeinterface.h"
#include "qwindowsmousehandler.h"
#include "qwindowspointerhandler.h"
#include "qtwindowsglobal.h"
@@ -72,6 +73,7 @@
#include <QtCore/qset.h>
#include <QtCore/qhash.h>
+#include <QtCore/qlibraryinfo.h>
#include <QtCore/qstringlist.h>
#include <QtCore/qdebug.h>
#include <QtCore/qoperatingsystemversion.h>
@@ -276,8 +278,11 @@ struct QWindowsContextPrivate {
bool m_asyncExpose = false;
HPOWERNOTIFY m_powerNotification = nullptr;
HWND m_powerDummyWindow = nullptr;
+ static bool m_darkMode;
};
+bool QWindowsContextPrivate::m_darkMode = false;
+
QWindowsContextPrivate::QWindowsContextPrivate()
: m_oleInitializeResult(OleInitialize(nullptr))
{
@@ -292,6 +297,7 @@ QWindowsContextPrivate::QWindowsContextPrivate()
m_systemInfo |= QWindowsContext::SI_RTL_Extensions;
m_keyMapper.setUseRTLExtensions(true);
}
+ m_darkMode = QWindowsTheme::queryDarkMode();
if (FAILED(m_oleInitializeResult)) {
qWarning() << "QWindowsContext: OleInitialize() failed: "
<< QWindowsContext::comErrorString(m_oleInitializeResult);
@@ -426,7 +432,7 @@ bool QWindowsContext::initPowerNotificationHandler()
if (d->m_powerNotification)
return false;
- d->m_powerDummyWindow = createDummyWindow(QStringLiteral("QtPowerDummyWindow"), L"QtPowerDummyWindow", qWindowsPowerWindowProc);
+ d->m_powerDummyWindow = createDummyWindow(QStringLiteral("PowerDummyWindow"), L"QtPowerDummyWindow", qWindowsPowerWindowProc);
if (!d->m_powerDummyWindow)
return false;
@@ -484,6 +490,11 @@ void QWindowsContext::setProcessDpiAwareness(QtWindows::ProcessDpiAwareness dpiA
}
}
+bool QWindowsContext::isDarkMode()
+{
+ return QWindowsContextPrivate::m_darkMode;
+}
+
QWindowsContext *QWindowsContext::instance()
{
return m_instance;
@@ -536,6 +547,23 @@ void QWindowsContext::setKeyGrabber(QWindow *w)
d->m_keyMapper.setKeyGrabber(w);
}
+QString QWindowsContext::classNamePrefix()
+{
+ static QString result;
+ if (result.isEmpty()) {
+ QTextStream str(&result);
+ str << "Qt" << QT_VERSION_MAJOR << QT_VERSION_MINOR << QT_VERSION_PATCH;
+ if (QLibraryInfo::isDebugBuild())
+ str << 'd';
+#ifdef QT_NAMESPACE
+# define xstr(s) str(s)
+# define str(s) #s
+ str << xstr(QT_NAMESPACE);
+#endif
+ }
+ return result;
+}
+
// Window class registering code (from qapplication_win.cpp)
QString QWindowsContext::registerWindowClass(const QWindow *w)
@@ -567,8 +595,8 @@ QString QWindowsContext::registerWindowClass(const QWindow *w)
break;
}
// Create a unique name for the flag combination
- QString cname;
- cname += QLatin1String("Qt5QWindow");
+ QString cname = classNamePrefix();
+ cname += QLatin1String("QWindow");
switch (type) {
case Qt::Tool:
cname += QLatin1String("Tool");
@@ -878,7 +906,7 @@ HWND QWindowsContext::createDummyWindow(const QString &classNameIn,
{
if (!wndProc)
wndProc = DefWindowProc;
- QString className = registerWindowClass(classNameIn, wndProc);
+ QString className = registerWindowClass(classNamePrefix() + classNameIn, wndProc);
return CreateWindowEx(0, reinterpret_cast<LPCWSTR>(className.utf16()),
windowName, style,
CW_USEDEFAULT, CW_USEDEFAULT,
@@ -1192,9 +1220,27 @@ bool QWindowsContext::windowsProc(HWND hwnd, UINT message,
t->displayChanged();
QWindowsWindow::displayChanged();
return d->m_screenManager.handleDisplayChange(wParam, lParam);
- case QtWindows::SettingChangedEvent:
+ case QtWindows::SettingChangedEvent: {
QWindowsWindow::settingsChanged();
+ const bool darkMode = QWindowsTheme::queryDarkMode();
+ if (darkMode != QWindowsContextPrivate::m_darkMode) {
+ QWindowsContextPrivate::m_darkMode = darkMode;
+ auto nativeInterface =
+ static_cast<QWindowsNativeInterface *>(QWindowsIntegration::instance()->nativeInterface());
+ emit nativeInterface->darkModeChanged(darkMode);
+ const auto options = QWindowsIntegration::instance()->options();
+ if ((options & QWindowsIntegration::DarkModeWindowFrames) != 0) {
+ for (QWindowsWindow *w : d->m_windows)
+ w->setDarkBorder(QWindowsContextPrivate::m_darkMode);
+ }
+ if ((options & QWindowsIntegration::DarkModeStyle) != 0) {
+ QWindowsTheme::instance()->refresh();
+ for (QWindowsWindow *w : d->m_windows)
+ QWindowSystemInterface::handleThemeChange(w->window());
+ }
+ }
return d->m_screenManager.handleScreenChanges();
+ }
default:
break;
}
diff --git a/src/plugins/platforms/windows/qwindowscontext.h b/src/plugins/platforms/windows/qwindowscontext.h
index 07398bd61c..c89b8b91f4 100644
--- a/src/plugins/platforms/windows/qwindowscontext.h
+++ b/src/plugins/platforms/windows/qwindowscontext.h
@@ -180,6 +180,7 @@ public:
int defaultDPI() const;
+ static QString classNamePrefix();
QString registerWindowClass(const QWindow *w);
QString registerWindowClass(QString cname, WNDPROC proc,
unsigned style = 0, HBRUSH brush = nullptr,
@@ -225,6 +226,8 @@ public:
void setProcessDpiAwareness(QtWindows::ProcessDpiAwareness dpiAwareness);
static int processDpiAwareness();
+ static bool isDarkMode();
+
void setDetectAltGrModifier(bool a);
// Returns a combination of SystemInfoFlags
diff --git a/src/plugins/platforms/windows/qwindowscursor.cpp b/src/plugins/platforms/windows/qwindowscursor.cpp
index 59457f1720..19de3d5939 100644
--- a/src/plugins/platforms/windows/qwindowscursor.cpp
+++ b/src/plugins/platforms/windows/qwindowscursor.cpp
@@ -80,10 +80,10 @@ QWindowsPixmapCursorCacheKey::QWindowsPixmapCursorCacheKey(const QCursor &c)
: bitmapCacheKey(c.pixmap().cacheKey()), maskCacheKey(0)
{
if (!bitmapCacheKey) {
- Q_ASSERT(c.bitmap());
- Q_ASSERT(c.mask());
- bitmapCacheKey = c.bitmap()->cacheKey();
- maskCacheKey = c.mask()->cacheKey();
+ Q_ASSERT(!c.bitmap(Qt::ReturnByValue).isNull());
+ Q_ASSERT(!c.mask(Qt::ReturnByValue).isNull());
+ bitmapCacheKey = c.bitmap(Qt::ReturnByValue).cacheKey();
+ maskCacheKey = c.mask(Qt::ReturnByValue).cacheKey();
}
}
@@ -169,9 +169,9 @@ static HCURSOR createBitmapCursor(const QImage &bbits, const QImage &mbits,
// Create a cursor from image and mask of the format QImage::Format_Mono.
static HCURSOR createBitmapCursor(const QCursor &cursor, qreal scaleFactor = 1)
{
- Q_ASSERT(cursor.shape() == Qt::BitmapCursor && cursor.bitmap());
- QImage bbits = cursor.bitmap()->toImage();
- QImage mbits = cursor.mask()->toImage();
+ Q_ASSERT(cursor.shape() == Qt::BitmapCursor && !cursor.bitmap(Qt::ReturnByValue).isNull());
+ QImage bbits = cursor.bitmap(Qt::ReturnByValue).toImage();
+ QImage mbits = cursor.mask(Qt::ReturnByValue).toImage();
scaleFactor /= bbits.devicePixelRatioF();
if (!qFuzzyCompare(scaleFactor, 1)) {
const QSize scaledSize = (QSizeF(bbits.size()) * scaleFactor).toSize();
diff --git a/src/plugins/platforms/windows/qwindowsdialoghelpers.cpp b/src/plugins/platforms/windows/qwindowsdialoghelpers.cpp
index b7ab952a1d..b038e19689 100644
--- a/src/plugins/platforms/windows/qwindowsdialoghelpers.cpp
+++ b/src/plugins/platforms/windows/qwindowsdialoghelpers.cpp
@@ -91,7 +91,7 @@ static inline QString guidToString(const GUID &g)
str << '{' << g.Data1 << ", " << g.Data2 << ", " << g.Data3;
str.setFieldWidth(2);
str.setFieldAlignment(QTextStream::AlignRight);
- str.setPadChar(QLatin1Char('0'));
+ str.setPadChar(u'0');
str << ",{" << g.Data4[0] << ", " << g.Data4[1] << ", " << g.Data4[2] << ", " << g.Data4[3]
<< ", " << g.Data4[4] << ", " << g.Data4[5] << ", " << g.Data4[6] << ", " << g.Data4[7]
<< "}};";
@@ -466,14 +466,14 @@ inline void QWindowsFileDialogSharedData::setSelectedNameFilter(const QString &f
inline QList<QUrl> QWindowsFileDialogSharedData::selectedFiles() const
{
m_data->mutex.lock();
- const QList<QUrl> result = m_data->selectedFiles;
+ const auto result = m_data->selectedFiles;
m_data->mutex.unlock();
return result;
}
inline QString QWindowsFileDialogSharedData::selectedFile() const
{
- const QList<QUrl> files = selectedFiles();
+ const auto files = selectedFiles();
return files.isEmpty() ? QString() : files.front().toLocalFile();
}
@@ -915,7 +915,7 @@ IShellItem *QWindowsNativeFileDialogBase::shellItem(const QUrl &url)
return nullptr;
}
return result;
- } else if (url.scheme() == QLatin1String("clsid")) {
+ } else if (url.scheme() == u"clsid") {
// Support for virtual folders via GUID
// (see https://msdn.microsoft.com/en-us/library/windows/desktop/dd378457(v=vs.85).aspx)
// specified as "clsid:<GUID>" (without '{', '}').
@@ -1040,20 +1040,20 @@ static QList<FilterSpec> filterSpecs(const QStringList &filters,
// Split filter specification as 'Texts (*.txt[;] *.doc)', '*.txt[;] *.doc'
// into description and filters specification as '*.txt;*.doc'
for (const QString &filterString : filters) {
- const int openingParenPos = filterString.lastIndexOf(QLatin1Char('('));
+ const int openingParenPos = filterString.lastIndexOf(u'(');
const int closingParenPos = openingParenPos != -1 ?
- filterString.indexOf(QLatin1Char(')'), openingParenPos + 1) : -1;
+ filterString.indexOf(u')', openingParenPos + 1) : -1;
FilterSpec filterSpec;
filterSpec.filter = closingParenPos == -1 ?
filterString :
filterString.mid(openingParenPos + 1, closingParenPos - openingParenPos - 1).trimmed();
if (filterSpec.filter.isEmpty())
- filterSpec.filter += QLatin1Char('*');
+ filterSpec.filter += u'*';
filterSpec.filter.replace(filterSeparatorRE, separator);
filterSpec.description = filterString;
if (hideFilterDetails && openingParenPos != -1) { // Do not show pattern in description
filterSpec.description.truncate(openingParenPos);
- while (filterSpec.description.endsWith(QLatin1Char(' ')))
+ while (filterSpec.description.endsWith(u' '))
filterSpec.description.truncate(filterSpec.description.size() - 1);
}
*totalStringLength += filterSpec.filter.size() + filterSpec.description.size();
@@ -1084,8 +1084,8 @@ void QWindowsNativeFileDialogBase::setNameFilters(const QStringList &filters)
// 'AAA files (a.*) (a.*)'
QString description = specs[i].description;
const QString &filter = specs[i].filter;
- if (!m_hideFiltersDetails && !filter.startsWith(QLatin1String("*."))) {
- const int pos = description.lastIndexOf(QLatin1Char('('));
+ if (!m_hideFiltersDetails && !filter.startsWith(u"*.")) {
+ const int pos = description.lastIndexOf(u'(');
if (pos > 0)
description.truncate(pos);
}
@@ -1151,8 +1151,8 @@ static bool isHexRange(const QString& s, int start, int end)
for (;start < end; ++start) {
QChar ch = s.at(start);
if (!(ch.isDigit()
- || (ch >= QLatin1Char('a') && ch <= QLatin1Char('f'))
- || (ch >= QLatin1Char('A') && ch <= QLatin1Char('F'))))
+ || (ch >= u'a' && ch <= u'f')
+ || (ch >= u'A' && ch <= u'F')))
return false;
}
return true;
@@ -1161,7 +1161,7 @@ static bool isHexRange(const QString& s, int start, int end)
static inline bool isClsid(const QString &s)
{
// detect "374DE290-123F-4565-9164-39C4925E467B".
- const QChar dash(QLatin1Char('-'));
+ const QChar dash(u'-');
return s.size() == 36
&& isHexRange(s, 0, 8)
&& s.at(8) == dash
@@ -1204,7 +1204,7 @@ void QWindowsNativeFileDialogBase::selectNameFilter(const QString &filter)
if (index < 0) {
qWarning("%s: Invalid parameter '%s' not found in '%s'.",
__FUNCTION__, qPrintable(filter),
- qPrintable(m_nameFilters.join(QLatin1String(", "))));
+ qPrintable(m_nameFilters.join(u", ")));
return;
}
m_fileDialog->SetFileTypeIndex(index + 1); // one-based.
@@ -1313,15 +1313,15 @@ public:
// Also handles the simple name filter case "*.txt" -> "txt"
static inline QString suffixFromFilter(const QString &filter)
{
- int suffixPos = filter.indexOf(QLatin1String("*."));
+ int suffixPos = filter.indexOf(u"*.");
if (suffixPos < 0)
return QString();
suffixPos += 2;
- int endPos = filter.indexOf(QLatin1Char(' '), suffixPos + 1);
+ int endPos = filter.indexOf(u' ', suffixPos + 1);
if (endPos < 0)
- endPos = filter.indexOf(QLatin1Char(';'), suffixPos + 1);
+ endPos = filter.indexOf(u';', suffixPos + 1);
if (endPos < 0)
- endPos = filter.indexOf(QLatin1Char(')'), suffixPos + 1);
+ endPos = filter.indexOf(u')', suffixPos + 1);
if (endPos < 0)
endPos = filter.size();
return filter.mid(suffixPos, endPos - suffixPos);
@@ -1406,27 +1406,27 @@ static void cleanupTemporaryItemCopies()
static bool validFileNameCharacter(QChar c)
{
- return c.isLetterOrNumber() || c == QLatin1Char('_') || c == QLatin1Char('-');
+ return c.isLetterOrNumber() || c == u'_' || c == u'-';
}
QString tempFilePattern(QString name)
{
- const int lastSlash = qMax(name.lastIndexOf(QLatin1Char('/')),
- name.lastIndexOf(QLatin1Char('\\')));
+ const int lastSlash = qMax(name.lastIndexOf(u'/'),
+ name.lastIndexOf(u'\\'));
if (lastSlash != -1)
name.remove(0, lastSlash + 1);
- int lastDot = name.lastIndexOf(QLatin1Char('.'));
+ int lastDot = name.lastIndexOf(u'.');
if (lastDot < 0)
lastDot = name.size();
name.insert(lastDot, QStringLiteral("_XXXXXX"));
for (int i = lastDot - 1; i >= 0; --i) {
if (!validFileNameCharacter(name.at(i)))
- name[i] = QLatin1Char('_');
+ name[i] = u'_';
}
- name.prepend(QDir::tempPath() + QLatin1Char('/'));
+ name.prepend(QDir::tempPath() + u'/');
return name;
}
@@ -1456,7 +1456,7 @@ static QString createTemporaryItemCopy(QWindowsShellItem &qItem, QString *errorM
static QUrl itemToDialogUrl(QWindowsShellItem &qItem, QString *errorMessage)
{
QUrl url = qItem.url();
- if (url.isLocalFile() || url.scheme().startsWith(QLatin1String("http")))
+ if (url.isLocalFile() || url.scheme().startsWith(u"http"))
return url;
const QString path = qItem.path();
if (path.isEmpty() && !qItem.isDir() && qItem.canStream()) {
@@ -1859,10 +1859,12 @@ void QWindowsXpNativeFileDialog::populateOpenFileName(OPENFILENAME *ofn, HWND ow
// for the target. If it contains any invalid character, the dialog
// will not show.
ofn->nMaxFile = 65535;
- const QString initiallySelectedFile =
- QDir::toNativeSeparators(m_data.selectedFile()).remove(QLatin1Char('<')).
- remove(QLatin1Char('>')).remove(QLatin1Char('"')).remove(QLatin1Char('|'));
- ofn->lpstrFile = qStringToWCharArray(initiallySelectedFile, ofn->nMaxFile);
+ QString initiallySelectedFile = m_data.selectedFile();
+ initiallySelectedFile.remove(u'<');
+ initiallySelectedFile.remove(u'>');
+ initiallySelectedFile.remove(u'"');
+ initiallySelectedFile.remove(u'|');
+ ofn->lpstrFile = qStringToWCharArray(QDir::toNativeSeparators(initiallySelectedFile), ofn->nMaxFile);
ofn->lpstrInitialDir = qStringToWCharArray(QDir::toNativeSeparators(m_data.directory().toLocalFile()));
ofn->lpstrTitle = (wchar_t*)m_title.utf16();
// Determine lpstrDefExt. Note that the current MSDN docs document this
@@ -1872,7 +1874,7 @@ void QWindowsXpNativeFileDialog::populateOpenFileName(OPENFILENAME *ofn, HWND ow
// the extension of the current filter".
if (m_options->acceptMode() == QFileDialogOptions::AcceptSave) {
QString defaultSuffix = m_options->defaultSuffix();
- if (defaultSuffix.startsWith(QLatin1Char('.')))
+ if (defaultSuffix.startsWith(u'.'))
defaultSuffix.remove(0, 1);
// QTBUG-33156, also create empty strings to trigger the appending mechanism.
ofn->lpstrDefExt = qStringToWCharArray(defaultSuffix);
@@ -1905,7 +1907,7 @@ QList<QUrl> QWindowsXpNativeFileDialog::execFileNames(HWND owner, int *selectedF
wchar_t *ptr = ofn.lpstrFile + dir.size() + 1;
if (*ptr) {
result.pop_front();
- const QString path = dir + QLatin1Char('/');
+ const QString path = dir + u'/';
while (*ptr) {
const QString fileName = QString::fromWCharArray(ptr);
result.push_back(QUrl::fromLocalFile(path + fileName));
diff --git a/src/plugins/platforms/windows/qwindowsdropdataobject.cpp b/src/plugins/platforms/windows/qwindowsdropdataobject.cpp
index e1a41c0ede..c9dd1c7c17 100644
--- a/src/plugins/platforms/windows/qwindowsdropdataobject.cpp
+++ b/src/plugins/platforms/windows/qwindowsdropdataobject.cpp
@@ -95,7 +95,7 @@ bool QWindowsDropDataObject::shouldIgnore(LPFORMATETC pformatetc) const
|| pformatetc->cfFormat == CF_TEXT
|| formatName == QStringLiteral("UniformResourceLocator")
|| formatName == QStringLiteral("UniformResourceLocatorW")) {
- QList<QUrl> urls = dropData->urls();
+ const auto urls = dropData->urls();
return std::all_of(urls.cbegin(), urls.cend(), [] (const QUrl &u) { return u.isLocalFile(); });
}
}
diff --git a/src/plugins/platforms/windows/qwindowseglcontext.cpp b/src/plugins/platforms/windows/qwindowseglcontext.cpp
index e9f3dc5189..76baa93d98 100644
--- a/src/plugins/platforms/windows/qwindowseglcontext.cpp
+++ b/src/plugins/platforms/windows/qwindowseglcontext.cpp
@@ -88,7 +88,7 @@ static void *resolveFunc(HMODULE lib, const char *name)
while (!proc && argSize <= 64) {
nameStr = baseNameStr;
if (argSize >= 0)
- nameStr += QLatin1Char('@') + QString::number(argSize);
+ nameStr += u'@' + QString::number(argSize);
argSize = argSize < 0 ? 0 : argSize + 4;
proc = (void *) ::GetProcAddress(lib, nameStr.toLatin1().constData());
}
diff --git a/src/plugins/platforms/windows/qwindowsglcontext.cpp b/src/plugins/platforms/windows/qwindowsglcontext.cpp
index 8bf88300e9..f5d0a8780a 100644
--- a/src/plugins/platforms/windows/qwindowsglcontext.cpp
+++ b/src/plugins/platforms/windows/qwindowsglcontext.cpp
@@ -196,6 +196,7 @@ bool QWindowsOpengl32DLL::init(bool softwareRendering)
wglShareLists = reinterpret_cast<BOOL (WINAPI *)(HGLRC, HGLRC)>(resolve("wglShareLists"));
wglSwapBuffers = reinterpret_cast<BOOL (WINAPI *)(HDC)>(resolve("wglSwapBuffers"));
wglSetPixelFormat = reinterpret_cast<BOOL (WINAPI *)(HDC, int, const PIXELFORMATDESCRIPTOR *)>(resolve("wglSetPixelFormat"));
+ wglDescribePixelFormat = reinterpret_cast<int (WINAPI *)(HDC, int, UINT, PIXELFORMATDESCRIPTOR *)>(resolve("wglDescribePixelFormat"));
glGetError = reinterpret_cast<GLenum (APIENTRY *)()>(resolve("glGetError"));
glGetIntegerv = reinterpret_cast<void (APIENTRY *)(GLenum , GLint *)>(resolve("glGetIntegerv"));
@@ -214,6 +215,11 @@ BOOL QWindowsOpengl32DLL::setPixelFormat(HDC dc, int pf, const PIXELFORMATDESCRI
return moduleIsNotOpengl32() ? wglSetPixelFormat(dc, pf, pfd) : SetPixelFormat(dc, pf, pfd);
}
+int QWindowsOpengl32DLL::describePixelFormat(HDC dc, int pf, UINT size, PIXELFORMATDESCRIPTOR *pfd)
+{
+ return moduleIsNotOpengl32() ? wglDescribePixelFormat(dc, pf, size, pfd) : DescribePixelFormat(dc, pf, size, pfd);
+}
+
QWindowsOpenGLContext *QOpenGLStaticContext::createContext(QOpenGLContext *context)
{
return new QWindowsGLContext(this, context);
@@ -322,11 +328,11 @@ static inline bool
static void describeFormats(HDC hdc)
{
- const int pfiMax = DescribePixelFormat(hdc, 0, 0, nullptr);
+ const int pfiMax = QOpenGLStaticContext::opengl32.describePixelFormat(hdc, 0, 0, nullptr);
for (int i = 0; i < pfiMax; i++) {
PIXELFORMATDESCRIPTOR pfd;
initPixelFormatDescriptor(&pfd);
- DescribePixelFormat(hdc, i, sizeof(PIXELFORMATDESCRIPTOR), &pfd);
+ QOpenGLStaticContext::opengl32.describePixelFormat(hdc, i, sizeof(PIXELFORMATDESCRIPTOR), &pfd);
qCDebug(lcQpaGl) << '#' << i << '/' << pfiMax << ':' << pfd;
}
}
@@ -617,7 +623,7 @@ static int choosePixelFormat(HDC hdc,
// Verify if format is acceptable. Note that the returned
// formats have been observed to not contain PFD_SUPPORT_OPENGL, ignore.
initPixelFormatDescriptor(obtainedPfd);
- DescribePixelFormat(hdc, pixelFormat, sizeof(PIXELFORMATDESCRIPTOR), obtainedPfd);
+ QOpenGLStaticContext::opengl32.describePixelFormat(hdc, pixelFormat, sizeof(PIXELFORMATDESCRIPTOR), obtainedPfd);
if (!isAcceptableFormat(additional, *obtainedPfd, true)) {
qCDebug(lcQpaGl) << __FUNCTION__ << " obtained px #" << pixelFormat
<< " not acceptable=" << *obtainedPfd;
@@ -796,7 +802,7 @@ static HGLRC createContext(const QOpenGLStaticContext &staticContext,
static inline HWND createDummyGLWindow()
{
return QWindowsContext::instance()->
- createDummyWindow(QStringLiteral("QtOpenGLDummyWindow"),
+ createDummyWindow(QStringLiteral("OpenGLDummyWindow"),
L"OpenGLDummyWindow", nullptr, WS_OVERLAPPED | WS_CLIPCHILDREN | WS_CLIPSIBLINGS);
}
diff --git a/src/plugins/platforms/windows/qwindowsglcontext.h b/src/plugins/platforms/windows/qwindowsglcontext.h
index 8b0c33f7d5..8794368fe4 100644
--- a/src/plugins/platforms/windows/qwindowsglcontext.h
+++ b/src/plugins/platforms/windows/qwindowsglcontext.h
@@ -89,7 +89,7 @@ struct QWindowsOpenGLContextFormat
QSurfaceFormat::OpenGLContextProfile profile = QSurfaceFormat::NoProfile;
int version = 0; //! majorVersion<<8 + minorVersion
- QSurfaceFormat::FormatOptions options = nullptr;
+ QSurfaceFormat::FormatOptions options;
};
#ifndef QT_NO_DEBUG_STREAM
@@ -107,6 +107,7 @@ struct QWindowsOpengl32DLL
// Wrappers. Always use these instead of SwapBuffers/wglSwapBuffers/etc.
BOOL swapBuffers(HDC dc);
BOOL setPixelFormat(HDC dc, int pf, const PIXELFORMATDESCRIPTOR *pfd);
+ int describePixelFormat(HDC dc, int pf, UINT size, PIXELFORMATDESCRIPTOR *pfd);
// WGL
HGLRC (WINAPI * wglCreateContext)(HDC dc);
@@ -130,6 +131,7 @@ private:
// For Mesa llvmpipe shipped with a name other than opengl32.dll
BOOL (WINAPI * wglSwapBuffers)(HDC dc);
BOOL (WINAPI * wglSetPixelFormat)(HDC dc, int pf, const PIXELFORMATDESCRIPTOR *pfd);
+ int (WINAPI * wglDescribePixelFormat)(HDC dc, int pf, UINT size, PIXELFORMATDESCRIPTOR *pfd);
};
class QOpenGLStaticContext : public QWindowsStaticOpenGLContext
diff --git a/src/plugins/platforms/windows/qwindowsinputcontext.cpp b/src/plugins/platforms/windows/qwindowsinputcontext.cpp
index 19d632dc10..7c4ddbd2a1 100644
--- a/src/plugins/platforms/windows/qwindowsinputcontext.cpp
+++ b/src/plugins/platforms/windows/qwindowsinputcontext.cpp
@@ -285,7 +285,8 @@ void QWindowsInputContext::showInputPanel()
// the Surface seems unnecessary there anyway. But leave it hidden for IME.
// Only trigger the native OSK if the Qt OSK is not in use.
static bool imModuleEmpty = qEnvironmentVariableIsEmpty("QT_IM_MODULE");
- if (imModuleEmpty
+ bool nativeVKDisabled = QCoreApplication::testAttribute(Qt::AA_DisableNativeVirtualKeyboard);
+ if ((imModuleEmpty && !nativeVKDisabled)
&& QOperatingSystemVersion::current()
>= QOperatingSystemVersion(QOperatingSystemVersion::Windows, 10, 0, 16299)) {
ShowCaret(platformWindow->handle());
diff --git a/src/plugins/platforms/windows/qwindowsintegration.cpp b/src/plugins/platforms/windows/qwindowsintegration.cpp
index d37b405db8..94274ffcd7 100644
--- a/src/plugins/platforms/windows/qwindowsintegration.cpp
+++ b/src/plugins/platforms/windows/qwindowsintegration.cpp
@@ -162,7 +162,7 @@ bool parseIntOption(const QString &parameter,const QLatin1String &option,
IntType minimumValue, IntType maximumValue, IntType *target)
{
const int valueLength = parameter.size() - option.size() - 1;
- if (valueLength < 1 || !parameter.startsWith(option) || parameter.at(option.size()) != QLatin1Char('='))
+ if (valueLength < 1 || !parameter.startsWith(option) || parameter.at(option.size()) != u'=')
return false;
bool ok;
const QStringRef valueRef = parameter.rightRef(valueLength);
@@ -186,39 +186,43 @@ static inline unsigned parseOptions(const QStringList &paramList,
{
unsigned options = 0;
for (const QString &param : paramList) {
- if (param.startsWith(QLatin1String("fontengine="))) {
- if (param.endsWith(QLatin1String("freetype"))) {
+ if (param.startsWith(u"fontengine=")) {
+ if (param.endsWith(u"freetype")) {
options |= QWindowsIntegration::FontDatabaseFreeType;
- } else if (param.endsWith(QLatin1String("native"))) {
+ } else if (param.endsWith(u"native")) {
options |= QWindowsIntegration::FontDatabaseNative;
}
- } else if (param.startsWith(QLatin1String("dialogs="))) {
- if (param.endsWith(QLatin1String("xp"))) {
+ } else if (param.startsWith(u"dialogs=")) {
+ if (param.endsWith(u"xp")) {
options |= QWindowsIntegration::XpNativeDialogs;
- } else if (param.endsWith(QLatin1String("none"))) {
+ } else if (param.endsWith(u"none")) {
options |= QWindowsIntegration::NoNativeDialogs;
}
- } else if (param == QLatin1String("altgr")) {
+ } else if (param == u"altgr") {
options |= QWindowsIntegration::DetectAltGrModifier;
- } else if (param == QLatin1String("gl=gdi")) {
+ } else if (param == u"gl=gdi") {
options |= QWindowsIntegration::DisableArb;
- } else if (param == QLatin1String("nodirectwrite")) {
+ } else if (param == u"nodirectwrite") {
options |= QWindowsIntegration::DontUseDirectWriteFonts;
- } else if (param == QLatin1String("nocolorfonts")) {
+ } else if (param == u"nocolorfonts") {
options |= QWindowsIntegration::DontUseColorFonts;
- } else if (param == QLatin1String("nomousefromtouch")) {
+ } else if (param == u"nomousefromtouch") {
options |= QWindowsIntegration::DontPassOsMouseEventsSynthesizedFromTouch;
} else if (parseIntOption(param, QLatin1String("verbose"), 0, INT_MAX, &QWindowsContext::verbose)
|| parseIntOption(param, QLatin1String("tabletabsoluterange"), 0, INT_MAX, tabletAbsoluteRange)
|| parseIntOption(param, QLatin1String("dpiawareness"), QtWindows::ProcessDpiUnaware, QtWindows::ProcessPerMonitorDpiAware, dpiAwareness)) {
- } else if (param == QLatin1String("menus=native")) {
+ } else if (param == u"menus=native") {
options |= QWindowsIntegration::AlwaysUseNativeMenus;
- } else if (param == QLatin1String("menus=none")) {
+ } else if (param == u"menus=none") {
options |= QWindowsIntegration::NoNativeMenus;
- } else if (param == QLatin1String("nowmpointer")) {
+ } else if (param == u"nowmpointer") {
options |= QWindowsIntegration::DontUseWMPointer;
- } else if (param == QLatin1String("reverse")) {
+ } else if (param == u"reverse") {
options |= QWindowsIntegration::RtlEnabled;
+ } else if (param == u"darkmode=1") {
+ options |= QWindowsIntegration::DarkModeWindowFrames;
+ } else if (param == u"darkmode=2") {
+ options |= QWindowsIntegration::DarkModeWindowFrames | QWindowsIntegration::DarkModeStyle;
} else {
qWarning() << "Unknown option" << param;
}
diff --git a/src/plugins/platforms/windows/qwindowsintegration.h b/src/plugins/platforms/windows/qwindowsintegration.h
index b49d21022b..1f16d13769 100644
--- a/src/plugins/platforms/windows/qwindowsintegration.h
+++ b/src/plugins/platforms/windows/qwindowsintegration.h
@@ -70,7 +70,9 @@ public:
NoNativeMenus = 0x200,
DontUseWMPointer = 0x400,
DetectAltGrModifier = 0x800,
- RtlEnabled = 0x1000
+ RtlEnabled = 0x1000,
+ DarkModeWindowFrames = 0x2000,
+ DarkModeStyle = 0x4000
};
explicit QWindowsIntegration(const QStringList &paramList);
diff --git a/src/plugins/platforms/windows/qwindowskeymapper.cpp b/src/plugins/platforms/windows/qwindowskeymapper.cpp
index 4f0f846749..e3edf7e81e 100644
--- a/src/plugins/platforms/windows/qwindowskeymapper.cpp
+++ b/src/plugins/platforms/windows/qwindowskeymapper.cpp
@@ -1019,14 +1019,14 @@ bool QWindowsKeyMapper::translateKeyEventInternal(QWindow *window, MSG msg,
if (dirStatus == VK_LSHIFT
&& ((msg.wParam == VK_SHIFT && GetKeyState(VK_LCONTROL))
|| (msg.wParam == VK_CONTROL && GetKeyState(VK_LSHIFT)))) {
- sendExtendedPressRelease(receiver, Qt::Key_Direction_L, nullptr,
+ sendExtendedPressRelease(receiver, Qt::Key_Direction_L, {},
scancode, vk_key, nModifiers, QString(), false);
result = true;
dirStatus = 0;
} else if (dirStatus == VK_RSHIFT
&& ( (msg.wParam == VK_SHIFT && GetKeyState(VK_RCONTROL))
|| (msg.wParam == VK_CONTROL && GetKeyState(VK_RSHIFT)))) {
- sendExtendedPressRelease(receiver, Qt::Key_Direction_R, nullptr,
+ sendExtendedPressRelease(receiver, Qt::Key_Direction_R, {},
scancode, vk_key, nModifiers, QString(), false);
result = true;
dirStatus = 0;
@@ -1388,7 +1388,7 @@ QList<int> QWindowsKeyMapper::possibleKeys(const QKeyEvent *e) const
if (key && key != baseKey && ((keyMods & neededMods) == neededMods)) {
const Qt::KeyboardModifiers missingMods = keyMods & ~neededMods;
const int matchedKey = int(key) + missingMods;
- const QList<int>::iterator it =
+ const auto it =
std::find_if(result.begin(), result.end(),
[key] (int k) { return (k & ~Qt::KeyboardModifierMask) == key; });
// QTBUG-67200: Use the match with the least modifiers (prefer
diff --git a/src/plugins/platforms/windows/qwindowsmenu.cpp b/src/plugins/platforms/windows/qwindowsmenu.cpp
index 221e4ff6ec..d29830b394 100644
--- a/src/plugins/platforms/windows/qwindowsmenu.cpp
+++ b/src/plugins/platforms/windows/qwindowsmenu.cpp
@@ -445,7 +445,7 @@ QString QWindowsMenuItem::nativeText() const
QString result = m_text;
#if QT_CONFIG(shortcut)
if (!m_shortcut.isEmpty()) {
- result += QLatin1Char('\t');
+ result += u'\t';
result += m_shortcut.toString(QKeySequence::NativeText);
}
#endif
diff --git a/src/plugins/platforms/windows/qwindowsmime.cpp b/src/plugins/platforms/windows/qwindowsmime.cpp
index b9d8b191f5..fe9e1fe31f 100644
--- a/src/plugins/platforms/windows/qwindowsmime.cpp
+++ b/src/plugins/platforms/windows/qwindowsmime.cpp
@@ -107,7 +107,7 @@ static inline QByteArray msgConversionError(const char *func, const char *format
msg += ": Unable to convert DIB image. The image converter plugin for '";
msg += format;
msg += "' is not available. Available formats: ";
- const QList<QByteArray> &formats = QImageReader::supportedImageFormats();
+ const auto &formats = QImageReader::supportedImageFormats();
for (const QByteArray &af : formats) {
msg += af;
msg += ' ';
@@ -635,11 +635,11 @@ bool QWindowsMimeText::convertFromMime(const FORMATETC &formatetc, const QMimeDa
int ri = 0;
bool cr = false;
for (int i=0; i < s; ++i) {
- if (*u == QLatin1Char('\r'))
+ if (*u == u'\r')
cr = true;
else {
- if (*u == QLatin1Char('\n') && !cr)
- res[ri++] = QLatin1Char('\r');
+ if (*u == u'\n' && !cr)
+ res[ri++] = u'\r';
cr = false;
}
res[ri++] = *u;
@@ -663,7 +663,7 @@ bool QWindowsMimeText::convertFromMime(const FORMATETC &formatetc, const QMimeDa
bool QWindowsMimeText::canConvertToMime(const QString &mimeType, IDataObject *pDataObj) const
{
- return mimeType.startsWith(QLatin1String("text/plain"))
+ return mimeType.startsWith(u"text/plain")
&& (canGetData(CF_UNICODETEXT, pDataObj)
|| canGetData(CF_TEXT, pDataObj));
}
@@ -680,7 +680,7 @@ QString QWindowsMimeText::mimeForFormat(const FORMATETC &formatetc) const
QVector<FORMATETC> QWindowsMimeText::formatsForMime(const QString &mimeType, const QMimeData *mimeData) const
{
QVector<FORMATETC> formatics;
- if (mimeType.startsWith(QLatin1String("text/plain")) && mimeData->hasText()) {
+ if (mimeType.startsWith(u"text/plain") && mimeData->hasText()) {
formatics += setCf(CF_UNICODETEXT);
formatics += setCf(CF_TEXT);
}
@@ -747,7 +747,7 @@ QWindowsMimeURI::QWindowsMimeURI()
bool QWindowsMimeURI::canConvertFromMime(const FORMATETC &formatetc, const QMimeData *mimeData) const
{
if (mimeData->hasUrls() && getCf(formatetc) == CF_HDROP) {
- const QList<QUrl> urls = mimeData->urls();
+ const auto urls = mimeData->urls();
for (const QUrl &url : urls) {
if (url.isLocalFile())
return true;
@@ -760,7 +760,7 @@ bool QWindowsMimeURI::convertFromMime(const FORMATETC &formatetc, const QMimeDat
{
if (canConvertFromMime(formatetc, mimeData)) {
if (getCf(formatetc) == CF_HDROP) {
- const QList<QUrl> &urls = mimeData->urls();
+ const auto &urls = mimeData->urls();
QStringList fileNames;
int size = sizeof(DROPFILES)+2;
for (const QUrl &url : urls) {
@@ -791,7 +791,7 @@ bool QWindowsMimeURI::convertFromMime(const FORMATETC &formatetc, const QMimeDat
return setData(result, pmedium);
}
if (getCf(formatetc) == CF_INETURL_W) {
- QList<QUrl> urls = mimeData->urls();
+ const auto urls = mimeData->urls();
QByteArray result;
if (!urls.isEmpty()) {
QString url = urls.at(0).toString();
@@ -803,7 +803,7 @@ bool QWindowsMimeURI::convertFromMime(const FORMATETC &formatetc, const QMimeDat
return setData(result, pmedium);
}
if (getCf(formatetc) == CF_INETURL) {
- QList<QUrl> urls = mimeData->urls();
+ const auto urls = mimeData->urls();
QByteArray result;
if (!urls.isEmpty())
result = urls.at(0).toString().toLocal8Bit();
@@ -816,7 +816,7 @@ bool QWindowsMimeURI::convertFromMime(const FORMATETC &formatetc, const QMimeDat
bool QWindowsMimeURI::canConvertToMime(const QString &mimeType, IDataObject *pDataObj) const
{
- return mimeType == QLatin1String("text/uri-list")
+ return mimeType == u"text/uri-list"
&& (canGetData(CF_HDROP, pDataObj) || canGetData(CF_INETURL_W, pDataObj) || canGetData(CF_INETURL, pDataObj));
}
@@ -831,7 +831,7 @@ QString QWindowsMimeURI::mimeForFormat(const FORMATETC &formatetc) const
QVector<FORMATETC> QWindowsMimeURI::formatsForMime(const QString &mimeType, const QMimeData *mimeData) const
{
QVector<FORMATETC> formatics;
- if (mimeType == QLatin1String("text/uri-list")) {
+ if (mimeType == u"text/uri-list") {
if (canConvertFromMime(setCf(CF_HDROP), mimeData))
formatics += setCf(CF_HDROP);
if (canConvertFromMime(setCf(CF_INETURL_W), mimeData))
@@ -844,7 +844,7 @@ QVector<FORMATETC> QWindowsMimeURI::formatsForMime(const QString &mimeType, cons
QVariant QWindowsMimeURI::convertToMime(const QString &mimeType, LPDATAOBJECT pDataObj, QVariant::Type preferredType) const
{
- if (mimeType == QLatin1String("text/uri-list")) {
+ if (mimeType == u"text/uri-list") {
if (canGetData(CF_HDROP, pDataObj)) {
QList<QVariant> urls;
@@ -916,7 +916,7 @@ QWindowsMimeHtml::QWindowsMimeHtml()
QVector<FORMATETC> QWindowsMimeHtml::formatsForMime(const QString &mimeType, const QMimeData *mimeData) const
{
QVector<FORMATETC> formatetcs;
- if (mimeType == QLatin1String("text/html") && (!mimeData->html().isEmpty()))
+ if (mimeType == u"text/html" && (!mimeData->html().isEmpty()))
formatetcs += setCf(CF_HTML);
return formatetcs;
}
@@ -930,7 +930,7 @@ QString QWindowsMimeHtml::mimeForFormat(const FORMATETC &formatetc) const
bool QWindowsMimeHtml::canConvertToMime(const QString &mimeType, IDataObject *pDataObj) const
{
- return mimeType == QLatin1String("text/html") && canGetData(CF_HTML, pDataObj);
+ return mimeType == u"text/html" && canGetData(CF_HTML, pDataObj);
}
@@ -1053,7 +1053,7 @@ QWindowsMimeImage::QWindowsMimeImage()
QVector<FORMATETC> QWindowsMimeImage::formatsForMime(const QString &mimeType, const QMimeData *mimeData) const
{
QVector<FORMATETC> formatetcs;
- if (mimeData->hasImage() && mimeType == QLatin1String("application/x-qt-image")) {
+ if (mimeData->hasImage() && mimeType == u"application/x-qt-image") {
//add DIBV5 if image has alpha channel. Do not add CF_PNG here as it will confuse MS Office (QTBUG47656).
auto image = qvariant_cast<QImage>(mimeData->imageData());
if (!image.isNull() && image.hasAlphaChannel())
@@ -1075,7 +1075,7 @@ QString QWindowsMimeImage::mimeForFormat(const FORMATETC &formatetc) const
bool QWindowsMimeImage::canConvertToMime(const QString &mimeType, IDataObject *pDataObj) const
{
- return mimeType == QLatin1String("application/x-qt-image")
+ return mimeType == u"application/x-qt-image"
&& (canGetData(CF_DIB, pDataObj) || canGetData(CF_PNG, pDataObj));
}
@@ -1149,7 +1149,7 @@ QVariant QWindowsMimeImage::convertToMime(const QString &mimeType, IDataObject *
{
Q_UNUSED(preferredType);
QVariant result;
- if (mimeType != QLatin1String("application/x-qt-image"))
+ if (mimeType != u"application/x-qt-image")
return result;
//Try to convert from a format which has more data
//DIBV5, use only if its is not synthesized
@@ -1220,7 +1220,7 @@ bool QBuiltInMimes::convertFromMime(const FORMATETC &formatetc, const QMimeData
{
if (canConvertFromMime(formatetc, mimeData)) {
QByteArray data;
- if (outFormats.value(getCf(formatetc)) == QLatin1String("text/html")) {
+ if (outFormats.value(getCf(formatetc)) == u"text/html") {
// text/html is in wide chars on windows (compatible with mozillia)
QString html = mimeData->html();
// same code as in the text converter up above
@@ -1232,11 +1232,11 @@ bool QBuiltInMimes::convertFromMime(const FORMATETC &formatetc, const QMimeData
int ri = 0;
bool cr = false;
for (int i=0; i < s; ++i) {
- if (*u == QLatin1Char('\r'))
+ if (*u == u'\r')
cr = true;
else {
- if (*u == QLatin1Char('\n') && !cr)
- res[ri++] = QLatin1Char('\r');
+ if (*u == u'\n' && !cr)
+ res[ri++] = u'\r';
cr = false;
}
res[ri++] = *u;
@@ -1285,7 +1285,7 @@ QVariant QBuiltInMimes::convertToMime(const QString &mimeType, IDataObject *pDat
QByteArray data = getData(inFormats.key(mimeType), pDataObj);
if (!data.isEmpty()) {
qCDebug(lcQpaMime) << __FUNCTION__;
- if (mimeType == QLatin1String("text/html") && preferredType == QVariant::String) {
+ if (mimeType == u"text/html" && preferredType == QVariant::String) {
// text/html is in wide chars on windows (compatible with Mozilla)
val = QString::fromWCharArray(reinterpret_cast<const wchar_t *>(data.constData()));
} else {
@@ -1404,12 +1404,12 @@ static bool isCustomMimeType(const QString &mimeType)
static QString customMimeType(const QString &mimeType, int *lindex = nullptr)
{
int len = sizeof(x_qt_windows_mime) - 1;
- int n = mimeType.lastIndexOf(QLatin1Char('\"')) - len;
+ int n = mimeType.lastIndexOf(u'\"') - len;
QString ret = mimeType.mid(len, n);
- const int beginPos = mimeType.indexOf(QLatin1String(";index="));
+ const int beginPos = mimeType.indexOf(u";index=");
if (beginPos > -1) {
- const int endPos = mimeType.indexOf(QLatin1Char(';'), beginPos + 1);
+ const int endPos = mimeType.indexOf(u';', beginPos + 1);
const int indexStartPos = beginPos + 7;
if (lindex)
*lindex = mimeType.midRef(indexStartPos, endPos == -1 ? endPos : endPos - indexStartPos).toInt();
@@ -1480,7 +1480,7 @@ QString QLastResortMimes::mimeForFormat(const FORMATETC &formatetc) const
}
}
if (!ianaType)
- format = QLatin1String(x_qt_windows_mime) + clipFormat + QLatin1Char('\"');
+ format = QLatin1String(x_qt_windows_mime) + clipFormat + u'"';
else
format = clipFormat;
}
diff --git a/src/plugins/platforms/windows/qwindowsmime.h b/src/plugins/platforms/windows/qwindowsmime.h
index 1c389e8800..f8708f1259 100644
--- a/src/plugins/platforms/windows/qwindowsmime.h
+++ b/src/plugins/platforms/windows/qwindowsmime.h
@@ -43,7 +43,6 @@
#include <QtCore/qt_windows.h>
#include <QtCore/qvector.h>
-#include <QtCore/qlist.h>
#include <QtCore/qvariant.h>
QT_BEGIN_NAMESPACE
@@ -95,7 +94,7 @@ public:
private:
void ensureInitialized() const;
- mutable QList<QWindowsMime *> m_mimes;
+ mutable QVector<QWindowsMime *> m_mimes;
mutable int m_internalMimeCount = 0;
};
diff --git a/src/plugins/platforms/windows/qwindowsmousehandler.cpp b/src/plugins/platforms/windows/qwindowsmousehandler.cpp
index 6df5e6aa27..b776efc942 100644
--- a/src/plugins/platforms/windows/qwindowsmousehandler.cpp
+++ b/src/plugins/platforms/windows/qwindowsmousehandler.cpp
@@ -165,7 +165,7 @@ void QWindowsMouseHandler::clearEvents()
Qt::MouseButtons QWindowsMouseHandler::queryMouseButtons()
{
- Qt::MouseButtons result = nullptr;
+ Qt::MouseButtons result;
const bool mouseSwapped = GetSystemMetrics(SM_SWAPBUTTON);
if (GetAsyncKeyState(VK_LBUTTON) < 0)
result |= mouseSwapped ? Qt::RightButton: Qt::LeftButton;
@@ -630,7 +630,7 @@ bool QWindowsMouseHandler::translateTouchEvent(QWindow *window, HWND,
QTouchPointList touchPoints;
touchPoints.reserve(winTouchPointCount);
- Qt::TouchPointStates allStates = nullptr;
+ Qt::TouchPointStates allStates;
GetTouchInputInfo(reinterpret_cast<HTOUCHINPUT>(msg.lParam),
UINT(msg.wParam), winTouchInputs.data(), sizeof(TOUCHINPUT));
diff --git a/src/plugins/platforms/windows/qwindowsnativeinterface.cpp b/src/plugins/platforms/windows/qwindowsnativeinterface.cpp
index d1d181d66e..1195f15a59 100644
--- a/src/plugins/platforms/windows/qwindowsnativeinterface.cpp
+++ b/src/plugins/platforms/windows/qwindowsnativeinterface.cpp
@@ -47,6 +47,7 @@
#include "qwindowsopengltester.h"
#include "qwindowsintegration.h"
#include "qwindowsmime.h"
+#include "qwindowstheme.h"
#include "qwin10helpers.h"
#include <QtGui/qwindow.h>
@@ -316,4 +317,15 @@ QVariant QWindowsNativeInterface::gpuList() const
return result;
}
+bool QWindowsNativeInterface::isDarkMode() const
+{
+ return QWindowsContext::isDarkMode();
+}
+
+// Dark mode support level 2 (style)
+bool QWindowsNativeInterface::isDarkModeStyle() const
+{
+ return (QWindowsIntegration::instance()->options() & QWindowsIntegration::DarkModeStyle) != 0;
+}
+
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/windows/qwindowsnativeinterface.h b/src/plugins/platforms/windows/qwindowsnativeinterface.h
index ce395dc5a4..90ba7a44c9 100644
--- a/src/plugins/platforms/windows/qwindowsnativeinterface.h
+++ b/src/plugins/platforms/windows/qwindowsnativeinterface.h
@@ -65,6 +65,8 @@ class QWindowsNativeInterface : public QPlatformNativeInterface
{
Q_OBJECT
Q_PROPERTY(bool asyncExpose READ asyncExpose WRITE setAsyncExpose)
+ Q_PROPERTY(bool darkMode READ isDarkMode STORED false NOTIFY darkModeChanged)
+ Q_PROPERTY(bool darkModeStyle READ isDarkModeStyle STORED false)
Q_PROPERTY(QVariant gpu READ gpu STORED false)
Q_PROPERTY(QVariant gpuList READ gpuList STORED false)
@@ -92,6 +94,9 @@ public:
bool asyncExpose() const;
void setAsyncExpose(bool value);
+ bool isDarkMode() const;
+ bool isDarkModeStyle() const;
+
QVariant gpu() const;
QVariant gpuList() const;
@@ -109,6 +114,9 @@ public:
QFunctionPointer platformFunction(const QByteArray &function) const override;
+Q_SIGNALS:
+ void darkModeChanged(bool);
+
private:
static QWindowsWindowFunctions::WindowActivationBehavior m_windowActivationBehavior;
};
diff --git a/src/plugins/platforms/windows/qwindowsopengltester.cpp b/src/plugins/platforms/windows/qwindowsopengltester.cpp
index afc1991e2c..72092a4481 100644
--- a/src/plugins/platforms/windows/qwindowsopengltester.cpp
+++ b/src/plugins/platforms/windows/qwindowsopengltester.cpp
@@ -206,7 +206,7 @@ QString GpuDescription::toString() const
str << " Card name : " << description
<< "\n Driver Name : " << driverName
<< "\n Driver Version : " << driverVersion.toString()
- << "\n Vendor ID : 0x" << qSetPadChar(QLatin1Char('0'))
+ << "\n Vendor ID : 0x" << qSetPadChar(u'0')
<< Qt::uppercasedigits << Qt::hex << qSetFieldWidth(4) << vendorId
<< "\n Device ID : 0x" << qSetFieldWidth(4) << deviceId
<< "\n SubSys ID : 0x" << qSetFieldWidth(8) << subSysId
@@ -285,7 +285,7 @@ static inline QString resolveBugListFile(const QString &fileName)
// then resolve via QStandardPaths::ConfigLocation.
const QString settingsPath = QLibraryInfo::location(QLibraryInfo::SettingsPath);
if (!settingsPath.isEmpty()) { // SettingsPath is empty unless specified in qt.conf.
- const QFileInfo fi(settingsPath + QLatin1Char('/') + fileName);
+ const QFileInfo fi(settingsPath + u'/' + fileName);
if (fi.isFile())
return fi.absoluteFilePath();
}
diff --git a/src/plugins/platforms/windows/qwindowspointerhandler.cpp b/src/plugins/platforms/windows/qwindowspointerhandler.cpp
index b477147da7..fba24d8696 100644
--- a/src/plugins/platforms/windows/qwindowspointerhandler.cpp
+++ b/src/plugins/platforms/windows/qwindowspointerhandler.cpp
@@ -482,7 +482,7 @@ bool QWindowsPointerHandler::translateTouchEvent(QWindow *window, HWND hwnd,
<< " message=" << Qt::hex << msg.message
<< " count=" << Qt::dec << count;
- Qt::TouchPointStates allStates = nullptr;
+ Qt::TouchPointStates allStates;
for (quint32 i = 0; i < count; ++i) {
if (QWindowsContext::verbose > 1)
diff --git a/src/plugins/platforms/windows/qwindowsscreen.cpp b/src/plugins/platforms/windows/qwindowsscreen.cpp
index df63adf558..c7a0c2e62e 100644
--- a/src/plugins/platforms/windows/qwindowsscreen.cpp
+++ b/src/plugins/platforms/windows/qwindowsscreen.cpp
@@ -73,7 +73,7 @@ static inline QDpi monitorDPI(HMONITOR hMonitor)
return {0, 0};
}
-using WindowsScreenDataList = QList<QWindowsScreenData>;
+using WindowsScreenDataList = QVector<QWindowsScreenData>;
static bool monitorData(HMONITOR hMonitor, QWindowsScreenData *data)
{
@@ -87,7 +87,7 @@ static bool monitorData(HMONITOR hMonitor, QWindowsScreenData *data)
data->geometry = QRect(QPoint(info.rcMonitor.left, info.rcMonitor.top), QPoint(info.rcMonitor.right - 1, info.rcMonitor.bottom - 1));
data->availableGeometry = QRect(QPoint(info.rcWork.left, info.rcWork.top), QPoint(info.rcWork.right - 1, info.rcWork.bottom - 1));
data->name = QString::fromWCharArray(info.szDevice);
- if (data->name == QLatin1String("WinDisc")) {
+ if (data->name == u"WinDisc") {
data->flags |= QWindowsScreenData::LockScreen;
} else {
if (const HDC hdc = CreateDC(info.szDevice, nullptr, nullptr, nullptr)) {
@@ -467,7 +467,7 @@ bool QWindowsScreenManager::handleDisplayChange(WPARAM wParam, LPARAM lParam)
return false;
}
-static inline int indexOfMonitor(const QList<QWindowsScreen *> &screens,
+static inline int indexOfMonitor(const QWindowsScreenManager::WindowsScreenList &screens,
const QString &monitorName)
{
for (int i= 0; i < screens.size(); ++i)
@@ -476,7 +476,7 @@ static inline int indexOfMonitor(const QList<QWindowsScreen *> &screens,
return -1;
}
-static inline int indexOfMonitor(const QList<QWindowsScreenData> &screenData,
+static inline int indexOfMonitor(const WindowsScreenDataList &screenData,
const QString &monitorName)
{
for (int i = 0; i < screenData.size(); ++i)
diff --git a/src/plugins/platforms/windows/qwindowsscreen.h b/src/plugins/platforms/windows/qwindowsscreen.h
index 2fd56f53cf..5c095808f2 100644
--- a/src/plugins/platforms/windows/qwindowsscreen.h
+++ b/src/plugins/platforms/windows/qwindowsscreen.h
@@ -127,7 +127,7 @@ private:
class QWindowsScreenManager
{
public:
- using WindowsScreenList = QList<QWindowsScreen *>;
+ using WindowsScreenList = QVector<QWindowsScreen *>;
QWindowsScreenManager();
diff --git a/src/plugins/platforms/windows/qwindowsservices.cpp b/src/plugins/platforms/windows/qwindowsservices.cpp
index 83b052bb49..6a2708ee26 100644
--- a/src/plugins/platforms/windows/qwindowsservices.cpp
+++ b/src/plugins/platforms/windows/qwindowsservices.cpp
@@ -92,7 +92,7 @@ static inline QString mailCommand()
// "rundll32.exe .. url.dll,MailToProtocolHandler %l" is returned. Launching it
// silently fails or brings up a broken dialog after a long time, so exclude it and
// fall back to ShellExecute() which brings up the URL assocation dialog.
- if (command.isEmpty() || command.contains(QLatin1String(",MailToProtocolHandler")))
+ if (command.isEmpty() || command.contains(u",MailToProtocolHandler"))
return QString();
wchar_t expandedCommand[MAX_PATH] = {0};
return ExpandEnvironmentStrings(reinterpret_cast<const wchar_t *>(command.utf16()),
@@ -108,7 +108,7 @@ static inline bool launchMail(const QUrl &url)
return false;
}
//Make sure the path for the process is in quotes
- const QChar doubleQuote = QLatin1Char('"');
+ const QChar doubleQuote = u'"';
if (!command.startsWith(doubleQuote)) {
const int exeIndex = command.indexOf(QStringLiteral(".exe "), 0, Qt::CaseInsensitive);
if (exeIndex != -1) {
@@ -140,7 +140,7 @@ static inline bool launchMail(const QUrl &url)
bool QWindowsServices::openUrl(const QUrl &url)
{
const QString scheme = url.scheme();
- if (scheme == QLatin1String("mailto") && launchMail(url))
+ if (scheme == u"mailto" && launchMail(url))
return true;
return shellExecute(url);
}
diff --git a/src/plugins/platforms/windows/qwindowssystemtrayicon.cpp b/src/plugins/platforms/windows/qwindowssystemtrayicon.cpp
index 9409d2db4d..d6a5b29a71 100644
--- a/src/plugins/platforms/windows/qwindowssystemtrayicon.cpp
+++ b/src/plugins/platforms/windows/qwindowssystemtrayicon.cpp
@@ -168,7 +168,7 @@ static inline HWND createTrayIconMessageWindow()
return nullptr;
// Register window class in the platform plugin.
const QString className =
- ctx->registerWindowClass(QStringLiteral("QTrayIconMessageWindowClass"),
+ ctx->registerWindowClass(QWindowsContext::classNamePrefix() + QStringLiteral("TrayIconMessageWindowClass"),
qWindowsTrayIconWndProc);
const wchar_t windowName[] = L"QTrayIconMessageWindow";
return CreateWindowEx(0, reinterpret_cast<const wchar_t *>(className.utf16()),
@@ -261,7 +261,7 @@ void QWindowsSystemTrayIcon::showMessage(const QString &title, const QString &me
// For empty messages, ensures that they show when only title is set
QString message = messageIn;
if (message.isEmpty() && !title.isEmpty())
- message.append(QLatin1Char(' '));
+ message.append(u' ');
NOTIFYICONDATA tnd;
initNotifyIconData(tnd);
diff --git a/src/plugins/platforms/windows/qwindowstheme.cpp b/src/plugins/platforms/windows/qwindowstheme.cpp
index 40f9652cbd..7f47cd712f 100644
--- a/src/plugins/platforms/windows/qwindowstheme.cpp
+++ b/src/plugins/platforms/windows/qwindowstheme.cpp
@@ -63,6 +63,7 @@
#include <QtCore/qcoreapplication.h>
#include <QtCore/qdebug.h>
#include <QtCore/qtextstream.h>
+#include <QtCore/qoperatingsystemversion.h>
#include <QtCore/qsysinfo.h>
#include <QtCore/qcache.h>
#include <QtCore/qthread.h>
@@ -78,6 +79,7 @@
#include <QtFontDatabaseSupport/private/qwindowsfontdatabase_p.h>
#include <private/qhighdpiscaling_p.h>
#include <private/qsystemlibrary_p.h>
+#include <private/qwinregistry_p.h>
#include <algorithm>
@@ -96,7 +98,7 @@ static inline QTextStream& operator<<(QTextStream &str, const QColor &c)
{
str.setIntegerBase(16);
str.setFieldWidth(2);
- str.setPadChar(QLatin1Char('0'));
+ str.setPadChar(u'0');
str << " rgb: #" << c.red() << c.green() << c.blue();
str.setIntegerBase(10);
str.setFieldWidth(0);
@@ -164,7 +166,7 @@ public:
QMutexLocker readyLocker(&m_readyMutex);
while (!m_cancelled.loadRelaxed()) {
if (!m_params && !m_cancelled.loadRelaxed()
- && !m_readyCondition.wait(&m_readyMutex, 1000))
+ && !m_readyCondition.wait(&m_readyMutex, QDeadlineTimer(1000ll)))
continue;
if (m_params) {
@@ -189,7 +191,7 @@ public:
CoUninitialize();
}
- bool runWithParams(QShGetFileInfoParams *params, unsigned long timeOutMSecs)
+ bool runWithParams(QShGetFileInfoParams *params, qint64 timeOutMSecs)
{
QMutexLocker doneLocker(&m_doneMutex);
@@ -198,7 +200,7 @@ public:
m_readyCondition.wakeAll();
m_readyMutex.unlock();
- return m_doneCondition.wait(&m_doneMutex, timeOutMSecs);
+ return m_doneCondition.wait(&m_doneMutex, QDeadlineTimer(timeOutMSecs));
}
void cancel()
@@ -220,7 +222,7 @@ private:
static bool shGetFileInfoBackground(const QString &fileName, DWORD attributes,
SHFILEINFO *info, UINT flags,
- unsigned long timeOutMSecs = 5000)
+ qint64 timeOutMSecs = 5000)
{
static QShGetFileInfoThread *getFileInfoThread = nullptr;
if (!getFileInfoThread) {
@@ -241,6 +243,14 @@ static bool shGetFileInfoBackground(const QString &fileName, DWORD attributes,
return result;
}
+// Dark Mode constants
+enum DarkModeColors : QRgb {
+ darkModeBtnHighlightRgb = 0xc0c0c0,
+ darkModeBtnShadowRgb = 0x808080,
+ darkModeHighlightRgb = 0x0055ff, // deviating from 0x800080
+ darkModeMenuHighlightRgb = darkModeHighlightRgb
+};
+
// from QStyle::standardPalette
static inline QPalette standardPalette()
{
@@ -258,23 +268,55 @@ static inline QPalette standardPalette()
return palette;
}
-static inline QPalette systemPalette()
+static void populateLightSystemBasePalette(QPalette &result)
{
- QPalette result = standardPalette();
result.setColor(QPalette::WindowText, getSysColor(COLOR_WINDOWTEXT));
- result.setColor(QPalette::Button, getSysColor(COLOR_BTNFACE));
- result.setColor(QPalette::Light, getSysColor(COLOR_BTNHIGHLIGHT));
+ const QColor btnFace = getSysColor(COLOR_BTNFACE);
+ result.setColor(QPalette::Button, btnFace);
+ const QColor btnHighlight = getSysColor(COLOR_BTNHIGHLIGHT);
+ result.setColor(QPalette::Light, btnHighlight);
result.setColor(QPalette::Dark, getSysColor(COLOR_BTNSHADOW));
result.setColor(QPalette::Mid, result.button().color().darker(150));
result.setColor(QPalette::Text, getSysColor(COLOR_WINDOWTEXT));
- result.setColor(QPalette::BrightText, getSysColor(COLOR_BTNHIGHLIGHT));
+ result.setColor(QPalette::BrightText, btnHighlight);
result.setColor(QPalette::Base, getSysColor(COLOR_WINDOW));
- result.setColor(QPalette::Window, getSysColor(COLOR_BTNFACE));
+ result.setColor(QPalette::Window, btnFace);
result.setColor(QPalette::ButtonText, getSysColor(COLOR_BTNTEXT));
result.setColor(QPalette::Midlight, getSysColor(COLOR_3DLIGHT));
result.setColor(QPalette::Shadow, getSysColor(COLOR_3DDKSHADOW));
result.setColor(QPalette::Highlight, getSysColor(COLOR_HIGHLIGHT));
result.setColor(QPalette::HighlightedText, getSysColor(COLOR_HIGHLIGHTTEXT));
+}
+
+static void populateDarkSystemBasePalette(QPalette &result)
+{
+ const QColor darkModeWindowText = Qt::white;
+ result.setColor(QPalette::WindowText, darkModeWindowText);
+ const QColor darkModebtnFace = Qt::black;
+ result.setColor(QPalette::Button, darkModebtnFace);
+ const QColor btnHighlight = QColor(darkModeBtnHighlightRgb);
+ result.setColor(QPalette::Light, btnHighlight);
+ result.setColor(QPalette::Dark, QColor(darkModeBtnShadowRgb));
+ result.setColor(QPalette::Mid, result.button().color().darker(150));
+ result.setColor(QPalette::Text, darkModeWindowText);
+ result.setColor(QPalette::BrightText, btnHighlight);
+ result.setColor(QPalette::Base, darkModebtnFace);
+ result.setColor(QPalette::Window, darkModebtnFace);
+ result.setColor(QPalette::ButtonText, darkModeWindowText);
+ result.setColor(QPalette::Midlight, darkModeWindowText);
+ result.setColor(QPalette::Shadow, darkModeWindowText);
+ result.setColor(QPalette::Highlight, QColor(darkModeHighlightRgb));
+ result.setColor(QPalette::HighlightedText, darkModeWindowText);
+}
+
+static QPalette systemPalette(bool light)
+{
+ QPalette result = standardPalette();
+ if (light)
+ populateLightSystemBasePalette(result);
+ else
+ populateDarkSystemBasePalette(result);
+
result.setColor(QPalette::Link, Qt::blue);
result.setColor(QPalette::LinkVisited, Qt::magenta);
result.setColor(QPalette::Inactive, QPalette::Button, result.button().color());
@@ -300,19 +342,19 @@ static inline QPalette systemPalette()
result.setColor(QPalette::Disabled, QPalette::Text, disabled);
result.setColor(QPalette::Disabled, QPalette::ButtonText, disabled);
result.setColor(QPalette::Disabled, QPalette::Highlight,
- getSysColor(COLOR_HIGHLIGHT));
+ light ? getSysColor(COLOR_HIGHLIGHT) : QColor(darkModeHighlightRgb));
result.setColor(QPalette::Disabled, QPalette::HighlightedText,
- getSysColor(COLOR_HIGHLIGHTTEXT));
+ light ? getSysColor(COLOR_HIGHLIGHTTEXT) : QColor(Qt::white));
result.setColor(QPalette::Disabled, QPalette::Base,
result.window().color());
return result;
}
-static inline QPalette toolTipPalette(const QPalette &systemPalette)
+static inline QPalette toolTipPalette(const QPalette &systemPalette, bool light)
{
QPalette result(systemPalette);
- const QColor tipBgColor(getSysColor(COLOR_INFOBK));
- const QColor tipTextColor(getSysColor(COLOR_INFOTEXT));
+ const QColor tipBgColor = light ? getSysColor(COLOR_INFOBK) : QColor(Qt::black);
+ const QColor tipTextColor = light ? getSysColor(COLOR_INFOTEXT) : QColor(Qt::white);
result.setColor(QPalette::All, QPalette::Button, tipBgColor);
result.setColor(QPalette::All, QPalette::Window, tipBgColor);
@@ -337,12 +379,13 @@ static inline QPalette toolTipPalette(const QPalette &systemPalette)
return result;
}
-static inline QPalette menuPalette(const QPalette &systemPalette)
+static inline QPalette menuPalette(const QPalette &systemPalette, bool light)
{
QPalette result(systemPalette);
- const QColor menuColor(getSysColor(COLOR_MENU));
- const QColor menuTextColor(getSysColor(COLOR_MENUTEXT));
- const QColor disabled(getSysColor(COLOR_GRAYTEXT));
+ const QColor menuColor = light ? getSysColor(COLOR_MENU) : QColor(Qt::black);
+ const QColor menuTextColor = light ? getSysColor(COLOR_MENUTEXT) : QColor(Qt::white);
+ const QColor disabled = light
+ ? getSysColor(COLOR_GRAYTEXT) : QColor(darkModeBtnHighlightRgb);
// we might need a special color group for the result.
result.setColor(QPalette::Active, QPalette::Button, menuColor);
result.setColor(QPalette::Active, QPalette::Text, menuTextColor);
@@ -351,8 +394,10 @@ static inline QPalette menuPalette(const QPalette &systemPalette)
result.setColor(QPalette::Disabled, QPalette::WindowText, disabled);
result.setColor(QPalette::Disabled, QPalette::Text, disabled);
const bool isFlat = booleanSystemParametersInfo(SPI_GETFLATMENU, false);
- result.setColor(QPalette::Disabled, QPalette::Highlight,
- getSysColor(isFlat ? COLOR_MENUHILIGHT : COLOR_HIGHLIGHT));
+ const QColor highlightColor = light
+ ? (getSysColor(isFlat ? COLOR_MENUHILIGHT : COLOR_HIGHLIGHT))
+ : QColor(darkModeMenuHighlightRgb);
+ result.setColor(QPalette::Disabled, QPalette::Highlight, highlightColor);
result.setColor(QPalette::Disabled, QPalette::HighlightedText, disabled);
result.setColor(QPalette::Disabled, QPalette::Button,
result.color(QPalette::Active, QPalette::Button));
@@ -373,12 +418,12 @@ static inline QPalette menuPalette(const QPalette &systemPalette)
return result;
}
-static inline QPalette *menuBarPalette(const QPalette &menuPalette)
+static inline QPalette *menuBarPalette(const QPalette &menuPalette, bool light)
{
QPalette *result = nullptr;
if (booleanSystemParametersInfo(SPI_GETFLATMENU, false)) {
result = new QPalette(menuPalette);
- const QColor menubar(getSysColor(COLOR_MENUBAR));
+ const QColor menubar(light ? getSysColor(COLOR_MENUBAR) : QColor(Qt::black));
result->setColor(QPalette::Active, QPalette::Button, menubar);
result->setColor(QPalette::Disabled, QPalette::Button, menubar);
result->setColor(QPalette::Inactive, QPalette::Button, menubar);
@@ -485,10 +530,26 @@ void QWindowsTheme::refreshPalettes()
if (!QGuiApplication::desktopSettingsAware())
return;
- m_palettes[SystemPalette] = new QPalette(systemPalette());
- m_palettes[ToolTipPalette] = new QPalette(toolTipPalette(*m_palettes[SystemPalette]));
- m_palettes[MenuPalette] = new QPalette(menuPalette(*m_palettes[SystemPalette]));
- m_palettes[MenuBarPalette] = menuBarPalette(*m_palettes[MenuPalette]);
+ const bool light =
+ !QWindowsContext::isDarkMode()
+ || (QWindowsIntegration::instance()->options() & QWindowsIntegration::DarkModeStyle) == 0;
+ m_palettes[SystemPalette] = new QPalette(systemPalette(light));
+ 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);
+ if (!light) {
+ m_palettes[ButtonPalette] = new QPalette(*m_palettes[SystemPalette]);
+ m_palettes[ButtonPalette]->setColor(QPalette::Button, QColor(0x666666u));
+ const QColor checkBoxBlue(0x0078d7u);
+ const QColor white(Qt::white);
+ m_palettes[CheckBoxPalette] = new QPalette(*m_palettes[SystemPalette]);
+ m_palettes[CheckBoxPalette]->setColor(QPalette::Window, checkBoxBlue);
+ m_palettes[CheckBoxPalette]->setColor(QPalette::Base, checkBoxBlue);
+ m_palettes[CheckBoxPalette]->setColor(QPalette::Button, checkBoxBlue);
+ m_palettes[CheckBoxPalette]->setColor(QPalette::ButtonText, white);
+ m_palettes[RadioButtonPalette] = new QPalette(*m_palettes[CheckBoxPalette]);
+
+ }
}
void QWindowsTheme::clearFonts()
@@ -497,6 +558,12 @@ void QWindowsTheme::clearFonts()
std::fill(m_fonts, m_fonts + NFonts, nullptr);
}
+void QWindowsTheme::refresh()
+{
+ refreshPalettes();
+ refreshFonts();
+}
+
void QWindowsTheme::refreshFonts()
{
clearFonts();
@@ -731,13 +798,13 @@ static QString dirIconPixmapCacheKey(int iIcon, int iconSize, int imageListSize)
{
QString key = QLatin1String("qt_dir_") + QString::number(iIcon);
if (iconSize == SHGFI_LARGEICON)
- key += QLatin1Char('l');
+ key += u'l';
switch (imageListSize) {
case sHIL_EXTRALARGE:
- key += QLatin1Char('e');
+ key += u'e';
break;
case sHIL_JUMBO:
- key += QLatin1Char('j');
+ key += u'j';
break;
}
return key;
@@ -815,9 +882,9 @@ QString QWindowsFileIconEngine::cacheKey() const
// It is faster to just look at the file extensions;
// avoiding slow QFileInfo::isExecutable() (QTBUG-13182)
QString suffix = fileInfo().suffix();
- if (!suffix.compare(QLatin1String("exe"), Qt::CaseInsensitive)
- || !suffix.compare(QLatin1String("lnk"), Qt::CaseInsensitive)
- || !suffix.compare(QLatin1String("ico"), Qt::CaseInsensitive)) {
+ if (!suffix.compare(u"exe", Qt::CaseInsensitive)
+ || !suffix.compare(u"lnk", Qt::CaseInsensitive)
+ || !suffix.compare(u"ico", Qt::CaseInsensitive)) {
return QString();
}
return QLatin1String("qt_.")
@@ -946,6 +1013,23 @@ bool QWindowsTheme::useNativeMenus()
return result;
}
+bool QWindowsTheme::queryDarkMode()
+{
+ if (QOperatingSystemVersion::current()
+ < QOperatingSystemVersion(QOperatingSystemVersion::Windows, 10, 0, 17763)
+ || queryHighContrast()) {
+ return false;
+ }
+ const auto setting = QWinRegistryKey(HKEY_CURRENT_USER, LR"(Software\Microsoft\Windows\CurrentVersion\Themes\Personalize)")
+ .dwordValue(L"AppsUseLightTheme");
+ return setting.second && setting.first == 0;
+}
+
+bool QWindowsTheme::queryHighContrast()
+{
+ return booleanSystemParametersInfo(SPI_GETHIGHCONTRAST, false);
+}
+
QPlatformMenuItem *QWindowsTheme::createPlatformMenuItem() const
{
qCDebug(lcQpaMenus) << __FUNCTION__;
diff --git a/src/plugins/platforms/windows/qwindowstheme.h b/src/plugins/platforms/windows/qwindowstheme.h
index 07120230ce..af28f2878c 100644
--- a/src/plugins/platforms/windows/qwindowstheme.h
+++ b/src/plugins/platforms/windows/qwindowstheme.h
@@ -71,7 +71,7 @@ public:
QPixmap standardPixmap(StandardPixmap sp, const QSizeF &size) const override;
- QIcon fileIcon(const QFileInfo &fileInfo, QPlatformTheme::IconOptions iconOptions = nullptr) const override;
+ QIcon fileIcon(const QFileInfo &fileInfo, QPlatformTheme::IconOptions iconOptions = {}) const override;
void windowsThemeChanged(QWindow *window);
void displayChanged() { refreshIconPixmapSizes(); }
@@ -84,13 +84,15 @@ public:
void showPlatformMenuBar() override;
static bool useNativeMenus();
+ static bool queryDarkMode();
+ static bool queryHighContrast();
void refreshFonts();
+ void refresh();
static const char *name;
private:
- void refresh() { refreshPalettes(); refreshFonts(); }
void clearPalettes();
void refreshPalettes();
void clearFonts();
diff --git a/src/plugins/platforms/windows/qwindowswindow.cpp b/src/plugins/platforms/windows/qwindowswindow.cpp
index 04478d5f1f..8191bbb42b 100644
--- a/src/plugins/platforms/windows/qwindowswindow.cpp
+++ b/src/plugins/platforms/windows/qwindowswindow.cpp
@@ -253,7 +253,7 @@ QDebug operator<<(QDebug d, const GUID &guid)
{
QDebugStateSaver saver(d);
d.nospace();
- d << '{' << Qt::hex << Qt::uppercasedigits << qSetPadChar(QLatin1Char('0'))
+ d << '{' << Qt::hex << Qt::uppercasedigits << qSetPadChar(u'0')
<< qSetFieldWidth(8) << guid.Data1
<< qSetFieldWidth(0) << '-' << qSetFieldWidth(4)
<< guid.Data2 << qSetFieldWidth(0) << '-' << qSetFieldWidth(4)
@@ -592,7 +592,7 @@ static QPoint calcPosition(const QWindow *w, const QWindowCreationContextPtr &co
return posFrame;
// Find the original screen containing the coordinates.
- const QList<QScreen *> screens = screenForGL->virtualSiblings();
+ const auto screens = screenForGL->virtualSiblings();
const QScreen *orgScreen = nullptr;
for (QScreen *screen : screens) {
if (screen->handle()->availableGeometry().contains(posFrame)) {
@@ -749,6 +749,11 @@ void WindowCreationData::fromWindow(const QWindow *w, const Qt::WindowFlags flag
}
}
+static inline bool shouldApplyDarkFrame(const QWindow *w)
+{
+ return w->isTopLevel() && !w->flags().testFlag(Qt::FramelessWindowHint);
+}
+
QWindowsWindowData
WindowCreationData::create(const QWindow *w, const WindowData &data, QString title) const
{
@@ -816,6 +821,12 @@ QWindowsWindowData
return result;
}
+ if (QWindowsContext::isDarkMode()
+ && (QWindowsIntegration::instance()->options() & QWindowsIntegration::DarkModeWindowFrames) != 0
+ && shouldApplyDarkFrame(w)) {
+ QWindowsWindow::setDarkBorderToWindow(result.hwnd, true);
+ }
+
if (mirrorParentWidth != 0) {
context->obtainedPos.setX(mirrorParentWidth - context->obtainedSize.width()
- context->obtainedPos.x());
@@ -2602,37 +2613,41 @@ bool QWindowsWindow::setMouseGrabEnabled(bool grab)
return grab;
}
-static inline DWORD cornerToWinOrientation(Qt::Corner corner)
+static inline DWORD edgesToWinOrientation(Qt::Edges edges)
{
- switch (corner) {
- case Qt::TopLeftCorner:
- return 0xf004; // SZ_SIZETOPLEFT;
- case Qt::TopRightCorner:
- return 0xf005; // SZ_SIZETOPRIGHT
- case Qt::BottomLeftCorner:
- return 0xf007; // SZ_SIZEBOTTOMLEFT
- case Qt::BottomRightCorner:
- return 0xf008; // SZ_SIZEBOTTOMRIGHT
- }
- return 0;
+ if (edges == Qt::LeftEdge)
+ return 0xf001; // SC_SIZELEFT;
+ else if (edges == (Qt::RightEdge))
+ return 0xf002; // SC_SIZERIGHT
+ else if (edges == (Qt::TopEdge))
+ return 0xf003; // SC_SIZETOP
+ else if (edges == (Qt::TopEdge | Qt::LeftEdge))
+ return 0xf004; // SC_SIZETOPLEFT
+ else if (edges == (Qt::TopEdge | Qt::RightEdge))
+ return 0xf005; // SC_SIZETOPRIGHT
+ else if (edges == (Qt::BottomEdge))
+ return 0xf006; // SC_SIZEBOTTOM
+ else if (edges == (Qt::BottomEdge | Qt::LeftEdge))
+ return 0xf007; // SC_SIZEBOTTOMLEFT
+ else if (edges == (Qt::BottomEdge | Qt::RightEdge))
+ return 0xf008; // SC_SIZEBOTTOMRIGHT
+
+ return 0xf000; // SC_SIZE
}
-bool QWindowsWindow::startSystemResize(const QPoint &, Qt::Corner corner)
+bool QWindowsWindow::startSystemResize(Qt::Edges edges)
{
- if (!GetSystemMenu(m_data.hwnd, FALSE))
+ if (Q_UNLIKELY(window()->flags().testFlag(Qt::MSWindowsFixedSizeDialogHint)))
return false;
ReleaseCapture();
- PostMessage(m_data.hwnd, WM_SYSCOMMAND, cornerToWinOrientation(corner), 0);
+ PostMessage(m_data.hwnd, WM_SYSCOMMAND, edgesToWinOrientation(edges), 0);
setFlag(SizeGripOperation);
return true;
}
-bool QWindowsWindow::startSystemMove(const QPoint &)
+bool QWindowsWindow::startSystemMove()
{
- if (!GetSystemMenu(m_data.hwnd, FALSE))
- return false;
-
ReleaseCapture();
PostMessage(m_data.hwnd, WM_SYSCOMMAND, 0xF012 /*SC_DRAGMOVE*/, 0);
return true;
@@ -2901,6 +2916,39 @@ bool QWindowsWindow::isTopLevel() const
return window()->isTopLevel() && !m_data.embedded;
}
+enum : WORD {
+ DwmwaUseImmersiveDarkMode = 20,
+ 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)
+ qWarning("%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;
+ const bool ok =
+ SUCCEEDED(DwmSetWindowAttribute(hwnd, DwmwaUseImmersiveDarkMode, &darkBorder, sizeof(darkBorder)))
+ || SUCCEEDED(DwmSetWindowAttribute(hwnd, DwmwaUseImmersiveDarkModeBefore20h1, &darkBorder, sizeof(darkBorder)));
+ if (!ok)
+ qWarning("%s: Unable to set dark window border.", __FUNCTION__);
+ return ok;
+}
+
+void QWindowsWindow::setDarkBorder(bool d)
+{
+ if (shouldApplyDarkFrame(window()) && queryDarkBorder(m_data.hwnd) != d)
+ setDarkBorderToWindow(m_data.hwnd, d);
+}
+
QWindowsMenuBar *QWindowsWindow::menuBar() const
{
return m_menuBar.data();
diff --git a/src/plugins/platforms/windows/qwindowswindow.h b/src/plugins/platforms/windows/qwindowswindow.h
index aaf02d2a81..b35081d41d 100644
--- a/src/plugins/platforms/windows/qwindowswindow.h
+++ b/src/plugins/platforms/windows/qwindowswindow.h
@@ -277,8 +277,8 @@ public:
bool setMouseGrabEnabled(bool grab) override;
inline bool hasMouseCapture() const { return GetCapture() == m_data.hwnd; }
- bool startSystemResize(const QPoint &pos, Qt::Corner corner) override;
- bool startSystemMove(const QPoint &pos) override;
+ bool startSystemResize(Qt::Edges edges) override;
+ bool startSystemMove() override;
void setFrameStrutEventsEnabled(bool enabled) override;
bool frameStrutEventsEnabled() const override { return testFlag(FrameStrutEventsEnabled); }
@@ -287,6 +287,9 @@ public:
HWND handle() const override { return m_data.hwnd; }
bool isTopLevel() const override;
+ static bool setDarkBorderToWindow(HWND hwnd, bool d);
+ void setDarkBorder(bool d);
+
QWindowsMenuBar *menuBar() const;
void setMenuBar(QWindowsMenuBar *mb);
diff --git a/src/plugins/platforms/windows/uiautomation/qwindowsuiamainprovider.cpp b/src/plugins/platforms/windows/uiautomation/qwindowsuiamainprovider.cpp
index c89dea3dfb..59360616a1 100644
--- a/src/plugins/platforms/windows/uiautomation/qwindowsuiamainprovider.cpp
+++ b/src/plugins/platforms/windows/uiautomation/qwindowsuiamainprovider.cpp
@@ -166,11 +166,27 @@ void QWindowsUiaMainProvider::notifyValueChange(QAccessibleValueChangeEvent *eve
}
if (event->value().type() == QVariant::String) {
if (QWindowsUiaMainProvider *provider = providerForAccessible(accessible)) {
- // Notifies changes in string values.
- VARIANT oldVal, newVal;
- clearVariant(&oldVal);
- setVariantString(event->value().toString(), &newVal);
- QWindowsUiaWrapper::instance()->raiseAutomationPropertyChangedEvent(provider, UIA_ValueValuePropertyId, oldVal, newVal);
+
+ // Tries to notify the change using UiaRaiseNotificationEvent(), which is only available on
+ // Windows 10 version 1709 or newer. Otherwise uses UiaRaiseAutomationPropertyChangedEvent().
+
+ BSTR displayString = bStrFromQString(event->value().toString());
+ BSTR activityId = bStrFromQString(QString());
+
+ HRESULT hr = QWindowsUiaWrapper::instance()->raiseNotificationEvent(provider, NotificationKind_Other,
+ NotificationProcessing_ImportantMostRecent,
+ displayString, activityId);
+
+ ::SysFreeString(displayString);
+ ::SysFreeString(activityId);
+
+ if (hr == static_cast<HRESULT>(UIA_E_NOTSUPPORTED)) {
+ VARIANT oldVal, newVal;
+ clearVariant(&oldVal);
+ setVariantString(event->value().toString(), &newVal);
+ QWindowsUiaWrapper::instance()->raiseAutomationPropertyChangedEvent(provider, UIA_ValueValuePropertyId, oldVal, newVal);
+ ::SysFreeString(newVal.bstrVal);
+ }
}
} else if (QAccessibleValueInterface *valueInterface = accessible->valueInterface()) {
if (QWindowsUiaMainProvider *provider = providerForAccessible(accessible)) {
@@ -402,12 +418,14 @@ HRESULT QWindowsUiaMainProvider::GetPropertyValue(PROPERTYID idProp, VARIANT *pR
// Control type converted from role.
auto controlType = roleToControlTypeId(accessible->role());
- // The native OSK should be disbled if the Qt OSK is in use.
+ // The native OSK should be disbled if the Qt OSK is in use,
+ // or if disabled via application attribute.
static bool imModuleEmpty = qEnvironmentVariableIsEmpty("QT_IM_MODULE");
+ bool nativeVKDisabled = QCoreApplication::testAttribute(Qt::AA_DisableNativeVirtualKeyboard);
// If we want to disable the native OSK auto-showing
// we have to report text fields as non-editable.
- if (controlType == UIA_EditControlTypeId && !imModuleEmpty)
+ if (controlType == UIA_EditControlTypeId && (!imModuleEmpty || nativeVKDisabled))
controlType = UIA_TextControlTypeId;
setVariantI4(controlType, pRetVal);
@@ -455,6 +473,10 @@ HRESULT QWindowsUiaMainProvider::GetPropertyValue(PROPERTYID idProp, VARIANT *pR
setVariantBool(wt == Qt::Popup || wt == Qt::ToolTip || wt == Qt::SplashScreen, pRetVal);
}
break;
+ case UIA_IsDialogPropertyId:
+ setVariantBool(accessible->role() == QAccessible::Dialog
+ || accessible->role() == QAccessible::AlertMessage, pRetVal);
+ break;
case UIA_FullDescriptionPropertyId:
setVariantString(accessible->text(QAccessible::Description), pRetVal);
break;
@@ -482,7 +504,7 @@ QString QWindowsUiaMainProvider::automationIdForAccessible(const QAccessibleInte
if (name.isEmpty())
return QString();
if (!result.isEmpty())
- result.prepend(QLatin1Char('.'));
+ result.prepend(u'.');
result.prepend(name);
obj = obj->parent();
}
diff --git a/src/plugins/platforms/windows/uiautomation/qwindowsuiaselectionprovider.cpp b/src/plugins/platforms/windows/uiautomation/qwindowsuiaselectionprovider.cpp
index 3305e9c5c4..fb41012cf4 100644
--- a/src/plugins/platforms/windows/uiautomation/qwindowsuiaselectionprovider.cpp
+++ b/src/plugins/platforms/windows/uiautomation/qwindowsuiaselectionprovider.cpp
@@ -49,6 +49,7 @@
#include <QtCore/qloggingcategory.h>
#include <QtCore/qstring.h>
#include <QtCore/qlist.h>
+#include <QtCore/qvector.h>
QT_BEGIN_NAMESPACE
@@ -78,7 +79,7 @@ HRESULT STDMETHODCALLTYPE QWindowsUiaSelectionProvider::GetSelection(SAFEARRAY *
return UIA_E_ELEMENTNOTAVAILABLE;
// First put selected items in a list, then build a safe array with the right size.
- QList<QAccessibleInterface *> selectedList;
+ QVector<QAccessibleInterface *> selectedList;
for (int i = 0; i < accessible->childCount(); ++i) {
if (QAccessibleInterface *child = accessible->child(i)) {
if (child->state().selected) {
diff --git a/src/plugins/platforms/windows/uiautomation/qwindowsuiatableitemprovider.cpp b/src/plugins/platforms/windows/uiautomation/qwindowsuiatableitemprovider.cpp
index 2a94012590..1348ec7cc0 100644
--- a/src/plugins/platforms/windows/uiautomation/qwindowsuiatableitemprovider.cpp
+++ b/src/plugins/platforms/windows/uiautomation/qwindowsuiatableitemprovider.cpp
@@ -80,7 +80,7 @@ HRESULT STDMETHODCALLTYPE QWindowsUiaTableItemProvider::GetRowHeaderItems(SAFEAR
if (!tableCellInterface)
return UIA_E_ELEMENTNOTAVAILABLE;
- QList<QAccessibleInterface *> headers = tableCellInterface->rowHeaderCells();
+ const auto headers = tableCellInterface->rowHeaderCells();
if ((*pRetVal = SafeArrayCreateVector(VT_UNKNOWN, 0, headers.size()))) {
for (LONG i = 0; i < headers.size(); ++i) {
@@ -110,7 +110,7 @@ HRESULT STDMETHODCALLTYPE QWindowsUiaTableItemProvider::GetColumnHeaderItems(SAF
if (!tableCellInterface)
return UIA_E_ELEMENTNOTAVAILABLE;
- QList<QAccessibleInterface *> headers = tableCellInterface->columnHeaderCells();
+ const auto headers = tableCellInterface->columnHeaderCells();
if ((*pRetVal = SafeArrayCreateVector(VT_UNKNOWN, 0, headers.size()))) {
for (LONG i = 0; i < headers.size(); ++i) {
diff --git a/src/plugins/platforms/windows/uiautomation/qwindowsuiautils.cpp b/src/plugins/platforms/windows/uiautomation/qwindowsuiautils.cpp
index ab04384616..682b8c19c0 100644
--- a/src/plugins/platforms/windows/uiautomation/qwindowsuiautils.cpp
+++ b/src/plugins/platforms/windows/uiautomation/qwindowsuiautils.cpp
@@ -161,7 +161,7 @@ long roleToControlTypeId(QAccessible::Role role)
{QAccessible::Sound, UIA_CustomControlTypeId},
{QAccessible::Cursor, UIA_CustomControlTypeId},
{QAccessible::Caret, UIA_CustomControlTypeId},
- {QAccessible::AlertMessage, UIA_CustomControlTypeId},
+ {QAccessible::AlertMessage, UIA_WindowControlTypeId},
{QAccessible::Window, UIA_WindowControlTypeId},
{QAccessible::Client, UIA_GroupControlTypeId},
{QAccessible::PopupMenu, UIA_MenuControlTypeId},
diff --git a/src/plugins/platforms/winrt/qwinrtfiledialoghelper.cpp b/src/plugins/platforms/winrt/qwinrtfiledialoghelper.cpp
index 114d6dacd8..fee8063f13 100644
--- a/src/plugins/platforms/winrt/qwinrtfiledialoghelper.cpp
+++ b/src/plugins/platforms/winrt/qwinrtfiledialoghelper.cpp
@@ -397,7 +397,15 @@ bool QWinRTFileDialogHelper::show(Qt::WindowFlags windowFlags, Qt::WindowModalit
RETURN_FALSE_IF_FAILED_WITH_ARGS("Failed to set default file extension \"%s\"", qPrintable(suffix));
}
- const QString suggestedName = QFileInfo(d->saveFileName.toLocalFile()).fileName();
+ QString suggestedName = QFileInfo(d->saveFileName.toLocalFile()).fileName();
+ if (suggestedName.isEmpty() && dialogOptions->initiallySelectedFiles().size() > 0)
+ suggestedName = QFileInfo(dialogOptions->initiallySelectedFiles().first().toLocalFile())
+ .fileName();
+ if (suggestedName.isEmpty()) {
+ const auto fileInfo = QFileInfo(dialogOptions->initialDirectory().toLocalFile());
+ if (!fileInfo.isDir())
+ suggestedName = fileInfo.fileName();
+ }
if (!suggestedName.isEmpty()) {
HStringReference nativeSuggestedName(reinterpret_cast<const wchar_t *>(suggestedName.utf16()),
uint(suggestedName.length()));
diff --git a/src/plugins/platforms/xcb/gl_integrations/xcb_egl/qxcbeglcontext.h b/src/plugins/platforms/xcb/gl_integrations/xcb_egl/qxcbeglcontext.h
index c3ce8d8745..fda53f17a1 100644
--- a/src/plugins/platforms/xcb/gl_integrations/xcb_egl/qxcbeglcontext.h
+++ b/src/plugins/platforms/xcb/gl_integrations/xcb_egl/qxcbeglcontext.h
@@ -52,7 +52,7 @@ class QXcbEglContext : public QEGLPlatformContext
public:
QXcbEglContext(const QSurfaceFormat &glFormat, QPlatformOpenGLContext *share,
EGLDisplay display, const QVariant &nativeHandle)
- : QEGLPlatformContext(glFormat, share, display, 0, nativeHandle)
+ : QEGLPlatformContext(glFormat, share, display, nullptr, nativeHandle)
{
}
diff --git a/src/plugins/platforms/xcb/gl_integrations/xcb_egl/qxcbeglwindow.cpp b/src/plugins/platforms/xcb/gl_integrations/xcb_egl/qxcbeglwindow.cpp
index 65beac227c..30e3381993 100644
--- a/src/plugins/platforms/xcb/gl_integrations/xcb_egl/qxcbeglwindow.cpp
+++ b/src/plugins/platforms/xcb/gl_integrations/xcb_egl/qxcbeglwindow.cpp
@@ -93,7 +93,7 @@ void QXcbEglWindow::create()
{
QXcbWindow::create();
- m_surface = eglCreateWindowSurface(m_glIntegration->eglDisplay(), m_config, m_window, 0);
+ m_surface = eglCreateWindowSurface(m_glIntegration->eglDisplay(), m_config, m_window, nullptr);
}
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/xcb/gl_integrations/xcb_glx/qglxintegration.cpp b/src/plugins/platforms/xcb/gl_integrations/xcb_glx/qglxintegration.cpp
index 2b77062b16..75189a9c80 100644
--- a/src/plugins/platforms/xcb/gl_integrations/xcb_glx/qglxintegration.cpp
+++ b/src/plugins/platforms/xcb/gl_integrations/xcb_glx/qglxintegration.cpp
@@ -223,13 +223,13 @@ QGLXContext::QGLXContext(QXcbScreen *screen, const QSurfaceFormat &format, QPlat
const QVariant &nativeHandle)
: QPlatformOpenGLContext()
, m_display(static_cast<Display *>(screen->connection()->xlib_display()))
- , m_config(0)
- , m_context(0)
- , m_shareContext(0)
+ , m_config(nullptr)
+ , m_context(nullptr)
+ , m_shareContext(nullptr)
, m_format(format)
, m_isPBufferCurrent(false)
, m_ownsContext(nativeHandle.isNull())
- , m_getGraphicsResetStatus(0)
+ , m_getGraphicsResetStatus(nullptr)
, m_lost(false)
{
if (nativeHandle.isNull())
@@ -254,14 +254,14 @@ void QGLXContext::init(QXcbScreen *screen, QPlatformOpenGLContext *share)
GLXFBConfig config = qglx_findConfig(m_display, screen->screenNumber(), m_format);
m_config = config;
- XVisualInfo *visualInfo = 0;
+ XVisualInfo *visualInfo = nullptr;
Window window = 0; // Temporary window used to query OpenGL context
if (config) {
const QByteArrayList glxExt = QByteArray(glXQueryExtensionsString(m_display, screen->screenNumber())).split(' ');
// Resolve entry point for glXCreateContextAttribsARB
- glXCreateContextAttribsARBProc glXCreateContextAttribsARB = 0;
+ glXCreateContextAttribsARBProc glXCreateContextAttribsARB = nullptr;
if (glxExt.contains("GLX_ARB_create_context"))
glXCreateContextAttribsARB = (glXCreateContextAttribsARBProc) glXGetProcAddress((const GLubyte*)"glXCreateContextAttribsARB");
@@ -271,7 +271,7 @@ void QGLXContext::init(QXcbScreen *screen, QPlatformOpenGLContext *share)
// Use glXCreateContextAttribsARB if available
// Also, GL ES context creation requires GLX_EXT_create_context_es2_profile
- if (glXCreateContextAttribsARB != 0
+ if (glXCreateContextAttribsARB != nullptr
&& (m_format.renderableType() != QSurfaceFormat::OpenGLES || (supportsProfiles && glxExt.contains("GLX_EXT_create_context_es2_profile")))) {
// Try to create an OpenGL context for each known OpenGL version in descending
// order from the requested version.
@@ -358,9 +358,9 @@ void QGLXContext::init(QXcbScreen *screen, QPlatformOpenGLContext *share)
m_context = glXCreateContextAttribsARB(m_display, config, m_shareContext, true, contextAttributes.data());
if (!m_context && m_shareContext) {
// re-try without a shared glx context
- m_context = glXCreateContextAttribsARB(m_display, config, 0, true, contextAttributes.data());
+ m_context = glXCreateContextAttribsARB(m_display, config, nullptr, true, contextAttributes.data());
if (m_context)
- m_shareContext = 0;
+ m_shareContext = nullptr;
}
}
}
@@ -375,9 +375,9 @@ void QGLXContext::init(QXcbScreen *screen, QPlatformOpenGLContext *share)
m_context = glXCreateNewContext(m_display, config, GLX_RGBA_TYPE, m_shareContext, true);
if (!m_context && m_shareContext) {
// re-try without a shared glx context
- m_context = glXCreateNewContext(m_display, config, GLX_RGBA_TYPE, 0, true);
+ m_context = glXCreateNewContext(m_display, config, GLX_RGBA_TYPE, nullptr, true);
if (m_context)
- m_shareContext = 0;
+ m_shareContext = nullptr;
}
}
@@ -399,7 +399,7 @@ void QGLXContext::init(QXcbScreen *screen, QPlatformOpenGLContext *share)
m_context = glXCreateContext(m_display, visualInfo, m_shareContext, true);
if (!m_context && m_shareContext) {
// re-try without a shared glx context
- m_shareContext = 0;
+ m_shareContext = nullptr;
m_context = glXCreateContext(m_display, visualInfo, nullptr, true);
}
@@ -429,7 +429,7 @@ void QGLXContext::init(QXcbScreen *screen, QPlatformOpenGLContext *share, const
qWarning("QGLXContext: Requires a QGLXNativeContext");
return;
}
- QGLXNativeContext handle = nativeHandle.value<QGLXNativeContext>();
+ QGLXNativeContext handle = qvariant_cast<QGLXNativeContext>(nativeHandle);
GLXContext context = handle.context();
if (!context) {
qWarning("QGLXContext: No GLXContext given");
@@ -444,7 +444,7 @@ void QGLXContext::init(QXcbScreen *screen, QPlatformOpenGLContext *share, const
// Legacy contexts created using glXCreateContext are created using a visual
// and the FBConfig cannot be queried. The only way to adapt these contexts
// is to figure out the visual id.
- XVisualInfo *vinfo = 0;
+ XVisualInfo *vinfo = nullptr;
// If the VisualID is provided use it.
VisualID vid = handle.visualId();
if (!vid) {
@@ -464,13 +464,13 @@ void QGLXContext::init(QXcbScreen *screen, QPlatformOpenGLContext *share, const
vinfo = XGetVisualInfo(dpy, VisualScreenMask | VisualIDMask, &v, &n);
if (n < 1) {
XFree(vinfo);
- vinfo = 0;
+ vinfo = nullptr;
}
}
// For contexts created with an FBConfig using the modern functions providing the
// visual or window is not mandatory. Just query the config from the context.
- GLXFBConfig config = 0;
+ GLXFBConfig config = nullptr;
if (!vinfo) {
int configId = 0;
if (glXQueryContext(dpy, context, GLX_FBCONFIG_ID, &configId) != Success) {
@@ -595,8 +595,8 @@ bool QGLXContext::makeCurrent(QPlatformSurface *surface)
if (interval >= 0 && interval != window->swapInterval() && screen) {
typedef void (*qt_glXSwapIntervalEXT)(Display *, GLXDrawable, int);
typedef void (*qt_glXSwapIntervalMESA)(unsigned int);
- static qt_glXSwapIntervalEXT glXSwapIntervalEXT = 0;
- static qt_glXSwapIntervalMESA glXSwapIntervalMESA = 0;
+ static qt_glXSwapIntervalEXT glXSwapIntervalEXT = nullptr;
+ static qt_glXSwapIntervalMESA glXSwapIntervalMESA = nullptr;
static bool resolved = false;
if (!resolved) {
resolved = true;
@@ -621,9 +621,9 @@ bool QGLXContext::makeCurrent(QPlatformSurface *surface)
void QGLXContext::doneCurrent()
{
if (m_isPBufferCurrent)
- glXMakeContextCurrent(m_display, 0, 0, 0);
+ glXMakeContextCurrent(m_display, 0, 0, nullptr);
else
- glXMakeCurrent(m_display, 0, 0);
+ glXMakeCurrent(m_display, 0, nullptr);
m_isPBufferCurrent = false;
}
@@ -658,12 +658,12 @@ QSurfaceFormat QGLXContext::format() const
bool QGLXContext::isSharing() const
{
- return m_shareContext != 0;
+ return m_shareContext != nullptr;
}
bool QGLXContext::isValid() const
{
- return m_context != 0 && !m_lost;
+ return m_context != nullptr && !m_lost;
}
bool QGLXContext::m_queriedDummyContext = false;
@@ -675,7 +675,7 @@ bool QGLXContext::m_supportsThreading = true;
// binary search.
static const char *qglx_threadedgl_blacklist_renderer[] = {
"Chromium", // QTBUG-32225 (initialization fails)
- 0
+ nullptr
};
static const char *qglx_threadedgl_blacklist_vendor[] = {
@@ -695,7 +695,7 @@ void QGLXContext::queryDummyContext()
return;
QOpenGLContext *oldContext = QOpenGLContext::currentContext();
- QSurface *oldSurface = 0;
+ QSurface *oldSurface = nullptr;
if (oldContext)
oldSurface = oldContext->surface();
@@ -732,7 +732,7 @@ void QGLXContext::queryDummyContext()
if (const char *renderer = (const char *) glGetString(GL_RENDERER)) {
for (int i = 0; qglx_threadedgl_blacklist_renderer[i]; ++i) {
- if (strstr(renderer, qglx_threadedgl_blacklist_renderer[i]) != 0) {
+ if (strstr(renderer, qglx_threadedgl_blacklist_renderer[i]) != nullptr) {
qCDebug(lcQpaGl).nospace() << "Multithreaded OpenGL disabled: "
"blacklisted renderer \""
<< qglx_threadedgl_blacklist_renderer[i]
@@ -744,7 +744,7 @@ void QGLXContext::queryDummyContext()
}
if (const char *vendor = (const char *) glGetString(GL_VENDOR)) {
for (int i = 0; qglx_threadedgl_blacklist_vendor[i]; ++i) {
- if (strstr(vendor, qglx_threadedgl_blacklist_vendor[i]) != 0) {
+ if (strstr(vendor, qglx_threadedgl_blacklist_vendor[i]) != nullptr) {
qCDebug(lcQpaGl).nospace() << "Multithreaded OpenGL disabled: "
"blacklisted vendor \""
<< qglx_threadedgl_blacklist_vendor[i]
@@ -759,7 +759,7 @@ void QGLXContext::queryDummyContext()
// Blacklist Mesa drivers due to QTCREATORBUG-10875 (crash in creator),
// QTBUG-34492 (flickering in fullscreen) and QTBUG-38221
const char *mesaVersionStr = nullptr;
- if (strstr(glxvendor, "Mesa Project") != 0) {
+ if (strstr(glxvendor, "Mesa Project") != nullptr) {
mesaVersionStr = (const char *) glGetString(GL_VERSION);
m_supportsThreading = false;
}
diff --git a/src/plugins/platforms/xcb/gl_integrations/xcb_glx/qxcbglxintegration.cpp b/src/plugins/platforms/xcb/gl_integrations/xcb_glx/qxcbglxintegration.cpp
index 34895caaa2..6814dbd844 100644
--- a/src/plugins/platforms/xcb/gl_integrations/xcb_glx/qxcbglxintegration.cpp
+++ b/src/plugins/platforms/xcb/gl_integrations/xcb_glx/qxcbglxintegration.cpp
@@ -133,7 +133,7 @@ bool QXcbGlxIntegration::handleXcbEvent(xcb_generic_event_t *event, uint respons
Display *xdisplay = static_cast<Display *>(m_connection->xlib_display());
XLockDisplay(xdisplay);
bool locked = true;
- Bool (*proc)(Display*, XEvent*, xEvent*) = XESetWireToEvent(xdisplay, responseType, 0);
+ Bool (*proc)(Display*, XEvent*, xEvent*) = XESetWireToEvent(xdisplay, responseType, nullptr);
if (proc) {
XESetWireToEvent(xdisplay, responseType, proc);
XEvent dummy;
@@ -212,7 +212,7 @@ QPlatformOffscreenSurface *QXcbGlxIntegration::createPlatformOffscreenSurface(QO
if (glxPbufferUsable)
return new QGLXPbuffer(surface);
else
- return 0; // trigger fallback to hidden QWindow
+ return nullptr; // trigger fallback to hidden QWindow
}
diff --git a/src/plugins/platforms/xcb/qxcbatom.cpp b/src/plugins/platforms/xcb/qxcbatom.cpp
index d366564dd6..ff5c50b702 100644
--- a/src/plugins/platforms/xcb/qxcbatom.cpp
+++ b/src/plugins/platforms/xcb/qxcbatom.cpp
@@ -266,7 +266,7 @@ void QXcbAtom::initializeAllAtoms(xcb_connection_t *connection) {
cookies[i] = xcb_intern_atom(connection, false, strlen(names[i]), names[i]);
for (i = 0; i < QXcbAtom::NAtoms; ++i) {
- xcb_intern_atom_reply_t *reply = xcb_intern_atom_reply(connection, cookies[i], 0);
+ xcb_intern_atom_reply_t *reply = xcb_intern_atom_reply(connection, cookies[i], nullptr);
m_allAtoms[i] = reply->atom;
free(reply);
}
diff --git a/src/plugins/platforms/xcb/qxcbbackingstore.cpp b/src/plugins/platforms/xcb/qxcbbackingstore.cpp
index 741317d766..8f55bc2e96 100644
--- a/src/plugins/platforms/xcb/qxcbbackingstore.cpp
+++ b/src/plugins/platforms/xcb/qxcbbackingstore.cpp
@@ -229,7 +229,7 @@ void QXcbBackingStoreImage::resize(const QSize &size)
m_xcb_format->bits_per_pixel,
0, byteOrder,
XCB_IMAGE_ORDER_MSB_FIRST,
- 0, ~0, 0);
+ nullptr, ~0, nullptr);
const size_t segmentSize = imageDataSize(m_xcb_image);
@@ -412,13 +412,13 @@ bool QXcbBackingStoreImage::createSystemVShmSegment(xcb_connection_t *c, size_t
return false;
}
- void *addr = shmat(id, 0, 0);
+ void *addr = shmat(id, nullptr, 0);
if (addr == (void *)-1) {
qCWarning(lcQpaXcb, "shmat() failed (%d: %s) for id %d", errno, strerror(errno), id);
return false;
}
- if (shmctl(id, IPC_RMID, 0) == -1)
+ if (shmctl(id, IPC_RMID, nullptr) == -1)
qCWarning(lcQpaXcb, "Error while marking the shared memory segment to be destroyed");
const auto seg = xcb_generate_id(c);
@@ -780,7 +780,7 @@ QXcbBackingStore::~QXcbBackingStore()
QPaintDevice *QXcbBackingStore::paintDevice()
{
if (!m_image)
- return 0;
+ return nullptr;
return m_rgbImage.isNull() ? m_image->image() : &m_rgbImage;
}
@@ -1036,7 +1036,7 @@ void QXcbSystemTrayBackingStore::recreateImage(QXcbWindow *win, const QSize &siz
xcb_create_pixmap(xcb_connection(), 32, m_xrenderPixmap, screen->root(), size.width(), size.height());
m_xrenderPicture = xcb_generate_id(xcb_connection());
- xcb_render_create_picture(xcb_connection(), m_xrenderPicture, m_xrenderPixmap, m_xrenderPictFormat, 0, 0);
+ xcb_render_create_picture(xcb_connection(), m_xrenderPicture, m_xrenderPixmap, m_xrenderPictFormat, 0, nullptr);
// XRender expects premultiplied alpha
if (m_image)
@@ -1077,7 +1077,7 @@ void QXcbSystemTrayBackingStore::initXRenderMode()
m_windowPicture = xcb_generate_id(conn);
xcb_void_cookie_t cookie =
- xcb_render_create_picture_checked(conn, m_windowPicture, platformWindow->xcb_window(), vfmt->format, 0, 0);
+ xcb_render_create_picture_checked(conn, m_windowPicture, platformWindow->xcb_window(), vfmt->format, 0, nullptr);
xcb_generic_error_t *error = xcb_request_check(conn, cookie);
if (error) {
qWarning("QXcbSystemTrayBackingStore: Failed to create Picture with format %x for window %x, error code %d",
diff --git a/src/plugins/platforms/xcb/qxcbclipboard.cpp b/src/plugins/platforms/xcb/qxcbclipboard.cpp
index 2cb6720d40..fe9ddfece7 100644
--- a/src/plugins/platforms/xcb/qxcbclipboard.cpp
+++ b/src/plugins/platforms/xcb/qxcbclipboard.cpp
@@ -123,8 +123,9 @@ protected:
return list.contains(format);
}
- QVariant retrieveData_sys(const QString &fmt, QVariant::Type requestedType) const override
+ QVariant retrieveData_sys(const QString &fmt, QVariant::Type type) const override
{
+ auto requestedType = QMetaType::Type(type);
if (fmt.isEmpty() || isEmpty())
return QByteArray();
@@ -226,8 +227,8 @@ QXcbClipboard::QXcbClipboard(QXcbConnection *c)
{
Q_ASSERT(QClipboard::Clipboard == 0);
Q_ASSERT(QClipboard::Selection == 1);
- m_clientClipboard[QClipboard::Clipboard] = 0;
- m_clientClipboard[QClipboard::Selection] = 0;
+ m_clientClipboard[QClipboard::Clipboard] = nullptr;
+ m_clientClipboard[QClipboard::Selection] = nullptr;
m_timestamp[QClipboard::Clipboard] = XCB_CURRENT_TIME;
m_timestamp[QClipboard::Selection] = XCB_CURRENT_TIME;
m_owner = connection()->getQtSelectionOwner();
@@ -316,7 +317,7 @@ QClipboard::Mode QXcbClipboard::modeForAtom(xcb_atom_t a) const
QMimeData * QXcbClipboard::mimeData(QClipboard::Mode mode)
{
if (mode > QClipboard::Selection)
- return 0;
+ return nullptr;
xcb_window_t clipboardOwner = getSelectionOwner(atomForMode(mode));
if (clipboardOwner == owner()) {
@@ -334,7 +335,7 @@ void QXcbClipboard::setMimeData(QMimeData *data, QClipboard::Mode mode)
if (mode > QClipboard::Selection)
return;
- QXcbClipboardMime *xClipboard = 0;
+ QXcbClipboardMime *xClipboard = nullptr;
// verify if there is data to be cleared on global X Clipboard.
if (!data) {
xClipboard = qobject_cast<QXcbClipboardMime *>(mimeData(mode));
@@ -353,7 +354,7 @@ void QXcbClipboard::setMimeData(QMimeData *data, QClipboard::Mode mode)
if (m_clientClipboard[mode]) {
if (m_clientClipboard[QClipboard::Clipboard] != m_clientClipboard[QClipboard::Selection])
delete m_clientClipboard[mode];
- m_clientClipboard[mode] = 0;
+ m_clientClipboard[mode] = nullptr;
m_timestamp[mode] = XCB_CURRENT_TIME;
}
@@ -416,7 +417,7 @@ xcb_window_t QXcbClipboard::requestor() const
XCB_WINDOW_CLASS_INPUT_OUTPUT, // window class
platformScreen->screen()->root_visual, // visual
0, // value mask
- 0); // value list
+ nullptr); // value list
QXcbWindow::setWindowTitle(connection(), window,
QStringLiteral("Qt Clipboard Requestor Window"));
@@ -529,7 +530,7 @@ void QXcbClipboard::handleSelectionClearRequest(xcb_selection_clear_event_t *eve
if (newOwner != XCB_NONE) {
if (m_clientClipboard[QClipboard::Clipboard] != m_clientClipboard[QClipboard::Selection])
delete m_clientClipboard[mode];
- m_clientClipboard[mode] = 0;
+ m_clientClipboard[mode] = nullptr;
m_timestamp[mode] = XCB_CURRENT_TIME;
}
}
@@ -576,7 +577,7 @@ void QXcbClipboard::handleSelectionRequest(xcb_selection_request_event_t *req)
xcb_atom_t multipleAtom = atom(QXcbAtom::MULTIPLE);
xcb_atom_t timestampAtom = atom(QXcbAtom::TIMESTAMP);
- struct AtomPair { xcb_atom_t target; xcb_atom_t property; } *multi = 0;
+ struct AtomPair { xcb_atom_t target; xcb_atom_t property; } *multi = nullptr;
xcb_atom_t multi_type = XCB_NONE;
int multi_format = 0;
int nmulti = 0;
@@ -587,7 +588,7 @@ void QXcbClipboard::handleSelectionRequest(xcb_selection_request_event_t *req)
QByteArray multi_data;
if (req->property == XCB_NONE
|| !clipboardReadProperty(req->requestor, req->property, false, &multi_data,
- 0, &multi_type, &multi_format)
+ nullptr, &multi_type, &multi_format)
|| multi_format != 32) {
// MULTIPLE property not formatted correctly
xcb_send_event(xcb_connection(), false, req->requestor, XCB_EVENT_MASK_NO_EVENT, (const char *)&event);
@@ -842,7 +843,7 @@ QByteArray QXcbClipboard::clipboardReadIncrementalProperty(xcb_window_t win, xcb
continue;
prev_time = event->time;
- if (clipboardReadProperty(win, property, true, &tmp_buf, &length, 0, 0)) {
+ if (clipboardReadProperty(win, property, true, &tmp_buf, &length, nullptr, nullptr)) {
if (length == 0) { // no more data, we're done
if (nullterm) {
buf.resize(offset+1);
@@ -900,7 +901,7 @@ QByteArray QXcbClipboard::getSelection(xcb_atom_t selection, xcb_atom_t target,
return buf;
xcb_atom_t type;
- if (clipboardReadProperty(win, property, true, &buf, 0, &type, 0)) {
+ if (clipboardReadProperty(win, property, true, &buf, nullptr, &type, nullptr)) {
if (type == atom(QXcbAtom::INCR)) {
int nbytes = buf.size() >= 4 ? *((int*)buf.data()) : 0;
buf = clipboardReadIncrementalProperty(win, property, nbytes, false);
diff --git a/src/plugins/platforms/xcb/qxcbconnection.cpp b/src/plugins/platforms/xcb/qxcbconnection.cpp
index cac6345b66..435c4aee93 100644
--- a/src/plugins/platforms/xcb/qxcbconnection.cpp
+++ b/src/plugins/platforms/xcb/qxcbconnection.cpp
@@ -66,14 +66,10 @@
#include <errno.h>
#include <xcb/xfixes.h>
-#if QT_CONFIG(xkb)
#define explicit dont_use_cxx_explicit
#include <xcb/xkb.h>
#undef explicit
-#endif
-#if QT_CONFIG(xcb_xinput)
#include <xcb/xinput.h>
-#endif
QT_BEGIN_NAMESPACE
@@ -88,12 +84,6 @@ Q_LOGGING_CATEGORY(lcQpaKeyboard, "qt.qpa.xkeyboard")
Q_LOGGING_CATEGORY(lcQpaClipboard, "qt.qpa.clipboard")
Q_LOGGING_CATEGORY(lcQpaXDnd, "qt.qpa.xdnd")
-// this event type was added in libxcb 1.10,
-// but we support also older version
-#ifndef XCB_GE_GENERIC
-#define XCB_GE_GENERIC 35
-#endif
-
QXcbConnection::QXcbConnection(QXcbNativeInterface *nativeInterface, bool canGrabServer, xcb_visualid_t defaultVisualId, const char *displayName)
: QXcbBasicConnection(displayName)
, m_canGrabServer(canGrabServer)
@@ -112,12 +102,10 @@ QXcbConnection::QXcbConnection(QXcbNativeInterface *nativeInterface, bool canGra
initializeScreens();
-#if QT_CONFIG(xcb_xinput)
if (hasXInput2()) {
xi2SetupDevices();
xi2SelectStateEvents();
}
-#endif
m_wmSupport.reset(new QXcbWMSupport(this));
m_keyboard = new QXcbKeyboard(this);
@@ -196,7 +184,7 @@ QXcbWindow *QXcbConnection::platformWindowFromId(xcb_window_t id)
QXcbWindowEventListener *listener = m_mapper.value(id, 0);
if (listener)
return listener->toWindow();
- return 0;
+ return nullptr;
}
#define HANDLE_PLATFORM_WINDOW_EVENT(event_t, windowMember, handler) \
@@ -467,7 +455,7 @@ void QXcbConnection::printXcbError(const char *message, xcb_generic_error_t *err
static Qt::MouseButtons translateMouseButtons(int s)
{
- Qt::MouseButtons ret = 0;
+ Qt::MouseButtons ret;
if (s & XCB_BUTTON_MASK_1)
ret |= Qt::LeftButton;
if (s & XCB_BUTTON_MASK_2)
@@ -518,7 +506,6 @@ Qt::MouseButton QXcbConnection::translateMouseButton(xcb_button_t s)
}
}
-#if QT_CONFIG(xkb)
namespace {
typedef union {
/* All XKB events share these fields. */
@@ -534,7 +521,6 @@ namespace {
xcb_xkb_state_notify_event_t state_notify;
} _xkb_event;
}
-#endif
void QXcbConnection::handleXcbEvent(xcb_generic_event_t *event)
{
@@ -611,16 +597,12 @@ void QXcbConnection::handleXcbEvent(xcb_generic_event_t *event)
HANDLE_PLATFORM_WINDOW_EVENT(xcb_client_message_event_t, window, handleClientMessageEvent);
}
case XCB_ENTER_NOTIFY:
-#if QT_CONFIG(xcb_xinput)
if (hasXInput2() && !xi2MouseEventsDisabled())
break;
-#endif
HANDLE_PLATFORM_WINDOW_EVENT(xcb_enter_notify_event_t, event, handleEnterNotifyEvent);
case XCB_LEAVE_NOTIFY:
-#if QT_CONFIG(xcb_xinput)
if (hasXInput2() && !xi2MouseEventsDisabled())
break;
-#endif
m_keyboard->updateXKBStateFromCore(reinterpret_cast<xcb_leave_notify_event_t *>(event)->state);
HANDLE_PLATFORM_WINDOW_EVENT(xcb_leave_notify_event_t, event, handleLeaveNotifyEvent);
case XCB_FOCUS_IN:
@@ -682,13 +664,11 @@ void QXcbConnection::handleXcbEvent(xcb_generic_event_t *event)
}
break;
}
-#if QT_CONFIG(xcb_xinput)
case XCB_GE_GENERIC:
// Here the windowEventListener is invoked from xi2HandleEvent()
if (hasXInput2() && isXIEvent(event))
xi2HandleEvent(reinterpret_cast<xcb_ge_event_t *>(event));
break;
-#endif
default:
handled = false; // event type not recognized
break;
@@ -712,7 +692,6 @@ void QXcbConnection::handleXcbEvent(xcb_generic_event_t *event)
auto change_event = reinterpret_cast<xcb_randr_screen_change_notify_event_t *>(event);
if (auto virtualDesktop = virtualDesktopForRootWindow(change_event->root))
virtualDesktop->handleScreenChange(change_event);
-#if QT_CONFIG(xkb)
} else if (isXkbType(response_type)) {
auto xkb_event = reinterpret_cast<_xkb_event *>(event);
if (xkb_event->any.deviceID == m_keyboard->coreDeviceId()) {
@@ -735,7 +714,6 @@ void QXcbConnection::handleXcbEvent(xcb_generic_event_t *event)
break;
}
}
-#endif
} else {
handled = false; // event type still not recognized
}
@@ -825,7 +803,7 @@ xcb_window_t QXcbConnection::getQtSelectionOwner()
XCB_WINDOW_CLASS_INPUT_OUTPUT, // window class
xcbScreen->root_visual, // visual
0, // value mask
- 0); // value list
+ nullptr); // value list
QXcbWindow::setWindowTitle(connection(), m_qtSelectionOwner,
QLatin1String("Qt Selection Owner for ") + QCoreApplication::applicationName());
@@ -852,7 +830,7 @@ xcb_window_t QXcbConnection::clientLeader()
0,
XCB_WINDOW_CLASS_INPUT_OUTPUT,
screen->screen()->root_visual,
- 0, 0);
+ 0, nullptr);
QXcbWindow::setWindowTitle(connection(), m_clientLeader,
@@ -912,7 +890,6 @@ bool QXcbConnection::compressEvent(xcb_generic_event_t *event) const
});
}
-#if QT_CONFIG(xcb_xinput)
// compress XI_* events
if (responseType == XCB_GE_GENERIC) {
if (!hasXInput2())
@@ -948,7 +925,6 @@ bool QXcbConnection::compressEvent(xcb_generic_event_t *event) const
return false;
}
-#endif
if (responseType == XCB_CONFIGURE_NOTIFY) {
// compress multiple configure notify events for the same window
@@ -978,7 +954,6 @@ bool QXcbConnection::isUserInputEvent(xcb_generic_event_t *event) const
if (isInputEvent)
return true;
-#if QT_CONFIG(xcb_xinput)
if (connection()->hasXInput2()) {
isInputEvent = isXIType(event, XCB_INPUT_BUTTON_PRESS) ||
isXIType(event, XCB_INPUT_BUTTON_RELEASE) ||
@@ -993,7 +968,6 @@ bool QXcbConnection::isUserInputEvent(xcb_generic_event_t *event) const
}
if (isInputEvent)
return true;
-#endif
if (eventType == XCB_CLIENT_MESSAGE) {
auto clientMessage = reinterpret_cast<const xcb_client_message_event_t *>(event);
@@ -1057,7 +1031,7 @@ void QXcbConnection::sync()
{
// from xcb_aux_sync
xcb_get_input_focus_cookie_t cookie = xcb_get_input_focus(xcb_connection());
- free(xcb_get_input_focus_reply(xcb_connection(), cookie, 0));
+ free(xcb_get_input_focus_reply(xcb_connection(), cookie, nullptr));
}
QXcbSystemTrayTracker *QXcbConnection::systemTrayTracker() const
@@ -1075,14 +1049,14 @@ QXcbSystemTrayTracker *QXcbConnection::systemTrayTracker() const
Qt::MouseButtons QXcbConnection::queryMouseButtons() const
{
int stateMask = 0;
- QXcbCursor::queryPointer(connection(), 0, 0, &stateMask);
+ QXcbCursor::queryPointer(connection(), nullptr, nullptr, &stateMask);
return translateMouseButtons(stateMask);
}
Qt::KeyboardModifiers QXcbConnection::queryKeyboardModifiers() const
{
int stateMask = 0;
- QXcbCursor::queryPointer(connection(), 0, 0, &stateMask);
+ QXcbCursor::queryPointer(connection(), nullptr, nullptr, &stateMask);
return keyboard()->translateModifiers(stateMask);
}
@@ -1140,7 +1114,7 @@ void QXcbSyncWindowRequest::invalidate()
{
if (m_window) {
m_window->clearSyncWindowRequest();
- m_window = 0;
+ m_window = nullptr;
}
}
@@ -1160,7 +1134,7 @@ void QXcbConnectionGrabber::release()
{
if (m_connection) {
m_connection->ungrabServer();
- m_connection = 0;
+ m_connection = nullptr;
}
}
diff --git a/src/plugins/platforms/xcb/qxcbconnection.h b/src/plugins/platforms/xcb/qxcbconnection.h
index 7cf25d41a6..8a4b577d2e 100644
--- a/src/plugins/platforms/xcb/qxcbconnection.h
+++ b/src/plugins/platforms/xcb/qxcbconnection.h
@@ -104,10 +104,8 @@ public:
virtual void handleFocusInEvent(const xcb_focus_in_event_t *) {}
virtual void handleFocusOutEvent(const xcb_focus_out_event_t *) {}
virtual void handlePropertyNotifyEvent(const xcb_property_notify_event_t *) {}
-#if QT_CONFIG(xcb_xinput)
virtual void handleXIMouseEvent(xcb_ge_event_t *, Qt::MouseEventSource = Qt::MouseEventNotSynthesized) {}
virtual void handleXIEnterLeave(xcb_ge_event_t *) {}
-#endif
virtual QXcbWindow *toWindow() { return nullptr; }
};
@@ -129,7 +127,7 @@ class Q_XCB_EXPORT QXcbConnection : public QXcbBasicConnection
{
Q_OBJECT
public:
- QXcbConnection(QXcbNativeInterface *nativeInterface, bool canGrabServer, xcb_visualid_t defaultVisualId, const char *displayName = 0);
+ QXcbConnection(QXcbNativeInterface *nativeInterface, bool canGrabServer, xcb_visualid_t defaultVisualId, const char *displayName = nullptr);
~QXcbConnection();
QXcbConnection *connection() const { return const_cast<QXcbConnection *>(this); }
@@ -225,7 +223,6 @@ public:
bool isUserInputEvent(xcb_generic_event_t *event) const;
-#if QT_CONFIG(xcb_xinput)
void xi2SelectStateEvents();
void xi2SelectDeviceEvents(xcb_window_t window);
void xi2SelectDeviceEventsCompatibility(xcb_window_t window);
@@ -233,10 +230,9 @@ public:
bool xi2MouseEventsDisabled() const;
Qt::MouseButton xiToQtMouseButton(uint32_t b);
void xi2UpdateScrollingDevices();
- bool startSystemMoveResizeForTouchBegin(xcb_window_t window, const QPoint &point, int corner);
+ bool startSystemMoveResizeForTouch(xcb_window_t window, int edges);
void abortSystemMoveResizeForTouch();
bool isTouchScreen(int id);
-#endif
bool canGrab() const { return m_canGrabServer; }
@@ -267,7 +263,6 @@ private:
inline bool timeGreaterThan(xcb_timestamp_t a, xcb_timestamp_t b) const
{ return static_cast<int32_t>(a - b) > 0 || b == XCB_CURRENT_TIME; }
-#if QT_CONFIG(xcb_xinput)
void xi2SetupDevice(void *info, bool removeExisting = true);
void xi2SetupDevices();
struct TouchDeviceData {
@@ -299,7 +294,7 @@ private:
int deviceId = 0;
QTabletEvent::PointerType pointerType = QTabletEvent::UnknownPointer;
QTabletEvent::TabletDevice tool = QTabletEvent::Stylus;
- Qt::MouseButtons buttons = 0;
+ Qt::MouseButtons buttons;
qint64 serialId = 0;
bool inProximity = false;
struct ValuatorClassInfo {
@@ -323,8 +318,8 @@ private:
int horizontalIndex = 0;
double verticalIncrement = 0;
double horizontalIncrement = 0;
- Qt::Orientations orientations = 0;
- Qt::Orientations legacyOrientations = 0;
+ Qt::Orientations orientations;
+ Qt::Orientations legacyOrientations;
QPointF lastScrollPosition;
};
QHash<int, ScrollingDevice> m_scrollingDevices;
@@ -339,9 +334,8 @@ private:
xcb_window_t window = XCB_NONE;
uint16_t deviceid;
uint32_t pointid;
- int corner;
+ int edges;
} m_startSystemMoveResizeInfo;
-#endif // QT_CONFIG(xcb_xinput)
const bool m_canGrabServer;
const xcb_visualid_t m_defaultVisualId;
@@ -366,7 +360,7 @@ private:
WindowMapper m_mapper;
- Qt::MouseButtons m_buttonState = nullptr;
+ Qt::MouseButtons m_buttonState;
Qt::MouseButton m_button = Qt::NoButton;
QXcbWindow *m_focusWindow = nullptr;
@@ -389,12 +383,10 @@ private:
QTimer m_focusInTimer;
};
-#if QT_CONFIG(xcb_xinput)
#if QT_CONFIG(tabletevent)
Q_DECLARE_TYPEINFO(QXcbConnection::TabletData::ValuatorClassInfo, Q_PRIMITIVE_TYPE);
Q_DECLARE_TYPEINFO(QXcbConnection::TabletData, Q_MOVABLE_TYPE);
#endif
-#endif
class QXcbConnectionGrabber
{
diff --git a/src/plugins/platforms/xcb/qxcbconnection_basic.cpp b/src/plugins/platforms/xcb/qxcbconnection_basic.cpp
index 9a028e5a7e..18dee89adb 100644
--- a/src/plugins/platforms/xcb/qxcbconnection_basic.cpp
+++ b/src/plugins/platforms/xcb/qxcbconnection_basic.cpp
@@ -45,14 +45,10 @@
#include <xcb/xfixes.h>
#include <xcb/xinerama.h>
#include <xcb/render.h>
-#if QT_CONFIG(xcb_xinput)
#include <xcb/xinput.h>
-#endif
-#if QT_CONFIG(xkb)
#define explicit dont_use_cxx_explicit
#include <xcb/xkb.h>
#undef explicit
-#endif
#if QT_CONFIG(xcb_xlib)
#define register /* C++17 deprecated register */
@@ -97,7 +93,7 @@ static int nullErrorHandler(Display *dpy, XErrorEvent *err)
static int ioErrorHandler(Display *dpy)
{
xcb_connection_t *conn = XGetXCBConnection(dpy);
- if (conn != NULL) {
+ if (conn != nullptr) {
/* Print a message with a textual description of the error */
int code = xcb_connection_has_error(conn);
const char *str = "Unknown error";
@@ -138,14 +134,7 @@ QXcbBasicConnection::QXcbBasicConnection(const char *displayName)
xcb_extension_t *extensions[] = {
&xcb_shm_id, &xcb_xfixes_id, &xcb_randr_id, &xcb_shape_id, &xcb_sync_id,
- &xcb_render_id,
-#if QT_CONFIG(xkb)
- &xcb_xkb_id,
-#endif
-#if QT_CONFIG(xcb_xinput)
- &xcb_input_id,
-#endif
- 0
+ &xcb_render_id, &xcb_xkb_id, &xcb_input_id, nullptr
};
for (xcb_extension_t **ext_it = extensions; *ext_it; ++ext_it)
@@ -160,10 +149,8 @@ QXcbBasicConnection::QXcbBasicConnection(const char *displayName)
initializeXinerama();
initializeXFixes();
initializeXRender();
-#if QT_CONFIG(xcb_xinput)
if (!qEnvironmentVariableIsSet("QT_XCB_NO_XI2"))
initializeXInput2();
-#endif
initializeXShape();
initializeXKB();
}
@@ -213,7 +200,6 @@ bool QXcbBasicConnection::hasBigRequest() const
return m_maximumRequestLength > m_setup->maximum_request_length;
}
-#if QT_CONFIG(xcb_xinput)
// Starting from the xcb version 1.9.3 struct xcb_ge_event_t has changed:
// - "pad0" became "extension"
// - "pad1" and "pad" became "pad0"
@@ -240,7 +226,6 @@ bool QXcbBasicConnection::isXIType(xcb_generic_event_t *event, uint16_t type) co
auto *e = reinterpret_cast<qt_xcb_ge_event_t *>(event);
return e->event_type == type;
}
-#endif // QT_CONFIG(xcb_xinput)
bool QXcbBasicConnection::isXFixesType(uint responseType, int eventType) const
{
@@ -370,7 +355,6 @@ void QXcbBasicConnection::initializeXRandr()
m_xrandrFirstEvent = reply->first_event;
}
-#if QT_CONFIG(xcb_xinput)
void QXcbBasicConnection::initializeXInput2()
{
const xcb_query_extension_reply_t *reply = xcb_get_extension_data(m_xcbConnection, &xcb_input_id);
@@ -393,7 +377,6 @@ void QXcbBasicConnection::initializeXInput2()
m_xinputFirstEvent = reply->first_event;
m_xi2Minor = xinputQuery->minor_version;
}
-#endif
void QXcbBasicConnection::initializeXShape()
{
@@ -417,7 +400,6 @@ void QXcbBasicConnection::initializeXShape()
void QXcbBasicConnection::initializeXKB()
{
-#if QT_CONFIG(xkb)
const xcb_query_extension_reply_t *reply = xcb_get_extension_data(m_xcbConnection, &xcb_xkb_id);
if (!reply || !reply->present) {
qCWarning(lcQpaXcb, "XKeyboard extension not present on the X server");
@@ -439,7 +421,6 @@ void QXcbBasicConnection::initializeXKB()
m_hasXkb = true;
m_xkbFirstEvent = reply->first_event;
-#endif
}
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/xcb/qxcbconnection_basic.h b/src/plugins/platforms/xcb/qxcbconnection_basic.h
index 1bd4310562..109186f966 100644
--- a/src/plugins/platforms/xcb/qxcbconnection_basic.h
+++ b/src/plugins/platforms/xcb/qxcbconnection_basic.h
@@ -99,12 +99,10 @@ public:
bool hasXinerama() const { return m_hasXinerama; }
bool hasBigRequest() const;
-#if QT_CONFIG(xcb_xinput)
bool isAtLeastXI21() const { return m_xi2Enabled && m_xi2Minor >= 1; }
bool isAtLeastXI22() const { return m_xi2Enabled && m_xi2Minor >= 2; }
bool isXIEvent(xcb_generic_event_t *event) const;
bool isXIType(xcb_generic_event_t *event, uint16_t type) const;
-#endif
bool isXFixesType(uint responseType, int eventType) const;
bool isXRandrType(uint responseType, int eventType) const;
@@ -119,9 +117,7 @@ protected:
void initializeXShape();
void initializeXKB();
void initializeXSync();
-#if QT_CONFIG(xcb_xinput)
void initializeXInput2();
-#endif
private:
#if QT_CONFIG(xcb_xlib)
@@ -147,11 +143,9 @@ private:
QPair<int, int> m_xrenderVersion;
bool m_xi2Enabled = false;
-#if QT_CONFIG(xcb_xinput)
int m_xi2Minor = -1;
int m_xiOpCode = -1;
uint32_t m_xinputFirstEvent = 0;
-#endif
uint32_t m_xfixesFirstEvent = 0;
uint32_t m_xrandrFirstEvent = 0;
diff --git a/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp b/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp
index 0a82bbc7a9..27a2526df1 100644
--- a/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp
+++ b/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp
@@ -166,7 +166,7 @@ void QXcbConnection::xi2SetupDevice(void *info, bool removeExisting)
}
case XCB_INPUT_DEVICE_CLASS_TYPE_BUTTON: {
auto *bci = reinterpret_cast<xcb_input_button_class_t *>(classinfo);
- xcb_atom_t *labels = 0;
+ xcb_atom_t *labels = nullptr;
if (bci->num_buttons >= 5) {
labels = xcb_input_button_class_labels(bci);
xcb_atom_t label4 = labels[3];
@@ -424,7 +424,7 @@ QXcbConnection::TouchDeviceData *QXcbConnection::touchDeviceForId(int id)
QXcbConnection::TouchDeviceData *QXcbConnection::populateTouchDevices(void *info)
{
auto *deviceinfo = reinterpret_cast<xcb_input_xi_device_info_t *>(info);
- QTouchDevice::Capabilities caps = 0;
+ QTouchDevice::Capabilities caps;
int type = -1;
int maxTouchPoints = 1;
bool isTouchDevice = false;
@@ -514,12 +514,10 @@ QXcbConnection::TouchDeviceData *QXcbConnection::populateTouchDevices(void *info
return isTouchDevice ? &m_touchDevices[deviceinfo->deviceid] : nullptr;
}
-#if QT_CONFIG(tabletevent)
static inline qreal fixed1616ToReal(xcb_input_fp1616_t val)
{
return qreal(val) / 0x10000;
}
-#endif // QT_CONFIG(tabletevent)
void QXcbConnection::xi2HandleEvent(xcb_ge_event_t *event)
{
@@ -527,7 +525,7 @@ void QXcbConnection::xi2HandleEvent(xcb_ge_event_t *event)
int sourceDeviceId = xiEvent->deviceid; // may be the master id
qt_xcb_input_device_event_t *xiDeviceEvent = nullptr;
xcb_input_enter_event_t *xiEnterEvent = nullptr;
- QXcbWindowEventListener *eventListener = 0;
+ QXcbWindowEventListener *eventListener = nullptr;
switch (xiEvent->event_type) {
case XCB_INPUT_BUTTON_PRESS:
@@ -753,7 +751,7 @@ void QXcbConnection::xi2ProcessTouch(void *xiDevEvent, QXcbWindow *platformWindo
xcb_input_xi_allow_events(xcb_connection(), XCB_CURRENT_TIME, xiDeviceEvent->deviceid,
XCB_INPUT_EVENT_MODE_REJECT_TOUCH,
xiDeviceEvent->detail, xiDeviceEvent->event);
- window->doStartSystemMoveResize(QPoint(x, y), m_startSystemMoveResizeInfo.corner);
+ window->doStartSystemMoveResize(QPoint(x, y), m_startSystemMoveResizeInfo.edges);
m_startSystemMoveResizeInfo.window = XCB_NONE;
}
}
@@ -787,19 +785,20 @@ void QXcbConnection::xi2ProcessTouch(void *xiDevEvent, QXcbWindow *platformWindo
touchPoint.state = Qt::TouchPointStationary;
}
-bool QXcbConnection::startSystemMoveResizeForTouchBegin(xcb_window_t window, const QPoint &point, int corner)
+bool QXcbConnection::startSystemMoveResizeForTouch(xcb_window_t window, int edges)
{
QHash<int, TouchDeviceData>::const_iterator devIt = m_touchDevices.constBegin();
for (; devIt != m_touchDevices.constEnd(); ++devIt) {
TouchDeviceData deviceData = devIt.value();
if (deviceData.qtTouchDevice->type() == QTouchDevice::TouchScreen) {
- QHash<int, QPointF>::const_iterator pointIt = deviceData.pointPressedPosition.constBegin();
- for (; pointIt != deviceData.pointPressedPosition.constEnd(); ++pointIt) {
- if (pointIt.value().toPoint() == point) {
+ auto pointIt = deviceData.touchPoints.constBegin();
+ for (; pointIt != deviceData.touchPoints.constEnd(); ++pointIt) {
+ Qt::TouchPointState state = pointIt.value().state;
+ if (state == Qt::TouchPointMoved || state == Qt::TouchPointPressed || state == Qt::TouchPointStationary) {
m_startSystemMoveResizeInfo.window = window;
m_startSystemMoveResizeInfo.deviceid = devIt.key();
m_startSystemMoveResizeInfo.pointid = pointIt.key();
- m_startSystemMoveResizeInfo.corner = corner;
+ m_startSystemMoveResizeInfo.edges = edges;
return true;
}
}
diff --git a/src/plugins/platforms/xcb/qxcbcursor.cpp b/src/plugins/platforms/xcb/qxcbcursor.cpp
index fbadab4d50..639e4f039c 100644
--- a/src/plugins/platforms/xcb/qxcbcursor.cpp
+++ b/src/plugins/platforms/xcb/qxcbcursor.cpp
@@ -67,10 +67,10 @@ enum {
};
#undef CursorShape
-static PtrXcursorLibraryLoadCursor ptrXcursorLibraryLoadCursor = 0;
-static PtrXcursorLibraryGetTheme ptrXcursorLibraryGetTheme = 0;
-static PtrXcursorLibrarySetTheme ptrXcursorLibrarySetTheme = 0;
-static PtrXcursorLibraryGetDefaultSize ptrXcursorLibraryGetDefaultSize = 0;
+static PtrXcursorLibraryLoadCursor ptrXcursorLibraryLoadCursor = nullptr;
+static PtrXcursorLibraryGetTheme ptrXcursorLibraryGetTheme = nullptr;
+static PtrXcursorLibrarySetTheme ptrXcursorLibrarySetTheme = nullptr;
+static PtrXcursorLibraryGetDefaultSize ptrXcursorLibraryGetDefaultSize = nullptr;
#endif
static xcb_font_t cursorFont = 0;
@@ -118,7 +118,7 @@ static const uint8_t mcur_fdiag_bits[] = {
static const uint8_t *cursor_bits16[] = {
cur_ver_bits, mcur_ver_bits, cur_hor_bits, mcur_hor_bits,
cur_bdiag_bits, mcur_bdiag_bits, cur_fdiag_bits, mcur_fdiag_bits,
- 0, 0, cur_blank_bits, cur_blank_bits };
+ nullptr, nullptr, cur_blank_bits, cur_blank_bits };
static const uint8_t vsplit_bits[] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
@@ -219,7 +219,7 @@ static const uint8_t busym_bits[] = {
static const uint8_t * const cursor_bits32[] = {
vsplit_bits, vsplitm_bits, hsplit_bits, hsplitm_bits,
- 0, 0, 0, 0, whatsthis_bits, whatsthism_bits, busy_bits, busym_bits
+ nullptr, nullptr, nullptr, nullptr, whatsthis_bits, whatsthism_bits, busy_bits, busym_bits
};
static const uint8_t forbidden_bits[] = {
@@ -452,19 +452,19 @@ xcb_cursor_t QXcbCursor::createNonStandardCursor(int cshape)
if (cshape == Qt::BlankCursor) {
xcb_pixmap_t cp = xcb_create_pixmap_from_bitmap_data(conn, m_screen->root(), cur_blank_bits, 16, 16,
- 1, 0, 0, 0);
+ 1, 0, 0, nullptr);
xcb_pixmap_t mp = xcb_create_pixmap_from_bitmap_data(conn, m_screen->root(), cur_blank_bits, 16, 16,
- 1, 0, 0, 0);
+ 1, 0, 0, nullptr);
cursor = xcb_generate_id(conn);
xcb_create_cursor(conn, cursor, cp, mp, 0, 0, 0, 0xFFFF, 0xFFFF, 0xFFFF, 8, 8);
} else if (cshape >= Qt::SizeVerCursor && cshape < Qt::SizeAllCursor) {
int i = (cshape - Qt::SizeVerCursor) * 2;
xcb_pixmap_t pm = xcb_create_pixmap_from_bitmap_data(conn, m_screen->root(),
const_cast<uint8_t*>(cursor_bits16[i]),
- 16, 16, 1, 0, 0, 0);
+ 16, 16, 1, 0, 0, nullptr);
xcb_pixmap_t pmm = xcb_create_pixmap_from_bitmap_data(conn, m_screen->root(),
const_cast<uint8_t*>(cursor_bits16[i + 1]),
- 16, 16, 1, 0, 0, 0);
+ 16, 16, 1, 0, 0, nullptr);
cursor = xcb_generate_id(conn);
xcb_create_cursor(conn, cursor, pm, pmm, 0, 0, 0, 0xFFFF, 0xFFFF, 0xFFFF, 8, 8);
} else if ((cshape >= Qt::SplitVCursor && cshape <= Qt::SplitHCursor)
@@ -472,10 +472,10 @@ xcb_cursor_t QXcbCursor::createNonStandardCursor(int cshape)
int i = (cshape - Qt::SplitVCursor) * 2;
xcb_pixmap_t pm = xcb_create_pixmap_from_bitmap_data(conn, m_screen->root(),
const_cast<uint8_t*>(cursor_bits32[i]),
- 32, 32, 1, 0, 0, 0);
+ 32, 32, 1, 0, 0, nullptr);
xcb_pixmap_t pmm = xcb_create_pixmap_from_bitmap_data(conn, m_screen->root(),
const_cast<uint8_t*>(cursor_bits32[i + 1]),
- 32, 32, 1, 0, 0, 0);
+ 32, 32, 1, 0, 0, nullptr);
int hs = (cshape == Qt::PointingHandCursor || cshape == Qt::WhatsThisCursor
|| cshape == Qt::BusyCursor) ? 0 : 16;
cursor = xcb_generate_id(conn);
@@ -484,20 +484,20 @@ xcb_cursor_t QXcbCursor::createNonStandardCursor(int cshape)
int i = (cshape - Qt::ForbiddenCursor) * 2;
xcb_pixmap_t pm = xcb_create_pixmap_from_bitmap_data(conn, m_screen->root(),
const_cast<uint8_t*>(cursor_bits20[i]),
- 20, 20, 1, 0, 0, 0);
+ 20, 20, 1, 0, 0, nullptr);
xcb_pixmap_t pmm = xcb_create_pixmap_from_bitmap_data(conn, m_screen->root(),
const_cast<uint8_t*>(cursor_bits20[i + 1]),
- 20, 20, 1, 0, 0, 0);
+ 20, 20, 1, 0, 0, nullptr);
cursor = xcb_generate_id(conn);
xcb_create_cursor(conn, cursor, pm, pmm, 0, 0, 0, 0xFFFF, 0xFFFF, 0xFFFF, 10, 10);
} else if (cshape == Qt::OpenHandCursor || cshape == Qt::ClosedHandCursor) {
bool open = cshape == Qt::OpenHandCursor;
xcb_pixmap_t pm = xcb_create_pixmap_from_bitmap_data(conn, m_screen->root(),
const_cast<uint8_t*>(open ? openhand_bits : closedhand_bits),
- 16, 16, 1, 0, 0, 0);
+ 16, 16, 1, 0, 0, nullptr);
xcb_pixmap_t pmm = xcb_create_pixmap_from_bitmap_data(conn, m_screen->root(),
const_cast<uint8_t*>(open ? openhandm_bits : closedhandm_bits),
- 16, 16, 1, 0, 0, 0);
+ 16, 16, 1, 0, 0, nullptr);
cursor = xcb_generate_id(conn);
xcb_create_cursor(conn, cursor, pm, pmm, 0, 0, 0, 0xFFFF, 0xFFFF, 0xFFFF, 8, 8);
} else if (cshape == Qt::DragCopyCursor || cshape == Qt::DragMoveCursor
@@ -660,14 +660,14 @@ void QXcbCursor::queryPointer(QXcbConnection *c, QXcbVirtualDesktop **virtualDes
QPoint QXcbCursor::pos() const
{
QPoint p;
- queryPointer(connection(), 0, &p);
+ queryPointer(connection(), nullptr, &p);
return p;
}
void QXcbCursor::setPos(const QPoint &pos)
{
QXcbVirtualDesktop *virtualDesktop = nullptr;
- queryPointer(connection(), &virtualDesktop, 0);
+ queryPointer(connection(), &virtualDesktop, nullptr);
xcb_warp_pointer(xcb_connection(), XCB_NONE, virtualDesktop->root(), 0, 0, 0, 0, pos.x(), pos.y());
xcb_flush(xcb_connection());
}
diff --git a/src/plugins/platforms/xcb/qxcbdrag.cpp b/src/plugins/platforms/xcb/qxcbdrag.cpp
index 3d525598ca..e76fc8bd40 100644
--- a/src/plugins/platforms/xcb/qxcbdrag.cpp
+++ b/src/plugins/platforms/xcb/qxcbdrag.cpp
@@ -114,7 +114,7 @@ protected:
QStringList formats_sys() const override;
QVariant retrieveData_sys(const QString &mimeType, QVariant::Type type) const override;
- QVariant xdndObtainData(const QByteArray &format, QVariant::Type requestedType) const;
+ QVariant xdndObtainData(const QByteArray &format, QMetaType::Type requestedType) const;
QXcbDrag *drag;
};
@@ -148,7 +148,7 @@ void QXcbDrag::init()
source_time = XCB_CURRENT_TIME;
target_time = XCB_CURRENT_TIME;
- QXcbCursor::queryPointer(connection(), &current_virtual_desktop, 0);
+ QXcbCursor::queryPointer(connection(), &current_virtual_desktop, nullptr);
drag_types.clear();
//current_embedding_widget = 0;
@@ -384,13 +384,13 @@ void QXcbDrag::move(const QPoint &globalPos, Qt::MouseButtons b, Qt::KeyboardMod
if (!findXdndAwareTarget(globalPos, &target))
return;
- QXcbWindow *w = 0;
+ QXcbWindow *w = nullptr;
if (target) {
w = connection()->platformWindowFromId(target);
if (w && (w->window()->type() == Qt::Desktop) /*&& !w->acceptDrops()*/)
- w = 0;
+ w = nullptr;
} else {
- w = 0;
+ w = nullptr;
target = current_virtual_desktop->root();
}
@@ -522,7 +522,7 @@ void QXcbDrag::drop(const QPoint &globalPos, Qt::MouseButtons b, Qt::KeyboardMod
QXcbWindow *w = connection()->platformWindowFromId(current_proxy_target);
if (w && w->window()->type() == Qt::Desktop) // && !w->acceptDrops()
- w = 0;
+ w = nullptr;
Transaction t = {
connection()->time(),
@@ -716,7 +716,7 @@ void QXcbDrag::handle_xdnd_position(QPlatformWindow *w, const xcb_client_message
target_time = e->data.data32[3];
}
- QMimeData *dropData = 0;
+ QMimeData *dropData = nullptr;
Qt::DropActions supported_actions = Qt::IgnoreAction;
if (currentDrag()) {
dropData = currentDrag()->mimeData();
@@ -883,7 +883,7 @@ void QXcbDrag::handleLeave(QPlatformWindow *w, const xcb_client_message_event_t
event->data.data32[0], xdnd_dragsource);
}
- QWindowSystemInterface::handleDrag(w->window(), nullptr, QPoint(), Qt::IgnoreAction, 0, 0);
+ QWindowSystemInterface::handleDrag(w->window(), nullptr, QPoint(), Qt::IgnoreAction, { }, { });
}
void QXcbDrag::send_leave()
@@ -911,7 +911,7 @@ void QXcbDrag::send_leave()
QXcbWindow *w = connection()->platformWindowFromId(current_proxy_target);
if (w && (w->window()->type() == Qt::Desktop) /*&& !w->acceptDrops()*/)
- w = 0;
+ w = nullptr;
qCDebug(lcQpaXDnd) << "sending XdndLeave to target:" << current_target;
@@ -945,7 +945,7 @@ void QXcbDrag::handleDrop(QPlatformWindow *, const xcb_client_message_event_t *e
target_time = l[2];
Qt::DropActions supported_drop_actions;
- QMimeData *dropData = 0;
+ QMimeData *dropData = nullptr;
if (currentDrag()) {
dropData = currentDrag()->mimeData();
supported_drop_actions = Qt::DropActions(l[4]);
@@ -1152,7 +1152,7 @@ void QXcbDrag::handleSelectionRequest(const xcb_selection_request_event_t *event
}
}
- QDrag *transactionDrag = 0;
+ QDrag *transactionDrag = nullptr;
if (at >= 0) {
transactionDrag = transactions.at(at).drag;
} else if (at == -2) {
@@ -1222,7 +1222,7 @@ bool QXcbDrag::dndEnable(QXcbWindow *w, bool on)
if (w->window()->type() == Qt::Desktop) {
xcb_delete_property(xcb_connection(), w->xcb_window(), atom(QXcbAtom::XdndProxy));
delete desktop_proxy;
- desktop_proxy = 0;
+ desktop_proxy = nullptr;
} else {
qCDebug(lcQpaXDnd) << "not deleting XDndAware";
}
@@ -1248,11 +1248,11 @@ QXcbDropData::~QXcbDropData()
QVariant QXcbDropData::retrieveData_sys(const QString &mimetype, QVariant::Type requestedType) const
{
QByteArray mime = mimetype.toLatin1();
- QVariant data = xdndObtainData(mime, requestedType);
+ QVariant data = xdndObtainData(mime, QMetaType::Type(requestedType));
return data;
}
-QVariant QXcbDropData::xdndObtainData(const QByteArray &format, QVariant::Type requestedType) const
+QVariant QXcbDropData::xdndObtainData(const QByteArray &format, QMetaType::Type requestedType) const
{
QByteArray result;
diff --git a/src/plugins/platforms/xcb/qxcbdrag.h b/src/plugins/platforms/xcb/qxcbdrag.h
index 1388e68acc..7bef7a818a 100644
--- a/src/plugins/platforms/xcb/qxcbdrag.h
+++ b/src/plugins/platforms/xcb/qxcbdrag.h
@@ -86,7 +86,7 @@ public:
void handlePosition(QPlatformWindow *w, const xcb_client_message_event_t *event);
void handleLeave(QPlatformWindow *w, const xcb_client_message_event_t *event);
void handleDrop(QPlatformWindow *, const xcb_client_message_event_t *event,
- Qt::MouseButtons b = nullptr, Qt::KeyboardModifiers mods = nullptr);
+ Qt::MouseButtons b = { }, Qt::KeyboardModifiers mods = { });
void handleStatus(const xcb_client_message_event_t *event);
void handleSelectionRequest(const xcb_selection_request_event_t *event);
@@ -109,7 +109,7 @@ private:
void init();
void handle_xdnd_position(QPlatformWindow *w, const xcb_client_message_event_t *event,
- Qt::MouseButtons b = nullptr, Qt::KeyboardModifiers mods = nullptr);
+ Qt::MouseButtons b = { }, Qt::KeyboardModifiers mods = { });
void handle_xdnd_status(const xcb_client_message_event_t *event);
void send_leave();
diff --git a/src/plugins/platforms/xcb/qxcbimage.cpp b/src/plugins/platforms/xcb/qxcbimage.cpp
index 8f33e6ed31..b0e610dd51 100644
--- a/src/plugins/platforms/xcb/qxcbimage.cpp
+++ b/src/plugins/platforms/xcb/qxcbimage.cpp
@@ -221,7 +221,7 @@ xcb_pixmap_t qt_xcb_XPixmapFromBitmap(QXcbScreen *screen, const QImage &image)
for (int i = 0; i < height; i++)
memcpy(buf + (destLineSize * i), map + (bytesPerLine * i), destLineSize);
xcb_pixmap_t pm = xcb_create_pixmap_from_bitmap_data(conn, screen->root(), buf,
- width, height, 1, 0, 0, 0);
+ width, height, 1, 0, 0, nullptr);
delete[] buf;
return pm;
}
@@ -249,7 +249,7 @@ xcb_cursor_t qt_xcb_createCursorXRender(QXcbScreen *screen, const QImage &image,
32, 32, 32, 32,
QSysInfo::ByteOrder == QSysInfo::BigEndian ? XCB_IMAGE_ORDER_MSB_FIRST : XCB_IMAGE_ORDER_LSB_FIRST,
XCB_IMAGE_ORDER_MSB_FIRST,
- 0, 0, 0);
+ nullptr, 0, nullptr);
if (!xi) {
qWarning("qt_xcb_createCursorXRender: xcb_image_create failed");
return XCB_NONE;
@@ -266,10 +266,10 @@ xcb_cursor_t qt_xcb_createCursorXRender(QXcbScreen *screen, const QImage &image,
xcb_create_pixmap(conn, 32, pix, screen->root(), w, h);
xcb_render_picture_t pic = xcb_generate_id(conn);
- xcb_render_create_picture(conn, pic, pix, fmt->id, 0, 0);
+ xcb_render_create_picture(conn, pic, pix, fmt->id, 0, nullptr);
xcb_gcontext_t gc = xcb_generate_id(conn);
- xcb_create_gc(conn, gc, pix, 0, 0);
+ xcb_create_gc(conn, gc, pix, 0, nullptr);
xcb_image_put(conn, pix, gc, xi, 0, 0, 0);
xcb_free_gc(conn, gc);
diff --git a/src/plugins/platforms/xcb/qxcbintegration.cpp b/src/plugins/platforms/xcb/qxcbintegration.cpp
index efda6b67ce..3fd989e1f9 100644
--- a/src/plugins/platforms/xcb/qxcbintegration.cpp
+++ b/src/plugins/platforms/xcb/qxcbintegration.cpp
@@ -130,7 +130,7 @@ QXcbIntegration *QXcbIntegration::m_instance = nullptr;
QXcbIntegration::QXcbIntegration(const QStringList &parameters, int &argc, char **argv)
: m_services(new QGenericUnixServices)
- , m_instanceName(0)
+ , m_instanceName(nullptr)
, m_canGrab(true)
, m_defaultVisualId(UINT_MAX)
{
@@ -146,7 +146,7 @@ QXcbIntegration::QXcbIntegration(const QStringList &parameters, int &argc, char
m_nativeInterface.reset(new QXcbNativeInterface);
// Parse arguments
- const char *displayName = 0;
+ const char *displayName = nullptr;
bool noGrabArg = false;
bool doGrabArg = false;
if (argc) {
diff --git a/src/plugins/platforms/xcb/qxcbkeyboard.cpp b/src/plugins/platforms/xcb/qxcbkeyboard.cpp
index d0e02ecdd1..e8286381a2 100644
--- a/src/plugins/platforms/xcb/qxcbkeyboard.cpp
+++ b/src/plugins/platforms/xcb/qxcbkeyboard.cpp
@@ -49,13 +49,7 @@
#include <private/qguiapplication_p.h>
-#if QT_CONFIG(xkb)
-#include <xkbcommon/xkbcommon-x11.h>
-#endif
-
-#if QT_CONFIG(xcb_xinput)
#include <xcb/xinput.h>
-#endif
QT_BEGIN_NAMESPACE
@@ -392,20 +386,16 @@ void QXcbKeyboard::updateKeymap()
xkb_context_set_log_level(m_xkbContext.get(), logLevel);
}
-#if QT_CONFIG(xkb)
if (connection()->hasXKB()) {
m_xkbKeymap.reset(xkb_x11_keymap_new_from_device(m_xkbContext.get(), xcb_connection(),
core_device_id, XKB_KEYMAP_COMPILE_NO_FLAGS));
if (m_xkbKeymap)
m_xkbState.reset(xkb_x11_state_new_from_device(m_xkbKeymap.get(), xcb_connection(), core_device_id));
} else {
-#endif
m_xkbKeymap.reset(keymapFromCore(keysymMods));
if (m_xkbKeymap)
m_xkbState.reset(xkb_state_new(m_xkbKeymap.get()));
-#if QT_CONFIG(xkb)
}
-#endif
if (!m_xkbKeymap) {
qCWarning(lcQpaKeyboard, "failed to compile a keymap");
@@ -428,7 +418,6 @@ QList<int> QXcbKeyboard::possibleKeys(const QKeyEvent *event) const
return QXkbCommon::possibleKeys(m_xkbState.get(), event, m_superAsMeta, m_hyperAsMeta);
}
-#if QT_CONFIG(xkb)
void QXcbKeyboard::updateXKBState(xcb_xkb_state_notify_event_t *state)
{
if (m_config && connection()->hasXKB()) {
@@ -444,7 +433,6 @@ void QXcbKeyboard::updateXKBState(xcb_xkb_state_notify_event_t *state)
handleStateChanges(changedComponents);
}
}
-#endif
static xkb_layout_index_t lockedGroup(quint16 state)
{
@@ -473,7 +461,6 @@ void QXcbKeyboard::updateXKBStateFromCore(quint16 state)
}
}
-#if QT_CONFIG(xcb_xinput)
void QXcbKeyboard::updateXKBStateFromXI(void *modInfo, void *groupInfo)
{
if (m_config && !connection()->hasXKB()) {
@@ -491,7 +478,6 @@ void QXcbKeyboard::updateXKBStateFromXI(void *modInfo, void *groupInfo)
handleStateChanges(changedComponents);
}
}
-#endif
void QXcbKeyboard::handleStateChanges(xkb_state_component changedComponents)
{
@@ -541,7 +527,6 @@ void QXcbKeyboard::updateXKBMods()
QXcbKeyboard::QXcbKeyboard(QXcbConnection *connection)
: QXcbObject(connection)
{
-#if QT_CONFIG(xkb)
core_device_id = 0;
if (connection->hasXKB()) {
selectEvents();
@@ -551,11 +536,9 @@ QXcbKeyboard::QXcbKeyboard(QXcbConnection *connection)
return;
}
} else {
-#endif
m_key_symbols = xcb_key_symbols_alloc(xcb_connection());
-#if QT_CONFIG(xkb)
}
-#endif
+
updateKeymap();
}
@@ -573,7 +556,6 @@ void QXcbKeyboard::initialize()
void QXcbKeyboard::selectEvents()
{
-#if QT_CONFIG(xkb)
const uint16_t required_map_parts = (XCB_XKB_MAP_PART_KEY_TYPES |
XCB_XKB_MAP_PART_KEY_SYMS |
XCB_XKB_MAP_PART_MODIFIER_MAP |
@@ -597,19 +579,17 @@ void QXcbKeyboard::selectEvents()
required_events,
required_map_parts,
required_map_parts,
- 0);
+ nullptr);
xcb_generic_error_t *error = xcb_request_check(xcb_connection(), select);
if (error) {
free(error);
qCWarning(lcQpaXcb, "failed to select notify events from XKB");
}
-#endif
}
void QXcbKeyboard::updateVModMapping()
{
-#if QT_CONFIG(xkb)
xcb_xkb_get_names_value_list_t names_list;
memset(&vmod_masks, 0, sizeof(vmod_masks));
@@ -640,7 +620,7 @@ void QXcbKeyboard::updateVModMapping()
vmod_mask = name_reply->virtualMods;
// find the virtual modifiers for which names are defined.
for (bit = 1; vmod_mask; bit <<= 1) {
- vmod_name = 0;
+ vmod_name = nullptr;
if (!(vmod_mask & bit))
continue;
@@ -667,12 +647,10 @@ void QXcbKeyboard::updateVModMapping()
else if (qstrcmp(vmod_name, "Hyper") == 0)
vmod_masks.hyper = bit;
}
-#endif
}
void QXcbKeyboard::updateVModToRModMapping()
{
-#if QT_CONFIG(xkb)
xcb_xkb_get_map_map_t map;
memset(&rmod_masks, 0, sizeof(rmod_masks));
@@ -729,7 +707,6 @@ void QXcbKeyboard::updateVModToRModMapping()
else if (vmod_masks.hyper == bit)
rmod_masks.hyper = modmap;
}
-#endif
}
// Small helper: set modifier bit, if modifier position is valid
diff --git a/src/plugins/platforms/xcb/qxcbkeyboard.h b/src/plugins/platforms/xcb/qxcbkeyboard.h
index e35c82ad24..0ee08aeff2 100644
--- a/src/plugins/platforms/xcb/qxcbkeyboard.h
+++ b/src/plugins/platforms/xcb/qxcbkeyboard.h
@@ -43,14 +43,12 @@
#include "qxcbobject.h"
#include <xcb/xcb_keysyms.h>
-#if QT_CONFIG(xkb)
#define explicit dont_use_cxx_explicit
#include <xcb/xkb.h>
#undef explicit
-#endif
-#include <xkbcommon/xkbcommon.h>
#include <QtXkbCommonSupport/private/qxkbcommon_p.h>
+#include <xkbcommon/xkbcommon-x11.h>
#include <QEvent>
@@ -74,18 +72,14 @@ public:
void updateKeymap();
QList<int> possibleKeys(const QKeyEvent *event) const;
- // when XKEYBOARD not present on the X server
void updateXKBMods();
xkb_mod_mask_t xkbModMask(quint16 state);
void updateXKBStateFromCore(quint16 state);
-#if QT_CONFIG(xcb_xinput)
void updateXKBStateFromXI(void *modInfo, void *groupInfo);
-#endif
-#if QT_CONFIG(xkb)
- // when XKEYBOARD is present on the X server
+
int coreDeviceId() const { return core_device_id; }
void updateXKBState(xcb_xkb_state_notify_event_t *state);
-#endif
+
void handleStateChanges(xkb_state_component changedComponents);
protected:
@@ -97,10 +91,9 @@ protected:
typedef QMap<xcb_keysym_t, int> KeysymModifierMap;
struct xkb_keymap *keymapFromCore(const KeysymModifierMap &keysymMods);
- // when XKEYBOARD not present on the X server
void updateModifiers(const KeysymModifierMap &keysymMods);
KeysymModifierMap keysymsToModifiers();
- // when XKEYBOARD is present on the X server
+
void updateVModMapping();
void updateVModToRModMapping();
@@ -119,7 +112,6 @@ private:
_mod_masks rmod_masks;
- // when XKEYBOARD not present on the X server
xcb_key_symbols_t *m_key_symbols = nullptr;
struct _xkb_mods {
xkb_mod_index_t shift;
@@ -132,11 +124,9 @@ private:
xkb_mod_index_t mod5;
};
_xkb_mods xkb_mods;
-#if QT_CONFIG(xkb)
- // when XKEYBOARD is present on the X server
+
_mod_masks vmod_masks;
int core_device_id;
-#endif
QXkbCommon::ScopedXKBState m_xkbState;
QXkbCommon::ScopedXKBKeymap m_xkbKeymap;
diff --git a/src/plugins/platforms/xcb/qxcbmime.cpp b/src/plugins/platforms/xcb/qxcbmime.cpp
index d611f86a9c..0b3219f792 100644
--- a/src/plugins/platforms/xcb/qxcbmime.cpp
+++ b/src/plugins/platforms/xcb/qxcbmime.cpp
@@ -159,7 +159,7 @@ QVector<xcb_atom_t> QXcbMime::mimeAtomsForFormat(QXcbConnection *connection, con
}
QVariant QXcbMime::mimeConvertToFormat(QXcbConnection *connection, xcb_atom_t a, const QByteArray &d, const QString &format,
- QVariant::Type requestedType, const QByteArray &encoding)
+ QMetaType::Type requestedType, const QByteArray &encoding)
{
QByteArray data = d;
QString atomName = mimeAtomToString(connection, a);
@@ -169,7 +169,7 @@ QVariant QXcbMime::mimeConvertToFormat(QXcbConnection *connection, xcb_atom_t a,
&& atomName == format + QLatin1String(";charset=") + QLatin1String(encoding)) {
#if QT_CONFIG(textcodec)
- if (requestedType == QVariant::String) {
+ if (requestedType == QMetaType::QString) {
QTextCodec *codec = QTextCodec::codecForName(encoding);
if (codec)
return codec->toUnicode(data);
@@ -264,7 +264,7 @@ QVariant QXcbMime::mimeConvertToFormat(QXcbConnection *connection, xcb_atom_t a,
return QVariant();
}
-xcb_atom_t QXcbMime::mimeAtomForFormat(QXcbConnection *connection, const QString &format, QVariant::Type requestedType,
+xcb_atom_t QXcbMime::mimeAtomForFormat(QXcbConnection *connection, const QString &format, QMetaType::Type requestedType,
const QVector<xcb_atom_t> &atoms, QByteArray *requestedEncoding)
{
requestedEncoding->clear();
@@ -297,7 +297,7 @@ xcb_atom_t QXcbMime::mimeAtomForFormat(QXcbConnection *connection, const QString
// for string/text requests try to use a format with a well-defined charset
// first to avoid encoding problems
- if (requestedType == QVariant::String
+ if (requestedType == QMetaType::QString
&& format.startsWith(QLatin1String("text/"))
&& !format.contains(QLatin1String("charset="))) {
diff --git a/src/plugins/platforms/xcb/qxcbmime.h b/src/plugins/platforms/xcb/qxcbmime.h
index f2136ec9f4..dcb4f6b6c6 100644
--- a/src/plugins/platforms/xcb/qxcbmime.h
+++ b/src/plugins/platforms/xcb/qxcbmime.h
@@ -60,8 +60,8 @@ public:
static bool mimeDataForAtom(QXcbConnection *connection, xcb_atom_t a, QMimeData *mimeData, QByteArray *data,
xcb_atom_t *atomFormat, int *dataFormat);
static QVariant mimeConvertToFormat(QXcbConnection *connection, xcb_atom_t a, const QByteArray &data, const QString &format,
- QVariant::Type requestedType, const QByteArray &encoding);
- static xcb_atom_t mimeAtomForFormat(QXcbConnection *connection, const QString &format, QVariant::Type requestedType,
+ QMetaType::Type requestedType, const QByteArray &encoding);
+ static xcb_atom_t mimeAtomForFormat(QXcbConnection *connection, const QString &format, QMetaType::Type requestedType,
const QVector<xcb_atom_t> &atoms, QByteArray *requestedEncoding);
};
diff --git a/src/plugins/platforms/xcb/qxcbnativeinterface.cpp b/src/plugins/platforms/xcb/qxcbnativeinterface.cpp
index 81b889a80f..30fa6864ac 100644
--- a/src/plugins/platforms/xcb/qxcbnativeinterface.cpp
+++ b/src/plugins/platforms/xcb/qxcbnativeinterface.cpp
@@ -268,7 +268,7 @@ QPlatformNativeInterface::NativeResourceForIntegrationFunction QXcbNativeInterfa
if (lowerCaseResource == "peekeventqueue")
return NativeResourceForIntegrationFunction(reinterpret_cast<void *>(peekEventQueue));
- return 0;
+ return nullptr;
}
QPlatformNativeInterface::NativeResourceForContextFunction QXcbNativeInterface::nativeResourceFunctionForContext(const QByteArray &resource)
@@ -291,7 +291,7 @@ QPlatformNativeInterface::NativeResourceForScreenFunction QXcbNativeInterface::n
return NativeResourceForScreenFunction(reinterpret_cast<void *>(setAppTime));
else if (lowerCaseResource == "setappusertime")
return NativeResourceForScreenFunction(reinterpret_cast<void *>(setAppUserTime));
- return 0;
+ return nullptr;
}
QPlatformNativeInterface::NativeResourceForWindowFunction QXcbNativeInterface::nativeResourceFunctionForWindow(const QByteArray &resource)
@@ -365,7 +365,7 @@ void *QXcbNativeInterface::startupId()
QXcbConnection *defaultConnection = integration->defaultConnection();
if (defaultConnection)
return reinterpret_cast<void *>(const_cast<char *>(defaultConnection->startupId().constData()));
- return 0;
+ return nullptr;
}
void *QXcbNativeInterface::x11Screen()
@@ -374,7 +374,7 @@ void *QXcbNativeInterface::x11Screen()
QXcbConnection *defaultConnection = integration->defaultConnection();
if (defaultConnection)
return reinterpret_cast<void *>(defaultConnection->primaryScreenNumber());
- return 0;
+ return nullptr;
}
void *QXcbNativeInterface::rootWindow()
@@ -383,7 +383,7 @@ void *QXcbNativeInterface::rootWindow()
QXcbConnection *defaultConnection = integration->defaultConnection();
if (defaultConnection)
return reinterpret_cast<void *>(defaultConnection->rootWindow());
- return 0;
+ return nullptr;
}
void *QXcbNativeInterface::display()
diff --git a/src/plugins/platforms/xcb/qxcbscreen.cpp b/src/plugins/platforms/xcb/qxcbscreen.cpp
index 87e1c9bdf8..505f7343ce 100644
--- a/src/plugins/platforms/xcb/qxcbscreen.cpp
+++ b/src/plugins/platforms/xcb/qxcbscreen.cpp
@@ -467,7 +467,7 @@ const xcb_visualtype_t *QXcbVirtualDesktop::visualForId(xcb_visualid_t visualid)
{
QMap<xcb_visualid_t, xcb_visualtype_t>::const_iterator it = m_visuals.find(visualid);
if (it == m_visuals.constEnd())
- return 0;
+ return nullptr;
return &*it;
}
@@ -587,7 +587,7 @@ QWindow *QXcbScreen::topLevelAt(const QPoint &p) const
do {
auto translate_reply = Q_XCB_REPLY_UNCHECKED(xcb_translate_coordinates, xcb_connection(), parent, child, x, y);
if (!translate_reply) {
- return 0;
+ return nullptr;
}
parent = child;
@@ -596,14 +596,14 @@ QWindow *QXcbScreen::topLevelAt(const QPoint &p) const
y = translate_reply->dst_y;
if (!child || child == root)
- return 0;
+ return nullptr;
QPlatformWindow *platformWindow = connection()->platformWindowFromId(child);
if (platformWindow)
return platformWindow->window();
} while (parent != child);
- return 0;
+ return nullptr;
}
void QXcbScreen::windowShown(QXcbWindow *window)
diff --git a/src/plugins/platforms/xcb/qxcbsessionmanager.cpp b/src/plugins/platforms/xcb/qxcbsessionmanager.cpp
index f880d4d722..2eb32c069e 100644
--- a/src/plugins/platforms/xcb/qxcbsessionmanager.cpp
+++ b/src/plugins/platforms/xcb/qxcbsessionmanager.cpp
@@ -69,7 +69,7 @@ public Q_SLOTS:
};
-static SmcConn smcConnection = 0;
+static SmcConn smcConnection = nullptr;
static bool sm_interactionActive;
static bool sm_smActive;
static int sm_interactStyle;
@@ -81,7 +81,7 @@ static bool sm_phase2;
static bool sm_in_phase2;
bool qt_sm_blockUserInput = false;
-static QSmSocketReceiver* sm_receiver = 0;
+static QSmSocketReceiver* sm_receiver = nullptr;
static void resetSmState();
static void sm_setProperty(const char *name, const char *type,
@@ -191,7 +191,7 @@ static void sm_performSaveYourself(QXcbSessionManager *sm)
// generate a new session key
timeval tv;
- gettimeofday(&tv, 0);
+ gettimeofday(&tv, nullptr);
sm->setSessionKey(QString::number(qulonglong(tv.tv_sec)) +
QLatin1Char('_') +
QString::number(qulonglong(tv.tv_usec)));
@@ -203,7 +203,7 @@ static void sm_performSaveYourself(QXcbSessionManager *sm)
// tell the session manager about our program in best POSIX style
sm_setProperty(QString::fromLatin1(SmProgram), argument0);
// tell the session manager about our user as well.
- struct passwd *entryPtr = 0;
+ struct passwd *entryPtr = nullptr;
#if defined(_POSIX_THREAD_SAFE_FUNCTIONS) && (_POSIX_THREAD_SAFE_FUNCTIONS - 0 > 0)
QVarLengthArray<char, 1024> buf(qMax<long>(sysconf(_SC_GETPW_R_SIZE_MAX), 1024L));
struct passwd entry;
@@ -329,7 +329,7 @@ static void sm_saveYourselfPhase2Callback(SmcConn smcConn, SmPointer clientData)
void QSmSocketReceiver::socketActivated(int)
{
- IceProcessMessages(SmcGetIceConnection(smcConnection), 0, 0);
+ IceProcessMessages(SmcGetIceConnection(smcConnection), nullptr, nullptr);
}
@@ -337,11 +337,11 @@ void QSmSocketReceiver::socketActivated(int)
QXcbSessionManager::QXcbSessionManager(const QString &id, const QString &key)
: QPlatformSessionManager(id, key)
- , m_eventLoop(0)
+ , m_eventLoop(nullptr)
{
resetSmState();
char cerror[256];
- char* myId = 0;
+ char* myId = nullptr;
QByteArray b_id = id.toLatin1();
char* prevId = b_id.data();
@@ -359,7 +359,7 @@ QXcbSessionManager::QXcbSessionManager(const QString &id, const QString &key)
if (!qEnvironmentVariableIsSet("SESSION_MANAGER"))
return;
- smcConnection = SmcOpenConnection(0, 0, 1, 0,
+ smcConnection = SmcOpenConnection(nullptr, nullptr, 1, 0,
SmcSaveYourselfProcMask |
SmcDieProcMask |
SmcSaveCompleteProcMask |
@@ -382,8 +382,8 @@ QXcbSessionManager::QXcbSessionManager(const QString &id, const QString &key)
QXcbSessionManager::~QXcbSessionManager()
{
if (smcConnection)
- SmcCloseConnection(smcConnection, 0, 0);
- smcConnection = 0;
+ SmcCloseConnection(smcConnection, 0, nullptr);
+ smcConnection = nullptr;
delete sm_receiver;
}
@@ -411,7 +411,7 @@ bool QXcbSessionManager::allowsInteraction()
QEventLoop eventLoop;
m_eventLoop = &eventLoop;
eventLoop.exec();
- m_eventLoop = 0;
+ m_eventLoop = nullptr;
sm_waitingForInteraction = false;
if (sm_smActive) { // not cancelled
@@ -441,7 +441,7 @@ bool QXcbSessionManager::allowsErrorInteraction()
QEventLoop eventLoop;
m_eventLoop = &eventLoop;
eventLoop.exec();
- m_eventLoop = 0;
+ m_eventLoop = nullptr;
sm_waitingForInteraction = false;
if (sm_smActive) { // not cancelled
diff --git a/src/plugins/platforms/xcb/qxcbsystemtraytracker.cpp b/src/plugins/platforms/xcb/qxcbsystemtraytracker.cpp
index 684e603fab..ff5ad98cd2 100644
--- a/src/plugins/platforms/xcb/qxcbsystemtraytracker.cpp
+++ b/src/plugins/platforms/xcb/qxcbsystemtraytracker.cpp
@@ -64,11 +64,11 @@ QXcbSystemTrayTracker *QXcbSystemTrayTracker::create(QXcbConnection *connection)
// Selection, tray atoms for GNOME, NET WM Specification
const xcb_atom_t trayAtom = connection->atom(QXcbAtom::_NET_SYSTEM_TRAY_OPCODE);
if (!trayAtom)
- return 0;
+ return nullptr;
const QByteArray netSysTray = QByteArrayLiteral("_NET_SYSTEM_TRAY_S") + QByteArray::number(connection->primaryScreenNumber());
const xcb_atom_t selection = connection->internAtom(netSysTray.constData());
if (!selection)
- return 0;
+ return nullptr;
return new QXcbSystemTrayTracker(connection, trayAtom, selection);
}
diff --git a/src/plugins/platforms/xcb/qxcbvulkaninstance.cpp b/src/plugins/platforms/xcb/qxcbvulkaninstance.cpp
index b3f8a5832d..bb82bcec39 100644
--- a/src/plugins/platforms/xcb/qxcbvulkaninstance.cpp
+++ b/src/plugins/platforms/xcb/qxcbvulkaninstance.cpp
@@ -93,7 +93,7 @@ bool QXcbVulkanInstance::supportsPresent(VkPhysicalDevice physicalDevice,
VkSurfaceKHR QXcbVulkanInstance::createSurface(QXcbWindow *window)
{
- VkSurfaceKHR surface = 0;
+ VkSurfaceKHR surface = VK_NULL_HANDLE;
if (!m_createSurface) {
m_createSurface = reinterpret_cast<PFN_vkCreateXcbSurfaceKHR>(
diff --git a/src/plugins/platforms/xcb/qxcbvulkanwindow.cpp b/src/plugins/platforms/xcb/qxcbvulkanwindow.cpp
index 25bc340f97..a05ecab51d 100644
--- a/src/plugins/platforms/xcb/qxcbvulkanwindow.cpp
+++ b/src/plugins/platforms/xcb/qxcbvulkanwindow.cpp
@@ -43,7 +43,7 @@ QT_BEGIN_NAMESPACE
QXcbVulkanWindow::QXcbVulkanWindow(QWindow *window)
: QXcbWindow(window),
- m_surface(0)
+ m_surface(VK_NULL_HANDLE)
{
}
diff --git a/src/plugins/platforms/xcb/qxcbwindow.cpp b/src/plugins/platforms/xcb/qxcbwindow.cpp
index a5974ec36e..40106bbeaf 100644
--- a/src/plugins/platforms/xcb/qxcbwindow.cpp
+++ b/src/plugins/platforms/xcb/qxcbwindow.cpp
@@ -67,9 +67,7 @@
#include <xcb/xcb_icccm.h>
#include <xcb/xfixes.h>
#include <xcb/shape.h>
-#if QT_CONFIG(xcb_xinput)
#include <xcb/xinput.h>
-#endif
#include <private/qguiapplication_p.h>
#include <private/qwindow_p.h>
@@ -176,13 +174,13 @@ static inline XTextProperty* qstringToXTP(Display *dpy, const QString& s)
{
#include <X11/Xatom.h>
- static XTextProperty tp = { 0, 0, 0, 0 };
+ static XTextProperty tp = { nullptr, 0, 0, 0 };
static bool free_prop = true; // we can't free tp.value in case it references
// the data of the static QByteArray below.
if (tp.value) {
if (free_prop)
XFree(tp.value);
- tp.value = 0;
+ tp.value = nullptr;
free_prop = true;
}
@@ -193,7 +191,7 @@ static inline XTextProperty* qstringToXTP(Display *dpy, const QString& s)
QByteArray mapped = mapper->fromUnicode(s);
char* tl[2];
tl[0] = mapped.data();
- tl[1] = 0;
+ tl[1] = nullptr;
errCode = XmbTextListToTextProperty(dpy, tl, 1, XStdICCTextStyle, &tp);
if (errCode < 0)
qCDebug(lcQpaXcb, "XmbTextListToTextProperty result code %d", errCode);
@@ -284,7 +282,7 @@ void QXcbWindow::create()
m_window = platformScreen->root();
m_depth = platformScreen->screen()->root_depth;
m_visualId = platformScreen->screen()->root_visual;
- const xcb_visualtype_t *visual = 0;
+ const xcb_visualtype_t *visual = nullptr;
if (connection()->hasDefaultVisualId()) {
visual = platformScreen->visualForId(connection()->defaultVisualId());
if (visual)
@@ -494,14 +492,12 @@ void QXcbWindow::create()
atom(QXcbAtom::_XEMBED_INFO),
32, 2, (void *)data);
-#if QT_CONFIG(xcb_xinput)
if (connection()->hasXInput2()) {
if (connection()->xi2MouseEventsDisabled())
connection()->xi2SelectDeviceEventsCompatibility(m_window);
else
connection()->xi2SelectDeviceEvents(m_window);
}
-#endif
setWindowState(window()->windowStates());
setWindowFlags(window()->flags());
@@ -825,7 +821,7 @@ bool QXcbWindow::relayFocusToModalWindow() const
while (w && w->parent())
w = w->parent();
- QWindow *modalWindow = 0;
+ QWindow *modalWindow = nullptr;
const bool blocked = QGuiApplicationPrivate::instance()->isWindowBlocked(w, &modalWindow);
if (blocked && modalWindow != w) {
modalWindow->requestActivate();
@@ -882,7 +878,7 @@ enum {
QXcbWindow::NetWmStates QXcbWindow::netWmStates()
{
- NetWmStates result(0);
+ NetWmStates result;
auto reply = Q_XCB_REPLY_UNCHECKED(xcb_get_property, xcb_connection(),
0, m_window, atom(QXcbAtom::_NET_WM_STATE),
@@ -935,10 +931,10 @@ void QXcbWindow::setWindowFlags(Qt::WindowFlags flags)
xcb_change_window_attributes(xcb_connection(), xcb_window(), mask, values);
- QXcbWindowFunctions::WmWindowTypes wmWindowTypes = 0;
+ QXcbWindowFunctions::WmWindowTypes wmWindowTypes;
if (window()->dynamicPropertyNames().contains(wm_window_type_property_id)) {
wmWindowTypes = static_cast<QXcbWindowFunctions::WmWindowTypes>(
- window()->property(wm_window_type_property_id).value<int>());
+ qvariant_cast<int>(window()->property(wm_window_type_property_id)));
}
setWmWindowType(wmWindowTypes, flags);
@@ -1071,7 +1067,7 @@ void QXcbWindow::setNetWmStateOnUnmappedWindow()
if (Q_UNLIKELY(m_mapped))
qCWarning(lcQpaXcb()) << "internal error: " << Q_FUNC_INFO << "called on mapped window";
- NetWmStates states(0);
+ NetWmStates states;
const Qt::WindowFlags flags = window()->flags();
if (flags & Qt::WindowStaysOnTopHint) {
states |= NetWmStateAbove;
@@ -1206,7 +1202,7 @@ void QXcbWindow::updateNetWmUserTime(xcb_timestamp_t timestamp)
XCB_WINDOW_CLASS_INPUT_OUTPUT, // window class
m_visualId, // visual
0, // value mask
- 0); // value list
+ nullptr); // value list
wid = m_netWmUserTimeWindow;
xcb_change_property(xcb_connection(), XCB_PROP_MODE_REPLACE, m_window, atom(QXcbAtom::_NET_WM_USER_TIME_WINDOW),
XCB_ATOM_WINDOW, 32, 1, &m_netWmUserTimeWindow);
@@ -1236,7 +1232,7 @@ void QXcbWindow::setTransparentForMouseEvents(bool transparent)
xcb_rectangle_t rectangle;
- xcb_rectangle_t *rect = 0;
+ xcb_rectangle_t *rect = nullptr;
int nrect = 0;
if (!transparent) {
@@ -1492,7 +1488,7 @@ uint QXcbWindow::visualIdStatic(QWindow *window)
QXcbWindowFunctions::WmWindowTypes QXcbWindow::wmWindowTypes() const
{
- QXcbWindowFunctions::WmWindowTypes result(0);
+ QXcbWindowFunctions::WmWindowTypes result;
auto reply = Q_XCB_REPLY_UNCHECKED(xcb_get_property, xcb_connection(),
0, m_window, atom(QXcbAtom::_NET_WM_WINDOW_TYPE),
@@ -1900,7 +1896,7 @@ void QXcbWindow::handleButtonPressEvent(int event_x, int event_y, int root_x, in
if (m_embedded && !m_trayIconWindow) {
if (window() != QGuiApplication::focusWindow()) {
const QXcbWindow *container = static_cast<const QXcbWindow *>(parent());
- Q_ASSERT(container != 0);
+ Q_ASSERT(container != nullptr);
sendXEmbedMessage(container->xcb_window(), XEMBED_REQUEST_FOCUS);
}
@@ -1909,9 +1905,7 @@ void QXcbWindow::handleButtonPressEvent(int event_x, int event_y, int root_x, in
QPoint global(root_x, root_y);
if (isWheel) {
-#if QT_CONFIG(xcb_xinput)
if (!connection()->isAtLeastXI21()) {
-#endif
QPoint angleDelta;
if (detail == 4)
angleDelta.setY(120);
@@ -1924,9 +1918,7 @@ void QXcbWindow::handleButtonPressEvent(int event_x, int event_y, int root_x, in
if (modifiers & Qt::AltModifier)
angleDelta = angleDelta.transposed();
QWindowSystemInterface::handleWheelEvent(window(), timestamp, local, global, QPoint(), angleDelta, modifiers);
-#if QT_CONFIG(xcb_xinput)
}
-#endif
return;
}
@@ -1962,13 +1954,8 @@ static inline bool doCheckUnGrabAncestor(QXcbConnection *conn)
* not pressed, otherwise (e.g. on Alt+Tab) it can igonre important enter/leave events.
*/
if (conn) {
-
const bool mouseButtonsPressed = (conn->buttonState() != Qt::NoButton);
-#if QT_CONFIG(xcb_xinput)
return mouseButtonsPressed || (conn->hasXInput2() && !conn->xi2MouseEventsDisabled());
-#else
- return mouseButtonsPressed;
-#endif
}
return true;
}
@@ -2000,10 +1987,9 @@ void QXcbWindow::handleEnterNotifyEvent(int event_x, int event_y, int root_x, in
if (ignoreEnterEvent(mode, detail, connection()) || connection()->mousePressWindow())
return;
-#if QT_CONFIG(xcb_xinput)
+
// Updates scroll valuators, as user might have done some scrolling outside our X client.
connection()->xi2UpdateScrollingDevices();
-#endif
const QPoint local(event_x, event_y);
QWindowSystemInterface::handleEnterEvent(window(), local, global);
@@ -2078,7 +2064,6 @@ void QXcbWindow::handleMotionNotifyEvent(const xcb_motion_notify_event_t *event)
event->time, QEvent::MouseMove);
}
-#if QT_CONFIG(xcb_xinput)
static inline int fixed1616ToInt(xcb_input_fp1616_t val)
{
return int(qreal(val) / 0x10000);
@@ -2116,7 +2101,7 @@ void QXcbWindow::handleXIMouseEvent(xcb_ge_event_t *event, Qt::MouseEventSource
const Qt::MouseButton button = conn->xiToQtMouseButton(ev->detail);
- const char *sourceName = 0;
+ const char *sourceName = nullptr;
if (Q_UNLIKELY(lcQpaXInputEvents().isDebugEnabled())) {
const QMetaObject *metaObject = qt_getEnumMetaObject(source);
const QMetaEnum me = metaObject->enumerator(metaObject->indexOfEnumerator(qt_getEnumName(source)));
@@ -2179,13 +2164,13 @@ void QXcbWindow::handleXIEnterLeave(xcb_ge_event_t *event)
break;
}
}
-#endif
QXcbWindow *QXcbWindow::toWindow() { return this; }
void QXcbWindow::handleMouseEvent(xcb_timestamp_t time, const QPoint &local, const QPoint &global,
Qt::KeyboardModifiers modifiers, QEvent::Type type, Qt::MouseEventSource source)
{
+ m_lastPointerPosition = local;
connection()->setTime(time);
Qt::MouseButton button = type == QEvent::MouseMove ? Qt::NoButton : connection()->button();
QWindowSystemInterface::handleMouseEvent(window(), time, local, global,
@@ -2321,14 +2306,12 @@ bool QXcbWindow::setMouseGrabEnabled(bool grab)
if (grab && !connection()->canGrab())
return false;
-#if QT_CONFIG(xcb_xinput)
if (connection()->hasXInput2() && !connection()->xi2MouseEventsDisabled()) {
bool result = connection()->xi2SetMouseGrabEnabled(m_window, grab);
if (grab && result)
connection()->setMouseGrabber(this);
return result;
}
-#endif
if (!grab) {
xcb_ungrab_pointer(xcb_connection(), XCB_TIME_CURRENT_TIME);
@@ -2378,47 +2361,65 @@ bool QXcbWindow::windowEvent(QEvent *event)
return QPlatformWindow::windowEvent(event);
}
-bool QXcbWindow::startSystemResize(const QPoint &pos, Qt::Corner corner)
+bool QXcbWindow::startSystemResize(Qt::Edges edges)
{
- return startSystemMoveResize(pos, corner);
+ return startSystemMoveResize(m_lastPointerPosition, edges);
}
-bool QXcbWindow::startSystemMove(const QPoint &pos)
+bool QXcbWindow::startSystemMove()
{
- return startSystemMoveResize(pos, 4);
+ return startSystemMoveResize(m_lastPointerPosition, 16);
}
-bool QXcbWindow::startSystemMoveResize(const QPoint &pos, int corner)
+bool QXcbWindow::startSystemMoveResize(const QPoint &pos, int edges)
{
- return false; // ### FIXME QTBUG-69716
const xcb_atom_t moveResize = connection()->atom(QXcbAtom::_NET_WM_MOVERESIZE);
if (!connection()->wmSupport()->isSupportedByWM(moveResize))
return false;
- const QPoint globalPos = QHighDpi::toNativePixels(window()->mapToGlobal(pos), window()->screen());
-#if QT_CONFIG(xcb_xinput)
// ### FIXME QTBUG-53389
- bool startedByTouch = connection()->startSystemMoveResizeForTouchBegin(m_window, globalPos, corner);
+ bool startedByTouch = connection()->startSystemMoveResizeForTouch(m_window, edges);
if (startedByTouch) {
- if (connection()->isUnity() || connection()->isGnome()) {
- // These desktops fail to move/resize via _NET_WM_MOVERESIZE (WM bug?).
+ if (connection()->isUnity()) {
+ // Unity fails to move/resize via _NET_WM_MOVERESIZE (WM bug?).
connection()->abortSystemMoveResizeForTouch();
return false;
}
- // KWin, Openbox, AwesomeWM have been tested to work with _NET_WM_MOVERESIZE.
- } else
-#endif
- { // Started by mouse press.
+ // KWin, Openbox, AwesomeWM and Gnome have been tested to work with _NET_WM_MOVERESIZE.
+ } else { // Started by mouse press.
if (connection()->isUnity())
return false; // _NET_WM_MOVERESIZE on this WM is bouncy (WM bug?).
- doStartSystemMoveResize(globalPos, corner);
+ doStartSystemMoveResize(mapToGlobal(pos), edges);
}
return true;
}
-void QXcbWindow::doStartSystemMoveResize(const QPoint &globalPos, int corner)
+static uint qtEdgesToXcbMoveResizeDirection(Qt::Edges edges)
+{
+ if (edges == (Qt::TopEdge | Qt::LeftEdge))
+ return 0;
+ if (edges == Qt::TopEdge)
+ return 1;
+ if (edges == (Qt::TopEdge | Qt::RightEdge))
+ return 2;
+ if (edges == Qt::RightEdge)
+ return 3;
+ if (edges == (Qt::RightEdge | Qt::BottomEdge))
+ return 4;
+ if (edges == Qt::BottomEdge)
+ return 5;
+ if (edges == (Qt::BottomEdge | Qt::LeftEdge))
+ return 6;
+ if (edges == Qt::LeftEdge)
+ return 7;
+
+ qWarning() << "Cannot convert " << edges << "to _NET_WM_MOVERESIZE direction.";
+ return 0;
+}
+
+void QXcbWindow::doStartSystemMoveResize(const QPoint &globalPos, int edges)
{
const xcb_atom_t moveResize = connection()->atom(QXcbAtom::_NET_WM_MOVERESIZE);
xcb_client_message_event_t xev;
@@ -2429,16 +2430,10 @@ void QXcbWindow::doStartSystemMoveResize(const QPoint &globalPos, int corner)
xev.format = 32;
xev.data.data32[0] = globalPos.x();
xev.data.data32[1] = globalPos.y();
- if (corner == 4) {
+ if (edges == 16)
xev.data.data32[2] = 8; // move
- } else {
- const bool bottom = corner == Qt::BottomRightCorner || corner == Qt::BottomLeftCorner;
- const bool left = corner == Qt::BottomLeftCorner || corner == Qt::TopLeftCorner;
- if (bottom)
- xev.data.data32[2] = left ? 6 : 4; // bottomleft/bottomright
- else
- xev.data.data32[2] = left ? 0 : 2; // topleft/topright
- }
+ else
+ xev.data.data32[2] = qtEdgesToXcbMoveResizeDirection(Qt::Edges(edges));
xev.data.data32[3] = XCB_BUTTON_INDEX_1;
xev.data.data32[4] = 0;
xcb_ungrab_pointer(connection()->xcb_connection(), XCB_CURRENT_TIME);
diff --git a/src/plugins/platforms/xcb/qxcbwindow.h b/src/plugins/platforms/xcb/qxcbwindow.h
index b84250d109..0cdc40f82d 100644
--- a/src/plugins/platforms/xcb/qxcbwindow.h
+++ b/src/plugins/platforms/xcb/qxcbwindow.h
@@ -108,8 +108,8 @@ public:
bool windowEvent(QEvent *event) override;
- bool startSystemResize(const QPoint &pos, Qt::Corner corner) override;
- bool startSystemMove(const QPoint &pos) override;
+ bool startSystemResize(Qt::Edges edges) override;
+ bool startSystemMove() override;
void setOpacity(qreal level) override;
void setMask(const QRegion &region) override;
@@ -138,10 +138,8 @@ public:
void handleFocusInEvent(const xcb_focus_in_event_t *event) override;
void handleFocusOutEvent(const xcb_focus_out_event_t *event) override;
void handlePropertyNotifyEvent(const xcb_property_notify_event_t *event) override;
-#if QT_CONFIG(xcb_xinput)
void handleXIMouseEvent(xcb_ge_event_t *, Qt::MouseEventSource source = Qt::MouseEventNotSynthesized) override;
void handleXIEnterLeave(xcb_ge_event_t *) override;
-#endif
QXcbWindow *toWindow() override;
@@ -171,8 +169,8 @@ public:
QXcbScreen *xcbScreen() const;
- bool startSystemMoveResize(const QPoint &pos, int corner);
- void doStartSystemMoveResize(const QPoint &globalPos, int corner);
+ bool startSystemMoveResize(const QPoint &pos, int edges);
+ void doStartSystemMoveResize(const QPoint &globalPos, int edges);
static bool isTrayIconWindow(QWindow *window)
{
@@ -267,6 +265,7 @@ protected:
QRegion m_exposeRegion;
QSize m_oldWindowSize;
+ QPoint m_lastPointerPosition;
xcb_visualid_t m_visualId = 0;
// Last sent state. Initialized to an invalid state, on purpose.
diff --git a/src/plugins/platforms/xcb/qxcbxsettings.cpp b/src/plugins/platforms/xcb/qxcbxsettings.cpp
index 88f15e344f..902f196ba9 100644
--- a/src/plugins/platforms/xcb/qxcbxsettings.cpp
+++ b/src/plugins/platforms/xcb/qxcbxsettings.cpp
@@ -256,7 +256,7 @@ QXcbXSettings::QXcbXSettings(QXcbVirtualDesktop *screen)
QXcbXSettings::~QXcbXSettings()
{
delete d_ptr;
- d_ptr = 0;
+ d_ptr = nullptr;
}
bool QXcbXSettings::initialized() const
diff --git a/src/plugins/platforms/xcb/xcb-static/xcb-static.pro b/src/plugins/platforms/xcb/xcb-static/xcb-static.pro
deleted file mode 100644
index 078b275381..0000000000
--- a/src/plugins/platforms/xcb/xcb-static/xcb-static.pro
+++ /dev/null
@@ -1,80 +0,0 @@
-#
-# Statically compile in code for
-# libxcb-fixes, libxcb-randr, libxcb-shm, libxcb-sync, libxcb-image,
-# libxcb-keysyms, libxcb-icccm, libxcb-renderutil, libxcb-xkb,
-# libxcb-xinerama, libxcb-xinput
-#
-CONFIG += static
-
-XCB_DIR = $$QT_SOURCE_TREE/src/3rdparty/xcb
-
-MODULE_INCLUDEPATH += $$XCB_DIR/include $$XCB_DIR/sysinclude
-INCLUDEPATH += $$XCB_DIR/include/xcb
-
-QMAKE_USE += xcb/nolink
-
-# ignore compiler warnings in 3rdparty code
-QMAKE_CFLAGS_STATIC_LIB+=-w
-
-#
-# libxcb
-#
-LIBXCB_DIR = $$XCB_DIR/libxcb
-
-SOURCES += \
- $$LIBXCB_DIR/xfixes.c \
- $$LIBXCB_DIR/randr.c \
- $$LIBXCB_DIR/shm.c \
- $$LIBXCB_DIR/sync.c \
- $$LIBXCB_DIR/render.c \
- $$LIBXCB_DIR/shape.c \
- $$LIBXCB_DIR/xkb.c \
- $$LIBXCB_DIR/xinerama.c \
- $$LIBXCB_DIR/xinput.c
-
-#
-# xcb-util
-#
-XCB_UTIL_DIR = $$XCB_DIR/xcb-util
-
-
-SOURCES += \
- $$XCB_UTIL_DIR/xcb_aux.c \
- $$XCB_UTIL_DIR/atoms.c \
- $$XCB_UTIL_DIR/event.c
-
-#
-# xcb-util-image
-#
-XCB_IMAGE_DIR = $$XCB_DIR/xcb-util-image
-
-SOURCES += $$XCB_IMAGE_DIR/xcb_image.c
-
-#
-# xcb-util-keysyms
-#
-XCB_KEYSYMS_DIR = $$XCB_DIR/xcb-util-keysyms
-
-SOURCES += $$XCB_KEYSYMS_DIR/keysyms.c
-
-#
-# xcb-util-renderutil
-#
-
-XCB_RENDERUTIL_DIR = $$XCB_DIR/xcb-util-renderutil
-
-SOURCES += $$XCB_RENDERUTIL_DIR/util.c
-
-#
-# xcb-util-wm
-#
-XCB_WM_DIR = $$XCB_DIR/xcb-util-wm
-
-SOURCES += \
- $$XCB_WM_DIR/icccm.c
-
-OTHER_FILES = $$XCB_DIR/README
-
-TR_EXCLUDE += $$XCB_DIR/*
-
-load(qt_helper_lib)
diff --git a/src/plugins/platforms/xcb/xcb.pro b/src/plugins/platforms/xcb/xcb.pro
index 0d27645a60..1c43c5ca04 100644
--- a/src/plugins/platforms/xcb/xcb.pro
+++ b/src/plugins/platforms/xcb/xcb.pro
@@ -2,8 +2,6 @@ TEMPLATE = subdirs
CONFIG += ordered
QT_FOR_CONFIG += gui-private
-!qtConfig(system-xcb): SUBDIRS += xcb-static
-
SUBDIRS += xcb_qpa_lib.pro
SUBDIRS += xcb-plugin.pro
SUBDIRS += gl_integrations
diff --git a/src/plugins/platforms/xcb/xcb_qpa_lib.pro b/src/plugins/platforms/xcb/xcb_qpa_lib.pro
index 34c671c8c7..a5d05faa9c 100644
--- a/src/plugins/platforms/xcb/xcb_qpa_lib.pro
+++ b/src/plugins/platforms/xcb/xcb_qpa_lib.pro
@@ -35,6 +35,7 @@ SOURCES = \
qxcbeventdispatcher.cpp \
qxcbconnection_basic.cpp \
qxcbconnection_screens.cpp \
+ qxcbconnection_xi2.cpp \
qxcbatom.cpp
HEADERS = \
@@ -71,10 +72,6 @@ qtConfig(xcb-xlib) {
QMAKE_USE += xcb_xlib
}
-qtConfig(xcb-xinput) {
- SOURCES += qxcbconnection_xi2.cpp
-}
-
qtConfig(xcb-sm) {
QMAKE_USE += x11sm
SOURCES += qxcbsessionmanager.cpp
@@ -94,20 +91,19 @@ qtConfig(vulkan) {
qxcbvulkanwindow.h
}
-!qtConfig(system-xcb) {
- QMAKE_USE += xcb-static
-} else {
- qtConfig(xcb-xinput): QMAKE_USE += xcb_xinput
- QMAKE_USE += \
- xcb_icccm xcb_image xcb_keysyms xcb_randr xcb_render xcb_renderutil \
- xcb_shape xcb_shm xcb_sync xcb_xfixes xcb_xinerama
-}
-QMAKE_USE += xcb
+QMAKE_USE += \
+ xcb xcb_icccm xcb_image xcb_keysyms xcb_randr xcb_render xcb_renderutil \
+ xcb_shape xcb_shm xcb_sync xcb_xfixes xcb_xinerama xcb_xkb xkbcommon xkbcommon_x11
-QMAKE_USE += xkbcommon
-qtConfig(xkb) {
- QMAKE_USE += xkbcommon_x11
- qtConfig(system-xcb): QMAKE_USE += xcb_xkb
+qtConfig(system-xcb-xinput) {
+ QMAKE_USE += xcb_xinput
+} else {
+ # Use bundled xcb-xinput sources.
+ XCB_DIR = $$QT_SOURCE_TREE/src/3rdparty/xcb
+ INCLUDEPATH += $$XCB_DIR/include/
+ SOURCES += $$XCB_DIR/libxcb/xinput.c
+ # Ignore compiler warnings in 3rdparty C code.
+ QMAKE_CFLAGS+=-w
}
qtConfig(dlopen): QMAKE_USE += libdl
diff --git a/src/plugins/platformthemes/gtk3/main.cpp b/src/plugins/platformthemes/gtk3/main.cpp
index fb1c425d8e..860fc3a26e 100644
--- a/src/plugins/platformthemes/gtk3/main.cpp
+++ b/src/plugins/platformthemes/gtk3/main.cpp
@@ -57,7 +57,7 @@ QPlatformTheme *QGtk3ThemePlugin::create(const QString &key, const QStringList &
if (!key.compare(QLatin1String(QGtk3Theme::name), Qt::CaseInsensitive))
return new QGtk3Theme;
- return 0;
+ return nullptr;
}
QT_END_NAMESPACE
diff --git a/src/plugins/platformthemes/gtk3/qgtk3dialoghelpers.cpp b/src/plugins/platformthemes/gtk3/qgtk3dialoghelpers.cpp
index c64a02fa0c..65564b59a1 100644
--- a/src/plugins/platformthemes/gtk3/qgtk3dialoghelpers.cpp
+++ b/src/plugins/platformthemes/gtk3/qgtk3dialoghelpers.cpp
@@ -165,12 +165,12 @@ void QGtk3Dialog::onResponse(QGtk3Dialog *dialog, int response)
void QGtk3Dialog::onParentWindowDestroyed()
{
// The QGtk3*DialogHelper classes own this object. Make sure the parent doesn't delete it.
- setParent(0);
+ setParent(nullptr);
}
QGtk3ColorDialogHelper::QGtk3ColorDialogHelper()
{
- d.reset(new QGtk3Dialog(gtk_color_chooser_dialog_new("", 0)));
+ d.reset(new QGtk3Dialog(gtk_color_chooser_dialog_new("", nullptr)));
connect(d.data(), SIGNAL(accept()), this, SLOT(onAccepted()));
connect(d.data(), SIGNAL(reject()), this, SIGNAL(reject()));
@@ -238,7 +238,7 @@ void QGtk3ColorDialogHelper::applyOptions()
QGtk3FileDialogHelper::QGtk3FileDialogHelper()
{
- d.reset(new QGtk3Dialog(gtk_file_chooser_dialog_new("", 0,
+ d.reset(new QGtk3Dialog(gtk_file_chooser_dialog_new("", nullptr,
GTK_FILE_CHOOSER_ACTION_OPEN,
qUtf8Printable(QGtk3Theme::defaultStandardButtonText(QPlatformDialogHelper::Cancel)), GTK_RESPONSE_CANCEL,
qUtf8Printable(QGtk3Theme::defaultStandardButtonText(QPlatformDialogHelper::Ok)), GTK_RESPONSE_OK,
@@ -497,7 +497,7 @@ void QGtk3FileDialogHelper::setNameFilters(const QStringList &filters)
QGtk3FontDialogHelper::QGtk3FontDialogHelper()
{
- d.reset(new QGtk3Dialog(gtk_font_chooser_dialog_new("", 0)));
+ d.reset(new QGtk3Dialog(gtk_font_chooser_dialog_new("", nullptr)));
connect(d.data(), SIGNAL(accept()), this, SLOT(onAccepted()));
connect(d.data(), SIGNAL(reject()), this, SIGNAL(reject()));
diff --git a/src/plugins/platformthemes/gtk3/qgtk3menu.cpp b/src/plugins/platformthemes/gtk3/qgtk3menu.cpp
index 4f0bd9d9a0..d9d117faeb 100644
--- a/src/plugins/platformthemes/gtk3/qgtk3menu.cpp
+++ b/src/plugins/platformthemes/gtk3/qgtk3menu.cpp
@@ -200,7 +200,7 @@ void QGtk3MenuItem::setMenu(QPlatformMenu *menu)
{
m_menu = qobject_cast<QGtk3Menu *>(menu);
if (GTK_IS_MENU_ITEM(m_item))
- gtk_menu_item_set_submenu(GTK_MENU_ITEM(m_item), m_menu ? m_menu->handle() : NULL);
+ gtk_menu_item_set_submenu(GTK_MENU_ITEM(m_item), m_menu ? m_menu->handle() : nullptr);
}
bool QGtk3MenuItem::isVisible() const
@@ -436,7 +436,7 @@ void QGtk3Menu::showPopup(const QWindow *parentWindow, const QRect &targetRect,
if (pw)
m_targetPos = pw->mapToGlobal(m_targetPos);
- gtk_menu_popup(GTK_MENU(m_menu), NULL, NULL, qt_gtk_menu_position_func, this, 0, gtk_get_current_event_time());
+ gtk_menu_popup(GTK_MENU(m_menu), nullptr, nullptr, qt_gtk_menu_position_func, this, 0, gtk_get_current_event_time());
}
void QGtk3Menu::dismiss()
diff --git a/src/plugins/platformthemes/gtk3/qgtk3theme.cpp b/src/plugins/platformthemes/gtk3/qgtk3theme.cpp
index 077955eb4e..93520344f8 100644
--- a/src/plugins/platformthemes/gtk3/qgtk3theme.cpp
+++ b/src/plugins/platformthemes/gtk3/qgtk3theme.cpp
@@ -86,9 +86,9 @@ QGtk3Theme::QGtk3Theme()
{
// gtk_init will reset the Xlib error handler, and that causes
// Qt applications to quit on X errors. Therefore, we need to manually restore it.
- int (*oldErrorHandler)(Display *, XErrorEvent *) = XSetErrorHandler(NULL);
+ int (*oldErrorHandler)(Display *, XErrorEvent *) = XSetErrorHandler(nullptr);
- gtk_init(0, 0);
+ gtk_init(nullptr, nullptr);
XSetErrorHandler(oldErrorHandler);
@@ -99,7 +99,7 @@ QGtk3Theme::QGtk3Theme()
g_type_ensure(PANGO_TYPE_FONT_FACE);
/* Use our custom log handler. */
- g_log_set_handler("Gtk", G_LOG_LEVEL_MESSAGE, gtkMessageHandler, NULL);
+ g_log_set_handler("Gtk", G_LOG_LEVEL_MESSAGE, gtkMessageHandler, nullptr);
}
static inline QVariant gtkGetLongPressTime()
@@ -173,7 +173,7 @@ QPlatformDialogHelper *QGtk3Theme::createPlatformDialogHelper(DialogType type) c
case FontDialog:
return new QGtk3FontDialogHelper;
default:
- return 0;
+ return nullptr;
}
}
@@ -197,7 +197,7 @@ bool QGtk3Theme::useNativeFileDialog()
* dialogs entirely since we can't avoid creation of a platform
* dialog helper.
*/
- return gtk_check_version(3, 15, 5) == 0;
+ return gtk_check_version(3, 15, 5) == nullptr;
}
QT_END_NAMESPACE
diff --git a/src/plugins/platformthemes/xdgdesktopportal/qxdgdesktopportalfiledialog.cpp b/src/plugins/platformthemes/xdgdesktopportal/qxdgdesktopportalfiledialog.cpp
index dcf52921aa..13c39436ba 100644
--- a/src/plugins/platformthemes/xdgdesktopportal/qxdgdesktopportalfiledialog.cpp
+++ b/src/plugins/platformthemes/xdgdesktopportal/qxdgdesktopportalfiledialog.cpp
@@ -225,7 +225,7 @@ void QXdgDesktopPortalFileDialog::openPortal()
QRegularExpressionMatch match = regexp.match(filter);
if (match.hasMatch()) {
QString userVisibleName = match.captured(1);
- QStringList filterStrings = match.captured(2).split(QLatin1Char(' '), QString::SkipEmptyParts);
+ QStringList filterStrings = match.captured(2).split(QLatin1Char(' '), Qt::SkipEmptyParts);
FilterConditionList filterConditions;
for (const QString &filterString : filterStrings) {
diff --git a/src/plugins/platformthemes/xdgdesktopportal/qxdgdesktopportaltheme.h b/src/plugins/platformthemes/xdgdesktopportal/qxdgdesktopportaltheme.h
index 5cfc4df0d0..d38b3ddda3 100644
--- a/src/plugins/platformthemes/xdgdesktopportal/qxdgdesktopportaltheme.h
+++ b/src/plugins/platformthemes/xdgdesktopportal/qxdgdesktopportaltheme.h
@@ -72,7 +72,7 @@ public:
QPixmap standardPixmap(StandardPixmap sp, const QSizeF &size) const override;
QIcon fileIcon(const QFileInfo &fileInfo,
- QPlatformTheme::IconOptions iconOptions = nullptr) const override;
+ QPlatformTheme::IconOptions iconOptions = { }) const override;
QIconEngine *createIconEngine(const QString &iconName) const override;
diff --git a/src/plugins/printsupport/cups/qcupsprintengine.cpp b/src/plugins/printsupport/cups/qcupsprintengine.cpp
index c9683eb99d..43d5e119ad 100644
--- a/src/plugins/printsupport/cups/qcupsprintengine.cpp
+++ b/src/plugins/printsupport/cups/qcupsprintengine.cpp
@@ -100,10 +100,10 @@ void QCupsPrintEngine::setProperty(PrintEnginePropertyKey key, const QVariant &v
d->cupsOptions = value.toStringList();
break;
case PPK_QPageSize:
- d->setPageSize(value.value<QPageSize>());
+ d->setPageSize(qvariant_cast<QPageSize>(value));
break;
case PPK_QPageLayout: {
- QPageLayout pageLayout = value.value<QPageLayout>();
+ QPageLayout pageLayout = qvariant_cast<QPageLayout>(value);
if (pageLayout.isValid() && (d->m_printDevice.isValidPageLayout(pageLayout, d->resolution)
|| d->m_printDevice.supportsCustomPageSizes()
|| d->m_printDevice.supportedPageSizes().isEmpty())) {
diff --git a/src/plugins/sqldrivers/configure.json b/src/plugins/sqldrivers/configure.json
index cd20eef1df..28ccbeadcd 100644
--- a/src/plugins/sqldrivers/configure.json
+++ b/src/plugins/sqldrivers/configure.json
@@ -72,7 +72,9 @@
{ "type": "mysqlConfig", "query": "--libs_r", "cleanlibs": false },
{ "type": "mysqlConfig", "query": "--libs", "cleanlibs": false },
{ "libs": "-lmysqlclient_r", "condition": "!config.win32" },
+ { "libs": "-llibmariadb", "condition": "config.win32" },
{ "libs": "-llibmysql", "condition": "config.win32" },
+ { "libs": "-lmariadb", "condition": "!config.win32" },
{ "libs": "-lmysqlclient", "condition": "!config.win32" }
]
},
diff --git a/src/plugins/sqldrivers/db2/qsql_db2.cpp b/src/plugins/sqldrivers/db2/qsql_db2.cpp
index 1d7e985731..ddf54666e7 100644
--- a/src/plugins/sqldrivers/db2/qsql_db2.cpp
+++ b/src/plugins/sqldrivers/db2/qsql_db2.cpp
@@ -1270,7 +1270,7 @@ bool QDB2Driver::open(const QString& db, const QString& user, const QString& pas
QString protocol;
// Set connection attributes
- const QStringList opts(connOpts.split(QLatin1Char(';'), QString::SkipEmptyParts));
+ const QStringList opts(connOpts.split(QLatin1Char(';'), Qt::SkipEmptyParts));
for (int i = 0; i < opts.count(); ++i) {
const QString tmp(opts.at(i));
int idx;
diff --git a/src/plugins/sqldrivers/ibase/qsql_ibase.cpp b/src/plugins/sqldrivers/ibase/qsql_ibase.cpp
index 3368c74373..0fa21f504c 100644
--- a/src/plugins/sqldrivers/ibase/qsql_ibase.cpp
+++ b/src/plugins/sqldrivers/ibase/qsql_ibase.cpp
@@ -730,7 +730,7 @@ static char* createArrayBuffer(char *buffer, const QList<QVariant> &list,
if (curDim != dim) {
for(i = 0; i < list.size(); ++i) {
- if (list.at(i).type() != QVariant::List) { // dimensions mismatch
+ if (list.at(i).userType() != QVariant::List) { // dimensions mismatch
error = QLatin1String("Array dimensons mismatch. Fieldname: %1");
return 0;
}
@@ -1162,7 +1162,7 @@ bool QIBaseResult::gotoNext(QSqlCachedResult::ValueCache& row, int rowIdx)
// null value
QVariant v;
v.convert(qIBaseTypeName2(d->sqlda->sqlvar[i].sqltype, d->sqlda->sqlvar[i].sqlscale < 0));
- if(v.type() == QVariant::Double) {
+ if (v.userType() == QVariant::Double) {
switch(numericalPrecisionPolicy()) {
case QSql::LowPrecisionInt32:
v.convert(QVariant::Int);
@@ -1477,7 +1477,7 @@ bool QIBaseDriver::open(const QString & db,
if (isOpen())
close();
- const QStringList opts(connOpts.split(QLatin1Char(';'), QString::SkipEmptyParts));
+ const QStringList opts(connOpts.split(QLatin1Char(';'), Qt::SkipEmptyParts));
QString encString;
QByteArray role;
@@ -1914,7 +1914,12 @@ void QIBaseDriver::qHandleEventNotification(void *updatedResultBuffer)
if (counts[0]) {
if (eBuffer->subscriptionState == QIBaseEventBuffer::Subscribed) {
+#if QT_DEPRECATED_SINCE(5, 15)
+QT_WARNING_PUSH
+QT_WARNING_DISABLE_DEPRECATED
emit notification(i.key());
+QT_WARNING_POP
+#endif
emit notification(i.key(), QSqlDriver::UnknownSource, QVariant());
}
else if (eBuffer->subscriptionState == QIBaseEventBuffer::Starting)
diff --git a/src/plugins/sqldrivers/mysql/main.cpp b/src/plugins/sqldrivers/mysql/main.cpp
index d8d70483ef..4c6753097f 100644
--- a/src/plugins/sqldrivers/mysql/main.cpp
+++ b/src/plugins/sqldrivers/mysql/main.cpp
@@ -61,7 +61,9 @@ QMYSQLDriverPlugin::QMYSQLDriverPlugin()
QSqlDriver* QMYSQLDriverPlugin::create(const QString &name)
{
- if (name == QLatin1String("QMYSQL") || name == QLatin1String("QMYSQL3")) {
+ if (name == QLatin1String("QMYSQL") ||
+ name == QLatin1String("QMYSQL3") ||
+ name == QLatin1String("QMARIADB")) {
QMYSQLDriver* driver = new QMYSQLDriver();
return driver;
}
diff --git a/src/plugins/sqldrivers/mysql/mysql.json b/src/plugins/sqldrivers/mysql/mysql.json
index 0caaadb7ce..89f5e65fb9 100644
--- a/src/plugins/sqldrivers/mysql/mysql.json
+++ b/src/plugins/sqldrivers/mysql/mysql.json
@@ -1,3 +1,3 @@
{
- "Keys": [ "QMYSQL3", "QMYSQL" ]
+ "Keys": [ "QMYSQL3", "QMYSQL", "QMARIADB" ]
}
diff --git a/src/plugins/sqldrivers/mysql/qsql_mysql.cpp b/src/plugins/sqldrivers/mysql/qsql_mysql.cpp
index febbe58506..a641935dc5 100644
--- a/src/plugins/sqldrivers/mysql/qsql_mysql.cpp
+++ b/src/plugins/sqldrivers/mysql/qsql_mysql.cpp
@@ -65,16 +65,7 @@
Q_DECLARE_METATYPE(MYSQL_RES*)
Q_DECLARE_METATYPE(MYSQL*)
-
-#if MYSQL_VERSION_ID >= 40108
Q_DECLARE_METATYPE(MYSQL_STMT*)
-#endif
-
-#if MYSQL_VERSION_ID >= 40100
-# define Q_CLIENT_MULTI_STATEMENTS CLIENT_MULTI_STATEMENTS
-#else
-# define Q_CLIENT_MULTI_STATEMENTS 0
-#endif
// MySQL above version 8 removed my_bool typedef while MariaDB kept it,
// by redefining it we can regain source compatibility.
@@ -87,17 +78,14 @@ class QMYSQLDriverPrivate : public QSqlDriverPrivate
Q_DECLARE_PUBLIC(QMYSQLDriver)
public:
- QMYSQLDriverPrivate() : QSqlDriverPrivate(), mysql(0),
+ QMYSQLDriverPrivate() : QSqlDriverPrivate(QSqlDriver::MySqlServer)
#if QT_CONFIG(textcodec)
- tc(QTextCodec::codecForLocale()),
-#else
- tc(0),
+ , tc(QTextCodec::codecForLocale())
#endif
- preparedQuerysEnabled(false) { dbmsType = QSqlDriver::MySqlServer; }
- MYSQL *mysql;
- QTextCodec *tc;
-
- bool preparedQuerysEnabled;
+ {}
+ MYSQL *mysql = nullptr;
+ QTextCodec *tc = nullptr;
+ bool preparedQuerysEnabled = false;
};
static inline QString toUnicode(QTextCodec *tc, const char *str)
@@ -199,10 +187,8 @@ protected:
bool nextResult() override;
void detachFromResultSet() override;
-#if MYSQL_VERSION_ID >= 40108
bool prepare(const QString &stmt) override;
bool exec() override;
-#endif
};
class QMYSQLResultPrivate: public QSqlResultPrivate
@@ -212,60 +198,42 @@ class QMYSQLResultPrivate: public QSqlResultPrivate
public:
Q_DECLARE_SQLDRIVER_PRIVATE(QMYSQLDriver)
- QMYSQLResultPrivate(QMYSQLResult *q, const QMYSQLDriver *drv)
- : QSqlResultPrivate(q, drv),
- result(0),
- rowsAffected(0),
- hasBlobs(false)
-#if MYSQL_VERSION_ID >= 40108
- , stmt(0), meta(0), inBinds(0), outBinds(0)
-#endif
- , preparedQuery(false)
- { }
-
- MYSQL_RES *result;
- MYSQL_ROW row;
-
- int rowsAffected;
+ using QSqlResultPrivate::QSqlResultPrivate;
bool bindInValues();
void bindBlobs();
- bool hasBlobs;
+ MYSQL_RES *result = nullptr;
+ MYSQL_ROW row;
+
struct QMyField
{
- QMyField()
- : outField(0), nullIndicator(false), bufLength(0ul),
- myField(0), type(QVariant::Invalid)
- {}
- char *outField;
- my_bool nullIndicator;
- ulong bufLength;
- MYSQL_FIELD *myField;
- QVariant::Type type;
+ char *outField = nullptr;
+ MYSQL_FIELD *myField = nullptr;
+ QMetaType::Type type = QMetaType::UnknownType;
+ my_bool nullIndicator = false;
+ ulong bufLength = 0ul;
};
QVector<QMyField> fields;
-#if MYSQL_VERSION_ID >= 40108
- MYSQL_STMT* stmt;
- MYSQL_RES* meta;
+ MYSQL_STMT *stmt = nullptr;
+ MYSQL_RES *meta = nullptr;
- MYSQL_BIND *inBinds;
- MYSQL_BIND *outBinds;
-#endif
+ MYSQL_BIND *inBinds = nullptr;
+ MYSQL_BIND *outBinds = nullptr;
- bool preparedQuery;
+ int rowsAffected = 0;
+ bool hasBlobs = false;
+ bool preparedQuery = false;
};
#if QT_CONFIG(textcodec)
static QTextCodec* codec(MYSQL* mysql)
{
-#if MYSQL_VERSION_ID >= 32321
QTextCodec* heuristicCodec = QTextCodec::codecForName(mysql_character_set_name(mysql));
if (heuristicCodec)
return heuristicCodec;
-#endif
return QTextCodec::codecForLocale();
}
#endif // textcodec
@@ -280,25 +248,25 @@ static QSqlError qMakeError(const QString& err, QSqlError::ErrorType type,
}
-static QVariant::Type qDecodeMYSQLType(int mysqltype, uint flags)
+static QMetaType::Type qDecodeMYSQLType(int mysqltype, uint flags)
{
- QVariant::Type type;
+ QMetaType::Type type;
switch (mysqltype) {
case FIELD_TYPE_TINY :
- type = static_cast<QVariant::Type>((flags & UNSIGNED_FLAG) ? QMetaType::UChar : QMetaType::Char);
+ type = (flags & UNSIGNED_FLAG) ? QMetaType::UChar : QMetaType::Char;
break;
case FIELD_TYPE_SHORT :
- type = static_cast<QVariant::Type>((flags & UNSIGNED_FLAG) ? QMetaType::UShort : QMetaType::Short);
+ type = (flags & UNSIGNED_FLAG) ? QMetaType::UShort : QMetaType::Short;
break;
case FIELD_TYPE_LONG :
case FIELD_TYPE_INT24 :
- type = (flags & UNSIGNED_FLAG) ? QVariant::UInt : QVariant::Int;
+ type = (flags & UNSIGNED_FLAG) ? QMetaType::UInt : QMetaType::Int;
break;
case FIELD_TYPE_YEAR :
- type = QVariant::Int;
+ type = QMetaType::Int;
break;
case FIELD_TYPE_LONGLONG :
- type = (flags & UNSIGNED_FLAG) ? QVariant::ULongLong : QVariant::LongLong;
+ type = (flags & UNSIGNED_FLAG) ? QMetaType::ULongLong : QMetaType::LongLong;
break;
case FIELD_TYPE_FLOAT :
case FIELD_TYPE_DOUBLE :
@@ -306,19 +274,19 @@ static QVariant::Type qDecodeMYSQLType(int mysqltype, uint flags)
#if defined(FIELD_TYPE_NEWDECIMAL)
case FIELD_TYPE_NEWDECIMAL:
#endif
- type = QVariant::Double;
+ type = QMetaType::Double;
break;
case FIELD_TYPE_DATE :
- type = QVariant::Date;
+ type = QMetaType::QDate;
break;
case FIELD_TYPE_TIME :
// A time field can be within the range '-838:59:59' to '838:59:59' so
// use QString instead of QTime since QTime is limited to 24 hour clock
- type = QVariant::String;
+ type = QMetaType::QString;
break;
case FIELD_TYPE_DATETIME :
case FIELD_TYPE_TIMESTAMP :
- type = QVariant::DateTime;
+ type = QMetaType::QDateTime;
break;
case FIELD_TYPE_STRING :
case FIELD_TYPE_VAR_STRING :
@@ -326,12 +294,13 @@ static QVariant::Type qDecodeMYSQLType(int mysqltype, uint flags)
case FIELD_TYPE_TINY_BLOB :
case FIELD_TYPE_MEDIUM_BLOB :
case FIELD_TYPE_LONG_BLOB :
- type = (flags & BINARY_FLAG) ? QVariant::ByteArray : QVariant::String;
+ case FIELD_TYPE_GEOMETRY :
+ type = (flags & BINARY_FLAG) ? QMetaType::QByteArray : QMetaType::QString;
break;
default:
case FIELD_TYPE_ENUM :
case FIELD_TYPE_SET :
- type = QVariant::String;
+ type = QMetaType::QString;
break;
}
return type;
@@ -340,7 +309,7 @@ static QVariant::Type qDecodeMYSQLType(int mysqltype, uint flags)
static QSqlField qToField(MYSQL_FIELD *field, QTextCodec *tc)
{
QSqlField f(toUnicode(tc, field->name),
- qDecodeMYSQLType(int(field->type), field->flags),
+ QVariant::Type(qDecodeMYSQLType(int(field->type), field->flags)),
toUnicode(tc, field->table));
f.setRequired(IS_NOT_NULL(field->flags));
f.setLength(field->length);
@@ -350,8 +319,6 @@ static QSqlField qToField(MYSQL_FIELD *field, QTextCodec *tc)
return f;
}
-#if MYSQL_VERSION_ID >= 40108
-
static QSqlError qMakeStmtError(const QString& err, QSqlError::ErrorType type,
MYSQL_STMT* stmt)
{
@@ -445,7 +412,6 @@ bool QMYSQLResultPrivate::bindInValues()
}
return true;
}
-#endif
QMYSQLResult::QMYSQLResult(const QMYSQLDriver* db)
: QSqlResult(*new QMYSQLResultPrivate(this, db))
@@ -460,11 +426,9 @@ QMYSQLResult::~QMYSQLResult()
QVariant QMYSQLResult::handle() const
{
Q_D(const QMYSQLResult);
-#if MYSQL_VERSION_ID >= 40108
if(d->preparedQuery)
return d->meta ? QVariant::fromValue(d->meta) : QVariant::fromValue(d->stmt);
else
-#endif
return QVariant::fromValue(d->result);
}
@@ -476,15 +440,12 @@ void QMYSQLResult::cleanup()
// must iterate trough leftover result sets from multi-selects or stored procedures
// if this isn't done subsequent queries will fail with "Commands out of sync"
-#if MYSQL_VERSION_ID >= 40100
while (driver() && d->drv_d_func()->mysql && mysql_next_result(d->drv_d_func()->mysql) == 0) {
MYSQL_RES *res = mysql_store_result(d->drv_d_func()->mysql);
if (res)
mysql_free_result(res);
}
-#endif
-#if MYSQL_VERSION_ID >= 40108
if (d->stmt) {
if (mysql_stmt_close(d->stmt))
qWarning("QMYSQLResult::cleanup: unable to free statement handle");
@@ -509,7 +470,6 @@ void QMYSQLResult::cleanup()
delete[] d->inBinds;
d->inBinds = 0;
}
-#endif
d->hasBlobs = false;
d->fields.clear();
@@ -536,7 +496,6 @@ bool QMYSQLResult::fetch(int i)
if (at() == i)
return true;
if (d->preparedQuery) {
-#if MYSQL_VERSION_ID >= 40108
mysql_stmt_data_seek(d->stmt, i);
int nRC = mysql_stmt_fetch(d->stmt);
@@ -550,9 +509,6 @@ bool QMYSQLResult::fetch(int i)
"Unable to fetch data"), QSqlError::StatementError, d->stmt));
return false;
}
-#else
- return false;
-#endif
} else {
mysql_data_seek(d->result, i);
d->row = mysql_fetch_row(d->result);
@@ -570,7 +526,6 @@ bool QMYSQLResult::fetchNext()
if (!driver())
return false;
if (d->preparedQuery) {
-#if MYSQL_VERSION_ID >= 40108
int nRC = mysql_stmt_fetch(d->stmt);
if (nRC) {
#ifdef MYSQL_DATA_TRUNCATED
@@ -582,9 +537,6 @@ bool QMYSQLResult::fetchNext()
"Unable to fetch data"), QSqlError::StatementError, d->stmt));
return false;
}
-#else
- return false;
-#endif
} else {
d->row = mysql_fetch_row(d->result);
if (!d->row)
@@ -607,11 +559,7 @@ bool QMYSQLResult::fetchLast()
my_ulonglong numRows;
if (d->preparedQuery) {
-#if MYSQL_VERSION_ID >= 40108
numRows = mysql_stmt_num_rows(d->stmt);
-#else
- numRows = 0;
-#endif
} else {
numRows = mysql_num_rows(d->result);
}
@@ -648,7 +596,7 @@ QVariant QMYSQLResult::data(int field)
QString val;
if (d->preparedQuery) {
if (f.nullIndicator)
- return QVariant(f.type);
+ return QVariant(QVariant::Type(f.type));
if (qIsInteger(f.type)) {
QVariant variant(f.type, f.outField);
@@ -660,34 +608,34 @@ QVariant QMYSQLResult::data(int field)
return variant;
}
- if (f.type != QVariant::ByteArray)
+ if (f.type != QMetaType::QByteArray)
val = toUnicode(d->drv_d_func()->tc, f.outField, f.bufLength);
} else {
if (d->row[field] == NULL) {
// NULL value
- return QVariant(f.type);
+ return QVariant(QVariant::Type(f.type));
}
fieldLength = mysql_fetch_lengths(d->result)[field];
- if (f.type != QVariant::ByteArray)
+ if (f.type != QMetaType::QByteArray)
val = toUnicode(d->drv_d_func()->tc, d->row[field], fieldLength);
}
switch (static_cast<int>(f.type)) {
- case QVariant::LongLong:
+ case QMetaType::LongLong:
return QVariant(val.toLongLong());
- case QVariant::ULongLong:
+ case QMetaType::ULongLong:
return QVariant(val.toULongLong());
case QMetaType::Char:
case QMetaType::Short:
- case QVariant::Int:
+ case QMetaType::Int:
return QVariant(val.toInt());
case QMetaType::UChar:
case QMetaType::UShort:
- case QVariant::UInt:
+ case QMetaType::UInt:
return QVariant(val.toUInt());
- case QVariant::Double: {
+ case QMetaType::Double: {
QVariant v;
bool ok=false;
double dbl = val.toDouble(&ok);
@@ -711,13 +659,13 @@ QVariant QMYSQLResult::data(int field)
return v;
return QVariant();
}
- case QVariant::Date:
+ case QMetaType::QDate:
return qDateFromString(val);
- case QVariant::Time:
+ case QMetaType::QTime:
return qTimeFromString(val);
- case QVariant::DateTime:
+ case QMetaType::QDateTime:
return qDateTimeFromString(val);
- case QVariant::ByteArray: {
+ case QMetaType::QByteArray: {
QByteArray ba;
if (d->preparedQuery) {
@@ -727,7 +675,7 @@ QVariant QMYSQLResult::data(int field)
}
return QVariant(ba);
}
- case QVariant::String:
+ case QMetaType::QString:
default:
return QVariant(val);
}
@@ -788,11 +736,7 @@ int QMYSQLResult::size()
Q_D(const QMYSQLResult);
if (driver() && isSelect())
if (d->preparedQuery)
-#if MYSQL_VERSION_ID >= 40108
return mysql_stmt_num_rows(d->stmt);
-#else
- return -1;
-#endif
else
return int(mysql_num_rows(d->result));
else
@@ -821,11 +765,9 @@ QVariant QMYSQLResult::lastInsertId() const
return QVariant();
if (d->preparedQuery) {
-#if MYSQL_VERSION_ID >= 40108
quint64 id = mysql_stmt_insert_id(d->stmt);
if (id)
return QVariant(id);
-#endif
} else {
quint64 id = mysql_insert_id(d->drv_d_func()->mysql);
if (id)
@@ -842,11 +784,7 @@ QSqlRecord QMYSQLResult::record() const
if (!isActive() || !isSelect() || !driver())
return info;
-#if MYSQL_VERSION_ID >= 40108
res = d->preparedQuery ? d->meta : d->result;
-#else
- res = d->result;
-#endif
if (!mysql_errno(d->drv_d_func()->mysql)) {
mysql_field_seek(res, 0);
@@ -865,7 +803,7 @@ bool QMYSQLResult::nextResult()
Q_D(QMYSQLResult);
if (!driver())
return false;
-#if MYSQL_VERSION_ID >= 40100
+
setAt(-1);
setActive(false);
@@ -908,9 +846,6 @@ bool QMYSQLResult::nextResult()
setActive(true);
return true;
-#else
- return false;
-#endif
}
void QMYSQLResult::virtual_hook(int id, void *data)
@@ -918,24 +853,21 @@ void QMYSQLResult::virtual_hook(int id, void *data)
QSqlResult::virtual_hook(id, data);
}
-
-#if MYSQL_VERSION_ID >= 40108
-
-static MYSQL_TIME *toMySqlDate(QDate date, QTime time, QVariant::Type type)
+static MYSQL_TIME *toMySqlDate(QDate date, QTime time, int type)
{
- Q_ASSERT(type == QVariant::Time || type == QVariant::Date
- || type == QVariant::DateTime);
+ Q_ASSERT(type == QMetaType::QTime || type == QMetaType::QDate
+ || type == QMetaType::QDateTime);
MYSQL_TIME *myTime = new MYSQL_TIME;
memset(myTime, 0, sizeof(MYSQL_TIME));
- if (type == QVariant::Time || type == QVariant::DateTime) {
+ if (type == QMetaType::QTime || type == QMetaType::QDateTime) {
myTime->hour = time.hour();
myTime->minute = time.minute();
myTime->second = time.second();
myTime->second_part = time.msec() * 1000;
}
- if (type == QVariant::Date || type == QVariant::DateTime) {
+ if (type == QMetaType::QDate || type == QMetaType::QDateTime) {
myTime->year = date.year();
myTime->month = date.month();
myTime->day = date.day();
@@ -949,7 +881,7 @@ bool QMYSQLResult::prepare(const QString& query)
Q_D(QMYSQLResult);
if (!driver())
return false;
-#if MYSQL_VERSION_ID >= 40108
+
cleanup();
if (!d->drv_d_func()->preparedQuerysEnabled)
return QSqlResult::prepare(query);
@@ -983,9 +915,6 @@ bool QMYSQLResult::prepare(const QString& query)
setSelect(d->bindInValues());
d->preparedQuery = true;
return true;
-#else
- return false;
-#endif
}
bool QMYSQLResult::exec()
@@ -1028,30 +957,30 @@ bool QMYSQLResult::exec()
currBind->length = 0;
currBind->is_unsigned = 0;
- switch (val.type()) {
- case QVariant::ByteArray:
+ switch (val.userType()) {
+ case QMetaType::QByteArray:
currBind->buffer_type = MYSQL_TYPE_BLOB;
currBind->buffer = const_cast<char *>(val.toByteArray().constData());
currBind->buffer_length = val.toByteArray().size();
break;
- case QVariant::Time:
- case QVariant::Date:
- case QVariant::DateTime: {
- MYSQL_TIME *myTime = toMySqlDate(val.toDate(), val.toTime(), val.type());
+ case QMetaType::QTime:
+ case QMetaType::QDate:
+ case QMetaType::QDateTime: {
+ MYSQL_TIME *myTime = toMySqlDate(val.toDate(), val.toTime(), val.userType());
timeVector.append(myTime);
currBind->buffer = myTime;
- switch(val.type()) {
- case QVariant::Time:
+ switch (val.userType()) {
+ case QMetaType::QTime:
currBind->buffer_type = MYSQL_TYPE_TIME;
myTime->time_type = MYSQL_TIMESTAMP_TIME;
break;
- case QVariant::Date:
+ case QMetaType::QDate:
currBind->buffer_type = MYSQL_TYPE_DATE;
myTime->time_type = MYSQL_TIMESTAMP_DATE;
break;
- case QVariant::DateTime:
+ case QMetaType::QDateTime:
currBind->buffer_type = MYSQL_TYPE_DATETIME;
myTime->time_type = MYSQL_TIMESTAMP_DATETIME;
break;
@@ -1061,32 +990,32 @@ bool QMYSQLResult::exec()
currBind->buffer_length = sizeof(MYSQL_TIME);
currBind->length = 0;
break; }
- case QVariant::UInt:
- case QVariant::Int:
+ case QMetaType::UInt:
+ case QMetaType::Int:
currBind->buffer_type = MYSQL_TYPE_LONG;
currBind->buffer = data;
currBind->buffer_length = sizeof(int);
- currBind->is_unsigned = (val.type() != QVariant::Int);
+ currBind->is_unsigned = (val.userType() != QMetaType::Int);
break;
- case QVariant::Bool:
+ case QMetaType::Bool:
currBind->buffer_type = MYSQL_TYPE_TINY;
currBind->buffer = data;
currBind->buffer_length = sizeof(bool);
currBind->is_unsigned = false;
break;
- case QVariant::Double:
+ case QMetaType::Double:
currBind->buffer_type = MYSQL_TYPE_DOUBLE;
currBind->buffer = data;
currBind->buffer_length = sizeof(double);
break;
- case QVariant::LongLong:
- case QVariant::ULongLong:
+ case QMetaType::LongLong:
+ case QMetaType::ULongLong:
currBind->buffer_type = MYSQL_TYPE_LONGLONG;
currBind->buffer = data;
currBind->buffer_length = sizeof(qint64);
- currBind->is_unsigned = (val.type() == QVariant::ULongLong);
+ currBind->is_unsigned = (val.userType() == QMetaType::ULongLong);
break;
- case QVariant::String:
+ case QMetaType::QString:
default: {
QByteArray ba = fromUnicode(d->drv_d_func()->tc, val.toString());
stringVector.append(ba);
@@ -1155,7 +1084,7 @@ bool QMYSQLResult::exec()
setActive(true);
return true;
}
-#endif
+
/////////////////////////////////////////////////////////
static int qMySqlConnectionCount = 0;
@@ -1164,18 +1093,16 @@ static bool qMySqlInitHandledByUser = false;
static void qLibraryInit()
{
#ifndef Q_NO_MYSQL_EMBEDDED
-# if MYSQL_VERSION_ID >= 40000
if (qMySqlInitHandledByUser || qMySqlConnectionCount > 1)
return;
-# if (MYSQL_VERSION_ID >= 40110 && MYSQL_VERSION_ID < 50000) || MYSQL_VERSION_ID >= 50003
+# if MYSQL_VERSION_ID >= 50003
if (mysql_library_init(0, 0, 0)) {
# else
if (mysql_server_init(0, 0, 0)) {
# endif
qWarning("QMYSQLDriver::qServerInit: unable to start server.");
}
-# endif // MYSQL_VERSION_ID
#endif // Q_NO_MYSQL_EMBEDDED
#if defined(MARIADB_BASE_VERSION) || defined(MARIADB_VERSION_ID)
@@ -1187,12 +1114,10 @@ static void qLibraryEnd()
{
#if !defined(MARIADB_BASE_VERSION) && !defined(MARIADB_VERSION_ID)
# if !defined(Q_NO_MYSQL_EMBEDDED)
-# if MYSQL_VERSION_ID > 40000
-# if (MYSQL_VERSION_ID >= 40110 && MYSQL_VERSION_ID < 50000) || MYSQL_VERSION_ID >= 50003
- mysql_library_end();
-# else
- mysql_server_end();
-# endif
+# if MYSQL_VERSION_ID >= 50003
+ mysql_library_end();
+# else
+ mysql_server_end();
# endif
# endif
#endif
@@ -1271,17 +1196,9 @@ bool QMYSQLDriver::hasFeature(DriverFeature f) const
return true;
case PreparedQueries:
case PositionalPlaceholders:
-#if MYSQL_VERSION_ID >= 40108
return d->preparedQuerysEnabled;
-#else
- return false;
-#endif
case MultipleResultSets:
-#if MYSQL_VERSION_ID >= 40100
return true;
-#else
- return false;
-#endif
}
return false;
}
@@ -1322,20 +1239,18 @@ bool QMYSQLDriver::open(const QString& db,
we have to enable CLIEN_MULTI_STATEMENTS here, otherwise _any_
stored procedure call will fail.
*/
- unsigned int optionFlags = Q_CLIENT_MULTI_STATEMENTS;
- const QStringList opts(connOpts.split(QLatin1Char(';'), QString::SkipEmptyParts));
+ unsigned int optionFlags = CLIENT_MULTI_STATEMENTS;
+ const QStringList opts(connOpts.split(QLatin1Char(';'), Qt::SkipEmptyParts));
QString unixSocket;
QString sslCert;
QString sslCA;
QString sslKey;
QString sslCAPath;
QString sslCipher;
-#if MYSQL_VERSION_ID >= 50000
my_bool reconnect=false;
uint connectTimeout = 0;
uint readTimeout = 0;
uint writeTimeout = 0;
-#endif
// extract the real options from the string
for (int i = 0; i < opts.count(); ++i) {
@@ -1346,18 +1261,15 @@ bool QMYSQLDriver::open(const QString& db,
QString opt = tmp.left(idx).simplified();
if (opt == QLatin1String("UNIX_SOCKET"))
unixSocket = val;
-#if MYSQL_VERSION_ID >= 50000
else if (opt == QLatin1String("MYSQL_OPT_RECONNECT")) {
if (val == QLatin1String("TRUE") || val == QLatin1String("1") || val.isEmpty())
reconnect = true;
- } else if (opt == QLatin1String("MYSQL_OPT_CONNECT_TIMEOUT")) {
+ } else if (opt == QLatin1String("MYSQL_OPT_CONNECT_TIMEOUT"))
connectTimeout = val.toInt();
- } else if (opt == QLatin1String("MYSQL_OPT_READ_TIMEOUT")) {
+ else if (opt == QLatin1String("MYSQL_OPT_READ_TIMEOUT"))
readTimeout = val.toInt();
- } else if (opt == QLatin1String("MYSQL_OPT_WRITE_TIMEOUT")) {
+ else if (opt == QLatin1String("MYSQL_OPT_WRITE_TIMEOUT"))
writeTimeout = val.toInt();
- }
-#endif
else if (opt == QLatin1String("SSL_KEY"))
sslKey = val;
else if (opt == QLatin1String("SSL_CERT"))
@@ -1442,7 +1354,7 @@ bool QMYSQLDriver::open(const QString& db,
return false;
}
-#if (MYSQL_VERSION_ID >= 40113 && MYSQL_VERSION_ID < 50000) || MYSQL_VERSION_ID >= 50007
+#if MYSQL_VERSION_ID >= 50007
if (mysql_get_client_version() >= 50503 && mysql_get_server_version(d->mysql) >= 50503) {
// force the communication to be utf8mb4 (only utf8mb4 supports 4-byte characters)
mysql_set_character_set(d->mysql, "utf8mb4");
@@ -1457,20 +1369,15 @@ bool QMYSQLDriver::open(const QString& db,
d->tc = codec(d->mysql);
#endif
}
-#endif
+#endif // MYSQL_VERSION_ID >= 50007
-#if MYSQL_VERSION_ID >= 40108
d->preparedQuerysEnabled = mysql_get_client_version() >= 40108
&& mysql_get_server_version(d->mysql) >= 40100;
-#else
- d->preparedQuerysEnabled = false;
-#endif
#if QT_CONFIG(thread)
mysql_thread_init();
#endif
-
setOpen(true);
setOpenError(false);
return true;
@@ -1499,46 +1406,21 @@ QStringList QMYSQLDriver::tables(QSql::TableType type) const
{
Q_D(const QMYSQLDriver);
QStringList tl;
-#if MYSQL_VERSION_ID >= 40100
- if( mysql_get_server_version(d->mysql) < 50000)
- {
-#endif
- if (!isOpen())
- return tl;
- if (!(type & QSql::Tables))
- return tl;
-
- MYSQL_RES* tableRes = mysql_list_tables(d->mysql, NULL);
- MYSQL_ROW row;
- int i = 0;
- while (tableRes) {
- mysql_data_seek(tableRes, i);
- row = mysql_fetch_row(tableRes);
- if (!row)
- break;
- tl.append(toUnicode(d->tc, row[0]));
- i++;
- }
- mysql_free_result(tableRes);
-#if MYSQL_VERSION_ID >= 40100
- } else {
- QSqlQuery q(createResult());
- if(type & QSql::Tables) {
- QString sql = QLatin1String("select table_name from information_schema.tables where table_schema = '") + QLatin1String(d->mysql->db) + QLatin1String("' and table_type = 'BASE TABLE'");
- q.exec(sql);
+ QSqlQuery q(createResult());
+ if (type & QSql::Tables) {
+ QString sql = QLatin1String("select table_name from information_schema.tables where table_schema = '") + QLatin1String(d->mysql->db) + QLatin1String("' and table_type = 'BASE TABLE'");
+ q.exec(sql);
- while(q.next())
- tl.append(q.value(0).toString());
- }
- if(type & QSql::Views) {
- QString sql = QLatin1String("select table_name from information_schema.tables where table_schema = '") + QLatin1String(d->mysql->db) + QLatin1String("' and table_type = 'VIEW'");
- q.exec(sql);
+ while (q.next())
+ tl.append(q.value(0).toString());
+ }
+ if (type & QSql::Views) {
+ QString sql = QLatin1String("select table_name from information_schema.tables where table_schema = '") + QLatin1String(d->mysql->db) + QLatin1String("' and table_type = 'VIEW'");
+ q.exec(sql);
- while(q.next())
- tl.append(q.value(0).toString());
- }
+ while (q.next())
+ tl.append(q.value(0).toString());
}
-#endif
return tl;
}
@@ -1652,16 +1534,16 @@ QString QMYSQLDriver::formatValue(const QSqlField &field, bool trimStrings) cons
if (field.isNull()) {
r = QStringLiteral("NULL");
} else {
- switch(field.type()) {
- case QVariant::Double:
+ switch (+field.type()) {
+ case QMetaType::Double:
r = QString::number(field.value().toDouble(), 'g', field.precision());
break;
- case QVariant::String:
+ case QMetaType::QString:
// Escape '\' characters
r = QSqlDriver::formatValue(field, trimStrings);
r.replace(QLatin1String("\\"), QLatin1String("\\\\"));
break;
- case QVariant::ByteArray:
+ case QMetaType::QByteArray:
if (isOpen()) {
const QByteArray ba = field.value().toByteArray();
// buffer has to be at least length*2+1 bytes
diff --git a/src/plugins/sqldrivers/mysql/qsql_mysql_p.h b/src/plugins/sqldrivers/mysql/qsql_mysql_p.h
index 48b04fb1f5..9ccc8f4e4f 100644
--- a/src/plugins/sqldrivers/mysql/qsql_mysql_p.h
+++ b/src/plugins/sqldrivers/mysql/qsql_mysql_p.h
@@ -75,8 +75,8 @@ class Q_EXPORT_SQLDRIVER_MYSQL QMYSQLDriver : public QSqlDriver
Q_DECLARE_PRIVATE(QMYSQLDriver)
Q_OBJECT
public:
- explicit QMYSQLDriver(QObject *parent=0);
- explicit QMYSQLDriver(MYSQL *con, QObject * parent=0);
+ explicit QMYSQLDriver(QObject *parent=nullptr);
+ explicit QMYSQLDriver(MYSQL *con, QObject * parent=nullptr);
~QMYSQLDriver();
bool hasFeature(DriverFeature f) const override;
bool open(const QString & db,
diff --git a/src/plugins/sqldrivers/oci/qsql_oci.cpp b/src/plugins/sqldrivers/oci/qsql_oci.cpp
index aee8e92b36..8da9837a59 100644
--- a/src/plugins/sqldrivers/oci/qsql_oci.cpp
+++ b/src/plugins/sqldrivers/oci/qsql_oci.cpp
@@ -2230,7 +2230,7 @@ bool QOCIDriver::hasFeature(DriverFeature f) const
static void qParseOpts(const QString &options, QOCIDriverPrivate *d)
{
- const QStringList opts(options.split(QLatin1Char(';'), QString::SkipEmptyParts));
+ const QStringList opts(options.split(QLatin1Char(';'), Qt::SkipEmptyParts));
for (int i = 0; i < opts.count(); ++i) {
const QString tmp(opts.at(i));
int idx;
diff --git a/src/plugins/sqldrivers/odbc/qsql_odbc.cpp b/src/plugins/sqldrivers/odbc/qsql_odbc.cpp
index 7709b13cd1..88f1c74028 100644
--- a/src/plugins/sqldrivers/odbc/qsql_odbc.cpp
+++ b/src/plugins/sqldrivers/odbc/qsql_odbc.cpp
@@ -118,23 +118,19 @@ class QODBCDriverPrivate : public QSqlDriverPrivate
Q_DECLARE_PUBLIC(QODBCDriver)
public:
- enum DefaultCase{Lower, Mixed, Upper, Sensitive};
- QODBCDriverPrivate()
- : QSqlDriverPrivate(), hEnv(0), hDbc(0), unicode(false), useSchema(false), disconnectCount(0), datetime_precision(19),
- isFreeTDSDriver(false), hasSQLFetchScroll(true), hasMultiResultSets(false), isQuoteInitialized(false), quote(QLatin1Char('"'))
- {
- }
+ enum DefaultCase {Lower, Mixed, Upper, Sensitive};
+ using QSqlDriverPrivate::QSqlDriverPrivate;
- SQLHANDLE hEnv;
- SQLHANDLE hDbc;
+ SQLHANDLE hEnv = nullptr;
+ SQLHANDLE hDbc = nullptr;
- bool unicode;
- bool useSchema;
- int disconnectCount;
- int datetime_precision;
- bool isFreeTDSDriver;
- bool hasSQLFetchScroll;
- bool hasMultiResultSets;
+ int disconnectCount = 0;
+ int datetimePrecision = 19;
+ bool unicode = false;
+ bool useSchema = false;
+ bool isFreeTDSDriver = false;
+ bool hasSQLFetchScroll = true;
+ bool hasMultiResultSets = false;
bool checkDriver() const;
void checkUnicode();
@@ -150,8 +146,8 @@ public:
QString adjustCase(const QString&) const;
QChar quoteChar();
private:
- bool isQuoteInitialized;
- QChar quote;
+ bool isQuoteInitialized = false;
+ QChar quote = QLatin1Char('"');
};
class QODBCResultPrivate;
@@ -194,10 +190,7 @@ class QODBCResultPrivate: public QSqlResultPrivate
public:
Q_DECLARE_SQLDRIVER_PRIVATE(QODBCDriver)
QODBCResultPrivate(QODBCResult *q, const QODBCDriver *db)
- : QSqlResultPrivate(q, db),
- hStmt(0),
- useSchema(false),
- hasSQLFetchScroll(true)
+ : QSqlResultPrivate(q, db)
{
unicode = drv_d_func()->unicode;
useSchema = drv_d_func()->useSchema;
@@ -210,16 +203,15 @@ public:
SQLHANDLE dpEnv() const { return drv_d_func() ? drv_d_func()->hEnv : 0;}
SQLHANDLE dpDbc() const { return drv_d_func() ? drv_d_func()->hDbc : 0;}
- SQLHANDLE hStmt;
-
- bool unicode;
- bool useSchema;
+ SQLHANDLE hStmt = nullptr;
QSqlRecord rInf;
QVector<QVariant> fieldCache;
- int fieldCacheIdx;
- int disconnectCount;
- bool hasSQLFetchScroll;
+ int fieldCacheIdx = 0;
+ int disconnectCount = 0;
+ bool hasSQLFetchScroll = true;
+ bool unicode = false;
+ bool useSchema = false;
bool isStmtHandleValid() const;
void updateStmtHandleState();
@@ -775,7 +767,7 @@ QChar QODBCDriverPrivate::quoteChar()
bool QODBCDriverPrivate::setConnectionOptions(const QString& connOpts)
{
// Set any connection attributes
- const QStringList opts(connOpts.split(QLatin1Char(';'), QString::SkipEmptyParts));
+ const QStringList opts(connOpts.split(QLatin1Char(';'), Qt::SkipEmptyParts));
SQLRETURN r = SQL_SUCCESS;
for (int i = 0; i < opts.count(); ++i) {
const QString tmp(opts.at(i));
@@ -1422,7 +1414,7 @@ bool QODBCResult::exec()
SQLLEN *ind = &indicators[i];
if (val.isNull())
*ind = SQL_NULL_DATA;
- switch (val.type()) {
+ switch (val.userType()) {
case QVariant::Date: {
QByteArray &ba = tmpStorage[i];
ba.resize(sizeof(DATE_STRUCT));
@@ -1464,20 +1456,22 @@ bool QODBCResult::exec()
case QVariant::DateTime: {
QByteArray &ba = tmpStorage[i];
ba.resize(sizeof(TIMESTAMP_STRUCT));
- TIMESTAMP_STRUCT * dt = (TIMESTAMP_STRUCT *)const_cast<char *>(ba.constData());
- QDateTime qdt = val.toDateTime();
- dt->year = qdt.date().year();
- dt->month = qdt.date().month();
- dt->day = qdt.date().day();
- dt->hour = qdt.time().hour();
- dt->minute = qdt.time().minute();
- dt->second = qdt.time().second();
-
- int precision = d->drv_d_func()->datetime_precision - 20; // (20 includes a separating period)
+ TIMESTAMP_STRUCT *dt = reinterpret_cast<TIMESTAMP_STRUCT *>(const_cast<char *>(ba.constData()));
+ const QDateTime qdt = val.toDateTime();
+ const QDate qdate = qdt.date();
+ const QTime qtime = qdt.time();
+ dt->year = qdate.year();
+ dt->month = qdate.month();
+ dt->day = qdate.day();
+ dt->hour = qtime.hour();
+ dt->minute = qtime.minute();
+ dt->second = qtime.second();
+ // (20 includes a separating period)
+ const int precision = d->drv_d_func()->datetimePrecision - 20;
if (precision <= 0) {
dt->fraction = 0;
} else {
- dt->fraction = qdt.time().msec() * 1000000;
+ dt->fraction = qtime.msec() * 1000000;
// (How many leading digits do we want to keep? With SQL Server 2005, this should be 3: 123000000)
int keep = (int)qPow(10.0, 9 - qMin(9, precision));
@@ -1489,7 +1483,7 @@ bool QODBCResult::exec()
qParamType[bindValueType(i) & QSql::InOut],
SQL_C_TIMESTAMP,
SQL_TIMESTAMP,
- d->drv_d_func()->datetime_precision,
+ d->drv_d_func()->datetimePrecision,
precision,
(void *) dt,
0,
@@ -1694,7 +1688,7 @@ bool QODBCResult::exec()
return true;
for (i = 0; i < values.count(); ++i) {
- switch (values.at(i).type()) {
+ switch (values.at(i).userType()) {
case QVariant::Date: {
DATE_STRUCT ds = *((DATE_STRUCT *)const_cast<char *>(tmpStorage.at(i).constData()));
values[i] = QVariant(QDate(ds.year, ds.month, ds.day));
@@ -1735,7 +1729,7 @@ bool QODBCResult::exec()
break; }
}
if (indicators[i] == SQL_NULL_DATA)
- values[i] = QVariant(values[i].type());
+ values[i] = QVariant(QVariant::Type(values[i].userType()));
}
return true;
}
@@ -2245,7 +2239,7 @@ void QODBCDriverPrivate::checkDateTimePrecision()
if ( r == SQL_SUCCESS || r == SQL_SUCCESS_WITH_INFO )
{
if (SQLGetData(hStmt, 3, SQL_INTEGER, &columnSize, sizeof(columnSize), 0) == SQL_SUCCESS) {
- datetime_precision = (int)columnSize;
+ datetimePrecision = (int)columnSize;
}
}
}
@@ -2385,7 +2379,7 @@ QStringList QODBCDriver::tables(QSql::TableType type) const
}
while (r == SQL_SUCCESS) {
- QString fieldVal = qGetStringData(hStmt, 2, -1, false);
+ QString fieldVal = qGetStringData(hStmt, 2, -1, d->unicode);
tl.append(fieldVal);
if (d->hasSQLFetchScroll)
diff --git a/src/plugins/sqldrivers/psql/qsql_psql.cpp b/src/plugins/sqldrivers/psql/qsql_psql.cpp
index e0f82eee73..38bf355856 100644
--- a/src/plugins/sqldrivers/psql/qsql_psql.cpp
+++ b/src/plugins/sqldrivers/psql/qsql_psql.cpp
@@ -149,26 +149,17 @@ class QPSQLDriverPrivate final : public QSqlDriverPrivate
{
Q_DECLARE_PUBLIC(QPSQLDriver)
public:
- QPSQLDriverPrivate() : QSqlDriverPrivate(),
- connection(nullptr),
- isUtf8(false),
- pro(QPSQLDriver::Version6),
- sn(nullptr),
- pendingNotifyCheck(false),
- hasBackslashEscape(false),
- stmtCount(0),
- currentStmtId(InvalidStatementId)
- { dbmsType = QSqlDriver::PostgreSQL; }
-
- PGconn *connection;
- bool isUtf8;
- QPSQLDriver::Protocol pro;
- QSocketNotifier *sn;
+ QPSQLDriverPrivate() : QSqlDriverPrivate(QSqlDriver::PostgreSQL) {}
+
QStringList seid;
- mutable bool pendingNotifyCheck;
- bool hasBackslashEscape;
- int stmtCount;
- StatementId currentStmtId;
+ PGconn *connection = nullptr;
+ QSocketNotifier *sn = nullptr;
+ QPSQLDriver::Protocol pro = QPSQLDriver::Version6;
+ StatementId currentStmtId = InvalidStatementId;
+ int stmtCount = 0;
+ mutable bool pendingNotifyCheck = false;
+ bool hasBackslashEscape = false;
+ bool isUtf8 = false;
void appendTables(QStringList &tl, QSqlQuery &t, QChar type);
PGresult *exec(const char *stmt);
@@ -297,25 +288,18 @@ class QPSQLResultPrivate : public QSqlResultPrivate
Q_DECLARE_PUBLIC(QPSQLResult)
public:
Q_DECLARE_SQLDRIVER_PRIVATE(QPSQLDriver)
- QPSQLResultPrivate(QPSQLResult *q, const QPSQLDriver *drv)
- : QSqlResultPrivate(q, drv),
- result(nullptr),
- stmtId(InvalidStatementId),
- currentSize(-1),
- canFetchMoreRows(false),
- preparedQueriesEnabled(false)
- { }
+ using QSqlResultPrivate::QSqlResultPrivate;
QString fieldSerial(int i) const override { return QLatin1Char('$') + QString::number(i + 1); }
void deallocatePreparedStmt();
- PGresult *result;
std::queue<PGresult*> nextResultSets;
QString preparedStmtId;
- StatementId stmtId;
- int currentSize;
- bool canFetchMoreRows;
- bool preparedQueriesEnabled;
+ PGresult *result = nullptr;
+ StatementId stmtId = InvalidStatementId;
+ int currentSize = -1;
+ bool canFetchMoreRows = false;
+ bool preparedQueriesEnabled = false;
bool processResults();
};
@@ -1684,7 +1668,12 @@ void QPSQLDriver::_q_handleNotification(int)
if (notify->extra)
payload = d->isUtf8 ? QString::fromUtf8(notify->extra) : QString::fromLatin1(notify->extra);
#endif
+#if QT_DEPRECATED_SINCE(5, 15)
+QT_WARNING_PUSH
+QT_WARNING_DISABLE_DEPRECATED
emit notification(name);
+QT_WARNING_POP
+#endif
QSqlDriver::NotificationSource source = (notify->be_pid == PQbackendPID(d->connection)) ? QSqlDriver::SelfSource : QSqlDriver::OtherSource;
emit notification(name, source, payload);
}
diff --git a/src/plugins/sqldrivers/sqlite/qsql_sqlite.cpp b/src/plugins/sqldrivers/sqlite/qsql_sqlite.cpp
index 001bd673fc..5eb9e7d2f8 100644
--- a/src/plugins/sqldrivers/sqlite/qsql_sqlite.cpp
+++ b/src/plugins/sqldrivers/sqlite/qsql_sqlite.cpp
@@ -144,42 +144,33 @@ class QSQLiteDriverPrivate : public QSqlDriverPrivate
Q_DECLARE_PUBLIC(QSQLiteDriver)
public:
- inline QSQLiteDriverPrivate() : QSqlDriverPrivate(), access(0) { dbmsType = QSqlDriver::SQLite; }
- sqlite3 *access;
- QList <QSQLiteResult *> results;
+ inline QSQLiteDriverPrivate() : QSqlDriverPrivate(QSqlDriver::SQLite) {}
+ sqlite3 *access = nullptr;
+ QVector<QSQLiteResult *> results;
QStringList notificationid;
};
-class QSQLiteResultPrivate: public QSqlCachedResultPrivate
+class QSQLiteResultPrivate : public QSqlCachedResultPrivate
{
Q_DECLARE_PUBLIC(QSQLiteResult)
public:
Q_DECLARE_SQLDRIVER_PRIVATE(QSQLiteDriver)
- QSQLiteResultPrivate(QSQLiteResult *q, const QSQLiteDriver *drv);
+ using QSqlCachedResultPrivate::QSqlCachedResultPrivate;
void cleanup();
bool fetchNext(QSqlCachedResult::ValueCache &values, int idx, bool initialFetch);
// initializes the recordInfo and the cache
void initColumns(bool emptyResultset);
void finalize();
- sqlite3_stmt *stmt;
-
- bool skippedStatus; // the status of the fetchNext() that's skipped
- bool skipRow; // skip the next fetchNext()?
+ sqlite3_stmt *stmt = nullptr;
QSqlRecord rInf;
QVector<QVariant> firstRow;
+ bool skippedStatus = false; // the status of the fetchNext() that's skipped
+ bool skipRow = false; // skip the next fetchNext()?
};
-QSQLiteResultPrivate::QSQLiteResultPrivate(QSQLiteResult *q, const QSQLiteDriver *drv)
- : QSqlCachedResultPrivate(q, drv),
- stmt(0),
- skippedStatus(false),
- skipRow(false)
-{
-}
-
void QSQLiteResultPrivate::cleanup()
{
Q_Q(QSQLiteResult);
@@ -505,7 +496,7 @@ bool QSQLiteResult::exec()
if (value.isNull()) {
res = sqlite3_bind_null(d->stmt, i + 1);
} else {
- switch (value.type()) {
+ switch (value.userType()) {
case QVariant::ByteArray: {
const QByteArray *ba = static_cast<const QByteArray*>(value.constData());
res = sqlite3_bind_blob(d->stmt, i + 1, ba->constData(),
@@ -1044,7 +1035,12 @@ void QSQLiteDriver::handleNotification(const QString &tableName, qint64 rowid)
{
Q_D(const QSQLiteDriver);
if (d->notificationid.contains(tableName)) {
+#if QT_DEPRECATED_SINCE(5, 15)
+QT_WARNING_PUSH
+QT_WARNING_DISABLE_DEPRECATED
emit notification(tableName);
+QT_WARNING_POP
+#endif
emit notification(tableName, QSqlDriver::UnknownSource, QVariant(rowid));
}
}
diff --git a/src/plugins/sqldrivers/sqlite2/qsql_sqlite2_p.h b/src/plugins/sqldrivers/sqlite2/qsql_sqlite2_p.h
index 48c64536f1..57db0a4d47 100644
--- a/src/plugins/sqldrivers/sqlite2/qsql_sqlite2_p.h
+++ b/src/plugins/sqldrivers/sqlite2/qsql_sqlite2_p.h
@@ -76,8 +76,8 @@ class Q_EXPORT_SQLDRIVER_SQLITE2 QSQLite2Driver : public QSqlDriver
Q_DECLARE_PRIVATE(QSQLite2Driver)
Q_OBJECT
public:
- explicit QSQLite2Driver(QObject *parent = 0);
- explicit QSQLite2Driver(sqlite *connection, QObject *parent = 0);
+ explicit QSQLite2Driver(QObject *parent = nullptr);
+ explicit QSQLite2Driver(sqlite *connection, QObject *parent = nullptr);
~QSQLite2Driver();
bool hasFeature(DriverFeature f) const override;
bool open(const QString &db,
diff --git a/src/plugins/sqldrivers/tds/qsql_tds_p.h b/src/plugins/sqldrivers/tds/qsql_tds_p.h
index 948e3c7024..b72fababbb 100644
--- a/src/plugins/sqldrivers/tds/qsql_tds_p.h
+++ b/src/plugins/sqldrivers/tds/qsql_tds_p.h
@@ -85,8 +85,8 @@ class Q_EXPORT_SQLDRIVER_TDS QTDSDriver : public QSqlDriver
Q_OBJECT
friend class QTDSResultPrivate;
public:
- explicit QTDSDriver(QObject* parent = 0);
- QTDSDriver(LOGINREC* rec, const QString& host, const QString &db, QObject* parent = 0);
+ explicit QTDSDriver(QObject* parent = nullptr);
+ QTDSDriver(LOGINREC* rec, const QString& host, const QString &db, QObject* parent = nullptr);
~QTDSDriver();
bool hasFeature(DriverFeature f) const override;
bool open(const QString &db,
diff --git a/src/plugins/styles/mac/qmacstyle_mac.mm b/src/plugins/styles/mac/qmacstyle_mac.mm
index 71eb88008e..8e4aaa19c7 100644
--- a/src/plugins/styles/mac/qmacstyle_mac.mm
+++ b/src/plugins/styles/mac/qmacstyle_mac.mm
@@ -56,6 +56,7 @@
#include <QtCore/private/qcore_mac_p.h>
+#include <QtGui/qpainterpath.h>
#include <QtGui/private/qcoregraphics_p.h>
#include <QtGui/qpa/qplatformfontdatabase.h>
#include <QtGui/qpa/qplatformtheme.h>
@@ -236,6 +237,18 @@ static QLinearGradient titlebarGradientInactive()
}
#if QT_CONFIG(tabwidget)
+/*
+ Since macOS 10.14 AppKit is using transparency more extensively, especially for the
+ dark theme. Inactive buttons, for example, are semi-transparent. And we use them to
+ draw tab widget's tab bar. The combination of NSBox (also a part of tab widget)
+ and these transparent buttons gives us an undesired side-effect: an outline of
+ NSBox is visible through transparent buttons. To avoid this, we have this hack below:
+ we clip the area where the line would be visible through the buttons. The area we
+ want to clip away can be described as an intersection of the option's rect and
+ the tab widget's tab bar rect. But some adjustments are required, since those rects
+ are anyway adjusted during the rendering and they are not exactly what you'll see on
+ the screen. Thus this switch-statement inside.
+*/
static void clipTabBarFrame(const QStyleOption *option, const QMacStyle *style, CGContextRef ctx)
{
Q_ASSERT(option);
@@ -246,7 +259,19 @@ static void clipTabBarFrame(const QStyleOption *option, const QMacStyle *style,
QTabWidget *tabWidget = qobject_cast<QTabWidget *>(option->styleObject);
Q_ASSERT(tabWidget);
- const QRect tabBarRect = style->subElementRect(QStyle::SE_TabWidgetTabBar, option, tabWidget).adjusted(2, 2, -3, -2);
+ QRect tabBarRect = style->subElementRect(QStyle::SE_TabWidgetTabBar, option, tabWidget).adjusted(2, 0, -3, 0);
+ switch (tabWidget->tabPosition()) {
+ case QTabWidget::South:
+ tabBarRect.setY(tabBarRect.y() + tabBarRect.height() / 2);
+ break;
+ case QTabWidget::North:
+ case QTabWidget::West:
+ tabBarRect = tabBarRect.adjusted(0, 2, 0, -2);
+ break;
+ case QTabWidget::East:
+ tabBarRect = tabBarRect.adjusted(tabBarRect.width() / 2, 2, tabBarRect.width() / 2, -2);
+ }
+
const QRegion clipPath = QRegion(option->rect) - tabBarRect;
QVarLengthArray<CGRect, 3> cgRects;
for (const QRect &qtRect : clipPath)
@@ -1388,14 +1413,22 @@ void QMacStylePrivate::tabLayout(const QStyleOptionTab *opt, const QWidget *widg
// High-dpi icons do not need adjustment; make sure tabIconSize is not larger than iconSize
tabIconSize = QSize(qMin(tabIconSize.width(), iconSize.width()), qMin(tabIconSize.height(), iconSize.height()));
- *iconRect = QRect(tr.left(), tr.center().y() - tabIconSize.height() / 2,
- tabIconSize.width(), tabIconSize.height());
+ const int stylePadding = proxyStyle->pixelMetric(QStyle::PM_TabBarTabHSpace, opt, widget) / 2 - hpadding;
+
+ if (opt->documentMode) {
+ // documents show the icon as part of the the text
+ const int textWidth =
+ opt->fontMetrics.boundingRect(tr, Qt::AlignCenter | Qt::TextShowMnemonic, opt->text).width();
+ *iconRect = QRect(tr.center().x() - textWidth / 2 - stylePadding - tabIconSize.width(),
+ tr.center().y() - tabIconSize.height() / 2,
+ tabIconSize.width(), tabIconSize.height());
+ } else {
+ *iconRect = QRect(tr.left() + stylePadding, tr.center().y() - tabIconSize.height() / 2,
+ tabIconSize.width(), tabIconSize.height());
+ }
if (!verticalTabs)
*iconRect = proxyStyle->visualRect(opt->direction, opt->rect, *iconRect);
- int stylePadding = proxyStyle->pixelMetric(QStyle::PM_TabBarTabHSpace, opt, widget) / 2;
- stylePadding -= hpadding;
-
tr.setLeft(tr.left() + stylePadding + tabIconSize.width() + 4);
tr.setRight(tr.right() - stylePadding - tabIconSize.width() - 4);
}
@@ -2553,7 +2586,7 @@ QPalette QMacStyle::standardPalette() const
auto platformTheme = QGuiApplicationPrivate::platformTheme();
auto styleNames = platformTheme->themeHint(QPlatformTheme::StyleNames);
if (styleNames.toStringList().contains("macintosh"))
- return *platformTheme->palette();
+ return QPalette(); // Inherit everything from theme
else
return QStyle::standardPalette();
}
@@ -2873,7 +2906,7 @@ int QMacStyle::styleHint(StyleHint sh, const QStyleOption *opt, const QWidget *w
ret = false;
break;
case SH_Table_GridLineColor:
- ret = int(qt_mac_toQColor(NSColor.gridColor).rgb());
+ ret = int(qt_mac_toQColor(NSColor.gridColor).rgba());
break;
default:
ret = QCommonStyle::styleHint(sh, opt, w, hret);
@@ -3064,13 +3097,18 @@ void QMacStyle::drawPrimitive(PrimitiveElement pe, const QStyleOption *opt, QPai
bool needTranslation = false;
if (QOperatingSystemVersion::current() >= QOperatingSystemVersion::MacOSMojave
&& !qt_mac_applicationIsInDarkMode()) {
- // Another surprise from AppKit (SDK 10.14) - -displayRectIgnoringOpacity:
- // is different from drawRect: for some Apple-known reason box is smaller
- // in height than we need, resulting in tab buttons sitting too high/not
- // centered. Attempts to play with insets etc did not work - the same wrong
- // height. Simple translation is not working (too much space "at bottom"),
- // so we make it bigger and translate (otherwise it's clipped at bottom btw).
- adjustedRect.adjust(0, 0, 0, 3);
+ // In Aqua theme we have to use the 'default' NSBox (as opposite
+ // to the 'custom' QDarkNSBox we use in dark theme). Since -drawRect:
+ // does nothing in default NSBox, we call -displayRectIgnoringOpaticty:.
+ // Unfortunately, the resulting box is smaller then the actual rect we
+ // wanted. This can be seen, e.g. because tabs (buttons) are misaligned
+ // vertically and even worse, if QTabWidget has autoFillBackground
+ // set, this background overpaints NSBox making it to disappear.
+ // We trick our NSBox to render in a larger rectangle, so that
+ // the actuall result (which is again smaller than requested),
+ // more or less is what we really want. We'll have to adjust CTM
+ // and translate accordingly.
+ adjustedRect.adjust(0, 0, 6, 6);
needTranslation = true;
}
d->drawNSViewInRect(box, adjustedRect, p, ^(CGContextRef ctx, const CGRect &rect) {
@@ -3085,7 +3123,7 @@ void QMacStyle::drawPrimitive(PrimitiveElement pe, const QStyleOption *opt, QPai
[box drawRect:rect];
} else {
if (needTranslation)
- CGContextTranslateCTM(ctx, 0.0, 4.0);
+ CGContextTranslateCTM(ctx, -3.0, 5.0);
[box displayRectIgnoringOpacity:box.bounds inContext:NSGraphicsContext.currentContext];
}
});
@@ -4594,6 +4632,7 @@ QRect QMacStyle::subElementRect(SubElement sr, const QStyleOption *opt,
case SE_ToolBoxTabContents:
rect = QCommonStyle::subElementRect(sr, opt, widget);
break;
+ case SE_PushButtonBevel:
case SE_PushButtonContents:
if (const QStyleOptionButton *btn = qstyleoption_cast<const QStyleOptionButton *>(opt)) {
// Comment from the old HITheme days:
@@ -4607,9 +4646,20 @@ QRect QMacStyle::subElementRect(SubElement sr, const QStyleOption *opt,
const auto ct = cocoaControlType(btn, widget);
const auto cs = d->effectiveAquaSizeConstrain(btn, widget);
const auto cw = QMacStylePrivate::CocoaControl(ct, cs);
- const auto frameRect = cw.adjustedControlFrame(btn->rect);
- const auto titleMargins = cw.titleMargins();
- rect = (frameRect - titleMargins).toRect();
+ auto frameRect = cw.adjustedControlFrame(btn->rect);
+ if (sr == SE_PushButtonContents) {
+ frameRect -= cw.titleMargins();
+ } else {
+ auto *pb = static_cast<NSButton *>(d->cocoaControl(cw));
+ if (cw.type != QMacStylePrivate::Button_SquareButton) {
+ frameRect = QRectF::fromCGRect([pb alignmentRectForFrame:pb.frame]);
+ if (cw.type == QMacStylePrivate::Button_PushButton)
+ frameRect -= pushButtonShadowMargins[cw.size];
+ else if (cw.type == QMacStylePrivate::Button_PullDown)
+ frameRect -= pullDownButtonShadowMargins[cw.size];
+ }
+ }
+ rect = frameRect.toRect();
}
break;
case SE_HeaderLabel: {
diff --git a/src/plugins/styles/mac/qmacstyle_mac_p_p.h b/src/plugins/styles/mac/qmacstyle_mac_p_p.h
index d6af18f01f..274936bd79 100644
--- a/src/plugins/styles/mac/qmacstyle_mac_p_p.h
+++ b/src/plugins/styles/mac/qmacstyle_mac_p_p.h
@@ -284,7 +284,7 @@ public:
CocoaControlType windowButtonCocoaControl(QStyle::SubControl sc) const;
#if QT_CONFIG(tabbar)
- void tabLayout(const QStyleOptionTab *opt, const QWidget *widget, QRect *textRect, QRect *iconRect) const;
+ void tabLayout(const QStyleOptionTab *opt, const QWidget *widget, QRect *textRect, QRect *iconRect) const override;
static Direction tabDirection(QTabBar::Shape shape);
static bool verticalTabs(QMacStylePrivate::Direction tabDirection);
#endif
diff --git a/src/plugins/styles/windowsvista/qwindowsvistastyle.cpp b/src/plugins/styles/windowsvista/qwindowsvistastyle.cpp
index f9d26c49ae..30b3786a80 100644
--- a/src/plugins/styles/windowsvista/qwindowsvistastyle.cpp
+++ b/src/plugins/styles/windowsvista/qwindowsvistastyle.cpp
@@ -1365,6 +1365,7 @@ void QWindowsVistaStyle::drawControl(ControlElement element, const QStyleOption
QWindowsStyle::drawControl(element, &copyOpt, painter, widget);
}
break;
+#if QT_CONFIG(dockwidget)
case CE_DockWidgetTitle:
if (const QStyleOptionDockWidget *dwOpt = qstyleoption_cast<const QStyleOptionDockWidget *>(option)) {
const QDockWidget *dockWidget = qobject_cast<const QDockWidget *>(widget);
@@ -1431,6 +1432,7 @@ void QWindowsVistaStyle::drawControl(ControlElement element, const QStyleOption
}
}
break;
+#endif // QT_CONFIG(dockwidget)
#if QT_CONFIG(itemviews)
case CE_ItemViewItem:
{
@@ -2110,7 +2112,7 @@ int QWindowsVistaStyle::styleHint(StyleHint hint, const QStyleOption *option, co
break;
case SH_Table_GridLineColor:
if (option)
- ret = int(option->palette.color(QPalette::Base).darker(118).rgb());
+ ret = int(option->palette.color(QPalette::Base).darker(118).rgba());
else
ret = -1;
break;
@@ -2311,11 +2313,13 @@ void QWindowsVistaStyle::polish(QWidget *widget)
#endif // QT_CONFIG(lineedit)
if (qobject_cast<QGroupBox*>(widget))
widget->setAttribute(Qt::WA_Hover);
+#if QT_CONFIG(commandlinkbutton)
else if (qobject_cast<QCommandLinkButton*>(widget)) {
QFont buttonFont = widget->font();
buttonFont.setFamily(QLatin1String("Segoe UI"));
widget->setFont(buttonFont);
}
+#endif // QT_CONFIG(commandlinkbutton)
else if (widget->inherits("QTipLabel")){
//note that since tooltips are not reused
//we do not have to care about unpolishing
@@ -2392,12 +2396,15 @@ void QWindowsVistaStyle::unpolish(QWidget *widget)
#endif // QT_CONFIG(inputdialog)
else if (QTreeView *tree = qobject_cast<QTreeView *> (widget)) {
tree->viewport()->setAttribute(Qt::WA_Hover, false);
- } else if (qobject_cast<QCommandLinkButton*>(widget)) {
+ }
+#if QT_CONFIG(commandlinkbutton)
+ else if (qobject_cast<QCommandLinkButton*>(widget)) {
QFont font = QApplication::font("QCommandLinkButton");
QFont widgetFont = widget->font();
widgetFont.setFamily(font.family()); //Only family set by polish
widget->setFont(widgetFont);
}
+#endif // QT_CONFIG(commandlinkbutton)
}
diff --git a/src/plugins/styles/windowsvista/qwindowsvistastyle_p_p.h b/src/plugins/styles/windowsvista/qwindowsvistastyle_p_p.h
index 8fef9f9927..c1d764a60e 100644
--- a/src/plugins/styles/windowsvista/qwindowsvistastyle_p_p.h
+++ b/src/plugins/styles/windowsvista/qwindowsvistastyle_p_p.h
@@ -106,7 +106,9 @@
#include <qtableview.h>
#endif
#include <qdatetime.h>
+#if QT_CONFIG(commandlinkbutton)
#include <qcommandlinkbutton.h>
+#endif
QT_BEGIN_NAMESPACE
diff --git a/src/plugins/styles/windowsvista/qwindowsxpstyle.cpp b/src/plugins/styles/windowsvista/qwindowsxpstyle.cpp
index ba590b3eca..e43746e79f 100644
--- a/src/plugins/styles/windowsvista/qwindowsxpstyle.cpp
+++ b/src/plugins/styles/windowsvista/qwindowsxpstyle.cpp
@@ -225,9 +225,11 @@ static HRGN qt_hrgn_from_qregion(const QRegion &region)
*/
bool QWindowsXPStylePrivate::useXP(bool update)
{
- if (!update)
- return use_xp;
- return use_xp = IsThemeActive() && (IsAppThemed() || !QCoreApplication::instance());
+ if (update) {
+ use_xp = IsThemeActive() && (IsAppThemed() || !QCoreApplication::instance())
+ && !QWindowsStylePrivate::isDarkMode();
+ }
+ return use_xp;
}
/* \internal
@@ -663,7 +665,7 @@ static inline bool isFullyOpaque(const XPThemeData &themeData)
\note drawBackgroundThruNativeBuffer() can return false for large
sizes due to buffer()/CreateDIBSection() failing.
*/
-bool QWindowsXPStylePrivate::drawBackground(XPThemeData &themeData)
+bool QWindowsXPStylePrivate::drawBackground(XPThemeData &themeData, qreal correctionFactor)
{
if (themeData.rect.isEmpty())
return true;
@@ -708,9 +710,9 @@ bool QWindowsXPStylePrivate::drawBackground(XPThemeData &themeData)
}
const HDC dc = canDrawDirectly ? hdcForWidgetBackingStore(themeData.widget) : nullptr;
- const bool result = dc
+ const bool result = dc && qFuzzyCompare(correctionFactor, qreal(1))
? drawBackgroundDirectly(dc, themeData, aditionalDevicePixelRatio)
- : drawBackgroundThruNativeBuffer(themeData, aditionalDevicePixelRatio);
+ : drawBackgroundThruNativeBuffer(themeData, aditionalDevicePixelRatio, correctionFactor);
painter->restore();
return result;
}
@@ -784,9 +786,14 @@ bool QWindowsXPStylePrivate::drawBackgroundDirectly(HDC dc, XPThemeData &themeDa
other pixmaps etc), or when special transformations are needed (e.g.
flips (horizonal mirroring only, vertical are handled by the theme
engine).
+
+ \a correctionFactor is an additional factor used to scale up controls
+ that are too small on High DPI screens, as has been observed for
+ WP_MDICLOSEBUTTON, WP_MDIRESTOREBUTTON, WP_MDIMINBUTTON (QTBUG-75927).
*/
bool QWindowsXPStylePrivate::drawBackgroundThruNativeBuffer(XPThemeData &themeData,
- qreal additionalDevicePixelRatio)
+ qreal additionalDevicePixelRatio,
+ qreal correctionFactor)
{
QPainter *painter = themeData.painter;
QRectF rectF = scaleRect(QRectF(themeData.rect), additionalDevicePixelRatio);
@@ -795,7 +802,11 @@ bool QWindowsXPStylePrivate::drawBackgroundThruNativeBuffer(XPThemeData &themeDa
rectF = QRectF(0, 0, rectF.height(), rectF.width());
}
rectF.moveTo(0, 0);
+
+ const bool hasCorrectionFactor = !qFuzzyCompare(correctionFactor, qreal(1));
QRect rect = rectF.toRect();
+ QRect drawRect = hasCorrectionFactor
+ ? QRectF(rectF.topLeft() / correctionFactor, rectF.size() / correctionFactor).toRect() : rect;
int partId = themeData.partId;
int stateId = themeData.stateId;
int w = rect.width();
@@ -824,6 +835,10 @@ bool QWindowsXPStylePrivate::drawBackgroundThruNativeBuffer(XPThemeData &themeDa
pixmapCacheKey.append(QLatin1Char('h'));
pixmapCacheKey.append(QString::number(additionalDevicePixelRatio));
pixmapCacheKey.append(QLatin1Char('d'));
+ if (hasCorrectionFactor) {
+ pixmapCacheKey.append(QLatin1Char('c'));
+ pixmapCacheKey.append(QString::number(correctionFactor));
+ }
QPixmap cachedPixmap;
ThemeMapKey key(themeData);
@@ -882,7 +897,7 @@ bool QWindowsXPStylePrivate::drawBackgroundThruNativeBuffer(XPThemeData &themeDa
// and DTGB_OMITCONTENT
bool addBorderContentClipping = false;
QRegion extraClip;
- QRect area = rect;
+ QRect area = drawRect;
if (themeData.noBorder || themeData.noContent) {
extraClip = area;
// We are running on a system where the uxtheme.dll does not have
@@ -913,19 +928,19 @@ bool QWindowsXPStylePrivate::drawBackgroundThruNativeBuffer(XPThemeData &themeDa
QImage img;
if (!haveCachedPixmap) { // If the pixmap is not cached, generate it! -------------------------
- if (!buffer(w, h)) // Ensure a buffer of at least (w, h) in size
+ if (!buffer(drawRect.width(), drawRect.height())) // Ensure a buffer of at least (w, h) in size
return false;
HDC dc = bufferHDC();
// Clear the buffer
if (alphaType != NoAlpha) {
// Consider have separate "memset" function for small chunks for more speedup
- memset(bufferPixels, 0x00, bufferW * h * 4);
+ memset(bufferPixels, 0x00, bufferW * drawRect.height() * 4);
}
// Difference between area and rect
- int dx = area.x() - rect.x();
- int dy = area.y() - rect.y();
+ int dx = area.x() - drawRect.x();
+ int dy = area.y() - drawRect.y();
// Adjust so painting rect starts from Origo
rect.moveTo(0,0);
@@ -955,7 +970,7 @@ bool QWindowsXPStylePrivate::drawBackgroundThruNativeBuffer(XPThemeData &themeDa
if (!hasAlpha && partIsTransparent)
potentialInvalidAlpha = true;
#if defined(DEBUG_XP_STYLE) && 1
- dumpNativeDIB(w, h);
+ dumpNativeDIB(drawRect.width(), drawRect.height());
#endif
}
@@ -983,6 +998,8 @@ bool QWindowsXPStylePrivate::drawBackgroundThruNativeBuffer(XPThemeData &themeDa
printf("Image format is: %s\n", alphaType == RealAlpha ? "Real Alpha" : alphaType == MaskAlpha ? "Masked Alpha" : "No Alpha");
#endif
img = QImage(bufferPixels, bufferW, bufferH, format);
+ if (hasCorrectionFactor)
+ img = img.scaled(w, h, Qt::KeepAspectRatio, Qt::SmoothTransformation);
img.setDevicePixelRatio(additionalDevicePixelRatio);
}
@@ -1023,7 +1040,7 @@ bool QWindowsXPStylePrivate::drawBackgroundThruNativeBuffer(XPThemeData &themeDa
imgCopy = cachedPixmap.toImage();
if (themeData.rotate) {
- QMatrix rotMatrix;
+ QTransform rotMatrix;
rotMatrix.rotate(themeData.rotate);
imgCopy = imgCopy.transformed(rotMatrix);
}
@@ -2461,6 +2478,61 @@ QRect QWindowsXPStylePrivate::scrollBarGripperBounds(QStyle::State flags, const
return sufficientSpace ? QRect(theme->rect.topLeft() + QPoint(hSpace, vSpace) / 2, size) : QRect();
}
+#if QT_CONFIG(mdiarea)
+// Helper for drawing MDI buttons into the corner widget of QMenuBar in case a
+// QMdiSubWindow is maximized.
+static void populateMdiButtonTheme(const QStyle *proxy, const QWidget *widget,
+ const QStyleOptionComplex *option,
+ QStyle::SubControl subControl, int part,
+ XPThemeData *theme)
+{
+ theme->partId = part;
+ theme->rect = proxy->subControlRect(QStyle::CC_MdiControls, option, subControl, widget);
+ if (!option->state.testFlag(QStyle::State_Enabled))
+ theme->stateId = CBS_INACTIVE;
+ else if (option->state.testFlag(QStyle::State_Sunken) && option->activeSubControls.testFlag(subControl))
+ theme->stateId = CBS_PUSHED;
+ else if (option->state.testFlag(QStyle::State_MouseOver) && option->activeSubControls.testFlag(subControl))
+ theme->stateId = CBS_HOT;
+ else
+ theme->stateId = CBS_NORMAL;
+}
+
+// Calculate an small (max 2), empirical correction factor for scaling up
+// WP_MDICLOSEBUTTON, WP_MDIRESTOREBUTTON, WP_MDIMINBUTTON, which are too
+// small on High DPI screens (QTBUG-75927).
+qreal mdiButtonCorrectionFactor(XPThemeData &theme, const QPaintDevice *pd = nullptr)
+{
+ const auto dpr = pd ? pd->devicePixelRatioF() : qApp->devicePixelRatio();
+ const QSizeF nativeSize = QSizeF(theme.size()) / dpr;
+ const QSizeF requestedSize(theme.rect.size());
+ const auto rawFactor = qMin(requestedSize.width() / nativeSize.width(),
+ requestedSize.height() / nativeSize.height());
+ const auto factor = rawFactor >= qreal(2) ? qreal(2) : qreal(1);
+ return factor;
+}
+#endif // QT_CONFIG(mdiarea)
+
+static void populateTitleBarButtonTheme(const QStyle *proxy, const QWidget *widget,
+ const QStyleOptionComplex *option,
+ QStyle::SubControl subControl,
+ bool isTitleBarActive, int part,
+ XPThemeData *theme)
+{
+ theme->rect = proxy->subControlRect(QStyle::CC_TitleBar, option, subControl, widget);
+ theme->partId = part;
+ if (widget && !widget->isEnabled())
+ theme->stateId = RBS_DISABLED;
+ else if (option->activeSubControls == subControl && option->state.testFlag(QStyle::State_Sunken))
+ theme->stateId = RBS_PUSHED;
+ else if (option->activeSubControls == subControl && option->state.testFlag(QStyle::State_MouseOver))
+ theme->stateId = RBS_HOT;
+ else if (!isTitleBarActive)
+ theme->stateId = RBS_INACTIVE;
+ else
+ theme->stateId = RBS_NORMAL;
+}
+
/*!
\reimp
*/
@@ -3022,56 +3094,17 @@ void QWindowsXPStyle::drawComplexControl(ComplexControl cc, const QStyleOptionCo
if (sub & SC_TitleBarMinButton && tb->titleBarFlags & Qt::WindowMinimizeButtonHint
&& !(tb->titleBarState & Qt::WindowMinimized)) {
- theme.rect = proxy()->subControlRect(CC_TitleBar, option, SC_TitleBarMinButton, widget);
- partId = WP_MINBUTTON;
- if (widget && !widget->isEnabled())
- stateId = MINBS_DISABLED;
- else if (option->activeSubControls == SC_TitleBarMinButton && (option->state & State_Sunken))
- stateId = MINBS_PUSHED;
- else if (option->activeSubControls == SC_TitleBarMinButton && (option->state & State_MouseOver))
- stateId = MINBS_HOT;
- else if (!isActive)
- stateId = MINBS_INACTIVE;
- else
- stateId = MINBS_NORMAL;
- theme.partId = partId;
- theme.stateId = stateId;
+ populateTitleBarButtonTheme(proxy(), widget, option, SC_TitleBarMinButton, isActive, WP_MINBUTTON, &theme);
d->drawBackground(theme);
}
if (sub & SC_TitleBarMaxButton && tb->titleBarFlags & Qt::WindowMaximizeButtonHint
&& !(tb->titleBarState & Qt::WindowMaximized)) {
- theme.rect = proxy()->subControlRect(CC_TitleBar, option, SC_TitleBarMaxButton, widget);
- partId = WP_MAXBUTTON;
- if (widget && !widget->isEnabled())
- stateId = MAXBS_DISABLED;
- else if (option->activeSubControls == SC_TitleBarMaxButton && (option->state & State_Sunken))
- stateId = MAXBS_PUSHED;
- else if (option->activeSubControls == SC_TitleBarMaxButton && (option->state & State_MouseOver))
- stateId = MAXBS_HOT;
- else if (!isActive)
- stateId = MAXBS_INACTIVE;
- else
- stateId = MAXBS_NORMAL;
- theme.partId = partId;
- theme.stateId = stateId;
+ populateTitleBarButtonTheme(proxy(), widget, option, SC_TitleBarMaxButton, isActive, WP_MAXBUTTON, &theme);
d->drawBackground(theme);
}
if (sub & SC_TitleBarContextHelpButton
&& tb->titleBarFlags & Qt::WindowContextHelpButtonHint) {
- theme.rect = proxy()->subControlRect(CC_TitleBar, option, SC_TitleBarContextHelpButton, widget);
- partId = WP_HELPBUTTON;
- if (widget && !widget->isEnabled())
- stateId = MINBS_DISABLED;
- else if (option->activeSubControls == SC_TitleBarContextHelpButton && (option->state & State_Sunken))
- stateId = MINBS_PUSHED;
- else if (option->activeSubControls == SC_TitleBarContextHelpButton && (option->state & State_MouseOver))
- stateId = MINBS_HOT;
- else if (!isActive)
- stateId = MINBS_INACTIVE;
- else
- stateId = MINBS_NORMAL;
- theme.partId = partId;
- theme.stateId = stateId;
+ populateTitleBarButtonTheme(proxy(), widget, option, SC_TitleBarContextHelpButton, isActive, WP_HELPBUTTON, &theme);
d->drawBackground(theme);
}
bool drawNormalButton = (sub & SC_TitleBarNormalButton)
@@ -3080,74 +3113,21 @@ void QWindowsXPStyle::drawComplexControl(ComplexControl cc, const QStyleOptionCo
|| ((tb->titleBarFlags & Qt::WindowMaximizeButtonHint)
&& (tb->titleBarState & Qt::WindowMaximized)));
if (drawNormalButton) {
- theme.rect = proxy()->subControlRect(CC_TitleBar, option, SC_TitleBarNormalButton, widget);
- partId = WP_RESTOREBUTTON;
- if (widget && !widget->isEnabled())
- stateId = RBS_DISABLED;
- else if (option->activeSubControls == SC_TitleBarNormalButton && (option->state & State_Sunken))
- stateId = RBS_PUSHED;
- else if (option->activeSubControls == SC_TitleBarNormalButton && (option->state & State_MouseOver))
- stateId = RBS_HOT;
- else if (!isActive)
- stateId = RBS_INACTIVE;
- else
- stateId = RBS_NORMAL;
- theme.partId = partId;
- theme.stateId = stateId;
+ populateTitleBarButtonTheme(proxy(), widget, option, SC_TitleBarNormalButton, isActive, WP_RESTOREBUTTON, &theme);
d->drawBackground(theme);
}
if (sub & SC_TitleBarShadeButton && tb->titleBarFlags & Qt::WindowShadeButtonHint
&& !(tb->titleBarState & Qt::WindowMinimized)) {
- theme.rect = proxy()->subControlRect(CC_TitleBar, option, SC_TitleBarShadeButton, widget);
- partId = WP_MINBUTTON;
- if (widget && !widget->isEnabled())
- stateId = MINBS_DISABLED;
- else if (option->activeSubControls == SC_TitleBarShadeButton && (option->state & State_Sunken))
- stateId = MINBS_PUSHED;
- else if (option->activeSubControls == SC_TitleBarShadeButton && (option->state & State_MouseOver))
- stateId = MINBS_HOT;
- else if (!isActive)
- stateId = MINBS_INACTIVE;
- else
- stateId = MINBS_NORMAL;
- theme.partId = partId;
- theme.stateId = stateId;
+ populateTitleBarButtonTheme(proxy(), widget, option, SC_TitleBarShadeButton, isActive, WP_MINBUTTON, &theme);
d->drawBackground(theme);
}
if (sub & SC_TitleBarUnshadeButton && tb->titleBarFlags & Qt::WindowShadeButtonHint
&& tb->titleBarState & Qt::WindowMinimized) {
- theme.rect = proxy()->subControlRect(CC_TitleBar, option, SC_TitleBarUnshadeButton, widget);
- partId = WP_RESTOREBUTTON;
- if (widget && !widget->isEnabled())
- stateId = RBS_DISABLED;
- else if (option->activeSubControls == SC_TitleBarUnshadeButton && (option->state & State_Sunken))
- stateId = RBS_PUSHED;
- else if (option->activeSubControls == SC_TitleBarUnshadeButton && (option->state & State_MouseOver))
- stateId = RBS_HOT;
- else if (!isActive)
- stateId = RBS_INACTIVE;
- else
- stateId = RBS_NORMAL;
- theme.partId = partId;
- theme.stateId = stateId;
+ populateTitleBarButtonTheme(proxy(), widget, option, SC_TitleBarUnshadeButton, isActive, WP_RESTOREBUTTON, &theme);
d->drawBackground(theme);
}
if (sub & SC_TitleBarCloseButton && tb->titleBarFlags & Qt::WindowSystemMenuHint) {
- theme.rect = proxy()->subControlRect(CC_TitleBar, option, SC_TitleBarCloseButton, widget);
- //partId = titlebar->testWFlags(Qt::WA_WState_Tool) ? WP_SMALLCLOSEBUTTON : WP_CLOSEBUTTON;
- partId = WP_CLOSEBUTTON;
- if (widget && !widget->isEnabled())
- stateId = CBS_DISABLED;
- else if (option->activeSubControls == SC_TitleBarCloseButton && (option->state & State_Sunken))
- stateId = CBS_PUSHED;
- else if (option->activeSubControls == SC_TitleBarCloseButton && (option->state & State_MouseOver))
- stateId = CBS_HOT;
- else if (!isActive)
- stateId = CBS_INACTIVE;
- else
- stateId = CBS_NORMAL;
- theme.partId = partId;
- theme.stateId = stateId;
+ populateTitleBarButtonTheme(proxy(), widget, option, SC_TitleBarCloseButton, isActive, WP_CLOSEBUTTON, &theme);
d->drawBackground(theme);
}
}
@@ -3157,56 +3137,21 @@ void QWindowsXPStyle::drawComplexControl(ComplexControl cc, const QStyleOptionCo
#if QT_CONFIG(mdiarea)
case CC_MdiControls:
{
- QRect buttonRect;
XPThemeData theme(widget, p, QWindowsXPStylePrivate::WindowTheme, WP_MDICLOSEBUTTON, CBS_NORMAL);
+ if (Q_UNLIKELY(!theme.isValid()))
+ return;
- if (option->subControls & SC_MdiCloseButton) {
- buttonRect = proxy()->subControlRect(CC_MdiControls, option, SC_MdiCloseButton, widget);
- if (theme.isValid()) {
- theme.partId = WP_MDICLOSEBUTTON;
- theme.rect = buttonRect;
- if (!(flags & State_Enabled))
- theme.stateId = CBS_INACTIVE;
- else if (flags & State_Sunken && (option->activeSubControls & SC_MdiCloseButton))
- theme.stateId = CBS_PUSHED;
- else if (flags & State_MouseOver && (option->activeSubControls & SC_MdiCloseButton))
- theme.stateId = CBS_HOT;
- else
- theme.stateId = CBS_NORMAL;
- d->drawBackground(theme);
- }
+ if (option->subControls.testFlag(SC_MdiCloseButton)) {
+ populateMdiButtonTheme(proxy(), widget, option, SC_MdiCloseButton, WP_MDICLOSEBUTTON, &theme);
+ d->drawBackground(theme, mdiButtonCorrectionFactor(theme, widget));
}
- if (option->subControls & SC_MdiNormalButton) {
- buttonRect = proxy()->subControlRect(CC_MdiControls, option, SC_MdiNormalButton, widget);
- if (theme.isValid()) {
- theme.partId = WP_MDIRESTOREBUTTON;
- theme.rect = buttonRect;
- if (!(flags & State_Enabled))
- theme.stateId = CBS_INACTIVE;
- else if (flags & State_Sunken && (option->activeSubControls & SC_MdiNormalButton))
- theme.stateId = CBS_PUSHED;
- else if (flags & State_MouseOver && (option->activeSubControls & SC_MdiNormalButton))
- theme.stateId = CBS_HOT;
- else
- theme.stateId = CBS_NORMAL;
- d->drawBackground(theme);
- }
+ if (option->subControls.testFlag(SC_MdiNormalButton)) {
+ populateMdiButtonTheme(proxy(), widget, option, SC_MdiNormalButton, WP_MDIRESTOREBUTTON, &theme);
+ d->drawBackground(theme, mdiButtonCorrectionFactor(theme, widget));
}
- if (option->subControls & QStyle::SC_MdiMinButton) {
- buttonRect = proxy()->subControlRect(CC_MdiControls, option, SC_MdiMinButton, widget);
- if (theme.isValid()) {
- theme.partId = WP_MDIMINBUTTON;
- theme.rect = buttonRect;
- if (!(flags & State_Enabled))
- theme.stateId = CBS_INACTIVE;
- else if (flags & State_Sunken && (option->activeSubControls & SC_MdiMinButton))
- theme.stateId = CBS_PUSHED;
- else if (flags & State_MouseOver && (option->activeSubControls & SC_MdiMinButton))
- theme.stateId = CBS_HOT;
- else
- theme.stateId = CBS_NORMAL;
- d->drawBackground(theme);
- }
+ if (option->subControls.testFlag(QStyle::SC_MdiMinButton)) {
+ populateMdiButtonTheme(proxy(), widget, option, SC_MdiMinButton, WP_MDIMINBUTTON, &theme);
+ d->drawBackground(theme, mdiButtonCorrectionFactor(theme, widget));
}
}
break;
@@ -3668,19 +3613,20 @@ QSize QWindowsXPStyle::sizeFromContents(ContentsType ct, const QStyleOption *opt
sz = QWindowsStyle::sizeFromContents(ct, option, sz, widget);
break;
- case CT_MdiControls:
+ case CT_MdiControls: {
+ sz.setHeight(int(QStyleHelper::dpiScaled(19, option)));
+ int width = 54;
if (const QStyleOptionComplex *styleOpt = qstyleoption_cast<const QStyleOptionComplex *>(option)) {
- int width = 0;
+ width = 0;
if (styleOpt->subControls & SC_MdiMinButton)
width += 17 + 1;
if (styleOpt->subControls & SC_MdiNormalButton)
width += 17 + 1;
if (styleOpt->subControls & SC_MdiCloseButton)
width += 17 + 1;
- sz = QSize(width, 19);
- } else {
- sz = QSize(54, 19);
}
+ sz.setWidth(int(QStyleHelper::dpiScaled(width, option)));
+ }
break;
default:
@@ -3774,8 +3720,7 @@ int QWindowsXPStyle::styleHint(StyleHint hint, const QStyleOption *option, const
/*! \reimp */
QPalette QWindowsXPStyle::standardPalette() const
{
- return QWindowsXPStylePrivate::useXP() && QApplicationPrivate::sys_pal
- ? *QApplicationPrivate::sys_pal : QWindowsStyle::standardPalette();
+ return QWindowsXPStylePrivate::useXP() ? QPalette() : QWindowsStyle::standardPalette();
}
/*!
diff --git a/src/plugins/styles/windowsvista/qwindowsxpstyle_p_p.h b/src/plugins/styles/windowsvista/qwindowsxpstyle_p_p.h
index ad7754e3d4..06b37a6e5c 100644
--- a/src/plugins/styles/windowsvista/qwindowsxpstyle_p_p.h
+++ b/src/plugins/styles/windowsvista/qwindowsxpstyle_p_p.h
@@ -241,8 +241,8 @@ public:
bool isTransparent(XPThemeData &themeData);
QRegion region(XPThemeData &themeData);
- bool drawBackground(XPThemeData &themeData);
- bool drawBackgroundThruNativeBuffer(XPThemeData &themeData, qreal aditionalDevicePixelRatio);
+ bool drawBackground(XPThemeData &themeData, qreal correctionFactor = 1);
+ bool drawBackgroundThruNativeBuffer(XPThemeData &themeData, qreal aditionalDevicePixelRatio, qreal correctionFactor);
bool drawBackgroundDirectly(HDC dc, XPThemeData &themeData, qreal aditionalDevicePixelRatio);
bool hasAlphaChannel(const QRect &rect);
diff --git a/src/plugins/styles/windowsvista/windowsvista.pro b/src/plugins/styles/windowsvista/windowsvista.pro
index c08db7f533..483914c13d 100644
--- a/src/plugins/styles/windowsvista/windowsvista.pro
+++ b/src/plugins/styles/windowsvista/windowsvista.pro
@@ -11,9 +11,7 @@ HEADERS += qwindowsxpstyle_p.h qwindowsxpstyle_p_p.h
SOURCES += qwindowsxpstyle.cpp
QMAKE_USE_PRIVATE += user32 gdi32
-
-# DEFINES/LIBS needed for qwizard_win.cpp and the styles
-include(../../../widgets/kernel/win.pri)
+LIBS_PRIVATE *= -luxtheme
DISTFILES += windowsvistastyle.json