diff options
Diffstat (limited to 'src/gui/kernel/qguiapplication.cpp')
-rw-r--r-- | src/gui/kernel/qguiapplication.cpp | 228 |
1 files changed, 183 insertions, 45 deletions
diff --git a/src/gui/kernel/qguiapplication.cpp b/src/gui/kernel/qguiapplication.cpp index 6653d5a207..1186cc2905 100644 --- a/src/gui/kernel/qguiapplication.cpp +++ b/src/gui/kernel/qguiapplication.cpp @@ -101,6 +101,8 @@ # include <QtCore/QLibraryInfo> #endif // Q_OS_WIN && !Q_OS_WINCE +#include <ctype.h> + QT_BEGIN_NAMESPACE Q_GUI_EXPORT bool qt_is_gui_used = true; @@ -215,6 +217,106 @@ static inline bool isPopupWindow(const QWindow *w) return (w->flags() & Qt::WindowType_Mask) == Qt::Popup; } +// Geometry specification for top level windows following the convention of the +// -geometry command line arguments in X11 (see XParseGeometry). +struct QWindowGeometrySpecification +{ + QWindowGeometrySpecification() : corner(Qt::TopLeftCorner), xOffset(-1), yOffset(-1), width(-1), height(-1) {} + static QWindowGeometrySpecification fromArgument(const QByteArray &a); + QRect apply(const QRect &windowGeometry, const QSize &windowMinimumSize, const QSize &windowMaximumSize, const QRect &availableGeometry) const; + inline QRect apply(const QRect &windowGeometry, const QWindow *window) const + { return apply(windowGeometry, window->minimumSize(), window->maximumSize(), window->screen()->virtualGeometry()); } + + Qt::Corner corner; + int xOffset; + int yOffset; + int width; + int height; +}; + +// Parse a token of a X11 geometry specification "200x100+10-20". +static inline int nextGeometryToken(const QByteArray &a, int &pos, char *op) +{ + *op = 0; + const int size = a.size(); + if (pos >= size) + return -1; + + *op = a.at(pos); + if (*op == '+' || *op == '-' || *op == 'x') + pos++; + else if (isdigit(*op)) + *op = 'x'; // If it starts with a digit, it is supposed to be a width specification. + else + return -1; + + const int numberPos = pos; + for ( ; pos < size && isdigit(a.at(pos)); ++pos) ; + + bool ok; + const int result = a.mid(numberPos, pos - numberPos).toInt(&ok); + return ok ? result : -1; +} + +QWindowGeometrySpecification QWindowGeometrySpecification::fromArgument(const QByteArray &a) +{ + QWindowGeometrySpecification result; + int pos = 0; + for (int i = 0; i < 4; ++i) { + char op; + const int value = nextGeometryToken(a, pos, &op); + if (value < 0) + break; + switch (op) { + case 'x': + (result.width >= 0 ? result.height : result.width) = value; + break; + case '+': + case '-': + if (result.xOffset >= 0) { + result.yOffset = value; + if (op == '-') + result.corner = result.corner == Qt::TopRightCorner ? Qt::BottomRightCorner : Qt::BottomLeftCorner; + } else { + result.xOffset = value; + if (op == '-') + result.corner = Qt::TopRightCorner; + } + } + } + return result; +} + +QRect QWindowGeometrySpecification::apply(const QRect &windowGeometry, const QSize &windowMinimumSize, const QSize &windowMaximumSize, const QRect &availableGeometry) const +{ + QRect result = windowGeometry; + if (width >= 0 || height >= 0) { + QSize size = windowGeometry.size(); + if (width >= 0) + size.setWidth(qBound(windowMinimumSize.width(), width, windowMaximumSize.width())); + if (height >= 0) + size.setHeight(qBound(windowMinimumSize.height(), height, windowMaximumSize.height())); + result.setSize(size); + } + if (xOffset >= 0 || yOffset >= 0) { + QPoint topLeft = windowGeometry.topLeft(); + if (xOffset >= 0) { + topLeft.setX(corner == Qt::TopLeftCorner || corner == Qt::BottomLeftCorner ? + xOffset : + qMax(availableGeometry.right() - result.width() - xOffset, availableGeometry.left())); + } + if (yOffset >= 0) { + topLeft.setY(corner == Qt::TopLeftCorner || corner == Qt::TopRightCorner ? + yOffset : + qMax(availableGeometry.bottom() - result.height() - yOffset, availableGeometry.top())); + } + result.moveTopLeft(topLeft); + } + return result; +} + +static QWindowGeometrySpecification windowGeometrySpecification; + /*! \class QGuiApplication \brief The QGuiApplication class manages the GUI application's control @@ -785,14 +887,14 @@ QString QGuiApplication::platformName() *QGuiApplicationPrivate::platform_name : QString(); } -static void init_platform(const QString &pluginArgument, const QString &platformPluginPath) +static void init_platform(const QString &pluginArgument, const QString &platformPluginPath, int &argc, char **argv) { // Split into platform name and arguments QStringList arguments = pluginArgument.split(QLatin1Char(':')); const QString name = arguments.takeFirst().toLower(); // Create the platform integration. - QGuiApplicationPrivate::platform_integration = QPlatformIntegrationFactory::create(name, arguments, platformPluginPath); + QGuiApplicationPrivate::platform_integration = QPlatformIntegrationFactory::create(name, arguments, argc, argv, platformPluginPath); if (QGuiApplicationPrivate::platform_integration) { QGuiApplicationPrivate::platform_name = new QString(name); } else { @@ -910,6 +1012,9 @@ void QGuiApplicationPrivate::createPlatformIntegration() } else if (arg == "-platform") { if (++i < argc) platformName = argv[i]; + } else if (arg == "-qwindowgeometry" || (platformName == "xcb" && arg == "-geometry")) { + if (++i < argc) + windowGeometrySpecification = QWindowGeometrySpecification::fromArgument(argv[i]); } else { argv[j++] = argv[i]; } @@ -920,7 +1025,7 @@ void QGuiApplicationPrivate::createPlatformIntegration() argc = j; } - init_platform(QLatin1String(platformName), platformPluginPath); + init_platform(QLatin1String(platformName), platformPluginPath, argc, argv); } @@ -963,7 +1068,10 @@ void QGuiApplicationPrivate::init() bool doGrabUnderDebugger = false; QList<QByteArray> pluginList; // Get command line params - +#ifndef QT_NO_SESSIONMANAGER + QString session_id; + QString session_key; +#endif int j = argc ? 1 : 0; for (int i=1; i<argc; i++) { if (argv[i] && *argv[i] != '-') { @@ -1313,7 +1421,7 @@ void QGuiApplicationPrivate::processWindowSystemEvent(QWindowSystemInterfacePriv QGuiApplicationPrivate::processWindowScreenChangedEvent(static_cast<QWindowSystemInterfacePrivate::WindowScreenChangedEvent *>(e)); break; case QWindowSystemInterfacePrivate::ApplicationStateChanged: - QGuiApplicationPrivate::processApplicationStateChangedEvent(static_cast<QWindowSystemInterfacePrivate::ApplicationStateChangedEvent *>(e)); + QGuiApplicationPrivate::setApplicationState(static_cast<QWindowSystemInterfacePrivate::ApplicationStateChangedEvent *>(e)->newState); break; case QWindowSystemInterfacePrivate::FlushEvents: QWindowSystemInterface::deferredFlushWindowSystemEvents(); @@ -1375,6 +1483,8 @@ void QGuiApplicationPrivate::processWindowSystemEvent(QWindowSystemInterfacePriv static_cast<QWindowSystemInterfacePrivate::ContextMenuEvent *>(e)); break; #endif + case QWindowSystemInterfacePrivate::EnterWhatsThisMode: + QGuiApplication::postEvent(QGuiApplication::instance(), new QEvent(QEvent::EnterWhatsThisMode)); default: qWarning() << "Unknown user input event type:" << e->type; break; @@ -1531,7 +1641,7 @@ void QGuiApplicationPrivate::processWheelEvent(QWindowSystemInterfacePrivate::Wh return; } - QWheelEvent ev(localPoint, globalPoint, e->pixelDelta, e->angleDelta, e->qt4Delta, e->qt4Orientation, buttons, e->modifiers); + QWheelEvent ev(localPoint, globalPoint, e->pixelDelta, e->angleDelta, e->qt4Delta, e->qt4Orientation, buttons, e->modifiers, e->phase); ev.setTimestamp(e->timestamp); QGuiApplication::sendSpontaneousEvent(window, &ev); #endif /* ifndef QT_NO_WHEELEVENT */ @@ -1641,10 +1751,7 @@ void QGuiApplicationPrivate::processActivatedEvent(QWindowSystemInterfacePrivate QObject::disconnect(previous, SIGNAL(focusObjectChanged(QObject*)), qApp, SLOT(_q_updateFocusObject(QObject*))); } else if (!platformIntegration()->hasCapability(QPlatformIntegration::ApplicationState)) { - QEvent appActivate(QEvent::ApplicationActivate); - qApp->sendSpontaneousEvent(qApp, &appActivate); - QApplicationStateChangeEvent appState(Qt::ApplicationActive); - qApp->sendSpontaneousEvent(qApp, &appState); + setApplicationState(Qt::ApplicationActive); } if (QGuiApplicationPrivate::focus_window) { @@ -1653,10 +1760,7 @@ void QGuiApplicationPrivate::processActivatedEvent(QWindowSystemInterfacePrivate QObject::connect(QGuiApplicationPrivate::focus_window, SIGNAL(focusObjectChanged(QObject*)), qApp, SLOT(_q_updateFocusObject(QObject*))); } else if (!platformIntegration()->hasCapability(QPlatformIntegration::ApplicationState)) { - QEvent appActivate(QEvent::ApplicationDeactivate); - qApp->sendSpontaneousEvent(qApp, &appActivate); - QApplicationStateChangeEvent appState(Qt::ApplicationInactive); - qApp->sendSpontaneousEvent(qApp, &appState); + setApplicationState(Qt::ApplicationInactive); } if (self) { @@ -1692,29 +1796,6 @@ void QGuiApplicationPrivate::processWindowScreenChangedEvent(QWindowSystemInterf } } -void QGuiApplicationPrivate::processApplicationStateChangedEvent(QWindowSystemInterfacePrivate::ApplicationStateChangedEvent *e) -{ - if (e->newState == applicationState) - return; - applicationState = e->newState; - - switch (e->newState) { - case Qt::ApplicationActive: { - QEvent appActivate(QEvent::ApplicationActivate); - qApp->sendSpontaneousEvent(qApp, &appActivate); - break; } - case Qt::ApplicationInactive: { - QEvent appDeactivate(QEvent::ApplicationDeactivate); - qApp->sendSpontaneousEvent(qApp, &appDeactivate); - break; } - default: - break; - } - - QApplicationStateChangeEvent event(applicationState); - qApp->sendSpontaneousEvent(qApp, &event); -} - void QGuiApplicationPrivate::processThemeChanged(QWindowSystemInterfacePrivate::ThemeChangeEvent *tce) { if (self) @@ -2398,6 +2479,11 @@ void QGuiApplication::setPalette(const QPalette &pal) applicationResourceFlags |= ApplicationPaletteExplicitlySet; } +QRect QGuiApplicationPrivate::applyWindowGeometrySpecification(const QRect &windowGeometry, const QWindow *window) +{ + return windowGeometrySpecification.apply(windowGeometry, window); +} + /*! Returns the default application font. @@ -2520,6 +2606,58 @@ bool QGuiApplicationPrivate::shouldQuitInternal(const QWindowList &processedWind } /*! + \since 5.2 + \fn Qt::ApplicationState QGuiApplication::applicationState() + + + Returns the current state of the application. + + You can react to application state changes to perform actions such as + stopping/resuming CPU-intensive tasks, freeing/loading resources or + saving/restoring application data. + */ + +Qt::ApplicationState QGuiApplication::applicationState() +{ + return QGuiApplicationPrivate::applicationState; +} + +/*! + \since 5.2 + \fn void QGuiApplication::applicationStateChanged(Qt::ApplicationState state) + + This signal is emitted when the \a state of the application changes. + + \sa applicationState() +*/ + +void QGuiApplicationPrivate::setApplicationState(Qt::ApplicationState state) +{ + if (applicationState == state) + return; + + applicationState = state; + + switch (state) { + case Qt::ApplicationActive: { + QEvent appActivate(QEvent::ApplicationActivate); + QCoreApplication::sendSpontaneousEvent(qApp, &appActivate); + break; } + case Qt::ApplicationInactive: { + QEvent appDeactivate(QEvent::ApplicationDeactivate); + QCoreApplication::sendSpontaneousEvent(qApp, &appDeactivate); + break; } + default: + break; + } + + QApplicationStateChangeEvent event(applicationState); + QCoreApplication::sendSpontaneousEvent(qApp, &event); + + emit qApp->applicationStateChanged(applicationState); +} + +/*! \since 4.2 \fn void QGuiApplication::commitDataRequest(QSessionManager &manager) @@ -2632,13 +2770,13 @@ bool QGuiApplication::isSessionRestored() const QString QGuiApplication::sessionId() const { Q_D(const QGuiApplication); - return d->session_id; + return d->session_manager->sessionId(); } QString QGuiApplication::sessionKey() const { Q_D(const QGuiApplication); - return d->session_key; + return d->session_manager->sessionKey(); } bool QGuiApplication::isSavingSession() const @@ -2647,12 +2785,12 @@ bool QGuiApplication::isSavingSession() const return d->is_saving_session; } -void QGuiApplicationPrivate::commitData(QSessionManager& manager) +void QGuiApplicationPrivate::commitData() { Q_Q(QGuiApplication); is_saving_session = true; - emit q->commitDataRequest(manager); - if (manager.allowsInteraction()) { + emit q->commitDataRequest(*session_manager); + if (session_manager->allowsInteraction()) { QWindowList done; QWindowList list = QGuiApplication::topLevelWindows(); bool cancelled = false; @@ -2667,17 +2805,17 @@ void QGuiApplicationPrivate::commitData(QSessionManager& manager) } } if (cancelled) - manager.cancel(); + session_manager->cancel(); } is_saving_session = false; } -void QGuiApplicationPrivate::saveState(QSessionManager &manager) +void QGuiApplicationPrivate::saveState() { Q_Q(QGuiApplication); is_saving_session = true; - emit q->saveStateRequest(manager); + emit q->saveStateRequest(*session_manager); is_saving_session = false; } #endif //QT_NO_SESSIONMANAGER |