mirror of
https://github.com/juce-framework/JUCE.git
synced 2026-01-24 01:54:22 +00:00
Windows: Add WebView2Preferences struct to modify aspects of WebView2 behaviour
This commit is contained in:
parent
315f6d8fcd
commit
4649bc1b13
6 changed files with 154 additions and 56 deletions
|
|
@ -192,4 +192,11 @@
|
|||
#if ! JUCE_WINDOWS
|
||||
juce::ScopedDPIAwarenessDisabler::ScopedDPIAwarenessDisabler() { ignoreUnused (previousContext); }
|
||||
juce::ScopedDPIAwarenessDisabler::~ScopedDPIAwarenessDisabler() {}
|
||||
|
||||
#if JUCE_WEB_BROWSER
|
||||
juce::WebBrowserComponent::WebBrowserComponent (ConstructWithoutPimpl) {}
|
||||
juce::WindowsWebView2WebBrowserComponent::WindowsWebView2WebBrowserComponent (bool unloadWhenHidden,
|
||||
const WebView2Preferences&)
|
||||
: juce::WebBrowserComponent (unloadWhenHidden) {}
|
||||
#endif
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -141,14 +141,17 @@ public:
|
|||
/** @internal */
|
||||
class Pimpl;
|
||||
|
||||
private:
|
||||
//==============================================================================
|
||||
protected:
|
||||
friend class WindowsWebView2WebBrowserComponent;
|
||||
|
||||
explicit WebBrowserComponent (bool unloadPageWhenBrowserIsHidden,
|
||||
const File& dllLocation,
|
||||
const File& userDataFolder);
|
||||
struct ConstructWithoutPimpl
|
||||
{
|
||||
explicit ConstructWithoutPimpl (bool unloadOnHide) : unloadWhenHidden (unloadOnHide) {}
|
||||
const bool unloadWhenHidden;
|
||||
};
|
||||
explicit WebBrowserComponent (ConstructWithoutPimpl);
|
||||
|
||||
private:
|
||||
//==============================================================================
|
||||
std::unique_ptr<Pimpl> browser;
|
||||
bool blankPageShown = false, unloadPageWhenHidden;
|
||||
|
|
@ -163,6 +166,72 @@ private:
|
|||
};
|
||||
|
||||
//==============================================================================
|
||||
/** Class used to create a set of preferences to pass to the WindowsWebView2WebBrowserComponent
|
||||
wrapper constructor to modify aspects of its behaviour and settings.
|
||||
|
||||
You can chain together a series of calls to this class's methods to create a set of whatever
|
||||
preferences you want to specify.
|
||||
|
||||
@tags{GUI}
|
||||
*/
|
||||
class JUCE_API WebView2Preferences
|
||||
{
|
||||
public:
|
||||
//==============================================================================
|
||||
/** Sets a custom location for the WebView2Loader.dll that is not a part of the
|
||||
standard system DLL search paths.
|
||||
*/
|
||||
WebView2Preferences withDLLLocation (const File& location) const { return with (&WebView2Preferences::dllLocation, location); }
|
||||
|
||||
/** Sets a non-default location for storing user data for the browser instance. */
|
||||
WebView2Preferences withUserDataFolder (const File& folder) const { return with (&WebView2Preferences::userDataFolder, folder); }
|
||||
|
||||
/** If this is set, the status bar usually displayed in the lower-left of the webview
|
||||
will be disabled.
|
||||
*/
|
||||
WebView2Preferences withStatusBarDisabled() const { return with (&WebView2Preferences::disableStatusBar, true); }
|
||||
|
||||
/** If this is set, a blank page will be displayed on error instead of the default
|
||||
built-in error page.
|
||||
*/
|
||||
WebView2Preferences withBuiltInErrorPageDisabled() const { return with (&WebView2Preferences::disableBuiltInErrorPage, true); }
|
||||
|
||||
/** Sets the background colour that WebView2 renders underneath all web content.
|
||||
|
||||
This colour must either be fully opaque or transparent. On Windows 7 this
|
||||
colour must be opaque.
|
||||
*/
|
||||
WebView2Preferences withBackgroundColour (const Colour& colour) const
|
||||
{
|
||||
// the background colour must be either fully opaque or transparent!
|
||||
jassert (colour.isOpaque() || colour.isTransparent());
|
||||
|
||||
return with (&WebView2Preferences::backgroundColour, colour);
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
File getDLLLocation() const { return dllLocation; }
|
||||
File getUserDataFolder() const { return userDataFolder; }
|
||||
bool getIsStatusBarDisabled() const noexcept { return disableStatusBar; }
|
||||
bool getIsBuiltInErrorPageDisabled() const noexcept { return disableBuiltInErrorPage; }
|
||||
Colour getBackgroundColour() const { return backgroundColour; }
|
||||
|
||||
private:
|
||||
//==============================================================================
|
||||
template <typename Member, typename Item>
|
||||
WebView2Preferences with (Member&& member, Item&& item) const
|
||||
{
|
||||
auto options = *this;
|
||||
options.*member = std::forward<Item> (item);
|
||||
|
||||
return options;
|
||||
}
|
||||
|
||||
File dllLocation, userDataFolder;
|
||||
bool disableStatusBar = false, disableBuiltInErrorPage = false;
|
||||
Colour backgroundColour = Colours::white;
|
||||
};
|
||||
|
||||
/**
|
||||
If you have enabled the JUCE_USE_WIN_WEBVIEW2 flag then this wrapper will attempt to
|
||||
use the Microsoft Edge (Chromium) WebView2 control instead of IE on Windows. It will
|
||||
|
|
@ -176,34 +245,38 @@ private:
|
|||
system DLL, we can't rely on it being found via the normal system DLL search paths.
|
||||
Therefore in order to use WebView2 you need to ensure that WebView2Loader.dll is
|
||||
installed either to a location covered by the Windows DLL system search paths or
|
||||
to the folder specified in the constructor of this class.
|
||||
to the folder specified in the WebView2Preferences.
|
||||
|
||||
@tags{GUI}
|
||||
*/
|
||||
class WindowsWebView2WebBrowserComponent : public WebBrowserComponent
|
||||
{
|
||||
public:
|
||||
//==============================================================================
|
||||
/** Creates a WebBrowserComponent that is compatible with the WebView2 control
|
||||
on Windows.
|
||||
|
||||
This allows you to specify a custom location for the WebView2Loader.dll as
|
||||
well as a non-default location for storing user data for the browser instance.
|
||||
|
||||
@param unloadPageWhenBrowserIsHidden if this is true, then when the browser
|
||||
component is taken offscreen, it'll clear the current page
|
||||
and replace it with a blank page - this can be handy to stop
|
||||
the browser using resources in the background when it's not
|
||||
actually being used.
|
||||
@param dllLocation the path to WebView2Loader.dll, if this is empty then the default
|
||||
system DLL search paths will be used
|
||||
@param userDataFolder a directory in which the WebView2 user data will be stored, if
|
||||
this is empty then a directory will be created next to the
|
||||
executable
|
||||
@param preferences a set of preferences used to control aspects of the webview's
|
||||
behaviour.
|
||||
|
||||
@see WebView2Preferences
|
||||
*/
|
||||
WindowsWebView2WebBrowserComponent (bool unloadPageWhenBrowserIsHidden = true,
|
||||
const WebView2Preferences& preferences = {});
|
||||
|
||||
// This constructor has been deprecated. Use the new constructor that takes a
|
||||
// WebView2Preferences instead.
|
||||
explicit WindowsWebView2WebBrowserComponent (bool unloadPageWhenBrowserIsHidden = true,
|
||||
const File& dllLocation = {},
|
||||
const File& userDataFolder = {})
|
||||
: WebBrowserComponent (unloadPageWhenBrowserIsHidden, dllLocation, userDataFolder)
|
||||
: WindowsWebView2WebBrowserComponent (unloadPageWhenBrowserIsHidden,
|
||||
WebView2Preferences().withDLLLocation (dllLocation)
|
||||
.withUserDataFolder (userDataFolder))
|
||||
{
|
||||
}
|
||||
};
|
||||
|
|
|
|||
|
|
@ -592,13 +592,6 @@ WebBrowserComponent::WebBrowserComponent (const bool unloadWhenHidden)
|
|||
addAndMakeVisible (browser.get());
|
||||
}
|
||||
|
||||
WebBrowserComponent::WebBrowserComponent (bool unloadWhenHidden,
|
||||
const File&,
|
||||
const File&)
|
||||
: WebBrowserComponent (unloadWhenHidden)
|
||||
{
|
||||
}
|
||||
|
||||
WebBrowserComponent::~WebBrowserComponent()
|
||||
{
|
||||
}
|
||||
|
|
|
|||
|
|
@ -917,13 +917,6 @@ WebBrowserComponent::WebBrowserComponent (const bool unloadWhenHidden)
|
|||
browser->init();
|
||||
}
|
||||
|
||||
WebBrowserComponent::WebBrowserComponent (bool unloadWhenHidden,
|
||||
const File&,
|
||||
const File&)
|
||||
: WebBrowserComponent (unloadWhenHidden)
|
||||
{
|
||||
}
|
||||
|
||||
WebBrowserComponent::~WebBrowserComponent()
|
||||
{
|
||||
}
|
||||
|
|
|
|||
|
|
@ -684,13 +684,6 @@ WebBrowserComponent::WebBrowserComponent (bool unloadWhenHidden)
|
|||
addAndMakeVisible (browser.get());
|
||||
}
|
||||
|
||||
WebBrowserComponent::WebBrowserComponent (bool unloadWhenHidden,
|
||||
const File&,
|
||||
const File&)
|
||||
: WebBrowserComponent (unloadWhenHidden)
|
||||
{
|
||||
}
|
||||
|
||||
WebBrowserComponent::~WebBrowserComponent()
|
||||
{
|
||||
}
|
||||
|
|
|
|||
|
|
@ -342,11 +342,12 @@ class WebView2 : public InternalWebViewType,
|
|||
public ComponentMovementWatcher
|
||||
{
|
||||
public:
|
||||
WebView2 (WebBrowserComponent& o, const File& dllLocation, const File& userDataFolder)
|
||||
WebView2 (WebBrowserComponent& o, const WebView2Preferences& prefs)
|
||||
: ComponentMovementWatcher (&o),
|
||||
owner (o)
|
||||
owner (o),
|
||||
preferences (prefs)
|
||||
{
|
||||
if (! createWebViewEnvironment (dllLocation, userDataFolder))
|
||||
if (! createWebViewEnvironment())
|
||||
throw std::runtime_error ("Failed to create the CoreWebView2Environemnt");
|
||||
|
||||
owner.addAndMakeVisible (this);
|
||||
|
|
@ -604,13 +605,38 @@ private:
|
|||
}
|
||||
}
|
||||
|
||||
bool createWebViewEnvironment (const File& dllLocation, const File& userDataFolder)
|
||||
void setWebViewPreferences()
|
||||
{
|
||||
ComSmartPtr<ICoreWebView2Controller2> controller2;
|
||||
webViewController->QueryInterface (controller2.resetAndGetPointerAddress());
|
||||
|
||||
if (controller2 != nullptr)
|
||||
{
|
||||
const auto bgColour = preferences.getBackgroundColour();
|
||||
|
||||
controller2->put_DefaultBackgroundColor ({ (BYTE) bgColour.getAlpha(),
|
||||
(BYTE) bgColour.getRed(),
|
||||
(BYTE) bgColour.getGreen(),
|
||||
(BYTE) bgColour.getBlue() });
|
||||
}
|
||||
|
||||
ComSmartPtr<ICoreWebView2Settings> settings;
|
||||
webView->get_Settings (settings.resetAndGetPointerAddress());
|
||||
|
||||
if (settings == nullptr)
|
||||
{
|
||||
settings->put_IsStatusBarEnabled (! preferences.getIsStatusBarDisabled());
|
||||
settings->put_IsBuiltInErrorPageEnabled (! preferences.getIsBuiltInErrorPageDisabled());
|
||||
}
|
||||
}
|
||||
|
||||
bool createWebViewEnvironment()
|
||||
{
|
||||
using CreateWebViewEnvironmentWithOptionsFunc = HRESULT (*) (PCWSTR, PCWSTR,
|
||||
ICoreWebView2EnvironmentOptions*,
|
||||
ICoreWebView2CreateCoreWebView2EnvironmentCompletedHandler*);
|
||||
|
||||
auto dllPath = dllLocation.getFullPathName();
|
||||
auto dllPath = preferences.getDLLLocation().getFullPathName();
|
||||
|
||||
if (dllPath.isEmpty())
|
||||
dllPath = "WebView2Loader.dll";
|
||||
|
|
@ -630,9 +656,10 @@ private:
|
|||
}
|
||||
|
||||
auto options = Microsoft::WRL::Make<CoreWebView2EnvironmentOptions>();
|
||||
const auto userDataFolder = preferences.getUserDataFolder().getFullPathName();
|
||||
|
||||
auto hr = createWebViewEnvironmentWithOptions (nullptr,
|
||||
userDataFolder != File() ? userDataFolder.getFullPathName().toWideCharPointer() : nullptr,
|
||||
userDataFolder.isNotEmpty() ? userDataFolder.toWideCharPointer() : nullptr,
|
||||
options.Get(),
|
||||
Callback<ICoreWebView2CreateCoreWebView2EnvironmentCompletedHandler>(
|
||||
[weakThis = WeakReference<WebView2> { this }] (HRESULT, ICoreWebView2Environment* env) -> HRESULT
|
||||
|
|
@ -667,11 +694,15 @@ private:
|
|||
weakThis->webViewController = controller;
|
||||
controller->get_CoreWebView2 (weakThis->webView.resetAndGetPointerAddress());
|
||||
|
||||
weakThis->addEventHandlers();
|
||||
weakThis->componentMovedOrResized (true, true);
|
||||
if (weakThis->webView != nullptr)
|
||||
{
|
||||
weakThis->addEventHandlers();
|
||||
weakThis->setWebViewPreferences();
|
||||
weakThis->componentMovedOrResized (true, true);
|
||||
|
||||
if (weakThis->webView != nullptr && weakThis->urlRequest.url.isNotEmpty())
|
||||
weakThis->webView->Navigate (weakThis->urlRequest.url.toWideCharPointer());
|
||||
if (weakThis->urlRequest.url.isNotEmpty())
|
||||
weakThis->webView->Navigate (weakThis->urlRequest.url.toWideCharPointer());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -715,6 +746,7 @@ private:
|
|||
|
||||
//==============================================================================
|
||||
WebBrowserComponent& owner;
|
||||
WebView2Preferences preferences;
|
||||
|
||||
HMODULE webView2LoaderHandle = nullptr;
|
||||
|
||||
|
|
@ -734,6 +766,7 @@ private:
|
|||
StringArray headers;
|
||||
MemoryBlock postData;
|
||||
};
|
||||
|
||||
URLRequest urlRequest;
|
||||
|
||||
bool isCreating = false;
|
||||
|
|
@ -749,20 +782,22 @@ private:
|
|||
class WebBrowserComponent::Pimpl
|
||||
{
|
||||
public:
|
||||
Pimpl (WebBrowserComponent& owner, const File& dllLocation, const File& userDataFolder, bool useWebView2)
|
||||
Pimpl (WebBrowserComponent& owner,
|
||||
const WebView2Preferences& preferences,
|
||||
bool useWebView2)
|
||||
{
|
||||
if (useWebView2)
|
||||
{
|
||||
#if JUCE_USE_WIN_WEBVIEW2
|
||||
try
|
||||
{
|
||||
internal.reset (new WebView2 (owner, dllLocation, userDataFolder));
|
||||
internal.reset (new WebView2 (owner, preferences));
|
||||
}
|
||||
catch (std::runtime_error&) {}
|
||||
catch (const std::runtime_error&) {}
|
||||
#endif
|
||||
}
|
||||
|
||||
ignoreUnused (dllLocation, userDataFolder);
|
||||
ignoreUnused (preferences);
|
||||
|
||||
if (internal == nullptr)
|
||||
internal.reset (new Win32WebView (owner));
|
||||
|
|
@ -779,17 +814,14 @@ private:
|
|||
|
||||
//==============================================================================
|
||||
WebBrowserComponent::WebBrowserComponent (bool unloadWhenHidden)
|
||||
: browser (new Pimpl (*this, {}, {}, false)),
|
||||
: browser (new Pimpl (*this, {}, false)),
|
||||
unloadPageWhenHidden (unloadWhenHidden)
|
||||
{
|
||||
setOpaque (true);
|
||||
}
|
||||
|
||||
WebBrowserComponent::WebBrowserComponent (bool unloadWhenHidden,
|
||||
const File& dllLocation,
|
||||
const File& userDataFolder)
|
||||
: browser (new Pimpl (*this, dllLocation, userDataFolder, true)),
|
||||
unloadPageWhenHidden (unloadWhenHidden)
|
||||
WebBrowserComponent::WebBrowserComponent (ConstructWithoutPimpl args)
|
||||
: unloadPageWhenHidden (args.unloadWhenHidden)
|
||||
{
|
||||
setOpaque (true);
|
||||
}
|
||||
|
|
@ -798,6 +830,13 @@ WebBrowserComponent::~WebBrowserComponent()
|
|||
{
|
||||
}
|
||||
|
||||
WindowsWebView2WebBrowserComponent::WindowsWebView2WebBrowserComponent (bool unloadWhenHidden,
|
||||
const WebView2Preferences& preferences)
|
||||
: WebBrowserComponent (ConstructWithoutPimpl { unloadWhenHidden })
|
||||
{
|
||||
browser = std::make_unique<Pimpl> (*this, preferences, true);
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
void WebBrowserComponent::goToURL (const String& url,
|
||||
const StringArray* headers,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue