+ // 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);
+ }
+
+ // 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.
+