mirror of
https://github.com/wailsapp/wails.git
synced 2025-05-02 22:31:06 +08:00
[linux] Dialogs WIP
This commit is contained in:
parent
5c24f8bf83
commit
1920a545f4
32
v2/internal/frontend/desktop/linux/calloc.go
Normal file
32
v2/internal/frontend/desktop/linux/calloc.go
Normal file
@ -0,0 +1,32 @@
|
||||
package linux
|
||||
|
||||
/*
|
||||
#include <stdlib.h>
|
||||
*/
|
||||
import "C"
|
||||
import "unsafe"
|
||||
|
||||
// Calloc handles alloc/dealloc of C data
|
||||
type Calloc struct {
|
||||
pool []unsafe.Pointer
|
||||
}
|
||||
|
||||
// NewCalloc creates a new allocator
|
||||
func NewCalloc() Calloc {
|
||||
return Calloc{}
|
||||
}
|
||||
|
||||
// String creates a new C string and retains a reference to it
|
||||
func (c Calloc) String(in string) *C.char {
|
||||
result := C.CString(in)
|
||||
c.pool = append(c.pool, unsafe.Pointer(result))
|
||||
return result
|
||||
}
|
||||
|
||||
// Free frees all allocated C memory
|
||||
func (c Calloc) Free() {
|
||||
for _, str := range c.pool {
|
||||
C.free(str)
|
||||
}
|
||||
c.pool = []unsafe.Pointer{}
|
||||
}
|
@ -3,10 +3,24 @@
|
||||
|
||||
package linux
|
||||
|
||||
import "github.com/wailsapp/wails/v2/internal/frontend"
|
||||
import (
|
||||
"github.com/wailsapp/wails/v2/internal/frontend"
|
||||
)
|
||||
import "C"
|
||||
|
||||
func (f *Frontend) OpenFileDialog(dialogOptions frontend.OpenDialogOptions) (string, error) {
|
||||
panic("implement me")
|
||||
var openFileResults = make(chan string)
|
||||
|
||||
func (f *Frontend) OpenFileDialog(dialogOptions frontend.OpenDialogOptions) (result string, err error) {
|
||||
|
||||
f.dispatch(func() {
|
||||
println("Before OpenFileDialog")
|
||||
f.mainWindow.OpenFileDialog(dialogOptions)
|
||||
println("After OpenFileDialog")
|
||||
})
|
||||
println("Waiting for result")
|
||||
result = <-openFileResults
|
||||
println("Got result")
|
||||
return
|
||||
}
|
||||
|
||||
func (f *Frontend) OpenMultipleFilesDialog(dialogOptions frontend.OpenDialogOptions) ([]string, error) {
|
||||
@ -24,3 +38,8 @@ func (f *Frontend) SaveFileDialog(dialogOptions frontend.SaveDialogOptions) (str
|
||||
func (f *Frontend) MessageDialog(dialogOptions frontend.MessageDialogOptions) (string, error) {
|
||||
panic("implement me")
|
||||
}
|
||||
|
||||
//export processOpenFileResult
|
||||
func processOpenFileResult(result *C.char) {
|
||||
openFileResults <- C.GoString(result)
|
||||
}
|
||||
|
@ -24,6 +24,7 @@ import "C"
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"log"
|
||||
"os"
|
||||
"strconv"
|
||||
@ -62,6 +63,7 @@ type Frontend struct {
|
||||
|
||||
func NewFrontend(ctx context.Context, appoptions *options.App, myLogger *logger.Logger, appBindings *binding.Bindings, dispatcher frontend.Dispatcher) *Frontend {
|
||||
|
||||
println("[NewFrontend] PID:", os.Getpid())
|
||||
// Set GDK_BACKEND=x11 to prevent warnings
|
||||
os.Setenv("GDK_BACKEND", "x11")
|
||||
|
||||
@ -301,10 +303,11 @@ var dispatchCallbackLock sync.Mutex
|
||||
|
||||
//export callDispatchedMethod
|
||||
func callDispatchedMethod(cid C.int) {
|
||||
println("[callDispatchedMethod] PID:", os.Getpid())
|
||||
id := int(cid)
|
||||
fn := dispatchCallbacks[id]
|
||||
if fn != nil {
|
||||
go fn()
|
||||
fn()
|
||||
dispatchCallbackLock.Lock()
|
||||
delete(dispatchCallbacks, id)
|
||||
dispatchCallbackLock.Unlock()
|
||||
@ -342,11 +345,24 @@ func (f *Frontend) processRequest(request unsafe.Pointer) {
|
||||
|
||||
// Load file from asset store
|
||||
content, mimeType, err := f.assets.Load(file)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
// TODO How to return 404/500 errors to webkit?
|
||||
if err != nil {
|
||||
if os.IsNotExist(err) {
|
||||
f.dispatch(func() {
|
||||
message := C.CString("not found")
|
||||
defer C.free(unsafe.Pointer(message))
|
||||
C.webkit_uri_scheme_request_finish_error(req, C.g_error_new_literal(C.G_FILE_ERROR_NOENT, C.int(404), message))
|
||||
})
|
||||
} else {
|
||||
err = fmt.Errorf("Error processing request %s: %w", uri, err)
|
||||
f.logger.Error(err.Error())
|
||||
message := C.CString("internal server error")
|
||||
defer C.free(unsafe.Pointer(message))
|
||||
C.webkit_uri_scheme_request_finish_error(req, C.g_error_new_literal(C.G_FILE_ERROR_NOENT, C.int(500), message))
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
cContent := C.CString(string(content))
|
||||
defer C.free(unsafe.Pointer(cContent))
|
||||
|
@ -4,10 +4,11 @@
|
||||
package linux
|
||||
|
||||
/*
|
||||
#cgo linux pkg-config: gtk+-3.0 webkit2gtk-4.0
|
||||
#cgo linux pkg-config: gtk+-3.0 webkit2gtk-4.0 x11
|
||||
|
||||
#include "gtk/gtk.h"
|
||||
#include "webkit2/webkit2.h"
|
||||
#include <X11/Xlib.h>
|
||||
#include <stdio.h>
|
||||
#include <limits.h>
|
||||
|
||||
@ -105,6 +106,11 @@ ulong setupInvokeSignal(void* contentManager) {
|
||||
return g_signal_connect((WebKitUserContentManager*)contentManager, "script-message-received::external", G_CALLBACK(sendMessageToBackend), NULL);
|
||||
}
|
||||
|
||||
void initThreads() {
|
||||
printf("init threads\n");
|
||||
XInitThreads();
|
||||
}
|
||||
|
||||
// These are the x,y & time of the last mouse down event
|
||||
// It's used for window dragging
|
||||
float xroot = 0.0f;
|
||||
@ -199,10 +205,37 @@ int executeJS(gpointer data) {
|
||||
void ExecuteOnMainThread(JSCallback* jscallback) {
|
||||
g_idle_add((GSourceFunc)executeJS, (gpointer)jscallback);
|
||||
}
|
||||
|
||||
void extern processOpenFileResult(char*);
|
||||
|
||||
static void OpenDialog(GtkWindow* window, char *title) {
|
||||
printf("Here\n");
|
||||
GtkWidget *dlg = gtk_file_chooser_dialog_new(title, window, GTK_FILE_CHOOSER_ACTION_OPEN,
|
||||
"_Cancel", GTK_RESPONSE_CANCEL,
|
||||
"_Open", GTK_RESPONSE_ACCEPT,
|
||||
NULL);
|
||||
printf("Here3\n");
|
||||
|
||||
gint response = gtk_dialog_run(GTK_DIALOG(dlg));
|
||||
printf("Here 4\n");
|
||||
|
||||
if (response == GTK_RESPONSE_ACCEPT)
|
||||
{
|
||||
printf("Here 5\n");
|
||||
|
||||
gchar *filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dlg));
|
||||
processOpenFileResult(filename);
|
||||
g_free(filename);
|
||||
}
|
||||
gtk_widget_destroy(dlg);
|
||||
}
|
||||
|
||||
*/
|
||||
import "C"
|
||||
import (
|
||||
"github.com/wailsapp/wails/v2/internal/frontend"
|
||||
"github.com/wailsapp/wails/v2/pkg/options"
|
||||
"os"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
@ -384,6 +417,8 @@ func (w *Window) Run() {
|
||||
case options.Maximised:
|
||||
w.Maximise()
|
||||
}
|
||||
|
||||
C.initThreads()
|
||||
C.gtk_main()
|
||||
w.Destroy()
|
||||
}
|
||||
@ -425,3 +460,11 @@ func (w *Window) StartDrag() {
|
||||
func (w *Window) Quit() {
|
||||
C.gtk_main_quit()
|
||||
}
|
||||
|
||||
func (w *Window) OpenFileDialog(dialogOptions frontend.OpenDialogOptions) {
|
||||
println("OpenFileDialog PID:", os.Getpid())
|
||||
mem := NewCalloc()
|
||||
title := mem.String(dialogOptions.Title)
|
||||
C.OpenDialog(w.asGTKWindow(), title)
|
||||
mem.Free()
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user