diff options
-rw-r--r-- | src/corelib/global/qnamespace.h | 3 | ||||
-rw-r--r-- | src/corelib/global/qnamespace.qdoc | 16 | ||||
-rw-r--r-- | src/corelib/tools/qdatetime.cpp | 6 | ||||
-rw-r--r-- | src/gui/kernel/qhighdpiscaling.cpp | 36 | ||||
-rw-r--r-- | src/plugins/platforms/winrt/qwinrtscreen.cpp | 123 |
5 files changed, 132 insertions, 52 deletions
diff --git a/src/corelib/global/qnamespace.h b/src/corelib/global/qnamespace.h index de8a17fa51..c4f5415a01 100644 --- a/src/corelib/global/qnamespace.h +++ b/src/corelib/global/qnamespace.h @@ -496,7 +496,8 @@ public: AA_UseSoftwareOpenGL = 17, AA_ShareOpenGLContexts = 18, AA_SetPalette = 19, - AA_NoHighDpiScaling = 20, + AA_EnableHighDpiScaling = 20, + AA_DisableHighDpiScaling = 21, // Add new attributes before this line AA_AttributeCount diff --git a/src/corelib/global/qnamespace.qdoc b/src/corelib/global/qnamespace.qdoc index 443eae5a11..e789daafbd 100644 --- a/src/corelib/global/qnamespace.qdoc +++ b/src/corelib/global/qnamespace.qdoc @@ -200,10 +200,22 @@ \value AA_SetPalette Indicates whether a palette was explicitly set on the QApplication/QGuiApplication. This value has been added in Qt 5.5. - \value AA_NoHighDpiScaling Disables all high-DPI scaling in Qt, exposing window + \value AA_EnableHighDpiScaling. Enables high-DPI scaling in Qt on supported + platforms (see also \l{High DPI Displays}). Supported platforms are + X11, Windows and Android. Enabling makes Qt scale the main (device + independent) coordinate system according to display scale factors + provided by the operating system. This corresponds to setting the + QT_AUTO_SCREEN_SCALE_FACTOR environment variable to 1. This value + has been added in Qt 5.6. This attribute must be set before + Q(Gui)Application is constructed. + + \value AA_DisableHighDpiScaling Disables high-DPI scaling in Qt, exposing window system coordinates. Note that the window system may do its own scaling, so this does not guarantee that QPaintDevice::devicePixelRatio() will - be equal to 1. This value has been added in Qt 5.6. + be equal to 1. In addition, scale factors set by QT_SCALE_FACTOR will not + be affected. This corresponds to setting the QT_AUTO_SCREEN_SCALE_FACTOR + environment variable to 0. This value has been added in Qt 5.6. This + attribute must be set before Q(Gui)Application is constructed. The following values are obsolete: diff --git a/src/corelib/tools/qdatetime.cpp b/src/corelib/tools/qdatetime.cpp index 4854ceb5ca..18fb9db9b6 100644 --- a/src/corelib/tools/qdatetime.cpp +++ b/src/corelib/tools/qdatetime.cpp @@ -2236,18 +2236,18 @@ static qint64 qt_mktime(QDate *date, QTime *time, QDateTimePrivate::DaylightStat #else // All other platforms provide standard C library time functions tm local; + memset(&local, 0, sizeof(local)); // tm_[wy]day plus any non-standard fields local.tm_sec = time->second(); local.tm_min = time->minute(); local.tm_hour = time->hour(); local.tm_mday = dd; local.tm_mon = mm - 1; local.tm_year = yy - 1900; - local.tm_wday = 0; - local.tm_yday = 0; if (daylightStatus) local.tm_isdst = int(*daylightStatus); else local.tm_isdst = -1; + #if defined(Q_OS_WIN) int hh = local.tm_hour; #endif // Q_OS_WIN @@ -2453,7 +2453,7 @@ static qint64 localMSecsToEpochMSecs(qint64 localMsecs, QTime tm; msecsToTime(localMsecs, &dt, &tm); - qint64 msecsMax = qint64(TIME_T_MAX) * 1000; + const qint64 msecsMax = qint64(TIME_T_MAX) * 1000; if (localMsecs <= qint64(MSECS_PER_DAY)) { diff --git a/src/gui/kernel/qhighdpiscaling.cpp b/src/gui/kernel/qhighdpiscaling.cpp index daba9f94a1..a002b8c48d 100644 --- a/src/gui/kernel/qhighdpiscaling.cpp +++ b/src/gui/kernel/qhighdpiscaling.cpp @@ -49,7 +49,7 @@ static const char scaleFactorEnvVar[] = "QT_SCALE_FACTOR"; static const char autoScreenEnvVar[] = "QT_AUTO_SCREEN_SCALE_FACTOR"; static const char screenFactorsEnvVar[] = "QT_SCREEN_SCALE_FACTORS"; -static inline qreal initialScaleFactor() +static inline qreal initialGlobalScaleFactor() { qreal result = 1; @@ -134,19 +134,31 @@ QDpi QHighDpiScaling::m_logicalDpi = QDpi(-1,-1); // The scaled logical DPI of t Initializes the QHighDpiScaling global variables. Called before the platform plugin is created. */ -void QHighDpiScaling::initHighDpiScaling() + +static inline bool usePixelDensity() { - if (QCoreApplication::testAttribute(Qt::AA_NoHighDpiScaling)) { - m_factor = 1; - m_active = false; - return; - } - m_factor = initialScaleFactor(); - bool usePlatformPluginPixelDensity = qEnvironmentVariableIsSet(autoScreenEnvVar) - || qgetenv(legacyDevicePixelEnvVar).toLower() == "auto"; + // Determine if we should set a scale factor based on the pixel density + // reported by the platform plugin. There are several enablers and several + // disablers. A single disable may veto all other enablers. + if (QCoreApplication::testAttribute(Qt::AA_DisableHighDpiScaling)) + return false; + bool screenEnvValueOk; + const int screenEnvValue = qEnvironmentVariableIntValue(autoScreenEnvVar, &screenEnvValueOk); + if (screenEnvValueOk && screenEnvValue < 1) + return false; + return QCoreApplication::testAttribute(Qt::AA_EnableHighDpiScaling) + || (screenEnvValueOk && screenEnvValue > 0) + || (qEnvironmentVariableIsSet(legacyDevicePixelEnvVar) && qgetenv(legacyDevicePixelEnvVar).toLower() == "auto"); +} +void QHighDpiScaling::initHighDpiScaling() +{ + // Determine if there is a global scale factor set. + m_factor = initialGlobalScaleFactor(); m_globalScalingActive = !qFuzzyCompare(m_factor, qreal(1)); - m_usePixelDensity = usePlatformPluginPixelDensity; + + m_usePixelDensity = usePixelDensity(); + m_pixelDensityScalingActive = false; //set in updateHighDpiScaling below // we update m_active in updateHighDpiScaling, but while we create the @@ -156,7 +168,7 @@ void QHighDpiScaling::initHighDpiScaling() void QHighDpiScaling::updateHighDpiScaling() { - if (QCoreApplication::testAttribute(Qt::AA_NoHighDpiScaling)) + if (QCoreApplication::testAttribute(Qt::AA_DisableHighDpiScaling)) return; if (m_usePixelDensity && !m_pixelDensityScalingActive) { diff --git a/src/plugins/platforms/winrt/qwinrtscreen.cpp b/src/plugins/platforms/winrt/qwinrtscreen.cpp index d1a69c43f7..8ba71d88e7 100644 --- a/src/plugins/platforms/winrt/qwinrtscreen.cpp +++ b/src/plugins/platforms/winrt/qwinrtscreen.cpp @@ -89,6 +89,27 @@ typedef ITypedEventHandler<StatusBar*, IInspectable*> StatusBarHandler; QT_BEGIN_NAMESPACE +struct KeyInfo { + KeyInfo() + : virtualKey(0) + { + } + + KeyInfo(const QString &text, quint32 virtualKey) + : text(text) + , virtualKey(virtualKey) + { + } + + KeyInfo(quint32 virtualKey) + : virtualKey(virtualKey) + { + } + + QString text; + quint32 virtualKey; +}; + static inline Qt::ScreenOrientations qtOrientationsFromNative(DisplayOrientations native) { Qt::ScreenOrientations orientations = Qt::PrimaryOrientation; @@ -435,10 +456,7 @@ public: Qt::ScreenOrientation nativeOrientation; Qt::ScreenOrientation orientation; QList<QWindow *> visibleWindows; -#ifndef Q_OS_WINPHONE - QHash<quint32, QPair<Qt::Key, QString>> activeKeys; -#endif - + QHash<Qt::Key, KeyInfo> activeKeys; QHash<CoreWindowCallbackRemover, EventRegistrationToken> windowTokens; QHash<DisplayCallbackRemover, EventRegistrationToken> displayTokens; #ifdef Q_OS_WINPHONE @@ -827,57 +845,94 @@ void QWinRTScreen::handleExpose() HRESULT QWinRTScreen::onKeyDown(ABI::Windows::UI::Core::ICoreWindow *, ABI::Windows::UI::Core::IKeyEventArgs *args) { + Q_D(QWinRTScreen); VirtualKey virtualKey; - args->get_VirtualKey(&virtualKey); + HRESULT hr = args->get_VirtualKey(&virtualKey); + Q_ASSERT_SUCCEEDED(hr); + CorePhysicalKeyStatus status; + hr = args->get_KeyStatus(&status); + Q_ASSERT_SUCCEEDED(hr); + Qt::Key key = qKeyFromVirtual(virtualKey); // Defer character key presses to onCharacterReceived - if (key == Qt::Key_unknown || (key >= Qt::Key_Space && key <= Qt::Key_ydiaeresis)) + if (key == Qt::Key_unknown || (key >= Qt::Key_Space && key <= Qt::Key_ydiaeresis)) { + d->activeKeys.insert(key, KeyInfo(virtualKey)); return S_OK; - QWindowSystemInterface::handleKeyEvent(topWindow(), QEvent::KeyPress, key, keyboardModifiers()); + } + + QWindowSystemInterface::handleExtendedKeyEvent( + topWindow(), + QEvent::KeyPress, + key, + keyboardModifiers(), + !status.ScanCode ? -1 : status.ScanCode, + virtualKey, + 0, + QString(), + status.RepeatCount > 1, + !status.RepeatCount ? 1 : status.RepeatCount, + false); return S_OK; } HRESULT QWinRTScreen::onKeyUp(ABI::Windows::UI::Core::ICoreWindow *, ABI::Windows::UI::Core::IKeyEventArgs *args) { - Qt::KeyboardModifiers mods = keyboardModifiers(); -#ifndef Q_OS_WINPHONE Q_D(QWinRTScreen); - CorePhysicalKeyStatus status; // Look for a pressed character key - if (SUCCEEDED(args->get_KeyStatus(&status)) && d->activeKeys.contains(status.ScanCode)) { - QPair<Qt::Key, QString> keyStatus = d->activeKeys.take(status.ScanCode); - QWindowSystemInterface::handleKeyEvent(topWindow(), QEvent::KeyRelease, - keyStatus.first, mods, keyStatus.second); - return S_OK; - } -#endif // !Q_OS_WINPHONE VirtualKey virtualKey; - args->get_VirtualKey(&virtualKey); - QWindowSystemInterface::handleKeyEvent(topWindow(), QEvent::KeyRelease, - qKeyFromVirtual(virtualKey), mods); + HRESULT hr = args->get_VirtualKey(&virtualKey); + Q_ASSERT_SUCCEEDED(hr); + CorePhysicalKeyStatus status; + hr = args->get_KeyStatus(&status); + Q_ASSERT_SUCCEEDED(hr); + + Qt::Key key = qKeyFromVirtual(virtualKey); + const KeyInfo info = d->activeKeys.take(key); + QWindowSystemInterface::handleExtendedKeyEvent( + topWindow(), + QEvent::KeyRelease, + key, + keyboardModifiers(), + !status.ScanCode ? -1 : status.ScanCode, + virtualKey, + 0, + info.text, + status.RepeatCount > 1, + !status.RepeatCount ? 1 : status.RepeatCount, + false); return S_OK; } HRESULT QWinRTScreen::onCharacterReceived(ICoreWindow *, ICharacterReceivedEventArgs *args) { + Q_D(QWinRTScreen); quint32 keyCode; - args->get_KeyCode(&keyCode); + HRESULT hr = args->get_KeyCode(&keyCode); + Q_ASSERT_SUCCEEDED(hr); + CorePhysicalKeyStatus status; + hr = args->get_KeyStatus(&status); + Q_ASSERT_SUCCEEDED(hr); + // Don't generate character events for non-printables; the meta key stage is enough if (qIsNonPrintable(keyCode)) return S_OK; - Qt::KeyboardModifiers mods = keyboardModifiers(); - Qt::Key key = qKeyFromCode(keyCode, mods); - QString text = QChar(keyCode); - QWindowSystemInterface::handleKeyEvent(topWindow(), QEvent::KeyPress, key, mods, text); -#ifndef Q_OS_WINPHONE - Q_D(QWinRTScreen); - CorePhysicalKeyStatus status; // Defer release to onKeyUp for physical keys - if (SUCCEEDED(args->get_KeyStatus(&status)) && !status.IsKeyReleased) { - d->activeKeys.insert(status.ScanCode, qMakePair(key, text)); - return S_OK; - } -#endif // !Q_OS_WINPHONE - QWindowSystemInterface::handleKeyEvent(topWindow(), QEvent::KeyRelease, key, mods, text); + const Qt::KeyboardModifiers modifiers = keyboardModifiers(); + const Qt::Key key = qKeyFromCode(keyCode, modifiers); + const QString text = QChar(keyCode); + const quint32 virtualKey = d->activeKeys.value(key).virtualKey; + QWindowSystemInterface::handleExtendedKeyEvent( + topWindow(), + QEvent::KeyPress, + key, + modifiers, + !status.ScanCode ? -1 : status.ScanCode, + virtualKey, + 0, + text, + status.RepeatCount > 1, + !status.RepeatCount ? 1 : status.RepeatCount, + false); + d->activeKeys.insert(key, KeyInfo(text, virtualKey)); return S_OK; } |