From 53481830a93a282bfb11d50797a432ac72d1d34d Mon Sep 17 00:00:00 2001 From: Lea Anthony Date: Mon, 29 Nov 2021 08:25:42 +1100 Subject: [PATCH] [linux] Basic webview working --- .../frontend/desktop/linux/frontend.go | 43 +++++++++++++++++++ v2/internal/frontend/desktop/linux/window.go | 10 +++++ 2 files changed, 53 insertions(+) diff --git a/v2/internal/frontend/desktop/linux/frontend.go b/v2/internal/frontend/desktop/linux/frontend.go index 2ffd37ac2..3b4c3409d 100644 --- a/v2/internal/frontend/desktop/linux/frontend.go +++ b/v2/internal/frontend/desktop/linux/frontend.go @@ -7,6 +7,7 @@ package linux #cgo linux pkg-config: gtk+-3.0 webkit2gtk-4.0 #include "gtk/gtk.h" +#include "webkit2/webkit2.h" extern void callDispatchedMethod(int id); @@ -31,8 +32,10 @@ import ( "log" "os" "strconv" + "strings" "sync" "text/template" + "unsafe" ) type Frontend struct { @@ -101,6 +104,7 @@ func NewFrontend(ctx context.Context, appoptions *options.App, myLogger *logger. result.assets = assets go result.startMessageProcessor() + go result.startRequestProcessor() C.gtk_init(nil, nil) @@ -438,3 +442,42 @@ func callDispatchedMethod(cid C.int) { println("Error: No dispatch method with id", id, cid) } } + +var requestBuffer = make(chan unsafe.Pointer, 100) + +func (f *Frontend) startRequestProcessor() { + for request := range requestBuffer { + f.processRequest(request) + } +} + +//export processURLRequest +func processURLRequest(request unsafe.Pointer) { + requestBuffer <- request +} + +func (f *Frontend) processRequest(request unsafe.Pointer) { + req := (*C.WebKitURISchemeRequest)(request) + uri := C.webkit_uri_scheme_request_get_uri(req) + goURI := C.GoString(uri) + + // Translate URI + goURI = strings.TrimPrefix(goURI, "wails://") + if !strings.HasPrefix(goURI, "/") { + return + } + + // Load file from asset store + content, mimeType, err := f.assets.Load(goURI) + if err != nil { + return + } + + cContent := C.CString(string(content)) + defer C.free(unsafe.Pointer(cContent)) + cMimeType := C.CString(mimeType) + defer C.free(unsafe.Pointer(cMimeType)) + var cLen C.long = (C.long)(C.strlen(cContent)) + stream := C.g_memory_input_stream_new_from_data(unsafe.Pointer(cContent), cLen, nil) + C.webkit_uri_scheme_request_finish(req, stream, cLen, cMimeType) +} diff --git a/v2/internal/frontend/desktop/linux/window.go b/v2/internal/frontend/desktop/linux/window.go index 0195ae7ab..b3c9974fe 100644 --- a/v2/internal/frontend/desktop/linux/window.go +++ b/v2/internal/frontend/desktop/linux/window.go @@ -105,9 +105,14 @@ ulong setupInvokeSignal(void* contentManager) { return g_signal_connect((WebKitUserContentManager*)contentManager, "script-message-received::external", G_CALLBACK(sendMessageToBackend), NULL); } +extern void processURLRequest(WebKitURISchemeRequest *request); + GtkWidget* setupWebview(void* contentManager, GtkWindow* window) { GtkWidget* webview = webkit_web_view_new_with_user_content_manager((WebKitUserContentManager*)contentManager); gtk_container_add(GTK_CONTAINER(window), webview); + WebKitWebContext *context = webkit_web_context_get_default(); + webkit_web_context_register_uri_scheme(context, "wails", (WebKitURISchemeRequestCallback)processURLRequest, NULL, NULL); + //g_signal_connect(G_OBJECT(webview), "load-changed", G_CALLBACK(webview_load_changed_cb), NULL); return webview; } @@ -117,6 +122,10 @@ void devtoolsEnabled(void* webview, int enabled) { webkit_settings_set_enable_developer_extras(settings, genabled); } + +void loadIndex(void* webview) { + webkit_web_view_load_uri(WEBKIT_WEB_VIEW(webview), "wails:///"); +} */ import "C" import ( @@ -290,6 +299,7 @@ func (w *Window) UpdateApplicationMenu() { } func (w *Window) Run() { + C.loadIndex(w.webview) C.gtk_widget_show_all(w.asGTKWidget()) w.Center() switch w.appoptions.WindowStartState {