Only account for WM frame extents in tlw size if WM supports _NET_FRAME_EXTENTS. Extents cache no longer needed.

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@50467 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Paul Cornett
2007-12-04 17:26:57 +00:00
parent 9dcff96ba9
commit 53e3cd047c
5 changed files with 52 additions and 112 deletions

View File

@@ -202,25 +202,6 @@ gboolean gtk_frame_focus_out_callback(GtkWidget * WXUNUSED(widget),
}
}
//-----------------------------------------------------------------------------
// Get cached size of WM decorations for given GdkWMDecoration.
static wxSize& GetDecorSize(int decor)
{
// In testing, only the title bar and GDK_DECOR_BORDER made a difference.
// 4 possible combinations of title bar and border
static wxSize size[4];
int index = 0;
// title bar
if (decor & (GDK_DECOR_MENU | GDK_DECOR_MINIMIZE | GDK_DECOR_MAXIMIZE | GDK_DECOR_TITLE))
index = 1;
// border
if (decor & GDK_DECOR_BORDER)
index |= 2;
return size[index];
}
//-----------------------------------------------------------------------------
// "size_allocate" from m_wxwindow
//-----------------------------------------------------------------------------
@@ -237,8 +218,7 @@ size_allocate(GtkWidget*, GtkAllocation* alloc, wxTopLevelWindowGTK* win)
wxSize size(win->m_widget->allocation.width,
win->m_widget->allocation.height);
if (!win->IsFullScreen())
size += win->m_decorSize;
size += win->m_decorSize;
win->m_width = size.x;
win->m_height = size.y;
@@ -356,29 +336,10 @@ gtk_frame_realized_callback( GtkWidget * WXUNUSED(widget),
extern "C" {
static gboolean
gtk_frame_map_callback( GtkWidget* widget,
gtk_frame_map_callback( GtkWidget*,
GdkEvent * WXUNUSED(event),
wxTopLevelWindow *win )
{
// Calculate size of WM decorations.
// Done here in case WM does not support the _NET_FRAME_EXTENTS property.
if (win->IsDecorCacheable() && !win->IsFullScreen())
{
GdkRectangle rect;
gdk_window_get_frame_extents(widget->window, &rect);
int w, h;
gdk_drawable_get_size(widget->window, &w, &h);
const wxSize decorSize = wxSize(rect.width - w, rect.height - h);
if (win->m_decorSize != decorSize)
{
// Update window size and frame extents cache
win->m_width = rect.width;
win->m_height = rect.height;
win->m_decorSize = decorSize;
GetDecorSize(win->m_gdkDecor) = decorSize;
}
}
const bool wasIconized = win->IsIconized();
win->SetIconizeState(false);
@@ -424,8 +385,7 @@ static gboolean property_notify_event(
{
// Watch for changes to _NET_FRAME_EXTENTS property
static GdkAtom property = gdk_atom_intern("_NET_FRAME_EXTENTS", false);
if (event->state == GDK_PROPERTY_NEW_VALUE && event->atom == property &&
win->IsDecorCacheable() && !win->IsFullScreen())
if (event->state == GDK_PROPERTY_NEW_VALUE && event->atom == property)
{
Atom xproperty = gdk_x11_atom_to_xatom_for_display(
gdk_drawable_get_display(event->window), property);
@@ -447,8 +407,7 @@ static gboolean property_notify_event(
{
const wxSize diff = win->m_decorSize - decorSize;
win->m_decorSize = decorSize;
GetDecorSize(win->m_gdkDecor) = decorSize;
if (GTK_WIDGET_VISIBLE(win->m_widget))
if (!win->m_deferShow)
{
// adjust overall size to match change in frame extents
win->m_width -= diff.x;
@@ -467,9 +426,10 @@ static gboolean property_notify_event(
gtk_window_resize(GTK_WINDOW(win->m_widget), w, h);
}
}
if (!GTK_WIDGET_VISIBLE(win->m_widget))
if (win->m_deferShow)
{
// gtk_widget_show() was deferred, do it now
win->m_deferShow = false;
wxSizeEvent sizeEvent(win->GetSize(), win->GetId());
sizeEvent.SetEventObject(win);
win->HandleWindowEvent(sizeEvent);
@@ -503,6 +463,7 @@ void wxTopLevelWindowGTK::Init()
m_themeEnabled = true;
m_gdkDecor = m_gdkFunc = 0;
m_grabbed = false;
m_deferShow = true;
m_urgency_hint = -2;
}
@@ -697,12 +658,7 @@ bool wxTopLevelWindowGTK::Create( wxWindow *parent,
}
}
m_decorSize = GetDecorSize(m_gdkDecor);
// m_sizeDecor needs to be set before calling GTKDoGetSize
int w, h;
GTKDoGetSize(&w, &h);
gtk_window_set_default_size(GTK_WINDOW(m_widget), w, h);
gtk_window_set_default_size(GTK_WINDOW(m_widget), m_width, m_height);
return true;
}
@@ -839,7 +795,9 @@ bool wxTopLevelWindowGTK::Show( bool show )
{
wxASSERT_MSG( (m_widget != NULL), wxT("invalid frame") );
if (show && !GTK_WIDGET_REALIZED(m_widget))
const bool wasRealized = GTK_WIDGET_REALIZED(m_widget);
bool deferShow = show && m_deferShow && !wasRealized;
if (deferShow)
{
// Initial show. If WM supports _NET_REQUEST_FRAME_EXTENTS, defer
// calling gtk_widget_show() until _NET_FRAME_EXTENTS property
@@ -865,32 +823,34 @@ bool wxTopLevelWindowGTK::Show( bool show )
g_object_unref(child);
}
// if WM supports _NET_REQUEST_FRAME_EXTENTS
GdkAtom request_extents =
gdk_atom_intern("_NET_REQUEST_FRAME_EXTENTS", false);
GdkScreen* screen = gdk_drawable_get_screen(m_widget->window);
if (gdk_x11_screen_supports_net_wm_hint(screen, request_extents))
{
// send _NET_REQUEST_FRAME_EXTENTS
XClientMessageEvent xevent;
memset(&xevent, 0, sizeof(xevent));
xevent.type = ClientMessage;
xevent.window = gdk_x11_drawable_get_xid(m_widget->window);
xevent.message_type = gdk_x11_atom_to_xatom_for_display(
gdk_drawable_get_display(m_widget->window), request_extents);
xevent.format = 32;
Display* display = gdk_x11_drawable_get_xdisplay(m_widget->window);
XSendEvent(display, DefaultRootWindow(display), false,
SubstructureNotifyMask | SubstructureRedirectMask,
(XEvent*)&xevent);
m_deferShow =
deferShow = gdk_x11_screen_supports_net_wm_hint(
gdk_drawable_get_screen(m_widget->window),
gdk_atom_intern("_NET_REQUEST_FRAME_EXTENTS", false)) != 0;
}
if (deferShow)
{
// send _NET_REQUEST_FRAME_EXTENTS
XClientMessageEvent xevent;
memset(&xevent, 0, sizeof(xevent));
xevent.type = ClientMessage;
xevent.window = gdk_x11_drawable_get_xid(m_widget->window);
xevent.message_type = gdk_x11_atom_to_xatom_for_display(
gdk_drawable_get_display(m_widget->window),
gdk_atom_intern("_NET_REQUEST_FRAME_EXTENTS", false));
xevent.format = 32;
Display* display = gdk_x11_drawable_get_xdisplay(m_widget->window);
XSendEvent(display, DefaultRootWindow(display), false,
SubstructureNotifyMask | SubstructureRedirectMask,
(XEvent*)&xevent);
// defer calling gtk_widget_show()
m_isShown = true;
return true;
}
// WM does not support _NET_REQUEST_FRAME_EXTENTS, overall size may
// change when correct frame extents become known.
// defer calling gtk_widget_show()
m_isShown = true;
return true;
}
if (show && !wasRealized)
{
// size_allocate signals occur in reverse order (bottom to top).
// Things work better if the initial wxSizeEvents are sent (from the
// top down), before the initial size_allocate signals occur.
@@ -929,12 +889,9 @@ void wxTopLevelWindowGTK::DoMoveWindow(int WXUNUSED(x), int WXUNUSED(y), int WXU
void wxTopLevelWindowGTK::GTKDoGetSize(int *width, int *height) const
{
wxSize size(m_width, m_height);
if (!IsFullScreen())
{
size -= m_decorSize;
if (size.x < 0) size.x = 0;
if (size.y < 0) size.y = 0;
}
size -= m_decorSize;
if (size.x < 0) size.x = 0;
if (size.y < 0) size.y = 0;
if (width) *width = size.x;
if (height) *height = size.y;
}
@@ -1044,11 +1001,6 @@ void wxTopLevelWindowGTK::DoSetSizeHints( int minW, int minH,
(GtkWindow*)m_widget, NULL, &hints, (GdkWindowHints)hints_mask);
}
bool wxTopLevelWindowGTK::IsDecorCacheable() const
{
return true;
}
void wxTopLevelWindowGTK::OnInternalIdle()
{
// set the focus if not done yet and if we can already do it