Hi all,
Any idea why the createSnapshotOfNativeWindow returns 1x1 image? I also tried with real native content component (VSTPluginWindow loaded from external .vst instead of juce::TextButton) and had same results. This is being called from desktop app, tested on Mac OS X, JUCE 5.4.5. Did I miss sth simple and obvious?
MessageManager::callAsync([](){ // just to avoid questions:)
ResizableWindow window("some window",true);
window.setVisible(true);
window.centreWithSize(100,100);
window.toFront(true);
auto* button = new TextButton("abc");
window.setContentOwned(button, true); // add some content just for test
button->setBounds(0,0,50,50);
DBG(window.getWidth()); // ok, gives 52 because of the content component
auto img = createSnapshotOfNativeWindow(window.getPeer()->getNativeHandle());
jassert(img.isValid()); // isValid returns true
DBG(img.getWidth()); // it gives 1 - the whole img is 1x1 only
});
Thanks for any help!
At least on Windows, just changing to this at least gives the correct sized image :
auto* button = new TextButton("abc");
button->setBounds(0, 0, 50, 50);
window.setContentOwned(button, true); // add some content just for test
That is, set the content component bounds first, then attach it to the window. You should have got a jassert about that already with your own code, though…? (setContentOwned checks that the component you are setting doesn’t have a zero size.)
It’s already there, I was just rewriting from my code into the juce forum to simplify things and di da mistake (obviously I would had a jassert caught when done as above!):
So I have now tried running the below code (literally - I copied it from here after posting to avoid further confusions), and still getting 1x1 on MacOS (Mojave):
MessageManager::callAsync([](){ // just to avoid questions:)
ResizableWindow window("some window",true);
window.setVisible(true);
window.centreWithSize(100,100);
window.toFront(true);
auto* button = new TextButton("abc");
button->setBounds(0,0,50,50);
window.setContentOwned(button, true); // add some content just for test
DBG(window.getWidth()); // ok, gives 52 because of the content component
auto img = createSnapshotOfNativeWindow(window.getPeer()->getNativeHandle());
jassert(img.isValid()); // isValid returns true
DBG(img.getWidth()); // it gives 1 - the whole img is 1x1 only
});
I have tried same project on different PC (this time running Mac OSX Catalina and latest XCode) - this time getting some exception (thrown when calling createSnapshotOfNativeWindow):
Maybe the native window is created asynchronously, so you can’t do your things right away when the Juce window has been created?
Yeah, probably that’s the case - if I delay calling createSnapshotOfNativeWindow from window creation and showing (eg. call createSnapshotOfNativeWindow when some button is pressed), then it’s all working fine.
So I have narrowed it to the below simple code (everything is executed on the MessageQueue Thread) :
If I run this first:
window.reset(new ResizableWindow("some window",true));
window->centreWithSize(500,500);
window->setVisible(true);
And then when some button is pressed call createSnapshotOfNativeWindow(window->getPeer()->getNativeHandle()), all is fine and working, no exceptions and Image object has proper size etc.
However, when I include everything in one call, ie.:
window.reset(new ResizableWindow("some window",true));
window->centreWithSize(500,500);
window->setVisible(true);
createSnapshotOfNativeWindow(window->getPeer()->getNativeHandle())
then I’m getting the previously described behaviour (1x1 size or exception thrown depending on my MacOSX/XCode versions).
Do we have any control over that? How do I find out if the native window is ready and can be manipulated? I have gone through https://developer.apple.com/documentation/appkit/nswindow to find out Mac OS solution, but found nothing.