mirror of
https://github.com/taigrr/wails.git
synced 2026-04-16 11:44:49 -07:00
Compare commits
24 Commits
930_-_defa
...
v2.0.0-bet
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9735bd1b01 | ||
|
|
cd8bad58cd | ||
|
|
53a3cd9422 | ||
|
|
5e2f25af9b | ||
|
|
f5f89c31eb | ||
|
|
46cb34f2ec | ||
|
|
f6f13540c8 | ||
|
|
21ce7709ab | ||
|
|
d569e37b81 | ||
|
|
c9c6edeb84 | ||
|
|
9525667ebd | ||
|
|
28a3d86348 | ||
|
|
fc8aa58e62 | ||
|
|
cb2bbacae8 | ||
|
|
c3c6261a2d | ||
|
|
8bfec24108 | ||
|
|
9ad2665ad8 | ||
|
|
28894868e3 | ||
|
|
a8fcd994c9 | ||
|
|
3a93c08813 | ||
|
|
ab1469638f | ||
|
|
9073caf287 | ||
|
|
1bed8234c9 | ||
|
|
621c70253d |
@@ -88,6 +88,14 @@ Click [here](https://wails.io) if you are interested in trying out v2 Beta for W
|
|||||||
|
|
||||||
This project is supported by these kind people / companies:
|
This project is supported by these kind people / companies:
|
||||||
|
|
||||||
|
<a href="https://github.com/sponsors/leaanthony" style="width:100px;">
|
||||||
|
<img src="sponsors/silver%20sponsor.png" width="100"/>
|
||||||
|
</a>
|
||||||
|
<a href="https://github.com/letheanVPN" style="width:100px;">
|
||||||
|
<img src="https://github.com/letheanVPN.png?size=100" width="100"/>
|
||||||
|
</a>
|
||||||
|
<br/>
|
||||||
|
<br/>
|
||||||
<a href="https://github.com/sponsors/leaanthony" style="width:100px;">
|
<a href="https://github.com/sponsors/leaanthony" style="width:100px;">
|
||||||
<img src="sponsors/bronze%20sponsor.png" width="100"/>
|
<img src="sponsors/bronze%20sponsor.png" width="100"/>
|
||||||
</a>
|
</a>
|
||||||
|
|||||||
@@ -91,6 +91,14 @@
|
|||||||
|
|
||||||
这个项目由以下这些人或者公司支持:
|
这个项目由以下这些人或者公司支持:
|
||||||
|
|
||||||
|
<a href="https://github.com/sponsors/leaanthony" style="width:100px;">
|
||||||
|
<img src="sponsors/silver%20sponsor.png" width="100"/>
|
||||||
|
</a>
|
||||||
|
<a href="https://github.com/letheanVPN" style="width:100px;">
|
||||||
|
<img src="https://github.com/letheanVPN.png?size=100" width="100"/>
|
||||||
|
</a>
|
||||||
|
<br/>
|
||||||
|
<br/>
|
||||||
<a href="https://github.com/sponsors/leaanthony" style="width:100px;">
|
<a href="https://github.com/sponsors/leaanthony" style="width:100px;">
|
||||||
<img src="sponsors/bronze%20sponsor.png" width="100"/>
|
<img src="sponsors/bronze%20sponsor.png" width="100"/>
|
||||||
</a>
|
</a>
|
||||||
|
|||||||
BIN
sponsors/silver sponsor.png
Normal file
BIN
sponsors/silver sponsor.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 22 KiB |
@@ -99,7 +99,7 @@ func AddBuildSubcommand(app *clir.Cli, w io.Writer) {
|
|||||||
"darwin/amd64",
|
"darwin/amd64",
|
||||||
"darwin/arm64",
|
"darwin/arm64",
|
||||||
"darwin/universal",
|
"darwin/universal",
|
||||||
//"linux",
|
"linux",
|
||||||
//"linux/amd64",
|
//"linux/amd64",
|
||||||
//"linux/arm-7",
|
//"linux/arm-7",
|
||||||
"windows",
|
"windows",
|
||||||
|
|||||||
@@ -278,7 +278,7 @@ func generateBuildOptions(flags devFlags) *build.Options {
|
|||||||
OutputType: "dev",
|
OutputType: "dev",
|
||||||
Mode: build.Dev,
|
Mode: build.Dev,
|
||||||
Arch: runtime.GOARCH,
|
Arch: runtime.GOARCH,
|
||||||
Pack: false,
|
Pack: true,
|
||||||
Platform: runtime.GOOS,
|
Platform: runtime.GOOS,
|
||||||
LDFlags: flags.ldflags,
|
LDFlags: flags.ldflags,
|
||||||
Compiler: flags.compilerCommand,
|
Compiler: flags.compilerCommand,
|
||||||
@@ -287,10 +287,7 @@ func generateBuildOptions(flags devFlags) *build.Options {
|
|||||||
Verbosity: flags.verbosity,
|
Verbosity: flags.verbosity,
|
||||||
WailsJSDir: flags.wailsjsdir,
|
WailsJSDir: flags.wailsjsdir,
|
||||||
}
|
}
|
||||||
switch runtime.GOOS {
|
|
||||||
case "darwin":
|
|
||||||
result.Pack = false
|
|
||||||
}
|
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,12 @@
|
|||||||
|
{
|
||||||
|
"private": true,
|
||||||
|
"scripts": {
|
||||||
|
"postinstall": "npm run setup && cd frontend && npm install",
|
||||||
|
"build": "wails build --clean",
|
||||||
|
"build:macos": "npm run build -- --platform darwin/universal",
|
||||||
|
"build:macos-arm": "npm run build -- --platform darwin/arm64",
|
||||||
|
"build:macos-intel": "npm run build -- --platform darwin",
|
||||||
|
"build:windows": "npm run build -- --platform windows/amd64",
|
||||||
|
"setup": "go install github.com/wailsapp/wails/v2/cmd/wails@latest"
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,3 +1,3 @@
|
|||||||
package internal
|
package internal
|
||||||
|
|
||||||
var Version = "v2.0.0-beta.20"
|
var Version = "v2.0.0-beta.21"
|
||||||
|
|||||||
@@ -49,6 +49,8 @@ require (
|
|||||||
nhooyr.io/websocket v1.8.6
|
nhooyr.io/websocket v1.8.6
|
||||||
)
|
)
|
||||||
|
|
||||||
|
require github.com/gotk3/gotk3 v0.6.1
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/Microsoft/go-winio v0.4.16 // indirect
|
github.com/Microsoft/go-winio v0.4.16 // indirect
|
||||||
github.com/andybalholm/brotli v1.0.2 // indirect
|
github.com/andybalholm/brotli v1.0.2 // indirect
|
||||||
|
|||||||
@@ -82,6 +82,8 @@ github.com/google/uuid v1.1.2 h1:EVhdT+1Kseyi1/pUmXKaFxYsDNy9RQYkMWRH68J/W7Y=
|
|||||||
github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||||
github.com/gorilla/websocket v1.4.1 h1:q7AeDBpnBk8AogcD4DSag/Ukw/KV+YhzLj2bP5HvKCM=
|
github.com/gorilla/websocket v1.4.1 h1:q7AeDBpnBk8AogcD4DSag/Ukw/KV+YhzLj2bP5HvKCM=
|
||||||
github.com/gorilla/websocket v1.4.1/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
|
github.com/gorilla/websocket v1.4.1/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
|
||||||
|
github.com/gotk3/gotk3 v0.6.1 h1:GJ400a0ecEEWrzjBvzBzH+pB/esEMIGdB9zPSmBdoeo=
|
||||||
|
github.com/gotk3/gotk3 v0.6.1/go.mod h1:/hqFpkNa9T3JgNAE2fLvCdov7c5bw//FHNZrZ3Uv9/Q=
|
||||||
github.com/imdario/mergo v0.3.12 h1:b6R2BslTbIEToALKP7LxUvijTsNI9TAe80pLWN2g/HU=
|
github.com/imdario/mergo v0.3.12 h1:b6R2BslTbIEToALKP7LxUvijTsNI9TAe80pLWN2g/HU=
|
||||||
github.com/imdario/mergo v0.3.12/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA=
|
github.com/imdario/mergo v0.3.12/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA=
|
||||||
github.com/jackmordaunt/icns v1.0.0 h1:RYSxplerf/l/DUd09AHtITwckkv/mqjVv4DjYdPmAMQ=
|
github.com/jackmordaunt/icns v1.0.0 h1:RYSxplerf/l/DUd09AHtITwckkv/mqjVv4DjYdPmAMQ=
|
||||||
|
|||||||
32
v2/internal/appng/app_default_linux.go
Normal file
32
v2/internal/appng/app_default_linux.go
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
//go:build !dev && !production && !bindings && linux
|
||||||
|
|
||||||
|
package appng
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"github.com/wailsapp/wails/v2/pkg/options"
|
||||||
|
)
|
||||||
|
|
||||||
|
// App defines a Wails application structure
|
||||||
|
type App struct{}
|
||||||
|
|
||||||
|
func (a *App) Run() error {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// CreateApp creates the app!
|
||||||
|
func CreateApp(_ *options.App) (*App, error) {
|
||||||
|
// result := w32.MessageBox(0,
|
||||||
|
// `Wails applications will not build without the correct build tags.
|
||||||
|
//Please use "wails build" or press "OK" to open the documentation on how to use "go build"`,
|
||||||
|
// "Error",
|
||||||
|
// w32.MB_ICONERROR|w32.MB_OKCANCEL)
|
||||||
|
// if result == 1 {
|
||||||
|
// exec.Command("rundll32", "url.dll,FileProtocolHandler", "https://wails.io").Start()
|
||||||
|
// }
|
||||||
|
|
||||||
|
err := fmt.Errorf(`Wails applications will not build without the correct build tags.`)
|
||||||
|
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
15
v2/internal/appng/app_linux.go
Normal file
15
v2/internal/appng/app_linux.go
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
//go:build linux && !bindings
|
||||||
|
|
||||||
|
package appng
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/wailsapp/wails/v2/internal/logger"
|
||||||
|
"github.com/wailsapp/wails/v2/pkg/options"
|
||||||
|
)
|
||||||
|
|
||||||
|
func PreflightChecks(options *options.App, logger *logger.Logger) error {
|
||||||
|
|
||||||
|
_ = options
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
@@ -35,6 +35,9 @@ type App struct {
|
|||||||
|
|
||||||
func (a *App) Run() error {
|
func (a *App) Run() error {
|
||||||
err := a.frontend.Run(a.ctx)
|
err := a.frontend.Run(a.ctx)
|
||||||
|
if a.shutdownCallback != nil {
|
||||||
|
a.shutdownCallback(a.ctx)
|
||||||
|
}
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -78,10 +78,16 @@ func (b *Bindings) getMethods(value interface{}) ([]*BoundMethod, error) {
|
|||||||
input := methodType.In(inputIndex)
|
input := methodType.In(inputIndex)
|
||||||
thisParam := newParameter("", input)
|
thisParam := newParameter("", input)
|
||||||
|
|
||||||
|
thisInput := input
|
||||||
|
|
||||||
|
if thisInput.Kind() == reflect.Slice {
|
||||||
|
thisInput = thisInput.Elem()
|
||||||
|
}
|
||||||
|
|
||||||
// Process struct pointer params
|
// Process struct pointer params
|
||||||
if input.Kind() == reflect.Ptr {
|
if thisInput.Kind() == reflect.Ptr {
|
||||||
if input.Elem().Kind() == reflect.Struct {
|
if thisInput.Elem().Kind() == reflect.Struct {
|
||||||
typ := input.Elem()
|
typ := thisInput.Elem()
|
||||||
a := reflect.New(typ)
|
a := reflect.New(typ)
|
||||||
s := reflect.Indirect(a).Interface()
|
s := reflect.Indirect(a).Interface()
|
||||||
b.converter.Add(s)
|
b.converter.Add(s)
|
||||||
@@ -89,8 +95,8 @@ func (b *Bindings) getMethods(value interface{}) ([]*BoundMethod, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Process struct params
|
// Process struct params
|
||||||
if input.Kind() == reflect.Struct {
|
if thisInput.Kind() == reflect.Struct {
|
||||||
a := reflect.New(input)
|
a := reflect.New(thisInput)
|
||||||
s := reflect.Indirect(a).Interface()
|
s := reflect.Indirect(a).Interface()
|
||||||
b.converter.Add(s)
|
b.converter.Add(s)
|
||||||
}
|
}
|
||||||
@@ -108,6 +114,30 @@ func (b *Bindings) getMethods(value interface{}) ([]*BoundMethod, error) {
|
|||||||
for outputIndex := 0; outputIndex < outputParamCount; outputIndex++ {
|
for outputIndex := 0; outputIndex < outputParamCount; outputIndex++ {
|
||||||
output := methodType.Out(outputIndex)
|
output := methodType.Out(outputIndex)
|
||||||
thisParam := newParameter("", output)
|
thisParam := newParameter("", output)
|
||||||
|
|
||||||
|
thisOutput := output
|
||||||
|
|
||||||
|
if thisOutput.Kind() == reflect.Slice {
|
||||||
|
thisOutput = thisOutput.Elem()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Process struct pointer params
|
||||||
|
if thisOutput.Kind() == reflect.Ptr {
|
||||||
|
if thisOutput.Elem().Kind() == reflect.Struct {
|
||||||
|
typ := thisOutput.Elem()
|
||||||
|
a := reflect.New(typ)
|
||||||
|
s := reflect.Indirect(a).Interface()
|
||||||
|
b.converter.Add(s)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Process struct params
|
||||||
|
if thisOutput.Kind() == reflect.Struct {
|
||||||
|
a := reflect.New(thisOutput)
|
||||||
|
s := reflect.Indirect(a).Interface()
|
||||||
|
b.converter.Add(s)
|
||||||
|
}
|
||||||
|
|
||||||
outputs = append(outputs, thisParam)
|
outputs = append(outputs, thisParam)
|
||||||
}
|
}
|
||||||
boundMethod.Outputs = outputs
|
boundMethod.Outputs = outputs
|
||||||
|
|||||||
@@ -15,6 +15,7 @@
|
|||||||
|
|
||||||
@property bool alwaysOnTop;
|
@property bool alwaysOnTop;
|
||||||
@property bool startHidden;
|
@property bool startHidden;
|
||||||
|
@property bool startFullscreen;
|
||||||
@property (retain) WailsWindow* mainWindow;
|
@property (retain) WailsWindow* mainWindow;
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|||||||
@@ -26,6 +26,12 @@
|
|||||||
|
|
||||||
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification {
|
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification {
|
||||||
[NSApp activateIgnoringOtherApps:YES];
|
[NSApp activateIgnoringOtherApps:YES];
|
||||||
|
if ( self.startFullscreen ) {
|
||||||
|
NSWindowCollectionBehavior behaviour = [self.mainWindow collectionBehavior];
|
||||||
|
behaviour |= NSWindowCollectionBehaviorFullScreenPrimary;
|
||||||
|
[self.mainWindow setCollectionBehavior:behaviour];
|
||||||
|
[self.mainWindow toggleFullScreen:nil];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)dealloc {
|
- (void)dealloc {
|
||||||
|
|||||||
@@ -17,7 +17,7 @@
|
|||||||
#define WindowStartsMinimised 2
|
#define WindowStartsMinimised 2
|
||||||
#define WindowStartsFullscreen 3
|
#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);
|
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);
|
||||||
void Run(void*);
|
void Run(void*);
|
||||||
|
|
||||||
void SetTitle(void* ctx, const char *title);
|
void SetTitle(void* ctx, const char *title);
|
||||||
|
|||||||
@@ -12,7 +12,7 @@
|
|||||||
#import "WailsMenu.h"
|
#import "WailsMenu.h"
|
||||||
#import "WailsMenuItem.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) {
|
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) {
|
||||||
|
|
||||||
[NSApplication sharedApplication];
|
[NSApplication sharedApplication];
|
||||||
|
|
||||||
@@ -24,7 +24,7 @@ WailsContext* Create(const char* title, int width, int height, int frameless, in
|
|||||||
fullscreen = 1;
|
fullscreen = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
[result CreateWindow:width :height :frameless :resizable :fullscreen :fullSizeContent :hideTitleBar :titlebarAppearsTransparent :hideTitle :useToolbar :hideToolbarSeparator :webviewIsTransparent :hideWindowOnClose :safeInit(appearance) :windowIsTranslucent];
|
[result CreateWindow:width :height :frameless :resizable :fullscreen :fullSizeContent :hideTitleBar :titlebarAppearsTransparent :hideTitle :useToolbar :hideToolbarSeparator :webviewIsTransparent :hideWindowOnClose :safeInit(appearance) :windowIsTranslucent :minWidth :minHeight :maxWidth :maxHeight];
|
||||||
[result SetTitle:safeInit(title)];
|
[result SetTitle:safeInit(title)];
|
||||||
[result Center];
|
[result Center];
|
||||||
|
|
||||||
@@ -41,6 +41,10 @@ WailsContext* Create(const char* title, int width, int height, int frameless, in
|
|||||||
result.startHidden = true;
|
result.startHidden = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ( fullscreen == 1 ) {
|
||||||
|
result.startFullscreen = true;
|
||||||
|
}
|
||||||
|
|
||||||
result.alwaysOnTop = alwaysOnTop;
|
result.alwaysOnTop = alwaysOnTop;
|
||||||
result.hideOnClose = hideWindowOnClose;
|
result.hideOnClose = hideWindowOnClose;
|
||||||
|
|
||||||
@@ -324,6 +328,7 @@ void Run(void *inctx) {
|
|||||||
delegate.mainWindow = ctx.mainWindow;
|
delegate.mainWindow = ctx.mainWindow;
|
||||||
delegate.alwaysOnTop = ctx.alwaysOnTop;
|
delegate.alwaysOnTop = ctx.alwaysOnTop;
|
||||||
delegate.startHidden = ctx.startHidden;
|
delegate.startHidden = ctx.startHidden;
|
||||||
|
delegate.startFullscreen = ctx.startFullscreen;
|
||||||
|
|
||||||
[ctx loadRequest:@"wails://wails/"];
|
[ctx loadRequest:@"wails://wails/"];
|
||||||
[app setMainMenu:ctx.applicationMenu];
|
[app setMainMenu:ctx.applicationMenu];
|
||||||
|
|||||||
@@ -11,11 +11,21 @@
|
|||||||
#import <Cocoa/Cocoa.h>
|
#import <Cocoa/Cocoa.h>
|
||||||
#import <WebKit/WebKit.h>
|
#import <WebKit/WebKit.h>
|
||||||
|
|
||||||
|
#if __has_include(<UniformTypeIdentifiers/UTType.h>)
|
||||||
|
#import <UniformTypeIdentifiers/UTType.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#define ON_MAIN_THREAD(str) dispatch_async(dispatch_get_main_queue(), ^{ str; });
|
#define ON_MAIN_THREAD(str) dispatch_async(dispatch_get_main_queue(), ^{ str; });
|
||||||
#define unicode(input) [NSString stringWithFormat:@"%C", input]
|
#define unicode(input) [NSString stringWithFormat:@"%C", input]
|
||||||
|
|
||||||
@interface WailsWindow : NSWindow
|
@interface WailsWindow : NSWindow
|
||||||
- (BOOL)canBecomeKeyWindow;
|
|
||||||
|
@property NSSize userMinSize;
|
||||||
|
@property NSSize userMaxSize;
|
||||||
|
|
||||||
|
- (BOOL) canBecomeKeyWindow;
|
||||||
|
- (void) applyWindowConstraints;
|
||||||
|
- (void) disableWindowConstraints;
|
||||||
@end
|
@end
|
||||||
|
|
||||||
@interface WailsContext : NSObject <WKURLSchemeHandler,WKScriptMessageHandler,WKNavigationDelegate>
|
@interface WailsContext : NSObject <WKURLSchemeHandler,WKScriptMessageHandler,WKNavigationDelegate>
|
||||||
@@ -27,9 +37,7 @@
|
|||||||
@property bool hideOnClose;
|
@property bool hideOnClose;
|
||||||
@property bool shuttingDown;
|
@property bool shuttingDown;
|
||||||
@property bool startHidden;
|
@property bool startHidden;
|
||||||
|
@property bool startFullscreen;
|
||||||
@property NSSize maxSize;
|
|
||||||
@property NSSize minSize;
|
|
||||||
|
|
||||||
@property (retain) NSEvent* mouseEvent;
|
@property (retain) NSEvent* mouseEvent;
|
||||||
|
|
||||||
@@ -46,7 +54,7 @@
|
|||||||
@property (retain) NSString* aboutTitle;
|
@property (retain) NSString* aboutTitle;
|
||||||
@property (retain) NSString* aboutDescription;
|
@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;
|
- (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) SetSize:(int)width :(int)height;
|
- (void) SetSize:(int)width :(int)height;
|
||||||
- (void) SetPosition:(int)x :(int) y;
|
- (void) SetPosition:(int)x :(int) y;
|
||||||
- (void) SetMinSize:(int)minWidth :(int)minHeight;
|
- (void) SetMinSize:(int)minWidth :(int)minHeight;
|
||||||
@@ -76,6 +84,7 @@
|
|||||||
- (NSScreen*) getCurrentScreen;
|
- (NSScreen*) getCurrentScreen;
|
||||||
|
|
||||||
- (void) SetAbout :(NSString*)title :(NSString*)description :(void*)imagedata :(int)datalen;
|
- (void) SetAbout :(NSString*)title :(NSString*)description :(void*)imagedata :(int)datalen;
|
||||||
|
- (void) dealloc;
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
|
|||||||
@@ -21,6 +21,16 @@
|
|||||||
return YES;
|
return YES;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (void) applyWindowConstraints {
|
||||||
|
[self setMinSize:self.userMinSize];
|
||||||
|
[self setMaxSize:self.userMaxSize];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void) disableWindowConstraints {
|
||||||
|
[self setMinSize:NSMakeSize(0, 0)];
|
||||||
|
[self setMaxSize:NSMakeSize(FLT_MAX, FLT_MAX)];
|
||||||
|
}
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
@implementation WailsContext
|
@implementation WailsContext
|
||||||
@@ -33,7 +43,7 @@
|
|||||||
frame.origin.y += frame.size.height - height;
|
frame.origin.y += frame.size.height - height;
|
||||||
frame.size.width = width;
|
frame.size.width = width;
|
||||||
frame.size.height = height;
|
frame.size.height = height;
|
||||||
ON_MAIN_THREAD([self.mainWindow setFrame:frame display:TRUE animate:FALSE];);
|
[self.mainWindow setFrame:frame display:TRUE animate:FALSE];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void) SetPosition:(int)x :(int)y {
|
- (void) SetPosition:(int)x :(int)y {
|
||||||
@@ -45,8 +55,8 @@
|
|||||||
NSRect screenFrame = [screen frame];
|
NSRect screenFrame = [screen frame];
|
||||||
windowFrame.origin.x = screenFrame.origin.x + (float)x;
|
windowFrame.origin.x = screenFrame.origin.x + (float)x;
|
||||||
windowFrame.origin.y = (screenFrame.origin.y + screenFrame.size.height) - windowFrame.size.height - (float)y;
|
windowFrame.origin.y = (screenFrame.origin.y + screenFrame.size.height) - windowFrame.size.height - (float)y;
|
||||||
|
|
||||||
ON_MAIN_THREAD([self.mainWindow setFrame:windowFrame display:TRUE animate:FALSE]; );
|
[self.mainWindow setFrame:windowFrame display:TRUE animate:FALSE];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void) SetMinSize:(int)minWidth :(int)minHeight {
|
- (void) SetMinSize:(int)minWidth :(int)minHeight {
|
||||||
@@ -54,13 +64,9 @@
|
|||||||
if (self.shuttingDown) return;
|
if (self.shuttingDown) return;
|
||||||
|
|
||||||
NSSize size = { minWidth, minHeight };
|
NSSize size = { minWidth, minHeight };
|
||||||
|
self.mainWindow.userMinSize = size;
|
||||||
self.minSize = size;
|
[self.mainWindow setMinSize:size];
|
||||||
|
[self adjustWindowSize];
|
||||||
ON_MAIN_THREAD(
|
|
||||||
[self.mainWindow setMinSize:size];
|
|
||||||
[self adjustWindowSize];
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -73,12 +79,9 @@
|
|||||||
size.width = maxWidth > 0 ? maxWidth : FLT_MAX;
|
size.width = maxWidth > 0 ? maxWidth : FLT_MAX;
|
||||||
size.height = maxHeight > 0 ? maxHeight : FLT_MAX;
|
size.height = maxHeight > 0 ? maxHeight : FLT_MAX;
|
||||||
|
|
||||||
self.maxSize = size;
|
self.mainWindow.userMaxSize = size;
|
||||||
|
[self.mainWindow setMaxSize:size];
|
||||||
ON_MAIN_THREAD(
|
[self adjustWindowSize];
|
||||||
[self.mainWindow setMaxSize:size];
|
|
||||||
[self adjustWindowSize];
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -88,23 +91,23 @@
|
|||||||
|
|
||||||
NSRect currentFrame = [self.mainWindow frame];
|
NSRect currentFrame = [self.mainWindow frame];
|
||||||
|
|
||||||
if ( currentFrame.size.width > self.maxSize.width ) currentFrame.size.width = self.maxSize.width;
|
if ( currentFrame.size.width > self.mainWindow.userMaxSize.width ) currentFrame.size.width = self.mainWindow.userMaxSize.width;
|
||||||
if ( currentFrame.size.width < self.minSize.width ) currentFrame.size.width = self.minSize.width;
|
if ( currentFrame.size.width < self.mainWindow.userMinSize.width ) currentFrame.size.width = self.mainWindow.userMinSize.width;
|
||||||
if ( currentFrame.size.height > self.maxSize.height ) currentFrame.size.height = self.maxSize.height;
|
if ( currentFrame.size.height > self.mainWindow.userMaxSize.height ) currentFrame.size.height = self.mainWindow.userMaxSize.height;
|
||||||
if ( currentFrame.size.height < self.minSize.height ) currentFrame.size.height = self.minSize.height;
|
if ( currentFrame.size.height < self.mainWindow.userMinSize.height ) currentFrame.size.height = self.mainWindow.userMinSize.height;
|
||||||
|
|
||||||
[self.mainWindow setFrame:currentFrame display:YES animate:FALSE];
|
[self.mainWindow setFrame:currentFrame display:YES animate:FALSE];
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void) dealloc {
|
- (void) dealloc {
|
||||||
[super dealloc];
|
|
||||||
[self.appdelegate release];
|
[self.appdelegate release];
|
||||||
[self.mainWindow release];
|
[self.mainWindow release];
|
||||||
[self.mouseEvent release];
|
[self.mouseEvent release];
|
||||||
[self.userContentController release];
|
[self.userContentController release];
|
||||||
[self.urlRequests release];
|
[self.urlRequests release];
|
||||||
[self.applicationMenu release];
|
[self.applicationMenu release];
|
||||||
|
[super dealloc];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (NSScreen*) getCurrentScreen {
|
- (NSScreen*) getCurrentScreen {
|
||||||
@@ -116,11 +119,11 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
- (void) SetTitle:(NSString*)title {
|
- (void) SetTitle:(NSString*)title {
|
||||||
ON_MAIN_THREAD([self.mainWindow setTitle:title];)
|
[self.mainWindow setTitle:title];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void) Center {
|
- (void) Center {
|
||||||
ON_MAIN_THREAD( [self.mainWindow center]; );
|
[self.mainWindow center];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (BOOL) isFullscreen {
|
- (BOOL) isFullscreen {
|
||||||
@@ -131,37 +134,29 @@
|
|||||||
return NO;
|
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 {
|
- (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.urlRequests = [NSMutableDictionary new];
|
self.urlRequests = [NSMutableDictionary new];
|
||||||
|
|
||||||
NSWindowStyleMask styleMask = NSWindowStyleMaskClosable | NSWindowStyleMaskMiniaturizable;
|
NSWindowStyleMask styleMask = 0;
|
||||||
|
|
||||||
if (frameless) {
|
if( !frameless ) {
|
||||||
styleMask = NSWindowStyleMaskBorderless;
|
|
||||||
titlebarAppearsTransparent = true;
|
|
||||||
hideTitle = true;
|
|
||||||
} else {
|
|
||||||
if (!hideTitleBar) {
|
if (!hideTitleBar) {
|
||||||
styleMask |= NSWindowStyleMaskTitled;
|
styleMask |= NSWindowStyleMaskTitled;
|
||||||
}
|
}
|
||||||
|
styleMask |= NSWindowStyleMaskClosable | NSWindowStyleMaskMiniaturizable;
|
||||||
if (fullscreen) {
|
|
||||||
styleMask |= NSWindowStyleMaskFullScreen;
|
|
||||||
}
|
|
||||||
|
|
||||||
if( fullSizeContent || frameless || titlebarAppearsTransparent ) {
|
|
||||||
styleMask |= NSWindowStyleMaskFullSizeContentView;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if( fullSizeContent || frameless || titlebarAppearsTransparent ) {
|
||||||
|
styleMask |= NSWindowStyleMaskFullSizeContentView;
|
||||||
|
}
|
||||||
|
|
||||||
if (resizable) {
|
if (resizable) {
|
||||||
styleMask |= NSWindowStyleMaskResizable;
|
styleMask |= NSWindowStyleMaskResizable;
|
||||||
}
|
}
|
||||||
|
|
||||||
self.mainWindow = [[[WailsWindow alloc] initWithContentRect:NSMakeRect(0, 0, width, height)
|
self.mainWindow = [[WailsWindow alloc] initWithContentRect:NSMakeRect(0, 0, width, height)
|
||||||
styleMask:styleMask backing:NSBackingStoreBuffered defer:NO]
|
styleMask:styleMask backing:NSBackingStoreBuffered defer:NO];
|
||||||
autorelease];
|
|
||||||
|
|
||||||
if (!frameless && useToolbar) {
|
if (!frameless && useToolbar) {
|
||||||
id toolbar = [[NSToolbar alloc] initWithIdentifier:@"wails.toolbar"];
|
id toolbar = [[NSToolbar alloc] initWithIdentifier:@"wails.toolbar"];
|
||||||
@@ -192,15 +187,25 @@
|
|||||||
[self.mainWindow setAppearance:nsAppearance];
|
[self.mainWindow setAppearance:nsAppearance];
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set up min/max
|
|
||||||
NSSize maxSize = { FLT_MAX, FLT_MAX };
|
NSSize minSize = { minWidth, minHeight };
|
||||||
self.maxSize = maxSize;
|
NSSize maxSize = { maxWidth, maxHeight };
|
||||||
NSSize minSize = { 0, 0 };
|
if (maxSize.width == 0) {
|
||||||
self.minSize = minSize;
|
maxSize.width = FLT_MAX;
|
||||||
[self adjustWindowSize];
|
}
|
||||||
|
if (maxSize.height == 0) {
|
||||||
|
maxSize.height = FLT_MAX;
|
||||||
|
}
|
||||||
|
self.mainWindow.userMaxSize = maxSize;
|
||||||
|
self.mainWindow.userMinSize = minSize;
|
||||||
|
|
||||||
|
if( !fullscreen ) {
|
||||||
|
[self.mainWindow applyWindowConstraints];
|
||||||
|
}
|
||||||
|
|
||||||
WindowDelegate *windowDelegate = [WindowDelegate new];
|
WindowDelegate *windowDelegate = [WindowDelegate new];
|
||||||
windowDelegate.hideOnClose = hideWindowOnClose;
|
windowDelegate.hideOnClose = hideWindowOnClose;
|
||||||
|
windowDelegate.ctx = self;
|
||||||
[self.mainWindow setDelegate:windowDelegate];
|
[self.mainWindow setDelegate:windowDelegate];
|
||||||
|
|
||||||
// Webview stuff here!
|
// Webview stuff here!
|
||||||
@@ -278,7 +283,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
- (NSMenu*) newMenu :(NSString*)title {
|
- (NSMenu*) newMenu :(NSString*)title {
|
||||||
WailsMenu *result = [[[WailsMenu new] initWithTitle:title] autorelease];
|
WailsMenu *result = [[WailsMenu new] initWithTitle:title];
|
||||||
[result setAutoenablesItems:NO];
|
[result setAutoenablesItems:NO];
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@@ -294,14 +299,14 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
- (void) SetRGBA:(int)r :(int)g :(int)b :(int)a {
|
- (void) SetRGBA:(int)r :(int)g :(int)b :(int)a {
|
||||||
float red = r/255;
|
float red = r/255.0;
|
||||||
float green = g/255;
|
float green = g/255.0;
|
||||||
float blue = b/255;
|
float blue = b/255.0;
|
||||||
float alpha = a/255;
|
float alpha = a/255.0;
|
||||||
|
|
||||||
id colour = [NSColor colorWithCalibratedRed:red green:green blue:blue alpha:alpha ];
|
id colour = [NSColor colorWithCalibratedRed:red green:green blue:blue alpha:alpha ];
|
||||||
|
|
||||||
ON_MAIN_THREAD([self.mainWindow setBackgroundColor:colour];);
|
[self.mainWindow setBackgroundColor:colour];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void) HideMouse {
|
- (void) HideMouse {
|
||||||
@@ -325,66 +330,64 @@
|
|||||||
// Fullscreen sets the main window to be fullscreen
|
// Fullscreen sets the main window to be fullscreen
|
||||||
- (void) Fullscreen {
|
- (void) Fullscreen {
|
||||||
if( ! [self isFullScreen] ) {
|
if( ! [self isFullScreen] ) {
|
||||||
ON_MAIN_THREAD([self.mainWindow toggleFullScreen:nil];)
|
[self.mainWindow disableWindowConstraints];
|
||||||
|
[self.mainWindow toggleFullScreen:nil];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// UnFullscreen resets the main window after a fullscreen
|
// UnFullscreen resets the main window after a fullscreen
|
||||||
- (void) UnFullscreen {
|
- (void) UnFullscreen {
|
||||||
if( [self isFullScreen] ) {
|
if( [self isFullScreen] ) {
|
||||||
ON_MAIN_THREAD([self.mainWindow toggleFullScreen:nil];)
|
[self.mainWindow applyWindowConstraints];
|
||||||
|
[self.mainWindow toggleFullScreen:nil];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void) Minimise {
|
- (void) Minimise {
|
||||||
ON_MAIN_THREAD([self.mainWindow miniaturize:nil];)
|
[self.mainWindow miniaturize:nil];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void) UnMinimise {
|
- (void) UnMinimise {
|
||||||
ON_MAIN_THREAD([self.mainWindow deminiaturize:nil];)
|
[self.mainWindow deminiaturize:nil];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void) Hide {
|
- (void) Hide {
|
||||||
ON_MAIN_THREAD([self.mainWindow orderOut:nil];)
|
[self.mainWindow orderOut:nil];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void) Show {
|
- (void) Show {
|
||||||
ON_MAIN_THREAD(
|
[self.mainWindow makeKeyAndOrderFront:nil];
|
||||||
[self.mainWindow makeKeyAndOrderFront:nil];
|
[NSApp activateIgnoringOtherApps:YES];
|
||||||
[NSApp activateIgnoringOtherApps:YES];
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void) Maximise {
|
- (void) Maximise {
|
||||||
if (![self.mainWindow isZoomed]) {
|
if (![self.mainWindow isZoomed]) {
|
||||||
ON_MAIN_THREAD([self.mainWindow zoom:nil];)
|
[self.mainWindow zoom:nil];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void) UnMaximise {
|
- (void) UnMaximise {
|
||||||
if ([self.mainWindow isZoomed]) {
|
if ([self.mainWindow isZoomed]) {
|
||||||
ON_MAIN_THREAD([self.mainWindow zoom:nil];)
|
[self.mainWindow zoom:nil];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void) ExecJS:(NSString*)script {
|
- (void) ExecJS:(NSString*)script {
|
||||||
ON_MAIN_THREAD(
|
[self.webview evaluateJavaScript:script completionHandler:nil];
|
||||||
[self.webview evaluateJavaScript:script completionHandler:nil];
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void) processURLResponse:(NSString *)url :(NSString *)contentType :(NSData *)data {
|
- (void) processURLResponse:(NSString *)url :(NSString *)contentType :(NSData *)data {
|
||||||
id<WKURLSchemeTask> urlSchemeTask = self.urlRequests[url];
|
id<WKURLSchemeTask> urlSchemeTask = self.urlRequests[url];
|
||||||
NSURL *nsurl = [NSURL URLWithString:url];
|
NSURL *nsurl = [NSURL URLWithString:url];
|
||||||
|
|
||||||
NSHTTPURLResponse *response = [NSHTTPURLResponse new];
|
|
||||||
NSMutableDictionary *headerFields = [NSMutableDictionary new];
|
NSMutableDictionary *headerFields = [NSMutableDictionary new];
|
||||||
headerFields[@"content-type"] = contentType;
|
headerFields[@"content-type"] = contentType;
|
||||||
[response initWithURL:nsurl statusCode:200 HTTPVersion:@"HTTP/1.1" headerFields:headerFields];
|
NSHTTPURLResponse *response = [[NSHTTPURLResponse new] initWithURL:nsurl statusCode:200 HTTPVersion:@"HTTP/1.1" headerFields:headerFields];
|
||||||
[urlSchemeTask didReceiveResponse:response];
|
[urlSchemeTask didReceiveResponse:response];
|
||||||
[urlSchemeTask didReceiveData:data];
|
[urlSchemeTask didReceiveData:data];
|
||||||
[urlSchemeTask didFinish];
|
[urlSchemeTask didFinish];
|
||||||
[self.urlRequests removeObjectForKey:url];
|
[self.urlRequests removeObjectForKey:url];
|
||||||
|
[response release];
|
||||||
|
[headerFields release];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)webView:(nonnull WKWebView *)webView startURLSchemeTask:(nonnull id<WKURLSchemeTask>)urlSchemeTask {
|
- (void)webView:(nonnull WKWebView *)webView startURLSchemeTask:(nonnull id<WKURLSchemeTask>)urlSchemeTask {
|
||||||
@@ -406,15 +409,13 @@
|
|||||||
|
|
||||||
// Check for drag
|
// Check for drag
|
||||||
if ( [m isEqualToString:@"drag"] ) {
|
if ( [m isEqualToString:@"drag"] ) {
|
||||||
if( ! [self isFullScreen] ) {
|
if( [self isFullScreen] ) {
|
||||||
if( self.mouseEvent != nil ) {
|
|
||||||
[self HideMouse];
|
|
||||||
ON_MAIN_THREAD(
|
|
||||||
[self.mainWindow performWindowDragWithEvent:self.mouseEvent];
|
|
||||||
);
|
|
||||||
}
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if( self.mouseEvent != nil ) {
|
||||||
|
[self.mainWindow performWindowDragWithEvent:self.mouseEvent];
|
||||||
|
}
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const char *_m = [m UTF8String];
|
const char *_m = [m UTF8String];
|
||||||
@@ -455,28 +456,26 @@
|
|||||||
NSData *imageData = [NSData dataWithBytes:iconData length:iconDataLength];
|
NSData *imageData = [NSData dataWithBytes:iconData length:iconDataLength];
|
||||||
icon = [[NSImage alloc] initWithData:imageData];
|
icon = [[NSImage alloc] initWithData:imageData];
|
||||||
}
|
}
|
||||||
ON_MAIN_THREAD(
|
if( icon != nil) {
|
||||||
if( icon != nil) {
|
[alert setIcon:icon];
|
||||||
[alert setIcon:icon];
|
}
|
||||||
}
|
[alert.window setLevel:NSFloatingWindowLevel];
|
||||||
[alert.window setLevel:NSFloatingWindowLevel];
|
|
||||||
|
|
||||||
long response = [alert runModal];
|
long response = [alert runModal];
|
||||||
int result;
|
int result;
|
||||||
|
|
||||||
if( response == NSAlertFirstButtonReturn ) {
|
if( response == NSAlertFirstButtonReturn ) {
|
||||||
result = 0;
|
result = 0;
|
||||||
}
|
}
|
||||||
else if( response == NSAlertSecondButtonReturn ) {
|
else if( response == NSAlertSecondButtonReturn ) {
|
||||||
result = 1;
|
result = 1;
|
||||||
}
|
}
|
||||||
else if( response == NSAlertThirdButtonReturn ) {
|
else if( response == NSAlertThirdButtonReturn ) {
|
||||||
result = 2;
|
result = 2;
|
||||||
} else {
|
} else {
|
||||||
result = 3;
|
result = 3;
|
||||||
}
|
}
|
||||||
processMessageDialogResponse(result);
|
processMessageDialogResponse(result);
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
-(void) OpenFileDialog :(NSString*)title :(NSString*)defaultFilename :(NSString*)defaultDirectory :(bool)allowDirectories :(bool)allowFiles :(bool)canCreateDirectories :(bool)treatPackagesAsDirectories :(bool)resolveAliases :(bool)showHiddenFiles :(bool)allowMultipleSelection :(NSString*)filters {
|
-(void) OpenFileDialog :(NSString*)title :(NSString*)defaultFilename :(NSString*)defaultDirectory :(bool)allowDirectories :(bool)allowFiles :(bool)canCreateDirectories :(bool)treatPackagesAsDirectories :(bool)resolveAliases :(bool)showHiddenFiles :(bool)allowMultipleSelection :(NSString*)filters {
|
||||||
@@ -492,11 +491,20 @@
|
|||||||
|
|
||||||
// Filters - semicolon delimited list of file extensions
|
// Filters - semicolon delimited list of file extensions
|
||||||
if( allowFiles ) {
|
if( allowFiles ) {
|
||||||
if( filters != nil ) {
|
if( filters != nil && [filters length] > 0) {
|
||||||
filters = [filters stringByReplacingOccurrencesOfString:@"*." withString:@""];
|
filters = [filters stringByReplacingOccurrencesOfString:@"*." withString:@""];
|
||||||
filters = [filters stringByReplacingOccurrencesOfString:@" " withString:@""];
|
filters = [filters stringByReplacingOccurrencesOfString:@" " withString:@""];
|
||||||
NSArray *filterList = [filters componentsSeparatedByString:@";"];
|
NSArray *filterList = [filters componentsSeparatedByString:@";"];
|
||||||
[dialog setAllowedFileTypes:filterList];
|
if (@available(macOS 10.16, *)) {
|
||||||
|
NSMutableArray *contentTypes = [[NSMutableArray new] autorelease];
|
||||||
|
for (NSString *filter in filterList) {
|
||||||
|
UTType *t = [UTType typeWithFilenameExtension:filter];
|
||||||
|
[contentTypes addObject:t];
|
||||||
|
}
|
||||||
|
[dialog setAllowedContentTypes:contentTypes];
|
||||||
|
} else {
|
||||||
|
[dialog setAllowedFileTypes:filterList];
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
[dialog setAllowsOtherFileTypes:true];
|
[dialog setAllowsOtherFileTypes:true];
|
||||||
}
|
}
|
||||||
@@ -613,8 +621,7 @@
|
|||||||
[alert setIcon:self.aboutImage];
|
[alert setIcon:self.aboutImage];
|
||||||
}
|
}
|
||||||
|
|
||||||
ON_MAIN_THREAD([alert runModal];)
|
[alert runModal];
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|||||||
@@ -64,7 +64,7 @@
|
|||||||
if( appName == nil ) {
|
if( appName == nil ) {
|
||||||
appName = [[NSProcessInfo processInfo] processName];
|
appName = [[NSProcessInfo processInfo] processName];
|
||||||
}
|
}
|
||||||
WailsMenu *appMenu = [[WailsMenu new] initWithNSTitle:appName];
|
WailsMenu *appMenu = [[[WailsMenu new] initWithNSTitle:appName] autorelease];
|
||||||
id quitTitle = [@"Quit " stringByAppendingString:appName];
|
id quitTitle = [@"Quit " stringByAppendingString:appName];
|
||||||
NSMenuItem* quitMenuItem = [self newMenuItem:quitTitle :@selector(Quit) :@"q" :NSEventModifierFlagCommand];
|
NSMenuItem* quitMenuItem = [self newMenuItem:quitTitle :@selector(Quit) :@"q" :NSEventModifierFlagCommand];
|
||||||
quitMenuItem.target = ctx;
|
quitMenuItem.target = ctx;
|
||||||
@@ -77,7 +77,7 @@
|
|||||||
}
|
}
|
||||||
case EditMenu:
|
case EditMenu:
|
||||||
{
|
{
|
||||||
WailsMenu *editMenu = [[WailsMenu new] initWithNSTitle:@"Edit"];
|
WailsMenu *editMenu = [[[WailsMenu new] initWithNSTitle:@"Edit"] autorelease];
|
||||||
[editMenu addItem:[self newMenuItem:@"Undo" :@selector(undoActionName) :@"z" :NSEventModifierFlagCommand]];
|
[editMenu addItem:[self newMenuItem:@"Undo" :@selector(undoActionName) :@"z" :NSEventModifierFlagCommand]];
|
||||||
[editMenu addItem:[self newMenuItem:@"Redo" :@selector(redoActionName) :@"z" :(NSEventModifierFlagShift | NSEventModifierFlagCommand)]];
|
[editMenu addItem:[self newMenuItem:@"Redo" :@selector(redoActionName) :@"z" :(NSEventModifierFlagShift | NSEventModifierFlagCommand)]];
|
||||||
[editMenu addItem:[NSMenuItem separatorItem]];
|
[editMenu addItem:[NSMenuItem separatorItem]];
|
||||||
@@ -91,7 +91,7 @@
|
|||||||
// NSMenuItem *speechMenuItem = [[NSMenuItem new] autorelease];
|
// NSMenuItem *speechMenuItem = [[NSMenuItem new] autorelease];
|
||||||
// [speechMenuItem setTitle:@"Speech"];
|
// [speechMenuItem setTitle:@"Speech"];
|
||||||
// [editMenu addItem:speechMenuItem];
|
// [editMenu addItem:speechMenuItem];
|
||||||
WailsMenu *speechMenu = [[WailsMenu new] initWithNSTitle:@"Speech"];
|
WailsMenu *speechMenu = [[[WailsMenu new] initWithNSTitle:@"Speech"] autorelease];
|
||||||
[speechMenu addItem:[self newMenuItem:@"Start Speaking" :@selector(startSpeaking:) :@""]];
|
[speechMenu addItem:[self newMenuItem:@"Start Speaking" :@selector(startSpeaking:) :@""]];
|
||||||
[speechMenu addItem:[self newMenuItem:@"Stop Speaking" :@selector(stopSpeaking:) :@""]];
|
[speechMenu addItem:[self newMenuItem:@"Stop Speaking" :@selector(stopSpeaking:) :@""]];
|
||||||
[editMenu appendSubmenu:speechMenu];
|
[editMenu appendSubmenu:speechMenu];
|
||||||
|
|||||||
@@ -8,10 +8,17 @@
|
|||||||
#ifndef WindowDelegate_h
|
#ifndef WindowDelegate_h
|
||||||
#define WindowDelegate_h
|
#define WindowDelegate_h
|
||||||
|
|
||||||
|
#import "WailsContext.h"
|
||||||
|
|
||||||
@interface WindowDelegate : NSObject <NSWindowDelegate>
|
@interface WindowDelegate : NSObject <NSWindowDelegate>
|
||||||
|
|
||||||
@property bool hideOnClose;
|
@property bool hideOnClose;
|
||||||
|
|
||||||
|
@property (assign) WailsContext* ctx;
|
||||||
|
|
||||||
|
- (void)windowDidExitFullScreen:(NSNotification *)notification;
|
||||||
|
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -21,4 +21,18 @@
|
|||||||
return !self.hideOnClose;
|
return !self.hideOnClose;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
- (void)windowDidExitFullScreen:(NSNotification *)notification {
|
||||||
|
[self.ctx.mainWindow applyWindowConstraints];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)windowWillEnterFullScreen:(NSNotification *)notification {
|
||||||
|
[self.ctx.mainWindow disableWindowConstraints];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (NSApplicationPresentationOptions)window:(WailsWindow *)window willUseFullScreenPresentationOptions:(NSApplicationPresentationOptions)proposedOptions {
|
||||||
|
return NSApplicationPresentationAutoHideToolbar | NSApplicationPresentationAutoHideMenuBar | NSApplicationPresentationFullScreen;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ package darwin
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
#cgo CFLAGS: -x objective-c
|
#cgo CFLAGS: -x objective-c
|
||||||
#cgo LDFLAGS: -framework Foundation -framework Cocoa -framework WebKit
|
#cgo LDFLAGS: -framework Foundation -framework Cocoa -framework WebKit -framework UniformTypeIdentifiers
|
||||||
#import <Foundation/Foundation.h>
|
#import <Foundation/Foundation.h>
|
||||||
#import "Application.h"
|
#import "Application.h"
|
||||||
#import "WailsContext.h"
|
#import "WailsContext.h"
|
||||||
@@ -51,11 +51,10 @@ type Frontend struct {
|
|||||||
assets *assetserver.DesktopAssetServer
|
assets *assetserver.DesktopAssetServer
|
||||||
|
|
||||||
// main window handle
|
// main window handle
|
||||||
mainWindow *Window
|
mainWindow *Window
|
||||||
minWidth, minHeight, maxWidth, maxHeight int
|
bindings *binding.Bindings
|
||||||
bindings *binding.Bindings
|
dispatcher frontend.Dispatcher
|
||||||
dispatcher frontend.Dispatcher
|
servingFromDisk bool
|
||||||
servingFromDisk bool
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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 {
|
||||||
@@ -163,15 +162,11 @@ func (f *Frontend) WindowSetTitle(title string) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (f *Frontend) WindowFullscreen() {
|
func (f *Frontend) WindowFullscreen() {
|
||||||
f.mainWindow.SetMaxSize(0, 0)
|
|
||||||
f.mainWindow.SetMinSize(0, 0)
|
|
||||||
f.mainWindow.Fullscreen()
|
f.mainWindow.Fullscreen()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *Frontend) WindowUnFullscreen() {
|
func (f *Frontend) WindowUnFullscreen() {
|
||||||
f.mainWindow.UnFullscreen()
|
f.mainWindow.UnFullscreen()
|
||||||
f.mainWindow.SetMaxSize(f.maxWidth, f.maxHeight)
|
|
||||||
f.mainWindow.SetMinSize(f.minWidth, f.minHeight)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *Frontend) WindowShow() {
|
func (f *Frontend) WindowShow() {
|
||||||
@@ -195,13 +190,9 @@ func (f *Frontend) WindowUnminimise() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (f *Frontend) WindowSetMinSize(width int, height int) {
|
func (f *Frontend) WindowSetMinSize(width int, height int) {
|
||||||
f.minWidth = width
|
|
||||||
f.minHeight = height
|
|
||||||
f.mainWindow.SetMinSize(width, height)
|
f.mainWindow.SetMinSize(width, height)
|
||||||
}
|
}
|
||||||
func (f *Frontend) WindowSetMaxSize(width int, height int) {
|
func (f *Frontend) WindowSetMaxSize(width int, height int) {
|
||||||
f.maxWidth = width
|
|
||||||
f.maxHeight = height
|
|
||||||
f.mainWindow.SetMaxSize(width, height)
|
f.mainWindow.SetMaxSize(width, height)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -214,9 +205,6 @@ func (f *Frontend) WindowSetRGBA(col *options.RGBA) {
|
|||||||
|
|
||||||
func (f *Frontend) Quit() {
|
func (f *Frontend) Quit() {
|
||||||
f.mainWindow.Quit()
|
f.mainWindow.Quit()
|
||||||
if f.frontendOptions.OnShutdown != nil {
|
|
||||||
f.frontendOptions.OnShutdown(f.ctx)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type EventNotify struct {
|
type EventNotify struct {
|
||||||
@@ -246,6 +234,11 @@ func (f *Frontend) processMessage(message string) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//if strings.HasPrefix(message, "systemevent:") {
|
||||||
|
// f.processSystemEvent(message)
|
||||||
|
// return
|
||||||
|
//}
|
||||||
|
|
||||||
result, err := f.dispatcher.ProcessMessage(message, f)
|
result, err := f.dispatcher.ProcessMessage(message, f)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
f.logger.Error(err.Error())
|
f.logger.Error(err.Error())
|
||||||
@@ -295,6 +288,22 @@ func (f *Frontend) processRequest(r *request) {
|
|||||||
C.ProcessURLResponse(r.ctx, r.url, mimetype, data, C.int(len(_contents)))
|
C.ProcessURLResponse(r.ctx, r.url, mimetype, data, C.int(len(_contents)))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//func (f *Frontend) processSystemEvent(message string) {
|
||||||
|
// sl := strings.Split(message, ":")
|
||||||
|
// if len(sl) != 2 {
|
||||||
|
// f.logger.Error("Invalid system message: %s", message)
|
||||||
|
// return
|
||||||
|
// }
|
||||||
|
// switch sl[1] {
|
||||||
|
// case "fullscreen":
|
||||||
|
// f.mainWindow.DisableSizeConstraints()
|
||||||
|
// case "unfullscreen":
|
||||||
|
// f.mainWindow.EnableSizeConstraints()
|
||||||
|
// default:
|
||||||
|
// f.logger.Error("Unknown system message: %s", message)
|
||||||
|
// }
|
||||||
|
//}
|
||||||
|
|
||||||
//export processMessage
|
//export processMessage
|
||||||
func processMessage(message *C.char) {
|
func processMessage(message *C.char) {
|
||||||
goMessage := C.GoString(message)
|
goMessage := C.GoString(message)
|
||||||
|
|||||||
@@ -200,9 +200,9 @@ unsigned int _Users_username_Pictures_SaltBae_png_len = 1863;
|
|||||||
|
|
||||||
int main(int argc, const char * argv[]) {
|
int main(int argc, const char * argv[]) {
|
||||||
// insert code here...
|
// insert code here...
|
||||||
int frameless = 1;
|
int frameless = 0;
|
||||||
int resizable = 0;
|
int resizable = 1;
|
||||||
int fullscreen = 0;
|
int fullscreen = 1;
|
||||||
int fullSizeContent = 1;
|
int fullSizeContent = 1;
|
||||||
int hideTitleBar = 0;
|
int hideTitleBar = 0;
|
||||||
int titlebarAppearsTransparent = 0;
|
int titlebarAppearsTransparent = 0;
|
||||||
@@ -215,7 +215,10 @@ int main(int argc, const char * argv[]) {
|
|||||||
const char* appearance = "NSAppearanceNameDarkAqua";
|
const char* appearance = "NSAppearanceNameDarkAqua";
|
||||||
int windowIsTranslucent = 1;
|
int windowIsTranslucent = 1;
|
||||||
int debug = 1;
|
int debug = 1;
|
||||||
WailsContext *result = Create("OI OI!",400,400, frameless, resizable, fullscreen, fullSizeContent, hideTitleBar, titlebarAppearsTransparent, hideTitle, useToolbar, hideToolbarSeparator, webviewIsTransparent, alwaysOnTop, hideWindowOnClose, appearance, windowIsTranslucent, debug);
|
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);
|
||||||
SetRGBA(result, 255, 0, 0, 255);
|
SetRGBA(result, 255, 0, 0, 255);
|
||||||
void *m = NewMenu("");
|
void *m = NewMenu("");
|
||||||
SetAbout(result, "Fake title", "I am a description", _Users_username_Pictures_SaltBae_png, _Users_username_Pictures_SaltBae_png_len);
|
SetAbout(result, "Fake title", "I am a description", _Users_username_Pictures_SaltBae_png, _Users_username_Pictures_SaltBae_png_len);
|
||||||
@@ -228,7 +231,7 @@ int main(int argc, const char * argv[]) {
|
|||||||
AppendSubmenu(m, submenu);
|
AppendSubmenu(m, submenu);
|
||||||
UpdateMenuItem(menuITem, 1);
|
UpdateMenuItem(menuITem, 1);
|
||||||
SetAsApplicationMenu(result, m);
|
SetAsApplicationMenu(result, m);
|
||||||
SetPosition(result, 100, 100);
|
// SetPosition(result, 100, 100);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,3 +1,6 @@
|
|||||||
|
//go:build darwin
|
||||||
|
// +build darwin
|
||||||
|
|
||||||
package darwin
|
package darwin
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -56,6 +59,10 @@ func NewWindow(frontendOptions *options.App, debugMode bool) *Window {
|
|||||||
|
|
||||||
width := C.int(frontendOptions.Width)
|
width := C.int(frontendOptions.Width)
|
||||||
height := C.int(frontendOptions.Height)
|
height := C.int(frontendOptions.Height)
|
||||||
|
minWidth := C.int(frontendOptions.MinWidth)
|
||||||
|
minHeight := C.int(frontendOptions.MinHeight)
|
||||||
|
maxWidth := C.int(frontendOptions.MaxWidth)
|
||||||
|
maxHeight := C.int(frontendOptions.MaxHeight)
|
||||||
windowStartState := C.int(int(frontendOptions.WindowStartState))
|
windowStartState := C.int(int(frontendOptions.WindowStartState))
|
||||||
|
|
||||||
title = c.String(frontendOptions.Title)
|
title = c.String(frontendOptions.Title)
|
||||||
@@ -77,7 +84,8 @@ func NewWindow(frontendOptions *options.App, debugMode bool) *Window {
|
|||||||
}
|
}
|
||||||
var context *C.WailsContext = C.Create(title, width, height, frameless, resizable, fullscreen, fullSizeContent,
|
var context *C.WailsContext = C.Create(title, width, height, frameless, resizable, fullscreen, fullSizeContent,
|
||||||
hideTitleBar, titlebarAppearsTransparent, hideTitle, useToolbar, hideToolbarSeparator, webviewIsTransparent,
|
hideTitleBar, titlebarAppearsTransparent, hideTitle, useToolbar, hideToolbarSeparator, webviewIsTransparent,
|
||||||
alwaysOnTop, hideWindowOnClose, appearance, windowIsTranslucent, debug, windowStartState, startsHidden)
|
alwaysOnTop, hideWindowOnClose, appearance, windowIsTranslucent, debug, windowStartState, startsHidden,
|
||||||
|
minWidth, minHeight, maxWidth, maxHeight)
|
||||||
|
|
||||||
// Create menu
|
// Create menu
|
||||||
result := &Window{
|
result := &Window{
|
||||||
@@ -104,9 +112,6 @@ func NewWindow(frontendOptions *options.App, debugMode bool) *Window {
|
|||||||
result.SetApplicationMenu(frontendOptions.Menu)
|
result.SetApplicationMenu(frontendOptions.Menu)
|
||||||
}
|
}
|
||||||
|
|
||||||
result.SetMinSize(frontendOptions.MinWidth, frontendOptions.MinHeight)
|
|
||||||
result.SetMaxSize(frontendOptions.MaxWidth, frontendOptions.MaxHeight)
|
|
||||||
|
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -163,16 +168,10 @@ func (w *Window) UnMinimise() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (w *Window) SetMinSize(width int, height int) {
|
func (w *Window) SetMinSize(width int, height int) {
|
||||||
if width == 0 && height == 0 {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
C.SetMinSize(w.context, C.int(width), C.int(height))
|
C.SetMinSize(w.context, C.int(width), C.int(height))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *Window) SetMaxSize(width int, height int) {
|
func (w *Window) SetMaxSize(width int, height int) {
|
||||||
if width == 0 && height == 0 {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
C.SetMaxSize(w.context, C.int(width), C.int(height))
|
C.SetMaxSize(w.context, C.int(width), C.int(height))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
17
v2/internal/frontend/desktop/desktop_linux.go
Normal file
17
v2/internal/frontend/desktop/desktop_linux.go
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
//go:build linux
|
||||||
|
// +build linux
|
||||||
|
|
||||||
|
package desktop
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"github.com/wailsapp/wails/v2/internal/binding"
|
||||||
|
"github.com/wailsapp/wails/v2/internal/frontend"
|
||||||
|
"github.com/wailsapp/wails/v2/internal/frontend/desktop/linux"
|
||||||
|
"github.com/wailsapp/wails/v2/internal/logger"
|
||||||
|
"github.com/wailsapp/wails/v2/pkg/options"
|
||||||
|
)
|
||||||
|
|
||||||
|
func NewFrontend(ctx context.Context, appoptions *options.App, logger *logger.Logger, appBindings *binding.Bindings, dispatcher frontend.Dispatcher) frontend.Frontend {
|
||||||
|
return linux.NewFrontend(ctx, appoptions, logger, appBindings, dispatcher)
|
||||||
|
}
|
||||||
12
v2/internal/frontend/desktop/linux/browser.go
Normal file
12
v2/internal/frontend/desktop/linux/browser.go
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
//go:build linux
|
||||||
|
// +build linux
|
||||||
|
|
||||||
|
package linux
|
||||||
|
|
||||||
|
import "github.com/pkg/browser"
|
||||||
|
|
||||||
|
// BrowserOpenURL Use the default browser to open the url
|
||||||
|
func (f *Frontend) BrowserOpenURL(url string) {
|
||||||
|
// Specific method implementation
|
||||||
|
_ = browser.OpenURL(url)
|
||||||
|
}
|
||||||
26
v2/internal/frontend/desktop/linux/dialog.go
Normal file
26
v2/internal/frontend/desktop/linux/dialog.go
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
//go:build linux
|
||||||
|
// +build linux
|
||||||
|
|
||||||
|
package linux
|
||||||
|
|
||||||
|
import "github.com/wailsapp/wails/v2/internal/frontend"
|
||||||
|
|
||||||
|
func (f *Frontend) OpenFileDialog(dialogOptions frontend.OpenDialogOptions) (string, error) {
|
||||||
|
panic("implement me")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *Frontend) OpenMultipleFilesDialog(dialogOptions frontend.OpenDialogOptions) ([]string, error) {
|
||||||
|
panic("implement me")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *Frontend) OpenDirectoryDialog(dialogOptions frontend.OpenDialogOptions) (string, error) {
|
||||||
|
panic("implement me")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *Frontend) SaveFileDialog(dialogOptions frontend.SaveDialogOptions) (string, error) {
|
||||||
|
panic("implement me")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *Frontend) MessageDialog(dialogOptions frontend.MessageDialogOptions) (string, error) {
|
||||||
|
panic("implement me")
|
||||||
|
}
|
||||||
401
v2/internal/frontend/desktop/linux/frontend.go
Normal file
401
v2/internal/frontend/desktop/linux/frontend.go
Normal file
@@ -0,0 +1,401 @@
|
|||||||
|
//go:build linux
|
||||||
|
// +build linux
|
||||||
|
|
||||||
|
package linux
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"encoding/json"
|
||||||
|
"log"
|
||||||
|
"strconv"
|
||||||
|
"text/template"
|
||||||
|
|
||||||
|
"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/logger"
|
||||||
|
"github.com/wailsapp/wails/v2/pkg/options"
|
||||||
|
|
||||||
|
"github.com/gotk3/gotk3/gtk"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Frontend struct {
|
||||||
|
|
||||||
|
// Context
|
||||||
|
ctx context.Context
|
||||||
|
|
||||||
|
frontendOptions *options.App
|
||||||
|
logger *logger.Logger
|
||||||
|
debug bool
|
||||||
|
|
||||||
|
// Assets
|
||||||
|
assets *assetserver.DesktopAssetServer
|
||||||
|
startURL string
|
||||||
|
|
||||||
|
// main window handle
|
||||||
|
mainWindow *Window
|
||||||
|
minWidth, minHeight, maxWidth, maxHeight int
|
||||||
|
bindings *binding.Bindings
|
||||||
|
dispatcher frontend.Dispatcher
|
||||||
|
servingFromDisk bool
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewFrontend(ctx context.Context, appoptions *options.App, myLogger *logger.Logger, appBindings *binding.Bindings, dispatcher frontend.Dispatcher) *Frontend {
|
||||||
|
|
||||||
|
result := &Frontend{
|
||||||
|
frontendOptions: appoptions,
|
||||||
|
logger: myLogger,
|
||||||
|
bindings: appBindings,
|
||||||
|
dispatcher: dispatcher,
|
||||||
|
ctx: ctx,
|
||||||
|
minHeight: appoptions.MinHeight,
|
||||||
|
minWidth: appoptions.MinWidth,
|
||||||
|
maxHeight: appoptions.MaxHeight,
|
||||||
|
maxWidth: appoptions.MaxWidth,
|
||||||
|
startURL: "file://wails/",
|
||||||
|
}
|
||||||
|
|
||||||
|
bindingsJSON, err := appBindings.ToJSON()
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
_devServerURL := ctx.Value("devserverurl")
|
||||||
|
if _devServerURL != nil {
|
||||||
|
devServerURL := _devServerURL.(string)
|
||||||
|
if len(devServerURL) > 0 && devServerURL != "http://localhost:34115" {
|
||||||
|
result.startURL = devServerURL
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if we have been given a directory to serve assets from.
|
||||||
|
// If so, this means we are in dev mode and are serving assets off disk.
|
||||||
|
// We indicate this through the `servingFromDisk` flag to ensure requests
|
||||||
|
// aren't cached by WebView2 in dev mode
|
||||||
|
|
||||||
|
_assetdir := ctx.Value("assetdir")
|
||||||
|
if _assetdir != nil {
|
||||||
|
result.servingFromDisk = true
|
||||||
|
}
|
||||||
|
|
||||||
|
assets, err := assetserver.NewDesktopAssetServer(ctx, appoptions.Assets, bindingsJSON)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
result.assets = assets
|
||||||
|
|
||||||
|
// Initialise GTK
|
||||||
|
gtk.Init(nil)
|
||||||
|
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *Frontend) WindowReload() {
|
||||||
|
f.ExecJS("runtime.WindowReload();")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *Frontend) Run(ctx context.Context) error {
|
||||||
|
|
||||||
|
f.ctx = context.WithValue(ctx, "frontend", f)
|
||||||
|
|
||||||
|
mainWindow := NewWindow(f.frontendOptions)
|
||||||
|
f.mainWindow = mainWindow
|
||||||
|
|
||||||
|
var _debug = ctx.Value("debug")
|
||||||
|
if _debug != nil {
|
||||||
|
f.debug = _debug.(bool)
|
||||||
|
}
|
||||||
|
|
||||||
|
//f.WindowCenter()
|
||||||
|
//f.setupChromium()
|
||||||
|
//
|
||||||
|
//gtkWindow.OnSize().Bind(func(arg *winc.Event) {
|
||||||
|
// f.chromium.Resize()
|
||||||
|
//})
|
||||||
|
//
|
||||||
|
//gtkWindow.OnClose().Bind(func(arg *winc.Event) {
|
||||||
|
// if f.frontendOptions.HideWindowOnClose {
|
||||||
|
// f.WindowHide()
|
||||||
|
// } else {
|
||||||
|
// f.Quit()
|
||||||
|
// }
|
||||||
|
//})
|
||||||
|
|
||||||
|
go func() {
|
||||||
|
if f.frontendOptions.OnStartup != nil {
|
||||||
|
f.frontendOptions.OnStartup(f.ctx)
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
|
if f.frontendOptions.Fullscreen {
|
||||||
|
mainWindow.Fullscreen()
|
||||||
|
}
|
||||||
|
|
||||||
|
mainWindow.Run()
|
||||||
|
mainWindow.Close()
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *Frontend) WindowCenter() {
|
||||||
|
f.mainWindow.Center()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *Frontend) WindowSetPos(x, y int) {
|
||||||
|
f.mainWindow.SetPos(x, y)
|
||||||
|
}
|
||||||
|
func (f *Frontend) WindowGetPos() (int, int) {
|
||||||
|
return f.mainWindow.Pos()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *Frontend) WindowSetSize(width, height int) {
|
||||||
|
f.mainWindow.SetSize(width, height)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *Frontend) WindowGetSize() (int, int) {
|
||||||
|
return f.mainWindow.Size()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *Frontend) WindowSetTitle(title string) {
|
||||||
|
f.mainWindow.SetText(title)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *Frontend) WindowFullscreen() {
|
||||||
|
f.mainWindow.SetMaxSize(0, 0)
|
||||||
|
f.mainWindow.SetMinSize(0, 0)
|
||||||
|
f.mainWindow.Fullscreen()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *Frontend) WindowUnFullscreen() {
|
||||||
|
f.mainWindow.UnFullscreen()
|
||||||
|
f.mainWindow.SetMaxSize(f.maxWidth, f.maxHeight)
|
||||||
|
f.mainWindow.SetMinSize(f.minWidth, f.minHeight)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *Frontend) WindowShow() {
|
||||||
|
f.mainWindow.Show()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *Frontend) WindowHide() {
|
||||||
|
f.mainWindow.Hide()
|
||||||
|
}
|
||||||
|
func (f *Frontend) WindowMaximise() {
|
||||||
|
f.mainWindow.Maximise()
|
||||||
|
}
|
||||||
|
func (f *Frontend) WindowUnmaximise() {
|
||||||
|
f.mainWindow.UnMaximise()
|
||||||
|
}
|
||||||
|
func (f *Frontend) WindowMinimise() {
|
||||||
|
f.mainWindow.Minimise()
|
||||||
|
}
|
||||||
|
func (f *Frontend) WindowUnminimise() {
|
||||||
|
f.mainWindow.UnMinimise()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *Frontend) WindowSetMinSize(width int, height int) {
|
||||||
|
f.minWidth = width
|
||||||
|
f.minHeight = height
|
||||||
|
f.mainWindow.SetMinSize(width, height)
|
||||||
|
}
|
||||||
|
func (f *Frontend) WindowSetMaxSize(width int, height int) {
|
||||||
|
f.maxWidth = width
|
||||||
|
f.maxHeight = height
|
||||||
|
f.mainWindow.SetMaxSize(width, height)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *Frontend) WindowSetRGBA(col *options.RGBA) {
|
||||||
|
if col == nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
//
|
||||||
|
//f.gtkWindow.Dispatch(func() {
|
||||||
|
// controller := f.chromium.GetController()
|
||||||
|
// controller2 := controller.GetICoreWebView2Controller2()
|
||||||
|
//
|
||||||
|
// backgroundCol := edge.COREWEBVIEW2_COLOR{
|
||||||
|
// A: col.A,
|
||||||
|
// R: col.R,
|
||||||
|
// G: col.G,
|
||||||
|
// B: col.B,
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// // Webview2 only has 0 and 255 as valid values.
|
||||||
|
// if backgroundCol.A > 0 && backgroundCol.A < 255 {
|
||||||
|
// backgroundCol.A = 255
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// if f.frontendOptions.Windows != nil && f.frontendOptions.Windows.WebviewIsTransparent {
|
||||||
|
// backgroundCol.A = 0
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// err := controller2.PutDefaultBackgroundColor(backgroundCol)
|
||||||
|
// if err != nil {
|
||||||
|
// log.Fatal(err)
|
||||||
|
// }
|
||||||
|
//})
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *Frontend) Quit() {
|
||||||
|
//winc.Exit()
|
||||||
|
}
|
||||||
|
|
||||||
|
//func (f *Frontend) setupChromium() {
|
||||||
|
// chromium := edge.NewChromium()
|
||||||
|
// f.chromium = chromium
|
||||||
|
// chromium.MessageCallback = f.processMessage
|
||||||
|
// chromium.WebResourceRequestedCallback = f.processRequest
|
||||||
|
// chromium.NavigationCompletedCallback = f.navigationCompleted
|
||||||
|
// chromium.AcceleratorKeyCallback = func(vkey uint) bool {
|
||||||
|
// w32.PostMessage(f.gtkWindow.Handle(), w32.WM_KEYDOWN, uintptr(vkey), 0)
|
||||||
|
// return false
|
||||||
|
// }
|
||||||
|
// chromium.Embed(f.gtkWindow.Handle())
|
||||||
|
// chromium.Resize()
|
||||||
|
// settings, err := chromium.GetSettings()
|
||||||
|
// if err != nil {
|
||||||
|
// log.Fatal(err)
|
||||||
|
// }
|
||||||
|
// err = settings.PutAreDefaultContextMenusEnabled(f.debug)
|
||||||
|
// if err != nil {
|
||||||
|
// log.Fatal(err)
|
||||||
|
// }
|
||||||
|
// err = settings.PutAreDevToolsEnabled(f.debug)
|
||||||
|
// if err != nil {
|
||||||
|
// log.Fatal(err)
|
||||||
|
// }
|
||||||
|
// err = settings.PutIsZoomControlEnabled(false)
|
||||||
|
// if err != nil {
|
||||||
|
// log.Fatal(err)
|
||||||
|
// }
|
||||||
|
// err = settings.PutIsStatusBarEnabled(false)
|
||||||
|
// if err != nil {
|
||||||
|
// log.Fatal(err)
|
||||||
|
// }
|
||||||
|
// err = settings.PutAreBrowserAcceleratorKeysEnabled(false)
|
||||||
|
// if err != nil {
|
||||||
|
// log.Fatal(err)
|
||||||
|
// }
|
||||||
|
// err = settings.PutIsSwipeNavigationEnabled(false)
|
||||||
|
// if err != nil {
|
||||||
|
// log.Fatal(err)
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// // Set background colour
|
||||||
|
// f.WindowSetRGBA(f.frontendOptions.RGBA)
|
||||||
|
//
|
||||||
|
// chromium.SetGlobalPermission(edge.CoreWebView2PermissionStateAllow)
|
||||||
|
// chromium.AddWebResourceRequestedFilter("*", edge.COREWEBVIEW2_WEB_RESOURCE_CONTEXT_ALL)
|
||||||
|
// chromium.Navigate(f.startURL)
|
||||||
|
//}
|
||||||
|
|
||||||
|
type EventNotify struct {
|
||||||
|
Name string `json:"name"`
|
||||||
|
Data []interface{} `json:"data"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *Frontend) Notify(name string, data ...interface{}) {
|
||||||
|
notification := EventNotify{
|
||||||
|
Name: name,
|
||||||
|
Data: data,
|
||||||
|
}
|
||||||
|
payload, err := json.Marshal(notification)
|
||||||
|
if err != nil {
|
||||||
|
f.logger.Error(err.Error())
|
||||||
|
return
|
||||||
|
}
|
||||||
|
f.ExecJS(`window.wails.EventsNotify('` + template.JSEscapeString(string(payload)) + `');`)
|
||||||
|
}
|
||||||
|
|
||||||
|
//func (f *Frontend) processRequest(req *edge.ICoreWebView2WebResourceRequest, args *edge.ICoreWebView2WebResourceRequestedEventArgs) {
|
||||||
|
// //Get the request
|
||||||
|
// uri, _ := req.GetUri()
|
||||||
|
//
|
||||||
|
// // Translate URI
|
||||||
|
// uri = strings.TrimPrefix(uri, "file://wails")
|
||||||
|
// if !strings.HasPrefix(uri, "/") {
|
||||||
|
// return
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// // Load file from asset store
|
||||||
|
// content, mimeType, err := f.assets.Load(uri)
|
||||||
|
// if err != nil {
|
||||||
|
// return
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// env := f.chromium.Environment()
|
||||||
|
// headers := "Content-Type: " + mimeType
|
||||||
|
// if f.servingFromDisk {
|
||||||
|
// headers += "\nPragma: no-cache"
|
||||||
|
// }
|
||||||
|
// response, err := env.CreateWebResourceResponse(content, 200, "OK", headers)
|
||||||
|
// if err != nil {
|
||||||
|
// return
|
||||||
|
// }
|
||||||
|
// // Send response back
|
||||||
|
// err = args.PutResponse(response)
|
||||||
|
// if err != nil {
|
||||||
|
// return
|
||||||
|
// }
|
||||||
|
// return
|
||||||
|
//}
|
||||||
|
|
||||||
|
func (f *Frontend) processMessage(message string) {
|
||||||
|
if message == "drag" {
|
||||||
|
if !f.mainWindow.IsFullScreen() {
|
||||||
|
err := f.startDrag()
|
||||||
|
if err != nil {
|
||||||
|
f.logger.Error(err.Error())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
result, err := f.dispatcher.ProcessMessage(message, f)
|
||||||
|
if err != nil {
|
||||||
|
f.logger.Error(err.Error())
|
||||||
|
f.Callback(result)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if result == "" {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
switch result[0] {
|
||||||
|
case 'c':
|
||||||
|
// Callback from a method call
|
||||||
|
f.Callback(result[1:])
|
||||||
|
default:
|
||||||
|
f.logger.Info("Unknown message returned from dispatcher: %+v", result)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *Frontend) Callback(message string) {
|
||||||
|
f.ExecJS(`window.wails.Callback(` + strconv.Quote(message) + `);`)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *Frontend) startDrag() error {
|
||||||
|
//if !w32.ReleaseCapture() {
|
||||||
|
// return fmt.Errorf("unable to release mouse capture")
|
||||||
|
//}
|
||||||
|
//w32.SendMessage(f.gtkWindow.Handle(), w32.WM_NCLBUTTONDOWN, w32.HTCAPTION, 0)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *Frontend) ExecJS(js string) {
|
||||||
|
//f.gtkWindow.Dispatch(func() {
|
||||||
|
// f.chromium.Eval(js)
|
||||||
|
//})
|
||||||
|
}
|
||||||
|
|
||||||
|
//func (f *Frontend) navigationCompleted(sender *edge.ICoreWebView2, args *edge.ICoreWebView2NavigationCompletedEventArgs) {
|
||||||
|
// if f.frontendOptions.OnDomReady != nil {
|
||||||
|
// go f.frontendOptions.OnDomReady(f.ctx)
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// // If you want to start hidden, return
|
||||||
|
// if f.frontendOptions.StartHidden {
|
||||||
|
// return
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// f.gtkWindow.Show()
|
||||||
|
//
|
||||||
|
//}
|
||||||
14
v2/internal/frontend/desktop/linux/menu.go
Normal file
14
v2/internal/frontend/desktop/linux/menu.go
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
//go:build linux
|
||||||
|
// +build linux
|
||||||
|
|
||||||
|
package linux
|
||||||
|
|
||||||
|
import "github.com/wailsapp/wails/v2/pkg/menu"
|
||||||
|
|
||||||
|
func (f *Frontend) MenuSetApplicationMenu(menu *menu.Menu) {
|
||||||
|
panic("implement me")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *Frontend) MenuUpdateApplicationMenu() {
|
||||||
|
panic("implement me")
|
||||||
|
}
|
||||||
247
v2/internal/frontend/desktop/linux/window.go
Normal file
247
v2/internal/frontend/desktop/linux/window.go
Normal file
@@ -0,0 +1,247 @@
|
|||||||
|
//go:build linux
|
||||||
|
// +build linux
|
||||||
|
|
||||||
|
package linux
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/gotk3/gotk3/gdk"
|
||||||
|
"github.com/gotk3/gotk3/glib"
|
||||||
|
"github.com/gotk3/gotk3/gtk"
|
||||||
|
"github.com/wailsapp/wails/v2/pkg/menu"
|
||||||
|
"github.com/wailsapp/wails/v2/pkg/options"
|
||||||
|
"github.com/wailsapp/wails/v2/pkg/options/linux"
|
||||||
|
"log"
|
||||||
|
"math"
|
||||||
|
"sync"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Window struct {
|
||||||
|
frontendOptions *options.App
|
||||||
|
applicationMenu *menu.Menu
|
||||||
|
m sync.Mutex
|
||||||
|
application *gtk.Application
|
||||||
|
gtkWindow *gtk.ApplicationWindow
|
||||||
|
|
||||||
|
//dispatchq []func()
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewWindow(options *options.App) *Window {
|
||||||
|
result := new(Window)
|
||||||
|
result.frontendOptions = options
|
||||||
|
|
||||||
|
var linuxOptions linux.Options
|
||||||
|
if options.Linux != nil {
|
||||||
|
linuxOptions = *options.Linux
|
||||||
|
}
|
||||||
|
appID := linuxOptions.AppID
|
||||||
|
if appID == "" {
|
||||||
|
appID = "io.wails"
|
||||||
|
}
|
||||||
|
|
||||||
|
println("AppID =", appID)
|
||||||
|
|
||||||
|
application, err := gtk.ApplicationNew(appID, glib.APPLICATION_FLAGS_NONE)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal("Could not create application:", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
result.application = application
|
||||||
|
|
||||||
|
application.Connect("activate", func() {
|
||||||
|
|
||||||
|
window, err := gtk.ApplicationWindowNew(application)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal("Could not create application window:", err)
|
||||||
|
}
|
||||||
|
window.Connect("delete-event", func() {
|
||||||
|
if options.HideWindowOnClose {
|
||||||
|
result.gtkWindow.Hide()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
result.gtkWindow.Close()
|
||||||
|
})
|
||||||
|
result.gtkWindow = window
|
||||||
|
window.SetTitle(options.Title)
|
||||||
|
window.SetDecorated(!options.Frameless)
|
||||||
|
window.SetDefaultSize(600, 300)
|
||||||
|
window.SetResizable(!options.DisableResize)
|
||||||
|
window.SetKeepAbove(options.AlwaysOnTop)
|
||||||
|
window.SetPosition(gtk.WIN_POS_CENTER)
|
||||||
|
if !options.StartHidden {
|
||||||
|
window.ShowAll()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
//result.SetIsForm(true)
|
||||||
|
//
|
||||||
|
//var exStyle int
|
||||||
|
//if options.Windows != nil {
|
||||||
|
// exStyle = w32.WS_EX_CONTROLPARENT | w32.WS_EX_APPWINDOW
|
||||||
|
// if options.Windows.WindowIsTranslucent {
|
||||||
|
// exStyle |= w32.WS_EX_NOREDIRECTIONBITMAP
|
||||||
|
// }
|
||||||
|
//}
|
||||||
|
//if options.AlwaysOnTop {
|
||||||
|
// exStyle |= w32.WS_EX_TOPMOST
|
||||||
|
//}
|
||||||
|
//
|
||||||
|
//var dwStyle = w32.WS_OVERLAPPEDWINDOW
|
||||||
|
//if options.Frameless {
|
||||||
|
// dwStyle = w32.WS_POPUP
|
||||||
|
//}
|
||||||
|
//
|
||||||
|
//winc.RegClassOnlyOnce("wailsWindow")
|
||||||
|
//result.SetHandle(winc.CreateWindow("wailsWindow", parent, uint(exStyle), uint(dwStyle)))
|
||||||
|
//result.SetParent(parent)
|
||||||
|
//
|
||||||
|
//loadIcon := true
|
||||||
|
//if options.Windows != nil && options.Windows.DisableWindowIcon == true {
|
||||||
|
// loadIcon = false
|
||||||
|
//}
|
||||||
|
//if loadIcon {
|
||||||
|
// if ico, err := winc.NewIconFromResource(winc.GetAppInstance(), uint16(winc.AppIconID)); err == nil {
|
||||||
|
// result.SetIcon(0, ico)
|
||||||
|
// }
|
||||||
|
//}
|
||||||
|
//
|
||||||
|
//result.SetSize(options.Width, options.Height)
|
||||||
|
//result.SetText(options.Title)
|
||||||
|
//if options.Frameless == false && !options.Fullscreen {
|
||||||
|
// result.EnableMaxButton(!options.DisableResize)
|
||||||
|
// result.EnableSizable(!options.DisableResize)
|
||||||
|
// result.SetMinSize(options.MinWidth, options.MinHeight)
|
||||||
|
// result.SetMaxSize(options.MaxWidth, options.MaxHeight)
|
||||||
|
//}
|
||||||
|
//
|
||||||
|
//if options.Windows != nil {
|
||||||
|
// if options.Windows.WindowIsTranslucent {
|
||||||
|
// result.SetTranslucentBackground()
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// if options.Windows.DisableWindowIcon {
|
||||||
|
// result.DisableIcon()
|
||||||
|
// }
|
||||||
|
//}
|
||||||
|
//
|
||||||
|
//// Dlg forces display of focus rectangles, as soon as the user starts to type.
|
||||||
|
//w32.SendMessage(result.Handle(), w32.WM_CHANGEUISTATE, w32.UIS_INITIALIZE, 0)
|
||||||
|
//winc.RegMsgHandler(result)
|
||||||
|
//
|
||||||
|
//result.SetFont(winc.DefaultFont)
|
||||||
|
//
|
||||||
|
//if options.Menu != nil {
|
||||||
|
// result.SetApplicationMenu(options.Menu)
|
||||||
|
//}
|
||||||
|
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w *Window) Run() {
|
||||||
|
w.application.Run(nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w *Window) Dispatch(f func()) {
|
||||||
|
glib.IdleAdd(f)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w *Window) Fullscreen() {
|
||||||
|
w.gtkWindow.Fullscreen()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w *Window) UnFullscreen() {
|
||||||
|
w.gtkWindow.Unfullscreen()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w *Window) Close() {
|
||||||
|
w.application.Quit()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w *Window) Center() {
|
||||||
|
w.gtkWindow.SetPosition(gtk.WIN_POS_CENTER)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w *Window) SetPos(x int, y int) {
|
||||||
|
display, err := w.gtkWindow.GetDisplay()
|
||||||
|
if err != nil {
|
||||||
|
w.gtkWindow.Move(x, y)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
window, err := w.gtkWindow.GetWindow()
|
||||||
|
if err != nil {
|
||||||
|
w.gtkWindow.Move(x, y)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
monitor, err := display.GetMonitorAtWindow(window)
|
||||||
|
if err != nil {
|
||||||
|
w.gtkWindow.Move(x, y)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
geom := monitor.GetGeometry()
|
||||||
|
w.gtkWindow.Move(geom.GetX()+x, geom.GetY()+y)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w *Window) Pos() (int, int) {
|
||||||
|
return w.gtkWindow.GetPosition()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w *Window) SetSize(width int, height int) {
|
||||||
|
w.gtkWindow.SetDefaultSize(width, height)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w *Window) Size() (int, int) {
|
||||||
|
return w.gtkWindow.GetSize()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w *Window) SetText(title string) {
|
||||||
|
w.gtkWindow.SetTitle(title)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w *Window) SetMaxSize(maxWidth int, maxHeight int) {
|
||||||
|
var geom gdk.Geometry
|
||||||
|
if maxWidth == 0 {
|
||||||
|
maxWidth = math.MaxInt
|
||||||
|
}
|
||||||
|
if maxHeight == 0 {
|
||||||
|
maxHeight = math.MaxInt
|
||||||
|
}
|
||||||
|
geom.SetMaxWidth(maxWidth)
|
||||||
|
geom.SetMaxHeight(maxHeight)
|
||||||
|
w.gtkWindow.SetGeometryHints(w.gtkWindow, geom, gdk.HINT_MAX_SIZE)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w *Window) SetMinSize(minWidth int, minHeight int) {
|
||||||
|
var geom gdk.Geometry
|
||||||
|
geom.SetMinWidth(minWidth)
|
||||||
|
geom.SetMinHeight(minHeight)
|
||||||
|
w.gtkWindow.SetGeometryHints(w.gtkWindow, geom, gdk.HINT_MIN_SIZE)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w *Window) Show() {
|
||||||
|
w.gtkWindow.ShowAll()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w *Window) Hide() {
|
||||||
|
w.gtkWindow.Hide()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w *Window) Maximise() {
|
||||||
|
w.gtkWindow.Maximize()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w *Window) UnMaximise() {
|
||||||
|
w.gtkWindow.Unmaximize()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w *Window) Minimise() {
|
||||||
|
w.gtkWindow.Iconify()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w *Window) UnMinimise() {
|
||||||
|
w.gtkWindow.Present()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w *Window) IsFullScreen() bool {
|
||||||
|
return false
|
||||||
|
}
|
||||||
@@ -168,11 +168,17 @@ func (f *Frontend) WindowFullscreen() {
|
|||||||
runtime.LockOSThread()
|
runtime.LockOSThread()
|
||||||
f.mainWindow.SetMaxSize(0, 0)
|
f.mainWindow.SetMaxSize(0, 0)
|
||||||
f.mainWindow.SetMinSize(0, 0)
|
f.mainWindow.SetMinSize(0, 0)
|
||||||
|
if f.frontendOptions.Frameless && f.frontendOptions.DisableResize == false {
|
||||||
|
f.ExecJS("window.wails.flags.enableResize = false;")
|
||||||
|
}
|
||||||
f.mainWindow.Fullscreen()
|
f.mainWindow.Fullscreen()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *Frontend) WindowUnFullscreen() {
|
func (f *Frontend) WindowUnFullscreen() {
|
||||||
runtime.LockOSThread()
|
runtime.LockOSThread()
|
||||||
|
if f.frontendOptions.Frameless && f.frontendOptions.DisableResize == false {
|
||||||
|
f.ExecJS("window.wails.flags.enableResize = true;")
|
||||||
|
}
|
||||||
f.mainWindow.UnFullscreen()
|
f.mainWindow.UnFullscreen()
|
||||||
f.mainWindow.SetMaxSize(f.maxWidth, f.maxHeight)
|
f.mainWindow.SetMaxSize(f.maxWidth, f.maxHeight)
|
||||||
f.mainWindow.SetMinSize(f.minWidth, f.minHeight)
|
f.mainWindow.SetMinSize(f.minWidth, f.minHeight)
|
||||||
@@ -354,6 +360,17 @@ func (f *Frontend) processRequest(req *edge.ICoreWebView2WebResourceRequest, arg
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var edgeMap = map[string]uintptr{
|
||||||
|
"n-resize": w32.HTTOP,
|
||||||
|
"ne-resize": w32.HTTOPRIGHT,
|
||||||
|
"e-resize": w32.HTRIGHT,
|
||||||
|
"se-resize": w32.HTBOTTOMRIGHT,
|
||||||
|
"s-resize": w32.HTBOTTOM,
|
||||||
|
"sw-resize": w32.HTBOTTOMLEFT,
|
||||||
|
"w-resize": w32.HTLEFT,
|
||||||
|
"nw-resize": w32.HTTOPLEFT,
|
||||||
|
}
|
||||||
|
|
||||||
func (f *Frontend) processMessage(message string) {
|
func (f *Frontend) processMessage(message string) {
|
||||||
if message == "drag" {
|
if message == "drag" {
|
||||||
if !f.mainWindow.IsFullScreen() {
|
if !f.mainWindow.IsFullScreen() {
|
||||||
@@ -364,6 +381,21 @@ func (f *Frontend) processMessage(message string) {
|
|||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
if strings.HasPrefix(message, "resize:") {
|
||||||
|
if !f.mainWindow.IsFullScreen() {
|
||||||
|
sl := strings.Split(message, ":")
|
||||||
|
if len(sl) != 2 {
|
||||||
|
f.logger.Info("Unknown message returned from dispatcher: %+v", message)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
edge := edgeMap[sl[1]]
|
||||||
|
err := f.startResize(edge)
|
||||||
|
if err != nil {
|
||||||
|
f.logger.Error(err.Error())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
result, err := f.dispatcher.ProcessMessage(message, f)
|
result, err := f.dispatcher.ProcessMessage(message, f)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
f.logger.Error(err.Error())
|
f.logger.Error(err.Error())
|
||||||
@@ -397,6 +429,14 @@ func (f *Frontend) startDrag() error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (f *Frontend) startResize(border uintptr) error {
|
||||||
|
if !w32.ReleaseCapture() {
|
||||||
|
return fmt.Errorf("unable to release mouse capture")
|
||||||
|
}
|
||||||
|
w32.SendMessage(f.mainWindow.Handle(), w32.WM_NCLBUTTONDOWN, border, 0)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func (f *Frontend) ExecJS(js string) {
|
func (f *Frontend) ExecJS(js string) {
|
||||||
f.mainWindow.Dispatch(func() {
|
f.mainWindow.Dispatch(func() {
|
||||||
f.chromium.Eval(js)
|
f.chromium.Eval(js)
|
||||||
@@ -408,6 +448,10 @@ func (f *Frontend) navigationCompleted(sender *edge.ICoreWebView2, args *edge.IC
|
|||||||
go f.frontendOptions.OnDomReady(f.ctx)
|
go f.frontendOptions.OnDomReady(f.ctx)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if f.frontendOptions.Frameless && f.frontendOptions.DisableResize == false {
|
||||||
|
f.ExecJS("window.wails.flags.enableResize = true;")
|
||||||
|
}
|
||||||
|
|
||||||
// Hack to make it visible: https://github.com/MicrosoftEdge/WebView2Feedback/issues/1077#issuecomment-825375026
|
// Hack to make it visible: https://github.com/MicrosoftEdge/WebView2Feedback/issues/1077#issuecomment-825375026
|
||||||
err := f.chromium.Hide()
|
err := f.chromium.Hide()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
@@ -43,6 +43,8 @@ window.wails = {
|
|||||||
flags: {
|
flags: {
|
||||||
disableScrollbarDrag: false,
|
disableScrollbarDrag: false,
|
||||||
disableWailsDefaultContextMenu: false,
|
disableWailsDefaultContextMenu: false,
|
||||||
|
enableResize: false,
|
||||||
|
defaultCursor: null
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -60,6 +62,15 @@ if (ENV === 0) {
|
|||||||
// Setup drag handler
|
// Setup drag handler
|
||||||
// Based on code from: https://github.com/patr0nus/DeskGap
|
// Based on code from: https://github.com/patr0nus/DeskGap
|
||||||
window.addEventListener('mousedown', (e) => {
|
window.addEventListener('mousedown', (e) => {
|
||||||
|
|
||||||
|
// Check for resizing
|
||||||
|
if (window.wails.flags.resizeEdge) {
|
||||||
|
window.WailsInvoke("resize:" + window.wails.flags.resizeEdge);
|
||||||
|
e.preventDefault();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check for dragging
|
||||||
let currentElement = e.target;
|
let currentElement = e.target;
|
||||||
while (currentElement != null) {
|
while (currentElement != null) {
|
||||||
if (currentElement.hasAttribute('data-wails-no-drag')) {
|
if (currentElement.hasAttribute('data-wails-no-drag')) {
|
||||||
@@ -79,6 +90,40 @@ window.addEventListener('mousedown', (e) => {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
function setResize(cursor) {
|
||||||
|
document.body.style.cursor = cursor || window.wails.flags.defaultCursor;
|
||||||
|
window.wails.flags.resizeEdge = cursor;
|
||||||
|
}
|
||||||
|
|
||||||
|
window.addEventListener('mousemove', function (e) {
|
||||||
|
if (!window.wails.flags.enableResize) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (window.wails.flags.defaultCursor == null) {
|
||||||
|
window.wails.flags.defaultCursor = document.body.style.cursor;
|
||||||
|
}
|
||||||
|
if (window.outerWidth - e.clientX < 16 && window.outerHeight - e.clientY < 16) {
|
||||||
|
document.body.style.cursor = "se-resize";
|
||||||
|
}
|
||||||
|
let rightBorder = window.outerWidth - e.clientX < 16;
|
||||||
|
let leftBorder = e.clientX < 16;
|
||||||
|
let topBorder = e.clientY < 16;
|
||||||
|
let bottomBorder = window.outerHeight - e.clientY < 16;
|
||||||
|
|
||||||
|
// If we aren't on an edge, but were, reset the cursor to default
|
||||||
|
if (!leftBorder && !rightBorder && !topBorder && !bottomBorder && window.wails.flags.resizeEdge !== undefined) {
|
||||||
|
setResize();
|
||||||
|
} else if (rightBorder && bottomBorder) setResize("se-resize");
|
||||||
|
else if (leftBorder && bottomBorder) setResize("sw-resize");
|
||||||
|
else if (leftBorder && topBorder) setResize("nw-resize");
|
||||||
|
else if (topBorder && rightBorder) setResize("ne-resize");
|
||||||
|
else if (leftBorder) setResize("w-resize");
|
||||||
|
else if (topBorder) setResize("n-resize");
|
||||||
|
else if (bottomBorder) setResize("s-resize");
|
||||||
|
else if (rightBorder) setResize("e-resize");
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
// Setup context menu hook
|
// Setup context menu hook
|
||||||
window.addEventListener('contextmenu', function (e) {
|
window.addEventListener('contextmenu', function (e) {
|
||||||
if (window.wails.flags.disableWailsDefaultContextMenu) {
|
if (window.wails.flags.disableWailsDefaultContextMenu) {
|
||||||
|
|||||||
@@ -1,5 +1,3 @@
|
|||||||
//go:build darwin || windows
|
|
||||||
|
|
||||||
package runtime
|
package runtime
|
||||||
|
|
||||||
import _ "embed"
|
import _ "embed"
|
||||||
|
|||||||
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
@@ -243,7 +243,7 @@ func (b *BaseBuilder) CompileProject(options *Options) error {
|
|||||||
|
|
||||||
if options.Mode == Production {
|
if options.Mode == Production {
|
||||||
ldflags.Add("-w", "-s")
|
ldflags.Add("-w", "-s")
|
||||||
if runtime.GOOS == "windows" {
|
if options.Platform == "windows" {
|
||||||
ldflags.Add("-H windowsgui")
|
ldflags.Add("-H windowsgui")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -295,10 +295,12 @@ func (b *BaseBuilder) CompileProject(options *Options) error {
|
|||||||
if options.Platform != "windows" {
|
if options.Platform != "windows" {
|
||||||
// Use upsertEnv so we don't overwrite user's CGO_CFLAGS
|
// Use upsertEnv so we don't overwrite user's CGO_CFLAGS
|
||||||
cmd.Env = upsertEnv(cmd.Env, "CGO_CFLAGS", func(v string) string {
|
cmd.Env = upsertEnv(cmd.Env, "CGO_CFLAGS", func(v string) string {
|
||||||
if v != "" {
|
if options.Platform == "darwin" {
|
||||||
v += " "
|
if v != "" {
|
||||||
|
v += " "
|
||||||
|
}
|
||||||
|
v += "-mmacosx-version-min=10.13"
|
||||||
}
|
}
|
||||||
v += "-mmacosx-version-min=10.13"
|
|
||||||
return v
|
return v
|
||||||
})
|
})
|
||||||
// Use upsertEnv so we don't overwrite user's CGO_CXXFLAGS
|
// Use upsertEnv so we don't overwrite user's CGO_CXXFLAGS
|
||||||
@@ -313,7 +315,7 @@ func (b *BaseBuilder) CompileProject(options *Options) error {
|
|||||||
cmd.Env = upsertEnv(cmd.Env, "CGO_ENABLED", func(v string) string {
|
cmd.Env = upsertEnv(cmd.Env, "CGO_ENABLED", func(v string) string {
|
||||||
return "1"
|
return "1"
|
||||||
})
|
})
|
||||||
if runtime.GOOS == "darwin" {
|
if options.Platform == "darwin" {
|
||||||
// Set the minimum Mac SDK to 10.13
|
// Set the minimum Mac SDK to 10.13
|
||||||
cmd.Env = upsertEnv(cmd.Env, "CGO_LDFLAGS", func(v string) string {
|
cmd.Env = upsertEnv(cmd.Env, "CGO_LDFLAGS", func(v string) string {
|
||||||
if v != "" {
|
if v != "" {
|
||||||
|
|||||||
@@ -6,7 +6,6 @@ import (
|
|||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"runtime"
|
"runtime"
|
||||||
"strings"
|
|
||||||
|
|
||||||
"github.com/wailsapp/wails/v2/internal/fs"
|
"github.com/wailsapp/wails/v2/internal/fs"
|
||||||
|
|
||||||
@@ -212,16 +211,6 @@ func Build(options *Options) (string, error) {
|
|||||||
|
|
||||||
result := options.CompiledBinary
|
result := options.CompiledBinary
|
||||||
|
|
||||||
if options.Pack && options.Platform == "darwin" {
|
|
||||||
sr := strings.Split(result, "/")
|
|
||||||
for i := len(sr) - 1; i >= 0; i-- {
|
|
||||||
if strings.Contains(sr[i], ".app") {
|
|
||||||
result = strings.Join(sr[:i+1], "/")
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return result, nil
|
return result, nil
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -27,6 +27,8 @@ func packageProject(options *Options, platform string) error {
|
|||||||
err = packageApplicationForDarwin(options)
|
err = packageApplicationForDarwin(options)
|
||||||
case "windows":
|
case "windows":
|
||||||
err = packageApplicationForWindows(options)
|
err = packageApplicationForWindows(options)
|
||||||
|
case "linux":
|
||||||
|
err = packageApplicationForLinux(options)
|
||||||
default:
|
default:
|
||||||
err = fmt.Errorf("packing not supported for %s yet", platform)
|
err = fmt.Errorf("packing not supported for %s yet", platform)
|
||||||
}
|
}
|
||||||
@@ -204,6 +206,29 @@ func packageApplicationForWindows(options *Options) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func packageApplicationForLinux(options *Options) error {
|
||||||
|
// Generate icon
|
||||||
|
//var err error
|
||||||
|
//err = generateIcoFile(options)
|
||||||
|
//if err != nil {
|
||||||
|
// return err
|
||||||
|
//}
|
||||||
|
//
|
||||||
|
//// Ensure Manifest is present
|
||||||
|
//err = generateManifest(options)
|
||||||
|
//if err != nil {
|
||||||
|
// return err
|
||||||
|
//}
|
||||||
|
//
|
||||||
|
//// Create syso file
|
||||||
|
//err = compileResources(options)
|
||||||
|
//if err != nil {
|
||||||
|
// return err
|
||||||
|
//}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func generateManifest(options *Options) error {
|
func generateManifest(options *Options) error {
|
||||||
filename := options.ProjectData.Name + ".exe.manifest"
|
filename := options.ProjectData.Name + ".exe.manifest"
|
||||||
manifestFile := filepath.Join(options.ProjectData.Path, "build", "windows", filename)
|
manifestFile := filepath.Join(options.ProjectData.Path, "build", "windows", filename)
|
||||||
|
|||||||
7
v2/pkg/options/linux/linux.go
Normal file
7
v2/pkg/options/linux/linux.go
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
package linux
|
||||||
|
|
||||||
|
// Options specific to Linux builds
|
||||||
|
type Options struct {
|
||||||
|
// AppID is the gtk application id string. Defaults to a random uuid.
|
||||||
|
AppID string
|
||||||
|
}
|
||||||
@@ -3,6 +3,7 @@ package options
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"embed"
|
"embed"
|
||||||
|
"github.com/wailsapp/wails/v2/pkg/options/linux"
|
||||||
"log"
|
"log"
|
||||||
"runtime"
|
"runtime"
|
||||||
|
|
||||||
@@ -54,6 +55,7 @@ type App struct {
|
|||||||
//TrayMenus []*menu.TrayMenu
|
//TrayMenus []*menu.TrayMenu
|
||||||
Windows *windows.Options
|
Windows *windows.Options
|
||||||
Mac *mac.Options
|
Mac *mac.Options
|
||||||
|
Linux *linux.Options
|
||||||
}
|
}
|
||||||
|
|
||||||
type RGBA struct {
|
type RGBA struct {
|
||||||
|
|||||||
@@ -14,6 +14,14 @@ sidebar_position: 99
|
|||||||
<div
|
<div
|
||||||
dangerouslySetInnerHTML={{
|
dangerouslySetInnerHTML={{
|
||||||
__html: `
|
__html: `
|
||||||
|
<a href="https://github.com/sponsors/leaanthony" style="width:100px;">
|
||||||
|
<img src="/img/silver%20sponsor.png" width="100"/>
|
||||||
|
</a>
|
||||||
|
<a href="https://github.com/letheanVPN" style="width:100px;">
|
||||||
|
<img src="https://github.com/letheanVPN.png?size=100" width="100"/>
|
||||||
|
</a>
|
||||||
|
<br/>
|
||||||
|
<br/>
|
||||||
<a href="https://github.com/sponsors/leaanthony" style="width:100px;">
|
<a href="https://github.com/sponsors/leaanthony" style="width:100px;">
|
||||||
<img src="/img/bronze%20sponsor.png" width="100"/>
|
<img src="/img/bronze%20sponsor.png" width="100"/>
|
||||||
</a>
|
</a>
|
||||||
|
|||||||
@@ -67,7 +67,7 @@ import TabItem from "@theme/TabItem";
|
|||||||
|
|
||||||
## Installing Wails
|
## Installing Wails
|
||||||
|
|
||||||
Run `go install github.com/wailsapp/wails/v2/cmd/wails@v2.0.0-beta.20` to install the Wails CLI.
|
Run `go install github.com/wailsapp/wails/v2/cmd/wails@latest` to install the Wails CLI.
|
||||||
|
|
||||||
## System Check
|
## System Check
|
||||||
|
|
||||||
|
|||||||
@@ -36,6 +36,7 @@ func main() {
|
|||||||
OnStartup: app.startup,
|
OnStartup: app.startup,
|
||||||
OnDomReady: app.domready,
|
OnDomReady: app.domready,
|
||||||
OnShutdown: app.shutdown,
|
OnShutdown: app.shutdown,
|
||||||
|
WindowStartState: options.Maximised,
|
||||||
Bind: []interface{}{
|
Bind: []interface{}{
|
||||||
app,
|
app,
|
||||||
},
|
},
|
||||||
@@ -258,6 +259,20 @@ Type: func(ctx context.Context)
|
|||||||
This callback is called after the frontend has been destroyed, just before the application terminates. It is given
|
This callback is called after the frontend has been destroyed, just before the application terminates. It is given
|
||||||
the application context.
|
the application context.
|
||||||
|
|
||||||
|
### WindowStartState
|
||||||
|
|
||||||
|
Name: WindowStartState
|
||||||
|
|
||||||
|
Type: options.WindowStartState
|
||||||
|
|
||||||
|
Defines how the window should present itself at startup.
|
||||||
|
|
||||||
|
| Value | Win | Mac |
|
||||||
|
| --------------- | --- | --- |
|
||||||
|
| Fullscreen | ✅ | ✅ |
|
||||||
|
| Maximised | ✅ | ✅ |
|
||||||
|
| Minimised | ✅ | |
|
||||||
|
|
||||||
### Bind
|
### Bind
|
||||||
|
|
||||||
Name: Bind
|
Name: Bind
|
||||||
@@ -452,3 +467,4 @@ When clicked, that will open an about message box:
|
|||||||
<img src="/img/reference/about-dialog.png" width="40%" style={{"box-shadow": "rgb(255 255 255 / 20%) 0px 4px 8px 0px, rgb(104 104 104) 0px 6px 20px 0px"}}/>
|
<img src="/img/reference/about-dialog.png" width="40%" style={{"box-shadow": "rgb(255 255 255 / 20%) 0px 4px 8px 0px, rgb(104 104 104) 0px 6px 20px 0px"}}/>
|
||||||
</div>
|
</div>
|
||||||
<br/>
|
<br/>
|
||||||
|
|
||||||
|
|||||||
@@ -8,9 +8,19 @@ The runtime is a library that provides utility methods for your application. The
|
|||||||
and the aim is to try and keep them at parity where possible.
|
and the aim is to try and keep them at parity where possible.
|
||||||
|
|
||||||
The Go Runtime is available through importing `github.com/wailsapp/wails/v2/pkg/runtime`. All methods in this package
|
The Go Runtime is available through importing `github.com/wailsapp/wails/v2/pkg/runtime`. All methods in this package
|
||||||
take a context as the first parameter. This context can be obtained from the [OnStartup](/docs/reference/options#OnStartup)
|
take a context as the first parameter. This context can be obtained from the [OnStartup](/docs/reference/options#onstartup)
|
||||||
or [OnDomReady](/docs/reference/options#OnDomReady) hooks.
|
or [OnDomReady](/docs/reference/options#ondomready) hooks.
|
||||||
|
|
||||||
|
:::info Note
|
||||||
|
|
||||||
|
Whilst the context will be provided to the
|
||||||
|
[OnStartup](/docs/reference/options#onstartup) method, there's no guarantee the runtime will work in this method as
|
||||||
|
the window is initialising in a different thread. If
|
||||||
|
you wish to call runtime methods at startup, use [OnDomReady](/docs/reference/options#ondomready).
|
||||||
|
|
||||||
|
:::
|
||||||
|
|
||||||
The Javascript library is available to the frontend via the `window.runtime` map. There is a runtime package generated when using `dev`
|
The Javascript library is available to the frontend via the `window.runtime` map. There is a runtime package generated when using `dev`
|
||||||
mode that provides Typescript declarations for the runtime. This should be located in the `wailsjs` directory in your
|
mode that provides Typescript declarations for the runtime. This should be located in the `wailsjs` directory in your
|
||||||
frontend directory.
|
frontend directory.
|
||||||
|
|
||||||
|
|||||||
@@ -14,6 +14,14 @@ sidebar_position: 99
|
|||||||
<div
|
<div
|
||||||
dangerouslySetInnerHTML={{
|
dangerouslySetInnerHTML={{
|
||||||
__html: `
|
__html: `
|
||||||
|
<a href="https://github.com/sponsors/leaanthony" style="width:100px;">
|
||||||
|
<img src="/img/silver%20sponsor.png" width="100"/>
|
||||||
|
</a>
|
||||||
|
<a href="https://github.com/letheanVPN" style="width:100px;">
|
||||||
|
<img src="https://github.com/letheanVPN.png?size=100" width="100"/>
|
||||||
|
</a>
|
||||||
|
<br/>
|
||||||
|
<br/>
|
||||||
<a href="https://github.com/sponsors/leaanthony" style="width:100px;">
|
<a href="https://github.com/sponsors/leaanthony" style="width:100px;">
|
||||||
<img src="/img/bronze%20sponsor.png" width="100"/>
|
<img src="/img/bronze%20sponsor.png" width="100"/>
|
||||||
</a>
|
</a>
|
||||||
|
|||||||
@@ -63,7 +63,7 @@ import TabItem from "@theme/TabItem";
|
|||||||
|
|
||||||
## 安装 Wails
|
## 安装 Wails
|
||||||
|
|
||||||
运行 `go install github.com/wailsapp/wails/v2/cmd/wails@v2.0.0-beta.20` 安装 Wails CLI。
|
运行 `go install github.com/wailsapp/wails/v2/cmd/wails@latest` 安装 Wails CLI。
|
||||||
|
|
||||||
## 系统检查
|
## 系统检查
|
||||||
|
|
||||||
|
|||||||
BIN
website/static/img/silver sponsor.png
Normal file
BIN
website/static/img/silver sponsor.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 22 KiB |
Reference in New Issue
Block a user