Compare commits

..

44 Commits

Author SHA1 Message Date
Lea Anthony 37b395c308 [v3] Add Naive build command 2023-01-22 20:40:35 +11:00
Lea Anthony 428584d583 [v3] Add TODO 2023-01-22 16:52:26 +11:00
Lea Anthony ee1978aa42 [v3] Initial template support (likely to change) 2023-01-22 15:39:57 +11:00
Sebastian Bauer 895d6d4b80 Size() calculates DPIs back to default space. (#2325) 2023-01-22 15:25:26 +11:00
github-actions[bot] a5ddce2c7c chore: update sponsors.svg (#2317)
Co-authored-by: leaanthony <leaanthony@users.noreply.github.com>
2023-01-22 15:25:04 +11:00
Richard Guay e4789750c8 Updating and Adding (#2324)
* Adding Tutorial link

* Fixed EmailIt, Modal File Manager, and ScriptBar descriptions and added BulletinBoard

Co-authored-by: Lea Anthony <lea.anthony@gmail.com>
2023-01-22 07:28:51 +11:00
Brian Dwyer f8c673874b Fix memory leak on Darwin when toggling system tray icon (#2322) 2023-01-21 15:46:06 +11:00
Lea Anthony 5ef32760f0 Update task 2023-01-18 22:08:25 +11:00
Lea Anthony 81645190f0 merge exp branch 2023-01-18 21:42:49 +11:00
Lea Anthony 18d0ed890a Merge branch 'blog/v3-roadmap' 2023-01-18 20:59:38 +11:00
Lea Anthony 2479603143 Add github issue link 2023-01-18 17:41:33 +11:00
Lea Anthony dbf6b3a718 updated 2023-01-18 07:57:10 +11:00
stffabi 45c3a501d9 [cli] Fix applying default arch to platform flag (#2309) 2023-01-17 20:39:15 +01:00
Lea Anthony 401165ce30 blog 2023-01-17 21:19:17 +11:00
stffabi caa0b6c804 [assetServer, darwin] Use AssetServer native WKWebView request handling (#2283) 2023-01-16 13:02:18 +01:00
stffabi 8f92cf1074 [assetHandler] Allow middleware to set the content-type for an assets file (#2286) 2023-01-16 21:05:25 +11:00
Gwyn 8c7fa4cf4c Updates all default gitignore templates to be newline terminated. (#2306)
This allows echoing new patterns to the end of the file without
causing a string concatenation error.
2023-01-16 21:02:52 +11:00
Oussama Sethoum d0bd849be6 Update events.mdx (#2300)
* Update events.mdx

* Add doc update to docs dir

Co-authored-by: Lea Anthony <lea.anthony@gmail.com>
2023-01-16 20:59:58 +11:00
stffabi 0a98efeea9 [runtime] Improve —wails-draggable by starting a drag immediately but only for the first click in a series (#2302)
This removes the sometime lagging experience when
starting to drag on Windows. But it's still possible to use
double-click events for adding e.g. a WindowToggleMaximise.
2023-01-16 20:56:13 +11:00
github-actions[bot] 93cfc777f9 chore: update sponsors.svg (#2293)
Co-authored-by: leaanthony <leaanthony@users.noreply.github.com>
2023-01-16 20:53:31 +11:00
stffabi d15e673a19 [windows] Some improvements to fullscreen (#2299) 2023-01-15 06:14:15 +01:00
Supian M ec8e9b2715 Fix Broken Badge (#2292) 2023-01-12 20:01:56 +11:00
stffabi aaf039bcff [windows] Disable frameless decorations during fullscreen (#2288)
Otherwise this leads to thin transparent lines on the window borders on older Windows versions.
2023-01-11 15:22:48 +01:00
stffabi 05679e70d0 [runtime] Frameless resize now sets the cursor on documentElement (#2289)
Otherwise if the body does not cover the full viewport the cursor won't
be shown outside of its rectangle.
2023-01-10 13:19:09 +01:00
stffabi 8e4606d104 [windows] Improve fullscreen mode for frameless windows (#2279)
* Improve fullscreen mode for frameless windows
* Set Window background color in addition to WebView2 background color
2023-01-09 12:15:43 +01:00
Lea Anthony 54ca6c7059 Refactor assetserver into pkg (#2260) 2023-01-08 11:25:21 +01:00
Lea Anthony 6e3b4cf1a1 Add Warmine to showcase 2023-01-08 12:53:14 +11:00
Zámbó, Levente c3011813b0 linux separate window c and go file (#2275) 2023-01-07 16:20:11 +11:00
Johannes Haseitl ccceadbd24 Replace more slack links with discord invites (#2256)
* Add Discord link and deprecate slack links

* More slack -> discord changes

Co-authored-by: Lea Anthony <lea.anthony@gmail.com>
2023-01-07 16:19:33 +11:00
Noah Hsu e1fc7119bc docs: fix admonitions syntax (#2263) 2023-01-07 15:36:37 +11:00
Zámbó, Levente add10df5ff fix missing bin dir on build hook (#2273)
* fix missing bin dir on build hook

* add fix to changelog
2023-01-07 06:51:01 +11:00
stffabi 284e20a290 Add EnableFraudulentWebsiteDetection to options (#2269)
This allows to explicitly opt-in to scan services for fraudulent
content, such as malware or phishing attempts.
2023-01-06 00:06:26 +11:00
Zámbó, Levente 0a32c1124e Add common text clipboard support (#2228) 2023-01-05 16:41:07 +11:00
Igor Sementsov fc9dd99dea Update troubleshooting.mdx (#2252)
* Update troubleshooting.mdx

https://github.com/wailsapp/wails/issues/2249

* Move guide to docs

Co-authored-by: Lea Anthony <lea.anthony@gmail.com>
2023-01-05 16:19:49 +11:00
希嘉嘉 2727af43d4 Update templates.mdx (#2230)
添加 solid 模版的中文描述信息。
2023-01-05 16:09:53 +11:00
github-actions[bot] 4d0163d8af chore: update sponsors.svg (#2271)
Co-authored-by: leaanthony <leaanthony@users.noreply.github.com>
2023-01-05 15:12:13 +11:00
stffabi ebc653a584 [windows] Add support for AdditionalBrowserArgs to the legacy Webview2Loader (#2267) 2023-01-02 22:41:56 +01:00
Zámbó, Levente ef5f547d27 Support GPU acceleration settings on Windows & Linux (#2266)
* support GPU acceleration settings Window & Linux

* fix linux empty option crash

* fix change linux gpu policy switch case

* add PR to changelog
2023-01-02 09:38:53 +11:00
Lea Anthony d3b4105f75 Chore/refactor assetserver (#2250)
* Remove context from API calls

* Remove logger dependency

* Remove fs dependency

* Remove runtime dependency

* Update Windows/Linux calls to NewAssetServerMainPage

* Add missing imports

* fix runtime import clash
2022-12-31 10:36:07 +11:00
stffabi 66bc258f81 [windows] Fix compile error for 386 platform (#2257) 2022-12-30 21:33:39 +01:00
Lea Anthony 908aecfd1c Update Changelog 2022-12-30 15:58:11 +11:00
Lea Anthony 0aa056fcc5 Bump version to v2.3.1 2022-12-30 07:38:22 +11:00
Lea Anthony 1b2bc8ee27 Remove old docs 2022-12-29 16:00:10 +11:00
Lea Anthony f01e1e5bda Update docs to v2.3.0 2022-12-29 15:59:38 +11:00
1457 changed files with 94817 additions and 1713 deletions
+3
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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"/>
+8 -8
View File
@@ -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
View File
@@ -1 +1 @@
v2.2.0
v2.3.1
+2 -1
View File
@@ -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
+2 -1
View File
@@ -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()
}
+17 -34
View File
@@ -19,13 +19,16 @@ 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/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 +36,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 +89,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 +113,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() {
@@ -341,31 +344,6 @@ 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 +370,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)
}
+1 -1
View File
@@ -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*);
@@ -67,6 +67,8 @@ func NewWindow(frontendOptions *options.App, debugMode bool) *Window {
title = c.String(frontendOptions.Title)
enableFraudulentWebsiteWarnings := C.bool(frontendOptions.EnableFraudulentWebsiteDetection)
if frontendOptions.Mac != nil {
mac := frontendOptions.Mac
if mac.TitleBar != nil {
@@ -85,7 +87,7 @@ func NewWindow(frontendOptions *options.App, debugMode bool) *Window {
var context *C.WailsContext = C.Create(title, width, height, frameless, resizable, fullscreen, fullSizeContent,
hideTitleBar, titlebarAppearsTransparent, hideTitle, useToolbar, hideToolbarSeparator, webviewIsTransparent,
alwaysOnTop, hideWindowOnClose, appearance, windowIsTranslucent, debug, windowStartState, startsHidden,
minWidth, minHeight, maxWidth, maxHeight)
minWidth, minHeight, maxWidth, maxHeight, enableFraudulentWebsiteWarnings)
// Create menu
result := &Window{
@@ -1,106 +0,0 @@
//go:build darwin
package darwin
/*
#cgo CFLAGS: -x objective-c
#cgo LDFLAGS: -framework Foundation -framework Cocoa -framework WebKit
#import "Application.h"
#include <stdlib.h>
*/
import "C"
import (
"bytes"
"encoding/json"
"fmt"
"io"
"net/http"
"unsafe"
)
//export processURLRequest
func processURLRequest(ctx unsafe.Pointer, requestId C.ulonglong, url *C.char, method *C.char, headers *C.char, body unsafe.Pointer, bodyLen C.int, hasBodyStream C.int) {
var bodyReader io.Reader
if body != nil && bodyLen != 0 {
bodyReader = bytes.NewReader(C.GoBytes(body, bodyLen))
} else if hasBodyStream != 0 {
bodyReader = &bodyStreamReader{id: requestId, ctx: ctx}
}
requestBuffer <- &wkWebViewRequest{
id: requestId,
url: C.GoString(url),
method: C.GoString(method),
headers: C.GoString(headers),
body: bodyReader,
ctx: ctx,
}
}
type wkWebViewRequest struct {
id C.ulonglong
url string
method string
headers string
body io.Reader
ctx unsafe.Pointer
}
func (r *wkWebViewRequest) GetHttpRequest() (*http.Request, error) {
req, err := http.NewRequest(r.method, r.url, r.body)
if err != nil {
return nil, err
}
if r.headers != "" {
var h map[string]string
if err := json.Unmarshal([]byte(r.headers), &h); err != nil {
return nil, fmt.Errorf("unable to unmarshal request headers: %s", err)
}
for k, v := range h {
req.Header.Add(k, v)
}
}
return req, nil
}
var _ io.Reader = &bodyStreamReader{}
type bodyStreamReader struct {
id C.ulonglong
ctx unsafe.Pointer
}
// Read implements io.Reader
func (r *bodyStreamReader) Read(p []byte) (n int, err error) {
var content unsafe.Pointer
var contentLen int
if p != nil {
content = unsafe.Pointer(&p[0])
contentLen = len(p)
}
res := C.ProcessURLRequestReadBodyStream(r.ctx, r.id, content, C.int(contentLen))
if res > 0 {
return int(res), nil
}
switch res {
case 0:
return 0, io.EOF
case -1:
return 0, fmt.Errorf("body: stream error")
case -2:
return 0, errRequestStopped
case -3:
return 0, fmt.Errorf("body: no stream defined")
case -4:
return 0, io.ErrClosedPipe
default:
return 0, fmt.Errorf("body: unknown error %d", res)
}
}
@@ -1,81 +0,0 @@
//go:build darwin
package darwin
/*
#cgo CFLAGS: -x objective-c
#cgo LDFLAGS: -framework Foundation -framework Cocoa -framework WebKit
#import "Application.h"
#include <stdlib.h>
*/
import "C"
import (
"encoding/json"
"errors"
"net/http"
"unsafe"
)
var (
errRequestStopped = errors.New("request has been stopped")
)
type wkWebViewResponseWriter struct {
r *wkWebViewRequest
header http.Header
wroteHeader bool
}
func (rw *wkWebViewResponseWriter) Header() http.Header {
if rw.header == nil {
rw.header = http.Header{}
}
return rw.header
}
func (rw *wkWebViewResponseWriter) Write(buf []byte) (int, error) {
rw.WriteHeader(http.StatusOK)
var content unsafe.Pointer
var contentLen int
if buf != nil {
content = unsafe.Pointer(&buf[0])
contentLen = len(buf)
}
if !C.ProcessURLDidReceiveData(rw.r.ctx, rw.r.id, content, C.int(contentLen)) {
return 0, errRequestStopped
}
return contentLen, nil
}
func (rw *wkWebViewResponseWriter) WriteHeader(code int) {
if rw.wroteHeader {
return
}
rw.wroteHeader = true
header := map[string]string{}
for k := range rw.Header() {
header[k] = rw.Header().Get(k)
}
headerData, _ := json.Marshal(header)
var headers unsafe.Pointer
var headersLen int
if len(headerData) != 0 {
headers = unsafe.Pointer(&headerData[0])
headersLen = len(headerData)
}
C.ProcessURLDidReceiveResponse(rw.r.ctx, rw.r.id, C.int(code), headers, C.int(headersLen))
}
func (rw *wkWebViewResponseWriter) Close() {
if !rw.wroteHeader {
rw.WriteHeader(http.StatusNotImplemented)
}
C.ProcessURLDidFinish(rw.r.ctx, rw.r.id)
}

Some files were not shown because too many files have changed in this diff Show More