mirror of
https://github.com/space-wizards/RobustToolbox.git
synced 2026-02-15 03:30:53 +01:00
Initial macOS WebView support
This is a gigantic kerfuffle because Chromium expects a very specific directory & app bundle layout. Have to change a bunch of resource loading code to account for content development being launched from an app bundle, and also had to make automatic MSBuild tooling & a python script to generate such an app bundle
This commit is contained in:
@@ -1,7 +1,9 @@
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.Globalization;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Threading;
|
||||
using Robust.Shared.ContentPack;
|
||||
using Xilium.CefGlue;
|
||||
|
||||
namespace Robust.Client.WebView.Cef
|
||||
@@ -20,6 +22,20 @@ namespace Robust.Client.WebView.Cef
|
||||
argv[0] = "-";
|
||||
}
|
||||
|
||||
#if MACOS
|
||||
NativeLibrary.SetDllImportResolver(typeof(CefSettings).Assembly,
|
||||
(name, assembly, path) =>
|
||||
{
|
||||
if (name == "libcef")
|
||||
{
|
||||
var libPath = PathHelpers.ExecutableRelativeFile("../../../../Frameworks/Chromium Embedded Framework.framework/Chromium Embedded Framework");
|
||||
return NativeLibrary.Load(libPath, assembly, path);
|
||||
}
|
||||
|
||||
return 0;
|
||||
});
|
||||
#endif
|
||||
|
||||
var mainArgs = new CefMainArgs(argv);
|
||||
|
||||
StartWatchThread();
|
||||
|
||||
@@ -17,11 +17,13 @@ namespace Robust.Client.WebView.Cef
|
||||
{
|
||||
internal partial class WebViewManagerCef
|
||||
{
|
||||
private readonly List<ControlImpl> _activeControls = new();
|
||||
|
||||
public IWebViewControlImpl MakeControlImpl(WebViewControl owner)
|
||||
{
|
||||
var shader = _prototypeManager.Index<ShaderPrototype>("bgra");
|
||||
var shaderInstance = shader.Instance();
|
||||
var impl = new ControlImpl(owner, shaderInstance);
|
||||
var impl = new ControlImpl(this, owner, shaderInstance);
|
||||
_dependencyCollection.InjectDependencies(impl);
|
||||
return impl;
|
||||
}
|
||||
@@ -133,11 +135,13 @@ namespace Robust.Client.WebView.Cef
|
||||
[Dependency] private readonly IClyde _clyde = default!;
|
||||
[Dependency] private readonly IInputManager _inputMgr = default!;
|
||||
|
||||
private readonly WebViewManagerCef _manager;
|
||||
public readonly WebViewControl Owner;
|
||||
private readonly ShaderInstance _shaderInstance;
|
||||
|
||||
public ControlImpl(WebViewControl owner, ShaderInstance shaderInstance)
|
||||
public ControlImpl(WebViewManagerCef manager, WebViewControl owner, ShaderInstance shaderInstance)
|
||||
{
|
||||
_manager = manager;
|
||||
Owner = owner;
|
||||
_shaderInstance = shaderInstance;
|
||||
}
|
||||
@@ -194,6 +198,7 @@ namespace Robust.Client.WebView.Cef
|
||||
var texture = _clyde.CreateBlankTexture<Rgba32>(Vector2i.One);
|
||||
|
||||
_data = new LiveData(texture, client, browser, renderer);
|
||||
_manager._activeControls.Add(this);
|
||||
}
|
||||
|
||||
public void CloseBrowser()
|
||||
@@ -203,6 +208,8 @@ namespace Robust.Client.WebView.Cef
|
||||
_data!.Texture.Dispose();
|
||||
_data.Browser.GetHost().CloseBrowser(true);
|
||||
_data = null;
|
||||
|
||||
_manager._activeControls.Remove(this);
|
||||
}
|
||||
|
||||
public void MouseMove(GUIMouseMoveEventArgs args)
|
||||
@@ -279,6 +286,7 @@ namespace Robust.Client.WebView.Cef
|
||||
|
||||
// Logger.Debug($"{guiRawEvent.Action} {guiRawEvent.Key} {guiRawEvent.ScanCode} {vkKey}");
|
||||
|
||||
#if !MACOS
|
||||
var lParam = 0;
|
||||
lParam |= (guiRawEvent.ScanCode & 0xFF) << 16;
|
||||
if (guiRawEvent.Action != RawKeyAction.Down)
|
||||
@@ -286,7 +294,9 @@ namespace Robust.Client.WebView.Cef
|
||||
|
||||
if (guiRawEvent.Action == RawKeyAction.Up)
|
||||
lParam |= 1 << 31;
|
||||
|
||||
#else
|
||||
var lParam = guiRawEvent.RawCode;
|
||||
#endif
|
||||
var modifiers = CalcModifiers(guiRawEvent.Key);
|
||||
|
||||
host.SendKeyEvent(new CefKeyEvent
|
||||
@@ -307,7 +317,7 @@ namespace Robust.Client.WebView.Cef
|
||||
host.SendKeyEvent(new CefKeyEvent
|
||||
{
|
||||
EventType = CefKeyEventType.Char,
|
||||
WindowsKeyCode = '\r',
|
||||
WindowsKeyCode = '\b',
|
||||
NativeKeyCode = lParam,
|
||||
Modifiers = modifiers
|
||||
});
|
||||
|
||||
@@ -1,11 +1,12 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Net;
|
||||
using System.Reflection;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
using Robust.Client.Console;
|
||||
using Robust.Client.Utility;
|
||||
using Robust.Shared.Configuration;
|
||||
using Robust.Shared.ContentPack;
|
||||
using Robust.Shared.IoC;
|
||||
@@ -47,11 +48,12 @@ namespace Robust.Client.WebView.Cef
|
||||
string subProcessName;
|
||||
if (OperatingSystem.IsWindows())
|
||||
subProcessName = "Robust.Client.WebView.exe";
|
||||
else if (OperatingSystem.IsLinux())
|
||||
else if (OperatingSystem.IsLinux() || OperatingSystem.IsMacOS())
|
||||
subProcessName = "Robust.Client.WebView";
|
||||
else
|
||||
throw new NotSupportedException("Unsupported platform for CEF!");
|
||||
|
||||
#if !MACOS
|
||||
var subProcessPath = Path.Combine(BasePath, subProcessName);
|
||||
var cefResourcesPath = LocateCefResources();
|
||||
_sawmill.Debug($"Subprocess path: {subProcessPath}, resources: {cefResourcesPath}");
|
||||
@@ -60,19 +62,36 @@ namespace Robust.Client.WebView.Cef
|
||||
|
||||
if (cefResourcesPath == null)
|
||||
throw new InvalidOperationException("Unable to locate cef_resources directory!");
|
||||
#endif
|
||||
|
||||
var remoteDebugPort = _cfg.GetCVar(WCVars.WebRemoteDebugPort);
|
||||
|
||||
var cachePath = FindAndLockCacheDirectory();
|
||||
|
||||
#if MACOS
|
||||
NativeLibrary.SetDllImportResolver(typeof(CefSettings).Assembly,
|
||||
(name, assembly, path) =>
|
||||
{
|
||||
if (name == "libcef")
|
||||
{
|
||||
var libPath = PathHelpers.ExecutableRelativeFile("../Frameworks/Chromium Embedded Framework.framework/Chromium Embedded Framework");
|
||||
return NativeLibrary.Load(libPath, assembly, path);
|
||||
}
|
||||
|
||||
return 0;
|
||||
});
|
||||
#endif
|
||||
|
||||
var settings = new CefSettings()
|
||||
{
|
||||
WindowlessRenderingEnabled = true, // So we can render to our UI controls.
|
||||
ExternalMessagePump = false, // Unsure, honestly. TODO CEF: Research this?
|
||||
NoSandbox = true, // Not disabling the sandbox crashes CEF.
|
||||
#if !MACOS
|
||||
BrowserSubprocessPath = subProcessPath,
|
||||
LocalesDirPath = Path.Combine(cefResourcesPath, "locales"),
|
||||
ResourcesDirPath = cefResourcesPath,
|
||||
#endif
|
||||
RemoteDebuggingPort = remoteDebugPort,
|
||||
CookieableSchemesList = "usr,res",
|
||||
CachePath = cachePath,
|
||||
@@ -113,7 +132,6 @@ namespace Robust.Client.WebView.Cef
|
||||
if (ProbeDir(BasePath, out var path))
|
||||
return path;
|
||||
|
||||
|
||||
foreach (var searchDir in NativeDllSearchDirectories())
|
||||
{
|
||||
if (ProbeDir(searchDir, out path))
|
||||
@@ -147,6 +165,16 @@ namespace Robust.Client.WebView.Cef
|
||||
|
||||
public void Shutdown()
|
||||
{
|
||||
foreach (var control in _activeControls.ToArray())
|
||||
{
|
||||
control.CloseBrowser();
|
||||
}
|
||||
|
||||
foreach (var window in _browserWindows.ToArray())
|
||||
{
|
||||
window.Dispose();
|
||||
}
|
||||
|
||||
CefRuntime.Shutdown();
|
||||
}
|
||||
|
||||
|
||||
@@ -8,10 +8,10 @@ internal sealed class TestBrowseWindow : DefaultWindow
|
||||
{
|
||||
protected override Vector2 ContentsMinimumSize => new Vector2(640, 480);
|
||||
|
||||
public TestBrowseWindow()
|
||||
public TestBrowseWindow(string url)
|
||||
{
|
||||
var wv = new WebViewControl();
|
||||
wv.Url = "https://spacestation14.io";
|
||||
wv.Url = url;
|
||||
|
||||
Contents.AddChild(wv);
|
||||
}
|
||||
@@ -23,6 +23,15 @@ internal sealed class TestBrowseWindowCommand : LocalizedCommands
|
||||
|
||||
public override void Execute(IConsoleShell shell, string argStr, string[] args)
|
||||
{
|
||||
new TestBrowseWindow().Open();
|
||||
var url = args.Length > 0 ? args[0] : "https://spacestation14.com";
|
||||
new TestBrowseWindow(url).Open();
|
||||
}
|
||||
|
||||
public override CompletionResult GetCompletion(IConsoleShell shell, string[] args)
|
||||
{
|
||||
if (args.Length == 1)
|
||||
return CompletionResult.FromHint("<url>");
|
||||
|
||||
return CompletionResult.Empty;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user