Implement QWindow minimum/maximum/base size hints and size increments.
This commit is contained in:
parent
276d60a4d6
commit
25f70314e0
@ -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());
|
||||
|
||||
|
@ -160,6 +160,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
|
||||
*/
|
||||
|
@ -80,6 +80,8 @@ public:
|
||||
virtual void raise();
|
||||
virtual void lower();
|
||||
|
||||
virtual void propagateSizeHints();
|
||||
|
||||
virtual void setOpacity(qreal level);
|
||||
virtual void requestActivateWindow();
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
};
|
||||
|
||||
|
||||
|
@ -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));
|
||||
|
@ -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;
|
||||
|
@ -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)
|
||||
|
Loading…
Reference in New Issue
Block a user