}
}
-//-----------------------------------------------------------------------------
-
-// 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
//-----------------------------------------------------------------------------
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;
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);
{
// 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);
wxSize(int(data[0] + data[1]), int(data[2] + data[3]));
if (win->m_decorSize != decorSize)
{
- const wxSize diff = win->m_decorSize - decorSize;
+ const wxSize diff = decorSize - win->m_decorSize;
win->m_decorSize = decorSize;
- GetDecorSize(win->m_gdkDecor) = decorSize;
- if (GTK_WIDGET_VISIBLE(win->m_widget))
+ bool resized = false;
+ if (win->m_deferShow)
+ {
+ // keep overall size unchanged by shrinking m_widget,
+ // if min size will allow it
+ const wxSize minSize = win->GetMinSize();
+ int w, h;
+ win->GTKDoGetSize(&w, &h);
+ if (w >= minSize.x && h >= minSize.y)
+ {
+ gtk_window_resize(GTK_WINDOW(win->m_widget), w, h);
+ resized = true;
+ }
+ }
+ if (!resized)
{
// adjust overall size to match change in frame extents
- win->m_width -= diff.x;
- win->m_height -= diff.y;
+ win->m_width += diff.x;
+ win->m_height += diff.y;
if (win->m_width < 0) win->m_width = 0;
if (win->m_height < 0) win->m_height = 0;
- win->m_oldClientWidth = 0;
- gtk_widget_queue_resize(win->m_wxwindow);
- }
- else
- {
- // Window not yet visible, adjust client size. This would
- // cause an obvious size change if window was visible.
- int w, h;
- win->GTKDoGetSize(&w, &h);
- gtk_window_resize(GTK_WINDOW(win->m_widget), w, h);
+ if (!win->m_deferShow)
+ {
+ win->m_oldClientWidth = 0;
+ gtk_widget_queue_resize(win->m_wxwindow);
+ }
}
}
- if (!GTK_WIDGET_VISIBLE(win->m_widget))
+ if (win->m_deferShow)
{
// gtk_widget_show() was deferred, do it now
+ win->m_deferShow = false;
+ win->GetClientSize(
+ &win->m_oldClientWidth, &win->m_oldClientHeight);
wxSizeEvent sizeEvent(win->GetSize(), win->GetId());
sizeEvent.SetEventObject(win);
win->HandleWindowEvent(sizeEvent);
+
gtk_widget_show(win->m_widget);
+
wxShowEvent showEvent(win->GetId(), true);
showEvent.SetEventObject(win);
win->HandleWindowEvent(showEvent);
m_themeEnabled = true;
m_gdkDecor = m_gdkFunc = 0;
m_grabbed = false;
+ m_deferShow = true;
m_urgency_hint = -2;
}
}
}
- 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;
}
{
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
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);
-
- // 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.
+ 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;
+ }
+ 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.
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;
}
(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