summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorQt Continuous Integration System <qt-info@nokia.com>2011-04-08 00:36:29 (GMT)
committerQt Continuous Integration System <qt-info@nokia.com>2011-04-08 00:36:29 (GMT)
commit75fd46451cabd680d16913d5dfd4733c09db3459 (patch)
treeff705d7f0df9382750005a39d284ad3c0200df5b
parenta43c406311e4888b2a1d8a6bbf099041022c7e54 (diff)
parentbaaa5ae00038c34c8a7539229cda083a8afde280 (diff)
downloadQt-75fd46451cabd680d16913d5dfd4733c09db3459.zip
Qt-75fd46451cabd680d16913d5dfd4733c09db3459.tar.gz
Qt-75fd46451cabd680d16913d5dfd4733c09db3459.tar.bz2
Merge branch '4.7' of scm.dev.nokia.troll.no:qt/qt-water-staging into 4.7-integration
* '4.7' of scm.dev.nokia.troll.no:qt/qt-water-staging: Cocoa: p1 bug fix: fix auto test regressions Cocoa: p1 bug fix: revert use of subWindowStacking
-rw-r--r--src/corelib/global/qnamespace.h1
-rw-r--r--src/corelib/global/qnamespace.qdoc8
-rw-r--r--src/gui/kernel/qcocoasharedwindowmethods_mac_p.h14
-rw-r--r--src/gui/kernel/qwidget_mac.mm35
-rw-r--r--tests/auto/macnativeevents/tst_macnativeevents.cpp8
5 files changed, 41 insertions, 25 deletions
diff --git a/src/corelib/global/qnamespace.h b/src/corelib/global/qnamespace.h
index 864d4a5..4d70744 100644
--- a/src/corelib/global/qnamespace.h
+++ b/src/corelib/global/qnamespace.h
@@ -525,7 +525,6 @@ public:
#endif
WA_X11DoNotAcceptFocus = 132,
- WA_MacNoCocoaChildWindow = 133,
// Add new attributes before this line
WA_AttributeCount
diff --git a/src/corelib/global/qnamespace.qdoc b/src/corelib/global/qnamespace.qdoc
index c495d6f..22ad83b 100644
--- a/src/corelib/global/qnamespace.qdoc
+++ b/src/corelib/global/qnamespace.qdoc
@@ -925,14 +925,6 @@
the brushed metal style as supported by the windowing system. This
attribute is only applicable to Mac OS X.
- \value WA_MacNoCocoaChildWindow Indicates the widget should not be added
- as a Cocoa child window of it's parent window. This will free the window
- from being moved around together with the parent. However, this
- will also allow it to stack/hide behind it's parent (if they are on
- the same window level, e.g both windows are dialogs). This can cause problems if
- both windows are modal, as the child can then block input to the parent
- while hiding behind it. This attribute is only applicable to Mac OS X.
-
\omitvalue WA_MacMetalStyle
\value WA_Mapped Indicates that the widget is mapped on screen.
diff --git a/src/gui/kernel/qcocoasharedwindowmethods_mac_p.h b/src/gui/kernel/qcocoasharedwindowmethods_mac_p.h
index 6254061..406e6d4 100644
--- a/src/gui/kernel/qcocoasharedwindowmethods_mac_p.h
+++ b/src/gui/kernel/qcocoasharedwindowmethods_mac_p.h
@@ -157,6 +157,20 @@ QT_END_NAMESPACE
[NSApp terminate:sender];
}
+- (void)setLevel:(NSInteger)windowLevel
+{
+ // Cocoa will upon activating/deactivating applications level modal
+ // windows up and down, regardsless of any explicit set window level.
+ // To ensure that modal stays-on-top dialogs actually stays on top after
+ // the application is activated (and therefore stacks in front of
+ // other stays-on-top windows), we need to add this little special-case override:
+ QWidget *widget = [[QT_MANGLE_NAMESPACE(QCocoaWindowDelegate) sharedDelegate] qt_qwidgetForWindow:self];
+ if (widget && widget->isModal() && (widget->windowFlags() & Qt::WindowStaysOnTopHint))
+ [super setLevel:NSPopUpMenuWindowLevel];
+ else
+ [super setLevel:windowLevel];
+}
+
- (void)sendEvent:(NSEvent *)event
{
if ([event type] == NSApplicationDefined) {
diff --git a/src/gui/kernel/qwidget_mac.mm b/src/gui/kernel/qwidget_mac.mm
index 7105d23..aca1d53 100644
--- a/src/gui/kernel/qwidget_mac.mm
+++ b/src/gui/kernel/qwidget_mac.mm
@@ -2794,14 +2794,16 @@ void QWidgetPrivate::transferChildren()
#ifdef QT_MAC_USE_COCOA
void QWidgetPrivate::setSubWindowStacking(bool set)
{
+ // After hitting too many unforeseen bugs trying to put Qt on top of the cocoa child
+ // window API, we have decided to revert this behaviour as much as we can. We
+ // therefore now only allow child windows to exist for children of modal dialogs.
+ static bool use_behaviour_qt473 = !qgetenv("QT_MAC_USE_CHILDWINDOWS").isEmpty();
+
// This will set/remove a visual relationship between parent and child on screen.
// The reason for doing this is to ensure that a child always stacks infront of
- // its parent (expecially if both windows are modal, and the child blocks input to
- // the parent while at the same time hiding behind it). Unfortunatly is turns out
- // that [NSWindow addChildWindow] has
+ // its parent. Unfortunatly is turns out that [NSWindow addChildWindow] has
// several unwanted side-effects, one of them being the moving of a child when
- // moving the parent, which we choose to accept (if this is unacceptable, consider
- // using Qt::WA_MacNoCocoaChildWindow). A way tougher side-effect is
+ // moving the parent, which we choose to accept. A way tougher side-effect is
// that Cocoa will hide the parent if you hide the child. And in the case of
// a tool window, since it will normally hide when you deactivate the
// application, Cocoa will hide the parent upon deactivate as well. The result often
@@ -2824,14 +2826,15 @@ void QWidgetPrivate::setSubWindowStacking(bool set)
if (QWidget *parent = q->parentWidget()) {
if (NSWindow *pwin = [qt_mac_nativeview_for(parent) window]) {
if (set) {
- if (!q->testAttribute(Qt::WA_MacNoCocoaChildWindow)) {
- Qt::WindowType ptype = parent->window()->windowType();
- if ([pwin isVisible] && (ptype == Qt::Window || ptype == Qt::Dialog) && ![qwin parentWindow]) {
- NSInteger level = [qwin level];
- [pwin addChildWindow:qwin ordered:NSWindowAbove];
- if ([qwin level] < level)
- [qwin setLevel:level];
- }
+ Qt::WindowType ptype = parent->window()->windowType();
+ if ([pwin isVisible]
+ && (ptype == Qt::Window || ptype == Qt::Dialog)
+ && ![qwin parentWindow]
+ && (!use_behaviour_qt473 && parent->windowModality() == Qt::ApplicationModal)) {
+ NSInteger level = [qwin level];
+ [pwin addChildWindow:qwin ordered:NSWindowAbove];
+ if ([qwin level] < level)
+ [qwin setLevel:level];
}
} else {
[pwin removeChildWindow:qwin];
@@ -2839,14 +2842,16 @@ void QWidgetPrivate::setSubWindowStacking(bool set)
}
}
+ // Only set-up child windows for q if q is modal:
+ if (set && !use_behaviour_qt473 && q->windowModality() != Qt::ApplicationModal)
+ return;
+
QObjectList widgets = q->children();
for (int i=0; i<widgets.size(); ++i) {
QWidget *child = qobject_cast<QWidget *>(widgets.at(i));
if (child && child->isWindow()) {
if (NSWindow *cwin = [qt_mac_nativeview_for(child) window]) {
if (set) {
- if (child->testAttribute(Qt::WA_MacNoCocoaChildWindow))
- continue;
Qt::WindowType ctype = child->window()->windowType();
if ([cwin isVisible] && (ctype == Qt::Window || ctype == Qt::Dialog) && ![cwin parentWindow]) {
NSInteger level = [cwin level];
diff --git a/tests/auto/macnativeevents/tst_macnativeevents.cpp b/tests/auto/macnativeevents/tst_macnativeevents.cpp
index ac7298c..731fe0a 100644
--- a/tests/auto/macnativeevents/tst_macnativeevents.cpp
+++ b/tests/auto/macnativeevents/tst_macnativeevents.cpp
@@ -68,7 +68,7 @@ private slots:
void testMouseEnter();
void testChildDialogInFrontOfModalParent();
#ifdef QT_MAC_USE_COCOA
- void testChildWindowInFrontOfParentWindow();
+// void testChildWindowInFrontOfParentWindow();
// void testChildToolWindowInFrontOfChildNormalWindow();
void testChildWindowInFrontOfStaysOnTopParentWindow();
#endif
@@ -314,6 +314,11 @@ void tst_MacNativeEvents::testChildDialogInFrontOfModalParent()
}
#ifdef QT_MAC_USE_COCOA
+#if 0
+// This test is disabled as of Qt-4.7.4 because we cannot do it
+// unless we use the Cocoa sub window API. But using that opens up
+// a world of side effects that we cannot live with. So we rather
+// not support child-on-top-of-parent instead.
void tst_MacNativeEvents::testChildWindowInFrontOfParentWindow()
{
// Test that a child window always stacks in front of its parent window.
@@ -338,6 +343,7 @@ void tst_MacNativeEvents::testChildWindowInFrontOfParentWindow()
QTest::qWait(100);
QVERIFY(!child.isVisible());
}
+#endif
/* This test can be enabled once setStackingOrder has been fixed in qwidget_mac.mm
void tst_MacNativeEvents::testChildToolWindowInFrontOfChildNormalWindow()