summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorrncbc <rncbc@rncbc.org>2018-07-07 19:46:42 +0100
committerDavid Robillard <d@drobilla.net>2018-07-09 21:17:40 +0200
commit570e04f26fffc6430ff6894da6a6e2f39b24efb7 (patch)
treef12f16ca23e2cf524bbb616075f98ccc7f4eecda
parentba5d56d27534c6996bc26eb5972d3562ad660545 (diff)
downloadsuil-570e04f26fffc6430ff6894da6a6e2f39b24efb7.tar.gz
suil-570e04f26fffc6430ff6894da6a6e2f39b24efb7.tar.bz2
suil-570e04f26fffc6430ff6894da6a6e2f39b24efb7.zip
Fix Qt5 in Gtk2 wrapper
- Fixes initial size and resizing in some cases - Adds LV2_UI__resize and LV2_UI__idleInterface features - Adds LV2_UI__updateRate option
-rw-r--r--NEWS1
-rw-r--r--src/qt5_in_gtk2.cpp109
2 files changed, 95 insertions, 15 deletions
diff --git a/NEWS b/NEWS
index 1e34284..710772f 100644
--- a/NEWS
+++ b/NEWS
@@ -1,6 +1,7 @@
suil (0.10.1) unstable;
* Add support for Cocoa in Qt5
+ * Fix resizing and add idle and update rate support for Qt5 in Gtk2
-- David Robillard <d@drobilla.net> Tue, 03 Oct 2017 22:11:49 +0200
diff --git a/src/qt5_in_gtk2.cpp b/src/qt5_in_gtk2.cpp
index 500fdf4..a03e8a7 100644
--- a/src/qt5_in_gtk2.cpp
+++ b/src/qt5_in_gtk2.cpp
@@ -1,5 +1,6 @@
/*
Copyright 2011-2017 David Robillard <http://drobilla.net>
+ Copyright 2018 Rui Nuno Capela <rncbc@rncbc.org>
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
@@ -21,6 +22,9 @@
#include <QWidget>
#include <QWindow>
+#include "lv2/lv2plug.in/ns/ext/options/options.h"
+#include "lv2/lv2plug.in/ns/ext/urid/urid.h"
+
#include "./suil_internal.h"
extern "C" {
@@ -31,17 +35,18 @@ extern "C" {
typedef struct _SuilQtWrapper SuilQtWrapper;
typedef struct _SuilQtWrapperClass SuilQtWrapperClass;
-struct _SuilQtWrapper
-{
- GtkSocket socket;
- QApplication* app;
- QWidget* qembed;
- SuilWrapper* wrapper;
- SuilInstance* instance;
+struct _SuilQtWrapper {
+ GtkSocket socket;
+ QApplication* app;
+ QWidget* qembed;
+ SuilWrapper* wrapper;
+ SuilInstance* instance;
+ const LV2UI_Idle_Interface* idle_iface;
+ guint idle_id;
+ guint idle_ms;
};
-struct _SuilQtWrapperClass
-{
+struct _SuilQtWrapperClass {
GtkSocketClass parent_class;
};
@@ -54,6 +59,11 @@ suil_qt_wrapper_finalize(GObject* gobject)
{
SuilQtWrapper* const self = SUIL_QT_WRAPPER(gobject);
+ if (self->idle_id) {
+ g_source_remove(self->idle_id);
+ self->idle_id = 0;
+ }
+
if (self->instance->handle) {
self->instance->descriptor->cleanup(self->instance->handle);
self->instance->handle = NULL;
@@ -63,6 +73,7 @@ suil_qt_wrapper_finalize(GObject* gobject)
self->qembed = NULL;
self->app = NULL;
+ self->idle_iface = NULL;
self->wrapper->impl = NULL;
G_OBJECT_CLASS(suil_qt_wrapper_parent_class)->finalize(gobject);
@@ -79,9 +90,13 @@ suil_qt_wrapper_class_init(SuilQtWrapperClass* klass)
static void
suil_qt_wrapper_init(SuilQtWrapper* self)
{
- self->app = NULL;
- self->qembed = NULL;
- self->instance = NULL;
+ self->app = NULL;
+ self->qembed = NULL;
+ self->wrapper = NULL;
+ self->instance = NULL;
+ self->idle_iface = NULL;
+ self->idle_id = 0;
+ self->idle_ms = 1000 / 30; // 30 Hz default
}
static void
@@ -97,7 +112,29 @@ suil_qt_wrapper_realize(GtkWidget* w, gpointer data)
}
static int
-wrapper_wrap(SuilWrapper* wrapper, SuilInstance* instance)
+suil_qt_wrapper_resize(LV2UI_Feature_Handle handle, int width, int height)
+{
+ gtk_widget_set_size_request(GTK_WIDGET(handle), width, height);
+
+ return 0;
+}
+
+static gboolean
+suil_qt_wrapper_idle(void* data)
+{
+ SuilQtWrapper* const wrap = SUIL_QT_WRAPPER(data);
+
+ if (wrap->idle_iface) {
+ wrap->idle_iface->idle(wrap->instance->handle);
+ return TRUE; // Continue calling
+ }
+
+ return FALSE;
+}
+
+static int
+wrapper_wrap(SuilWrapper* wrapper,
+ SuilInstance* instance)
{
SuilQtWrapper* const wrap = SUIL_QT_WRAPPER(wrapper->impl);
@@ -106,16 +143,30 @@ wrapper_wrap(SuilWrapper* wrapper, SuilInstance* instance)
wrap->instance = instance;
QWidget* qwidget = (QWidget*)instance->ui_widget;
- QVBoxLayout* layout = new QVBoxLayout(wrap->qembed);
+ QVBoxLayout* layout = new QVBoxLayout();
+ layout->setMargin(0);
+ layout->setSpacing(0);
layout->addWidget(qwidget);
- qwidget->setParent(wrap->qembed);
+ wrap->qembed->setLayout(layout);
g_signal_connect_after(G_OBJECT(wrap), "realize",
G_CALLBACK(suil_qt_wrapper_realize), NULL);
instance->host_widget = GTK_WIDGET(wrap);
+ const LV2UI_Idle_Interface* idle_iface = NULL;
+ if (instance->descriptor->extension_data) {
+ idle_iface = (const LV2UI_Idle_Interface*)
+ instance->descriptor->extension_data(LV2_UI__idleInterface);
+ }
+
+ if (idle_iface) {
+ wrap->idle_iface = idle_iface;
+ wrap->idle_id = g_timeout_add(
+ wrap->idle_ms, suil_qt_wrapper_idle, wrap);
+ }
+
return 0;
}
@@ -152,6 +203,34 @@ suil_wrapper_new(SuilHost* host,
wrap->wrapper = NULL;
wrapper->impl = wrap;
+ wrapper->resize.handle = wrap;
+ wrapper->resize.ui_resize = suil_qt_wrapper_resize;
+
+ suil_add_feature(features, &n_features, LV2_UI__resize, &wrapper->resize);
+ suil_add_feature(features, &n_features, LV2_UI__idleInterface, NULL);
+
+ // Scan for URID map and options
+ LV2_URID_Map* map = NULL;
+ LV2_Options_Option* options = NULL;
+ for (LV2_Feature** f = *features; *f && (!map || !options); ++f) {
+ if (!strcmp((*f)->URI, LV2_OPTIONS__options)) {
+ options = (LV2_Options_Option*)(*f)->data;
+ } else if (!strcmp((*f)->URI, LV2_URID__map)) {
+ map = (LV2_URID_Map*)(*f)->data;
+ }
+ }
+
+ if (map && options) {
+ // Set UI update rate if given
+ LV2_URID ui_updateRate = map->map(map->handle, LV2_UI__updateRate);
+ for (LV2_Options_Option* o = options; o->key; ++o) {
+ if (o->key == ui_updateRate) {
+ wrap->idle_ms = 1000.0f / *(const float*)o->value;
+ break;
+ }
+ }
+ }
+
return wrapper;
}