diff options
-rw-r--r-- | AUTHORS | 2 | ||||
-rw-r--r-- | NEWS | 1 | ||||
-rw-r--r-- | src/x11_in_gtk2.c | 58 | ||||
-rw-r--r-- | wscript | 2 |
4 files changed, 62 insertions, 1 deletions
@@ -8,3 +8,5 @@ Contributors: * Fix crash when a broken UI returns a NULL descriptor * Filipe Lopes <falktx@gmail.com> * Idle interface fixes for X11 in Qt4 + * Robin Gareus <robin@gareus.org> + * Support for resizing X11 UIs in Gtk @@ -3,6 +3,7 @@ suil (0.6.13) unstable; * Print system error message if module fails to load * Lower dependency from Gtk 2.24 introduced in 0.6.12 * Add support for new LV2 idle interface + * Support resizing for X11 in Gtk (patch from Robin Gareus) -- David Robillard <d@drobilla.net> Sun, 24 Feb 2013 12:02:41 -0500 diff --git a/src/x11_in_gtk2.c b/src/x11_in_gtk2.c index 57a9194..3fd23cf 100644 --- a/src/x11_in_gtk2.c +++ b/src/x11_in_gtk2.c @@ -52,6 +52,33 @@ GType suil_x11_wrapper_get_type(void); // Accessor for SUIL_TYPE_X11_WRAPPER G_DEFINE_TYPE(SuilX11Wrapper, suil_x11_wrapper, GTK_TYPE_SOCKET) +/** + Check if 'swallowed' subwindow is known to the X server. + + Gdk/GTK can mark the window as realized, mapped and visible even though there + is no window-ID on the X server for it, yet. -> suil_x11_on_size_allocate() + will make the application crash with "BadWinow" +*/ +static bool +x_window_is_valid(SuilX11Wrapper* socket) +{ + GdkWindow* window = gtk_widget_get_window(GTK_WIDGET(socket->plug)); + Window root = 0; + Window parent = 0; + Window* children = NULL; + unsigned childcount = 0; + + XQueryTree(GDK_WINDOW_XDISPLAY(window), + GDK_WINDOW_XID(window), + &root, &parent, &children, &childcount); + for (unsigned i = 0; i < childcount; ++i) { + if (children[i] == (Window)socket->instance->ui_widget) { + return true; + } + } + return false; +} + static gboolean on_plug_removed(GtkSocket* sock, gpointer data) { @@ -136,6 +163,18 @@ forward_key_event(SuilX11Wrapper* socket, (XEvent*)&xev); } +static void +forward_size_request(SuilX11Wrapper* socket, + GtkAllocation* allocation) +{ + GdkWindow* window = gtk_widget_get_window(GTK_WIDGET(socket->plug)); + if (x_window_is_valid(socket)) { + XResizeWindow(GDK_WINDOW_XDISPLAY(window), + (Window) socket->instance->ui_widget, + allocation->width, allocation->height); + } +} + static gboolean suil_x11_wrapper_key_event(GtkWidget* widget, GdkEventKey* event) @@ -151,6 +190,20 @@ suil_x11_wrapper_key_event(GtkWidget* widget, } static void +suil_x11_on_size_allocate(GtkWidget* widget, + GtkAllocation* a) +{ + SuilX11Wrapper* const self = SUIL_X11_WRAPPER(widget); + + if (self->plug + && GTK_WIDGET_REALIZED(widget) + && GTK_WIDGET_MAPPED(widget) + && GTK_WIDGET_VISIBLE(widget)) { + forward_size_request(self, a); + } +} + +static void suil_x11_wrapper_class_init(SuilX11WrapperClass* klass) { GObjectClass* const gobject_class = G_OBJECT_CLASS(klass); @@ -218,6 +271,11 @@ wrapper_wrap(SuilWrapper* wrapper, G_CALLBACK(on_plug_removed), NULL); + g_signal_connect(G_OBJECT(wrap), + "size-allocate", + G_CALLBACK(suil_x11_on_size_allocate), + NULL); + return 0; } @@ -9,7 +9,7 @@ import waflib.extras.autowaf as autowaf # major increment <=> incompatible changes # minor increment <=> compatible changes (additions) # micro increment <=> no interface changes -SUIL_VERSION = '0.6.12' +SUIL_VERSION = '0.6.13' SUIL_MAJOR_VERSION = '0' # Mandatory waf variables |