VST UI sizeing rework
* prefer signal over timer-poll for VST size changes * properly offset VST window (Windows) * constrain window size (Windows) * explicitly notify re-parent'ed child window (Linux)
This commit is contained in:
parent
4b982ef895
commit
819d9fa3cd
@ -33,6 +33,7 @@
|
||||
#include <glibmm/timer.h>
|
||||
|
||||
#include "ardour/linux_vst_support.h"
|
||||
#include "ardour/vst_plugin.h"
|
||||
|
||||
#include <X11/X.h>
|
||||
#include <X11/Xlib.h>
|
||||
@ -189,31 +190,37 @@ dispatch_x_events (XEvent* event, VSTState* vstfx)
|
||||
int width = event->xconfigure.width;
|
||||
int height = event->xconfigure.height;
|
||||
|
||||
/*If we get a config notify on the parent window XID then we need to see
|
||||
if the size has been changed - some plugins re-size their UI window e.g.
|
||||
when opening a preset manager (you might think that should be spawned as a new window...) */
|
||||
|
||||
/*if the size has changed, we flag this so that in lxvst_pluginui.cc we can make the
|
||||
change to the GTK parent window in ardour, from its UI thread*/
|
||||
/* If we get a config notify on the parent window XID then we need to see
|
||||
* if the size has been changed - some plugins re-size their UI window e.g.
|
||||
* when opening a preset manager.
|
||||
*
|
||||
* if the size has changed, we flag this so that in lxvst_pluginui.cc
|
||||
* we can make the change to the GTK parent window in ardour, from its UI thread */
|
||||
|
||||
if (window == (Window) (vstfx->linux_window)) {
|
||||
if (width != vstfx->width || height!=vstfx->height) {
|
||||
#ifndef NDEBUG
|
||||
printf("dispatch_x_events: ConfigureNotify cfg:(%d %d) plugin:(%d %d)\n",
|
||||
width, height,
|
||||
vstfx->width, vstfx->height
|
||||
);
|
||||
#endif
|
||||
if (width != vstfx->width || height != vstfx->height) {
|
||||
vstfx->width = width;
|
||||
vstfx->height = height;
|
||||
vstfx->want_resize = 1;
|
||||
ARDOUR::VSTPlugin* plug = (ARDOUR::VSTPlugin *)(vstfx->plugin->user);
|
||||
plug->VSTSizeWindow (); /* EMIT SIGNAL */
|
||||
}
|
||||
|
||||
/*QUIRK : Loomer plugins not only resize the UI but throw it into some random
|
||||
position at the same time. We need to re-position the window at the origin of
|
||||
the parent window*/
|
||||
/* QUIRK : Loomer plugins not only resize the UI but throw it into some random
|
||||
* position at the same time. We need to re-position the window at the origin of
|
||||
* the parent window*/
|
||||
|
||||
if (vstfx->linux_plugin_ui_window) {
|
||||
XMoveWindow (LXVST_XDisplay, vstfx->linux_plugin_ui_window, 0, 0);
|
||||
}
|
||||
if (vstfx->linux_plugin_ui_window) {
|
||||
XMoveWindow (LXVST_XDisplay, vstfx->linux_plugin_ui_window, 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
/*Reparent Notify - when the plugin UI is reparented into
|
||||
|
@ -17,10 +17,10 @@
|
||||
|
||||
*/
|
||||
|
||||
#include "gtkmm2ext/gui_thread.h"
|
||||
#include "ardour/lxvst_plugin.h"
|
||||
#include "ardour/linux_vst_support.h"
|
||||
#include "lxvst_plugin_ui.h"
|
||||
#include "timers.h"
|
||||
#include <gdk/gdkx.h>
|
||||
|
||||
#define LXVST_H_FIDDLE 40
|
||||
@ -38,53 +38,31 @@ LXVSTPluginUI::LXVSTPluginUI (boost::shared_ptr<PluginInsert> pi, boost::shared_
|
||||
|
||||
LXVSTPluginUI::~LXVSTPluginUI ()
|
||||
{
|
||||
_screen_update_connection.disconnect();
|
||||
_resize_connection.disconnect();
|
||||
|
||||
// plugin destructor destroys the custom GUI, via the vstfx engine,
|
||||
// and then our PluginUIWindow does the rest
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
LXVSTPluginUI::start_updating (GdkEventAny*)
|
||||
{
|
||||
_screen_update_connection.disconnect();
|
||||
_screen_update_connection = Timers::rapid_connect (mem_fun(*this, &LXVSTPluginUI::resize_callback));
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
LXVSTPluginUI::stop_updating (GdkEventAny*)
|
||||
{
|
||||
_screen_update_connection.disconnect();
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
LXVSTPluginUI::resize_callback ()
|
||||
{
|
||||
/* We could maybe use this to resize the plugin GTK parent window
|
||||
if required
|
||||
*/
|
||||
|
||||
if (!_vst->state()->want_resize) {
|
||||
return;
|
||||
}
|
||||
|
||||
int new_height = _vst->state()->height;
|
||||
int new_width = _vst->state()->width;
|
||||
|
||||
void* gtk_parent_window = _vst->state()->extra_data;
|
||||
void* gtk_parent_window = _vst->state()->gtk_window_parent;
|
||||
|
||||
if (gtk_parent_window) {
|
||||
int width = _vst->state()->width;
|
||||
int height = _vst->state()->height;
|
||||
#ifndef NDEBUG
|
||||
printf ("LXVSTPluginUI::resize_callback %d x %d\n", width, height);
|
||||
#endif
|
||||
_socket.set_size_request(
|
||||
new_width + _vst->state()->hoffset,
|
||||
new_height + _vst->state()->voffset);
|
||||
width + _vst->state()->hoffset,
|
||||
height + _vst->state()->voffset);
|
||||
|
||||
((Gtk::Window*) gtk_parent_window)->resize (new_width, new_height + LXVST_H_FIDDLE);
|
||||
((Gtk::Window*) gtk_parent_window)->resize (width, height + LXVST_H_FIDDLE);
|
||||
if (_vst->state()->linux_plugin_ui_window) {
|
||||
}
|
||||
}
|
||||
_vst->state()->want_resize = 0;
|
||||
}
|
||||
|
||||
int
|
||||
@ -106,15 +84,11 @@ int
|
||||
LXVSTPluginUI::package (Gtk::Window& win)
|
||||
{
|
||||
VSTPluginUI::package (win);
|
||||
_vst->state()->gtk_window_parent = (void*) (&win);
|
||||
|
||||
/* Map the UI start and stop updating events to 'Map' events on the Window */
|
||||
|
||||
win.signal_map_event().connect (mem_fun (*this, &LXVSTPluginUI::start_updating));
|
||||
win.signal_unmap_event().connect (mem_fun (*this, &LXVSTPluginUI::stop_updating));
|
||||
|
||||
_vst->state()->extra_data = (void*) (&win);
|
||||
_vst->state()->want_resize = 0;
|
||||
|
||||
_vst->VSTSizeWindow.connect (_resize_connection, invalidator (*this), boost::bind (&LXVSTPluginUI::resize_callback, this), gui_context());
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -181,4 +155,3 @@ gui_init (int* argc, char** argv[])
|
||||
the_gtk_display = gdk_x11_display_get_xdisplay (gdk_display_get_default());
|
||||
gtk_error_handler = XSetErrorHandler (gtk_xerror_handler);
|
||||
}
|
||||
|
||||
|
@ -20,7 +20,7 @@
|
||||
#ifndef __lxvst_plugin_ui_h__
|
||||
#define __lxvst_plugin_ui_h__
|
||||
|
||||
#include <sigc++/signal.h>
|
||||
#include "pbd/signals.h"
|
||||
#include "vst_plugin_ui.h"
|
||||
|
||||
#ifdef LXVST_SUPPORT
|
||||
@ -38,8 +38,8 @@ class LXVSTPluginUI : public VSTPluginUI
|
||||
|
||||
int get_preferred_height ();
|
||||
|
||||
bool start_updating (GdkEventAny *);
|
||||
bool stop_updating (GdkEventAny *);
|
||||
bool start_updating (GdkEventAny*) { return false; }
|
||||
bool stop_updating (GdkEventAny*) { return false; }
|
||||
|
||||
int package (Gtk::Window&);
|
||||
void forward_key_event (GdkEventKey *);
|
||||
@ -49,7 +49,7 @@ private:
|
||||
void resize_callback ();
|
||||
int get_XID ();
|
||||
|
||||
sigc::connection _screen_update_connection;
|
||||
PBD::ScopedConnection _resize_connection;
|
||||
};
|
||||
|
||||
#endif //LXVST_SUPPORT
|
||||
|
@ -51,6 +51,7 @@ VSTPluginUI::VSTPluginUI (boost::shared_ptr<ARDOUR::PluginInsert> insert, boost:
|
||||
bypass_button.set_active (!insert->active ());
|
||||
|
||||
pack_start (*box, false, false);
|
||||
box->signal_size_allocate().connect (sigc::mem_fun (*this, &VSTPluginUI::top_box_allocated));
|
||||
#ifdef GDK_WINDOWING_X11
|
||||
pack_start (_socket, true, true);
|
||||
_socket.set_border_width (0);
|
||||
@ -122,6 +123,7 @@ VSTPluginUI::configure_handler (GdkEventConfigure*)
|
||||
XEvent event;
|
||||
gint x, y;
|
||||
GdkWindow* w;
|
||||
Window xw = _vst->state()->linux_plugin_ui_window;
|
||||
|
||||
if ((w = _socket.gobj()->plug_window) == 0) {
|
||||
return false;
|
||||
@ -150,8 +152,19 @@ VSTPluginUI::configure_handler (GdkEventConfigure*)
|
||||
|
||||
gdk_error_trap_push ();
|
||||
XSendEvent (GDK_WINDOW_XDISPLAY (w), GDK_WINDOW_XWINDOW (w), False, StructureNotifyMask, &event);
|
||||
/* if the plugin does adds itself to the parent,
|
||||
* but ardour re-parents it, we have a pointer to
|
||||
* the socket's child and need to resize the
|
||||
* child window (e.g. JUCE, u-he)
|
||||
*/
|
||||
if (xw) {
|
||||
XMoveResizeWindow (GDK_WINDOW_XDISPLAY (w), xw,
|
||||
0, 0, _vst->state()->width, _vst->state()->height);
|
||||
XMapRaised (GDK_WINDOW_XDISPLAY (w), xw);
|
||||
XFlush (GDK_WINDOW_XDISPLAY (w));
|
||||
}
|
||||
gdk_error_trap_pop ();
|
||||
|
||||
#endif
|
||||
|
||||
return false;
|
||||
}
|
||||
|
@ -48,6 +48,7 @@ protected:
|
||||
|
||||
boost::shared_ptr<ARDOUR::VSTPlugin> _vst;
|
||||
Gtk::Socket _socket;
|
||||
virtual void top_box_allocated (Gtk::Allocation&) {}
|
||||
|
||||
private:
|
||||
|
||||
|
@ -20,7 +20,8 @@
|
||||
#include <gtkmm.h>
|
||||
#include <gtk/gtk.h>
|
||||
#include <gtk/gtksocket.h>
|
||||
#include <fst.h>
|
||||
#include "gtkmm2ext/gui_thread.h"
|
||||
#include "fst.h"
|
||||
#include "ardour/plugin_insert.h"
|
||||
#include "ardour/windows_vst_plugin.h"
|
||||
|
||||
@ -64,12 +65,48 @@ WindowsVSTPluginUI::~WindowsVSTPluginUI ()
|
||||
// and then our PluginUIWindow does the rest
|
||||
}
|
||||
|
||||
void
|
||||
WindowsVSTPluginUI::top_box_allocated (Gtk::Allocation& a)
|
||||
{
|
||||
int h = a.get_height() + 12; // 2 * 6px spacing
|
||||
if (_vst->state()->voffset != h) {
|
||||
#ifndef NDEBUG
|
||||
printf("WindowsVSTPluginUI:: update voffset to %d px\n", h);
|
||||
#endif
|
||||
_vst->state()->voffset = h;
|
||||
resize_callback ();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
WindowsVSTPluginUI::resize_callback ()
|
||||
{
|
||||
void* gtk_parent_window = _vst->state()->gtk_window_parent;
|
||||
if (gtk_parent_window) {
|
||||
int width = _vst->state()->width + _vst->state()->hoffset;
|
||||
int height = _vst->state()->height + _vst->state()->voffset;
|
||||
#ifndef NDEBUG
|
||||
printf ("WindowsVSTPluginUI::resize_callback %d x %d\n", width, height);
|
||||
#endif
|
||||
set_size_request (width, height);
|
||||
((Gtk::Window*) gtk_parent_window)->set_size_request (width, height);
|
||||
((Gtk::Window*) gtk_parent_window)->resize (width, height);
|
||||
fst_move_window_into_view (_vst->state ());
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
WindowsVSTPluginUI::package (Gtk::Window& win)
|
||||
{
|
||||
#ifndef NDEBUG
|
||||
printf ("WindowsVSTPluginUI::package\n");
|
||||
#endif
|
||||
VSTPluginUI::package (win);
|
||||
_vst->state()->gtk_window_parent = (void*) (&win);
|
||||
|
||||
fst_move_window_into_view (_vst->state ());
|
||||
_vst->VSTSizeWindow.connect (_resize_connection, invalidator (*this), boost::bind (&WindowsVSTPluginUI::resize_callback, this), gui_context());
|
||||
|
||||
resize_callback ();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -17,6 +17,10 @@
|
||||
|
||||
*/
|
||||
|
||||
#ifndef __windows_vst_plugin_ui_h__
|
||||
#define __windows_vst_plugin_ui_h__
|
||||
|
||||
#include "pbd/signals.h"
|
||||
#include "vst_plugin_ui.h"
|
||||
|
||||
class WindowsVSTPluginUI : public VSTPluginUI
|
||||
@ -34,6 +38,10 @@ public:
|
||||
|
||||
private:
|
||||
|
||||
void resize_callback ();
|
||||
int get_XID ();
|
||||
void top_box_allocated (Gtk::Allocation&);
|
||||
|
||||
PBD::ScopedConnection _resize_connection;
|
||||
};
|
||||
#endif
|
||||
|
Loading…
Reference in New Issue
Block a user