Compare commits

..

2 Commits

Author SHA1 Message Date
Lea\Anthony
b296fbbb99 Fix signatures
(cherry picked from commit 0f09e8d433)
2021-12-30 11:20:54 +11:00
Lea Anthony
26c4f112e3 [linux] Dialogs WIP 2021-12-29 09:47:31 +11:00
10 changed files with 119 additions and 55 deletions

View File

@@ -74,8 +74,6 @@ const (
NixOS NixOS
// Artix linux distribution // Artix linux distribution
ArtixLinux ArtixLinux
//Uos distribution
Uos
) )
// DistroInfo contains all the information relating to a linux distribution // DistroInfo contains all the information relating to a linux distribution
@@ -192,8 +190,6 @@ func parseOsRelease(osRelease string) *DistroInfo {
result.Distribution = NixOS result.Distribution = NixOS
case "artix": case "artix":
result.Distribution = ArtixLinux result.Distribution = ArtixLinux
case "uos":
result.Distribution = Uos
default: default:
result.Distribution = Unknown result.Distribution = Unknown
} }

View File

@@ -100,15 +100,6 @@ distributions:
gccversioncommand: *gccdumpfullversion gccversioncommand: *gccdumpfullversion
programs: *debiandefaultprograms programs: *debiandefaultprograms
libraries: *debiandefaultlibraries libraries: *debiandefaultlibraries
uos:
id: uos
releases:
default:
version: default
name: Uos
gccversioncommand: *gccdumpfullversion
programs: *debiandefaultprograms
libraries: *debiandefaultlibraries
void: void:
id: void id: void
releases: releases:

View File

@@ -278,7 +278,7 @@ func CheckDependencies(logger *Logger) (bool, error) {
distroInfo := GetLinuxDistroInfo() distroInfo := GetLinuxDistroInfo()
switch distroInfo.Distribution { switch distroInfo.Distribution {
case Ubuntu, Debian, Zorin, Parrot, Linuxmint, Elementary, Kali, Neon, Deepin, Raspbian, PopOS, Uos: case Ubuntu, Debian, Zorin, Parrot, Linuxmint, Elementary, Kali, Neon, Deepin, Raspbian, PopOS:
libraryChecker = DpkgInstalled libraryChecker = DpkgInstalled
case Arch, ArcoLinux, ArchLabs, Ctlos, Manjaro, ManjaroARM, EndeavourOS, ArtixLinux: case Arch, ArcoLinux, ArchLabs, Ctlos, Manjaro, ManjaroARM, EndeavourOS, ArtixLinux:
libraryChecker = PacmanInstalled libraryChecker = PacmanInstalled

View 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{}
}

View File

@@ -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)
}

View File

@@ -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))

View File

@@ -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;
@@ -184,10 +190,36 @@ static void startDrag(void *webview, GtkWindow* mainwindow)
gtk_window_begin_move_drag(mainwindow, 1, xroot, yroot, dragTime); gtk_window_begin_move_drag(mainwindow, 1, xroot, yroot, dragTime);
} }
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"
) )
@@ -369,6 +401,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()
} }
@@ -408,3 +442,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()
}

View File

@@ -57,10 +57,10 @@ func NewWindow(parent winc.Controller, appoptions *options.App) *Window {
result.SetText(appoptions.Title) result.SetText(appoptions.Title)
if appoptions.Frameless == false && !appoptions.Fullscreen { if appoptions.Frameless == false && !appoptions.Fullscreen {
result.EnableMaxButton(!appoptions.DisableResize) result.EnableMaxButton(!appoptions.DisableResize)
result.EnableSizable(!appoptions.DisableResize)
result.SetMinSize(appoptions.MinWidth, appoptions.MinHeight) result.SetMinSize(appoptions.MinWidth, appoptions.MinHeight)
result.SetMaxSize(appoptions.MaxWidth, appoptions.MaxHeight) result.SetMaxSize(appoptions.MaxWidth, appoptions.MaxHeight)
} }
result.EnableSizable(!appoptions.DisableResize)
if appoptions.Windows != nil { if appoptions.Windows != nil {
if appoptions.Windows.WindowIsTranslucent { if appoptions.Windows.WindowIsTranslucent {

View File

@@ -2,9 +2,7 @@ package runtime
import ( import (
"context" "context"
"fmt"
"github.com/wailsapp/wails/v2/internal/frontend" "github.com/wailsapp/wails/v2/internal/frontend"
"github.com/wailsapp/wails/v2/internal/fs"
) )
// FileFilter defines a filter for dialog boxes // FileFilter defines a filter for dialog boxes
@@ -31,44 +29,24 @@ type MessageDialogOptions = frontend.MessageDialogOptions
// OpenDirectoryDialog prompts the user to select a directory // OpenDirectoryDialog prompts the user to select a directory
func OpenDirectoryDialog(ctx context.Context, dialogOptions OpenDialogOptions) (string, error) { func OpenDirectoryDialog(ctx context.Context, dialogOptions OpenDialogOptions) (string, error) {
appFrontend := getFrontend(ctx) appFrontend := getFrontend(ctx)
if dialogOptions.DefaultDirectory != "" {
if !fs.DirExists(dialogOptions.DefaultDirectory) {
return "", fmt.Errorf("default directory '%s' does not exist", dialogOptions.DefaultDirectory)
}
}
return appFrontend.OpenDirectoryDialog(dialogOptions) return appFrontend.OpenDirectoryDialog(dialogOptions)
} }
// OpenFileDialog prompts the user to select a file // OpenFileDialog prompts the user to select a file
func OpenFileDialog(ctx context.Context, dialogOptions OpenDialogOptions) (string, error) { func OpenFileDialog(ctx context.Context, dialogOptions OpenDialogOptions) (string, error) {
appFrontend := getFrontend(ctx) appFrontend := getFrontend(ctx)
if dialogOptions.DefaultDirectory != "" {
if !fs.DirExists(dialogOptions.DefaultDirectory) {
return "", fmt.Errorf("default directory '%s' does not exist", dialogOptions.DefaultDirectory)
}
}
return appFrontend.OpenFileDialog(dialogOptions) return appFrontend.OpenFileDialog(dialogOptions)
} }
// OpenMultipleFilesDialog prompts the user to select a file // OpenMultipleFilesDialog prompts the user to select a file
func OpenMultipleFilesDialog(ctx context.Context, dialogOptions OpenDialogOptions) ([]string, error) { func OpenMultipleFilesDialog(ctx context.Context, dialogOptions OpenDialogOptions) ([]string, error) {
appFrontend := getFrontend(ctx) appFrontend := getFrontend(ctx)
if dialogOptions.DefaultDirectory != "" {
if !fs.DirExists(dialogOptions.DefaultDirectory) {
return nil, fmt.Errorf("default directory '%s' does not exist", dialogOptions.DefaultDirectory)
}
}
return appFrontend.OpenMultipleFilesDialog(dialogOptions) return appFrontend.OpenMultipleFilesDialog(dialogOptions)
} }
// SaveFileDialog prompts the user to select a file // SaveFileDialog prompts the user to select a file
func SaveFileDialog(ctx context.Context, dialogOptions SaveDialogOptions) (string, error) { func SaveFileDialog(ctx context.Context, dialogOptions SaveDialogOptions) (string, error) {
appFrontend := getFrontend(ctx) appFrontend := getFrontend(ctx)
if dialogOptions.DefaultDirectory != "" {
if !fs.DirExists(dialogOptions.DefaultDirectory) {
return "", fmt.Errorf("default directory '%s' does not exist", dialogOptions.DefaultDirectory)
}
}
return appFrontend.SaveFileDialog(dialogOptions) return appFrontend.SaveFileDialog(dialogOptions)
} }

View File

@@ -27,13 +27,3 @@ sidebar_position: 1
## Angular ## Angular
- [wails-angular-template](https://github.com/TAINCER/wails-angular-template) - 带有 TypeScript, Sass, 热重载, 代码拆分和 i18n 的 Angular - [wails-angular-template](https://github.com/TAINCER/wails-angular-template) - 带有 TypeScript, Sass, 热重载, 代码拆分和 i18n 的 Angular
## React
- [wails-react-template](https://github.com/AlienRecall/wails-react-template) - 基于 reactjs 的模板
- [wails-react-template](https://github.com/flin7/wails-react-template) - 基于 React 并支持实时开发模式的轻量级模板
## Svelte
- [wails-svelte-template](https://github.com/raitonoberu/wails-svelte-template) - 基于 Svelte 的模板