Skip to content

Commit

Permalink
x11 webview
Browse files Browse the repository at this point in the history
Signed-off-by: falkTX <[email protected]>
  • Loading branch information
falkTX committed Mar 13, 2024
1 parent 3a203fd commit 54f8034
Show file tree
Hide file tree
Showing 13 changed files with 271 additions and 22 deletions.
25 changes: 24 additions & 1 deletion src/plugin/ChildProcess.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,29 @@ class ChildProcess
#endif
}

bool start2(const char* const args[])
{
const pid_t ret = pid = vfork();

switch (ret)
{
// child process
case 0:
execvp(args[0], const_cast<char* const*>(args));

d_stderr2("exec failed: %d:%s", errno, std::strerror(errno));
_exit(1);
break;

// error
case -1:
d_stderr2("vfork() failed: %d:%s", errno, std::strerror(errno));
break;
}

return ret > 0;
}

void stop(const uint32_t timeoutInMilliseconds = 2000)
{
const uint32_t timeout = d_gettime_ms() + timeoutInMilliseconds;
Expand Down Expand Up @@ -237,7 +260,7 @@ class ChildProcess
#endif
}

DISTRHO_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(ChildProcess)
DISTRHO_DECLARE_NON_COPYABLE(ChildProcess)
};

// -----------------------------------------------------------------------------------------------------------
Expand Down
4 changes: 2 additions & 2 deletions src/plugin/DesktopAudioDriver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,7 @@ class DesktopAudioDriver : public JackAudioDriver
printf("%03d:%s\n", __LINE__, __FUNCTION__);
}

int Open(jack_nframes_t buffer_size,
int Open(jack_nframes_t buffersize,
jack_nframes_t samplerate,
bool capturing,
bool playing,
Expand All @@ -177,7 +177,7 @@ class DesktopAudioDriver : public JackAudioDriver
jack_nframes_t playback_latency) override
{
printf("%03d:%s\n", __LINE__, __FUNCTION__);
if (JackAudioDriver::Open(buffer_size, samplerate, capturing, playing, chan_in, chan_out, monitor,
if (JackAudioDriver::Open(buffersize, samplerate, capturing, playing, chan_in, chan_out, monitor,
capture_driver_name, playback_driver_name, capture_latency, playback_latency) != 0) {
return -1;
}
Expand Down
12 changes: 4 additions & 8 deletions src/plugin/DesktopUI.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,12 @@
// SPDX-License-Identifier: AGPL-3.0-or-later

#include "DistrhoUI.hpp"
#include "WebView.hpp"

START_NAMESPACE_DISTRHO

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

void* addWebView(void* view);
void reloadWebView(void* webview);
void resizeWebView(void* webview, uint offset, uint width, uint height);

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

class DesktopUI : public UI
{
void* webview = nullptr;
Expand All @@ -21,7 +16,7 @@ class DesktopUI : public UI
DesktopUI()
: UI(DISTRHO_UI_DEFAULT_WIDTH, DISTRHO_UI_DEFAULT_HEIGHT)
{
webview = addWebView(reinterpret_cast<void*>(getWindow().getNativeWindowHandle()));
webview = addWebView(getWindow().getNativeWindowHandle());

const double scaleFactor = getScaleFactor();

Expand All @@ -39,6 +34,7 @@ class DesktopUI : public UI

~DesktopUI() override
{
destroyWebView(webview);
}

protected:
Expand Down Expand Up @@ -85,7 +81,7 @@ class DesktopUI : public UI
{
UI::onResize(ev);

uint offset = 20;
uint offset = kVerticalOffset;
uint width = ev.size.getWidth();
uint height = ev.size.getHeight() - offset;

Expand Down
2 changes: 2 additions & 0 deletions src/plugin/DistrhoPluginInfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,3 +22,5 @@
#define DISTRHO_UI_DEFAULT_WIDTH 1170
#define DISTRHO_UI_DEFAULT_HEIGHT 600
#define DISTRHO_UI_USER_RESIZABLE 1

static const constexpr unsigned int kVerticalOffset = 25;
23 changes: 22 additions & 1 deletion src/plugin/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ FILES_UI = DesktopUI.cpp

ifeq ($(MACOS),true)
FILES_UI += WebView.mm
else ifeq ($(LINUX),true)
FILES_UI += WebViewX11.cpp
endif

# ---------------------------------------------------------------------------------------------------------------------
Expand All @@ -29,8 +31,27 @@ ifeq ($(MACOS),true)
LINK_FLAGS += -framework WebKit
else ifeq ($(WINDOWS),true)
LINK_FLAGS += -lwinmm
else ifeq ($(LINUX),true)
LINK_FLAGS += -ldl
endif

all: jack vst2
TARGETS = jack vst2

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

ifeq ($(LINUX),true)

TARGETS += $(TARGET_DIR)/MOD-Desktop-WebView

$(TARGET_DIR)/MOD-Desktop-WebView: $(BUILD_DIR)/WebViewQt.cpp.o
$(CXX) $^ $(LINK_FLAGS) $(shell $(PKG_CONFIG) --libs Qt5WebEngineWidgets) -o $@

$(BUILD_DIR)/WebViewQt.cpp.o: BUILD_CXX_FLAGS += -std=gnu++14 $(shell $(PKG_CONFIG) --cflags Qt5WebEngineWidgets)

include $(BUILD_DIR)/WebViewQt.cpp.d

endif

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

all: $(TARGETS)
17 changes: 17 additions & 0 deletions src/plugin/WebView.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
// SPDX-FileCopyrightText: 2023-2024 MOD Audio UG
// SPDX-License-Identifier: AGPL-3.0-or-later

#include "DistrhoUtils.hpp"

START_NAMESPACE_DISTRHO

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

void* addWebView(uintptr_t viewptr);
void destroyWebView(void* webview);
void reloadWebView(void* webview);
void resizeWebView(void* webview, uint offset, uint width, uint height);

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

END_NAMESPACE_DISTRHO
18 changes: 10 additions & 8 deletions src/plugin/WebView.mm
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// SPDX-FileCopyrightText: 2023-2024 MOD Audio UG
// SPDX-License-Identifier: AGPL-3.0-or-later

#include "DistrhoUtils.hpp"
#include "WebView.hpp"

#import <Cocoa/Cocoa.h>
#import <WebKit/WebKit.h>
Expand All @@ -10,14 +10,16 @@

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

void* addWebView(void* view);
void reloadWebView(void* webview);
void resizeWebView(void* webview, uint offset, uint width, uint height);

void* addWebView(void* const viewptr)
void* addWebView(const uintptr_t viewptr)
{
NSView* const view = static_cast<NSView*>(viewptr);
WKWebView* const webview = [[WKWebView alloc] initWithFrame: CGRectMake(0, 25, 225, 300)];
NSView* const view = reinterpret_cast<NSView*>(viewptr);

cosnt CGRect rect = CGRectMake(0,
kVerticalOffset,
DISTRHO_UI_DEFAULT_WIDTH,
DISTRHO_UI_DEFAULT_HEIGHT - kVerticalOffset);

WKWebView* const webview = [[WKWebView alloc] initWithFrame: rect];

[[[webview configuration] preferences] setValue: @(true) forKey: @"developerExtrasEnabled"];

Expand Down
72 changes: 72 additions & 0 deletions src/plugin/WebViewQt.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
// SPDX-FileCopyrightText: 2023-2024 MOD Audio UG
// SPDX-License-Identifier: AGPL-3.0-or-later

#include "DistrhoPluginInfo.h"

#include "../systray/qrc_mod-desktop.hpp"

// TODO split build
#include "../systray/utils.cpp"

#include <QtGui/QWindow>
#include <QtWidgets/QApplication>
#include <QtWidgets/QMainWindow>
#include <QtWebEngineWidgets/QWebEngineView>

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

int main(int argc, char* argv[])
{
QApplication::setAttribute(Qt::AA_X11InitThreads);
QApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
QApplication::setAttribute(Qt::AA_UseHighDpiPixmaps);

setupControlCloseSignal();

// TODO set up all branding here
QApplication app(argc, argv);
app.setApplicationName("MOD Desktop");
app.setOrganizationName("MOD Audio");
app.setWindowIcon(QIcon(":/res/mod-logo.svg"));

const bool darkMode = shouldUseDarkMode();

if (darkMode)
setupDarkModePalette(app);

printf("'%s' '%s'\n", argv[1], argv[2]);

if (argc == 3 && std::strcmp(argv[1], "-xembed") == 0)
{
const uintptr_t parentId = std::atoll(argv[2]);
QWindow* const parentWindow = QWindow::fromWinId(parentId);

QWebEngineView webview;
webview.move(0, kVerticalOffset);
webview.setFixedSize(DISTRHO_UI_DEFAULT_WIDTH, DISTRHO_UI_DEFAULT_HEIGHT - kVerticalOffset);
webview.winId();
webview.windowHandle()->setParent(parentWindow);
webview.setUrl(QUrl("http://127.0.0.1:18181/"));
webview.show();
return app.exec();
}
else
{
QMainWindow window;
window.setWindowTitle("Web View");

QWebEngineView webview(&window);
webview.setUrl(QUrl("http://127.0.0.1:18181/"));

window.setCentralWidget(&webview);
window.resize(DISTRHO_UI_DEFAULT_WIDTH, DISTRHO_UI_DEFAULT_HEIGHT - kVerticalOffset);

if (darkMode)
setupDarkModeWindow(window);

window.show();
return app.exec();
}
}

// -----------------------------------------------------------------------------------------------------------
110 changes: 110 additions & 0 deletions src/plugin/WebViewX11.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
// SPDX-FileCopyrightText: 2023-2024 MOD Audio UG
// SPDX-License-Identifier: AGPL-3.0-or-later

#include "WebView.hpp"

#include "ChildProcess.hpp"
#include "extra/String.hpp"

#include <dlfcn.h>
#include <linux/limits.h>
#include <X11/Xlib.h>
// #include <X11/Xutil.h>

START_NAMESPACE_DISTRHO

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

struct WebViewIPC {
ChildProcess p;
::Display* display;
::Window childWindow;
::Window ourWindow;
};

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

void* addWebView(uintptr_t viewptr)
{
::Display* const display = XOpenDisplay(nullptr);
DISTRHO_SAFE_ASSERT_RETURN(display != nullptr, nullptr);

WebViewIPC* const ipc = new WebViewIPC();
ipc->display = display;
ipc->childWindow = 0;
ipc->ourWindow = viewptr;

char webviewTool[PATH_MAX] = {};

{
Dl_info info = {};
dladdr((void*)addWebView, &info);

if (info.dli_fname[0] == '.')
{
getcwd(webviewTool, PATH_MAX - 1);
std::strncat(webviewTool, info.dli_fname + 1, PATH_MAX - 1);
}
else if (info.dli_fname[0] != '/')
{
getcwd(webviewTool, PATH_MAX - 1);
std::strncat(webviewTool, "/", PATH_MAX - 1);
std::strncat(webviewTool, info.dli_fname, PATH_MAX - 1);
}
else
{
std::strncpy(webviewTool, info.dli_fname, PATH_MAX - 1);
}
}

if (char* const c = std::strrchr(webviewTool, '/'))
*c = 0;

std::strncat(webviewTool, "/MOD-Desktop-WebView", PATH_MAX - 1);

const String viewStr(viewptr);
const char* const args[] = { webviewTool, "-platform", "xcb", "-xembed", viewStr.buffer(), nullptr };
ipc->p.start2(args);

return ipc;
}

void destroyWebView(void* const webviewptr)
{
WebViewIPC* const ipc = static_cast<WebViewIPC*>(webviewptr);

XCloseDisplay(ipc->display);
delete ipc;
}

void reloadWebView(void* const webviewptr)
{
}

void resizeWebView(void* const webviewptr, const uint offset, const uint width, const uint height)
{
WebViewIPC* const ipc = static_cast<WebViewIPC*>(webviewptr);

if (ipc->childWindow == 0)
{
::Window rootWindow, parentWindow;
::Window* childWindows = nullptr;
uint numChildren = 0;

XFlush(ipc->display);
XQueryTree(ipc->display, ipc->ourWindow, &rootWindow, &parentWindow, &childWindows, &numChildren);

if (numChildren == 0 || childWindows == nullptr)
return;

ipc->childWindow = childWindows[0];
XFree(childWindows);
}

XMoveResizeWindow(ipc->display, ipc->childWindow, 0, offset, width, height);
XFlush(ipc->display);
}

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

END_NAMESPACE_DISTRHO
4 changes: 4 additions & 0 deletions src/systray/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,10 @@

int main(int argc, char* argv[])
{
QApplication::setAttribute(Qt::AA_X11InitThreads);
QApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
QApplication::setAttribute(Qt::AA_UseHighDpiPixmaps);

initEvironment();
setupControlCloseSignal();

Expand Down
1 change: 0 additions & 1 deletion src/systray/mod-desktop.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@
#include <QtCore/QProcess>
#include <QtCore/QSettings>
#include <QtCore/QTimer>
#include <QtGui/QDesktopServices>
#include <QtWidgets/QMessageBox>
#include <QtWidgets/QMenu>
#include <QtWidgets/QSystemTrayIcon>
Expand Down
Loading

0 comments on commit 54f8034

Please sign in to comment.