Heya - I noticed the new webui stuff makes the bounds of its rect transparent for a split second before actually showing the webpage, and figured it was just a quirk of web browsers in general, so set about having some sort of loading screen beneath the webview, setting it invisible, and then in response to pageFinishedLoading, invoking a callback to set it visible - so something like:
// SinglePageBrowser.h
class SinglePageBrowser final : public juce::WebBrowserComponent {
public:
// Page about to load etc..
void pageFinishedLoading(const juce::String&) override {
if(!pageLoadedCallback) return;
pageLoadedCallback();
}
std::function<void(void)> pageLoadedCallback{ nullptr };
};
// Editor
PluginEditor::PluginEditor(/* etc etc etc */) {
m_browser.setVisible(false);
addChildComponent(&m_browser);
auto pageLoadedCallback = [this]() -> void {
jassert(!m_browser.isVisible());
m_browser.setVisible(true);
};
m_browser.pageLoadedCallback = std::move(pageLoadedCallback);
m_browser.goToUrl(/*etc*/);
// set size etc etc etc etc
}
void PluginEditor::paint(juce::Graphics& g) {
g.fillAll(juce::Colour{ 0xFF000000 });
}
// and then obviously set the browser's bounds etc etc
And the same thing happens: just before my pageLoadedCallback gets called, the area the WebUI takes up is made transparent (and then my breakpoint is hit within my callback) - the assertion passes too, so it seems to not even be directly caused by the page loading.
Any ideas on what’s going on here? I have admittedly only tried this on Windows, and have only rigourously tested its behaviour in Standalone, maybe it’s different in a VST3 context somehow?
The browser component isn’t set visible until the callback in my snippet - and it passes the assertion, so it seems to be unrelated to the component’s visibility - so don’t think so, it seems to be more like the clip rect for the browser component gets turned transparent for a second regardless of its visibility.
Awesome just tried it, seems a bit better but I’m still getting weird behaviour on startup, I can’t attach a video but some screenshots: (this is loading the files from Binary Data as opposed to from localhost if that makes a difference)
So it flickers white when it opens:
then the window goes transparent:
and then it sort of “half-renders” (this is probably my end, the background is an svg so I guess it’s taking a split second to load it)
and then it fully loads
The default background colour prior to loading the content is white, this is now consistent across all platforms.
We could probably make this configurable, but right now on Windows a white flash may be inevitable unless the WEBVIEW2_DEFAULT_BACKGROUND_COLOR environment variable is set.
I’m not sure what the flash to transparency is caused by, this isn’t something I observed. Could you share maybe a simple example that produces this?
As a workaround I’d try to delay showing the WebBrowserComponent. Initially by a Timer, to see if it’s even possible to wait long enough, and then by using maybe adding a NativeFunction that toggles visibility, and then a Javascript onload script could control this.
Correction, I am seeing a transparent flash with the WebBrowserComponent in a plugin window. Just for our own record, this is not a regression caused by the latest change.
We’ll investigate. Until then, I can only suggest trying to explicitly toggle visibility.
Ah awesome, reassuring that you were able to recreate it (makes me slightly less worried about my javascript).
Will give the timer stuff a go, thanks for the tip, and will post if I get a nice workaround set up, thanks for looking into this!
So actually another interesting find - on Windows, setVisible() seems to be ignored by the browser component - I’m explicitly setting it invisible and never calling setVisible(true) but it’s still showing up - maybe I’m missing something but thought I’d mention it
I tried to solve it with .setVisible(true) after the loading finished, but the webbrowser wouldn’t load if it wasn’t visible.
@attila what are the changes of getting faster browser/webview loadings?
I’m getting around half a second between window opens and content is displayed.
Thanks for the snippet, will give this a try later on!
@attila were you able to recreate the setVisible issue? To clarify it a little:
PluginEditor::PluginEditor() {
addChildComponent(&m_webBrowser);
// Should already be invisible iirc, but to sanity check::
m_webBrowser.setVisible(false);
}
void PluginEditor::resized() {
m_webBrowser.setBounds(getLocalBounds()); // This is still visible, but not interactable
// Waiting to call setBounds until the page has loaded works, so it seems like something is either happening in setBounds that *calls* setVisible, or there's something weird going on with setVisible in the first place
}
It’s possible I’ve missed something in the docs about setVisible and the browser, but thought I’d verify that this wasn’t intended behaviour!
FWIW this was really helpful but didn’t quite get me there. Even with a fairly simple webpage, the resize on setting visibility still caused the white flash. Pages still don’t load when the browser is invisible, so Instead I use (pseudocode):
if(pageReady){
webComponent.setBounds(getLocalBounds());
} else {
const auto w = getWidth();
const auto h = getHeight();
webComponent.setBounds (w-1, h-1, w, h);
}