mirror of
https://github.com/wailsapp/wails.git
synced 2025-05-02 22:13:36 +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
|
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) {
|
var openFileResults = make(chan string)
|
||||||
panic("implement me")
|
|
||||||
|
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) {
|
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) {
|
func (f *Frontend) MessageDialog(dialogOptions frontend.MessageDialogOptions) (string, error) {
|
||||||
panic("implement me")
|
panic("implement me")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//export processOpenFileResult
|
||||||
|
func processOpenFileResult(result *C.char) {
|
||||||
|
openFileResults <- C.GoString(result)
|
||||||
|
}
|
||||||
|
@ -24,6 +24,7 @@ import "C"
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
"log"
|
"log"
|
||||||
"os"
|
"os"
|
||||||
"strconv"
|
"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 {
|
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
|
// Set GDK_BACKEND=x11 to prevent warnings
|
||||||
os.Setenv("GDK_BACKEND", "x11")
|
os.Setenv("GDK_BACKEND", "x11")
|
||||||
|
|
||||||
@ -301,10 +303,11 @@ var dispatchCallbackLock sync.Mutex
|
|||||||
|
|
||||||
//export callDispatchedMethod
|
//export callDispatchedMethod
|
||||||
func callDispatchedMethod(cid C.int) {
|
func callDispatchedMethod(cid C.int) {
|
||||||
|
println("[callDispatchedMethod] PID:", os.Getpid())
|
||||||
id := int(cid)
|
id := int(cid)
|
||||||
fn := dispatchCallbacks[id]
|
fn := dispatchCallbacks[id]
|
||||||
if fn != nil {
|
if fn != nil {
|
||||||
go fn()
|
fn()
|
||||||
dispatchCallbackLock.Lock()
|
dispatchCallbackLock.Lock()
|
||||||
delete(dispatchCallbacks, id)
|
delete(dispatchCallbacks, id)
|
||||||
dispatchCallbackLock.Unlock()
|
dispatchCallbackLock.Unlock()
|
||||||
@ -342,11 +345,24 @@ func (f *Frontend) processRequest(request unsafe.Pointer) {
|
|||||||
|
|
||||||
// Load file from asset store
|
// Load file from asset store
|
||||||
content, mimeType, err := f.assets.Load(file)
|
content, mimeType, err := f.assets.Load(file)
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO How to return 404/500 errors to webkit?
|
// 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))
|
cContent := C.CString(string(content))
|
||||||
defer C.free(unsafe.Pointer(cContent))
|
defer C.free(unsafe.Pointer(cContent))
|
||||||
|
@ -4,10 +4,11 @@
|
|||||||
package linux
|
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 "gtk/gtk.h"
|
||||||
#include "webkit2/webkit2.h"
|
#include "webkit2/webkit2.h"
|
||||||
|
#include <X11/Xlib.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <limits.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);
|
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
|
// These are the x,y & time of the last mouse down event
|
||||||
// It's used for window dragging
|
// It's used for window dragging
|
||||||
float xroot = 0.0f;
|
float xroot = 0.0f;
|
||||||
@ -199,10 +205,37 @@ int executeJS(gpointer data) {
|
|||||||
void ExecuteOnMainThread(JSCallback* jscallback) {
|
void ExecuteOnMainThread(JSCallback* jscallback) {
|
||||||
g_idle_add((GSourceFunc)executeJS, (gpointer)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 "C"
|
||||||
import (
|
import (
|
||||||
|
"github.com/wailsapp/wails/v2/internal/frontend"
|
||||||
"github.com/wailsapp/wails/v2/pkg/options"
|
"github.com/wailsapp/wails/v2/pkg/options"
|
||||||
|
"os"
|
||||||
"unsafe"
|
"unsafe"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -384,6 +417,8 @@ func (w *Window) Run() {
|
|||||||
case options.Maximised:
|
case options.Maximised:
|
||||||
w.Maximise()
|
w.Maximise()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
C.initThreads()
|
||||||
C.gtk_main()
|
C.gtk_main()
|
||||||
w.Destroy()
|
w.Destroy()
|
||||||
}
|
}
|
||||||
@ -425,3 +460,11 @@ func (w *Window) StartDrag() {
|
|||||||
func (w *Window) Quit() {
|
func (w *Window) Quit() {
|
||||||
C.gtk_main_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