diff --git a/docs/changes.txt b/docs/changes.txt index a0d08e31ac..556d005d63 100644 --- a/docs/changes.txt +++ b/docs/changes.txt @@ -93,7 +93,7 @@ Major new features in 2.8 release All: -- Fixed bug with default proxy destruction in wxURL (Axel Gembe) +- Fixed bug with default proxy destruction in wxURL (Axel Gembe). All (GUI): @@ -113,6 +113,7 @@ wxGTK: - wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW) now returns the background colour of text controls. - wxFrame::ShowFullScreen now preserves the menubar's accelerators. +- Implemented wxGetClientDisplayRect() correctly for wxGTK and X11-based ports. wxMac: diff --git a/src/gtk/utilsgtk.cpp b/src/gtk/utilsgtk.cpp index bb1c1b4195..efc330f45c 100644 --- a/src/gtk/utilsgtk.cpp +++ b/src/gtk/utilsgtk.cpp @@ -149,17 +149,6 @@ void wxDisplaySizeMM( int *width, int *height ) if (height) *height = gdk_screen_height_mm(); } -void wxClientDisplayRect(int *x, int *y, int *width, int *height) -{ - // This is supposed to return desktop dimensions minus any window - // manager panels, menus, taskbars, etc. If there is a way to do that - // for this platform please fix this function, otherwise it defaults - // to the entire desktop. - if (x) *x = 0; - if (y) *y = 0; - wxDisplaySize(width, height); -} - void wxGetMousePosition( int* x, int* y ) { gdk_window_get_pointer( (GdkWindow*) NULL, x, y, (GdkModifierType*) NULL ); diff --git a/src/gtk1/utilsgtk.cpp b/src/gtk1/utilsgtk.cpp index 3439ce69e6..de3153f76b 100644 --- a/src/gtk1/utilsgtk.cpp +++ b/src/gtk1/utilsgtk.cpp @@ -103,17 +103,6 @@ void wxDisplaySizeMM( int *width, int *height ) if (height) *height = gdk_screen_height_mm(); } -void wxClientDisplayRect(int *x, int *y, int *width, int *height) -{ - // This is supposed to return desktop dimensions minus any window - // manager panels, menus, taskbars, etc. If there is a way to do that - // for this platform please fix this function, otherwise it defaults - // to the entire desktop. - if (x) *x = 0; - if (y) *y = 0; - wxDisplaySize(width, height); -} - void wxGetMousePosition( int* x, int* y ) { gdk_window_get_pointer( (GdkWindow*) NULL, x, y, (GdkModifierType*) NULL ); diff --git a/src/motif/utils.cpp b/src/motif/utils.cpp index c3b452d42b..a8257298f6 100644 --- a/src/motif/utils.cpp +++ b/src/motif/utils.cpp @@ -557,18 +557,6 @@ void wxDisplaySizeMM(int *width, int *height) *height = DisplayHeightMM(dpy, DefaultScreen (dpy)); } -void wxClientDisplayRect(int *x, int *y, int *width, int *height) -{ - // This is supposed to return desktop dimensions minus any window - // manager panels, menus, taskbars, etc. If there is a way to do that - // for this platform please fix this function, otherwise it defaults - // to the entire desktop. - if (x) *x = 0; - if (y) *y = 0; - wxDisplaySize(width, height); -} - - // Configurable display in wxX11 and wxMotif static WXDisplay *gs_currentDisplay = NULL; static wxString gs_displayName; diff --git a/src/unix/displayx11.cpp b/src/unix/displayx11.cpp index f08b0bdcae..cce24221cc 100644 --- a/src/unix/displayx11.cpp +++ b/src/unix/displayx11.cpp @@ -92,6 +92,14 @@ public: } virtual wxRect GetGeometry() const { return m_rect; } + virtual wxRect GetClientArea() const + { + // we intentionally don't cache the result here because the client + // display area may change (e.g. the user resized or hid a panel) and + // we don't currently react to its changes + return IsPrimary() ? wxGetClientDisplayRect() : m_rect; + } + virtual wxString GetName() const { return wxString(); } virtual wxArrayVideoModes GetModes(const wxVideoMode& mode) const; @@ -315,3 +323,102 @@ bool wxDisplayImplX11::ChangeMode(const wxVideoMode& WXUNUSED(mode)) } #endif /* wxUSE_DISPLAY */ + +#if defined(__WXGTK__) || defined(__X__) + +#include "wx/utils.h" + +#include + +// TODO: make this a full-fledged class and move to a public header +class wxX11Ptr +{ +public: + wxX11Ptr(void *ptr = NULL) : m_ptr(ptr) { } + ~wxX11Ptr() { if ( m_ptr ) XFree(m_ptr); } + +private: + void *m_ptr; + + DECLARE_NO_COPY_CLASS(wxX11Ptr) +}; + +// NB: this function is implemented using X11 and not GDK calls as it's shared +// by wxGTK[12], wxX11 and wxMotif ports +void wxClientDisplayRect(int *x, int *y, int *width, int *height) +{ + Display * const dpy = (Display *)wxGetDisplay(); + wxCHECK_RET( dpy, _T("can't be called before initializing the GUI") ); + + const Atom atomWorkArea = XInternAtom(dpy, "_NET_WORKAREA", True); + if ( atomWorkArea ) + { + long *workareas = NULL; + unsigned long numItems; + unsigned long bytesRemaining; + Atom actualType; + int format; + + if ( XGetWindowProperty + ( + dpy, + XDefaultRootWindow(dpy), + atomWorkArea, + 0, // offset of data to retrieve + 4, // number of items to retrieve + False, // don't delete property + XA_CARDINAL, // type of the items to get + &actualType, + &format, + &numItems, + &bytesRemaining, + (unsigned char **)&workareas + ) == Success && workareas ) + { + wxX11Ptr x11ptr(workareas); // ensure it will be freed + + // check that we retrieved the property of the expected type and + // that we did get back 4 longs (32 is the format for long), as + // requested + if ( actualType != XA_CARDINAL || + format != 32 || + numItems != 4 ) + { + wxLogDebug(_T("XGetWindowProperty(\"_NET_WORKAREA\") failed")); + return; + } + + if ( x ) + *x = workareas[0]; + if ( y ) + *y = workareas[1]; + if ( width ) + *width = workareas[2]; + if ( height ) + *height = workareas[3]; + + return; + } + } + + // if we get here, _NET_WORKAREA is not supported so return the entire + // screen size as fall back + if (x) + *x = 0; + if (y) + *y = 0; + wxDisplaySize(width, height); +} + +#else // !(wxGTK or X) + +void wxClientDisplayRect(int *x, int *y, int *width, int *height) +{ + if (x) + *x = 0; + if (y) + *y = 0; + wxDisplaySize(width, height); +} + +#endif // wxGTK or X diff --git a/src/x11/utils.cpp b/src/x11/utils.cpp index 80e3fcacda..1b643c492f 100644 --- a/src/x11/utils.cpp +++ b/src/x11/utils.cpp @@ -229,17 +229,6 @@ void wxDisplaySizeMM(int *width, int *height) *height = DisplayHeightMM(dpy, DefaultScreen (dpy)); } -void wxClientDisplayRect(int *x, int *y, int *width, int *height) -{ - // This is supposed to return desktop dimensions minus any window - // manager panels, menus, taskbars, etc. If there is a way to do that - // for this platform please fix this function, otherwise it defaults - // to the entire desktop. - if (x) *x = 0; - if (y) *y = 0; - wxDisplaySize(width, height); -} - wxWindow* wxFindWindowAtPoint(const wxPoint& pt) { return wxGenericFindWindowAtPoint(pt);