+void wxTopLevelWindowBase::DoCentre(int dir)
+{
+ // on some platforms centering top level windows is impossible
+ // because they are always maximized by guidelines or limitations
+ if(IsAlwaysMaximized())
+ return;
+
+ // we need the display rect anyhow so store it first: notice that we should
+ // be centered on the same display as our parent window, the display of
+ // this window itself is not really defined yet
+ int nDisplay = wxDisplay::GetFromWindow(GetParent() ? GetParent() : this);
+ wxDisplay dpy(nDisplay == wxNOT_FOUND ? 0 : nDisplay);
+ const wxRect rectDisplay(dpy.GetClientArea());
+
+ // what should we centre this window on?
+ wxRect rectParent;
+ if ( !(dir & wxCENTRE_ON_SCREEN) && GetParent() )
+ {
+ // centre on parent window: notice that we need screen coordinates for
+ // positioning this TLW
+ rectParent = GetParent()->GetScreenRect();
+
+ // if the parent is entirely off screen (happens at least with MDI
+ // parent frame under Mac but could happen elsewhere too if the frame
+ // was hidden/moved away for some reason), don't use it as otherwise
+ // this window wouldn't be visible at all
+ if ( !rectDisplay.Contains(rectParent.GetTopLeft()) &&
+ !rectParent.Contains(rectParent.GetBottomRight()) )
+ {
+ // this is enough to make IsEmpty() test below pass
+ rectParent.width = 0;
+ }
+ }
+
+ if ( rectParent.IsEmpty() )
+ {
+ // we were explicitly asked to centre this window on the entire screen
+ // or if we have no parent anyhow and so can't centre on it
+ rectParent = rectDisplay;
+ }
+
+ // centering maximized window on screen is no-op
+ if((rectParent == rectDisplay) && IsMaximized())
+ return;
+
+ // the new window rect candidate
+ wxRect rect = GetRect().CentreIn(rectParent, dir);
+
+ // we don't want to place the window off screen if Centre() is called as
+ // this is (almost?) never wanted and it would be very difficult to prevent
+ // it from happening from the user code if we didn't check for it here
+ if ( !rectDisplay.Contains(rect.GetTopLeft()) )
+ {
+ // move the window just enough to make the corner visible
+ int dx = rectDisplay.GetLeft() - rect.GetLeft();
+ int dy = rectDisplay.GetTop() - rect.GetTop();
+ rect.Offset(dx > 0 ? dx : 0, dy > 0 ? dy : 0);
+ }
+
+ if ( !rectDisplay.Contains(rect.GetBottomRight()) )
+ {
+ // do the same for this corner too
+ int dx = rectDisplay.GetRight() - rect.GetRight();
+ int dy = rectDisplay.GetBottom() - rect.GetBottom();
+ rect.Offset(dx < 0 ? dx : 0, dy < 0 ? dy : 0);
+ }
+
+ // the window top left and bottom right corner are both visible now and
+ // although the window might still be not entirely on screen (with 2
+ // staggered displays for example) we wouldn't be able to improve the
+ // layout much in such case, so we stop here
+
+ // -1 could be valid coordinate here if there are several displays
+ SetSize(rect, wxSIZE_ALLOW_MINUS_ONE);
+}
+