workaround for broken window managers which claim to support _NET_REQUEST_FRAME_EXTENTS, but don't respond to it

see #13146


git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@67496 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Paul Cornett
2011-04-15 18:31:57 +00:00
parent 35f8ae6572
commit f5c0761f51
2 changed files with 43 additions and 8 deletions

View File

@@ -117,6 +117,8 @@ public:
// private gtk_timeout_add result for mimicing wxUSER_ATTENTION_INFO and // private gtk_timeout_add result for mimicing wxUSER_ATTENTION_INFO and
// wxUSER_ATTENTION_ERROR difference, -2 for no hint, -1 for ERROR hint, rest for GtkTimeout handle. // wxUSER_ATTENTION_ERROR difference, -2 for no hint, -1 for ERROR hint, rest for GtkTimeout handle.
int m_urgency_hint; int m_urgency_hint;
// timer for detecting WM with broken _NET_REQUEST_FRAME_EXTENTS handling
unsigned m_netFrameExtentsTimerId;
// return the size of the window without WM decorations // return the size of the window without WM decorations
void GTKDoGetSize(int *width, int *height) const; void GTKDoGetSize(int *width, int *height) const;

View File

@@ -72,6 +72,10 @@ static wxTopLevelWindowGTK *g_lastActiveFrame = NULL;
// send any activate events at all // send any activate events at all
static int g_sendActivateEvent = -1; static int g_sendActivateEvent = -1;
// Whether _NET_REQUEST_FRAME_EXTENTS support is working
// 0 == not tested yet, 1 == working, 2 == broken
static int gs_requestFrameExtentsStatus;
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// RequestUserAttention related functions // RequestUserAttention related functions
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
@@ -441,6 +445,14 @@ static gboolean property_notify_event(
static GdkAtom property = gdk_atom_intern("_NET_FRAME_EXTENTS", false); static GdkAtom property = gdk_atom_intern("_NET_FRAME_EXTENTS", false);
if (event->state == GDK_PROPERTY_NEW_VALUE && event->atom == property) if (event->state == GDK_PROPERTY_NEW_VALUE && event->atom == property)
{ {
if (win->m_netFrameExtentsTimerId)
{
// WM support for _NET_REQUEST_FRAME_EXTENTS is working
gs_requestFrameExtentsStatus = 1;
g_source_remove(win->m_netFrameExtentsTimerId);
win->m_netFrameExtentsTimerId = 0;
}
wxSize decorSize = win->m_decorSize; wxSize decorSize = win->m_decorSize;
int left, right, top, bottom; int left, right, top, bottom;
if (wxGetFrameExtents(event->window, &left, &right, &top, &bottom)) if (wxGetFrameExtents(event->window, &left, &right, &top, &bottom))
@@ -452,6 +464,24 @@ static gboolean property_notify_event(
} }
} }
extern "C" {
static gboolean request_frame_extents_timeout(void* data)
{
// WM support for _NET_REQUEST_FRAME_EXTENTS is broken
gs_requestFrameExtentsStatus = 2;
gdk_threads_enter();
wxTopLevelWindowGTK* win = static_cast<wxTopLevelWindowGTK*>(data);
win->m_netFrameExtentsTimerId = 0;
wxSize decorSize = win->m_decorSize;
int left, right, top, bottom;
if (wxGetFrameExtents(gtk_widget_get_window(win->m_widget), &left, &right, &top, &bottom))
decorSize.Set(left + right, top + bottom);
win->GTKUpdateDecorSize(decorSize);
gdk_threads_leave();
return false;
}
}
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// wxTopLevelWindowGTK creation // wxTopLevelWindowGTK creation
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
@@ -468,6 +498,7 @@ void wxTopLevelWindowGTK::Init()
m_deferShow = true; m_deferShow = true;
m_deferShowAllowed = true; m_deferShowAllowed = true;
m_updateDecorSize = true; m_updateDecorSize = true;
m_netFrameExtentsTimerId = 0;
m_urgency_hint = -2; m_urgency_hint = -2;
} }
@@ -828,7 +859,8 @@ bool wxTopLevelWindowGTK::Show( bool show )
bool deferShow = show && !m_isShown && m_deferShow; bool deferShow = show && !m_isShown && m_deferShow;
if (deferShow) if (deferShow)
{ {
deferShow = m_deferShowAllowed && !gtk_widget_get_realized(m_widget); deferShow = gs_requestFrameExtentsStatus != 2 &&
m_deferShowAllowed && !gtk_widget_get_realized(m_widget);
if (deferShow) if (deferShow)
{ {
deferShow = g_signal_handler_find(m_widget, deferShow = g_signal_handler_find(m_widget,
@@ -848,13 +880,6 @@ bool wxTopLevelWindowGTK::Show( bool show )
// restore and save. // restore and save.
m_updateDecorSize = deferShow; m_updateDecorSize = deferShow;
} }
if (deferShow)
{
// Fluxbox support for _NET_REQUEST_FRAME_EXTENTS is broken
const char* name = gdk_x11_screen_get_window_manager_name(screen);
deferShow = strcmp(name, "Fluxbox") != 0;
m_updateDecorSize = deferShow;
}
m_deferShow = deferShow; m_deferShow = deferShow;
} }
@@ -901,6 +926,14 @@ bool wxTopLevelWindowGTK::Show( bool show )
SubstructureNotifyMask | SubstructureRedirectMask, SubstructureNotifyMask | SubstructureRedirectMask,
(XEvent*)&xevent); (XEvent*)&xevent);
if (gs_requestFrameExtentsStatus == 0)
{
// if WM does not respond to request within 1 second,
// we assume support for _NET_REQUEST_FRAME_EXTENTS is not working
m_netFrameExtentsTimerId =
g_timeout_add(1000, request_frame_extents_timeout, this);
}
// defer calling gtk_widget_show() // defer calling gtk_widget_show()
m_isShown = true; m_isShown = true;
return true; return true;