summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorJørgen Lind <jorgen.lind@nokia.com>2011-06-10 13:35:10 +0200
committerJørgen Lind <jorgen.lind@nokia.com>2011-06-10 13:35:10 +0200
commit11dc006328140e2dc91280ad350087b5cf970edb (patch)
tree59f2687a16b10f92263805abc045dee3b19070c3 /src
parent85a992a3f802cf2ac39fad905c74b85af2c7c48a (diff)
parent6b0cd62e5ecad075c4528d3a09ec903ab057680e (diff)
Merge branch 'refactor' of scm.dev.nokia.troll.no:qt/qtbase-staging into refactor
Diffstat (limited to 'src')
-rw-r--r--src/gui/kernel/qeventdispatcher_qpa.cpp2
-rw-r--r--src/gui/kernel/qeventdispatcher_qpa_p.h2
-rw-r--r--src/gui/kernel/qplatformwindow_qpa.cpp5
-rw-r--r--src/gui/kernel/qplatformwindow_qpa.h3
-rw-r--r--src/gui/kernel/qwindow.cpp8
-rw-r--r--src/gui/kernel/qwindow.h3
-rw-r--r--src/plugins/platforms/xcb/qxcbwindow.cpp92
-rw-r--r--src/plugins/platforms/xcb/qxcbwindow.h5
-rw-r--r--src/widgets/kernel/qwidget_qpa.cpp47
-rw-r--r--src/widgets/kernel/qwidgetwindow_qpa.cpp15
-rw-r--r--src/widgets/kernel/qwidgetwindow_qpa_p.h2
11 files changed, 165 insertions, 19 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);
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 <QtCore/qscopedpointer.h>
#include <QtCore/qrect.h>
+#include <QtCore/qmargins.h>
#include <QtCore/qstring.h>
#include <QtGui/qwindowdefs.h>
@@ -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 <QtCore/QObject>
#include <QtCore/QEvent>
+#include <QtCore/QMargins>
#include <QtGui/qguiglformat_qpa.h>
#include <QtGui/qwindowdefs.h>
@@ -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<xcb_window_t> &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<QWidget> m_implicit_mouse_grabber;
QWeakPointer<QWidget> m_dragTarget;