diff options
Diffstat (limited to 'src/gui/kernel/qguiapplication.cpp')
-rw-r--r-- | src/gui/kernel/qguiapplication.cpp | 177 |
1 files changed, 152 insertions, 25 deletions
diff --git a/src/gui/kernel/qguiapplication.cpp b/src/gui/kernel/qguiapplication.cpp index 3c85dbe097..54f3996b6e 100644 --- a/src/gui/kernel/qguiapplication.cpp +++ b/src/gui/kernel/qguiapplication.cpp @@ -58,6 +58,7 @@ #include <QtCore/private/qabstracteventdispatcher_p.h> #include <QtCore/qmutex.h> #include <QtCore/private/qthread_p.h> +#include <QtCore/private/qlocking_p.h> #include <QtCore/qdir.h> #include <QtCore/qlibraryinfo.h> #include <QtCore/qnumeric.h> @@ -68,7 +69,7 @@ #include <qpalette.h> #include <qscreen.h> #include "qsessionmanager.h" -#include <private/qcolorprofile_p.h> +#include <private/qcolortrclut_p.h> #include <private/qscreen_p.h> #include <QtGui/qgenericpluginfactory.h> @@ -146,6 +147,8 @@ QString QGuiApplicationPrivate::styleOverride; Qt::ApplicationState QGuiApplicationPrivate::applicationState = Qt::ApplicationInactive; +Qt::HighDpiScaleFactorRoundingPolicy QGuiApplicationPrivate::highDpiScaleFactorRoundingPolicy = + Qt::HighDpiScaleFactorRoundingPolicy::RoundPreferFloor; bool QGuiApplicationPrivate::highDpiScalingUpdated = false; QPointer<QWindow> QGuiApplicationPrivate::currentDragWindow; @@ -687,6 +690,8 @@ QGuiApplication::~QGuiApplication() QGuiApplicationPrivate::lastCursorPosition = {qInf(), qInf()}; QGuiApplicationPrivate::currentMousePressWindow = QGuiApplicationPrivate::currentMouseWindow = nullptr; QGuiApplicationPrivate::applicationState = Qt::ApplicationInactive; + QGuiApplicationPrivate::highDpiScaleFactorRoundingPolicy = + Qt::HighDpiScaleFactorRoundingPolicy::RoundPreferFloor; QGuiApplicationPrivate::highDpiScalingUpdated = false; QGuiApplicationPrivate::currentDragWindow = nullptr; QGuiApplicationPrivate::tabletDevicePoints.clear(); @@ -1306,6 +1311,60 @@ static void init_plugins(const QList<QByteArray> &pluginList) } } +#if QT_CONFIG(commandlineparser) +void QGuiApplicationPrivate::addQtOptions(QList<QCommandLineOption> *options) +{ + QCoreApplicationPrivate::addQtOptions(options); + +#if defined(Q_OS_UNIX) && !defined(Q_OS_DARWIN) + const QByteArray sessionType = qgetenv("XDG_SESSION_TYPE"); + const bool x11 = sessionType == "x11"; + // Technically the x11 aliases are only available if platformName is "xcb", but we can't know that here. +#else + const bool x11 = false; +#endif + + options->append(QCommandLineOption(QStringLiteral("platform"), + QGuiApplication::tr("QPA plugin. See QGuiApplication documentation for available options for each plugin."), QStringLiteral("platformName[:options]"))); + options->append(QCommandLineOption(QStringLiteral("platformpluginpath"), + QGuiApplication::tr("Path to the platform plugins."), QStringLiteral("path"))); + options->append(QCommandLineOption(QStringLiteral("platformtheme"), + QGuiApplication::tr("Platform theme."), QStringLiteral("theme"))); + options->append(QCommandLineOption(QStringLiteral("plugin"), + QGuiApplication::tr("Additional plugins to load, can be specified multiple times."), QStringLiteral("plugin"))); + options->append(QCommandLineOption(QStringLiteral("qwindowgeometry"), + QGuiApplication::tr("Window geometry for the main window, using the X11-syntax, like 100x100+50+50."), QStringLiteral("geometry"))); + options->append(QCommandLineOption(QStringLiteral("qwindowicon"), + QGuiApplication::tr("Default window icon."), QStringLiteral("icon"))); + options->append(QCommandLineOption(QStringLiteral("qwindowtitle"), + QGuiApplication::tr("Title of the first window."), QStringLiteral("title"))); + options->append(QCommandLineOption(QStringLiteral("reverse"), + QGuiApplication::tr("Sets the application's layout direction to Qt::RightToLeft (debugging helper)."))); + options->append(QCommandLineOption(QStringLiteral("session"), + QGuiApplication::tr("Restores the application from an earlier session."), QStringLiteral("session"))); + + if (x11) { + options->append(QCommandLineOption(QStringLiteral("display"), + QGuiApplication::tr("Display name, overrides $DISPLAY."), QStringLiteral("display"))); + options->append(QCommandLineOption(QStringLiteral("name"), + QGuiApplication::tr("Instance name according to ICCCM 4.1.2.5."), QStringLiteral("name"))); + options->append(QCommandLineOption(QStringLiteral("nograb"), + QGuiApplication::tr("Disable mouse grabbing (useful in debuggers)."))); + options->append(QCommandLineOption(QStringLiteral("dograb"), + QGuiApplication::tr("Force mouse grabbing (even when running in a debugger)."))); + options->append(QCommandLineOption(QStringLiteral("visual"), + QGuiApplication::tr("ID of the X11 Visual to use."), QStringLiteral("id"))); + // Not using the "QStringList names" solution for those aliases, because it makes the first column too wide + options->append(QCommandLineOption(QStringLiteral("geometry"), + QGuiApplication::tr("Alias for --windowgeometry."), QStringLiteral("geometry"))); + options->append(QCommandLineOption(QStringLiteral("icon"), + QGuiApplication::tr("Alias for --windowicon."), QStringLiteral("icon"))); + options->append(QCommandLineOption(QStringLiteral("title"), + QGuiApplication::tr("Alias for --windowtitle."), QStringLiteral("title"))); + } +} +#endif // QT_CONFIG(commandlineparser) + void QGuiApplicationPrivate::createPlatformIntegration() { QHighDpiScaling::initHighDpiScaling(); @@ -1648,8 +1707,6 @@ QGuiApplicationPrivate::~QGuiApplicationPrivate() platform_theme = 0; delete platform_integration; platform_integration = 0; - delete m_a8ColorProfile.load(); - delete m_a32ColorProfile.load(); window_list.clear(); screen_list.clear(); @@ -1806,7 +1863,20 @@ bool QGuiApplication::event(QEvent *e) { if(e->type() == QEvent::LanguageChange) { setLayoutDirection(qt_detectRTLLanguage()?Qt::RightToLeft:Qt::LeftToRight); + } else if (e->type() == QEvent::Quit) { + // Close open windows. This is done in order to deliver de-expose + // events while the event loop is still running. + for (QWindow *topLevelWindow : QGuiApplication::topLevelWindows()) { + // Already closed windows will not have a platform window, skip those + if (!topLevelWindow->handle()) + continue; + if (!topLevelWindow->close()) { + e->ignore(); + return true; + } + } } + return QCoreApplication::event(e); } @@ -1832,7 +1902,11 @@ bool QGuiApplicationPrivate::sendQWindowEventToQPlatformWindow(QWindow *window, return platformWindow->windowEvent(event); } +#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) +bool QGuiApplicationPrivate::processNativeEvent(QWindow *window, const QByteArray &eventType, void *message, qintptr *result) +#else bool QGuiApplicationPrivate::processNativeEvent(QWindow *window, const QByteArray &eventType, void *message, long *result) +#endif { return window->nativeEvent(eventType, message, result); } @@ -1879,6 +1953,9 @@ void QGuiApplicationPrivate::processWindowSystemEvent(QWindowSystemInterfacePriv QWindowSystemInterfacePrivate::ApplicationStateChangedEvent * changeEvent = static_cast<QWindowSystemInterfacePrivate::ApplicationStateChangedEvent *>(e); QGuiApplicationPrivate::setApplicationState(changeEvent->newState, changeEvent->forcePropagate); } break; + case QWindowSystemInterfacePrivate::ApplicationTermination: + QGuiApplicationPrivate::processApplicationTermination(e); + break; case QWindowSystemInterfacePrivate::FlushEvents: { QWindowSystemInterfacePrivate::FlushEventsEvent *flushEventsEvent = static_cast<QWindowSystemInterfacePrivate::FlushEventsEvent *>(e); QWindowSystemInterface::deferredFlushWindowSystemEvents(flushEventsEvent->flags); } @@ -2183,8 +2260,16 @@ void QGuiApplicationPrivate::processWheelEvent(QWindowSystemInterfacePrivate::Wh return; } +#if QT_DEPRECATED_SINCE(5, 14) +QT_WARNING_PUSH +QT_WARNING_DISABLE_DEPRECATED QWheelEvent ev(localPoint, globalPoint, e->pixelDelta, e->angleDelta, e->qt4Delta, e->qt4Orientation, mouse_buttons, e->modifiers, e->phase, e->source, e->inverted); +QT_WARNING_POP +#else + QWheelEvent ev(localPoint, globalPoint, e->pixelDelta, e->angleDelta, + mouse_buttons, e->modifiers, e->phase, e->inverted, e->source); +#endif ev.setTimestamp(e->timestamp); QGuiApplication::sendSpontaneousEvent(window, &ev); #else @@ -2458,9 +2543,8 @@ void QGuiApplicationPrivate::processCloseEvent(QWindowSystemInterfacePrivate::Cl QCloseEvent event; QGuiApplication::sendSpontaneousEvent(e->window.data(), &event); - if (e->accepted) { - *(e->accepted) = event.isAccepted(); - } + + e->eventAccepted = event.isAccepted(); } void QGuiApplicationPrivate::processFileOpenEvent(QWindowSystemInterfacePrivate::FileOpenEvent *e) @@ -2777,10 +2861,12 @@ void QGuiApplicationPrivate::processTouchEvent(QWindowSystemInterfacePrivate::To if (touchPoint.state() == Qt::TouchPointStationary) { if (touchInfo.touchPoint.velocity() != touchPoint.velocity()) { touchInfo.touchPoint.setVelocity(touchPoint.velocity()); + touchPoint.d->stationaryWithModifiedProperty = true; stationaryTouchPointChangedProperty = true; } if (!qFuzzyCompare(touchInfo.touchPoint.pressure(), touchPoint.pressure())) { touchInfo.touchPoint.setPressure(touchPoint.pressure()); + touchPoint.d->stationaryWithModifiedProperty = true; stationaryTouchPointChangedProperty = true; } } else { @@ -3240,7 +3326,7 @@ void QGuiApplicationPrivate::applyWindowGeometrySpecificationTo(QWindow *window) QFont QGuiApplication::font() { Q_ASSERT_X(QGuiApplicationPrivate::self, "QGuiApplication::font()", "no QGuiApplication instance"); - QMutexLocker locker(&applicationFontMutex); + const auto locker = qt_scoped_lock(applicationFontMutex); initFontUnlocked(); return *QGuiApplicationPrivate::app_font; } @@ -3252,7 +3338,7 @@ QFont QGuiApplication::font() */ void QGuiApplication::setFont(const QFont &font) { - QMutexLocker locker(&applicationFontMutex); + auto locker = qt_unique_lock(applicationFontMutex); const bool emitChange = !QGuiApplicationPrivate::app_font || (*QGuiApplicationPrivate::app_font != font); if (!QGuiApplicationPrivate::app_font) @@ -3419,6 +3505,13 @@ bool QGuiApplicationPrivate::tryCloseRemainingWindows(QWindowList processedWindo return true; } +void QGuiApplicationPrivate::processApplicationTermination(QWindowSystemInterfacePrivate::WindowSystemEvent *windowSystemEvent) +{ + QEvent event(QEvent::Quit); + QGuiApplication::sendSpontaneousEvent(QGuiApplication::instance(), &event); + windowSystemEvent->eventAccepted = event.isAccepted(); +} + /*! \since 5.2 \fn Qt::ApplicationState QGuiApplication::applicationState() @@ -3437,6 +3530,46 @@ Qt::ApplicationState QGuiApplication::applicationState() } /*! + \since 5.14 + + Sets the high-DPI scale factor rounding policy for the application. The + \a policy decides how non-integer scale factors (such as Windows 150%) are + handled, for applications that have AA_EnableHighDpiScaling enabled. + + The two principal options are whether fractional scale factors should + be rounded to an integer or not. Keeping the scale factor as-is will + make the user interface size match the OS setting exactly, but may cause + painting errors, for example with the Windows style. + + If rounding is wanted, then which type of rounding should be decided + next. Mathematically correct rounding is supported but may not give + the best visual results: Consider if you want to render 1.5x as 1x + ("small UI") or as 2x ("large UI"). See the Qt::HighDpiScaleFactorRoundingPolicy + enum for a complete list of all options. + + This function must be called before creating the application object, + and can be overridden by setting the QT_SCALE_FACTOR_ROUNDING_POLICY + environment variable. The QGuiApplication::highDpiScaleFactorRoundingPolicy() + accessor will reflect the environment, if set. + + The default value is Qt::HighDpiScaleFactorRoundingPolicy::RoundPreferFloor. +*/ +void QGuiApplication::setHighDpiScaleFactorRoundingPolicy(Qt::HighDpiScaleFactorRoundingPolicy policy) +{ + QGuiApplicationPrivate::highDpiScaleFactorRoundingPolicy = policy; +} + +/*! + \since 5.14 + + Returns the high-DPI scale factor rounding policy. +*/ +Qt::HighDpiScaleFactorRoundingPolicy QGuiApplication::highDpiScaleFactorRoundingPolicy() +{ + return QGuiApplicationPrivate::highDpiScaleFactorRoundingPolicy; +} + +/*! \since 5.2 \fn void QGuiApplication::applicationStateChanged(Qt::ApplicationState state) @@ -3976,7 +4109,7 @@ void QGuiApplicationPrivate::notifyThemeChanged() sendApplicationPaletteChange(); } if (!(applicationResourceFlags & ApplicationFontExplicitlySet)) { - QMutexLocker locker(&applicationFontMutex); + const auto locker = qt_scoped_lock(applicationFontMutex); clearFontUnlocked(); initFontUnlocked(); } @@ -4000,32 +4133,26 @@ void QGuiApplicationPrivate::notifyDragStarted(const QDrag *drag) } #endif -const QColorProfile *QGuiApplicationPrivate::colorProfileForA8Text() +const QColorTrcLut *QGuiApplicationPrivate::colorProfileForA8Text() { #ifdef Q_OS_WIN - QColorProfile *result = m_a8ColorProfile.load(); - if (!result){ - QColorProfile *cs = QColorProfile::fromGamma(2.31); // This is a hard-coded thing for Windows text rendering - if (!m_a8ColorProfile.testAndSetRelease(0, cs)) - delete cs; - result = m_a8ColorProfile.load(); + if (!m_a8ColorProfile){ + QColorTrcLut *cs = QColorTrcLut::fromGamma(2.31); // This is a hard-coded thing for Windows text rendering + m_a8ColorProfile.reset(cs); } - return result; + return m_a8ColorProfile.get(); #else return colorProfileForA32Text(); #endif } -const QColorProfile *QGuiApplicationPrivate::colorProfileForA32Text() +const QColorTrcLut *QGuiApplicationPrivate::colorProfileForA32Text() { - QColorProfile *result = m_a32ColorProfile.load(); - if (!result){ - QColorProfile *cs = QColorProfile::fromGamma(fontSmoothingGamma); - if (!m_a32ColorProfile.testAndSetRelease(0, cs)) - delete cs; - result = m_a32ColorProfile.load(); + if (!m_a32ColorProfile) { + QColorTrcLut *cs = QColorTrcLut::fromGamma(fontSmoothingGamma); + m_a32ColorProfile.reset(cs); } - return result; + return m_a32ColorProfile.get(); } void QGuiApplicationPrivate::_q_updateFocusObject(QObject *object) |