MSW: Fix dialog default positions under RTL locales

Toplevel windows use their parent's coordinate system as the reference
frame, not desktop's, so need to be adjusted accordingly if its
mirrored. Without these changes, default-positioned wxDialogs would end
to the right side of the parent window's right border (instead of being
slightly inside the window) and changing their size would move them as
well.
This commit is contained in:
Václav Slavík
2016-04-04 18:11:14 +02:00
parent 6243e0e507
commit a0805d32eb
2 changed files with 42 additions and 6 deletions

View File

@@ -1822,6 +1822,26 @@ wxWindowMSW::DoMoveSibling(WXHWND hwnd, int x, int y, int width, int height)
// otherwise (or if deferring failed) move the window in place immediately
#endif // wxUSE_DEFERRED_SIZING
// toplevel window's coordinates are mirrored if the TLW is a child of another
// RTL window and changing width without moving the position would enlarge the
// window in the wrong direction, so we need to adjust for it
if ( IsTopLevel() )
{
// note that this may be different from GetParent() for wxDialogs
HWND tlwParent = ::GetParent((HWND)hwnd);
if ( tlwParent && (::GetWindowLong(tlwParent, GWL_EXSTYLE) & WS_EX_LAYOUTRTL) != 0 )
{
RECT old;
::GetWindowRect((HWND) hwnd, &old);
if ( old.left == x && old.right - old.left != width )
{
x -= width - (old.right - old.left);
}
// else: not a simple resize
}
}
if ( !::MoveWindow((HWND)hwnd, x, y, width, height, IsShown()) )
{
wxLogLastError(wxT("MoveWindow"));
@@ -1967,10 +1987,25 @@ void wxWindowMSW::DoSetClientSize(int width, int height)
const int widthWin = rectWin.right - rectWin.left,
heightWin = rectWin.bottom - rectWin.top;
// MoveWindow positions the child windows relative to the parent, so
// adjust if necessary
if ( !IsTopLevel() )
if ( IsTopLevel() )
{
// toplevel window's coordinates are mirrored if the TLW is a child of another
// RTL window and changing width without moving the position would enlarge the
// window in the wrong direction, so we need to adjust for it
// note that this may be different from GetParent() for wxDialogs
HWND tlwParent = ::GetParent(GetHwnd());
if ( tlwParent && (::GetWindowLong(tlwParent, GWL_EXSTYLE) & WS_EX_LAYOUTRTL) != 0 )
{
const int diffWidth = width - (rectClient.right - rectClient.left);
rectWin.left -= diffWidth;
rectWin.right -= diffWidth;
}
}
else
{
// MoveWindow positions the child windows relative to the parent, so
// adjust if necessary
wxWindow *parent = GetParent();
if ( parent )
{