mirror of
https://github.com/wavetermdev/wails.git
synced 2026-04-22 15:26:15 -07:00
Compare commits
122 Commits
v2.3.0
...
future/exp
| Author | SHA1 | Date | |
|---|---|---|---|
| d24d82f86d | |||
| 81e9223124 | |||
| 18d0ed890a | |||
| 2374bb7e0e | |||
| 4c42ef9710 | |||
| b4d64678b5 | |||
| 2479603143 | |||
| a4f729a6a0 | |||
| dbf6b3a718 | |||
| 45c3a501d9 | |||
| 401165ce30 | |||
| 8e593e9c35 | |||
| 0a09363db7 | |||
| caa0b6c804 | |||
| 8f92cf1074 | |||
| 8c7fa4cf4c | |||
| d0bd849be6 | |||
| 0a98efeea9 | |||
| 93cfc777f9 | |||
| b0b96c9838 | |||
| 8bbf5ff3f1 | |||
| d15e673a19 | |||
| 572fbc9705 | |||
| f371b513d1 | |||
| ec8e9b2715 | |||
| aaf039bcff | |||
| 05679e70d0 | |||
| 8e4606d104 | |||
| 54ca6c7059 | |||
| e5d3803fc1 | |||
| 6e3b4cf1a1 | |||
| c3011813b0 | |||
| ccceadbd24 | |||
| e1fc7119bc | |||
| 06a0377963 | |||
| add10df5ff | |||
| 62a5509390 | |||
| 54805d99a0 | |||
| 284e20a290 | |||
| 0a32c1124e | |||
| fc9dd99dea | |||
| 2727af43d4 | |||
| 4d0163d8af | |||
| d1e2ee452f | |||
| b5127d95ff | |||
| 174a31b49a | |||
| ebc653a584 | |||
| 746b4dfc04 | |||
| e5da0eb5f8 | |||
| ef5f547d27 | |||
| f4044ebcd9 | |||
| bc7d8295ba | |||
| 71fb7fadff | |||
| be240795e2 | |||
| cf5def05a6 | |||
| d3b4105f75 | |||
| 66bc258f81 | |||
| 908aecfd1c | |||
| ad802a3ad0 | |||
| 0aa056fcc5 | |||
| 1b2bc8ee27 | |||
| f01e1e5bda | |||
| 287039a8f3 | |||
| ad1d104d85 | |||
| 92af7455ad | |||
| b6b6acf1d9 | |||
| 5187641e25 | |||
| 41779866c4 | |||
| f800222781 | |||
| 0c364b2813 | |||
| 7dbb8c1377 | |||
| 6a0c101b08 | |||
| f240f2100c | |||
| 2b91ced1b7 | |||
| b7f1defbf3 | |||
| 2946a0aa25 | |||
| b043126031 | |||
| 4d58b56d54 | |||
| 025e8d7645 | |||
| e7abe1c606 | |||
| ea1f086289 | |||
| b1e8f2f887 | |||
| 45adc49683 | |||
| 2409984aab | |||
| 8f9eeb8055 | |||
| a8d5f185c2 | |||
| bbb418f98f | |||
| f8eb680559 | |||
| da5fa806d7 | |||
| 88f6a3d1b9 | |||
| 475880c0a8 | |||
| faf418eac0 | |||
| f35b8dfec5 | |||
| 14fcfb8348 | |||
| f84c4aca72 | |||
| dad7798da9 | |||
| 79af667b7a | |||
| d84cb5b190 | |||
| 7c18f25508 | |||
| 085de606ee | |||
| c7ac90def4 | |||
| bb36ce61bc | |||
| a35a876094 | |||
| f38c6c6d1c | |||
| f6a16950f2 | |||
| ddb2f63f7b | |||
| bf8e541221 | |||
| 4a2cf597c2 | |||
| 27370559d3 | |||
| a134bfac42 | |||
| d5e21d5003 | |||
| 85abb1122f | |||
| 0257362a86 | |||
| 1872672d0c | |||
| 644655662e | |||
| 508bbb4fb4 | |||
| cb9df61a98 | |||
| ab976e56af | |||
| df1cc2ee0b | |||
| af6daa273e | |||
| 05803fb5d5 | |||
| 5a37091bb0 |
@@ -31,3 +31,6 @@ v2/test/kitchensink/frontend/package.json.md5
|
||||
v2/cmd/wails/internal/commands/initialise/templates/testtemplates/
|
||||
.env
|
||||
/website/static/img/.cache.json
|
||||
|
||||
/v3/.task
|
||||
/v3/examples/build/bin/testapp
|
||||
|
||||
+2
-2
@@ -30,8 +30,8 @@
|
||||
<img alt="Slack" src="https://img.shields.io/badge/slack-gophers%2Fwails%20-blue?logo=slack"/>
|
||||
</a>
|
||||
<br/>
|
||||
<a href="https://github.com/wailsapp/wails/actions/workflows/build.yml" rel="nofollow">
|
||||
<img src="https://img.shields.io/github/workflow/status/wailsapp/wails/Build?logo=github" alt="Build" />
|
||||
<a href="https://github.com/wailsapp/wails/actions/workflows/build-and-test.yml" rel="nofollow">
|
||||
<img src="https://img.shields.io/github/actions/workflow/status/wailsapp/wails/build-and-test.yml?branch=master&logo=Github" alt="Build" />
|
||||
</a>
|
||||
<a href="https://github.com/wailsapp/wails/tags" rel="nofollow">
|
||||
<img alt="GitHub tag (latest SemVer pre-release)" src="https://img.shields.io/github/v/tag/wailsapp/wails?include_prereleases&label=version"/>
|
||||
|
||||
+2
-2
@@ -30,8 +30,8 @@
|
||||
<img alt="Slack" src="https://img.shields.io/badge/slack-gophers%2Fwails%20-blue?logo=slack"/>
|
||||
</a>
|
||||
<br/>
|
||||
<a href="https://github.com/wailsapp/wails/actions/workflows/build.yml" rel="nofollow">
|
||||
<img src="https://img.shields.io/github/workflow/status/wailsapp/wails/Build?logo=github" alt="Build" />
|
||||
<a href="https://github.com/wailsapp/wails/actions/workflows/build-and-test.yml" rel="nofollow">
|
||||
<img src="https://img.shields.io/github/actions/workflow/status/wailsapp/wails/build-and-test.yml?branch=master&logo=Github" alt="Build" />
|
||||
</a>
|
||||
<a href="https://github.com/wailsapp/wails/tags" rel="nofollow">
|
||||
<img alt="GitHub tag (latest SemVer pre-release)" src="https://img.shields.io/github/v/tag/wailsapp/wails?include_prereleases&label=version"/>
|
||||
|
||||
@@ -28,8 +28,8 @@
|
||||
<img alt="Slack" src="https://img.shields.io/badge/slack-gophers%2Fwails%20-blue?logo=slack"/>
|
||||
</a>
|
||||
<br/>
|
||||
<a href="https://github.com/wailsapp/wails/actions/workflows/build.yml" rel="nofollow">
|
||||
<img src="https://img.shields.io/github/workflow/status/wailsapp/wails/Build?logo=github" alt="Build" />
|
||||
<a href="https://github.com/wailsapp/wails/actions/workflows/build-and-test.yml" rel="nofollow">
|
||||
<img src="https://img.shields.io/github/actions/workflow/status/wailsapp/wails/build-and-test.yml?branch=master&logo=Github" alt="Build" />
|
||||
</a>
|
||||
<a href="https://github.com/wailsapp/wails/tags" rel="nofollow">
|
||||
<img alt="GitHub tag (latest SemVer pre-release)" src="https://img.shields.io/github/v/tag/wailsapp/wails?include_prereleases&label=version"/>
|
||||
|
||||
+2
-2
@@ -30,8 +30,8 @@
|
||||
<img alt="Slack" src="https://img.shields.io/badge/slack-gophers%2Fwails%20-blue?logo=slack"/>
|
||||
</a>
|
||||
<br/>
|
||||
<a href="https://github.com/wailsapp/wails/actions/workflows/build.yml" rel="nofollow">
|
||||
<img src="https://img.shields.io/github/workflow/status/wailsapp/wails/Build?logo=github" alt="Build" />
|
||||
<a href="https://github.com/wailsapp/wails/actions/workflows/build-and-test.yml" rel="nofollow">
|
||||
<img src="https://img.shields.io/github/actions/workflow/status/wailsapp/wails/build-and-test.yml?branch=master&logo=Github" alt="Build" />
|
||||
</a>
|
||||
<a href="https://github.com/wailsapp/wails/tags" rel="nofollow">
|
||||
<img alt="GitHub tag (latest SemVer pre-release)" src="https://img.shields.io/github/v/tag/wailsapp/wails?include_prereleases&label=version"/>
|
||||
|
||||
@@ -141,7 +141,7 @@ func (a *App) start() error {
|
||||
// Defer the shutdown
|
||||
defer a.shutdown()
|
||||
|
||||
// Run the renderer
|
||||
// run the renderer
|
||||
err = a.renderer.Run()
|
||||
if err != nil {
|
||||
return err
|
||||
|
||||
+1
-1
@@ -55,7 +55,7 @@ func newIPCMessage(incomingMessage string, responseFunction func(*ipcResponse) e
|
||||
// hasCallbackID checks if the message can send an error back to the frontend
|
||||
func (m *ipcMessage) hasCallbackID() error {
|
||||
if m.CallbackID == "" {
|
||||
return fmt.Errorf("attempted to return error to message with no Callback ID")
|
||||
return fmt.Errorf("attempted to return error to message with no callback ID")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -186,7 +186,7 @@ func (w *WebView) evalJSSync(js string) error {
|
||||
|
||||
go func() {
|
||||
exit := false
|
||||
// We are done when we receive the Callback ID
|
||||
// We are done when we receive the callback ID
|
||||
w.log.Debug("SyncJS: sending with ID = " + ID)
|
||||
w.eventManager.On(ID, func(...interface{}) {
|
||||
w.log.Debug("SyncJS: Got callback ID = " + ID)
|
||||
@@ -361,7 +361,7 @@ func (w *WebView) focus() {
|
||||
|
||||
// callback sends a callback to the frontend
|
||||
func (w *WebView) callback(data string) error {
|
||||
callbackCMD := fmt.Sprintf("window.wails._.Callback('%s');", data)
|
||||
callbackCMD := fmt.Sprintf("window.wails._.callback('%s');", data)
|
||||
return w.evalJS(callbackCMD)
|
||||
}
|
||||
|
||||
|
||||
@@ -2,14 +2,15 @@ package flags
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/leaanthony/slicer"
|
||||
"github.com/wailsapp/wails/v2/internal/system"
|
||||
"github.com/wailsapp/wails/v2/pkg/commands/build"
|
||||
"github.com/wailsapp/wails/v2/pkg/commands/buildtags"
|
||||
"os"
|
||||
"os/exec"
|
||||
"runtime"
|
||||
"strings"
|
||||
|
||||
"github.com/leaanthony/slicer"
|
||||
"github.com/wailsapp/wails/v2/internal/system"
|
||||
"github.com/wailsapp/wails/v2/pkg/commands/build"
|
||||
"github.com/wailsapp/wails/v2/pkg/commands/buildtags"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -51,7 +52,6 @@ type Build struct {
|
||||
}
|
||||
|
||||
func (b *Build) Default() *Build {
|
||||
|
||||
defaultPlatform := os.Getenv("GOOS")
|
||||
if defaultPlatform == "" {
|
||||
defaultPlatform = runtime.GOOS
|
||||
@@ -64,13 +64,13 @@ func (b *Build) Default() *Build {
|
||||
defaultArch = runtime.GOARCH
|
||||
}
|
||||
}
|
||||
b.defaultArch = defaultArch
|
||||
platform := defaultPlatform + "/" + defaultArch
|
||||
|
||||
result := &Build{
|
||||
Platform: platform,
|
||||
Platform: defaultPlatform + "/" + defaultArch,
|
||||
WebView2: "download",
|
||||
GarbleArgs: "-literals -tiny -seed=random",
|
||||
|
||||
defaultArch: defaultArch,
|
||||
}
|
||||
result.BuildCommon = result.BuildCommon.Default()
|
||||
return result
|
||||
|
||||
@@ -1 +1 @@
|
||||
v2.2.0
|
||||
v2.3.1
|
||||
@@ -4,12 +4,13 @@ import (
|
||||
"context"
|
||||
"embed"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/wailsapp/wails/v2/pkg/application"
|
||||
"github.com/wailsapp/wails/v2/pkg/menu"
|
||||
"github.com/wailsapp/wails/v2/pkg/options"
|
||||
"github.com/wailsapp/wails/v2/pkg/options/windows"
|
||||
"github.com/wailsapp/wails/v2/pkg/runtime"
|
||||
"time"
|
||||
)
|
||||
|
||||
//go:embed all:frontend/dist
|
||||
@@ -52,7 +53,7 @@ func main() {
|
||||
// create windows programmatically and be able to show/hide
|
||||
// them from the systray with something like:
|
||||
//
|
||||
// myWindow := mainApp.NewWindow(...)
|
||||
// myWindow := mainApp.NewWebviewWindow(...)
|
||||
// mainApp.NewSystemTray(&options.SystemTray{
|
||||
// OnLeftClick: func() {
|
||||
// myWindow.SetVisibility(!myWindow.IsVisible())
|
||||
|
||||
@@ -12,8 +12,9 @@ import (
|
||||
"os"
|
||||
"path/filepath"
|
||||
|
||||
"github.com/wailsapp/wails/v2/pkg/assetserver"
|
||||
|
||||
"github.com/wailsapp/wails/v2/internal/binding"
|
||||
"github.com/wailsapp/wails/v2/internal/frontend/assetserver"
|
||||
"github.com/wailsapp/wails/v2/internal/frontend/desktop"
|
||||
"github.com/wailsapp/wails/v2/internal/frontend/devserver"
|
||||
"github.com/wailsapp/wails/v2/internal/frontend/dispatcher"
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
#define WindowStartsMinimised 2
|
||||
#define WindowStartsFullscreen 3
|
||||
|
||||
WailsContext* Create(const char* title, int width, int height, int frameless, int resizable, int fullscreen, int fullSizeContent, int hideTitleBar, int titlebarAppearsTransparent, int hideTitle, int useToolbar, int hideToolbarSeparator, int webviewIsTransparent, int alwaysOnTop, int hideWindowOnClose, const char *appearance, int windowIsTranslucent, int debug, int windowStartState, int startsHidden, int minWidth, int minHeight, int maxWidth, int maxHeight);
|
||||
WailsContext* Create(const char* title, int width, int height, int frameless, int resizable, int fullscreen, int fullSizeContent, int hideTitleBar, int titlebarAppearsTransparent, int hideTitle, int useToolbar, int hideToolbarSeparator, int webviewIsTransparent, int alwaysOnTop, int hideWindowOnClose, const char *appearance, int windowIsTranslucent, int debug, int windowStartState, int startsHidden, int minWidth, int minHeight, int maxWidth, int maxHeight, bool fraudulentWebsiteWarningEnabled);
|
||||
void Run(void*, const char* url);
|
||||
|
||||
void SetTitle(void* ctx, const char *title);
|
||||
@@ -48,11 +48,6 @@ const bool IsFullScreen(void *ctx);
|
||||
const bool IsMinimised(void *ctx);
|
||||
const bool IsMaximised(void *ctx);
|
||||
|
||||
void ProcessURLDidReceiveResponse(void *inctx, unsigned long long requestId, int statusCode, void *headersString, int headersStringLength);
|
||||
bool ProcessURLDidReceiveData(void *inctx, unsigned long long requestId, void* data, int datalength);
|
||||
void ProcessURLDidFinish(void *inctx, unsigned long long requestId);
|
||||
int ProcessURLRequestReadBodyStream(void *inctx, unsigned long long requestId, void *buf, int bufLen);
|
||||
|
||||
/* Dialogs */
|
||||
|
||||
void MessageDialog(void *inctx, const char* dialogType, const char* title, const char* message, const char* button1, const char* button2, const char* button3, const char* button4, const char* defaultButton, const char* cancelButton, void* iconData, int iconDataLength);
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
#import "WailsMenu.h"
|
||||
#import "WailsMenuItem.h"
|
||||
|
||||
WailsContext* Create(const char* title, int width, int height, int frameless, int resizable, int fullscreen, int fullSizeContent, int hideTitleBar, int titlebarAppearsTransparent, int hideTitle, int useToolbar, int hideToolbarSeparator, int webviewIsTransparent, int alwaysOnTop, int hideWindowOnClose, const char *appearance, int windowIsTranslucent, int debug, int windowStartState, int startsHidden, int minWidth, int minHeight, int maxWidth, int maxHeight) {
|
||||
WailsContext* Create(const char* title, int width, int height, int frameless, int resizable, int fullscreen, int fullSizeContent, int hideTitleBar, int titlebarAppearsTransparent, int hideTitle, int useToolbar, int hideToolbarSeparator, int webviewIsTransparent, int alwaysOnTop, int hideWindowOnClose, const char *appearance, int windowIsTranslucent, int debug, int windowStartState, int startsHidden, int minWidth, int minHeight, int maxWidth, int maxHeight, bool fraudulentWebsiteWarningEnabled) {
|
||||
|
||||
[NSApplication sharedApplication];
|
||||
|
||||
@@ -25,7 +25,7 @@ WailsContext* Create(const char* title, int width, int height, int frameless, in
|
||||
fullscreen = 1;
|
||||
}
|
||||
|
||||
[result CreateWindow:width :height :frameless :resizable :fullscreen :fullSizeContent :hideTitleBar :titlebarAppearsTransparent :hideTitle :useToolbar :hideToolbarSeparator :webviewIsTransparent :hideWindowOnClose :safeInit(appearance) :windowIsTranslucent :minWidth :minHeight :maxWidth :maxHeight];
|
||||
[result CreateWindow:width :height :frameless :resizable :fullscreen :fullSizeContent :hideTitleBar :titlebarAppearsTransparent :hideTitle :useToolbar :hideToolbarSeparator :webviewIsTransparent :hideWindowOnClose :safeInit(appearance) :windowIsTranslucent :minWidth :minHeight :maxWidth :maxHeight :fraudulentWebsiteWarningEnabled];
|
||||
[result SetTitle:safeInit(title)];
|
||||
[result Center];
|
||||
|
||||
@@ -52,36 +52,6 @@ WailsContext* Create(const char* title, int width, int height, int frameless, in
|
||||
return result;
|
||||
}
|
||||
|
||||
void ProcessURLDidReceiveResponse(void *inctx, unsigned long long requestId, int statusCode, void *headersString, int headersStringLength) {
|
||||
WailsContext *ctx = (__bridge WailsContext*) inctx;
|
||||
@autoreleasepool {
|
||||
NSData *nsHeadersJSON = [NSData dataWithBytes:headersString length:headersStringLength];
|
||||
[ctx processURLDidReceiveResponse:requestId :statusCode :nsHeadersJSON];
|
||||
}
|
||||
}
|
||||
|
||||
bool ProcessURLDidReceiveData(void *inctx, unsigned long long requestId, void* data, int datalength) {
|
||||
WailsContext *ctx = (__bridge WailsContext*) inctx;
|
||||
@autoreleasepool {
|
||||
NSData *nsdata = [NSData dataWithBytes:data length:datalength];
|
||||
return [ctx processURLDidReceiveData:requestId :nsdata];
|
||||
}
|
||||
}
|
||||
|
||||
void ProcessURLDidFinish(void *inctx, unsigned long long requestId) {
|
||||
WailsContext *ctx = (__bridge WailsContext*) inctx;
|
||||
@autoreleasepool {
|
||||
[ctx processURLDidFinish:requestId];
|
||||
}
|
||||
}
|
||||
|
||||
int ProcessURLRequestReadBodyStream(void *inctx, unsigned long long requestId, void *buf, int bufLen) {
|
||||
WailsContext *ctx = (__bridge WailsContext*) inctx;
|
||||
@autoreleasepool {
|
||||
return [ctx processURLRequestReadBodyStream:requestId :buf :bufLen];
|
||||
}
|
||||
}
|
||||
|
||||
void ExecJS(void* inctx, const char *script) {
|
||||
WailsContext *ctx = (__bridge WailsContext*) inctx;
|
||||
NSString *nsscript = safeInit(script);
|
||||
|
||||
@@ -47,9 +47,6 @@
|
||||
@property bool debug;
|
||||
|
||||
@property (retain) WKUserContentController* userContentController;
|
||||
@property (retain) NSLock *urlRequestsLock;
|
||||
@property unsigned long long urlRequestsId;
|
||||
@property (retain) NSMutableDictionary *urlRequests;
|
||||
|
||||
@property (retain) NSMenu* applicationMenu;
|
||||
|
||||
@@ -57,7 +54,7 @@
|
||||
@property (retain) NSString* aboutTitle;
|
||||
@property (retain) NSString* aboutDescription;
|
||||
|
||||
- (void) CreateWindow:(int)width :(int)height :(bool)frameless :(bool)resizable :(bool)fullscreen :(bool)fullSizeContent :(bool)hideTitleBar :(bool)titlebarAppearsTransparent :(bool)hideTitle :(bool)useToolbar :(bool)hideToolbarSeparator :(bool)webviewIsTransparent :(bool)hideWindowOnClose :(NSString *)appearance :(bool)windowIsTranslucent :(int)minWidth :(int)minHeight :(int)maxWidth :(int)maxHeight;
|
||||
- (void) CreateWindow:(int)width :(int)height :(bool)frameless :(bool)resizable :(bool)fullscreen :(bool)fullSizeContent :(bool)hideTitleBar :(bool)titlebarAppearsTransparent :(bool)hideTitle :(bool)useToolbar :(bool)hideToolbarSeparator :(bool)webviewIsTransparent :(bool)hideWindowOnClose :(NSString *)appearance :(bool)windowIsTranslucent :(int)minWidth :(int)minHeight :(int)maxWidth :(int)maxHeight :(bool)fraudulentWebsiteWarningEnabled;
|
||||
- (void) SetSize:(int)width :(int)height;
|
||||
- (void) SetPosition:(int)x :(int) y;
|
||||
- (void) SetMinSize:(int)minWidth :(int)minHeight;
|
||||
@@ -89,10 +86,6 @@
|
||||
- (void) SaveFileDialog :(NSString*)title :(NSString*)defaultFilename :(NSString*)defaultDirectory :(bool)canCreateDirectories :(bool)treatPackagesAsDirectories :(bool)showHiddenFiles :(NSString*)filters;
|
||||
|
||||
- (void) loadRequest:(NSString*)url;
|
||||
- (void) processURLDidReceiveResponse:(unsigned long long)requestId :(int)statusCode :(NSData *)headersJSON;
|
||||
- (bool) processURLDidReceiveData:(unsigned long long)requestId :(NSData *)data;
|
||||
- (void) processURLDidFinish:(unsigned long long)requestId;
|
||||
- (int) processURLRequestReadBodyStream:(unsigned long long)requestId :(void *)buf :(int)bufLen;
|
||||
- (void) ExecJS:(NSString*)script;
|
||||
- (NSScreen*) getCurrentScreen;
|
||||
|
||||
|
||||
@@ -108,7 +108,6 @@ typedef void (^schemeTaskCaller)(id<WKURLSchemeTask>);
|
||||
[self.mainWindow release];
|
||||
[self.mouseEvent release];
|
||||
[self.userContentController release];
|
||||
[self.urlRequests release];
|
||||
[self.applicationMenu release];
|
||||
[super dealloc];
|
||||
}
|
||||
@@ -137,10 +136,7 @@ typedef void (^schemeTaskCaller)(id<WKURLSchemeTask>);
|
||||
return NO;
|
||||
}
|
||||
|
||||
- (void) CreateWindow:(int)width :(int)height :(bool)frameless :(bool)resizable :(bool)fullscreen :(bool)fullSizeContent :(bool)hideTitleBar :(bool)titlebarAppearsTransparent :(bool)hideTitle :(bool)useToolbar :(bool)hideToolbarSeparator :(bool)webviewIsTransparent :(bool)hideWindowOnClose :(NSString*)appearance :(bool)windowIsTranslucent :(int)minWidth :(int)minHeight :(int)maxWidth :(int)maxHeight {
|
||||
self.urlRequestsId = 0;
|
||||
self.urlRequests = [NSMutableDictionary new];
|
||||
|
||||
- (void) CreateWindow:(int)width :(int)height :(bool)frameless :(bool)resizable :(bool)fullscreen :(bool)fullSizeContent :(bool)hideTitleBar :(bool)titlebarAppearsTransparent :(bool)hideTitle :(bool)useToolbar :(bool)hideToolbarSeparator :(bool)webviewIsTransparent :(bool)hideWindowOnClose :(NSString*)appearance :(bool)windowIsTranslucent :(int)minWidth :(int)minHeight :(int)maxWidth :(int)maxHeight :(bool)fraudulentWebsiteWarningEnabled {
|
||||
NSWindowStyleMask styleMask = 0;
|
||||
|
||||
if( !frameless ) {
|
||||
@@ -220,7 +216,11 @@ typedef void (^schemeTaskCaller)(id<WKURLSchemeTask>);
|
||||
[config setURLSchemeHandler:self forURLScheme:@"wails"];
|
||||
|
||||
// [config.preferences setValue:[NSNumber numberWithBool:true] forKey:@"developerExtrasEnabled"];
|
||||
|
||||
|
||||
if (@available(macOS 10.15, *)) {
|
||||
config.preferences.fraudulentWebsiteWarningEnabled = fraudulentWebsiteWarningEnabled;
|
||||
}
|
||||
|
||||
WKUserContentController* userContentController = [WKUserContentController new];
|
||||
[userContentController addScriptMessageHandler:self name:@"external"];
|
||||
config.userContentController = userContentController;
|
||||
@@ -427,156 +427,19 @@ typedef void (^schemeTaskCaller)(id<WKURLSchemeTask>);
|
||||
}];
|
||||
}
|
||||
|
||||
- (void) processURLDidReceiveResponse:(unsigned long long)requestId :(int)statusCode :(NSData *)headersJSON {
|
||||
[self processURLSchemeTaskCall:requestId :^(id<WKURLSchemeTask> urlSchemeTask) {
|
||||
NSDictionary *headerFields = [NSJSONSerialization JSONObjectWithData: headersJSON options: NSJSONReadingMutableContainers error: nil];
|
||||
NSHTTPURLResponse *response = [[[NSHTTPURLResponse alloc] initWithURL:urlSchemeTask.request.URL statusCode:statusCode HTTPVersion:@"HTTP/1.1" headerFields:headerFields] autorelease];
|
||||
|
||||
[urlSchemeTask didReceiveResponse:response];
|
||||
}];
|
||||
}
|
||||
|
||||
- (bool) processURLDidReceiveData:(unsigned long long)requestId :(NSData *)data {
|
||||
return [self processURLSchemeTaskCall:requestId :^(id<WKURLSchemeTask> urlSchemeTask) {
|
||||
[urlSchemeTask didReceiveData:data];
|
||||
}];
|
||||
}
|
||||
|
||||
- (void) processURLDidFinish:(unsigned long long)requestId {
|
||||
[self processURLSchemeTaskCall:requestId :^(id<WKURLSchemeTask> urlSchemeTask) {
|
||||
[urlSchemeTask didFinish];
|
||||
}];
|
||||
|
||||
NSNumber *key = [NSNumber numberWithUnsignedLongLong:requestId];
|
||||
[self removeURLSchemeTask:key];
|
||||
}
|
||||
|
||||
- (int) processURLRequestReadBodyStream:(unsigned long long)requestId :(void *)buf :(int)bufLen {
|
||||
int res = 0;
|
||||
int *pRes = &res;
|
||||
|
||||
bool hasRequest = [self processURLSchemeTaskCall:requestId :^(id<WKURLSchemeTask> urlSchemeTask) {
|
||||
NSInputStream *stream = urlSchemeTask.request.HTTPBodyStream;
|
||||
if (!stream) {
|
||||
*pRes = -3;
|
||||
} else {
|
||||
NSStreamStatus status = stream.streamStatus;
|
||||
if (status == NSStreamStatusAtEnd) {
|
||||
*pRes = 0;
|
||||
} else if (status != NSStreamStatusOpen) {
|
||||
*pRes = -4;
|
||||
} else if (!stream.hasBytesAvailable) {
|
||||
*pRes = 0;
|
||||
} else {
|
||||
*pRes = [stream read:buf maxLength:bufLen];
|
||||
}
|
||||
}
|
||||
}];
|
||||
|
||||
if (!hasRequest) {
|
||||
res = -2;
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
- (void)webView:(nonnull WKWebView *)webView startURLSchemeTask:(nonnull id<WKURLSchemeTask>)urlSchemeTask {
|
||||
// This callback is run with an autorelease pool
|
||||
const char *url = [urlSchemeTask.request.URL.absoluteString UTF8String];
|
||||
const char *method = [urlSchemeTask.request.HTTPMethod UTF8String];
|
||||
const char *headerJSON = "";
|
||||
const void *body = nil;
|
||||
int bodyLen = 0;
|
||||
int hasBodyStream = 0;
|
||||
|
||||
NSData *headers = [NSJSONSerialization dataWithJSONObject: urlSchemeTask.request.allHTTPHeaderFields options:0 error: nil];
|
||||
if (headers) {
|
||||
NSString* headerString = [[[NSString alloc] initWithData:headers encoding:NSUTF8StringEncoding] autorelease];
|
||||
headerJSON = [headerString UTF8String];
|
||||
}
|
||||
|
||||
if (urlSchemeTask.request.HTTPBody) {
|
||||
body = urlSchemeTask.request.HTTPBody.bytes;
|
||||
bodyLen = urlSchemeTask.request.HTTPBody.length;
|
||||
} else if (urlSchemeTask.request.HTTPBodyStream) {
|
||||
hasBodyStream = 1;
|
||||
[urlSchemeTask.request.HTTPBodyStream open];
|
||||
}
|
||||
|
||||
unsigned long long requestId;
|
||||
@synchronized(self.urlRequests) {
|
||||
self.urlRequestsId++;
|
||||
requestId = self.urlRequestsId;
|
||||
NSNumber *key = [NSNumber numberWithUnsignedLongLong:requestId];
|
||||
self.urlRequests[key] = urlSchemeTask;
|
||||
}
|
||||
|
||||
processURLRequest(self, requestId, url, method, headerJSON, body, bodyLen, hasBodyStream);
|
||||
processURLRequest(self, urlSchemeTask);
|
||||
}
|
||||
|
||||
- (void)webView:(nonnull WKWebView *)webView stopURLSchemeTask:(nonnull id<WKURLSchemeTask>)urlSchemeTask {
|
||||
NSArray<NSNumber*> *keys;
|
||||
@synchronized(self.urlRequests) {
|
||||
keys = [self.urlRequests allKeys];
|
||||
}
|
||||
|
||||
for (NSNumber *key in keys) {
|
||||
if (self.urlRequests[key] == urlSchemeTask) {
|
||||
[self removeURLSchemeTask:key];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
- (void) removeURLSchemeTask:(NSNumber *)urlSchemeTaskKey {
|
||||
id<WKURLSchemeTask> urlSchemeTask = nil;
|
||||
@synchronized(self.urlRequests) {
|
||||
urlSchemeTask = self.urlRequests[urlSchemeTaskKey];
|
||||
}
|
||||
|
||||
if (!urlSchemeTask) {
|
||||
return;
|
||||
}
|
||||
|
||||
NSInputStream *stream = urlSchemeTask.request.HTTPBodyStream;
|
||||
if (stream) {
|
||||
[stream close];
|
||||
}
|
||||
|
||||
@synchronized(self.urlRequests) {
|
||||
[self.urlRequests removeObjectForKey:urlSchemeTaskKey];
|
||||
}
|
||||
}
|
||||
|
||||
- (bool)processURLSchemeTaskCall:(unsigned long long)requestId :(schemeTaskCaller)fn {
|
||||
NSNumber *key = [NSNumber numberWithUnsignedLongLong:requestId];
|
||||
|
||||
id<WKURLSchemeTask> urlSchemeTask;
|
||||
@synchronized(self.urlRequests) {
|
||||
urlSchemeTask = self.urlRequests[key];
|
||||
}
|
||||
|
||||
if (urlSchemeTask == nil) {
|
||||
// Stopped task, drop content...
|
||||
return false;
|
||||
}
|
||||
|
||||
@try {
|
||||
fn(urlSchemeTask);
|
||||
} @catch (NSException *exception) {
|
||||
[self removeURLSchemeTask:key];
|
||||
|
||||
// This is very bad to detect a stopped schemeTask this should be implemented in a better way
|
||||
// But it seems to be very tricky to not deadlock when keeping a lock curing executing fn()
|
||||
// It seems like those call switch the thread back to the main thread and then deadlocks when they reentrant want
|
||||
// to get the lock again to start another request or stop it.
|
||||
if ([exception.reason isEqualToString: @"This task has already been stopped"]) {
|
||||
return false;
|
||||
NSStreamStatus status = stream.streamStatus;
|
||||
if (status != NSStreamStatusClosed && status != NSStreamStatusNotOpen) {
|
||||
[stream close];
|
||||
}
|
||||
|
||||
@throw exception;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
- (void)webView:(WKWebView *)webView didFinishNavigation:(WKNavigation *)navigation {
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
//go:build darwin
|
||||
|
||||
package darwin
|
||||
|
||||
import (
|
||||
"os/exec"
|
||||
)
|
||||
|
||||
func (f *Frontend) ClipboardGetText() (string, error) {
|
||||
pasteCmd := exec.Command("pbpaste")
|
||||
out, err := pasteCmd.Output()
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return string(out), nil
|
||||
}
|
||||
|
||||
func (f *Frontend) ClipboardSetText(text string) error {
|
||||
|
||||
copyCmd := exec.Command("pbcopy")
|
||||
in, err := copyCmd.StdinPipe()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := copyCmd.Start(); err != nil {
|
||||
return err
|
||||
}
|
||||
if _, err := in.Write([]byte(text)); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := in.Close(); err != nil {
|
||||
return err
|
||||
}
|
||||
return copyCmd.Wait()
|
||||
}
|
||||
@@ -19,13 +19,18 @@ import (
|
||||
"fmt"
|
||||
"html/template"
|
||||
"log"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"strconv"
|
||||
"unsafe"
|
||||
|
||||
"github.com/wailsapp/wails/v2/pkg/assetserver"
|
||||
"github.com/wailsapp/wails/v2/pkg/assetserver/webview"
|
||||
|
||||
"github.com/wailsapp/wails/v2/pkg/assetserver"
|
||||
|
||||
"github.com/wailsapp/wails/v2/internal/binding"
|
||||
"github.com/wailsapp/wails/v2/internal/frontend"
|
||||
"github.com/wailsapp/wails/v2/internal/frontend/assetserver"
|
||||
"github.com/wailsapp/wails/v2/internal/frontend/runtime"
|
||||
"github.com/wailsapp/wails/v2/internal/logger"
|
||||
"github.com/wailsapp/wails/v2/pkg/options"
|
||||
)
|
||||
@@ -33,7 +38,7 @@ import (
|
||||
const startURL = "wails://wails/"
|
||||
|
||||
var messageBuffer = make(chan string, 100)
|
||||
var requestBuffer = make(chan *wkWebViewRequest, 100)
|
||||
var requestBuffer = make(chan webview.Request, 100)
|
||||
var callbackBuffer = make(chan uint, 10)
|
||||
|
||||
type Frontend struct {
|
||||
@@ -86,16 +91,15 @@ func NewFrontend(ctx context.Context, appoptions *options.App, myLogger *logger.
|
||||
} else {
|
||||
appBindings.DB().UpdateObfuscatedCallMap()
|
||||
}
|
||||
assets, err := assetserver.NewAssetServerMainPage(ctx, bindings, appoptions)
|
||||
|
||||
assets, err := assetserver.NewAssetServerMainPage(bindings, appoptions, ctx.Value("assetdir") != nil, myLogger, runtime.RuntimeAssetsBundle)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
assets.ExpectedWebViewHost = result.startURL.Host
|
||||
result.assets = assets
|
||||
|
||||
// Start 10 processors to handle requests in parallel
|
||||
for i := 0; i < 10; i++ {
|
||||
go result.startRequestProcessor()
|
||||
}
|
||||
go result.startRequestProcessor()
|
||||
}
|
||||
|
||||
go result.startMessageProcessor()
|
||||
@@ -111,7 +115,8 @@ func (f *Frontend) startMessageProcessor() {
|
||||
}
|
||||
func (f *Frontend) startRequestProcessor() {
|
||||
for request := range requestBuffer {
|
||||
f.processRequest(request)
|
||||
f.assets.ServeWebViewRequest(request)
|
||||
request.Release()
|
||||
}
|
||||
}
|
||||
func (f *Frontend) startCallbackProcessor() {
|
||||
@@ -324,7 +329,7 @@ func (f *Frontend) processMessage(message string) {
|
||||
|
||||
switch result[0] {
|
||||
case 'c':
|
||||
// Callback from a method call
|
||||
// callback from a method call
|
||||
f.Callback(result[1:])
|
||||
default:
|
||||
f.logger.Info("Unknown message returned from dispatcher: %+v", result)
|
||||
@@ -334,38 +339,13 @@ func (f *Frontend) processMessage(message string) {
|
||||
}
|
||||
|
||||
func (f *Frontend) Callback(message string) {
|
||||
f.ExecJS(`window.wails.Callback(` + strconv.Quote(message) + `);`)
|
||||
f.ExecJS(`window.wails.callback(` + strconv.Quote(message) + `);`)
|
||||
}
|
||||
|
||||
func (f *Frontend) ExecJS(js string) {
|
||||
f.mainWindow.ExecJS(js)
|
||||
}
|
||||
|
||||
func (f *Frontend) processRequest(r *wkWebViewRequest) {
|
||||
rw := &wkWebViewResponseWriter{r: r}
|
||||
defer rw.Close()
|
||||
|
||||
f.assets.ProcessHTTPRequest(
|
||||
r.url,
|
||||
rw,
|
||||
func() (*http.Request, error) {
|
||||
req, err := r.GetHttpRequest()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if req.URL.Host != f.startURL.Host {
|
||||
if req.Body != nil {
|
||||
req.Body.Close()
|
||||
}
|
||||
|
||||
return nil, fmt.Errorf("Expected host '%s' in request, but was '%s'", f.startURL.Host, req.URL.Host)
|
||||
}
|
||||
return req, nil
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
//func (f *Frontend) processSystemEvent(message string) {
|
||||
// sl := strings.Split(message, ":")
|
||||
// if len(sl) != 2 {
|
||||
@@ -392,3 +372,8 @@ func processMessage(message *C.char) {
|
||||
func processCallback(callbackID uint) {
|
||||
callbackBuffer <- callbackID
|
||||
}
|
||||
|
||||
//export processURLRequest
|
||||
func processURLRequest(ctx unsafe.Pointer, wkURLSchemeTask unsafe.Pointer) {
|
||||
requestBuffer <- webview.NewRequest(wkURLSchemeTask)
|
||||
}
|
||||
|
||||
@@ -219,7 +219,7 @@ int main(int argc, const char * argv[]) {
|
||||
int windowStartState = 0;
|
||||
int startsHidden = 0;
|
||||
WailsContext *result = Create("OI OI!",400,400, frameless, resizable, fullscreen, fullSizeContent, hideTitleBar, titlebarAppearsTransparent, hideTitle, useToolbar, hideToolbarSeparator, webviewIsTransparent, alwaysOnTop, hideWindowOnClose, appearance, windowIsTranslucent, debug, windowStartState,
|
||||
startsHidden, 400, 400, 600, 600);
|
||||
startsHidden, 400, 400, 600, 600, false);
|
||||
SetBackgroundColour(result, 255, 0, 0, 255);
|
||||
void *m = NewMenu("");
|
||||
SetAbout(result, "Fake title", "I am a description", _Users_username_Pictures_SaltBae_png, _Users_username_Pictures_SaltBae_png_len);
|
||||
|
||||
@@ -15,7 +15,7 @@ extern "C"
|
||||
#endif
|
||||
|
||||
void processMessage(const char *);
|
||||
void processURLRequest(void*, unsigned long long, const char *, const char *, const char *, const void *, int, int);
|
||||
void processURLRequest(void *, void*);
|
||||
void processMessageDialogResponse(int);
|
||||
void processOpenFileDialogResponse(const char*);
|
||||
void processSaveFileDialogResponse(const char*);
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user