diff options
Diffstat (limited to 'src/corelib/kernel')
21 files changed, 396 insertions, 260 deletions
diff --git a/src/corelib/kernel/kernel.pri b/src/corelib/kernel/kernel.pri index 61d0f2bdf1..461fbd7840 100644 --- a/src/corelib/kernel/kernel.pri +++ b/src/corelib/kernel/kernel.pri @@ -88,6 +88,8 @@ win32 { SOURCES += kernel/qeventdispatcher_win.cpp HEADERS += kernel/qeventdispatcher_win_p.h } + + !winrt: LIBS_PRIVATE += -lversion } winrt { @@ -119,8 +121,8 @@ mac { osx: LIBS_PRIVATE += -framework CoreServices -framework AppKit - uikit { - # We need UIKit for UIDevice + ios|tvos { + # We need UIKit for UIApplication in qeventdispatcher_cf.mm LIBS_PRIVATE += -framework UIKit } diff --git a/src/corelib/kernel/qcore_foundation.mm b/src/corelib/kernel/qcore_foundation.mm index f5ccd1c1f2..8b6be9b08e 100644 --- a/src/corelib/kernel/qcore_foundation.mm +++ b/src/corelib/kernel/qcore_foundation.mm @@ -46,6 +46,13 @@ #include <QtCore/qbytearray.h> #include <QtCore/qrect.h> +#if QT_CONFIG(timezone) && !defined(QT_NO_SYSTEMLOCALE) +#include <QtCore/qtimezone.h> +#include <QtCore/private/qtimezoneprivate_p.h> +#include <QtCore/private/qcore_mac_p.h> +#endif + +#import <CoreFoundation/CoreFoundation.h> #import <Foundation/Foundation.h> #if defined(QT_PLATFORM_UIKIT) @@ -422,6 +429,67 @@ NSDate *QDateTime::toNSDate() const // ---------------------------------------------------------------------------- +#if QT_CONFIG(timezone) && !defined(QT_NO_SYSTEMLOCALE) +/*! + \since 5.9 + + Constructs a new QTimeZone containing a copy of the CFTimeZone \a timeZone. + + \sa toCFTimeZone() +*/ +QTimeZone QTimeZone::fromCFTimeZone(CFTimeZoneRef timeZone) +{ + if (!timeZone) + return QTimeZone(); + return QTimeZone(QString::fromCFString(CFTimeZoneGetName(timeZone)).toLatin1()); +} + +/*! + \since 5.9 + + Creates a CFTimeZone from a QTimeZone. The caller owns the CFTimeZone object + and is responsible for releasing it. + + \sa fromCFTimeZone() +*/ +CFTimeZoneRef QTimeZone::toCFTimeZone() const +{ +#ifndef QT_NO_DYNAMIC_CAST + Q_ASSERT(dynamic_cast<const QMacTimeZonePrivate *>(d.data())); +#endif + const QMacTimeZonePrivate *p = static_cast<const QMacTimeZonePrivate *>(d.data()); + return reinterpret_cast<CFTimeZoneRef>([p->nsTimeZone() copy]); +} + +/*! + \since 5.9 + + Constructs a new QTimeZone containing a copy of the NSTimeZone \a timeZone. + + \sa toNSTimeZone() +*/ +QTimeZone QTimeZone::fromNSTimeZone(const NSTimeZone *timeZone) +{ + if (!timeZone) + return QTimeZone(); + return QTimeZone(QString::fromNSString(timeZone.name).toLatin1()); +} + +/*! + \since 5.9 + + Creates an NSTimeZone from a QTimeZone. The NSTimeZone object is autoreleased. + + \sa fromNSTimeZone() +*/ +NSTimeZone *QTimeZone::toNSTimeZone() const +{ + return [static_cast<NSTimeZone *>(toCFTimeZone()) autorelease]; +} +#endif + +// ---------------------------------------------------------------------------- + /*! \since 5.8 diff --git a/src/corelib/kernel/qcore_mac_objc.mm b/src/corelib/kernel/qcore_mac_objc.mm index d7e8d4847a..231afb991c 100644 --- a/src/corelib/kernel/qcore_mac_objc.mm +++ b/src/corelib/kernel/qcore_mac_objc.mm @@ -47,14 +47,8 @@ #include <qdebug.h> -#if defined(Q_OS_IOS) -#import <UIKit/UIKit.h> -#endif - QT_BEGIN_NAMESPACE -typedef qint16 (*GestaltFunction)(quint32 selector, qint32 *response); - // ------------------------------------------------------------------------- QDebug operator<<(QDebug dbg, const NSObject *nsObject) @@ -87,54 +81,6 @@ QT_FOR_EACH_MUTABLE_CORE_GRAPHICS_TYPE(QT_DECLARE_WEAK_QDEBUG_OPERATOR_FOR_CF_TY // ------------------------------------------------------------------------- -QAppleOperatingSystemVersion qt_apple_os_version() -{ - QAppleOperatingSystemVersion v = {0, 0, 0}; -#if QT_MAC_PLATFORM_SDK_EQUAL_OR_ABOVE(__MAC_10_10, __IPHONE_8_0) || defined(Q_OS_TVOS) || defined(Q_OS_WATCHOS) - if ([NSProcessInfo instancesRespondToSelector:@selector(operatingSystemVersion)]) { - NSOperatingSystemVersion osv = NSProcessInfo.processInfo.operatingSystemVersion; - v.major = osv.majorVersion; - v.minor = osv.minorVersion; - v.patch = osv.patchVersion; - return v; - } -#endif - // Use temporary variables so we can return 0.0.0 (unknown version) - // in case of an error partway through determining the OS version - qint32 major = 0, minor = 0, patch = 0; -#if QT_MAC_DEPLOYMENT_TARGET_BELOW(__MAC_10_10, __IPHONE_8_0) -#if defined(Q_OS_IOS) - @autoreleasepool { - NSArray *parts = [UIDevice.currentDevice.systemVersion componentsSeparatedByString:@"."]; - major = parts.count > 0 ? [[parts objectAtIndex:0] intValue] : 0; - minor = parts.count > 1 ? [[parts objectAtIndex:1] intValue] : 0; - patch = parts.count > 2 ? [[parts objectAtIndex:2] intValue] : 0; - } -#elif defined(Q_OS_OSX) - static GestaltFunction pGestalt = 0; - if (!pGestalt) { - CFBundleRef b = CFBundleGetBundleWithIdentifier(CFSTR("com.apple.CoreServices")); - pGestalt = reinterpret_cast<GestaltFunction>(CFBundleGetFunctionPointerForName(b, - CFSTR("Gestalt"))); - } - if (!pGestalt) - return v; - if (pGestalt('sys1', &major) != 0) - return v; - if (pGestalt('sys2', &minor) != 0) - return v; - if (pGestalt('sys3', &patch) != 0) - return v; -#endif -#endif - v.major = major; - v.minor = minor; - v.patch = patch; - return v; -} - -// ------------------------------------------------------------------------- - QMacAutoReleasePool::QMacAutoReleasePool() : pool([[NSAutoreleasePool alloc] init]) { diff --git a/src/corelib/kernel/qcore_mac_p.h b/src/corelib/kernel/qcore_mac_p.h index cb709f9d4b..d0edef33a2 100644 --- a/src/corelib/kernel/qcore_mac_p.h +++ b/src/corelib/kernel/qcore_mac_p.h @@ -131,12 +131,6 @@ private: QString string; }; -typedef struct { - int major, minor, patch; -} QAppleOperatingSystemVersion; - -QAppleOperatingSystemVersion qt_apple_os_version(); - #ifdef Q_OS_OSX Q_CORE_EXPORT QChar qt_mac_qtKey2CocoaKey(Qt::Key key); Q_CORE_EXPORT Qt::Key qt_mac_cocoaKey2QtKey(QChar keyCode); diff --git a/src/corelib/kernel/qcoreapplication.cpp b/src/corelib/kernel/qcoreapplication.cpp index 3796df5614..152177a926 100644 --- a/src/corelib/kernel/qcoreapplication.cpp +++ b/src/corelib/kernel/qcoreapplication.cpp @@ -95,6 +95,11 @@ #endif #endif // QT_NO_QOBJECT +#if defined(Q_OS_ANDROID) +# include <private/qjni_p.h> +# include <private/qjnihelpers_p.h> +#endif + #ifdef Q_OS_MAC # include "qcore_mac_p.h" #endif @@ -144,11 +149,13 @@ int QCoreApplicationPrivate::app_compile_version = 0x050000; //we don't know exa bool QCoreApplicationPrivate::setuidAllowed = false; #if !defined(Q_OS_WIN) -#ifdef Q_OS_MAC -QString QCoreApplicationPrivate::macMenuBarName() +#ifdef Q_OS_DARWIN +QString QCoreApplicationPrivate::infoDictionaryStringProperty(const QString &propertyName) { QString bundleName; - CFTypeRef string = CFBundleGetValueForInfoDictionaryKey(CFBundleGetMainBundle(), CFSTR("CFBundleName")); + QCFString cfPropertyName = propertyName.toCFString(); + CFTypeRef string = CFBundleGetValueForInfoDictionaryKey(CFBundleGetMainBundle(), + cfPropertyName); if (string) bundleName = QString::fromCFString(static_cast<CFStringRef>(string)); return bundleName; @@ -157,8 +164,8 @@ QString QCoreApplicationPrivate::macMenuBarName() QString QCoreApplicationPrivate::appName() const { QString applicationName; -#ifdef Q_OS_MAC - applicationName = macMenuBarName(); +#ifdef Q_OS_DARWIN + applicationName = infoDictionaryStringProperty(QStringLiteral("CFBundleName")); #endif if (applicationName.isEmpty() && argv[0]) { char *p = strrchr(argv[0], '/'); @@ -167,6 +174,34 @@ QString QCoreApplicationPrivate::appName() const return applicationName; } +QString QCoreApplicationPrivate::appVersion() const +{ + QString applicationVersion; +#ifndef QT_BOOTSTRAPPED +# ifdef Q_OS_DARWIN + applicationVersion = infoDictionaryStringProperty(QStringLiteral("CFBundleVersion")); +# elif defined(Q_OS_ANDROID) + QJNIObjectPrivate context(QtAndroidPrivate::context()); + if (context.isValid()) { + QJNIObjectPrivate pm = context.callObjectMethod( + "getPackageManager", "()Landroid/content/pm/PackageManager;"); + QJNIObjectPrivate pn = context.callObjectMethod<jstring>("getPackageName"); + if (pm.isValid() && pn.isValid()) { + QJNIObjectPrivate packageInfo = pm.callObjectMethod( + "getPackageInfo", "(Ljava/lang/String;I)Landroid/content/pm/PackageInfo;", + pn.object(), 0); + if (packageInfo.isValid()) { + QJNIObjectPrivate versionName = packageInfo.getObjectField( + "versionName", "Ljava/lang/String;"); + if (versionName.isValid()) + return versionName.toString(); + } + } + } +# endif +#endif + return applicationVersion; +} #endif QString *QCoreApplicationPrivate::cachedApplicationFilePath = 0; @@ -332,6 +367,7 @@ uint QCoreApplicationPrivate::attribs = struct QCoreApplicationData { QCoreApplicationData() Q_DECL_NOTHROW { applicationNameSet = false; + applicationVersionSet = false; } ~QCoreApplicationData() { #ifndef QT_NO_QOBJECT @@ -347,6 +383,7 @@ struct QCoreApplicationData { QString application; // application name, initially from argv[0], can then be modified. QString applicationVersion; bool applicationNameSet; // true if setApplicationName was called + bool applicationVersionSet; // true if setApplicationVersion was called #ifndef QT_NO_LIBRARY QScopedPointer<QStringList> app_libpaths; @@ -532,12 +569,10 @@ void QCoreApplicationPrivate::checkReceiverThread(QObject *receiver) QThread *thr = receiver->thread(); Q_ASSERT_X(currentThread == thr || !thr, "QCoreApplication::sendEvent", - QString::fromLatin1("Cannot send events to objects owned by a different thread. " - "Current thread %1. Receiver '%2' (of type '%3') was created in thread %4") - .arg(QString::number((quintptr) currentThread, 16)) - .arg(receiver->objectName()) - .arg(QLatin1String(receiver->metaObject()->className())) - .arg(QString::number((quintptr) thr, 16)) + QString::asprintf("Cannot send events to objects owned by a different thread. " + "Current thread 0x%p. Receiver '%ls' (of type '%s') was created in thread 0x%p", + currentThread, qUtf16Printable(receiver->objectName()), + receiver->metaObject()->className(), thr) .toLocal8Bit().data()); Q_UNUSED(currentThread); Q_UNUSED(thr); @@ -742,10 +777,13 @@ void QCoreApplicationPrivate::init() Q_ASSERT_X(!QCoreApplication::self, "QCoreApplication", "there should be only one application object"); QCoreApplication::self = q; - // Store app name (so it's still available after QCoreApplication is destroyed) + // Store app name/version (so they're still available after QCoreApplication is destroyed) if (!coreappdata()->applicationNameSet) coreappdata()->application = appName(); + if (!coreappdata()->applicationVersionSet) + coreappdata()->applicationVersion = appVersion(); + QLoggingRegistry::instance()->init(); #ifndef QT_NO_LIBRARY @@ -2403,6 +2441,29 @@ Q_CORE_EXPORT QString qt_applicationName_noFallback() \since 4.4 \brief the version of this application + If not set, the application version defaults to a platform-specific value + determined from the main application executable or package (since Qt 5.9): + + \table + \header + \li Platform + \li Source + \row + \li Windows (classic desktop) + \li PRODUCTVERSION parameter of the VERSIONINFO resource + \row + \li Universal Windows Platform + \li version attribute of the application package manifest + \row + \li macOS, iOS, tvOS, watchOS + \li CFBundleVersion property of the information property list + \row + \li Android + \li android:versionName property of the AndroidManifest.xml manifest element + \endtable + + On other platforms, the default is the empty string. + \sa applicationName, organizationName, organizationDomain */ /*! @@ -2413,9 +2474,13 @@ Q_CORE_EXPORT QString qt_applicationName_noFallback() */ void QCoreApplication::setApplicationVersion(const QString &version) { - if (coreappdata()->applicationVersion == version) + coreappdata()->applicationVersionSet = !version.isEmpty(); + QString newVersion = version; + if (newVersion.isEmpty() && QCoreApplication::self) + newVersion = QCoreApplication::self->d_func()->appVersion(); + if (coreappdata()->applicationVersion == newVersion) return; - coreappdata()->applicationVersion = version; + coreappdata()->applicationVersion = newVersion; #ifndef QT_NO_QOBJECT if (QCoreApplication::self) emit QCoreApplication::self->applicationVersionChanged(); @@ -2424,7 +2489,7 @@ void QCoreApplication::setApplicationVersion(const QString &version) QString QCoreApplication::applicationVersion() { - return coreappdata()->applicationVersion; + return coreappdata() ? coreappdata()->applicationVersion : QString(); } #ifndef QT_NO_LIBRARY diff --git a/src/corelib/kernel/qcoreapplication_p.h b/src/corelib/kernel/qcoreapplication_p.h index 3601add098..c646786296 100644 --- a/src/corelib/kernel/qcoreapplication_p.h +++ b/src/corelib/kernel/qcoreapplication_p.h @@ -83,9 +83,10 @@ public: void init(); QString appName() const; + QString appVersion() const; -#ifdef Q_OS_MAC - static QString macMenuBarName(); +#ifdef Q_OS_DARWIN + static QString infoDictionaryStringProperty(const QString &propertyName); #endif static void initLocale(); diff --git a/src/corelib/kernel/qcoreapplication_win.cpp b/src/corelib/kernel/qcoreapplication_win.cpp index 67e509eeef..856d2a2101 100644 --- a/src/corelib/kernel/qcoreapplication_win.cpp +++ b/src/corelib/kernel/qcoreapplication_win.cpp @@ -51,27 +51,20 @@ #include <ctype.h> #include <qt_windows.h> +#ifdef Q_OS_WINRT +#include <qfunctions_winrt.h> +#include <wrl.h> +#include <Windows.ApplicationModel.core.h> +#include <windows.foundation.h> +using namespace ABI::Windows::ApplicationModel; +using namespace Microsoft::WRL; +using namespace Microsoft::WRL::Wrappers; +#endif + QT_BEGIN_NAMESPACE int appCmdShow = 0; -// GetModuleFileName only exists for MSVC2015 and upwards for WinRT, meaning -// Windows 10 (Mobile). Hence take the first argument passed to the -// QCoreApplication contructor for older versions as a fallback on older platforms. -#if defined(Q_OS_WINRT) && _MSC_VER < 1900 - -Q_CORE_EXPORT QString qAppFileName() -{ - return QFileInfo(QCoreApplication::arguments().constFirst()).filePath(); -} - -QString QCoreApplicationPrivate::appName() const -{ - return QFileInfo(QCoreApplication::arguments().constFirst()).baseName(); -} - -#else // !(defined(Q_OS_WINRT) && _MSC_VER < 1900) - Q_CORE_EXPORT QString qAppFileName() // get application file name { // We do MAX_PATH + 2 here, and request with MAX_PATH + 1, so we can handle all paths @@ -118,7 +111,63 @@ QString QCoreApplicationPrivate::appName() const return QFileInfo(qAppFileName()).baseName(); } -#endif // !(defined(Q_OS_WINRT) && _MSC_VER < 1900) +QString QCoreApplicationPrivate::appVersion() const +{ + QString applicationVersion; +#ifndef QT_BOOTSTRAPPED +# ifdef Q_OS_WINRT + HRESULT hr; + + ComPtr<IPackageStatics> packageFactory; + hr = RoGetActivationFactory( + HString::MakeReference(RuntimeClass_Windows_ApplicationModel_Package).Get(), + IID_PPV_ARGS(&packageFactory)); + RETURN_IF_FAILED("Failed to create package instance", return QString()); + + ComPtr<IPackage> package; + packageFactory->get_Current(&package); + RETURN_IF_FAILED("Failed to get current application package", return QString()); + + ComPtr<IPackageId> packageId; + package->get_Id(&packageId); + RETURN_IF_FAILED("Failed to get current application package ID", return QString()); + + PackageVersion version; + packageId->get_Version(&version); + RETURN_IF_FAILED("Failed to get current application package version", return QString()); + + applicationVersion = QStringLiteral("%1.%2.%3.%4") + .arg(version.Major) + .arg(version.Minor) + .arg(version.Build) + .arg(version.Revision); +# else + const QString appFileName = qAppFileName(); + QVarLengthArray<wchar_t> buffer(appFileName.size() + 1); + buffer[appFileName.toWCharArray(buffer.data())] = 0; + + DWORD versionInfoSize = GetFileVersionInfoSize(buffer.data(), nullptr); + if (versionInfoSize) { + QVarLengthArray<BYTE> info(static_cast<int>(versionInfoSize)); + if (GetFileVersionInfo(buffer.data(), 0, versionInfoSize, info.data())) { + UINT size; + DWORD *fi; + + if (VerQueryValue(info.data(), __TEXT("\\"), + reinterpret_cast<void **>(&fi), &size) && size) { + const VS_FIXEDFILEINFO *verInfo = reinterpret_cast<const VS_FIXEDFILEINFO *>(fi); + applicationVersion = QStringLiteral("%1.%2.%3.%4") + .arg(HIWORD(verInfo->dwProductVersionMS)) + .arg(LOWORD(verInfo->dwProductVersionMS)) + .arg(HIWORD(verInfo->dwProductVersionLS)) + .arg(LOWORD(verInfo->dwProductVersionLS)); + } + } + } +# endif +#endif + return applicationVersion; +} #ifndef Q_OS_WINRT diff --git a/src/corelib/kernel/qdeadlinetimer.cpp b/src/corelib/kernel/qdeadlinetimer.cpp index 1f554c9f2e..ad549dcd7b 100644 --- a/src/corelib/kernel/qdeadlinetimer.cpp +++ b/src/corelib/kernel/qdeadlinetimer.cpp @@ -175,9 +175,9 @@ Q_DECL_CONST_FUNCTION static inline QPair<qint64, qint64> toSecsAndNSecs(qint64 */ /*! - \fn QDeadlineTimer::QDeadlineTimer(ForeverConstant foreverConstant, Qt::TimerType timerType) + \fn QDeadlineTimer::QDeadlineTimer(ForeverConstant forever, Qt::TimerType timerType) - QDeadlineTimer objects created with parameter \a foreverConstant never expire. + QDeadlineTimer objects created with parameter \a forever never expire. For such objects, remainingTime() will return -1, deadline() will return the maximum value, and isForever() will return true. @@ -343,54 +343,6 @@ void QDeadlineTimer::setPreciseRemainingTime(qint64 secs, qint64 nsecs, Qt::Time */ /*! - \fn std::chrono::nanoseconds remainingTimeAsDuration() const - - Returns a \c{std::chrono::duration} object of type \c{Duration} containing - the remaining time in this QDeadlineTimer, if it still has time left. If - the deadline has passed, this returns \c{Duration::zero()}, whereas if the - object is set to never expire, it returns \c{Duration::max()} (instead of - -1). - - It is not possible to obtain the overdue time for expired timers with this - function. To do that, see deadline(). - - \note The overload of this function without template parameter always - returns milliseconds. - - \sa setRemainingTime(), deadline<Clock, Duration>() -*/ - -/*! - \overload - \fn std::chrono::time_point<Clock, Duration> QDeadlineTimer::deadline() const - - Returns the absolute time point for the deadline stored in QDeadlineTimer - object as a \c{std::chrono::time_point} object. The template parameter - \c{Clock} is mandatory and indicates which of the C++ timekeeping clocks to - use as a reference. The value will be in the past if this QDeadlineTimer - has expired. - - If this QDeadlineTimer never expires, this function returns - \c{std::chrono::time_point<Clock, Duration>::max()}. - - This function can be used to calculate the amount of time a timer is - overdue, by subtracting the current time point of the reference clock, as - in the following example: - - \code - auto realTimeLeft = std::chrono::nanoseconds::max(); - auto tp = deadline.deadline<std::chrono::steady_clock>(); - if (tp != std::chrono::steady_clock::max()) - realTimeLeft = tp - std::chrono::steady_clock::now(); - \endcode - - \note Timers that were created as expired have an indetermine time point in - the past as their deadline, so the above calculation may not work. - - \sa remainingTime(), deadlineNSecs(), setDeadline() -*/ - -/*! \fn bool QDeadlineTimer::isForever() const Returns true if this QDeadlineTimer object never expires, false otherwise. @@ -791,6 +743,30 @@ QDeadlineTimer QDeadlineTimer::addNSecs(QDeadlineTimer dt, qint64 nsecs) Q_DECL_ To subtract times of precision greater than 1 millisecond, use addNSecs(). */ +/*! + \fn void QDeadlineTimer::swap(QDeadlineTimer &other) + + Swaps this deadline timer with the \a other deadline timer. + */ + +/*! + \fn QDeadlineTimer & QDeadlineTimer::operator=(std::chrono::time_point<Clock, Duration> deadline_) + + Assigns \a deadline_ to this deadline timer. + */ + +/*! + \fn QDeadlineTimer & QDeadlineTimer::operator=(std::chrono::duration<Rep, Period> remaining) + + Sets this deadline timer to the \a remaining time. + */ + +/*! + \fn std::chrono::nanoseconds QDeadlineTimer::remainingTimeAsDuration() const + + Returns the time remaining before the deadline. + */ + // the rest of the functions are in qelapsedtimer_xxx.cpp QT_END_NAMESPACE diff --git a/src/corelib/kernel/qeventdispatcher_win.cpp b/src/corelib/kernel/qeventdispatcher_win.cpp index 1a0efae2dc..75ac104155 100644 --- a/src/corelib/kernel/qeventdispatcher_win.cpp +++ b/src/corelib/kernel/qeventdispatcher_win.cpp @@ -42,6 +42,7 @@ #include "qcoreapplication.h" #include <private/qsystemlibrary_p.h> +#include "qoperatingsystemversion.h" #include "qpair.h" #include "qset.h" #include "qsocketnotifier.h" @@ -236,7 +237,7 @@ static inline UINT inputTimerMask() // QTBUG 28513, QTBUG-29097, QTBUG-29435: QS_TOUCH, QS_POINTER became part of // QS_INPUT in Windows Kit 8. They should not be used when running on pre-Windows 8. #if WINVER > 0x0601 - if (QSysInfo::WindowsVersion < QSysInfo::WV_WINDOWS8) + if (QOperatingSystemVersion::current() < QOperatingSystemVersion::Windows8) result &= ~(QS_TOUCH | QS_POINTER); #endif // WINVER > 0x0601 return result; @@ -1058,4 +1059,11 @@ void QEventDispatcherWin32::sendPostedEvents() QCoreApplicationPrivate::sendPostedEvents(0, 0, d->threadData); } +HWND QEventDispatcherWin32::internalHwnd() +{ + Q_D(QEventDispatcherWin32); + createInternalHwnd(); + return d->internalHwnd; +} + QT_END_NAMESPACE diff --git a/src/corelib/kernel/qeventdispatcher_win_p.h b/src/corelib/kernel/qeventdispatcher_win_p.h index 773315c04f..227fcf89ff 100644 --- a/src/corelib/kernel/qeventdispatcher_win_p.h +++ b/src/corelib/kernel/qeventdispatcher_win_p.h @@ -106,6 +106,8 @@ public: bool event(QEvent *e); + HWND internalHwnd(); + protected: QEventDispatcherWin32(QEventDispatcherWin32Private &dd, QObject *parent = 0); virtual void sendPostedEvents(); diff --git a/src/corelib/kernel/qmetatype.cpp b/src/corelib/kernel/qmetatype.cpp index ef68878f68..5623b085b8 100644 --- a/src/corelib/kernel/qmetatype.cpp +++ b/src/corelib/kernel/qmetatype.cpp @@ -1025,7 +1025,7 @@ int QMetaType::registerNormalizedType(const NS(QByteArray) &normalizedTypeName, normalizedTypeName.size()); int previousSize = 0; - int previousFlags = 0; + QMetaType::TypeFlags::Int previousFlags = 0; if (idx == UnknownType) { QWriteLocker locker(customTypesLock()); int posInVector = -1; diff --git a/src/corelib/kernel/qmetatype_p.h b/src/corelib/kernel/qmetatype_p.h index dd0bce2645..6f1334d082 100644 --- a/src/corelib/kernel/qmetatype_p.h +++ b/src/corelib/kernel/qmetatype_p.h @@ -129,7 +129,7 @@ public: QMetaType::Constructor constructor; QMetaType::Destructor destructor; int size; - quint32 flags; // same as QMetaType::TypeFlags + QMetaType::TypeFlags::Int flags; const QMetaObject *metaObject; }; diff --git a/src/corelib/kernel/qobject.cpp b/src/corelib/kernel/qobject.cpp index 63b02d2c0c..ac1b2d41bf 100644 --- a/src/corelib/kernel/qobject.cpp +++ b/src/corelib/kernel/qobject.cpp @@ -147,12 +147,13 @@ static inline QMutex *signalSlotLock(const QObject *o) uint(quintptr(o)) % sizeof(_q_ObjectMutexPool)/sizeof(QBasicMutex)]); } -// ### Qt >= 5.6, remove qt_add/removeObject +#if QT_VERSION < 0x60000 extern "C" Q_CORE_EXPORT void qt_addObject(QObject *) {} extern "C" Q_CORE_EXPORT void qt_removeObject(QObject *) {} +#endif struct QConnectionSenderSwitcher { QObject *receiver; @@ -754,30 +755,6 @@ void QMetaCallEvent::placeMetaCall(QObject *object) \sa {Object Trees & Ownership} */ -/*! - \relates QObject - - Returns a pointer to the object named \a name that inherits \a - type and with a given \a parent. - - Returns 0 if there is no such child. - - \snippet code/src_corelib_kernel_qobject.cpp 0 -*/ - -void *qt_find_obj_child(QObject *parent, const char *type, const QString &name) -{ - QObjectList list = parent->children(); - if (list.size() == 0) return 0; - for (int i = 0; i < list.size(); ++i) { - QObject *obj = list.at(i); - if (name == obj->objectName() && obj->inherits(type)) - return obj; - } - return 0; -} - - /***************************************************************************** QObject member functions *****************************************************************************/ @@ -835,7 +812,9 @@ QObject::QObject(QObject *parent) QT_RETHROW; } } +#if QT_VERSION < 0x60000 qt_addObject(this); +#endif if (Q_UNLIKELY(qtHookData[QHooks::AddQObject])) reinterpret_cast<QHooks::AddQObjectCallback>(qtHookData[QHooks::AddQObject])(this); } @@ -868,7 +847,9 @@ QObject::QObject(QObjectPrivate &dd, QObject *parent) QT_RETHROW; } } +#if QT_VERSION < 0x60000 qt_addObject(this); +#endif if (Q_UNLIKELY(qtHookData[QHooks::AddQObject])) reinterpret_cast<QHooks::AddQObjectCallback>(qtHookData[QHooks::AddQObject])(this); } @@ -1040,7 +1021,9 @@ QObject::~QObject() if (!d->children.isEmpty()) d->deleteChildren(); +#if QT_VERSION < 0x60000 qt_removeObject(this); +#endif if (Q_UNLIKELY(qtHookData[QHooks::RemoveQObject])) reinterpret_cast<QHooks::RemoveQObjectCallback>(qtHookData[QHooks::RemoveQObject])(this); @@ -1651,6 +1634,45 @@ int QObject::startTimer(int interval, Qt::TimerType timerType) } /*! + \since 5.9 + \overload + \fn int QObject::startTimer(std::chrono::milliseconds time, Qt::TimerType timerType) + + Starts a timer and returns a timer identifier, or returns zero if + it could not start a timer. + + A timer event will occur every \a time interval until killTimer() + is called. If \a interval is equal to \c{std::chrono::duration::zero()}, + then the timer event occurs once every time there are no more window + system events to process. + + The virtual timerEvent() function is called with the QTimerEvent + event parameter class when a timer event occurs. Reimplement this + function to get timer events. + + If multiple timers are running, the QTimerEvent::timerId() can be + used to find out which timer was activated. + + Example: + + \snippet code/src_corelib_kernel_qobject.cpp 8 + + Note that QTimer's accuracy depends on the underlying operating system and + hardware. The \a timerType argument allows you to customize the accuracy of + the timer. See Qt::TimerType for information on the different timer types. + Most platforms support an accuracy of 20 milliseconds; some provide more. + If Qt is unable to deliver the requested number of timer events, it will + silently discard some. + + The QTimer class provides a high-level programming interface with + single-shot timers and timer signals instead of events. There is + also a QBasicTimer class that is more lightweight than QTimer and + less clumsy than using timer IDs directly. + + \sa timerEvent(), killTimer(), QTimer::singleShot() +*/ + +/*! Kills the timer with timer identifier, \a id. The timer identifier is returned by startTimer() when a timer @@ -3941,9 +3963,8 @@ QList<QByteArray> QObject::dynamicPropertyNames() const QObject debugging output routines. *****************************************************************************/ -static void dumpRecursive(int level, QObject *object) +static void dumpRecursive(int level, const QObject *object) { -#if defined(QT_DEBUG) if (object) { QByteArray buf; buf.fill(' ', level / 2 * 8); @@ -3972,45 +3993,65 @@ static void dumpRecursive(int level, QObject *object) dumpRecursive(level+1, children.at(i)); } } -#else - Q_UNUSED(level) - Q_UNUSED(object) -#endif } /*! - Dumps a tree of children to the debug output. + \overload + \obsolete - This function is useful for debugging, but does nothing if the - library has been compiled in release mode (i.e. without debugging - information). + Dumps a tree of children to the debug output. \sa dumpObjectInfo() */ void QObject::dumpObjectTree() { + const_cast<const QObject *>(this)->dumpObjectTree(); +} + +/*! + Dumps a tree of children to the debug output. + + \note before Qt 5.9, this function was not const. + + \sa dumpObjectInfo() +*/ + +void QObject::dumpObjectTree() const +{ dumpRecursive(0, this); } /*! + \overload + \obsolete + Dumps information about signal connections, etc. for this object to the debug output. - This function is useful for debugging, but does nothing if the - library has been compiled in release mode (i.e. without debugging - information). - \sa dumpObjectTree() */ void QObject::dumpObjectInfo() { -#if defined(QT_DEBUG) + const_cast<const QObject *>(this)->dumpObjectInfo(); +} + +/*! + Dumps information about signal connections, etc. for this object + to the debug output. + + \note before Qt 5.9, this function was not const. + + \sa dumpObjectTree() +*/ + +void QObject::dumpObjectInfo() const +{ qDebug("OBJECT %s::%s", metaObject()->className(), objectName().isEmpty() ? "unnamed" : objectName().toLocal8Bit().data()); - Q_D(QObject); + Q_D(const QObject); QMutexLocker locker(signalSlotLock(this)); // first, look for connections where this object is the sender @@ -4066,7 +4107,6 @@ void QObject::dumpObjectInfo() } else { qDebug(" <None>"); } -#endif } #ifndef QT_NO_USERDATA diff --git a/src/corelib/kernel/qobject.h b/src/corelib/kernel/qobject.h index 69b70ad6ec..d42eb2a13d 100644 --- a/src/corelib/kernel/qobject.h +++ b/src/corelib/kernel/qobject.h @@ -55,6 +55,10 @@ #include <QtCore/qobject_impl.h> +#if QT_HAS_INCLUDE(<chrono>) +# include <chrono> +#endif + QT_BEGIN_NAMESPACE @@ -150,6 +154,13 @@ public: void moveToThread(QThread *thread); int startTimer(int interval, Qt::TimerType timerType = Qt::CoarseTimer); +#if QT_HAS_INCLUDE(<chrono>) || defined(Q_QDOC) + Q_ALWAYS_INLINE + int startTimer(std::chrono::milliseconds time, Qt::TimerType timerType = Qt::CoarseTimer) + { + return startTimer(int(time.count()), timerType); + } +#endif void killTimer(int id); template<typename T> @@ -375,8 +386,12 @@ public: #endif //Q_QDOC - void dumpObjectTree(); - void dumpObjectInfo(); +#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) + void dumpObjectTree(); // ### Qt 6: remove + void dumpObjectInfo(); // ### Qt 6: remove +#endif + void dumpObjectTree() const; + void dumpObjectInfo() const; #ifndef QT_NO_PROPERTIES bool setProperty(const char *name, const QVariant &value); diff --git a/src/corelib/kernel/qobjectdefs.h b/src/corelib/kernel/qobjectdefs.h index 5cdbef443b..ea4046df55 100644 --- a/src/corelib/kernel/qobjectdefs.h +++ b/src/corelib/kernel/qobjectdefs.h @@ -147,34 +147,8 @@ class QString; # define QT_TR_FUNCTIONS #endif -#if defined(QT_NO_QOBJECT_CHECK) -/* qmake ignore Q_OBJECT */ -#define Q_OBJECT_CHECK -#else - -/* This is a compile time check that ensures that any class cast with qobject_cast - actually contains a Q_OBJECT macro. Note: qobject_cast will fail if a QObject - subclass doesn't contain Q_OBJECT. - - In qt_check_for_QOBJECT_macro, we call a dummy templated function with two - parameters, the first being "this" and the other the target of the qobject - cast. If the types are not identical, we know that a Q_OBJECT macro is missing. - - If you get a compiler error here, make sure that the class you are casting - to contains a Q_OBJECT macro. -*/ - -/* qmake ignore Q_OBJECT */ -#define Q_OBJECT_CHECK \ - template <typename ThisObject> inline void qt_check_for_QOBJECT_macro(const ThisObject &_q_argument) const \ - { int i = qYouForgotTheQ_OBJECT_Macro(this, &_q_argument); i = i + 1; } - -template <typename T> -inline int qYouForgotTheQ_OBJECT_Macro(T, T) { return 0; } - -template <typename T1, typename T2> -inline void qYouForgotTheQ_OBJECT_Macro(T1, T2) {} -#endif // QT_NO_QOBJECT_CHECK +// ### Qt6: remove +#define Q_OBJECT_CHECK /* empty, unused since Qt 5.2 */ #if defined(Q_CC_INTEL) // Cannot redefine the visibility of a method in an exported class @@ -200,7 +174,6 @@ inline void qYouForgotTheQ_OBJECT_Macro(T1, T2) {} /* qmake ignore Q_OBJECT */ #define Q_OBJECT \ public: \ - Q_OBJECT_CHECK \ QT_WARNING_PUSH \ Q_OBJECT_NO_OVERRIDE_WARNING \ static const QMetaObject staticMetaObject; \ @@ -267,6 +240,11 @@ private: \ #define Q_SLOT Q_SLOT #endif //Q_MOC_RUN +#ifdef Q_CLANG_QDOC +#undef Q_GADGET +#define Q_GADGET +#endif + #ifndef QT_NO_META_MACROS // macro for onaming members #ifdef METHOD diff --git a/src/corelib/kernel/qppsobject.cpp b/src/corelib/kernel/qppsobject.cpp index dd01d48cc0..d58715d12b 100644 --- a/src/corelib/kernel/qppsobject.cpp +++ b/src/corelib/kernel/qppsobject.cpp @@ -492,8 +492,7 @@ void QPpsObjectPrivate::encodeObject(pps_encoder_t *encoder, const QVariantMap & /////////////////////////////////////////////////////////////////////////////// QPpsObject::QPpsObject(const QString &path, QObject *parent) - : QObject(parent), - d_ptr(new QPpsObjectPrivate(path)) + : QObject(*new QPpsObjectPrivate(path), parent) { } diff --git a/src/corelib/kernel/qppsobject_p.h b/src/corelib/kernel/qppsobject_p.h index 86f4528c93..c7b99c8e42 100644 --- a/src/corelib/kernel/qppsobject_p.h +++ b/src/corelib/kernel/qppsobject_p.h @@ -118,7 +118,6 @@ Q_SIGNALS: void readyRead(); private: - QScopedPointer<QPpsObjectPrivate> d_ptr; Q_DECLARE_PRIVATE(QPpsObject) Q_DISABLE_COPY(QPpsObject) }; diff --git a/src/corelib/kernel/qsharedmemory_win.cpp b/src/corelib/kernel/qsharedmemory_win.cpp index 07d4930332..be42a369c2 100644 --- a/src/corelib/kernel/qsharedmemory_win.cpp +++ b/src/corelib/kernel/qsharedmemory_win.cpp @@ -64,11 +64,6 @@ void QSharedMemoryPrivate::setErrorString(QLatin1String function) errorString = QSharedMemory::tr("%1: already exists").arg(function); break; case ERROR_FILE_NOT_FOUND: -#if defined(Q_OS_WINRT) && _MSC_VER < 1900 - // This happens on WinRT only if no file is present as CreateFileMappingW - // bails out with this error code - case ERROR_INVALID_PARAMETER: -#endif error = QSharedMemory::NotFound; errorString = QSharedMemory::tr("%1: doesn't exist").arg(function); break; @@ -103,16 +98,9 @@ HANDLE QSharedMemoryPrivate::handle() errorString = QSharedMemory::tr("%1: unable to make key").arg(function); return 0; } -#if defined(Q_OS_WINPHONE) - Q_UNIMPLEMENTED(); - hand = 0; -#elif defined(Q_OS_WINRT) -#if _MSC_VER >= 1900 +#if defined(Q_OS_WINRT) hand = OpenFileMappingFromApp(FILE_MAP_ALL_ACCESS, FALSE, reinterpret_cast<PCWSTR>(nativeKey.utf16())); #else - hand = CreateFileMappingFromApp(INVALID_HANDLE_VALUE, 0, PAGE_READWRITE, 0, (PCWSTR)nativeKey.utf16()); -#endif -#else hand = OpenFileMapping(FILE_MAP_ALL_ACCESS, false, (wchar_t*)nativeKey.utf16()); #endif if (!hand) { @@ -144,11 +132,7 @@ bool QSharedMemoryPrivate::create(int size) } // Create the file mapping. -#if defined(Q_OS_WINPHONE) - Q_UNIMPLEMENTED(); - Q_UNUSED(size) - hand = 0; -#elif defined(Q_OS_WINRT) +#if defined(Q_OS_WINRT) hand = CreateFileMappingFromApp(INVALID_HANDLE_VALUE, 0, PAGE_READWRITE, size, (PCWSTR)nativeKey.utf16()); #else hand = CreateFileMapping(INVALID_HANDLE_VALUE, 0, PAGE_READWRITE, 0, size, (wchar_t*)nativeKey.utf16()); @@ -166,12 +150,7 @@ bool QSharedMemoryPrivate::attach(QSharedMemory::AccessMode mode) { // Grab a pointer to the memory block int permissions = (mode == QSharedMemory::ReadOnly ? FILE_MAP_READ : FILE_MAP_ALL_ACCESS); -#if defined(Q_OS_WINPHONE) - Q_UNIMPLEMENTED(); - Q_UNUSED(mode) - Q_UNUSED(permissions) - memory = 0; -#elif defined(Q_OS_WINRT) +#if defined(Q_OS_WINRT) memory = (void *)MapViewOfFileFromApp(handle(), permissions, 0, 0); #else memory = (void *)MapViewOfFile(handle(), permissions, 0, 0, 0); @@ -199,15 +178,10 @@ bool QSharedMemoryPrivate::attach(QSharedMemory::AccessMode mode) bool QSharedMemoryPrivate::detach() { // umap memory -#if defined(Q_OS_WINPHONE) - Q_UNIMPLEMENTED(); - return false; -#else if (!UnmapViewOfFile(memory)) { setErrorString(QLatin1String("QSharedMemory::detach")); return false; } -#endif memory = 0; size = 0; diff --git a/src/corelib/kernel/qsystemsemaphore_systemv.cpp b/src/corelib/kernel/qsystemsemaphore_systemv.cpp index 1967899a58..83da09da44 100644 --- a/src/corelib/kernel/qsystemsemaphore_systemv.cpp +++ b/src/corelib/kernel/qsystemsemaphore_systemv.cpp @@ -72,7 +72,13 @@ QT_BEGIN_NAMESPACE key_t QSystemSemaphorePrivate::handle(QSystemSemaphore::AccessMode mode) { if (key.isEmpty()){ - errorString = QCoreApplication::tr("%1: key is empty", "QSystemSemaphore").arg(QLatin1String("QSystemSemaphore::handle:")); + errorString = +#if QT_CONFIG(translation) + QCoreApplication::tr("%1: key is empty", "QSystemSemaphore") +#else + QString::fromLatin1("%1: key is empty") +#endif + .arg(QLatin1String("QSystemSemaphore::handle:")); error = QSystemSemaphore::KeyError; return -1; } @@ -84,16 +90,30 @@ key_t QSystemSemaphorePrivate::handle(QSystemSemaphore::AccessMode mode) // Create the file needed for ftok int built = QSharedMemoryPrivate::createUnixKeyFile(fileName); if (-1 == built) { - errorString = QCoreApplication::tr("%1: unable to make key", "QSystemSemaphore").arg(QLatin1String("QSystemSemaphore::handle:")); + errorString = +#if QT_CONFIG(translation) + QCoreApplication::tr("%1: unable to make key", "QSystemSemaphore") +#else + QString::fromLatin1("%1: unable to make key") +#endif + .arg(QLatin1String("QSystemSemaphore::handle:")); error = QSystemSemaphore::KeyError; return -1; } createdFile = (1 == built); +#if !defined(QT_NO_SHAREDMEMORY) && !defined(QT_POSIX_IPC) && !defined(Q_OS_ANDROID) // Get the unix key for the created file unix_key = qt_safe_ftok(QFile::encodeName(fileName), 'Q'); +#endif if (-1 == unix_key) { - errorString = QCoreApplication::tr("%1: ftok failed", "QSystemSemaphore").arg(QLatin1String("QSystemSemaphore::handle:")); + errorString = +#if QT_CONFIG(translation) + QCoreApplication::tr("%1: ftok failed", "QSystemSemaphore") +#else + QString::fromLatin1("%1: ftok failed") +#endif + .arg(QLatin1String("QSystemSemaphore::handle:")); error = QSystemSemaphore::KeyError; return -1; } diff --git a/src/corelib/kernel/qvariant.cpp b/src/corelib/kernel/qvariant.cpp index 9476ab3f5b..8a4ad8bbf3 100644 --- a/src/corelib/kernel/qvariant.cpp +++ b/src/corelib/kernel/qvariant.cpp @@ -2914,7 +2914,7 @@ static const quint32 qCanConvertMatrix[QVariant::LastCoreType + 1] = static const size_t qCanConvertMatrixMaximumTargetType = 8 * sizeof(*qCanConvertMatrix); #ifndef QT_BOOTSTRAPPED -/*! +/* Returns \c true if from inherits to. */ static bool canConvertMetaObject(const QMetaObject *from, const QMetaObject *to) diff --git a/src/corelib/kernel/qwineventnotifier.h b/src/corelib/kernel/qwineventnotifier.h index f17fa059a1..f29f325d13 100644 --- a/src/corelib/kernel/qwineventnotifier.h +++ b/src/corelib/kernel/qwineventnotifier.h @@ -42,7 +42,7 @@ #include "QtCore/qobject.h" -#ifdef Q_OS_WIN +#if defined(Q_OS_WIN) || defined(Q_CLANG_QDOC) QT_BEGIN_NAMESPACE |