summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--AUTHORS2
-rw-r--r--NEWS1
-rw-r--r--src/x11_in_gtk2.c58
-rw-r--r--wscript2
4 files changed, 62 insertions, 1 deletions
diff --git a/AUTHORS b/AUTHORS
index 9a2e16d..9a3a56b 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -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
diff --git a/NEWS b/NEWS
index 2e84526..3f3908c 100644
--- a/NEWS
+++ b/NEWS
@@ -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;
}
diff --git a/wscript b/wscript
index a24805e..6a05a15 100644
--- a/wscript
+++ b/wscript
@@ -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