summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFriedemann Kleint <Friedemann.Kleint@digia.com>2013-07-25 08:40:24 +0200
committerThe Qt Project <gerrit-noreply@qt-project.org>2013-07-25 15:06:46 +0200
commitd7e37537d4fa2127e6ec404b9f8358337f63d9b1 (patch)
treed1aca9a4f2af9baf9a9a571b4bcaa64ee711ec45
parent5ec08045837a5c689487b03a828f6ac4923375f6 (diff)
Reintroduce -geometry command line argument for X11/XCB.
Add parsing for the window geometry specification to QGuiApplicationPrivate. Enable the argument under a different name for the other platforms as well. Task-number: QTBUG-27349 Change-Id: I973b2c69f5172f7d0bc983b8ba4b0d164649ef02 Reviewed-by: David Faure <david.faure@kdab.com> Reviewed-by: Shawn Rutledge <shawn.rutledge@digia.com>
-rw-r--r--src/gui/kernel/qguiapplication.cpp110
-rw-r--r--src/gui/kernel/qguiapplication_p.h2
-rw-r--r--src/widgets/kernel/qwidget.cpp17
3 files changed, 125 insertions, 4 deletions
diff --git a/src/gui/kernel/qguiapplication.cpp b/src/gui/kernel/qguiapplication.cpp
index e1d0b1c01f..dd111be0eb 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
@@ -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];
}
@@ -2398,6 +2503,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.
diff --git a/src/gui/kernel/qguiapplication_p.h b/src/gui/kernel/qguiapplication_p.h
index 3a4b692b69..11f68ba2ff 100644
--- a/src/gui/kernel/qguiapplication_p.h
+++ b/src/gui/kernel/qguiapplication_p.h
@@ -275,6 +275,8 @@ public:
// hook reimplemented in QApplication to apply the QStyle function on the QIcon
virtual QPixmap applyQIconStyleHelper(QIcon::Mode, const QPixmap &basePixmap) const { return basePixmap; }
+ static QRect applyWindowGeometrySpecification(const QRect &windowGeometry, const QWindow *window);
+
protected:
virtual void notifyThemeChanged();
#ifndef QT_NO_DRAGANDDROP
diff --git a/src/widgets/kernel/qwidget.cpp b/src/widgets/kernel/qwidget.cpp
index 869362654c..ac649b4bdf 100644
--- a/src/widgets/kernel/qwidget.cpp
+++ b/src/widgets/kernel/qwidget.cpp
@@ -7268,10 +7268,19 @@ void QWidget::setVisible(bool visible)
create();
}
-#if defined(Q_WS_X11)
- if (windowType() == Qt::Window)
- QApplicationPrivate::applyX11SpecificCommandLineArguments(this);
-#endif
+ // Handling of the -qwindowgeometry, -geometry command line arguments
+ if (windowType() == Qt::Window && windowHandle()) {
+ static bool done = false;
+ if (!done) {
+ done = true;
+ const QRect oldGeometry = frameGeometry();
+ const QRect geometry = QGuiApplicationPrivate::applyWindowGeometrySpecification(oldGeometry, windowHandle());
+ if (oldGeometry.size() != geometry.size())
+ resize(geometry.size());
+ if (geometry.topLeft() != oldGeometry.topLeft())
+ move(geometry.topLeft());
+ } // done
+ }
bool wasResized = testAttribute(Qt::WA_Resized);
Qt::WindowStates initialWindowState = windowState();