Browse Source

more web-ui, macos with init js

Signed-off-by: falkTX <falktx@falktx.com>
web-ui
falkTX 1 year ago
parent
commit
6da9fcdf90
Signed by: falkTX <falktx@falktx.com> GPG Key ID: CDBAA37ABC74FBA0
11 changed files with 140 additions and 91 deletions
  1. +13
    -10
      Makefile.plugins.mk
  2. +3
    -3
      dgl/Web.hpp
  3. +4
    -12
      dgl/src/Web.cpp
  4. +3
    -4
      distrho/DistrhoUI_macOS.mm
  5. +49
    -19
      distrho/extra/WebViewImpl.cpp
  6. +5
    -4
      distrho/extra/WebViewImpl.hpp
  7. +4
    -8
      distrho/src/DistrhoPluginJACK.cpp
  8. +45
    -29
      distrho/src/DistrhoUI.cpp
  9. +1
    -0
      distrho/src/DistrhoUIVST3.cpp
  10. +0
    -1
      examples/WebMeters/DistrhoPluginInfo.h
  11. +13
    -1
      examples/WebMeters/Makefile

+ 13
- 10
Makefile.plugins.mk View File

@@ -238,16 +238,6 @@ endif

ifeq ($(UI_TYPE),web)
DGL_FLAGS += -DDGL_WEB -DHAVE_DGL
ifeq ($(MACOS),true)
# BUILD_CXX_FLAGS += -std=gnu++17
DGL_LIBS += -framework WebKit
else ifeq ($(WINDOWS),true)
# DGL_FLAGS += -std=gnu++17
DGL_LIBS += -lole32 -luuid
else
DGL_FLAGS += -pthread
DGL_LIBS += -pthread -lrt
endif
DGL_LIB = $(DGL_BUILD_DIR)/libdgl-web.a
HAVE_DGL = true
USE_WEBVIEW = true
@@ -271,6 +261,19 @@ ifeq ($(HAVE_DGL)$(LINUX)$(USE_WEBVIEW),truetruetrue)
DGL_LIB_SHARED = $(shell $(CC) -print-file-name=Scrt1.o)
endif

ifeq ($(USE_WEBVIEW),true)
ifeq ($(MACOS),true)
# BUILD_CXX_FLAGS += -std=gnu++17
DGL_LIBS += -framework WebKit
else ifeq ($(WINDOWS),true)
# DGL_FLAGS += -std=gnu++17
DGL_LIBS += -lole32 -luuid
else
DGL_FLAGS += -pthread
DGL_LIBS += -pthread -lrt
endif
endif

DGL_LIBS += $(DGL_SYSTEM_LIBS) -lm

# TODO split dsp and ui object build flags


+ 3
- 3
dgl/Web.hpp View File

@@ -43,20 +43,20 @@ public:
/**
Constructor for a WebViewWidget.
*/
explicit WebViewWidget(Window& windowToMapTo, bool initLater = false);
explicit WebViewWidget(Window& windowToMapTo);

/**
Destructor.
*/
~WebViewWidget() override;

void init(const char* url, const char* initialJS);

// webview methods
void evaluateJS(const char* js);
void reload();

protected:
void init(const char* initialJS);

virtual void onMessage(char* message);
void onResize(const ResizeEvent& ev) override;



+ 4
- 12
dgl/src/Web.cpp View File

@@ -28,18 +28,10 @@ START_NAMESPACE_DGL

// --------------------------------------------------------------------------------------------------------------------

WebViewWidget::WebViewWidget(Window& windowToMapTo, bool initLater)
WebViewWidget::WebViewWidget(Window& windowToMapTo)
: TopLevelWidget(windowToMapTo),
webview(initLater ? nullptr : webViewCreate(windowToMapTo.getNativeWindowHandle(),
windowToMapTo.getWidth(),
windowToMapTo.getHeight(),
windowToMapTo.getScaleFactor(),
WebViewOptions(_on_msg, this)))
webview(nullptr)
{
#if !(defined(DISTRHO_OS_MAC) || defined(DISTRHO_OS_WINDOWS))
if (webview != nullptr)
addIdleCallback(this, 1000 / 60);
#endif
}

WebViewWidget::~WebViewWidget()
@@ -53,13 +45,13 @@ WebViewWidget::~WebViewWidget()
}
}

void WebViewWidget::init(const char* const initialJS)
void WebViewWidget::init(const char* const url, const char* const initialJS)
{
DISTRHO_SAFE_ASSERT_RETURN(webview == nullptr,);

WebViewOptions options(_on_msg, this);
options.initialJS = initialJS;
webview = webViewCreate(getWindow().getNativeWindowHandle(), getWidth(), getHeight(), getScaleFactor(), options);
webview = webViewCreate(url, getWindow().getNativeWindowHandle(), getWidth(), getHeight(), getScaleFactor(), options);

// FIXME implement initialJS
if (webview != nullptr)


+ 3
- 4
distrho/DistrhoUI_macOS.mm View File

@@ -44,9 +44,9 @@ END_NAMESPACE_DISTRHO
# include "extra/WebViewImpl.cpp"
#endif

#if DISTRHO_PLUGIN_HAS_EXTERNAL_UI
# include <algorithm>
# include <cmath>
#include <algorithm>
#include <cmath>
START_NAMESPACE_DISTRHO
double getDesktopScaleFactor(const uintptr_t parentWindowHandle)
{
@@ -61,4 +61,3 @@ double getDesktopScaleFactor(const uintptr_t parentWindowHandle)
return [NSScreen mainScreen].backingScaleFactor;
}
END_NAMESPACE_DISTRHO
#endif

+ 49
- 19
distrho/extra/WebViewImpl.cpp View File

@@ -406,7 +406,8 @@ static void getFilenameFromFunctionPtr(char filename[PATH_MAX], const void* cons

// -----------------------------------------------------------------------------------------------------------

WebViewHandle webViewCreate(const uintptr_t windowId,
WebViewHandle webViewCreate(const char* const url,
const uintptr_t windowId,
const uint initialWidth,
const uint initialHeight,
const double scaleFactor,
@@ -464,11 +465,6 @@ WebViewHandle webViewCreate(const uintptr_t windowId,
#elif WEB_VIEW_USING_MACOS_WEBKIT
NSView* const view = reinterpret_cast<NSView*>(windowId);

const CGRect rect = CGRectMake(options.offset.x,
options.offset.y,
(initialWidth - options.offset.x),
(initialHeight - options.offset.y));

WKPreferences* const prefs = [[WKPreferences alloc] init];
[prefs setValue:@YES forKey:@"javaScriptCanAccessClipboard"];
[prefs setValue:@YES forKey:@"DOMPasteAllowed"];
@@ -483,6 +479,11 @@ WebViewHandle webViewCreate(const uintptr_t windowId,
config.limitsNavigationsToAppBoundDomains = false;
config.preferences = prefs;

const CGRect rect = CGRectMake(options.offset.x / scaleFactor,
options.offset.y / scaleFactor,
initialWidth,
initialHeight);

WKWebView* const webview = [[WKWebView alloc] initWithFrame:rect
configuration:config];
[webview setHidden:YES];
@@ -495,31 +496,61 @@ WebViewHandle webViewCreate(const uintptr_t windowId,
delegate->callbackPtr = options.callbackPtr;
delegate->loaded = false;

webview.navigationDelegate = delegate;
webview.UIDelegate = delegate;

if (WKUserContentController* const controller = [config userContentController])
{
[controller retain];
[controller addScriptMessageHandler:delegate name:@"external"];
if (options.initialJS != nullptr)
{
NSString* const nsInitialJS = [[NSString alloc] initWithBytes:options.initialJS
length:std::strlen(options.initialJS)
encoding:NSUTF8StringEncoding];

WKUserScript* const script = [[WKUserScript alloc] initWithSource:nsInitialJS
injectionTime:WKUserScriptInjectionTimeAtDocumentStart
forMainFrameOnly:true];

[controller addUserScript:script];

[script release];
[nsInitialJS release];
}
}

const char* const url = "file:///Users/falktx/Source/DISTRHO/DPF/examples/WebMeters/index.html";
[webview setNavigationDelegate:delegate];
[webview setUIDelegate:delegate];

NSString* const nsurl = [[NSString alloc] initWithBytes:url
length:std::strlen(url)
encoding:NSUTF8StringEncoding];
NSURLRequest* const urlreq = [[NSURLRequest alloc] initWithURL: [NSURL URLWithString: nsurl]];

// [webview loadRequest:urlreq];
[webview loadFileRequest:urlreq
allowingReadAccessToURL:[NSURL URLWithString:@"file:///Users/falktx/Source/DISTRHO/DPF/examples/WebMeters/"]];
d_stdout("url is '%s'", url);
if (std::strncmp(url, "file://", 7) == 0)
{
const char* const lastsep = std::strrchr(url + 7, '/');

NSString* const urlpath = [[NSString alloc] initWithBytes:url
length:(lastsep - url)
encoding:NSUTF8StringEncoding];

[webview loadFileRequest:urlreq
allowingReadAccessToURL:[NSURL URLWithString:urlpath]];

[urlpath release];
}
else
{
[webview loadRequest:urlreq];
}

d_stdout("waiting for load");

if (! delegate->loaded)
{
NSAutoreleasePool* const pool = [[NSAutoreleasePool alloc] init];
NSDate* const date = [NSDate distantFuture];
NSDate* const date = [NSDate dateWithTimeIntervalSinceNow:0.05];
NSEvent* event;

while (! delegate->loaded)
@@ -702,7 +733,7 @@ void webViewDestroy(const WebViewHandle handle)
[handle->webview setHidden:YES];
[handle->webview removeFromSuperview];
[handle->urlreq release];
[handle->delegate release];
// [handle->delegate release];
#elif WEB_VIEW_USING_X11_IPC
munmap(handle->shmptr, sizeof(WebViewRingBuffer));
close(handle->shmfd);
@@ -804,16 +835,15 @@ void webViewResize(const WebViewHandle handle, const uint width, const uint heig
#if WEB_VIEW_USING_CHOC
#ifdef DISTRHO_OS_MAC
NSView* const view = static_cast<NSView*>(handle->webview->getViewHandle());
[view setFrameSize:NSMakeSize(width, height)];
[view setFrameSize:NSMakeSize(width / scaleFactor, height / scaleFactor)];
#else
const HWND hwnd = static_cast<HWND>(handle->webview->getViewHandle());
SetWindowPos(hwnd, nullptr, 0, 0,
width * scaleFactor,
height * scaleFactor,
width, height,
SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOZORDER);
#endif
#elif WEB_VIEW_USING_MACOS_WEBKIT
[handle->webview setFrameSize:NSMakeSize(width, height)];
[handle->webview setFrameSize:NSMakeSize(width / scaleFactor, height / scaleFactor)];
#elif WEB_VIEW_USING_X11_IPC
if (handle->childWindow == 0)
{


+ 5
- 4
distrho/extra/WebViewImpl.hpp View File

@@ -35,10 +35,10 @@ struct WebViewOptions {
Position offset, for cases of mixing regular widgets with web views.
*/
struct PositionOffset {
/** Horizontal offset */
/** Horizontal offset, with scale factor pre-applied */
int x;

/** Vertical offset */
/** Vertical offset, with scale factor pre-applied */
int y;

/** Constructor for default values */
@@ -83,10 +83,11 @@ struct WebViewOptions {
Provided metrics must not have scale factor pre-applied.

@p windowId: The native window id to attach this view to (X11 Window, HWND or NSView*)
@p scaleFactor: Scale factor to use (ignored on macOS)
@p scaleFactor: Scale factor in use
@p options: Extra options, optional
*/
WebViewHandle webViewCreate(uintptr_t windowId,
WebViewHandle webViewCreate(const char* url,
uintptr_t windowId,
uint initialWidth,
uint initialHeight,
double scaleFactor,


+ 4
- 8
distrho/src/DistrhoPluginJACK.cpp View File

@@ -980,15 +980,11 @@ int main(int argc, char* argv[])
String tmpPath(getBinaryFilename());
tmpPath.truncate(tmpPath.rfind(DISTRHO_OS_SEP));
#if defined(DISTRHO_OS_MAC)
if (tmpPath.endsWith("/MacOS"))
if (tmpPath.endsWith("/Contents/MacOS"))
{
tmpPath.truncate(tmpPath.rfind('/'));
if (tmpPath.endsWith("/Contents"))
{
tmpPath.truncate(tmpPath.rfind('/'));
bundlePath = tmpPath;
d_nextBundlePath = bundlePath.buffer();
}
tmpPath.truncate(tmpPath.length() - 15);
bundlePath = tmpPath;
d_nextBundlePath = bundlePath.buffer();
}
#else
#ifdef DISTRHO_OS_WINDOWS


+ 45
- 29
distrho/src/DistrhoUI.cpp View File

@@ -15,8 +15,8 @@
*/

#include "DistrhoDetails.hpp"
#include "DistrhoPluginUtils.hpp"
#include "src/DistrhoPluginChecks.h"
#include "src/DistrhoDefines.h"

#include <cstddef>

@@ -88,7 +88,6 @@ uintptr_t g_nextWindowId = 0;
double g_nextScaleFactor = 1.0;
#endif

#if DISTRHO_PLUGIN_HAS_EXTERNAL_UI
/* ------------------------------------------------------------------------------------------------------------
* get global scale factor */

@@ -101,23 +100,23 @@ static double getDesktopScaleFactor(const uintptr_t parentWindowHandle)
if (const char* const scale = getenv("DPF_SCALE_FACTOR"))
return std::max(1.0, std::atof(scale));

#if defined(DISTRHO_OS_WINDOWS)
#if defined(DISTRHO_OS_WINDOWS)
if (const HMODULE Shcore = LoadLibraryA("Shcore.dll"))
{
typedef HRESULT(WINAPI* PFN_GetProcessDpiAwareness)(HANDLE, DWORD*);
typedef HRESULT(WINAPI* PFN_GetScaleFactorForMonitor)(HMONITOR, DWORD*);

# if defined(__GNUC__) && (__GNUC__ >= 9)
# pragma GCC diagnostic push
# pragma GCC diagnostic ignored "-Wcast-function-type"
# endif
#if defined(__GNUC__) && (__GNUC__ >= 9)
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wcast-function-type"
#endif
const PFN_GetProcessDpiAwareness GetProcessDpiAwareness
= (PFN_GetProcessDpiAwareness)GetProcAddress(Shcore, "GetProcessDpiAwareness");
const PFN_GetScaleFactorForMonitor GetScaleFactorForMonitor
= (PFN_GetScaleFactorForMonitor)GetProcAddress(Shcore, "GetScaleFactorForMonitor");
# if defined(__GNUC__) && (__GNUC__ >= 9)
# pragma GCC diagnostic pop
# endif
#if defined(__GNUC__) && (__GNUC__ >= 9)
#pragma GCC diagnostic pop
#endif

DWORD dpiAware = 0;
DWORD scaleFactor = 100;
@@ -133,7 +132,7 @@ static double getDesktopScaleFactor(const uintptr_t parentWindowHandle)
FreeLibrary(Shcore);
return static_cast<double>(scaleFactor) / 100.0;
}
#elif defined(HAVE_X11)
#elif defined(HAVE_X11)
::Display* const display = XOpenDisplay(nullptr);
DISTRHO_SAFE_ASSERT_RETURN(display != nullptr, 1.0);

@@ -164,7 +163,7 @@ static double getDesktopScaleFactor(const uintptr_t parentWindowHandle)

XCloseDisplay(display);
return dpi / 96;
#endif
#endif

return 1.0;

@@ -173,8 +172,6 @@ static double getDesktopScaleFactor(const uintptr_t parentWindowHandle)
}
#endif // !DISTRHO_OS_MAC

#endif

/* ------------------------------------------------------------------------------------------------------------
* UI::PrivateData special handling */

@@ -188,7 +185,6 @@ PluginWindow&
UI::PrivateData::createNextWindow(UI* const ui, uint width, uint height, const bool adjustForScaleFactor)
{
UI::PrivateData* const pData = s_nextPrivateData;
#if DISTRHO_PLUGIN_HAS_EXTERNAL_UI
const double scaleFactor = d_isNotZero(pData->scaleFactor) ? pData->scaleFactor : getDesktopScaleFactor(pData->winId);

if (adjustForScaleFactor && d_isNotZero(scaleFactor) && d_isNotEqual(scaleFactor, 1.0))
@@ -197,6 +193,7 @@ UI::PrivateData::createNextWindow(UI* const ui, uint width, uint height, const b
height *= scaleFactor;
}

#if DISTRHO_PLUGIN_HAS_EXTERNAL_UI
pData->window = new PluginWindow(ui, pData->app);
ExternalWindow::PrivateData ewData;
ewData.parentWindowHandle = pData->winId;
@@ -207,14 +204,7 @@ UI::PrivateData::createNextWindow(UI* const ui, uint width, uint height, const b
ewData.isStandalone = DISTRHO_UI_IS_STANDALONE;
return ewData;
#else
const double scaleFactor = pData->scaleFactor;

if (adjustForScaleFactor && d_isNotZero(scaleFactor) && d_isNotEqual(scaleFactor, 1.0))
{
width *= scaleFactor;
height *= scaleFactor;
}

d_stdout("createNextWindow %u %u %f %d", width, height, scaleFactor, adjustForScaleFactor);
pData->window = new PluginWindow(ui, pData->app, pData->winId, width, height, scaleFactor);

// If there are no callbacks, this is most likely a temporary window, so ignore idle callbacks
@@ -246,11 +236,7 @@ UI::UI(const uint width, const uint height, const bool automaticallyScaleAndSetA
#else
false
#endif
)
#if DISTRHO_UI_WEB_VIEW
, true
#endif
),
)),
uiData(UI::PrivateData::s_nextPrivateData)
{
#if !DISTRHO_PLUGIN_HAS_EXTERNAL_UI
@@ -273,7 +259,37 @@ UI::UI(const uint width, const uint height, const bool automaticallyScaleAndSetA
#endif

#if DISTRHO_UI_WEB_VIEW
init(
String path(uiData->bundlePath);

if (path.isNotEmpty())
{
// FIXME get resource path
#ifdef DISTRHO_OS_MAC
path += "/Contents/Resources";
#endif
}
else
{
path = getBinaryFilename();
path.truncate(path.rfind(DISTRHO_OS_SEP));
#ifdef DISTRHO_OS_WINDOWS
// TODO make valid URL
#endif
#ifdef DISTRHO_OS_MAC
if (path.endsWith("/Contents/MacOS"))
{
path.truncate(path.length() - 5);
path += "Resources";
}
else
#endif
{
path += "/resources";
}
// TODO encode for HTML URL
}

init("file://" + path + "/index.html",
"editParameter=function(index,started){window.webkit.messageHandlers.external.postMessage('editparam '+index+' '+(started ? 1 : 0))};"
"setParameterValue=function(index,value){window.webkit.messageHandlers.external.postMessage('setparam '+index+' '+value)};"
#if DISTRHO_PLUGIN_WANT_STATE


+ 1
- 0
distrho/src/DistrhoUIVST3.cpp View File

@@ -1636,6 +1636,7 @@ v3_plugin_view** dpf_plugin_view_create(v3_host_application** const host,
void* const instancePointer,
const double sampleRate)
{
g_nextBundlePath = d_nextBundlePath;
dpf_plugin_view** const viewptr = new dpf_plugin_view*;
*viewptr = new dpf_plugin_view(host, instancePointer, sampleRate);
return static_cast<v3_plugin_view**>(static_cast<void*>(viewptr));


+ 0
- 1
examples/WebMeters/DistrhoPluginInfo.h View File

@@ -39,6 +39,5 @@

#define DISTRHO_UI_DEFAULT_WIDTH 100
#define DISTRHO_UI_DEFAULT_HEIGHT 500
#define kVerticalOffset 0

#endif // DISTRHO_PLUGIN_INFO_H_INCLUDED

+ 13
- 1
examples/WebMeters/Makefile View File

@@ -51,6 +51,18 @@ TARGETS += au

endif # HAVE_OPENGL

all: $(TARGETS)
ifeq ($(MACOS_APP_BUNDLE),true)
jackfiles += $(TARGET_DIR)/$(NAME).app/Contents/Resources/index.html
else
jackfiles += $(TARGET_DIR)/resources/index.html
endif

vst3files += $(TARGET_DIR)/$(NAME).vst3/Contents/Resources/index.html

all: $(TARGETS) $(jackfiles) $(vst3files)

%/index.html: index.html
-$(SILENT)$(shell mkdir -p "$(shell dirname $(abspath $@))")
install -m 644 $< $(abspath $@)

# --------------------------------------------------------------

Loading…
Cancel
Save