[LV2] Implement UI:sizeConstraints extension
David Robillard
d at drobilla.net
Sat May 30 05:55:46 PDT 2020
On Thu, 2020-05-28 at 15:25 +0300, Vladimir Sadovnikov wrote:
> Hello all!
>
>
> I suggest to implement UI:sizeConstraints interface as an addition to
> UI:resize.
>
>
> The main reason is that plugins may provide sizeable interface which
> is
> currently not very good handled by hosts.
>
> Case 1.
>
> If user manually resizes the plugin window in the host, we can catch
> the size
> change event by two ways:
>
> a. The X11 event that is sent to the plugin about window size change.
>
> b. The host calls ui::resize () to inform the UI about the window
> resize (Ardour
> 5.12 doesn't do this).
>
> In both cases all information is related to the plugin window which
> can be
> embedded into the other toolkit's window.
>
> If the size is too small, plugin probably will trigger ui:resize
> event. But
> after that, host (like Ardour) won't be able to set the size less
> than plugin
> has reported to it anymore.
>
> And here's the Case 2.
>
> User changes something in the UI that causes the UI do change it's
> size. When
> the UI becomes larger, plugin just initiates ui:resize and host
> changes the size
> of plugin's parent window.
>
> But if the size becomes smaller, then host keeps the same size of the
> parent
> window as it was set previously and doesn't allow the user to reduce
> the size of
> plugin window.
>
> If the plugin forces to call ui:resize, then host forces the parent
> window to
> resize and user observes smaller window.
>
> This is not always expected behaviour, especially when the window is
> maximized
> or manually enlarged by the user.
>
>
> If we rely on a toolkit that should properly arrange child window
> inside of
> parent, we get different results on different versions of toolkit: on
> latest
> Ubuntu all works just fine with
>
> Ardour installed from official repositories. But on my openSUSE Leap
> with
> official Ardour distribution, I get the plugin window clipped from
> right and
> bottom side.
>
>
> For this situation, the good option would be if plugin could report
> size
> constraints (minimum and maximum possible sizes) of it's window to
> the host.
>
> When user changes something in UI that causes it to resize, the
> plugin reports
> both size constraints and actual size to the host and it makes a
> decision about
> how to resize it's parent window
>
> that holds the plugin. Moreover, it sets proper size constraints to
> the parent
> window allowing the user to set window size within strictly defined
> ranges (if
> they are).
>
>
> UI:sizeConstraints extension prototype is designed to deliver
> additional
> information from the plugin to the host about size constraints of
> it's main window:
>
> > typedef struct LV2UI_SizeConstraints {
> > /**
> > Pointer to opaque data which must be passed to
> > ui_set_constraints()
> > */
> > LV2UI_Feature_Handle handle;
> >
> > /**
> > Report UI size constraints to the host
> > When provided by the host, the UI may call this function to
> > inform the
> > host about the minimum and maximum size of the UI.
> >
> > @param min_width the minimum allowed width of the UI
> > (negative value
> > means no limit)
> > @param min_height the minimum allowed height of the UI
> > (negative value
> > means no limit)
> > @param max_width the maximum allowed width of the UI
> > (negative value
> > means no limit)
> > if both min_width and max_width are non-negative and
> > max_width
> > is less than min_width,
> > then it is considered to be the same as min_width by
> > the host
> > @param max_height the maximum allowed height of the UI
> > (negative value
> > means no limit)
> > if both min_height and max_height are non-negative
> > and
> > max_height is less than min_height,
> > then it is considered to be the same as min_height by
> > the host
> > @return 0 on success.
> > */
> > int (*ui_set_constraints)(LV2UI_Feature_Handle handle,
> > int min_width, int min_height,
> > int max_width, int max_height);
> > } LV2UI_SizeConstraints;
>
> The usual behaviour in code:
>
> > // Somewhere in the code
> >
> > LV2UI_Resize *lv2_rs;
> >
> > LV2UI_SizeConstraints *lv2_sc;
> >
> >
> > // Method that synchronizes the size of the plugin window with the
> > host
> >
> > void sync_size(Window *wnd)
> >
> > {
> >
> > int w, h;
> >
> > int min_w, min_h, max_w, max_h;
> >
> > // We obtain actual size constraints and size of the plugin
> > window
> >
> > wnd->get_size_constraints(&min_w, &min_h, &max_w, &max_h);
> >
> > wnd->get_size(&w, &h);
> >
> > // We inform the host about size constraints and actual size of
> > the plugin
> > window
> >
> > lv2_sc->ui_set_constraints(lv2_sc->handle, min_w, min_h, max_w,
> > max_h);
> >
> > lv2_rs->ui_resize(lv2_rs->handle, w, h);
> >
> > }
> >
>
> Please let me know what you think
I think, or at least strongly suspect, that ui:resize was a mistake,
and this is an even more intense version of that same mistake.
In working on this recently with that in mind (writing a plugin UI
myself and working on suil at the same time) I seem to have managed to
make everything work without using it at all. The window systems
already have this stuff, after all. Most of the problems in practical
use (including with LSP plugins) seem to be caused by abuse of
ui:resize and a lot of legacy of people hammering on it to try and make
things do what they want, but it seems to work much better to me to
just use the platform window APIs properly on both host and plugin
side.
So the big question is: why not set up the window correctly and require
hosts to handle that correctly, rather that require implementing
multiple conflicting implementations of the same thing (the native
window API, and also a parallel bunch of LV2 extensions that do the
same thing)?
--
dr
More information about the Devel
mailing list