+ 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
+ // notification is received, so correct frame extents are known.
+ // This allows resizing m_widget to keep the overall size in sync with
+ // what wxWidgets expects it to be without an obvious change in the
+ // window size immediately after it becomes visible.
+
+ // Realize m_widget, so m_widget->window can be used. Realizing causes
+ // the widget tree to be size_allocated, which generates size events in
+ // the wrong order. So temporarily remove child from m_widget while
+ // realizing.
+ GtkWidget* child = GTK_BIN(m_widget)->child;
+ if (child)
+ {
+ g_object_ref(child);
+ gtk_container_remove(GTK_CONTAINER(m_widget), child);
+ }
+ gtk_widget_realize(m_widget);
+ if (child)
+ {
+ gtk_container_add(GTK_CONTAINER(m_widget), child);
+ g_object_unref(child);
+ }
+
+ 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)