qtractor icon indicating copy to clipboard operation
qtractor copied to clipboard

VST3 plugin size request

Open oldcastlehq opened this issue 2 years ago • 13 comments

Hi Rui,

I noticed that the plugin https://www.fullbucket.de/music/whispair.html have window sizing issue (this is a Windows plugin, and I'm using Yabridge to run it on Linux).

Screenshot_20220310_230023

The plugin offers a VST2 version, which works fine. So, Robbert (Yabridge's author) suspected that Qtractor does not ask the plugin (VST3) for its size at all, so the window does not have the correct size. So, it's a problem only for VST3 plugins.

oldcastlehq avatar Mar 10 '22 22:03 oldcastlehq

is that the only VST3 plugin (via yabridge) that shows with incorrect size?

most VST3 plugins do report their intended editor window (GUI) size alright, at least the Linux native VST3 ones (I don't test any under any wine bridge, so you and Robert are to delve on that suspicion a little further, sorry)

rncbc avatar Mar 11 '22 11:03 rncbc

After more digging, it seems that the issue only happens with Full Bucket plugins. I could not replicate the issue with other plugins at all.

Thanks!

oldcastlehq avatar Mar 11 '22 12:03 oldcastlehq

Sorry. I was too fast to closed it. More digging is happening :-)

oldcastlehq avatar Mar 11 '22 12:03 oldcastlehq

The problem is that Qtractor never even queries the editor's size. This is an excerpt from yabridge's tracing:

trace
13:42:31 [whispair-4AJacdky] [host -> vst] >> 0: IEditController::createView(name = "editor")
13:42:31 [whispair-4AJacdky] [host <- vst]    <IPlugView*>
13:42:31 [whispair-4AJacdky] [host -> vst] >> 0: IPlugView::isPLatformTypeSupported(type = "X11EmbedWindowID" (will be translated to "HWND"))
13:42:31 [whispair-4AJacdky] [host <- vst]    kResultOk
13:42:31 [whispair-4AJacdky] [host -> vst] >> 0: IPlugView::setFrame(frame = <IPlugFrame*>)
13:42:31 [whispair-4AJacdky] [host <- vst]    kResultOk
13:42:31 [whispair-4AJacdky] [host -> vst] >> 0: IPlugView::attached(parent = 90177685, type = "X11EmbedWindowID" (will be translated to "HWND"))
13:42:31 [whispair-4AJacdky] [Wine STDERR] DEBUG: host_window: 90177685
13:42:31 [whispair-4AJacdky] [Wine STDERR] DEBUG: parent_window: 90177685
13:42:31 [whispair-4AJacdky] [Wine STDERR] DEBUG: wrapper_window: 104857600
13:42:31 [whispair-4AJacdky] [Wine STDERR] DEBUG: wine_window: 109051907
13:42:31 [whispair-4AJacdky] [Wine STDERR] DEBUG: Reparenting 104857600 to 90177685 succeeded
13:42:31 [whispair-4AJacdky] [Wine STDERR] DEBUG: Reparenting 109051907 to 104857600 succeeded
13:42:31 [whispair-4AJacdky] [Wine STDERR] 0128:fixme:imm:ImeSetActiveContext (0x1990a60, 1): stub
13:42:31 [whispair-4AJacdky] [Wine STDERR] 0128:fixme:imm:ImmReleaseContext (0000000000010062, 0000000001990A60): stub
13:42:31 [whispair-4AJacdky] [Wine STDERR] 0128:fixme:dwrite:dwritefontface5_HasVariations 00000000019A1B00: stub
13:42:31 [whispair-4AJacdky] [Wine STDERR] DEBUG: Resizing wrapper window to 1127x776
13:42:31 [whispair-4AJacdky] [host <- vst]    kResultOk
13:42:31 [whispair-4AJacdky] [host -> vst] >> 0: IPlugView::canResize()
13:42:31 [whispair-4AJacdky] [Wine STDERR] 0090:fixme:imm:ImeSetActiveContext (0x274fb0, 0): stub
13:42:31 [whispair-4AJacdky] [Wine STDERR] 0090:fixme:imm:ImmReleaseContext (0000000000010020, 0000000000274FB0): stub
13:42:31 [whispair-4AJacdky] [Wine STDERR] DEBUG: ReparentNotify for window 104857600 to new parent 90177685, generated from 104857600
13:42:31 [whispair-4AJacdky] [Wine STDERR] DEBUG: Removing XdndAware properties from window 90177685 and all of its ancestors
13:42:31 [whispair-4AJacdky] [Wine STDERR] DEBUG: Unhandled X11 event 19
13:42:31 [whispair-4AJacdky] [Wine STDERR] DEBUG: ConfigureNotify for window 104857600
13:42:31 [whispair-4AJacdky] [Wine STDERR] DEBUG: Spoofing local coordinates to (0, 0)
13:42:31 [whispair-4AJacdky] [host <- vst]    kResultFalse
13:42:31 [whispair-4AJacdky] [Wine STDERR] DEBUG: ConfigureNotify for window 90177685
13:42:31 [whispair-4AJacdky] [Wine STDERR] DEBUG: Spoofing local coordinates to (0, 0)
13:42:31 [whispair-4AJacdky] [Wine STDERR] DEBUG: ReparentNotify for window 90177685 to new parent 10493449, generated from 90177685
13:42:31 [whispair-4AJacdky] [Wine STDERR] DEBUG: Removing XdndAware properties from window 90177685 and all of its ancestors
13:42:31 [whispair-4AJacdky] [Wine STDERR] DEBUG: Unhandled X11 event 19
13:42:31 [whispair-4AJacdky] [Wine STDERR] DEBUG: VisibilityNotify for window 90177685
13:42:31 [whispair-4AJacdky] [Wine STDERR] DEBUG: FocusIn for window 90177685 (wine window active)
13:42:31 [whispair-4AJacdky] [Wine STDERR] DEBUG: Spoofing local coordinates to (1083, 526)
13:42:31 [whispair-4AJacdky] [Wine STDERR] DEBUG: Active keyboard modifiers: 0
13:42:31 [whispair-4AJacdky] [Wine STDERR] DEBUG: Not grabbing input focus for window 90177685(already focused)
13:42:31 [whispair-4AJacdky] [Wine STDERR] DEBUG: VisibilityNotify for window 90177685
13:42:31 [whispair-4AJacdky] [Wine STDERR] DEBUG: ConfigureNotify for window 90177685
13:42:31 [whispair-4AJacdky] [Wine STDERR] DEBUG: Spoofing local coordinates to (1083, 526)
13:42:31 [whispair-4AJacdky] [Wine STDERR] DEBUG: EnterNotify for window 104857600 (wine window active)
13:42:31 [whispair-4AJacdky] [Wine STDERR] DEBUG: Spoofing local coordinates to (1083, 526)
13:42:31 [whispair-4AJacdky] [Wine STDERR] DEBUG: Active keyboard modifiers: 0
13:42:31 [whispair-4AJacdky] [Wine STDERR] DEBUG: Not grabbing input focus for window 90177685(already focused)
13:42:31 [whispair-4AJacdky] [Wine STDERR] DEBUG: ConfigureNotify for window 90177685
13:42:31 [whispair-4AJacdky] [Wine STDERR] DEBUG: Spoofing local coordinates to (1083, 526)
13:42:33 [whispair-4AJacdky] [Wine STDERR] DEBUG: LeaveNotify for window 104857600 (wine window active, detail: 1, pointer pos: 1041, 736, pointer is not in Wine window)
13:42:33 [whispair-4AJacdky] [Wine STDERR] DEBUG: Not grabbing input focus for window 90177685(already focused)
13:42:33 [whispair-4AJacdky] [Wine STDERR] DEBUG: Unhandled X11 event 10
13:42:33 [whispair-4AJacdky] [Wine STDERR] DEBUG: EnterNotify for window 104857600 (wine window inactive)
13:42:33 [whispair-4AJacdky] [Wine STDERR] DEBUG: Spoofing local coordinates to (1083, 526)
13:42:33 [whispair-4AJacdky] [Wine STDERR] DEBUG: LeaveNotify for window 104857600 (wine window inactive, detail: 4, pointer pos: 1058, 763, pointer is not in Wine window)
13:42:49 [whispair-4AJacdky] [host -> vst] >> 0: IAudioProcessor::setProcessing(state = false)
13:42:49 [whispair-4AJacdky] [host <- vst]    kResultOk
...after this there are only some more audio processor related things until the IPlugView::removed() call when clsoing the editor

After that IPlugView::canResize() (to which the plugin returned kResultFalse) there are no more IPlugView method calls until the editor gets closed again.

robbert-vdh avatar Mar 11 '22 12:03 robbert-vdh

and? what do you propose?

the host (qtractor) calls IPlugView::canResize() under IPlugFrame::resizeView() , which is supposed to catch the intended initial size anyway... the plugin replies it cannot resize, and then qtractor (the host) makes it fixed-size forever more with the exact size given... what gives?

rncbc avatar Mar 11 '22 14:03 rncbc

This plugin does not call IPlugFrame::resizeView() however. And since Qtractor never asks the plugin how large its GUI is, the window is left at whatever the default size is.

robbert-vdh avatar Mar 11 '22 15:03 robbert-vdh

This plugin does not call IPlugFrame::resizeView() however.

maybe the question is why that is the case? (most) other plugins do, only these don't? baffles me.

anyway, if the above is true, the gui is still user resizeable or it is not?

rncbc avatar Mar 11 '22 15:03 rncbc

If the plugin doesn't need to resize its view, why would it need to call IPlugFrame::resizeView()?

robbert-vdh avatar Mar 11 '22 15:03 robbert-vdh

good call, and then, yet again, what do you propose? when do you think the host should call IPlugView::canResize() ? or how should the host know the dang initial size anyway?

rncbc avatar Mar 11 '22 16:03 rncbc

You can call IPlugView::canResize() before or after attached(), that shouldn't matter. But the problem here is that Qtractor enver sets the editor window's size to IPlugView::getSize(). The correct sequence of events would be:

  1. Qtractor creates a (hidden/not yet mapped) window for the editor.
  2. Qtractor should set the plug frame with IPlugView::setFrame() so the plugin can request a resize.
  3. Qtractor uses IPlugView::isPlatformTypeSupported() to check if the plugin supports X11 GUIs.
  4. Qtractor sets the DPI scale with IPlugViewContentScale::setContentScale(), if Qtractor handles HiDPI and the plugin supports it.
  5. (optional, you may still need step 6 anyways for misbehaving plugins) Qtractor asks the plugin how large its editor is with IPlugView::getSize() and resizes its own window accordingly. This returned size is already multiplied by the content scale factor.
  6. Qtractor calls IPlugView::attached() to allow the plugin to embed itself itself in the editor window.
  7. Repeat of step 4, in case the plugin does something wonky.
  8. Qtractor calls IPlugView::onSize() with the size it has resized its editor window to.
  9. Qtractor calls IPlugView::canResize() (can also do this before creating the window at all, but just like getSize() there may be one or two plugins that report the incorrect value before the attached() call. If the plugin returns kResultOk, make the editor window resizable and call IPlugView::checkSizeConstraint() followed by a window resize and IPlugView::onSize() if the plugin accepts the new size whenever the window is being resized.
  10. Not really part of this sequence, but whenever the plugin calls IPlugFrame::resizeView(), resize the window to that new size and call IPlugView::onSize() with the new size. Keep track of the current size to prevent sending this size twice since resizing the window would also trigger the behavior from 9).
  11. Finally Qtractor should map the window/make it visible.

robbert-vdh avatar Mar 11 '22 16:03 robbert-vdh

@robbert-vdh really appreciated, wholly thanks for the extensive explanation

unfortunately this isn't going to fly any day soon, at least from my keyboard, sorry (truth is, I don't feel the need, as said, most of VST3 plugins I love do work the way it is now; so why bother?)

let there be no restraints whatsoever for an incoming PR ntl. :) cheers

ps. fwiw. qtractor does all of the above in that sequence, but steps 4 and 5. -- mind you, the call to IPlugFrame::resizeView() (step 10) is always expected to occur under the auspices to IPlugView::attached() (step 6): a plugin failing to do so or never calling it might be the reason for the OP behavior -- so maybe a PR should probably focus on introducing step 5.

rncbc avatar Mar 11 '22 16:03 rncbc

please check whether df98d329 goes any better

rncbc avatar Mar 12 '22 19:03 rncbc

That indeed fixes the issue with Whispair, Kontakt, and the other plugins that were affected by this!

robbert-vdh avatar Mar 12 '22 19:03 robbert-vdh