mirror of
https://github.com/taigrr/wails.git
synced 2026-04-06 07:02:42 -07:00
Compare commits
8 Commits
linux-dial
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f6d7ec3d50 | ||
|
|
d2a116fe55 | ||
|
|
eb3cf9d130 | ||
|
|
7e2258be7d | ||
|
|
bb5d446001 | ||
|
|
e9aba4795f | ||
|
|
c16bb9715f | ||
|
|
0f09e8d433 |
@@ -74,6 +74,8 @@ 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
|
||||||
@@ -190,6 +192,8 @@ 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
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -100,6 +100,15 @@ 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:
|
||||||
|
|||||||
@@ -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:
|
case Ubuntu, Debian, Zorin, Parrot, Linuxmint, Elementary, Kali, Neon, Deepin, Raspbian, PopOS, Uos:
|
||||||
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
|
||||||
|
|||||||
@@ -1,32 +0,0 @@
|
|||||||
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,24 +3,10 @@
|
|||||||
|
|
||||||
package linux
|
package linux
|
||||||
|
|
||||||
import (
|
import "github.com/wailsapp/wails/v2/internal/frontend"
|
||||||
"github.com/wailsapp/wails/v2/internal/frontend"
|
|
||||||
)
|
|
||||||
import "C"
|
|
||||||
|
|
||||||
var openFileResults = make(chan string)
|
func (f *Frontend) OpenFileDialog(dialogOptions frontend.OpenDialogOptions) (string, error) {
|
||||||
|
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) {
|
||||||
@@ -38,8 +24,3 @@ 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,7 +24,6 @@ import "C"
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
|
||||||
"log"
|
"log"
|
||||||
"os"
|
"os"
|
||||||
"strconv"
|
"strconv"
|
||||||
@@ -63,7 +62,6 @@ 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")
|
||||||
|
|
||||||
@@ -303,11 +301,10 @@ 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 {
|
||||||
fn()
|
go fn()
|
||||||
dispatchCallbackLock.Lock()
|
dispatchCallbackLock.Lock()
|
||||||
delete(dispatchCallbacks, id)
|
delete(dispatchCallbacks, id)
|
||||||
dispatchCallbackLock.Unlock()
|
dispatchCallbackLock.Unlock()
|
||||||
@@ -345,25 +342,12 @@ 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)
|
||||||
|
|
||||||
// TODO How to return 404/500 errors to webkit?
|
|
||||||
if err != nil {
|
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
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO How to return 404/500 errors to webkit?
|
||||||
|
|
||||||
cContent := C.CString(string(content))
|
cContent := C.CString(string(content))
|
||||||
defer C.free(unsafe.Pointer(cContent))
|
defer C.free(unsafe.Pointer(cContent))
|
||||||
cMimeType := C.CString(mimeType)
|
cMimeType := C.CString(mimeType)
|
||||||
|
|||||||
@@ -4,11 +4,10 @@
|
|||||||
package linux
|
package linux
|
||||||
|
|
||||||
/*
|
/*
|
||||||
#cgo linux pkg-config: gtk+-3.0 webkit2gtk-4.0 x11
|
#cgo linux pkg-config: gtk+-3.0 webkit2gtk-4.0
|
||||||
|
|
||||||
#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>
|
||||||
|
|
||||||
@@ -106,11 +105,6 @@ 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;
|
||||||
@@ -190,36 +184,10 @@ 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"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -401,8 +369,6 @@ 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()
|
||||||
}
|
}
|
||||||
@@ -442,11 +408,3 @@ 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()
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -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 {
|
||||||
|
|||||||
@@ -2,7 +2,9 @@ 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
|
||||||
@@ -29,24 +31,44 @@ 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)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -27,3 +27,13 @@ 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 的模板
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user