From f56a905ced02b387f6ac7f482f997629f27bcf89 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Fri, 10 Jun 2011 10:40:52 +0200 Subject: Compile Windows. --- src/gui/kernel/qeventdispatcher_qpa.cpp | 2 +- src/gui/kernel/qeventdispatcher_qpa_p.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/gui/kernel/qeventdispatcher_qpa.cpp b/src/gui/kernel/qeventdispatcher_qpa.cpp index 1a67fee4cd..e850dda97b 100644 --- a/src/gui/kernel/qeventdispatcher_qpa.cpp +++ b/src/gui/kernel/qeventdispatcher_qpa.cpp @@ -71,7 +71,7 @@ QEventDispatcherQPA::QEventDispatcherQPA(QObject *parent) : EVENTDISPATCHERBASE(*new QEventDispatcherQPAPrivate, parent) { } -QEventDispatcherQPA::QEventDispatcherQPA(QEventDispatcherUNIXPrivate &priv, QObject *parent) +QEventDispatcherQPA::QEventDispatcherQPA(EVENTDISPATCHERBASEPRIVATE &priv, QObject *parent) : EVENTDISPATCHERBASE(priv, parent) { } diff --git a/src/gui/kernel/qeventdispatcher_qpa_p.h b/src/gui/kernel/qeventdispatcher_qpa_p.h index f1eab6d927..fde3e47262 100644 --- a/src/gui/kernel/qeventdispatcher_qpa_p.h +++ b/src/gui/kernel/qeventdispatcher_qpa_p.h @@ -75,7 +75,7 @@ class QEventDispatcherQPA : public EVENTDISPATCHERBASE public: explicit QEventDispatcherQPA(QObject *parent = 0); - QEventDispatcherQPA(QEventDispatcherUNIXPrivate &priv, QObject *parent); + QEventDispatcherQPA(EVENTDISPATCHERBASEPRIVATE &priv, QObject *parent); ~QEventDispatcherQPA(); bool processEvents(QEventLoop::ProcessEventsFlags flags); -- cgit v1.2.3 From 6b0cd62e5ecad075c4528d3a09ec903ab057680e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Samuel=20R=C3=B8dal?= Date: Fri, 10 Jun 2011 12:40:29 +0200 Subject: Added frameMargins() API and support in XCB plugin. --- src/gui/kernel/qplatformwindow_qpa.cpp | 5 ++ src/gui/kernel/qplatformwindow_qpa.h | 3 ++ src/gui/kernel/qwindow.cpp | 8 +++ src/gui/kernel/qwindow.h | 3 ++ src/plugins/platforms/xcb/qxcbwindow.cpp | 92 ++++++++++++++++++++++++++++++++ src/plugins/platforms/xcb/qxcbwindow.h | 5 ++ src/widgets/kernel/qwidget_qpa.cpp | 47 ++++++++++------ src/widgets/kernel/qwidgetwindow_qpa.cpp | 15 +++++- src/widgets/kernel/qwidgetwindow_qpa_p.h | 2 + 9 files changed, 163 insertions(+), 17 deletions(-) diff --git a/src/gui/kernel/qplatformwindow_qpa.cpp b/src/gui/kernel/qplatformwindow_qpa.cpp index cba5529df4..feffd0cfed 100644 --- a/src/gui/kernel/qplatformwindow_qpa.cpp +++ b/src/gui/kernel/qplatformwindow_qpa.cpp @@ -108,6 +108,11 @@ QRect QPlatformWindow::geometry() const return d->rect; } +QMargins QPlatformWindow::frameMargins() const +{ + return QMargins(); +} + /*! Reimplemented in subclasses to show the surface if \a visible is \c true, and hide it if \a visible is \c false. diff --git a/src/gui/kernel/qplatformwindow_qpa.h b/src/gui/kernel/qplatformwindow_qpa.h index 72f63ebcef..8166344246 100644 --- a/src/gui/kernel/qplatformwindow_qpa.h +++ b/src/gui/kernel/qplatformwindow_qpa.h @@ -44,6 +44,7 @@ #include #include +#include #include #include @@ -71,6 +72,8 @@ public: virtual void setGeometry(const QRect &rect); virtual QRect geometry() const; + virtual QMargins frameMargins() const; + virtual void setVisible(bool visible); virtual Qt::WindowFlags setWindowFlags(Qt::WindowFlags flags); virtual Qt::WindowState setWindowState(Qt::WindowState state); diff --git a/src/gui/kernel/qwindow.cpp b/src/gui/kernel/qwindow.cpp index 97e74c5652..9ba8af2d2d 100644 --- a/src/gui/kernel/qwindow.cpp +++ b/src/gui/kernel/qwindow.cpp @@ -396,6 +396,14 @@ QRect QWindow::geometry() const return d->geometry; } +QMargins QWindow::frameMargins() const +{ + Q_D(const QWindow); + if (d->platformWindow) + return d->platformWindow->frameMargins(); + return QMargins(); +} + void QWindow::setWindowIcon(const QImage &icon) const { Q_UNUSED(icon); diff --git a/src/gui/kernel/qwindow.h b/src/gui/kernel/qwindow.h index 4356153683..7910c3884c 100644 --- a/src/gui/kernel/qwindow.h +++ b/src/gui/kernel/qwindow.h @@ -44,6 +44,7 @@ #include #include +#include #include #include @@ -138,6 +139,8 @@ public: void setGeometry(const QRect &rect); QRect geometry() const; + QMargins frameMargins() const; + void setWindowIcon(const QImage &icon) const; void destroy(); diff --git a/src/plugins/platforms/xcb/qxcbwindow.cpp b/src/plugins/platforms/xcb/qxcbwindow.cpp index 86a8c75878..d635ee8bcb 100644 --- a/src/plugins/platforms/xcb/qxcbwindow.cpp +++ b/src/plugins/platforms/xcb/qxcbwindow.cpp @@ -113,6 +113,7 @@ void QXcbWindow::create() m_windowState = Qt::WindowNoState; m_hasReceivedSyncRequest = false; + m_dirtyFrameMargins = true; Qt::WindowType type = window()->windowType(); @@ -304,6 +305,93 @@ void QXcbWindow::setGeometry(const QRect &rect) Q_XCB_CALL(xcb_configure_window(xcb_connection(), m_window, mask, values)); } +QMargins QXcbWindow::frameMargins() const +{ + if (m_dirtyFrameMargins) { + xcb_window_t window = m_window; + xcb_window_t parent = m_window; + + bool foundRoot = false; + + const QVector &virtualRoots = + connection()->wmSupport()->virtualRoots(); + + while (!foundRoot) { + xcb_query_tree_cookie_t cookie = xcb_query_tree(xcb_connection(), parent); + + xcb_generic_error_t *error; + xcb_query_tree_reply_t *reply = xcb_query_tree_reply(xcb_connection(), cookie, &error); + if (reply) { + if (reply->root == reply->parent || virtualRoots.indexOf(reply->parent) != -1) { + foundRoot = true; + } else { + window = parent; + parent = reply->parent; + } + + free(reply); + } else { + if (error) { + connection()->handleXcbError(error); + free(error); + } + + m_dirtyFrameMargins = false; + m_frameMargins = QMargins(); + return m_frameMargins; + } + } + + QPoint offset; + + xcb_generic_error_t *error; + xcb_translate_coordinates_reply_t *reply = + xcb_translate_coordinates_reply( + xcb_connection(), + xcb_translate_coordinates(xcb_connection(), window, parent, 0, 0), + &error); + + if (reply) { + offset = QPoint(reply->dst_x, reply->dst_y); + free(reply); + } else if (error) { + free(error); + } + + xcb_get_geometry_reply_t *geom = + xcb_get_geometry_reply( + xcb_connection(), + xcb_get_geometry(xcb_connection(), parent), + &error); + + if (geom) { + // -- + // add the border_width for the window managers frame... some window managers + // do not use a border_width of zero for their frames, and if we the left and + // top strut, we ensure that pos() is absolutely correct. frameGeometry() + // will still be incorrect though... perhaps i should have foffset as well, to + // indicate the frame offset (equal to the border_width on X). + // - Brad + // -- copied from qwidget_x11.cpp + + int left = offset.x() + geom->border_width; + int top = offset.y() + geom->border_width; + int right = geom->width + geom->border_width - geometry().width() - offset.x(); + int bottom = geom->height + geom->border_width - geometry().height() - offset.y(); + + m_frameMargins = QMargins(left, top, right, bottom); + + free(geom); + } else if (error) { + free(error); + } + + m_dirtyFrameMargins = false; + } + + return m_frameMargins; +} + void QXcbWindow::setVisible(bool visible) { if (visible) @@ -327,6 +415,8 @@ void QXcbWindow::show() free(error); } + m_dirtyFrameMargins = true; + if (window()->windowState() & Qt::WindowMinimized) xcb_wm_hints_set_iconic(&hints); else @@ -635,6 +725,8 @@ Qt::WindowState QXcbWindow::setWindowState(Qt::WindowState state) if (state == m_windowState) return state; + m_dirtyFrameMargins = true; + // unset old state switch (m_windowState) { case Qt::WindowMinimized: diff --git a/src/plugins/platforms/xcb/qxcbwindow.h b/src/plugins/platforms/xcb/qxcbwindow.h index f50a611b4e..501e9a33c4 100644 --- a/src/plugins/platforms/xcb/qxcbwindow.h +++ b/src/plugins/platforms/xcb/qxcbwindow.h @@ -61,6 +61,8 @@ public: void setGeometry(const QRect &rect); + QMargins frameMargins() const; + void setVisible(bool visible); Qt::WindowFlags setWindowFlags(Qt::WindowFlags flags); Qt::WindowState setWindowState(Qt::WindowState state); @@ -139,6 +141,9 @@ private: bool m_mapped; xcb_window_t m_netWmUserTimeWindow; + + mutable bool m_dirtyFrameMargins; + mutable QMargins m_frameMargins; }; #endif diff --git a/src/widgets/kernel/qwidget_qpa.cpp b/src/widgets/kernel/qwidget_qpa.cpp index 3363ad7454..caaa065b64 100644 --- a/src/widgets/kernel/qwidget_qpa.cpp +++ b/src/widgets/kernel/qwidget_qpa.cpp @@ -641,24 +641,41 @@ void QWidgetPrivate::setGeometry_sys(int x, int y, int w, int h, bool isMove) QPoint oldPos = q->pos(); data.crect = r; + bool needsShow = false; + + if (w == 0 || h == 0) { + q->setAttribute(Qt::WA_OutsideWSRange, true); + if (q->isVisible() && q->testAttribute(Qt::WA_Mapped)) + hide_sys(); + data.crect = QRect(x, y, w, h); + } else if (q->isVisible() && q->testAttribute(Qt::WA_OutsideWSRange)) { + q->setAttribute(Qt::WA_OutsideWSRange, false); + needsShow = true; + } + if (q->isVisible()) { - if (q->windowHandle()) { - if (q->isWindow()) { - q->windowHandle()->setGeometry(q->geometry()); + if (!q->testAttribute(Qt::WA_DontShowOnScreen) && !q->testAttribute(Qt::WA_OutsideWSRange)) { + if (q->windowHandle()) { + if (q->isWindow()) { + q->windowHandle()->setGeometry(q->geometry()); + } else { + QPoint posInNativeParent = q->mapTo(q->nativeParentWidget(),QPoint()); + q->windowHandle()->setGeometry(QRect(posInNativeParent,r.size())); + } + const QWidgetBackingStore *bs = maybeBackingStore(); + if (bs->windowSurface) { + if (isResize) + bs->windowSurface->resize(r.size()); + } + + if (needsShow) + show_sys(); } else { - QPoint posInNativeParent = q->mapTo(q->nativeParentWidget(),QPoint()); - q->windowHandle()->setGeometry(QRect(posInNativeParent,r.size())); + if (isMove && !isResize) + moveRect(QRect(oldPos, olds), x - oldPos.x(), y - oldPos.y()); + else + invalidateBuffer_resizeHelper(oldPos, olds); } - const QWidgetBackingStore *bs = maybeBackingStore(); - if (bs->windowSurface) { - if (isResize) - bs->windowSurface->resize(r.size()); - } - } else { - if (isMove && !isResize) - moveRect(QRect(oldPos, olds), x - oldPos.x(), y - oldPos.y()); - else - invalidateBuffer_resizeHelper(oldPos, olds); } if (isMove) { diff --git a/src/widgets/kernel/qwidgetwindow_qpa.cpp b/src/widgets/kernel/qwidgetwindow_qpa.cpp index 786293a716..27f9c9e2f8 100644 --- a/src/widgets/kernel/qwidgetwindow_qpa.cpp +++ b/src/widgets/kernel/qwidgetwindow_qpa.cpp @@ -266,9 +266,20 @@ void QWidgetWindow::handleKeyEvent(QKeyEvent *event) QGuiApplication::sendSpontaneousEvent(widget, event); } +void QWidgetWindow::updateGeometry() +{ + if (m_widget->testAttribute(Qt::WA_OutsideWSRange)) + return; + + QMargins margins = frameMargins(); + + m_widget->data->crect = geometry().translated(-margins.left(), -margins.top()); + m_widget->d_func()->topData()->frameStrut.setCoords(margins.left(), margins.top(), margins.right(), margins.bottom()); +} + void QWidgetWindow::handleMoveEvent(QMoveEvent *event) { - m_widget->data->crect = geometry(); + updateGeometry(); QGuiApplication::sendSpontaneousEvent(m_widget, event); } @@ -276,7 +287,7 @@ void QWidgetWindow::handleResizeEvent(QResizeEvent *event) { QSize oldSize = m_widget->data->crect.size(); - m_widget->data->crect = geometry(); + updateGeometry(); QGuiApplication::sendSpontaneousEvent(m_widget, event); if (m_widget->d_func()->paintOnScreen()) { diff --git a/src/widgets/kernel/qwidgetwindow_qpa_p.h b/src/widgets/kernel/qwidgetwindow_qpa_p.h index a217a969ca..f200839b0b 100644 --- a/src/widgets/kernel/qwidgetwindow_qpa_p.h +++ b/src/widgets/kernel/qwidgetwindow_qpa_p.h @@ -78,6 +78,8 @@ protected: void handleExposeEvent(QExposeEvent *); private: + void updateGeometry(); + QWidget *m_widget; QWeakPointer m_implicit_mouse_grabber; QWeakPointer m_dragTarget; -- cgit v1.2.3