summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--NEWS3
-rw-r--r--src/gtk2_in_qt4.cpp51
2 files changed, 48 insertions, 6 deletions
diff --git a/NEWS b/NEWS
index ce6f207..16c6e5f 100644
--- a/NEWS
+++ b/NEWS
@@ -1,12 +1,13 @@
suil (0.6.5) unstable;
+ * Fix embedding Gtk in Qt as a child widget (support reparenting)
* Support for wrapping native Windows UIs in Gtk2
* Gracefully handle UIs with no port_event method
* Replace host provided features that match Suil implemented features, rather
than passing UIs duplicate features
* Disable timestamps in HTML documentation for reproducible build
- -- David Robillard <d@drobilla.net> Sun, 09 Sep 2012 03:19:01 -0400
+ -- David Robillard <d@drobilla.net> Sun, Tue, 13 Nov 2012 22:02:19 -0500
suil (0.6.4) stable;
diff --git a/src/gtk2_in_qt4.cpp b/src/gtk2_in_qt4.cpp
index a9298bf..e23e988 100644
--- a/src/gtk2_in_qt4.cpp
+++ b/src/gtk2_in_qt4.cpp
@@ -25,6 +25,14 @@
extern "C" {
+typedef struct _SuilGtk2InQt4Wrapper SuilGtk2InQt4Wrapper;
+
+struct _SuilGtk2InQt4Wrapper {
+ QX11EmbedContainer* host_widget;
+ QWidget* parent;
+ GtkWidget* plug;
+};
+
static void
on_size_request(GtkWidget* widget,
GtkRequisition* requisition,
@@ -43,13 +51,31 @@ on_size_allocate(GtkWidget* widget,
wrap->resize(allocation->width, allocation->height);
}
+static void
+wrapper_free(SuilWrapper* wrapper)
+{
+ SuilGtk2InQt4Wrapper* impl = (SuilGtk2InQt4Wrapper*)wrapper->impl;
+
+ if (impl->plug) {
+ gtk_widget_destroy(impl->plug);
+ }
+
+ if (impl->host_widget) {
+ delete impl->host_widget;
+ }
+
+ free(impl);
+}
+
static int
wrapper_wrap(SuilWrapper* wrapper,
SuilInstance* instance)
{
- QX11EmbedContainer* const wrap = new QX11EmbedContainer();
- GtkWidget* const plug = gtk_plug_new(wrap->winId());
- GtkWidget* const widget = (GtkWidget*)instance->ui_widget;
+ SuilGtk2InQt4Wrapper* const impl = (SuilGtk2InQt4Wrapper*)wrapper->impl;
+ QWidget* root = static_cast<QWidget*>(impl->parent);
+ QX11EmbedContainer* const wrap = new QX11EmbedContainer(root);
+ GtkWidget* const plug = gtk_plug_new(wrap->winId());
+ GtkWidget* const widget = (GtkWidget*)instance->ui_widget;
gtk_container_add(GTK_CONTAINER(plug), widget);
gtk_widget_show_all(plug);
@@ -68,6 +94,8 @@ wrapper_wrap(SuilWrapper* wrapper,
g_signal_connect(
G_OBJECT(plug), "size-allocate", G_CALLBACK(on_size_allocate), wrap);
+ impl->host_widget = wrap;
+ impl->plug = plug;
instance->host_widget = wrap;
return 0;
@@ -97,10 +125,23 @@ suil_wrapper_new(SuilHost* host,
gtk_init(NULL, NULL);
}
+ /* Set parent widget if given. */
+ for (unsigned i = 0; i < n_features; ++i) {
+ if (!strcmp((*features)[i]->URI, LV2_UI__parent)) {
+ impl->parent = static_cast<QWidget*>((*features)[i]->data);
+ }
+ }
+
+ /* Create wrapper implementation. */
+ SuilGtk2InQt4Wrapper* const impl = (SuilGtk2InQt4Wrapper*)
+ malloc(sizeof(SuilGtk2InQt4Wrapper));
+ impl->host_widget = NULL;
+ impl->plug = NULL;
+
SuilWrapper* wrapper = (SuilWrapper*)malloc(sizeof(SuilWrapper));
wrapper->wrap = wrapper_wrap;
- wrapper->free = NULL;
- wrapper->impl = NULL;
+ wrapper->free = wrapper_free;
+ wrapper->impl = impl;
return wrapper;
}