diff options
author | David Robillard <d@drobilla.net> | 2013-05-26 23:16:40 +0000 |
---|---|---|
committer | David Robillard <d@drobilla.net> | 2013-05-26 23:16:40 +0000 |
commit | 8b2a971c42e5588555488c56966adf1687e38140 (patch) | |
tree | afa43f3bdc4027b0b48aa2bba9ca32596086754c /src | |
parent | 2ba8fe75d93a8a1591c53336933bf7f4285e31bc (diff) | |
download | suil-8b2a971c42e5588555488c56966adf1687e38140.tar.gz suil-8b2a971c42e5588555488c56966adf1687e38140.tar.bz2 suil-8b2a971c42e5588555488c56966adf1687e38140.zip |
Support resizing for X11 in Gtk (patch from Robin Gareus, #906).
git-svn-id: http://svn.drobilla.net/lad/trunk/suil@5112 a436a847-0d15-0410-975c-d299462d15a1
Diffstat (limited to 'src')
-rw-r--r-- | src/x11_in_gtk2.c | 58 |
1 files changed, 58 insertions, 0 deletions
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; } |