From c1410b6476316a5f76019a26f0efd028366e86c2 Mon Sep 17 00:00:00 2001 From: falkTX Date: Sun, 5 May 2024 01:56:38 +0200 Subject: [PATCH] add macos web parts, interaction tests with choc Signed-off-by: falkTX --- Makefile.plugins.mk | 1 + dgl/Web.hpp | 10 +- dgl/src/Web.cpp | 13 +- distrho/DistrhoUI.hpp | 6 +- distrho/DistrhoUI_macOS.mm | 12 +- distrho/extra/WebViewImpl.cpp | 421 ++++++++++++++++++++++++------ distrho/extra/WebViewImpl.hpp | 66 ++++- distrho/src/DistrhoPluginChecks.h | 18 +- distrho/src/DistrhoPluginVST2.cpp | 2 +- distrho/src/DistrhoUI.cpp | 36 +++ examples/WebMeters/Makefile | 1 + 11 files changed, 473 insertions(+), 113 deletions(-) diff --git a/Makefile.plugins.mk b/Makefile.plugins.mk index 3a314803..f563d4d7 100644 --- a/Makefile.plugins.mk +++ b/Makefile.plugins.mk @@ -239,6 +239,7 @@ 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 diff --git a/dgl/Web.hpp b/dgl/Web.hpp index 41c6f730..0a30f858 100644 --- a/dgl/Web.hpp +++ b/dgl/Web.hpp @@ -14,8 +14,8 @@ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -#ifndef DGL_WEBVIEW_HPP_INCLUDED -#define DGL_WEBVIEW_HPP_INCLUDED +#ifndef DGL_WEB_VIEW_HPP_INCLUDED +#define DGL_WEB_VIEW_HPP_INCLUDED #include "TopLevelWidget.hpp" @@ -28,6 +28,8 @@ typedef WebViewData* WebViewHandle; END_NAMESPACE_DISTRHO +// -------------------------------------------------------------------------------------------------------------------- + START_NAMESPACE_DGL // -------------------------------------------------------------------------------------------------------------------- @@ -51,7 +53,7 @@ protected: private: const DISTRHO_NAMESPACE::WebViewHandle webview; - void onDisplay() {} + void onDisplay() override {} DISTRHO_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(WebViewWidget) }; @@ -60,4 +62,4 @@ private: END_NAMESPACE_DGL -#endif // DGL_WEBVIEW_HPP_INCLUDED +#endif // DGL_WEB_VIEW_HPP_INCLUDED diff --git a/dgl/src/Web.cpp b/dgl/src/Web.cpp index d49ec6bf..df8662ef 100644 --- a/dgl/src/Web.cpp +++ b/dgl/src/Web.cpp @@ -29,16 +29,15 @@ START_NAMESPACE_DGL WebViewWidget::WebViewWidget(Window& windowToMapTo) : TopLevelWidget(windowToMapTo), - webview(addWebView(windowToMapTo.getNativeWindowHandle(), - 0, 0, - windowToMapTo.getWidth(), - windowToMapTo.getHeight(), - windowToMapTo.getScaleFactor())) {} + webview(webViewCreate(windowToMapTo.getNativeWindowHandle(), + windowToMapTo.getWidth(), + windowToMapTo.getHeight(), + windowToMapTo.getScaleFactor())) {} WebViewWidget::~WebViewWidget() { if (webview != nullptr) - destroyWebView(webview); + webViewDestroy(webview); } void WebViewWidget::onResize(const ResizeEvent& ev) @@ -46,7 +45,7 @@ void WebViewWidget::onResize(const ResizeEvent& ev) TopLevelWidget::onResize(ev); if (webview != nullptr) - resizeWebView(webview, 0, 0, ev.size.getWidth(), ev.size.getHeight()); + webViewResize(webview, ev.size.getWidth(), ev.size.getHeight(), getScaleFactor()); } // ----------------------------------------------------------------------- diff --git a/distrho/DistrhoUI.hpp b/distrho/DistrhoUI.hpp index a6b73d88..f12e319d 100644 --- a/distrho/DistrhoUI.hpp +++ b/distrho/DistrhoUI.hpp @@ -253,14 +253,14 @@ protected: A parameter has changed on the plugin side.@n This is called by the host to inform the UI about parameter changes. */ - virtual void parameterChanged(uint32_t index, float value) = 0; + virtual void parameterChanged(uint32_t index, float value); #if DISTRHO_PLUGIN_WANT_PROGRAMS /** A program has been loaded on the plugin side.@n This is called by the host to inform the UI about program changes. */ - virtual void programLoaded(uint32_t index) = 0; + virtual void programLoaded(uint32_t index); #endif #if DISTRHO_PLUGIN_WANT_STATE @@ -268,7 +268,7 @@ protected: A state has changed on the plugin side.@n This is called by the host to inform the UI about state changes. */ - virtual void stateChanged(const char* key, const char* value) = 0; + virtual void stateChanged(const char* key, const char* value); #endif /* -------------------------------------------------------------------------------------------------------- diff --git a/distrho/DistrhoUI_macOS.mm b/distrho/DistrhoUI_macOS.mm index f2b33593..17bda5f4 100644 --- a/distrho/DistrhoUI_macOS.mm +++ b/distrho/DistrhoUI_macOS.mm @@ -20,7 +20,7 @@ #include "src/DistrhoPluginChecks.h" #include "src/DistrhoDefines.h" -#if DISTRHO_UI_FILE_BROWSER || DISTRHO_PLUGIN_HAS_EXTERNAL_UI +#if DISTRHO_UI_FILE_BROWSER || DISTRHO_UI_WEB_VIEW || DISTRHO_PLUGIN_HAS_EXTERNAL_UI # import #endif @@ -34,6 +34,16 @@ END_NAMESPACE_DISTRHO # include "extra/FileBrowserDialogImpl.cpp" #endif +#if DISTRHO_UI_WEB_VIEW +# define DISTRHO_WEB_VIEW_HPP_INCLUDED +# define WEB_VIEW_NAMESPACE DISTRHO_NAMESPACE +# define WEB_VIEW_DISTRHO_NAMESPACE +START_NAMESPACE_DISTRHO +# include "extra/WebViewImpl.hpp" +END_NAMESPACE_DISTRHO +# include "extra/WebViewImpl.cpp" +#endif + #if DISTRHO_PLUGIN_HAS_EXTERNAL_UI # include # include diff --git a/distrho/extra/WebViewImpl.cpp b/distrho/extra/WebViewImpl.cpp index 25134227..c5547f36 100644 --- a/distrho/extra/WebViewImpl.cpp +++ b/distrho/extra/WebViewImpl.cpp @@ -14,45 +14,45 @@ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -#if !defined(DISTRHO_WEBVIEW_HPP_INCLUDED) && !defined(DGL_WEBVIEW_HPP_INCLUDED) +#if !defined(DISTRHO_WEB_VIEW_HPP_INCLUDED) && !defined(DGL_WEB_VIEW_HPP_INCLUDED) # error bad include #endif -#if !defined(WEBVIEW_DISTRHO_NAMESPACE) && !defined(WEBVIEW_DGL_NAMESPACE) +#if !defined(WEB_VIEW_DISTRHO_NAMESPACE) && !defined(WEB_VIEW_DGL_NAMESPACE) # error bad usage #endif -#define WEBVIEW_USING_CHOC 1 +#define WEB_VIEW_USING_CHOC 0 -#ifndef WEBVIEW_USING_CHOC -# define WEBVIEW_USING_CHOC 0 -#elif WEBVIEW_USING_CHOC && !defined(DISTRHO_OS_WINDOWS) -# undef WEBVIEW_USING_CHOC -# define WEBVIEW_USING_CHOC 0 +#ifndef WEB_VIEW_USING_CHOC +# define WEB_VIEW_USING_CHOC 0 +#elif WEB_VIEW_USING_CHOC && !(defined(DISTRHO_OS_MAC) || defined(DISTRHO_OS_WINDOWS)) +# undef WEB_VIEW_USING_CHOC +# define WEB_VIEW_USING_CHOC 0 #endif -#ifdef DISTRHO_OS_MAC -# undef WEBVIEW_USING_MACOS_WEBKIT -# define WEBVIEW_USING_MACOS_WEBKIT 1 +#if defined(DISTRHO_OS_MAC) && !WEB_VIEW_USING_CHOC +# undef WEB_VIEW_USING_MACOS_WEBKIT +# define WEB_VIEW_USING_MACOS_WEBKIT 1 #else -# undef WEBVIEW_USING_MACOS_WEBKIT -# define WEBVIEW_USING_MACOS_WEBKIT 0 +# undef WEB_VIEW_USING_MACOS_WEBKIT +# define WEB_VIEW_USING_MACOS_WEBKIT 0 #endif -#if defined(HAVE_X11) && !(defined(DISTRHO_OS_MAC) || defined(DISTRHO_OS_WINDOWS)) -# undef WEBVIEW_USING_X11_IPC -# define WEBVIEW_USING_X11_IPC 1 +#if defined(HAVE_X11) && defined(DISTRHO_OS_LINUX) +# undef WEB_VIEW_USING_X11_IPC +# define WEB_VIEW_USING_X11_IPC 1 #else -# undef WEBVIEW_USING_X11_IPC -# define WEBVIEW_USING_X11_IPC 0 +# undef WEB_VIEW_USING_X11_IPC +# define WEB_VIEW_USING_X11_IPC 0 #endif -#if WEBVIEW_USING_CHOC +#if WEB_VIEW_USING_CHOC # define WC_ERR_INVALID_CHARS 0 # include "../CHOC/gui/choc_WebView.h" -#elif WEBVIEW_USING_MACOS_WEBKIT +#elif WEB_VIEW_USING_MACOS_WEBKIT # include # include -#elif WEBVIEW_USING_X11_IPC +#elif WEB_VIEW_USING_X11_IPC // #define QT_NO_VERSION_TAGGING // #include // #include @@ -68,7 +68,122 @@ # include #endif -#ifdef WEBVIEW_DGL_NAMESPACE +// ----------------------------------------------------------------------------------------------------------- + +#if WEB_VIEW_USING_MACOS_WEBKIT + +#define MACRO_NAME2(a, b, c) a ## b ## c +#define MACRO_NAME(a, b, c) MACRO_NAME2(a, b, c) + +#define WEB_VIEW_DELEGATE_CLASS_NAME \ + MACRO_NAME(WebViewDelegate_, _, DISTRHO_NAMESPACE) + +@interface WEB_VIEW_DELEGATE_CLASS_NAME : NSObject +@end + +@implementation WEB_VIEW_DELEGATE_CLASS_NAME + +- (void)webView:(WKWebView*)webview + runJavaScriptAlertPanelWithMessage:(NSString*)message + initiatedByFrame:(WKFrameInfo*)frame + completionHandler:(void (^)(void))completionHandler +{ + NSAlert* const alert = [[NSAlert alloc] init]; + [alert addButtonWithTitle:@"OK"]; + [alert setInformativeText:message]; + [alert setMessageText:@"Alert"]; + + dispatch_async(dispatch_get_main_queue(), ^ + { + [alert beginSheetModalForWindow:[webview window] + completionHandler:^(NSModalResponse) + { + completionHandler(); + [alert release]; + }]; + }); +} + +- (void)webView:(WKWebView*)webview + runJavaScriptConfirmPanelWithMessage:(NSString*)message + initiatedByFrame:(WKFrameInfo*)frame + completionHandler:(void (^)(BOOL))completionHandler +{ + NSAlert* const alert = [[NSAlert alloc] init]; + [alert addButtonWithTitle:@"OK"]; + [alert addButtonWithTitle:@"Cancel"]; + [alert setInformativeText:message]; + [alert setMessageText:@"Confirm"]; + + dispatch_async(dispatch_get_main_queue(), ^ + { + [alert beginSheetModalForWindow:[webview window] + completionHandler:^(NSModalResponse result) + { + completionHandler(result == NSAlertFirstButtonReturn); + [alert release]; + }]; + }); +} + +- (void)webView:(WKWebView*)webview + runJavaScriptTextInputPanelWithPrompt:(NSString*)prompt + defaultText:(NSString*)defaultText + initiatedByFrame:(WKFrameInfo*)frame + completionHandler:(void (^)(NSString*))completionHandler +{ + NSTextField* const input = [[NSTextField alloc] initWithFrame:NSMakeRect(0, 0, 250, 30)]; + [input setStringValue:defaultText]; + + NSAlert* const alert = [[NSAlert alloc] init]; + [alert setAccessoryView:input]; + [alert addButtonWithTitle:@"OK"]; + [alert addButtonWithTitle:@"Cancel"]; + [alert setInformativeText:prompt]; + [alert setMessageText: @"Prompt"]; + + dispatch_async(dispatch_get_main_queue(), ^ + { + [alert beginSheetModalForWindow:[webview window] + completionHandler:^(NSModalResponse result) + { + [input validateEditing]; + completionHandler(result == NSAlertFirstButtonReturn ? [input stringValue] : nil); + [alert release]; + }]; + }); +} + +- (void)webView:(WKWebView*)webview + runOpenPanelWithParameters:(WKOpenPanelParameters*)params + initiatedByFrame:(WKFrameInfo*)frame + completionHandler:(void (^)(NSArray*))completionHandler +{ + NSOpenPanel* const panel = [[NSOpenPanel alloc] init]; + + [panel setAllowsMultipleSelection:[params allowsMultipleSelection]]; + // [panel setAllowedFileTypes:(NSArray*)[params _allowedFileExtensions]]; + [panel setCanChooseDirectories:[params allowsDirectories]]; + [panel setCanChooseFiles:![params allowsDirectories]]; + + dispatch_async(dispatch_get_main_queue(), ^ + { + [panel beginSheetModalForWindow:[webview window] + completionHandler:^(NSModalResponse result) + { + completionHandler(result == NSModalResponseOK ? [panel URLs] : nil); + [panel release]; + }]; + }); +} + +@end + +#endif // WEB_VIEW_USING_MACOS_WEBKIT + +// ----------------------------------------------------------------------------------------------------------- + +#ifdef WEB_VIEW_DGL_NAMESPACE START_NAMESPACE_DGL using DISTRHO_NAMESPACE::String; #else @@ -78,20 +193,69 @@ START_NAMESPACE_DISTRHO // ----------------------------------------------------------------------------------------------------------- struct WebViewData { -#if defined(DISTRHO_OS_MAC) -#elif WEBVIEW_USING_CHOC - choc::ui::WebView* webview; -#elif WEBVIEW_USING_X11_IPC + #if WEB_VIEW_USING_CHOC + choc::ui::WebView* const webview; + #elif WEB_VIEW_USING_MACOS_WEBKIT + NSView* const view; + WKWebView* const webview; + NSURLRequest* const urlreq; + WEB_VIEW_DELEGATE_CLASS_NAME* const delegate; + #elif WEB_VIEW_USING_X11_IPC ChildProcess p; ::Display* display; ::Window childWindow; ::Window ourWindow; -#endif + #endif }; // ----------------------------------------------------------------------------------------------------------- -#if WEBVIEW_USING_X11_IPC +#if WEB_VIEW_USING_CHOC +static std::optional fetch_resource(const std::string& path) +{ + d_stdout("requested path %s", path.c_str()); + + if (path == "/") + { + const std::string html = R"PREFIX( + + + + + + +hello world! + + +)PREFIX"; + const std::vector data(html.begin(), html.end()); + return choc::ui::WebView::Options::Resource{ data, "text/html" }; + } + if (path == "/img.svg") + { + const std::string html = R"PREFIX( + + + + + + + + +)PREFIX"; + const std::vector data(html.begin(), html.end()); + return choc::ui::WebView::Options::Resource{ data, "image/svg+xml" }; + } + + return {}; +} +#elif WEB_VIEW_USING_X11_IPC static void getFilenameFromFunctionPtr(char filename[PATH_MAX], const void* const ptr) { Dl_info info = {}; @@ -115,40 +279,99 @@ static void getFilenameFromFunctionPtr(char filename[PATH_MAX], const void* cons } #endif -WebViewHandle addWebView(const uintptr_t parentWindowId, - const int x, - const int y, - const uint width, - const uint height, - const double scaleFactor) +// ----------------------------------------------------------------------------------------------------------- + +WebViewHandle webViewCreate(const uintptr_t windowId, + const uint initialWidth, + const uint initialHeight, + const double scaleFactor, + const WebViewOptions& options) { -#if defined(DISTRHO_OS_MAC) -#elif WEBVIEW_USING_CHOC - std::unique_ptr webview = std::make_unique(); +#if WEB_VIEW_USING_CHOC + choc::ui::WebView::Options woptions; + woptions.acceptsFirstMouseClick = true; + woptions.enableDebugMode = true; + woptions.fetchResource = fetch_resource; + + std::unique_ptr webview = std::make_unique(woptions); DISTRHO_SAFE_ASSERT_RETURN(webview->loadedOK(), nullptr); - const HWND handle = static_cast(webview->getViewHandle()); + void* const handle = webview->getViewHandle(); DISTRHO_SAFE_ASSERT_RETURN(handle != nullptr, nullptr); - webview->navigate("https://mastodon.falktx.com/"); - - LONG_PTR flags = GetWindowLongPtr(handle, -16); + choc::ui::WebView* const www = webview.get(); + webview->bind("setParameterValue", [www](const choc::value::ValueView&) -> choc::value::Value { + static int pp = 0; + std::string toeval = "typeof(parameterChanged) === 'function' && parameterChanged("; + toeval += std::to_string(++pp); + toeval += ", 0.1)"; + d_stdout("param received | %s", toeval.c_str()); + www->evaluateJavascript(toeval); + return {}; + }); + + #ifdef DISTRHO_OS_MAC + NSView* const view = static_cast(handle); + + [reinterpret_cast(windowId) addSubview:view]; + [view setFrame:NSMakeRect(options.offset.x, + options.offset.y, + DISTRHO_UI_DEFAULT_WIDTH - options.offset.x, + DISTRHO_UI_DEFAULT_HEIGHT - options.offset.y)]; + #else + const HWND hwnd = static_cast(handle); + + LONG_PTR flags = GetWindowLongPtr(hwnd, -16); flags = (flags & ~WS_POPUP) | WS_CHILD; - SetWindowLongPtr(handle, -16, flags); - - SetParent(handle, reinterpret_cast(parentWindowId)); - SetWindowPos(handle, nullptr, - x * scaleFactor, - y * scaleFactor, - (width - x) * scaleFactor, - (height - y) * scaleFactor, + SetWindowLongPtr(hwnd, -16, flags); + + SetParent(hwnd, reinterpret_cast(windowId)); + SetWindowPos(hwnd, nullptr, + options.offset.x * scaleFactor, + options.offset.y * scaleFactor, + (initialWidth - options.offset.x) * scaleFactor, + (initialHeight - options.offset.y) * scaleFactor, SWP_NOZORDER | SWP_NOACTIVATE | SWP_FRAMECHANGED); - ShowWindow(handle, SW_SHOW); + ShowWindow(hwnd, SW_SHOW); + #endif - WebViewData* const wvdata = new WebViewData(); - wvdata->webview = webview.release(); - return wvdata; -#elif WEBVIEW_USING_X11_IPC + return new WebViewData{webview.release()}; +#elif WEB_VIEW_USING_MACOS_WEBKIT + NSView* const view = reinterpret_cast(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:@"developerExtrasEnabled"]; + + WKWebViewConfiguration* const config = [[WKWebViewConfiguration alloc] init]; + config.preferences = prefs; + + WKWebView* const webview = [[WKWebView alloc] initWithFrame:rect + configuration:config]; + [view addSubview:webview]; + + WEB_VIEW_DELEGATE_CLASS_NAME* const delegate = [[WEB_VIEW_DELEGATE_CLASS_NAME alloc] init]; + webview.UIDelegate = delegate; + + const char* const url = "https://mastodon.falktx.com/"; + 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 setHidden:NO]; + + [nsurl release]; + [config release]; + [prefs release]; + + return new WebViewData{view, webview, urlreq, delegate}; +#elif WEB_VIEW_USING_X11_IPC char ldlinux[PATH_MAX] = {}; getFilenameFromFunctionPtr(ldlinux, dlsym(nullptr, "_rtld_global")); @@ -179,8 +402,8 @@ WebViewHandle addWebView(const uintptr_t parentWindowId, } envp[e++] = strdup("LANG=en_US.UTF-8"); - envp[e++] = ("DPF_WEBVIEW_SCALE_FACTOR=" + String(scaleFactor)).getAndReleaseBuffer(); - envp[e++] = ("DPF_WEBVIEW_WIN_ID=" +String(parentWindowId)).getAndReleaseBuffer(); + envp[e++] = ("DPF_WEB_VIEW_SCALE_FACTOR=" + String(scaleFactor)).getAndReleaseBuffer(); + envp[e++] = ("DPF_WEB_VIEW_WIN_ID=" +String(windowId)).getAndReleaseBuffer(); for (uint i = e; i < envsize + 5; ++i) envp[e++] = nullptr; @@ -189,7 +412,7 @@ WebViewHandle addWebView(const uintptr_t parentWindowId, WebViewData* const handle = new WebViewData(); handle->display = display; handle->childWindow = 0; - handle->ourWindow = parentWindowId; + handle->ourWindow = windowId; const char* const args[] = { ldlinux, filename, "dpf-ld-linux-webview", nullptr }; handle->p.start(args, envp); @@ -201,37 +424,64 @@ WebViewHandle addWebView(const uintptr_t parentWindowId, return handle; #endif + // maybe unused + (void)windowId; + (void)initialWidth; + (void)initialHeight; + (void)scaleFactor; + (void)options; return nullptr; } -void destroyWebView(const WebViewHandle handle) +void webViewDestroy(const WebViewHandle handle) { -#if defined(DISTRHO_OS_MAC) -#elif WEBVIEW_USING_CHOC + #if WEB_VIEW_USING_CHOC delete handle->webview; delete handle; -#elif WEBVIEW_USING_X11_IPC + #elif WEB_VIEW_USING_MACOS_WEBKIT + [handle->webview setHidden:YES]; + [handle->webview removeFromSuperview]; + [handle->urlreq release]; + [handle->delegate release]; + delete handle; + #elif WEB_VIEW_USING_X11_IPC XCloseDisplay(handle->display); delete handle; -#endif + #endif + + // maybe unused + (void)handle; } -void reloadWebView(const WebViewHandle handle, uint) +void webViewReload(const WebViewHandle handle) { -#if defined(DISTRHO_OS_MAC) -#elif WEBVIEW_USING_CHOC -#elif WEBVIEW_USING_X11_IPC + #if WEB_VIEW_USING_CHOC + #elif WEB_VIEW_USING_MACOS_WEBKIT + [handle->webview loadRequest:handle->urlreq]; + #elif WEB_VIEW_USING_X11_IPC handle->p.signal(SIGUSR1); -#endif + #endif + + // maybe unused + (void)handle; } -void resizeWebView(const WebViewHandle handle, int x, int y, uint width, uint height) +void webViewResize(const WebViewHandle handle, const uint width, const uint height, const double scaleFactor) { -#if defined(DISTRHO_OS_MAC) -#elif WEBVIEW_USING_CHOC + #if WEB_VIEW_USING_CHOC + #ifdef DISTRHO_OS_MAC + NSView* const view = static_cast(handle->webview->getViewHandle()); + [view setFrameSize:NSMakeSize(width, height)]; + #else const HWND hwnd = static_cast(handle->webview->getViewHandle()); - SetWindowPos(hwnd, nullptr, x, y, width, height, SWP_NOZORDER | SWP_NOACTIVATE); -#elif WEBVIEW_USING_X11_IPC + SetWindowPos(hwnd, nullptr, 0, 0, + width * scaleFactor, + height * scaleFactor, + SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOZORDER); + #endif + #elif WEB_VIEW_USING_MACOS_WEBKIT + [handle->webview setFrameSize:NSMakeSize(width, height)]; + #elif WEB_VIEW_USING_X11_IPC if (handle->childWindow == 0) { ::Window rootWindow, parentWindow; @@ -250,10 +500,16 @@ void resizeWebView(const WebViewHandle handle, int x, int y, uint width, uint he XMoveResizeWindow(handle->display, handle->childWindow, x, y, width, height); XFlush(handle->display); -#endif + #endif + + // maybe unused + (void)handle; + (void)width; + (void)height; + (void)scaleFactor; } -#if WEBVIEW_USING_X11_IPC +#if WEB_VIEW_USING_X11_IPC // ----------------------------------------------------------------------------------------------------------- @@ -622,10 +878,10 @@ int dpf_webview_start(int /* argc */, char** /* argv[] */) { uselocale(newlocale(LC_NUMERIC_MASK, "C", nullptr)); - const char* const envScaleFactor = std::getenv("DPF_WEBVIEW_SCALE_FACTOR"); + const char* const envScaleFactor = std::getenv("DPF_WEB_VIEW_SCALE_FACTOR"); DISTRHO_SAFE_ASSERT_RETURN(envScaleFactor != nullptr, 1); - const char* const envWinId = std::getenv("DPF_WEBVIEW_WIN_ID"); + const char* const envWinId = std::getenv("DPF_WEB_VIEW_WIN_ID"); DISTRHO_SAFE_ASSERT_RETURN(envWinId != nullptr, 1); const Window winId = std::strtoul(envWinId, nullptr, 10); @@ -657,14 +913,17 @@ int dpf_webview_start(int /* argc */, char** /* argv[] */) // -------------------------------------------------------------------------------------------------------------------- -#endif // WEBVIEW_USING_X11_IPC +#endif // WEB_VIEW_USING_X11_IPC -#ifdef WEBVIEW_DGL_NAMESPACE +#ifdef WEB_VIEW_DGL_NAMESPACE END_NAMESPACE_DGL #else END_NAMESPACE_DISTRHO #endif -#undef WEBVIEW_DISTRHO_NAMESPACE -#undef WEBVIEW_DGL_NAMESPACE -#undef WEBVIEW_NAMESPACE +#undef MACRO_NAME +#undef MACRO_NAME2 + +#undef WEB_VIEW_DISTRHO_NAMESPACE +#undef WEB_VIEW_DGL_NAMESPACE +#undef WEB_VIEW_NAMESPACE diff --git a/distrho/extra/WebViewImpl.hpp b/distrho/extra/WebViewImpl.hpp index c2550204..c16a91c6 100644 --- a/distrho/extra/WebViewImpl.hpp +++ b/distrho/extra/WebViewImpl.hpp @@ -14,7 +14,7 @@ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -#if !defined(DISTRHO_WEBVIEW_HPP_INCLUDED) && !defined(DGL_WEBVIEW_HPP_INCLUDED) +#if !defined(DISTRHO_WEB_VIEW_HPP_INCLUDED) && !defined(DGL_WEB_VIEW_HPP_INCLUDED) # error bad include #endif @@ -24,11 +24,63 @@ struct WebViewData; typedef WebViewData* WebViewHandle; -// ----------------------------------------------------------------------------------------------------------- +// -------------------------------------------------------------------------------------------------------------------- + +/** + Web view options, for customizing web view details. +*/ +struct WebViewOptions { + /** + Position offset, for cases of mixing regular widgets with web views. + */ + struct PositionOffset { + /** Horizontal offset */ + int x; + + /** Vertical offset */ + int y; + + /** Constructor for default values */ + PositionOffset() : x(0), y(0) {} + } offset; + + /** Constructor for default values */ + WebViewOptions() + : offset() {} +}; + +// -------------------------------------------------------------------------------------------------------------------- -WebViewHandle addWebView(uintptr_t parentWinId, int x, int y, uint width, uint height,double scaleFactor); -void destroyWebView(WebViewHandle webview); -void reloadWebView(WebViewHandle webview, uint port); -void resizeWebView(WebViewHandle webview, int x, int y, uint width, uint height); +/** + Create a new web view. -// ----------------------------------------------------------------------------------------------------------- + The web view will be added on top of an existing platform-specific view/window. + This means it will draw on top of whatever is below it, + something to take into consideration if mixing regular widgets with web views. + + @p windowId: The native window id to attach this view to (X11 Window, HWND or NSView*) + @p scaleFactor: Scale factor to use (only used on X11) + @p options: Extra options, optional +*/ +WebViewHandle webViewCreate(uintptr_t windowId, + uint initialWidth, + uint initialHeight, + double scaleFactor, + const WebViewOptions& options = WebViewOptions()); + +/** + Destroy the web view, handle must not be used afterwards. +*/ +void webViewDestroy(WebViewHandle webview); + +/** + Reload the web view current page. +*/ +void webViewReload(WebViewHandle webview); + +/** + Resize the web view. +*/ +void webViewResize(WebViewHandle webview, uint width, uint height, double scaleFactor); + +// -------------------------------------------------------------------------------------------------------------------- diff --git a/distrho/src/DistrhoPluginChecks.h b/distrho/src/DistrhoPluginChecks.h index 52176e0e..ef4f476e 100644 --- a/distrho/src/DistrhoPluginChecks.h +++ b/distrho/src/DistrhoPluginChecks.h @@ -94,10 +94,6 @@ # define DISTRHO_PLUGIN_WANT_TIMEPOS 0 #endif -#ifndef DISTRHO_PLUGIN_WANT_WEBVIEW -# define DISTRHO_PLUGIN_WANT_WEBVIEW 0 -#endif - #ifndef DISTRHO_UI_FILE_BROWSER # if defined(DGL_FILE_BROWSER_DISABLED) || DISTRHO_PLUGIN_HAS_EXTERNAL_UI # define DISTRHO_UI_FILE_BROWSER 0 @@ -106,6 +102,10 @@ # endif #endif +#ifndef DISTRHO_UI_WEB_VIEW +# define DISTRHO_UI_WEB_VIEW 0 +#endif + #ifndef DISTRHO_UI_USER_RESIZABLE # define DISTRHO_UI_USER_RESIZABLE 0 #endif @@ -130,11 +130,11 @@ #endif // -------------------------------------------------------------------------------------------------------------------- -// Define DISTRHO_PLUGIN_WANT_WEBVIEW if needed +// Define DISTRHO_UI_WEB_VIEW if needed -#if DISTRHO_UI_USE_WEBVIEW && !DISTRHO_PLUGIN_WANT_WEBVIEW -# undef DISTRHO_PLUGIN_WANT_WEBVIEW -# define DISTRHO_PLUGIN_WANT_WEBVIEW 1 +#if DISTRHO_UI_USE_WEBVIEW && !DISTRHO_UI_WEB_VIEW +# undef DISTRHO_UI_WEB_VIEW +# define DISTRHO_UI_WEB_VIEW 1 #endif // -------------------------------------------------------------------------------------------------------------------- @@ -280,7 +280,7 @@ static_assert(sizeof(STRINGIFY(DISTRHO_PLUGIN_UNIQUE_ID)) == 5, "The macro DISTR // -------------------------------------------------------------------------------------------------------------------- // Set DPF_USING_LD_LINUX_WEBVIEW for internal use -#if DISTRHO_PLUGIN_WANT_WEBVIEW && defined(__linux__) +#if DISTRHO_UI_WEB_VIEW && defined(__linux__) # define DPF_USING_LD_LINUX_WEBVIEW #endif diff --git a/distrho/src/DistrhoPluginVST2.cpp b/distrho/src/DistrhoPluginVST2.cpp index 134981f6..8ea40c06 100644 --- a/distrho/src/DistrhoPluginVST2.cpp +++ b/distrho/src/DistrhoPluginVST2.cpp @@ -1720,7 +1720,7 @@ const vst_effect* VSTPluginMain(const vst_host_callback audioMaster) return effect; } -#if !(defined(DISTRHO_OS_MAC) || defined(DISTRHO_OS_WASM) || defined(DISTRHO_OS_WINDOWS) || DISTRHO_PLUGIN_WANT_WEBVIEW) +#if !(defined(DISTRHO_OS_MAC) || defined(DISTRHO_OS_WASM) || defined(DISTRHO_OS_WINDOWS) || DISTRHO_UI_WEB_VIEW) DISTRHO_PLUGIN_EXPORT const vst_effect* VSTPluginMainCompat(vst_host_callback) asm ("main"); diff --git a/distrho/src/DistrhoUI.cpp b/distrho/src/DistrhoUI.cpp index 8050e248..0ec1112b 100644 --- a/distrho/src/DistrhoUI.cpp +++ b/distrho/src/DistrhoUI.cpp @@ -376,6 +376,42 @@ uintptr_t UI::getNextWindowId() noexcept # endif #endif // DISTRHO_PLUGIN_HAS_EXTERNAL_UI +/* ------------------------------------------------------------------------------------------------------------ + * DSP/Plugin Callbacks */ + +void UI::parameterChanged(const uint32_t index, const float value) +{ +#if DISTRHO_UI_WEB_VIEW +#else + // unused + (void)index; + (void)value; +#endif +} + +#if DISTRHO_PLUGIN_WANT_PROGRAMS +void UI::programLoaded(const uint32_t index) +{ +#if DISTRHO_UI_WEB_VIEW +#else + // unused + (void)index; +#endif +} +#endif + +#if DISTRHO_PLUGIN_WANT_STATE +void UI::stateChanged(const char* const key, const char* const value) +{ +#if DISTRHO_UI_WEB_VIEW +#else + // unused + (void)key; + (void)value; +#endif +} +#endif + /* ------------------------------------------------------------------------------------------------------------ * DSP/Plugin Callbacks (optional) */ diff --git a/examples/WebMeters/Makefile b/examples/WebMeters/Makefile index 2fa36f57..a8c2b631 100644 --- a/examples/WebMeters/Makefile +++ b/examples/WebMeters/Makefile @@ -21,6 +21,7 @@ FILES_UI = \ # -------------------------------------------------------------- # Do some magic +# MACOS_NO_DEAD_STRIP = true UI_TYPE = web include ../../Makefile.plugins.mk