macOS: Use public API for fullscreen in wxWebView
To enable fullscreen support with WKWebView private API which was available since macOS 10.11 was used. Beginning with macOS 12.1 this resulted in unpredictable layout issues inside the webview. This reimplementation using java script and message handlers does only use public API. This also makes the fullscreen message more controlable as the webview does no longer put the containing window in fullscreen mode without application code intervention. That also unifies macOS with the way Edge sends this event in MSW. Closes https://github.com/wxWidgets/wxWidgets/pull/2629
This commit is contained in:
parent
c864c9119b
commit
a5cec42bb6
@ -306,6 +306,7 @@ WebFrame::WebFrame(const wxString& url) :
|
|||||||
// set the frame icon
|
// set the frame icon
|
||||||
SetIcon(wxICON(sample));
|
SetIcon(wxICON(sample));
|
||||||
SetTitle("wxWebView Sample");
|
SetTitle("wxWebView Sample");
|
||||||
|
EnableFullScreenView(); // Enable native fullscreen API on macOS
|
||||||
|
|
||||||
wxBoxSizer* topsizer = new wxBoxSizer(wxVERTICAL);
|
wxBoxSizer* topsizer = new wxBoxSizer(wxVERTICAL);
|
||||||
|
|
||||||
|
@ -124,11 +124,6 @@ bool wxWebViewWebKit::Create(wxWindow *parent,
|
|||||||
NSRect r = wxOSXGetFrameForControl( this, pos , size ) ;
|
NSRect r = wxOSXGetFrameForControl( this, pos , size ) ;
|
||||||
WKWebViewConfiguration* webViewConfig = [[WKWebViewConfiguration alloc] init];
|
WKWebViewConfiguration* webViewConfig = [[WKWebViewConfiguration alloc] init];
|
||||||
|
|
||||||
// WebKit API available since macOS 10.11 and iOS 9.0
|
|
||||||
SEL fullScreenSelector = @selector(_setFullScreenEnabled:);
|
|
||||||
if ([webViewConfig.preferences respondsToSelector:fullScreenSelector])
|
|
||||||
[webViewConfig.preferences performSelector:fullScreenSelector withObject:[NSNumber numberWithBool:YES]];
|
|
||||||
|
|
||||||
if (!m_handlers.empty())
|
if (!m_handlers.empty())
|
||||||
{
|
{
|
||||||
#if __MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_13
|
#if __MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_13
|
||||||
@ -171,10 +166,22 @@ bool wxWebViewWebKit::Create(wxWindow *parent,
|
|||||||
|
|
||||||
[m_webView setUIDelegate:uiDelegate];
|
[m_webView setUIDelegate:uiDelegate];
|
||||||
|
|
||||||
// WebKit API available since macOS 10.13 and iOS 11.0
|
// Implement javascript fullscreen interface with user script and message handler
|
||||||
SEL fullScreenDelegateSelector = @selector(_setFullscreenDelegate:);
|
AddUserScript("\
|
||||||
if ([m_webView respondsToSelector:fullScreenDelegateSelector])
|
document.__wxToggleFullscreen = function (elem) { \
|
||||||
[m_webView performSelector:fullScreenDelegateSelector withObject:uiDelegate];
|
document.fullscreenElement = elem; \
|
||||||
|
window.webkit.messageHandlers.__wxfullscreen.postMessage((elem) ? 1: 0); \
|
||||||
|
document.dispatchEvent(new Event('fullscreenchange')); \
|
||||||
|
}; \
|
||||||
|
Element.prototype.requestFullscreen = function() {document.__wxToggleFullscreen(this);}; \
|
||||||
|
Element.prototype.webkitRequestFullscreen = Element.prototype.requestFullscreen; \
|
||||||
|
document.exitFullscreen = function() {document.__wxToggleFullscreen(undefined);}; \
|
||||||
|
document.webkitExitFullscreen = document.exitFullscreen; \
|
||||||
|
document.onfullscreenchange = null; \
|
||||||
|
document.fullscreenEnabled = true; \
|
||||||
|
");
|
||||||
|
[m_webView.configuration.userContentController addScriptMessageHandler:
|
||||||
|
[[WebViewScriptMessageHandler alloc] initWithWxWindow:this] name:@"__wxfullscreen"];
|
||||||
|
|
||||||
m_UIDelegate = uiDelegate;
|
m_UIDelegate = uiDelegate;
|
||||||
|
|
||||||
@ -978,25 +985,6 @@ WX_API_AVAILABLE_MACOS(10, 12)
|
|||||||
webKitWindow->Print();
|
webKitWindow->Print();
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)SendFullscreenChangedEvent:(int)status
|
|
||||||
{
|
|
||||||
wxWebViewEvent event(wxEVT_WEBVIEW_FULLSCREEN_CHANGED, webKitWindow->GetId(),
|
|
||||||
webKitWindow->GetCurrentURL(), wxString());
|
|
||||||
event.SetEventObject(webKitWindow);
|
|
||||||
event.SetInt(status);
|
|
||||||
webKitWindow->HandleWindowEvent(event);
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)_webViewDidEnterFullscreen:(WKWebView *)webView
|
|
||||||
{
|
|
||||||
[self SendFullscreenChangedEvent:1];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)_webViewDidExitFullscreen:(WKWebView *)webView
|
|
||||||
{
|
|
||||||
[self SendFullscreenChangedEvent:0];
|
|
||||||
}
|
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
@implementation WebViewScriptMessageHandler
|
@implementation WebViewScriptMessageHandler
|
||||||
@ -1013,6 +1001,17 @@ WX_API_AVAILABLE_MACOS(10, 12)
|
|||||||
- (void)userContentController:(nonnull WKUserContentController *)userContentController
|
- (void)userContentController:(nonnull WKUserContentController *)userContentController
|
||||||
didReceiveScriptMessage:(nonnull WKScriptMessage *)message
|
didReceiveScriptMessage:(nonnull WKScriptMessage *)message
|
||||||
{
|
{
|
||||||
|
// Handle internal fullscreen message independent of user message handlers
|
||||||
|
if ([message.name isEqualToString:@"__wxfullscreen"])
|
||||||
|
{
|
||||||
|
wxWebViewEvent event(wxEVT_WEBVIEW_FULLSCREEN_CHANGED, webKitWindow->GetId(),
|
||||||
|
webKitWindow->GetCurrentURL(), wxString());
|
||||||
|
event.SetEventObject(webKitWindow);
|
||||||
|
event.SetInt(((NSNumber*)message.body).intValue);
|
||||||
|
webKitWindow->HandleWindowEvent(event);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
wxWebViewEvent event(wxEVT_WEBVIEW_SCRIPT_MESSAGE_RECEIVED,
|
wxWebViewEvent event(wxEVT_WEBVIEW_SCRIPT_MESSAGE_RECEIVED,
|
||||||
webKitWindow->GetId(),
|
webKitWindow->GetId(),
|
||||||
webKitWindow->GetCurrentURL(),
|
webKitWindow->GetCurrentURL(),
|
||||||
|
Loading…
Reference in New Issue
Block a user