summaryrefslogtreecommitdiffstats
path: root/src/gui/kernel/qguiapplication.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/gui/kernel/qguiapplication.cpp')
-rw-r--r--src/gui/kernel/qguiapplication.cpp228
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