Fix ClientToScreen()/ScreenToClient() when used immediately after window creation.
And whenever window does not have an up-to-date GTK size allocation. Closes #16061 git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@78033 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
@@ -255,6 +255,8 @@ public:
|
|||||||
// (because they have been validated by a size-allocate) and should
|
// (because they have been validated by a size-allocate) and should
|
||||||
// be used to report client size
|
// be used to report client size
|
||||||
bool m_useCachedClientSize;
|
bool m_useCachedClientSize;
|
||||||
|
// Whether the GtkAllocation and GdkWindow positions are known to be correct
|
||||||
|
bool m_isGtkPositionValid;
|
||||||
|
|
||||||
// see the docs in src/gtk/window.cpp
|
// see the docs in src/gtk/window.cpp
|
||||||
GtkWidget *m_widget; // mostly the widget seen by the rest of GTK
|
GtkWidget *m_widget; // mostly the widget seen by the rest of GTK
|
||||||
|
@@ -2049,6 +2049,7 @@ size_allocate(GtkWidget*, GtkAllocation* alloc, wxWindow* win)
|
|||||||
win->m_y = a.y;
|
win->m_y = a.y;
|
||||||
}
|
}
|
||||||
win->m_useCachedClientSize = true;
|
win->m_useCachedClientSize = true;
|
||||||
|
win->m_isGtkPositionValid = true;
|
||||||
if (win->m_clientWidth != w || win->m_clientHeight != h)
|
if (win->m_clientWidth != w || win->m_clientHeight != h)
|
||||||
{
|
{
|
||||||
win->m_clientWidth = w;
|
win->m_clientWidth = w;
|
||||||
@@ -2210,6 +2211,8 @@ void wxWindowGTK::GTKHandleRealized()
|
|||||||
|
|
||||||
void wxWindowGTK::GTKHandleUnrealize()
|
void wxWindowGTK::GTKHandleUnrealize()
|
||||||
{
|
{
|
||||||
|
m_isGtkPositionValid = false;
|
||||||
|
|
||||||
// unrealizing a frozen window seems to have some lingering effect
|
// unrealizing a frozen window seems to have some lingering effect
|
||||||
// preventing updates to the affected area
|
// preventing updates to the affected area
|
||||||
if (IsFrozen())
|
if (IsFrozen())
|
||||||
@@ -2365,6 +2368,7 @@ void wxWindowGTK::Init()
|
|||||||
m_clientWidth =
|
m_clientWidth =
|
||||||
m_clientHeight = 0;
|
m_clientHeight = 0;
|
||||||
m_useCachedClientSize = false;
|
m_useCachedClientSize = false;
|
||||||
|
m_isGtkPositionValid = false;
|
||||||
|
|
||||||
m_clipPaintRegion = false;
|
m_clipPaintRegion = false;
|
||||||
|
|
||||||
@@ -2909,11 +2913,14 @@ void wxWindowGTK::DoSetSize( int x, int y, int width, int height, int sizeFlags
|
|||||||
height = m_height;
|
height = m_height;
|
||||||
|
|
||||||
const bool sizeChange = m_width != width || m_height != height;
|
const bool sizeChange = m_width != width || m_height != height;
|
||||||
|
const bool positionChange = m_x != x || m_y != y;
|
||||||
|
|
||||||
if (sizeChange)
|
if (sizeChange)
|
||||||
m_useCachedClientSize = false;
|
m_useCachedClientSize = false;
|
||||||
|
if (positionChange)
|
||||||
|
m_isGtkPositionValid = false;
|
||||||
|
|
||||||
if (sizeChange || m_x != x || m_y != y)
|
if (sizeChange || positionChange)
|
||||||
{
|
{
|
||||||
m_x = x;
|
m_x = x;
|
||||||
m_y = y;
|
m_y = y;
|
||||||
@@ -3136,7 +3143,37 @@ void wxWindowGTK::DoClientToScreen( int *x, int *y ) const
|
|||||||
{
|
{
|
||||||
wxCHECK_RET( (m_widget != NULL), wxT("invalid window") );
|
wxCHECK_RET( (m_widget != NULL), wxT("invalid window") );
|
||||||
|
|
||||||
if (gtk_widget_get_window(m_widget) == NULL) return;
|
if (!m_isGtkPositionValid && !IsTopLevel() && m_parent)
|
||||||
|
{
|
||||||
|
m_parent->DoClientToScreen(x, y);
|
||||||
|
int xx, yy;
|
||||||
|
DoGetPosition(&xx, &yy);
|
||||||
|
if (m_wxwindow)
|
||||||
|
{
|
||||||
|
GtkBorder border;
|
||||||
|
WX_PIZZA(m_wxwindow)->get_border(border);
|
||||||
|
xx += border.left;
|
||||||
|
yy += border.top;
|
||||||
|
}
|
||||||
|
if (y) *y += yy;
|
||||||
|
if (x)
|
||||||
|
{
|
||||||
|
if (GetLayoutDirection() != wxLayout_RightToLeft)
|
||||||
|
*x += xx;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
int w;
|
||||||
|
// undo RTL conversion done by parent
|
||||||
|
m_parent->DoGetClientSize(&w, NULL);
|
||||||
|
*x = w - *x;
|
||||||
|
|
||||||
|
DoGetClientSize(&w, NULL);
|
||||||
|
*x += xx;
|
||||||
|
*x = w - *x;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
GdkWindow *source = NULL;
|
GdkWindow *source = NULL;
|
||||||
if (m_wxwindow)
|
if (m_wxwindow)
|
||||||
@@ -3144,6 +3181,8 @@ void wxWindowGTK::DoClientToScreen( int *x, int *y ) const
|
|||||||
else
|
else
|
||||||
source = gtk_widget_get_window(m_widget);
|
source = gtk_widget_get_window(m_widget);
|
||||||
|
|
||||||
|
wxCHECK_RET(source, "ClientToScreen failed on unrealized window");
|
||||||
|
|
||||||
int org_x = 0;
|
int org_x = 0;
|
||||||
int org_y = 0;
|
int org_y = 0;
|
||||||
gdk_window_get_origin( source, &org_x, &org_y );
|
gdk_window_get_origin( source, &org_x, &org_y );
|
||||||
@@ -3175,7 +3214,37 @@ void wxWindowGTK::DoScreenToClient( int *x, int *y ) const
|
|||||||
{
|
{
|
||||||
wxCHECK_RET( (m_widget != NULL), wxT("invalid window") );
|
wxCHECK_RET( (m_widget != NULL), wxT("invalid window") );
|
||||||
|
|
||||||
if (!gtk_widget_get_realized(m_widget)) return;
|
if (!m_isGtkPositionValid && !IsTopLevel() && m_parent)
|
||||||
|
{
|
||||||
|
m_parent->DoScreenToClient(x, y);
|
||||||
|
int xx, yy;
|
||||||
|
DoGetPosition(&xx, &yy);
|
||||||
|
if (m_wxwindow)
|
||||||
|
{
|
||||||
|
GtkBorder border;
|
||||||
|
WX_PIZZA(m_wxwindow)->get_border(border);
|
||||||
|
xx += border.left;
|
||||||
|
yy += border.top;
|
||||||
|
}
|
||||||
|
if (y) *y -= yy;
|
||||||
|
if (x)
|
||||||
|
{
|
||||||
|
if (GetLayoutDirection() != wxLayout_RightToLeft)
|
||||||
|
*x -= xx;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
int w;
|
||||||
|
// undo RTL conversion done by parent
|
||||||
|
m_parent->DoGetClientSize(&w, NULL);
|
||||||
|
*x = w - *x;
|
||||||
|
|
||||||
|
DoGetClientSize(&w, NULL);
|
||||||
|
*x -= xx;
|
||||||
|
*x = w - *x;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
GdkWindow *source = NULL;
|
GdkWindow *source = NULL;
|
||||||
if (m_wxwindow)
|
if (m_wxwindow)
|
||||||
@@ -3183,6 +3252,8 @@ void wxWindowGTK::DoScreenToClient( int *x, int *y ) const
|
|||||||
else
|
else
|
||||||
source = gtk_widget_get_window(m_widget);
|
source = gtk_widget_get_window(m_widget);
|
||||||
|
|
||||||
|
wxCHECK_RET(source, "ScreenToClient failed on unrealized window");
|
||||||
|
|
||||||
int org_x = 0;
|
int org_x = 0;
|
||||||
int org_y = 0;
|
int org_y = 0;
|
||||||
gdk_window_get_origin( source, &org_x, &org_y );
|
gdk_window_get_origin( source, &org_x, &org_y );
|
||||||
|
Reference in New Issue
Block a user