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:
Paul Cornett
2007-08-27 17:29:36 +00:00
parent eedb553a68
commit 37cafc6af8

View File

@@ -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,49 +445,21 @@ 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; switch (index)
if ((type == XA_CARDINAL) && (format == 32) && (nitems >= 4) && (data))
{ {
switch(index) case wxSYS_BORDER_X:
{ case wxSYS_EDGE_X:
case wxSYS_BORDER_X: case wxSYS_FRAMESIZE_X:
case wxSYS_EDGE_X: return right; // width of right extent
case wxSYS_FRAMESIZE_X: default:
border_return = int(data[1]); // width of right extent return bottom; // height of bottom extent
break;
default:
border_return = int(data[3]); // 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