mirror of
https://github.com/taigrr/wails.git
synced 2026-04-02 13:19:00 -07:00
Compare commits
11 Commits
v2.0.0-bet
...
linux-dial
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b296fbbb99 | ||
|
|
26c4f112e3 | ||
|
|
f338dff171 | ||
|
|
3c6ed12637 | ||
|
|
e2f3a11a33 | ||
|
|
0571deb290 | ||
|
|
451b357e40 | ||
|
|
84b67a8f53 | ||
|
|
448cf731bb | ||
|
|
9cb480f0f0 | ||
|
|
6825a631f5 |
10
cmd/fs.go
10
cmd/fs.go
@@ -148,16 +148,6 @@ func (fs *FSHelper) LocalDir(dir string) (*Dir, error) {
|
||||
}, err
|
||||
}
|
||||
|
||||
// LoadRelativeFile loads the given file relative to the caller's directory
|
||||
func (fs *FSHelper) LoadRelativeFile(relativePath string) ([]byte, error) {
|
||||
_, filename, _, _ := runtime.Caller(0)
|
||||
fullPath, err := filepath.Abs(filepath.Join(path.Dir(filename), relativePath))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return os.ReadFile(fullPath)
|
||||
}
|
||||
|
||||
// GetSubdirs will return a list of FQPs to subdirectories in the given directory
|
||||
func (d *Dir) GetSubdirs() (map[string]string, error) {
|
||||
|
||||
|
||||
@@ -1,11 +1,15 @@
|
||||
package cmd
|
||||
|
||||
import (
|
||||
_ "embed"
|
||||
"log"
|
||||
|
||||
"gopkg.in/yaml.v3"
|
||||
)
|
||||
|
||||
//go:embed linuxdb.yaml
|
||||
var LinuxDBYaml []byte
|
||||
|
||||
// LinuxDB is the database for linux distribution data.
|
||||
type LinuxDB struct {
|
||||
Distributions map[string]*Distribution `yaml:"distributions"`
|
||||
@@ -78,14 +82,10 @@ func (l *LinuxDB) GetDistro(distro string) *Distribution {
|
||||
// NewLinuxDB creates a new LinuxDB instance from the bundled
|
||||
// linuxdb.yaml file.
|
||||
func NewLinuxDB() *LinuxDB {
|
||||
data, err := fs.LoadRelativeFile("./linuxdb.yaml")
|
||||
if err != nil {
|
||||
log.Fatal("Could not load linuxdb.yaml")
|
||||
}
|
||||
result := LinuxDB{
|
||||
Distributions: make(map[string]*Distribution),
|
||||
}
|
||||
err = result.ImportData(data)
|
||||
err := result.ImportData(LinuxDBYaml)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@ package build
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/wailsapp/wails/v2/internal/colour"
|
||||
"io"
|
||||
"os"
|
||||
"os/exec"
|
||||
@@ -79,6 +80,12 @@ func AddBuildSubcommand(app *clir.Cli, w io.Writer) {
|
||||
forceBuild := false
|
||||
command.BoolFlag("f", "Force build application", &forceBuild)
|
||||
|
||||
updateGoMod := false
|
||||
command.BoolFlag("u", "Updates go.mod to use the same Wails version as the CLI", &updateGoMod)
|
||||
|
||||
debug := false
|
||||
command.BoolFlag("debug", "Retains debug data in the compiled application", &debug)
|
||||
|
||||
command.Action(func() error {
|
||||
|
||||
quiet := verbosity == 0
|
||||
@@ -160,13 +167,20 @@ func AddBuildSubcommand(app *clir.Cli, w io.Writer) {
|
||||
}
|
||||
}
|
||||
|
||||
mode := build.Production
|
||||
modeString := "Production"
|
||||
if debug {
|
||||
mode = build.Debug
|
||||
modeString = "Debug"
|
||||
}
|
||||
|
||||
// Create BuildOptions
|
||||
buildOptions := &build.Options{
|
||||
Logger: logger,
|
||||
OutputType: outputType,
|
||||
OutputFile: outputFilename,
|
||||
CleanBuildDirectory: cleanBuildDirectory,
|
||||
Mode: build.Production,
|
||||
Mode: mode,
|
||||
Pack: !noPackage,
|
||||
LDFlags: ldflags,
|
||||
Compiler: compilerCommand,
|
||||
@@ -202,6 +216,7 @@ func AddBuildSubcommand(app *clir.Cli, w io.Writer) {
|
||||
fmt.Fprintf(w, "Platform: \t%s\n", buildOptions.Platform)
|
||||
fmt.Fprintf(w, "Arch: \t%s\n", buildOptions.Arch)
|
||||
fmt.Fprintf(w, "Compiler: \t%s\n", compilerPath)
|
||||
fmt.Fprintf(w, "Build Mode: \t%s\n", modeString)
|
||||
fmt.Fprintf(w, "Skip Frontend: \t%t\n", skipFrontend)
|
||||
fmt.Fprintf(w, "Compress: \t%t\n", buildOptions.Compress)
|
||||
fmt.Fprintf(w, "Package: \t%t\n", buildOptions.Pack)
|
||||
@@ -214,7 +229,7 @@ func AddBuildSubcommand(app *clir.Cli, w io.Writer) {
|
||||
fmt.Fprintf(w, "\n")
|
||||
w.Flush()
|
||||
|
||||
err = checkGoModVersion(logger)
|
||||
err = checkGoModVersion(logger, updateGoMod)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -243,7 +258,7 @@ func doBuild(buildOptions *build.Options) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func checkGoModVersion(logger *clilogger.CLILogger) error {
|
||||
func checkGoModVersion(logger *clilogger.CLILogger, updateGoMod bool) error {
|
||||
cwd, err := os.Getwd()
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -265,6 +280,36 @@ func checkGoModVersion(logger *clilogger.CLILogger) error {
|
||||
return err
|
||||
}
|
||||
|
||||
logger.Println("Warning: go.mod is using Wails '%s' but the CLI is '%s'. Consider updating it.\n", gomodversion.String(), internal.Version)
|
||||
if updateGoMod {
|
||||
return syncGoModVersion(cwd)
|
||||
}
|
||||
|
||||
logger.Println("Warning: go.mod is using Wails '%s' but the CLI is '%s'. Consider updating your project's `go.mod` file.\n", gomodversion.String(), internal.Version)
|
||||
return nil
|
||||
}
|
||||
|
||||
func LogGreen(message string, args ...interface{}) {
|
||||
text := fmt.Sprintf(message, args...)
|
||||
println(colour.Green(text))
|
||||
}
|
||||
|
||||
func syncGoModVersion(cwd string) error {
|
||||
gomodFilename := filepath.Join(cwd, "go.mod")
|
||||
gomodData, err := os.ReadFile(gomodFilename)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
outOfSync, err := gomod.GoModOutOfSync(gomodData, internal.Version)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if !outOfSync {
|
||||
return nil
|
||||
}
|
||||
LogGreen("Updating go.mod to use Wails '%s'", internal.Version)
|
||||
newGoData, err := gomod.UpdateGoModVersion(gomodData, internal.Version)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return os.WriteFile(gomodFilename, newGoData, 0755)
|
||||
}
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
package internal
|
||||
|
||||
var Version = "v2.0.0-beta.26"
|
||||
var Version = "v2.0.0-beta.27"
|
||||
|
||||
@@ -540,6 +540,10 @@
|
||||
|
||||
// Setup callback handler
|
||||
[dialog beginSheetModalForWindow:self.mainWindow completionHandler:^(NSModalResponse returnCode) {
|
||||
if ( returnCode != NSModalResponseOK) {
|
||||
processOpenFileDialogResponse("[]");
|
||||
return;
|
||||
}
|
||||
NSMutableArray *arr = [NSMutableArray new];
|
||||
for (NSURL *url in [dialog URLs]) {
|
||||
[arr addObject:[url path]];
|
||||
@@ -558,7 +562,7 @@
|
||||
|
||||
|
||||
// Create the dialog
|
||||
NSSavePanel *dialog = [NSOpenPanel savePanel];
|
||||
NSSavePanel *dialog = [NSSavePanel savePanel];
|
||||
|
||||
// Valid but appears to do nothing.... :/
|
||||
if( title != nil ) {
|
||||
@@ -592,10 +596,12 @@
|
||||
|
||||
// Setup callback handler
|
||||
[dialog beginSheetModalForWindow:self.mainWindow completionHandler:^(NSModalResponse returnCode) {
|
||||
NSURL *url = [dialog URL];
|
||||
if ( url != nil ) {
|
||||
processSaveFileDialogResponse([url.path UTF8String]);
|
||||
return;
|
||||
if ( returnCode == NSModalResponseOK ) {
|
||||
NSURL *url = [dialog URL];
|
||||
if ( url != nil ) {
|
||||
processSaveFileDialogResponse([url.path UTF8String]);
|
||||
return;
|
||||
}
|
||||
}
|
||||
processSaveFileDialogResponse("");
|
||||
}];
|
||||
|
||||
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>
|
||||
|
||||
@@ -83,7 +84,7 @@ extern void processMessage(char*);
|
||||
|
||||
static void sendMessageToBackend(WebKitUserContentManager *contentManager,
|
||||
WebKitJavascriptResult *result,
|
||||
void*)
|
||||
void* data)
|
||||
{
|
||||
#if WEBKIT_MAJOR_VERSION >= 2 && WEBKIT_MINOR_VERSION >= 22
|
||||
JSCValue *value = webkit_javascript_result_get_js_value(result);
|
||||
@@ -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;
|
||||
@@ -145,7 +151,7 @@ void connectButtons(void* webview) {
|
||||
extern void processURLRequest(WebKitURISchemeRequest *request);
|
||||
|
||||
// This is called when the close button on the window is pressed
|
||||
gboolean close_button_pressed(GtkWidget *widget, GdkEvent *event, void*)
|
||||
gboolean close_button_pressed(GtkWidget *widget, GdkEvent *event, void* data)
|
||||
{
|
||||
processMessage("Q");
|
||||
return FALSE;
|
||||
@@ -184,10 +190,36 @@ static void startDrag(void *webview, GtkWindow* mainwindow)
|
||||
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 (
|
||||
"github.com/wailsapp/wails/v2/internal/frontend"
|
||||
"github.com/wailsapp/wails/v2/pkg/options"
|
||||
"os"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
@@ -369,6 +401,8 @@ func (w *Window) Run() {
|
||||
case options.Maximised:
|
||||
w.Maximise()
|
||||
}
|
||||
|
||||
C.initThreads()
|
||||
C.gtk_main()
|
||||
w.Destroy()
|
||||
}
|
||||
@@ -408,3 +442,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()
|
||||
}
|
||||
|
||||
@@ -152,7 +152,7 @@ export function EventsEmit(eventName) {
|
||||
|
||||
export function EventsOff(eventName) {
|
||||
// Remove local listeners
|
||||
eventListeners.delete(eventName);
|
||||
delete eventListeners[eventName];
|
||||
|
||||
// Notify Go listeners
|
||||
window.WailsInvoke('EX' + eventName);
|
||||
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
BIN
v2/internal/webview2runtime/MicrosoftEdgeWebview2Setup.exe
Normal file
BIN
v2/internal/webview2runtime/MicrosoftEdgeWebview2Setup.exe
Normal file
Binary file not shown.
@@ -215,7 +215,7 @@ func (b *BaseBuilder) CompileProject(options *Options) error {
|
||||
commands := slicer.String([]string{"build"})
|
||||
|
||||
// Add better debugging flags
|
||||
if options.Mode == Dev {
|
||||
if options.Mode == Dev || options.Mode == Debug {
|
||||
commands.Add("-gcflags")
|
||||
commands.Add(`"all=-N -l"`)
|
||||
}
|
||||
@@ -233,7 +233,7 @@ func (b *BaseBuilder) CompileProject(options *Options) error {
|
||||
tags.Add(options.WebView2Strategy)
|
||||
}
|
||||
|
||||
if options.Mode == Production {
|
||||
if options.Mode == Production || options.Mode == Debug {
|
||||
tags.Add("production")
|
||||
}
|
||||
|
||||
|
||||
@@ -23,6 +23,8 @@ const (
|
||||
Dev Mode = iota
|
||||
// Production mode
|
||||
Production
|
||||
// Debug build
|
||||
Debug
|
||||
)
|
||||
|
||||
// Options contains all the build options as well as the project data
|
||||
|
||||
@@ -66,6 +66,8 @@ A list of community maintained templates can be found [here](/docs/community/tem
|
||||
| -upxflags | Flags to pass to upx | |
|
||||
| -v int | Verbosity level (0 - silent, 1 - default, 2 - verbose) | 1 |
|
||||
| -webview2 | WebView2 installer strategy: download,embed,browser,error | download |
|
||||
| -u | Updates your project's `go.mod` to use the same version of Wails as the CLI | |
|
||||
| -debug | Retains debug information in the application | false |
|
||||
|
||||
For a detailed description of the `webview2` flag, please refer to the [Windows](/docs/guides/windows) Guide.
|
||||
|
||||
|
||||
Reference in New Issue
Block a user