summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSamuel Rødal <samuel.rodal@nokia.com>2011-05-16 16:39:50 +0200
committerSamuel Rødal <samuel.rodal@nokia.com>2011-05-16 16:40:32 +0200
commit25f70314e0e2aa5cb913aba108d2e9c16117004a (patch)
tree3a7a3a115ade70e24cf3b2a8887cf356da58cfe6
parent276d60a4d6c9d1b72c4aa7df1f86e7ce9097beeb (diff)
Implement QWindow minimum/maximum/base size hints and size increments.
-rw-r--r--examples/qpa/windows/window.cpp8
-rw-r--r--src/gui/kernel/qplatformwindow_qpa.cpp8
-rw-r--r--src/gui/kernel/qplatformwindow_qpa.h2
-rw-r--r--src/gui/kernel/qwindow.cpp76
-rw-r--r--src/gui/kernel/qwindow.h11
-rw-r--r--src/gui/kernel/qwindow_p.h10
-rw-r--r--src/plugins/platforms/xcb/qxcbwindow.cpp85
-rw-r--r--src/plugins/platforms/xcb/qxcbwindow.h4
-rw-r--r--src/widgets/kernel/qwidget_qpa.cpp17
9 files changed, 189 insertions, 32 deletions
diff --git a/examples/qpa/windows/window.cpp b/examples/qpa/windows/window.cpp
index d08db5714b..76bc117793 100644
--- a/examples/qpa/windows/window.cpp
+++ b/examples/qpa/windows/window.cpp
@@ -23,9 +23,15 @@ Window::Window(QWindow *parent)
if (parent)
setGeometry(QRect(160, 120, 320, 240));
- else
+ else {
setGeometry(QRect(10, 10, 640, 480));
+ setSizeIncrement(QSize(10, 10));
+ setBaseSize(QSize(640, 480));
+ setMinimumSize(QSize(240, 160));
+ setMaximumSize(QSize(800, 600));
+ }
+
create();
QGuiApplicationPrivate::platformIntegration()->createWindowSurface(this, winId());
diff --git a/src/gui/kernel/qplatformwindow_qpa.cpp b/src/gui/kernel/qplatformwindow_qpa.cpp
index d7d1d96f42..afbff2ad5d 100644
--- a/src/gui/kernel/qplatformwindow_qpa.cpp
+++ b/src/gui/kernel/qplatformwindow_qpa.cpp
@@ -161,6 +161,14 @@ void QPlatformWindow::raise() { qWarning("This plugin does not support raise()")
void QPlatformWindow::lower() { qWarning("This plugin does not support lower()"); }
/*!
+ Reimplement to propagate the size hints of the QWindow.
+
+ The size hints include QWindow::minimumSize(), QWindow::maximumSize(),
+ QWindow::sizeIncrement(), and QWindow::baseSize().
+*/
+void QPlatformWindow::propagateSizeHints() {qWarning("This plugin does not support propagateSizeHints()"); }
+
+/*!
Reimplement to be able to let Qt set the opacity level of a window
*/
void QPlatformWindow::setOpacity(qreal level)
diff --git a/src/gui/kernel/qplatformwindow_qpa.h b/src/gui/kernel/qplatformwindow_qpa.h
index c74e96695d..de3174bde9 100644
--- a/src/gui/kernel/qplatformwindow_qpa.h
+++ b/src/gui/kernel/qplatformwindow_qpa.h
@@ -80,6 +80,8 @@ public:
virtual void raise();
virtual void lower();
+ virtual void propagateSizeHints();
+
virtual void setOpacity(qreal level);
virtual void requestActivateWindow();
diff --git a/src/gui/kernel/qwindow.cpp b/src/gui/kernel/qwindow.cpp
index 897b370cf5..5d4fd763b8 100644
--- a/src/gui/kernel/qwindow.cpp
+++ b/src/gui/kernel/qwindow.cpp
@@ -143,6 +143,15 @@ void QWindow::setParent(QWindow *parent)
d->parentWindow = parent;
}
+/*!
+ Returns whether the window is top level, i.e. parent-less.
+ */
+bool QWindow::isTopLevel() const
+{
+ Q_D(const QWindow);
+ return d->parentWindow == 0;
+}
+
void QWindow::setWindowFormat(const QWindowFormat &format)
{
Q_D(QWindow);
@@ -256,26 +265,68 @@ void QWindow::setWindowState(Qt::WindowState state)
QSize QWindow::minimumSize() const
{
- qDebug() << "unimplemented:" << __FILE__ << __LINE__;
- return QSize();
+ Q_D(const QWindow);
+ return d->minimumSize;
}
QSize QWindow::maximumSize() const
{
- qDebug() << "unimplemented:" << __FILE__ << __LINE__;
- return QSize();
+ Q_D(const QWindow);
+ return d->maximumSize;
}
-void QWindow::setMinimumSize(const QSize &size) const
+QSize QWindow::baseSize() const
{
- Q_UNUSED(size);
- qDebug() << "unimplemented:" << __FILE__ << __LINE__;
+ Q_D(const QWindow);
+ return d->baseSize;
}
-void QWindow::setMaximumSize(const QSize &size) const
+QSize QWindow::sizeIncrement() const
{
- Q_UNUSED(size);
- qDebug() << "unimplemented:" << __FILE__ << __LINE__;
+ Q_D(const QWindow);
+ return d->sizeIncrement;
+}
+
+void QWindow::setMinimumSize(const QSize &size)
+{
+ Q_D(QWindow);
+ QSize adjustedSize = QSize(qBound(0, size.width(), QWINDOWSIZE_MAX), qBound(0, size.height(), QWINDOWSIZE_MAX));
+ if (d->minimumSize == adjustedSize)
+ return;
+ d->minimumSize = adjustedSize;
+ if (d->platformWindow && isTopLevel())
+ d->platformWindow->propagateSizeHints();
+}
+
+void QWindow::setMaximumSize(const QSize &size)
+{
+ Q_D(QWindow);
+ QSize adjustedSize = QSize(qBound(0, size.width(), QWINDOWSIZE_MAX), qBound(0, size.height(), QWINDOWSIZE_MAX));
+ if (d->maximumSize == adjustedSize)
+ return;
+ d->maximumSize = adjustedSize;
+ if (d->platformWindow && isTopLevel())
+ d->platformWindow->propagateSizeHints();
+}
+
+void QWindow::setBaseSize(const QSize &size)
+{
+ Q_D(QWindow);
+ if (d->baseSize == size)
+ return;
+ d->baseSize = size;
+ if (d->platformWindow && isTopLevel())
+ d->platformWindow->propagateSizeHints();
+}
+
+void QWindow::setSizeIncrement(const QSize &size)
+{
+ Q_D(QWindow);
+ if (d->sizeIncrement == size)
+ return;
+ d->sizeIncrement = size;
+ if (d->platformWindow && isTopLevel())
+ d->platformWindow->propagateSizeHints();
}
void QWindow::setGeometry(const QRect &rect)
@@ -464,4 +515,9 @@ void QWindow::wheelEvent(QWheelEvent *)
}
#endif //QT_NO_WHEELEVENT
+Q_GUI_EXPORT QWindowPrivate *qt_window_private(QWindow *window)
+{
+ return window->d_func();
+}
+
QT_END_NAMESPACE
diff --git a/src/gui/kernel/qwindow.h b/src/gui/kernel/qwindow.h
index 70227106b1..e0a1871ea1 100644
--- a/src/gui/kernel/qwindow.h
+++ b/src/gui/kernel/qwindow.h
@@ -94,6 +94,8 @@ public:
QWindow *parent() const;
void setParent(QWindow *parent);
+ bool isTopLevel() const;
+
QWindow *topLevelWindow() const;
void setWindowFormat(const QWindowFormat &format);
@@ -116,9 +118,13 @@ public:
QSize minimumSize() const;
QSize maximumSize() const;
+ QSize baseSize() const;
+ QSize sizeIncrement() const;
- void setMinimumSize(const QSize &size) const;
- void setMaximumSize(const QSize &size) const;
+ void setMinimumSize(const QSize &size);
+ void setMaximumSize(const QSize &size);
+ void setBaseSize(const QSize &size);
+ void setSizeIncrement(const QSize &size);
void setGeometry(const QRect &rect);
QRect geometry() const;
@@ -177,6 +183,7 @@ private:
friend class QGuiApplication;
friend class QGuiApplicationPrivate;
friend class QWindowSurface;
+ friend Q_GUI_EXPORT QWindowPrivate *qt_window_private(QWindow *window);
};
QT_END_NAMESPACE
diff --git a/src/gui/kernel/qwindow_p.h b/src/gui/kernel/qwindow_p.h
index b6227741ba..215a18d27e 100644
--- a/src/gui/kernel/qwindow_p.h
+++ b/src/gui/kernel/qwindow_p.h
@@ -52,7 +52,9 @@ QT_BEGIN_NAMESPACE
QT_MODULE(Gui)
-class QWindowPrivate : public QObjectPrivate
+#define QWINDOWSIZE_MAX ((1<<24)-1)
+
+class Q_GUI_EXPORT QWindowPrivate : public QObjectPrivate
{
public:
QWindowPrivate()
@@ -65,6 +67,7 @@ public:
, glContext(0)
, surface(0)
, windowState(Qt::WindowNoState)
+ , maximumSize(QWINDOWSIZE_MAX, QWINDOWSIZE_MAX)
{
isWindow = true;
}
@@ -84,6 +87,11 @@ public:
QWindowContext *glContext;
QWindowSurface *surface;
Qt::WindowState windowState;
+
+ QSize minimumSize;
+ QSize maximumSize;
+ QSize baseSize;
+ QSize sizeIncrement;
};
diff --git a/src/plugins/platforms/xcb/qxcbwindow.cpp b/src/plugins/platforms/xcb/qxcbwindow.cpp
index dd28d13eb5..709efb2bc6 100644
--- a/src/plugins/platforms/xcb/qxcbwindow.cpp
+++ b/src/plugins/platforms/xcb/qxcbwindow.cpp
@@ -52,6 +52,7 @@
#include <xcb/xcb_icccm.h>
#include <private/qguiapplication_p.h>
+#include <private/qwindow_p.h>
#include <private/qwindowsurface_p.h>
#include <QtGui/QWindowSystemInterface>
@@ -256,31 +257,49 @@ void QXcbWindow::setGeometry(const QRect &rect)
void QXcbWindow::setVisible(bool visible)
{
- xcb_wm_hints_t hints;
- if (visible) {
- // TODO: QWindow::isMinimized() or similar
+ if (visible)
+ show();
+ else
+ hide();
+}
+
+void QXcbWindow::show()
+{
+ if (window()->isTopLevel()) {
+ xcb_get_property_cookie_t cookie = xcb_get_wm_hints(xcb_connection(), m_window);
+
+ xcb_wm_hints_t hints;
+ xcb_get_wm_hints_reply(xcb_connection(), cookie, &hints, 0);
+
if (window()->windowState() & Qt::WindowMinimized)
xcb_wm_hints_set_iconic(&hints);
else
xcb_wm_hints_set_normal(&hints);
+
xcb_set_wm_hints(xcb_connection(), m_window, &hints);
- Q_XCB_CALL(xcb_map_window(xcb_connection(), m_window));
- connection()->sync();
- } else {
- Q_XCB_CALL(xcb_unmap_window(xcb_connection(), m_window));
-
- // send synthetic UnmapNotify event according to icccm 4.1.4
- xcb_unmap_notify_event_t event;
- event.response_type = XCB_UNMAP_NOTIFY;
- event.sequence = 0; // does this matter?
- event.event = m_screen->root();
- event.window = m_window;
- event.from_configure = false;
- Q_XCB_CALL(xcb_send_event(xcb_connection(), false, m_screen->root(),
- XCB_EVENT_MASK_SUBSTRUCTURE_NOTIFY | XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT, (const char *)&event));
- xcb_flush(xcb_connection());
+ propagateSizeHints();
}
+
+ Q_XCB_CALL(xcb_map_window(xcb_connection(), m_window));
+ connection()->sync();
+}
+
+void QXcbWindow::hide()
+{
+ Q_XCB_CALL(xcb_unmap_window(xcb_connection(), m_window));
+
+ // send synthetic UnmapNotify event according to icccm 4.1.4
+ xcb_unmap_notify_event_t event;
+ event.response_type = XCB_UNMAP_NOTIFY;
+ event.sequence = 0; // does this matter?
+ event.event = m_screen->root();
+ event.window = m_window;
+ event.from_configure = false;
+ Q_XCB_CALL(xcb_send_event(xcb_connection(), false, m_screen->root(),
+ XCB_EVENT_MASK_SUBSTRUCTURE_NOTIFY | XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT, (const char *)&event));
+
+ xcb_flush(xcb_connection());
}
struct QtMWMHints {
@@ -577,6 +596,36 @@ void QXcbWindow::lower()
Q_XCB_CALL(xcb_configure_window(xcb_connection(), m_window, mask, values));
}
+void QXcbWindow::propagateSizeHints()
+{
+ xcb_size_hints_t hints;
+
+ QRect rect = geometry();
+
+ xcb_size_hints_set_position(&hints, true, rect.x(), rect.y());
+ xcb_size_hints_set_size(&hints, true, rect.width(), rect.height());
+
+ QWindow *win = window();
+
+ QSize minimumSize = win->minimumSize();
+ QSize maximumSize = win->maximumSize();
+ QSize baseSize = win->baseSize();
+ QSize sizeIncrement = win->sizeIncrement();
+
+ if (minimumSize.width() > 0 || minimumSize.height() > 0)
+ xcb_size_hints_set_min_size(&hints, minimumSize.width(), minimumSize.height());
+
+ if (maximumSize.width() < QWINDOWSIZE_MAX || maximumSize.height() < QWINDOWSIZE_MAX)
+ xcb_size_hints_set_max_size(&hints, maximumSize.width(), maximumSize.height());
+
+ if (sizeIncrement.width() > 0 || sizeIncrement.height() > 0) {
+ xcb_size_hints_set_base_size(&hints, baseSize.width(), baseSize.height());
+ xcb_size_hints_set_resize_inc(&hints, sizeIncrement.width(), sizeIncrement.height());
+ }
+
+ xcb_set_wm_normal_hints(xcb_connection(), m_window, &hints);
+}
+
void QXcbWindow::requestActivateWindow()
{
Q_XCB_CALL(xcb_set_input_focus(xcb_connection(), XCB_INPUT_FOCUS_PARENT, m_window, XCB_TIME_CURRENT_TIME));
diff --git a/src/plugins/platforms/xcb/qxcbwindow.h b/src/plugins/platforms/xcb/qxcbwindow.h
index 831c25bdfb..accb32b36e 100644
--- a/src/plugins/platforms/xcb/qxcbwindow.h
+++ b/src/plugins/platforms/xcb/qxcbwindow.h
@@ -69,6 +69,7 @@ public:
void setWindowTitle(const QString &title);
void raise();
void lower();
+ void propagateSizeHints();
void requestActivateWindow();
@@ -96,6 +97,9 @@ private:
void setNetWmWindowTypes(Qt::WindowFlags flags);
void changeNetWmState(bool set, xcb_atom_t one, xcb_atom_t two = 0);
+ void show();
+ void hide();
+
QXcbScreen *m_screen;
xcb_window_t m_window;
diff --git a/src/widgets/kernel/qwidget_qpa.cpp b/src/widgets/kernel/qwidget_qpa.cpp
index b7b502a35f..533cc0a47c 100644
--- a/src/widgets/kernel/qwidget_qpa.cpp
+++ b/src/widgets/kernel/qwidget_qpa.cpp
@@ -49,6 +49,7 @@
#include "QtWidgets/qdesktopwidget.h"
#include "QtGui/qplatformwindow_qpa.h"
#include "QtGui/qplatformglcontext_qpa.h"
+#include "QtGui/private/qwindow_p.h"
#include <QtGui/QPlatformCursor>
@@ -628,6 +629,22 @@ void QWidgetPrivate::setGeometry_sys(int x, int y, int w, int h, bool isMove)
void QWidgetPrivate::setConstraints_sys()
{
+ Q_Q(QWidget);
+ if (extra && q->windowHandle()) {
+ QWindow *win = q->windowHandle();
+ QWindowPrivate *winp = qt_window_private(win);
+
+ winp->minimumSize = QSize(extra->minw, extra->minh);
+ winp->maximumSize = QSize(extra->maxw, extra->maxh);
+
+ if (extra->topextra) {
+ winp->baseSize = QSize(extra->topextra->basew, extra->topextra->baseh);
+ winp->sizeIncrement = QSize(extra->topextra->incw, extra->topextra->inch);
+ }
+
+ if (winp->platformWindow)
+ winp->platformWindow->propagateSizeHints();
+ }
}
void QWidgetPrivate::scroll_sys(int dx, int dy)