fix getting frame extents on 64-bit platforms, cleanup XGetWindowProperty code
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@48416 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
@@ -364,36 +364,66 @@ wxFont wxSystemSettingsNative::GetFont( wxSystemFont index )
|
|||||||
return font;
|
return font;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool wxXGetWindowProperty(GdkWindow* window, Atom& type, int& format, gulong& nitems, guchar*& data)
|
static bool GetFrameExtents(GdkWindow* window, int* left, int* right, int* top, int* bottom)
|
||||||
{
|
{
|
||||||
bool success = false;
|
bool success = false;
|
||||||
|
Atom property = 0;
|
||||||
#if GTK_CHECK_VERSION(2, 2, 0)
|
#if GTK_CHECK_VERSION(2, 2, 0)
|
||||||
if (gtk_check_version(2, 2, 0) == NULL)
|
if (gtk_check_version(2, 2, 0) == NULL)
|
||||||
{
|
{
|
||||||
gulong bytes_after;
|
if (gdk_x11_screen_supports_net_wm_hint(
|
||||||
success = XGetWindowProperty(
|
gdk_drawable_get_screen(window),
|
||||||
GDK_DISPLAY_XDISPLAY(gdk_drawable_get_display(window)),
|
gdk_atom_intern("_NET_FRAME_EXTENTS", false)))
|
||||||
GDK_WINDOW_XWINDOW(window),
|
{
|
||||||
gdk_x11_get_xatom_by_name_for_display(
|
success = true;
|
||||||
|
property = gdk_x11_get_xatom_by_name_for_display(
|
||||||
gdk_drawable_get_display(window),
|
gdk_drawable_get_display(window),
|
||||||
"_NET_FRAME_EXTENTS"),
|
"_NET_FRAME_EXTENTS");
|
||||||
0, // left, right, top, bottom, CARDINAL[4]/32
|
|
||||||
G_MAXLONG, // size of long
|
|
||||||
false, // do not delete property
|
|
||||||
XA_CARDINAL, // 32 bit
|
|
||||||
&type, &format, &nitems, &bytes_after, &data
|
|
||||||
) == Success;
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
#endif
|
#endif
|
||||||
|
{
|
||||||
|
if (gdk_net_wm_supports(gdk_atom_intern("_NET_FRAME_EXTENTS", false)))
|
||||||
|
{
|
||||||
|
success = true;
|
||||||
|
property = gdk_x11_get_xatom_by_name("_NET_FRAME_EXTENTS");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (success)
|
||||||
|
{
|
||||||
|
Atom type;
|
||||||
|
int format;
|
||||||
|
gulong nitems, bytes_after;
|
||||||
|
long* data = NULL;
|
||||||
|
success = XGetWindowProperty(
|
||||||
|
gdk_x11_drawable_get_xdisplay(window),
|
||||||
|
gdk_x11_drawable_get_xid(window),
|
||||||
|
property,
|
||||||
|
0, 4,
|
||||||
|
false,
|
||||||
|
XA_CARDINAL,
|
||||||
|
&type, &format, &nitems, &bytes_after, (guchar**)&data
|
||||||
|
) == Success;
|
||||||
|
if (success)
|
||||||
|
{
|
||||||
|
success = data && nitems == 4;
|
||||||
|
if (success)
|
||||||
|
{
|
||||||
|
if (left) *left = int(data[0]);
|
||||||
|
if (right) *right = int(data[1]);
|
||||||
|
if (top) *top = int(data[2]);
|
||||||
|
if (bottom) *bottom = int(data[3]);
|
||||||
|
}
|
||||||
|
if (data)
|
||||||
|
XFree(data);
|
||||||
|
}
|
||||||
|
}
|
||||||
return success;
|
return success;
|
||||||
}
|
}
|
||||||
|
|
||||||
int wxSystemSettingsNative::GetMetric( wxSystemMetric index, wxWindow* win )
|
int wxSystemSettingsNative::GetMetric( wxSystemMetric index, wxWindow* win )
|
||||||
{
|
{
|
||||||
guchar *data = NULL;
|
|
||||||
Atom type;
|
|
||||||
int format;
|
|
||||||
gulong nitems;
|
|
||||||
GdkWindow *window = NULL;
|
GdkWindow *window = NULL;
|
||||||
if(win && GTK_WIDGET_REALIZED(win->GetHandle()))
|
if(win && GTK_WIDGET_REALIZED(win->GetHandle()))
|
||||||
window = win->GetHandle()->window;
|
window = win->GetHandle()->window;
|
||||||
@@ -415,50 +445,22 @@ int wxSystemSettingsNative::GetMetric( wxSystemMetric index, wxWindow* win )
|
|||||||
return -1; // not a tlw, not sure how to approach
|
return -1; // not a tlw, not sure how to approach
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Check if wm supports frame extents - we can't know
|
|
||||||
// the border widths if it does not.
|
|
||||||
#if GTK_CHECK_VERSION(2,2,0)
|
|
||||||
if (!gtk_check_version(2,2,0))
|
|
||||||
{
|
|
||||||
if (!gdk_x11_screen_supports_net_wm_hint(
|
|
||||||
gdk_drawable_get_screen(window),
|
|
||||||
gdk_atom_intern("_NET_FRAME_EXTENTS", false) ) )
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
#endif
|
|
||||||
{
|
|
||||||
if (!gdk_net_wm_supports(gdk_atom_intern("_NET_FRAME_EXTENTS", false)))
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get the frame extents from the windowmanager.
|
// Get the frame extents from the windowmanager.
|
||||||
// In most cases the top extent is the titlebar, so we use the bottom extent
|
// In most cases the top extent is the titlebar, so we use the bottom extent
|
||||||
// for the heights.
|
// for the heights.
|
||||||
if (wxXGetWindowProperty(window, type, format, nitems, data))
|
int right, bottom;
|
||||||
{
|
if (GetFrameExtents(window, NULL, &right, NULL, &bottom))
|
||||||
int border_return = -1;
|
|
||||||
|
|
||||||
if ((type == XA_CARDINAL) && (format == 32) && (nitems >= 4) && (data))
|
|
||||||
{
|
{
|
||||||
switch (index)
|
switch (index)
|
||||||
{
|
{
|
||||||
case wxSYS_BORDER_X:
|
case wxSYS_BORDER_X:
|
||||||
case wxSYS_EDGE_X:
|
case wxSYS_EDGE_X:
|
||||||
case wxSYS_FRAMESIZE_X:
|
case wxSYS_FRAMESIZE_X:
|
||||||
border_return = int(data[1]); // width of right extent
|
return right; // width of right extent
|
||||||
break;
|
|
||||||
default:
|
default:
|
||||||
border_return = int(data[3]); // height of bottom extent
|
return bottom; // height of bottom extent
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (data)
|
|
||||||
XFree(data);
|
|
||||||
|
|
||||||
return border_return;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -546,22 +548,6 @@ int wxSystemSettingsNative::GetMetric( wxSystemMetric index, wxWindow* win )
|
|||||||
// No realized window specified, and no implementation for that case yet.
|
// No realized window specified, and no implementation for that case yet.
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
// Check if wm supports frame extents - we can't know the caption height if it does not.
|
|
||||||
#if GTK_CHECK_VERSION(2,2,0)
|
|
||||||
if (!gtk_check_version(2,2,0))
|
|
||||||
{
|
|
||||||
if (!gdk_x11_screen_supports_net_wm_hint(
|
|
||||||
gdk_drawable_get_screen(window),
|
|
||||||
gdk_atom_intern("_NET_FRAME_EXTENTS", false) ) )
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
#endif
|
|
||||||
{
|
|
||||||
if (!gdk_net_wm_supports(gdk_atom_intern("_NET_FRAME_EXTENTS", false)))
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
wxASSERT_MSG( wxDynamicCast(win, wxTopLevelWindow),
|
wxASSERT_MSG( wxDynamicCast(win, wxTopLevelWindow),
|
||||||
wxT("Asking for caption height of a non toplevel window") );
|
wxT("Asking for caption height of a non toplevel window") );
|
||||||
|
|
||||||
@@ -570,19 +556,12 @@ int wxSystemSettingsNative::GetMetric( wxSystemMetric index, wxWindow* win )
|
|||||||
// we could check which is the thickest wm border to decide on which side the
|
// we could check which is the thickest wm border to decide on which side the
|
||||||
// titlebar is, but this might lead to interesting behaviours in used code.
|
// titlebar is, but this might lead to interesting behaviours in used code.
|
||||||
// Reconsider when we have a way to report to the user on which side it is.
|
// Reconsider when we have a way to report to the user on which side it is.
|
||||||
if (wxXGetWindowProperty(window, type, format, nitems, data))
|
|
||||||
{
|
{
|
||||||
int caption_height = -1;
|
int top;
|
||||||
|
if (GetFrameExtents(window, NULL, NULL, &top, NULL))
|
||||||
if ((type == XA_CARDINAL) && (format == 32) && (nitems >= 3) && (data))
|
|
||||||
{
|
{
|
||||||
caption_height = int(data[2]); // top frame extent
|
return top; // top frame extent
|
||||||
}
|
}
|
||||||
|
|
||||||
if (data)
|
|
||||||
XFree(data);
|
|
||||||
|
|
||||||
return caption_height;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Try a default approach without a window pointer, if possible
|
// Try a default approach without a window pointer, if possible
|
||||||
|
Reference in New Issue
Block a user