diff options
author | Richard Moe Gustavsen <richard.gustavsen@nokia.com> | 2011-04-04 08:29:40 (GMT) |
---|---|---|
committer | Richard Moe Gustavsen <richard.gustavsen@nokia.com> | 2011-04-04 08:29:40 (GMT) |
commit | 3c2373d7ea9bc91bb537c0725984d19ad0fbab01 (patch) | |
tree | ceb8c101baa7fac93c316069454b9542582746b4 | |
parent | 73b32e942696156c7c9fe84682394ec26f16c5c6 (diff) | |
download | Qt-3c2373d7ea9bc91bb537c0725984d19ad0fbab01.zip Qt-3c2373d7ea9bc91bb537c0725984d19ad0fbab01.tar.gz Qt-3c2373d7ea9bc91bb537c0725984d19ad0fbab01.tar.bz2 |
Cocoa: p1 bugfix, add widget flag MacNoCocoaChildWindow
This problem has been known for a long time, but a good solution has
never been found. The problem is that a child window should always
stay on top of it's parent, if not for anything else than secure that
a modal child does not block input while hiding behind the parent at
the same time. The only sensible solution found to ensure this in the
Cocoa port is to use Cocoa child windows. But this API has a sad side
effect; it will move the child along with the parent when the parent
is moved on screen. This is something it seems we have to live with.
But for those users that wants to handle this issue otherwise, we now
add a widget flag to switch this off.
Task-number: QTBUG-11481
Reviewed-by: msorvig
-rw-r--r-- | src/corelib/global/qnamespace.h | 1 | ||||
-rw-r--r-- | src/corelib/global/qnamespace.qdoc | 8 | ||||
-rw-r--r-- | src/gui/kernel/qwidget_mac.mm | 23 |
3 files changed, 24 insertions, 8 deletions
diff --git a/src/corelib/global/qnamespace.h b/src/corelib/global/qnamespace.h index 4d70744..864d4a5 100644 --- a/src/corelib/global/qnamespace.h +++ b/src/corelib/global/qnamespace.h @@ -525,6 +525,7 @@ 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 a79411b..224d9b6 100644 --- a/src/corelib/global/qnamespace.qdoc +++ b/src/corelib/global/qnamespace.qdoc @@ -981,6 +981,14 @@ 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/qwidget_mac.mm b/src/gui/kernel/qwidget_mac.mm index 7e5173f..7105d23 100644 --- a/src/gui/kernel/qwidget_mac.mm +++ b/src/gui/kernel/qwidget_mac.mm @@ -2796,9 +2796,12 @@ void QWidgetPrivate::setSubWindowStacking(bool set) { // 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. Unfortunatly is turns out that [NSWindow addChildWindow] has + // 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 // several unwanted side-effects, one of them being the moving of a child when - // moving the parent, which we choose to accept. A way tougher side-effect is + // moving the parent, which we choose to accept (if this is unacceptable, consider + // using Qt::WA_MacNoCocoaChildWindow). 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 @@ -2821,12 +2824,14 @@ void QWidgetPrivate::setSubWindowStacking(bool set) if (QWidget *parent = q->parentWidget()) { if (NSWindow *pwin = [qt_mac_nativeview_for(parent) window]) { if (set) { - 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]; + 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]; + } } } else { [pwin removeChildWindow:qwin]; @@ -2840,6 +2845,8 @@ void QWidgetPrivate::setSubWindowStacking(bool set) 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]; |