Hello Everyone,
I am trying to detect movement of the audio plugin editor window, but without much success. I am hoping that someone can give me a hint, or confirm there is an issue in the framework.
I am on JUCE v4.3.1 at the moment, but I would convince my people to upgrade to latest if that would solve this problem. Currently working on macOS Sierra 10.12.4 and need for this to work eventually on Win32.
As I said, I need to detect when the audio plugin editor is moved by the user. (The reason is that we are integrating a chromium embedded framework browser window for the plugin editor, and as was pointed out in the docs for ComponentMovementWatcher (https://www.juce.com/doc/classComponentMovementWatcher#details), I need to keep my custom window in the right place, just like JUCE’s own WebBrowserComponent.)
Besides ComponentMovementWatcher docs, I have also seen this post (ComponentMovementWatcher class is not working as expected), where near the end of the discussion, Jules says “The only thing it [the ComponentMovementWatcher] watches is the target component, and it will only tell you when that component is moved relative to either the screen (if it is itself a window) or the top-level comp, if it’s embedded at some arbitrary depth within a window.” I want to know when the window itself moves relative to the screen. Simple enough.
I realized after some experimentation that you can’t just create the ComponentMovementWatcher too early, because the hierarchy of Components might not be fully built, and the ultimate parent target Component (the window) of the ComponentMovementWatcher might not be in the Component hierarchy yet (to pass into the ComponentMovementWatcher(Component *component) constructor). My solution was to make my browser component a ComponentListener, and create my ComponentMovementWatcher in componentParentHierarchyChanged(). The last time the function is called, everything ought to be built, and the call to browserComponent.getTopLevelComponent() should return the top level window:
class TopWindowMovementWatcher;
class WebBrowserComponent : public Component, public ComponentListener
{
. . .
void componentParentHierarchyChanged( Component & component )
{
topWindowMovementWatcher = new TopWindowMovementWatcher( *this );
}
ScopedPointer<TopWindowMovementWatcher> topWindowMovementWatcher;
};
class TopWindowMovementWatcher : public ComponentMovementWatcher
{
TopWindowMovementWatcher( WebBrowserComponent& browserComponent )
: ComponentMovementWatcher( browserComponent.getTopLevelComponent() ),
webBrowserComponent( browserComponent )
{
}
. . .
// From ComponentMovementWatcher
void componentMovedOrResized( bool wasMoved, bool wasResized ) override;
{
Rectangle<int> bounds( webBrowserComponent.getScreenBounds() );
. . .
std::cerr << "typeid(*getComponent()).name(): " << typeid(*getComponent()).name() << std::endl;
}
WebBrowserComponent & webBrowserComponent;
};
The problem is that the componentMovedOrResized() function gets called only a few times at the time the plugin editor is created, and never again even when I move the editor on screen. Note that the top level window just doesn’t ever seem to appear, as my diagnostic messages show:
. . .
typeid(*getComponent()).name(): 15MyMainComponent
typeid(*getComponent()).name(): 28MypluginAudioProcessorEditor
typeid(*getComponent()).name(): N6JuceAU16EditorCompHolderE
typeid(*getComponent()).name(): N6JuceAU16EditorCompHolderE
typeid(*getComponent()).name(): N6JuceAU16EditorCompHolderE
typeid(*getComponent()).name(): N6JuceAU16EditorCompHolderE
A search in the JUCE codebase shows that the internal class EditorCompHolder is a Component and not any sort of window:
class EditorCompHolder : public Component
{. . .}
And the EditorCompHolder is added to the desktop in the same JUCE source file:
static NSView* createViewFor (AudioProcessor* filter, JuceAU* au, AudioProcessorEditor* const editor)
{
EditorCompHolder* editorCompHolder = new EditorCompHolder (editor);
. . .
editorCompHolder->addToDesktop (0, (void*) view);
. . .
}
(These last lines I don’t completely understand.)
But in the end, the EditorCompHolder never moves relative to its parent (something on the “desktop”, I guess), and I don’t get componentMovedOrResized() messages.
So do I have a fundamental misunderstanding of how this is supposed to work: you register a ComponentMovementWatcher to listen for movement of its target relative to the screen (if the target is a window) or the top level Component (if the target is not a window) by passing that target to the ComponentMovementWatcher constructor? Or is there something not quite correct in the JUCE implementation?
Thanks for any help,
Isaac