diff --git a/v2/internal/binding/binding.go b/v2/internal/binding/binding.go index 4908635e1..b7bf07ae0 100644 --- a/v2/internal/binding/binding.go +++ b/v2/internal/binding/binding.go @@ -123,7 +123,15 @@ func (b *Bindings) GenerateModels() ([]byte, error) { // if we have enums for this package, add them as well var enums, enumsExist = b.enumsToGenerateTS[packageName] if enumsExist { - for enumName, enum := range enums { + // Sort the enum names first to make the output deterministic + sortedEnumNames := make([]string, 0, len(enums)) + for enumName := range enums { + sortedEnumNames = append(sortedEnumNames, enumName) + } + sort.Strings(sortedEnumNames) + + for _, enumName := range sortedEnumNames { + enum := enums[enumName] fqemumname := packageName + "." + enumName if seen.Contains(fqemumname) { continue @@ -172,7 +180,7 @@ func (b *Bindings) GenerateModels() ([]byte, error) { } // Sort the package names first to make the output deterministic - sortedPackageNames := make([]string, 0) + sortedPackageNames := make([]string, 0, len(models)) for packageName := range models { sortedPackageNames = append(sortedPackageNames, packageName) } diff --git a/v2/internal/binding/binding_test/binding_enum_ordering_test.go b/v2/internal/binding/binding_test/binding_enum_ordering_test.go new file mode 100644 index 000000000..0939535ec --- /dev/null +++ b/v2/internal/binding/binding_test/binding_enum_ordering_test.go @@ -0,0 +1,271 @@ +package binding_test + +// Test for PR #4664: Fix generated enums ordering +// This test ensures that enum output is deterministic regardless of map iteration order + +// ZFirstEnum - named with Z prefix to test alphabetical sorting +type ZFirstEnum int + +const ( + ZFirstEnumValue1 ZFirstEnum = iota + ZFirstEnumValue2 +) + +var AllZFirstEnumValues = []struct { + Value ZFirstEnum + TSName string +}{ + {ZFirstEnumValue1, "ZValue1"}, + {ZFirstEnumValue2, "ZValue2"}, +} + +// ASecondEnum - named with A prefix to test alphabetical sorting +type ASecondEnum int + +const ( + ASecondEnumValue1 ASecondEnum = iota + ASecondEnumValue2 +) + +var AllASecondEnumValues = []struct { + Value ASecondEnum + TSName string +}{ + {ASecondEnumValue1, "AValue1"}, + {ASecondEnumValue2, "AValue2"}, +} + +// MMiddleEnum - named with M prefix to test alphabetical sorting +type MMiddleEnum int + +const ( + MMiddleEnumValue1 MMiddleEnum = iota + MMiddleEnumValue2 +) + +var AllMMiddleEnumValues = []struct { + Value MMiddleEnum + TSName string +}{ + {MMiddleEnumValue1, "MValue1"}, + {MMiddleEnumValue2, "MValue2"}, +} + +type EntityWithMultipleEnums struct { + Name string `json:"name"` + EnumZ ZFirstEnum `json:"enumZ"` + EnumA ASecondEnum `json:"enumA"` + EnumM MMiddleEnum `json:"enumM"` +} + +func (e EntityWithMultipleEnums) Get() EntityWithMultipleEnums { + return e +} + +// EnumOrderingTest tests that multiple enums in the same package are output +// in alphabetical order by enum name. Before PR #4664, the order was +// non-deterministic due to Go map iteration order. +var EnumOrderingTest = BindingTest{ + name: "EnumOrderingTest", + structs: []interface{}{ + &EntityWithMultipleEnums{}, + }, + enums: []interface{}{ + // Intentionally add enums in non-alphabetical order + AllZFirstEnumValues, + AllASecondEnumValues, + AllMMiddleEnumValues, + }, + exemptions: nil, + shouldError: false, + TsGenerationOptionsTest: TsGenerationOptionsTest{ + TsPrefix: "", + TsSuffix: "", + }, + // Expected output should have enums in alphabetical order: ASecondEnum, MMiddleEnum, ZFirstEnum + want: `export namespace binding_test { + + export enum ASecondEnum { + AValue1 = 0, + AValue2 = 1, + } + export enum MMiddleEnum { + MValue1 = 0, + MValue2 = 1, + } + export enum ZFirstEnum { + ZValue1 = 0, + ZValue2 = 1, + } + export class EntityWithMultipleEnums { + name: string; + enumZ: ZFirstEnum; + enumA: ASecondEnum; + enumM: MMiddleEnum; + + static createFrom(source: any = {}) { + return new EntityWithMultipleEnums(source); + } + + constructor(source: any = {}) { + if ('string' === typeof source) source = JSON.parse(source); + this.name = source["name"]; + this.enumZ = source["enumZ"]; + this.enumA = source["enumA"]; + this.enumM = source["enumM"]; + } + } + +} +`, +} + +// EnumElementOrderingEnum tests sorting of enum elements by TSName +type EnumElementOrderingEnum string + +const ( + EnumElementZ EnumElementOrderingEnum = "z_value" + EnumElementA EnumElementOrderingEnum = "a_value" + EnumElementM EnumElementOrderingEnum = "m_value" +) + +// AllEnumElementOrderingValues intentionally lists values out of alphabetical order +// to test that AddEnum sorts them +var AllEnumElementOrderingValues = []struct { + Value EnumElementOrderingEnum + TSName string +}{ + {EnumElementZ, "Zebra"}, + {EnumElementA, "Apple"}, + {EnumElementM, "Mango"}, +} + +type EntityWithUnorderedEnumElements struct { + Name string `json:"name"` + Enum EnumElementOrderingEnum `json:"enum"` +} + +func (e EntityWithUnorderedEnumElements) Get() EntityWithUnorderedEnumElements { + return e +} + +// EnumElementOrderingTest tests that enum elements are sorted alphabetically +// by their TSName within an enum. Before PR #4664, elements appeared in the +// order they were added, which could be arbitrary. +var EnumElementOrderingTest = BindingTest{ + name: "EnumElementOrderingTest", + structs: []interface{}{ + &EntityWithUnorderedEnumElements{}, + }, + enums: []interface{}{ + AllEnumElementOrderingValues, + }, + exemptions: nil, + shouldError: false, + TsGenerationOptionsTest: TsGenerationOptionsTest{ + TsPrefix: "", + TsSuffix: "", + }, + // Expected output should have enum elements sorted: Apple, Mango, Zebra + want: `export namespace binding_test { + + export enum EnumElementOrderingEnum { + Apple = "a_value", + Mango = "m_value", + Zebra = "z_value", + } + export class EntityWithUnorderedEnumElements { + name: string; + enum: EnumElementOrderingEnum; + + static createFrom(source: any = {}) { + return new EntityWithUnorderedEnumElements(source); + } + + constructor(source: any = {}) { + if ('string' === typeof source) source = JSON.parse(source); + this.name = source["name"]; + this.enum = source["enum"]; + } + } + +} +`, +} + +// TSNameEnumElementOrdering tests sorting with TSName() method enum +type TSNameEnumElementOrdering string + +const ( + TSNameEnumZ TSNameEnumElementOrdering = "z_value" + TSNameEnumA TSNameEnumElementOrdering = "a_value" + TSNameEnumM TSNameEnumElementOrdering = "m_value" +) + +func (v TSNameEnumElementOrdering) TSName() string { + switch v { + case TSNameEnumZ: + return "Zebra" + case TSNameEnumA: + return "Apple" + case TSNameEnumM: + return "Mango" + default: + return "Unknown" + } +} + +// AllTSNameEnumValues intentionally out of order +var AllTSNameEnumValues = []TSNameEnumElementOrdering{TSNameEnumZ, TSNameEnumA, TSNameEnumM} + +type EntityWithTSNameEnumOrdering struct { + Name string `json:"name"` + Enum TSNameEnumElementOrdering `json:"enum"` +} + +func (e EntityWithTSNameEnumOrdering) Get() EntityWithTSNameEnumOrdering { + return e +} + +// TSNameEnumElementOrderingTest tests that enums using TSName() method +// also have their elements sorted alphabetically by the TSName. +var TSNameEnumElementOrderingTest = BindingTest{ + name: "TSNameEnumElementOrderingTest", + structs: []interface{}{ + &EntityWithTSNameEnumOrdering{}, + }, + enums: []interface{}{ + AllTSNameEnumValues, + }, + exemptions: nil, + shouldError: false, + TsGenerationOptionsTest: TsGenerationOptionsTest{ + TsPrefix: "", + TsSuffix: "", + }, + // Expected output should have enum elements sorted: Apple, Mango, Zebra + want: `export namespace binding_test { + + export enum TSNameEnumElementOrdering { + Apple = "a_value", + Mango = "m_value", + Zebra = "z_value", + } + export class EntityWithTSNameEnumOrdering { + name: string; + enum: TSNameEnumElementOrdering; + + static createFrom(source: any = {}) { + return new EntityWithTSNameEnumOrdering(source); + } + + constructor(source: any = {}) { + if ('string' === typeof source) source = JSON.parse(source); + this.name = source["name"]; + this.enum = source["enum"]; + } + } + +} +`, +} diff --git a/v2/internal/binding/binding_test/binding_test.go b/v2/internal/binding/binding_test/binding_test.go index d358d8b0f..41f0618ce 100644 --- a/v2/internal/binding/binding_test/binding_test.go +++ b/v2/internal/binding/binding_test/binding_test.go @@ -55,6 +55,10 @@ func TestBindings_GenerateModels(t *testing.T) { Generics2Test, IgnoredTest, DeepElementsTest, + // PR #4664: Enum ordering tests + EnumOrderingTest, + EnumElementOrderingTest, + TSNameEnumElementOrderingTest, } testLogger := &logger.Logger{} diff --git a/v2/internal/frontend/desktop/darwin/AppDelegate.m b/v2/internal/frontend/desktop/darwin/AppDelegate.m index 318c333d8..a73ec3ec3 100644 --- a/v2/internal/frontend/desktop/darwin/AppDelegate.m +++ b/v2/internal/frontend/desktop/darwin/AppDelegate.m @@ -9,6 +9,7 @@ #import #import "AppDelegate.h" +#import "CustomProtocol.h" #import "message.h" @implementation AppDelegate @@ -19,6 +20,17 @@ return YES; } +- (BOOL)application:(NSApplication *)application continueUserActivity:(NSUserActivity *)userActivity restorationHandler:(void (^)(NSArray> * _Nullable))restorationHandler { + if ([userActivity.activityType isEqualToString:NSUserActivityTypeBrowsingWeb]) { + NSURL *url = userActivity.webpageURL; + if (url) { + HandleOpenURL((char*)[[url absoluteString] UTF8String]); + return YES; + } + } + return NO; +} + - (BOOL)applicationShouldTerminateAfterLastWindowClosed:(NSApplication *)sender { return NO; } diff --git a/v2/internal/frontend/desktop/darwin/CustomProtocol.h b/v2/internal/frontend/desktop/darwin/CustomProtocol.h index da0e7079f..0698a4d45 100644 --- a/v2/internal/frontend/desktop/darwin/CustomProtocol.h +++ b/v2/internal/frontend/desktop/darwin/CustomProtocol.h @@ -3,7 +3,7 @@ #import -extern void HandleCustomProtocol(char*); +extern void HandleOpenURL(char*); @interface CustomProtocolSchemeHandler : NSObject + (void)handleGetURLEvent:(NSAppleEventDescriptor *)event withReplyEvent:(NSAppleEventDescriptor *)replyEvent; diff --git a/v2/internal/frontend/desktop/darwin/CustomProtocol.m b/v2/internal/frontend/desktop/darwin/CustomProtocol.m index 7365e4f50..ebc61aa00 100644 --- a/v2/internal/frontend/desktop/darwin/CustomProtocol.m +++ b/v2/internal/frontend/desktop/darwin/CustomProtocol.m @@ -6,7 +6,7 @@ NSString *urlStr = [[event paramDescriptorForKeyword:keyDirectObject] stringValue]; - HandleCustomProtocol((char*)[[[event paramDescriptorForKeyword:keyDirectObject] stringValue] UTF8String]); + HandleOpenURL((char*)[[[event paramDescriptorForKeyword:keyDirectObject] stringValue] UTF8String]); } @end diff --git a/v2/internal/frontend/desktop/darwin/frontend.go b/v2/internal/frontend/desktop/darwin/frontend.go index c9e70d4be..6566445d5 100644 --- a/v2/internal/frontend/desktop/darwin/frontend.go +++ b/v2/internal/frontend/desktop/darwin/frontend.go @@ -518,8 +518,8 @@ func HandleOpenFile(filePath *C.char) { openFilepathBuffer <- goFilepath } -//export HandleCustomProtocol -func HandleCustomProtocol(url *C.char) { +//export HandleOpenURL +func HandleOpenURL(url *C.char) { goUrl := C.GoString(url) openUrlBuffer <- goUrl } diff --git a/v2/internal/typescriptify/typescriptify.go b/v2/internal/typescriptify/typescriptify.go index 216fba820..e732c5976 100644 --- a/v2/internal/typescriptify/typescriptify.go +++ b/v2/internal/typescriptify/typescriptify.go @@ -2,6 +2,7 @@ package typescriptify import ( "bufio" + "cmp" "fmt" "io" "log" @@ -9,6 +10,7 @@ import ( "path" "reflect" "regexp" + "slices" "strings" "time" @@ -372,6 +374,9 @@ func (t *TypeScriptify) AddEnum(values interface{}) *TypeScriptify { elements = append(elements, el) } + slices.SortFunc(elements, func(a, b enumElement) int { + return cmp.Compare(a.name, b.name) + }) ty := reflect.TypeOf(elements[0].value) t.enums[ty] = elements t.enumTypes = append(t.enumTypes, EnumType{Type: ty}) @@ -516,9 +521,6 @@ func (t TypeScriptify) ConvertToFile(fileName string, packageName string) error if _, err := f.WriteString(converted); err != nil { return err } - if err != nil { - return err - } return nil } diff --git a/website/docs/guides/application-development.mdx b/website/docs/guides/application-development.mdx index ae3880fd9..adefa4b04 100644 --- a/website/docs/guides/application-development.mdx +++ b/website/docs/guides/application-development.mdx @@ -10,6 +10,10 @@ The pattern used by the default templates are that `main.go` is used for configu The `app.go` file will define a struct that has 2 methods which act as hooks into the main application: ```go title="app.go" +import ( + "context" +) + type App struct { ctx context.Context } @@ -28,7 +32,7 @@ func (a *App) shutdown(ctx context.Context) { - The startup method is called as soon as Wails allocates the resources it needs and is a good place for creating resources, setting up event listeners and anything else the application needs at startup. - It is given a `context.Context` which is usually saved in a struct field. This context is needed for calling the + It is given a [`context.Context`](https://pkg.go.dev/context) which is usually saved in a struct field. This context is needed for calling the [runtime](../reference/runtime/intro.mdx). If this method returns an error, the application will terminate. In dev mode, the error will be output to the console. @@ -55,7 +59,6 @@ func main() { log.Fatal(err) } } - ``` More information on application lifecycle hooks can be found [here](../howdoesitwork.mdx#application-lifecycle-callbacks). @@ -65,7 +68,12 @@ More information on application lifecycle hooks can be found [here](../howdoesit It is likely that you will want to call Go methods from the frontend. This is normally done by adding public methods to the already defined struct in `app.go`: -```go {16-18} title="app.go" +```go {3,21-23} title="app.go" +import ( + "context" + "fmt" +) + type App struct { ctx context.Context } @@ -82,7 +90,7 @@ func (a *App) shutdown(ctx context.Context) { } func (a *App) Greet(name string) string { - return fmt.Sprintf("Hello %s!", name) + return fmt.Sprintf("Hello %s!", name) } ``` @@ -99,15 +107,14 @@ func main() { Height: 600, OnStartup: app.startup, OnShutdown: app.shutdown, - Bind: []interface{}{ - app, - }, + Bind: []interface{}{ + app, + }, }) if err != nil { log.Fatal(err) } } - ``` This will bind all public methods in our `App` struct (it will never bind the startup and shutdown methods). @@ -133,10 +140,10 @@ func main() { otherStruct.SetContext(ctx) }, OnShutdown: app.shutdown, - Bind: []interface{}{ - app, + Bind: []interface{}{ + app, otherStruct - }, + }, }) if err != nil { log.Fatal(err) @@ -187,18 +194,17 @@ func main() { Height: 600, OnStartup: app.startup, OnShutdown: app.shutdown, - Bind: []interface{}{ - app, - }, - EnumBind: []interface{}{ - AllWeekdays, - }, + Bind: []interface{}{ + app, + }, + EnumBind: []interface{}{ + AllWeekdays, + }, }) if err != nil { log.Fatal(err) } } - ``` This will add missing enums to your `model.ts` file. @@ -223,15 +229,14 @@ func main() { OnStartup: app.startup, OnShutdown: app.shutdown, Menu: app.menu(), - Bind: []interface{}{ - app, - }, + Bind: []interface{}{ + app, + }, }) if err != nil { log.Fatal(err) } } - ``` ## Assets diff --git a/website/docs/guides/custom-protocol-schemes.mdx b/website/docs/guides/custom-protocol-schemes.mdx index c56634f0e..216fb7100 100644 --- a/website/docs/guides/custom-protocol-schemes.mdx +++ b/website/docs/guides/custom-protocol-schemes.mdx @@ -59,6 +59,24 @@ func main() { } ``` +If you want to handle universal links as well, follow this [guide](https://developer.apple.com/documentation/xcode/supporting-universal-links-in-your-app) to add required entitlements, add required keys to Info.plist and configure `apple-app-site-association` on your website. + +Here is example for Info.plist: +```xml +NSUserActivityTypes + + NSUserActivityTypeBrowsingWeb + +``` + +And for entitlements.plist +```xml +com.apple.developer.associated-domains + + applinks:myawesomeapp.com + +``` + ### Windows On Windows Custom Protocol Schemes is supported only with NSIS installer. During installation, the installer will create a diff --git a/website/docs/howdoesitwork.mdx b/website/docs/howdoesitwork.mdx index 48243f4eb..bdfbcb278 100644 --- a/website/docs/howdoesitwork.mdx +++ b/website/docs/howdoesitwork.mdx @@ -63,17 +63,17 @@ func main() { type App struct { - ctx context.Context + ctx context.Context } func (b *App) startup(ctx context.Context) { - b.ctx = ctx + b.ctx = ctx } func (b *App) shutdown(ctx context.Context) {} func (b *App) Greet(name string) string { - return fmt.Sprintf("Hello %s!", name) + return fmt.Sprintf("Hello %s!", name) } ``` @@ -178,18 +178,18 @@ func main() { type App struct { - ctx context.Context + ctx context.Context } func (a *App) Greet(name string) string { - return fmt.Sprintf("Hello %s!", name) + return fmt.Sprintf("Hello %s!", name) } ``` You may bind as many structs as you like. Just make sure you create an instance of it and pass it in `Bind`: ```go {10-12} - //... + //... err := wails.Run(&options.App{ Title: "Basic Demo", Width: 1024, @@ -203,7 +203,6 @@ You may bind as many structs as you like. Just make sure you create an instance &mystruct2{}, }, }) - ``` You may bind enums types as well. @@ -237,7 +236,7 @@ var AllWeekdays = []struct { ``` ```go {10-12} - //... + //... err := wails.Run(&options.App{ Title: "Basic Demo", Width: 1024, @@ -250,11 +249,10 @@ var AllWeekdays = []struct { &mystruct1{}, &mystruct2{}, }, - EnumBind: []interface{}{ - AllWeekdays, - }, + EnumBind: []interface{}{ + AllWeekdays, + }, }) - ``` When you run `wails dev` (or `wails generate module`), a frontend module will be generated containing the following: diff --git a/website/docs/reference/menus.mdx b/website/docs/reference/menus.mdx index 4a9b4da1b..52f399f0b 100644 --- a/website/docs/reference/menus.mdx +++ b/website/docs/reference/menus.mdx @@ -8,10 +8,23 @@ It is possible to add an application menu to Wails projects. This is achieved by setting it in the [`Menu`](../reference/options.mdx#menu) application config, or by calling the runtime method [MenuSetApplicationMenu](../reference/runtime/menu.mdx#menusetapplicationmenu). -An example of how to create a menu: +An example of how to create a menu, using [the `NewApp` scaffold](../guides/application-development.mdx): -```go +```go title="main.go" +package main +import ( + "log" + "runtime" + + "github.com/wailsapp/wails/v2" + "github.com/wailsapp/wails/v2/pkg/menu" + "github.com/wailsapp/wails/v2/pkg/menu/keys" + "github.com/wailsapp/wails/v2/pkg/options" + rt "github.com/wailsapp/wails/v2/pkg/runtime" +) + +func main() { app := NewApp() AppMenu := menu.NewMenu() @@ -29,7 +42,7 @@ An example of how to create a menu: }) if runtime.GOOS == "darwin" { - AppMenu.Append(menu.EditMenu()) // On macOS platform, EditMenu should be appended to enable Cmd+C, Cmd+V, Cmd+Z... shortcuts + AppMenu.Append(menu.EditMenu()) // On macOS platform, EditMenu should be appended to enable Cmd+C, Cmd+V, Cmd+Z... shortcuts } err := wails.Run(&options.App{ @@ -40,8 +53,11 @@ An example of how to create a menu: Bind: []interface{}{ app, }, - ) - // ... + }) + if err != nil { + log.Fatal(err) + } +} ``` It is also possible to dynamically update the menu, by updating the menu struct and calling diff --git a/website/i18n/zh-Hans/docusaurus-plugin-content-docs/current/reference/runtime/window.mdx b/website/i18n/zh-Hans/docusaurus-plugin-content-docs/current/reference/runtime/window.mdx index f1fc78c99..3645087e7 100644 --- a/website/i18n/zh-Hans/docusaurus-plugin-content-docs/current/reference/runtime/window.mdx +++ b/website/i18n/zh-Hans/docusaurus-plugin-content-docs/current/reference/runtime/window.mdx @@ -86,7 +86,7 @@ Go: `WindowSetDarkTheme(ctx context.Context)`
JS: `WindowSetDarkTheme()` Go: `WindowShow(ctx context.Context)`
JS: `WindowShow()` -### WindowShow 隐藏窗口 +### WindowHide 隐藏窗口 如果当前可见,则隐藏窗口。 diff --git a/website/i18n/zh-Hans/docusaurus-plugin-content-docs/version-v2.10/reference/runtime/window.mdx b/website/i18n/zh-Hans/docusaurus-plugin-content-docs/version-v2.10/reference/runtime/window.mdx index a9799f06a..0a0f434ae 100644 --- a/website/i18n/zh-Hans/docusaurus-plugin-content-docs/version-v2.10/reference/runtime/window.mdx +++ b/website/i18n/zh-Hans/docusaurus-plugin-content-docs/version-v2.10/reference/runtime/window.mdx @@ -86,7 +86,7 @@ Go: `WindowSetDarkTheme(ctx context.Context)`
JS: `WindowSetDarkTheme()` Go: `WindowShow(ctx context.Context)`
JS: `WindowShow()` -### WindowShow 隐藏窗口 +### WindowHide 隐藏窗口 如果当前可见,则隐藏窗口。 diff --git a/website/i18n/zh-Hans/docusaurus-plugin-content-docs/version-v2.5.0/reference/runtime/window.mdx b/website/i18n/zh-Hans/docusaurus-plugin-content-docs/version-v2.5.0/reference/runtime/window.mdx index 9cad686ed..be711f34b 100644 --- a/website/i18n/zh-Hans/docusaurus-plugin-content-docs/version-v2.5.0/reference/runtime/window.mdx +++ b/website/i18n/zh-Hans/docusaurus-plugin-content-docs/version-v2.5.0/reference/runtime/window.mdx @@ -86,7 +86,7 @@ Go: `WindowSetDarkTheme(ctx context.Context)`
JS: `WindowSetDarkTheme()` Go: `WindowShow(ctx context.Context)`
JS: `WindowShow()` -### WindowShow 隐藏窗口 +### WindowHide 隐藏窗口 如果当前可见,则隐藏窗口。 diff --git a/website/i18n/zh-Hans/docusaurus-plugin-content-docs/version-v2.6.0/reference/runtime/window.mdx b/website/i18n/zh-Hans/docusaurus-plugin-content-docs/version-v2.6.0/reference/runtime/window.mdx index 9cad686ed..be711f34b 100644 --- a/website/i18n/zh-Hans/docusaurus-plugin-content-docs/version-v2.6.0/reference/runtime/window.mdx +++ b/website/i18n/zh-Hans/docusaurus-plugin-content-docs/version-v2.6.0/reference/runtime/window.mdx @@ -86,7 +86,7 @@ Go: `WindowSetDarkTheme(ctx context.Context)`
JS: `WindowSetDarkTheme()` Go: `WindowShow(ctx context.Context)`
JS: `WindowShow()` -### WindowShow 隐藏窗口 +### WindowHide 隐藏窗口 如果当前可见,则隐藏窗口。 diff --git a/website/i18n/zh-Hans/docusaurus-plugin-content-docs/version-v2.7.0/reference/runtime/window.mdx b/website/i18n/zh-Hans/docusaurus-plugin-content-docs/version-v2.7.0/reference/runtime/window.mdx index a4b9c1263..3b405c76b 100644 --- a/website/i18n/zh-Hans/docusaurus-plugin-content-docs/version-v2.7.0/reference/runtime/window.mdx +++ b/website/i18n/zh-Hans/docusaurus-plugin-content-docs/version-v2.7.0/reference/runtime/window.mdx @@ -86,7 +86,7 @@ Go: `WindowSetDarkTheme(ctx context.Context)`
JS: `WindowSetDarkTheme()` Go: `WindowShow(ctx context.Context)`
JS: `WindowShow()` -### WindowShow 隐藏窗口 +### WindowHide 隐藏窗口 如果当前可见,则隐藏窗口。 diff --git a/website/i18n/zh-Hans/docusaurus-plugin-content-docs/version-v2.8.0/reference/runtime/window.mdx b/website/i18n/zh-Hans/docusaurus-plugin-content-docs/version-v2.8.0/reference/runtime/window.mdx index a4b9c1263..3b405c76b 100644 --- a/website/i18n/zh-Hans/docusaurus-plugin-content-docs/version-v2.8.0/reference/runtime/window.mdx +++ b/website/i18n/zh-Hans/docusaurus-plugin-content-docs/version-v2.8.0/reference/runtime/window.mdx @@ -86,7 +86,7 @@ Go: `WindowSetDarkTheme(ctx context.Context)`
JS: `WindowSetDarkTheme()` Go: `WindowShow(ctx context.Context)`
JS: `WindowShow()` -### WindowShow 隐藏窗口 +### WindowHide 隐藏窗口 如果当前可见,则隐藏窗口。 diff --git a/website/i18n/zh-Hans/docusaurus-plugin-content-docs/version-v2.8.1/reference/runtime/window.mdx b/website/i18n/zh-Hans/docusaurus-plugin-content-docs/version-v2.8.1/reference/runtime/window.mdx index a4b9c1263..3b405c76b 100644 --- a/website/i18n/zh-Hans/docusaurus-plugin-content-docs/version-v2.8.1/reference/runtime/window.mdx +++ b/website/i18n/zh-Hans/docusaurus-plugin-content-docs/version-v2.8.1/reference/runtime/window.mdx @@ -86,7 +86,7 @@ Go: `WindowSetDarkTheme(ctx context.Context)`
JS: `WindowSetDarkTheme()` Go: `WindowShow(ctx context.Context)`
JS: `WindowShow()` -### WindowShow 隐藏窗口 +### WindowHide 隐藏窗口 如果当前可见,则隐藏窗口。 diff --git a/website/src/pages/changelog.mdx b/website/src/pages/changelog.mdx index 25fab6e4c..671d209c9 100644 --- a/website/src/pages/changelog.mdx +++ b/website/src/pages/changelog.mdx @@ -14,6 +14,16 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +### Fixed + +- Updated menu reference docs with complete imports by @agilgur5 in [#4727](https://github.com/wailsapp/wails/pull/4727) and [#4742](https://github.com/wailsapp/wails/pull/4742) +- Fixed menu reference syntax by @agilgur5 in [#4726](https://github.com/wailsapp/wails/pull/4726) +- Fixed indentation in Application Development guide by @agilgur5 in [#4730](https://github.com/wailsapp/wails/pull/4730) +- Updated Application Development guide to show imports in the `app.go` snippets by @agilgur5 in [#4731](https://github.com/wailsapp/wails/pull/4731) +- Fixed link to CoC in Community Guide when there was a trailing slash by @agilgur5 in [#4732](https://github.com/wailsapp/wails/pull/4732) +- Fixed indentation in "How does it work?" page by @agilgur5 in [#4733](https://github.com/wailsapp/wails/pull/4733) +- Updated wails installation documentation to allow copying the `install wails` command with one click by @tilak999 in [#4692](https://github.com/wailsapp/wails/pull/4692) + ## v2.11.0 - 2025-11-08 ### Added @@ -23,12 +33,14 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Added `ContentProtection` option to allow hiding the application window from screen sharing software [#4241](https://github.com/wailsapp/wails/pull/4241) by [@Taiterbase](https://github.com/Taiterbase) - Added `build:tags` to project specification for automatically adding compilation tags by @symball in [PR](https://github.com/wailsapp/wails/pull/4439) - Support for binding generics in [PR](https://github.dev/wailsapp/wails/pull/3626) by @ktsivkov +- Add universal link support for macOS by @APshenkin in [PR](https://github.com/wailsapp/wails/pull/4693) ### Fixed - Added url validation for BrowserOpenURL by @APshenkin in [PR](https://github.com/wailsapp/wails/pull/4484) - Fixed C compilation error in onWayland on Linux due to declaration after label [#4446](https://github.com/wailsapp/wails/pull/4446) by [@jaesung9507](https://github.com/jaesung9507) - Use computed style when adding 'wails-drop-target-active' [PR](https://github.com/wailsapp/wails/pull/4420) by [@riannucci](https://github.com/riannucci) - Fixed panic when adding menuroles on Linux [#4558](https://github.com/wailsapp/wails/pull/4558) by [@jaesung9507](https://github.com/jaesung9507) +- Fixed generated enums ordering [#4664](https://github.com/wailsapp/wails/pull/4664) by [@rprtr258](https://github.com/rprtr258). - Fixed Discord badge in README by @sharkmu in [PR](https://github.com/wailsapp/wails/pull/4626) - Fixed HTML DnD by @leaanthony diff --git a/website/src/pages/community-guide.mdx b/website/src/pages/community-guide.mdx index 585015942..a0be54ad9 100644 --- a/website/src/pages/community-guide.mdx +++ b/website/src/pages/community-guide.mdx @@ -6,7 +6,7 @@ The number of Wails users is growing at an incredible rate, and if you're readin ### Code of Conduct -This [Code of Conduct](./coc) is an easy guide to develop the technical communities in which we participate. +This [Code of Conduct](/coc) is an easy guide to develop the technical communities in which we participate. ### Stay in the Know diff --git a/website/static/img/sponsors.svg b/website/static/img/sponsors.svg index eb8c70dfd..ac7e8aa23 100644 --- a/website/static/img/sponsors.svg +++ b/website/static/img/sponsors.svg @@ -1,4 +1,4 @@ - + -Silver Sponsors - letheanVPN - - - - - - - - Orb +Silver Sponsors + Orb - + - + Bronze Sponsors Cody Bentley @@ -70,91 +62,107 @@ text { Covering Costs - Marcus + Marcus - + - + - Iain + Iain - + - + - Michael + Michael - + - + - BlueSky... + BlueSky... - + - + + + + Sergio + + + + + Buying Breakfast - Tai Groot + Tai Groot - + - + - Tom Wu + Tom Wu - + - + - vaaski + vaaski - + - + - Sander + Sander - + - + - Kevin + Kevin - + - + - elapse2039 + elapse2039 - + - + - Zach + Zach - + - + + + + zakaria + + + + + Buying Coffee @@ -234,139 +242,133 @@ text { - + - + - - + + - - - - - - - - + - - + + - + - + - + - + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Helpers - + - + - + - + - + - - - - - - - - + - + - + - + - + - + - + - + - - - - - - - - + - + - + - + - + - - + + - - - - - - - - - - - - - - + diff --git a/website/versioned_docs/version-v2.10/gettingstarted/installation.mdx b/website/versioned_docs/version-v2.10/gettingstarted/installation.mdx index 1511e3865..19f349f3e 100644 --- a/website/versioned_docs/version-v2.10/gettingstarted/installation.mdx +++ b/website/versioned_docs/version-v2.10/gettingstarted/installation.mdx @@ -73,6 +73,10 @@ import TabItem from "@theme/TabItem"; Run `go install github.com/wailsapp/wails/v2/cmd/wails@latest` to install the Wails CLI. +```shell +go install github.com/wailsapp/wails/v2/cmd/wails@latest +``` + Note: If you get an error similar to this: ```shell diff --git a/website/versioned_docs/version-v2.11.0/community/templates.mdx b/website/versioned_docs/version-v2.11.0/community/templates.mdx index 3b020b60b..f10f51df3 100644 --- a/website/versioned_docs/version-v2.11.0/community/templates.mdx +++ b/website/versioned_docs/version-v2.11.0/community/templates.mdx @@ -29,6 +29,8 @@ If you are unsure about a template, inspect `package.json` and `wails.json` for - [wails-template-naive](https://github.com/tk103331/wails-template-naive) - Wails template based on Naive UI (A Vue 3 Component Library) - [wails-template-primevue-sakai](https://github.com/TekWizely/wails-template-primevue-sakai) - Wails starter using [PrimeVue's Sakai Application Template](https://sakai.primevue.org) (Vite, Vue, PrimeVue, TailwindCSS, Vue Router, Themes, Dark Mode, UI Components, and more) - [wails-template-tdesign-js](https://github.com/tongque0/wails-template-tdesign-js) - Wails template based on TDesign UI (a Vue 3 UI library by Tencent), using Vite, Pinia, Vue Router, ESLint, and Prettier. +- [wails-nuxt-template](https://github.com/paulbrickwell/wails-nuxt-template) - Wails template using Nuxt 4 +- [wails-nuxt-tailwind-template](https://github.com/paulbrickwell/wails-nuxt-tailwind-template) - Wails template using Nuxt 4 and the official Nuxt Tailwind and Nuxt Color Mode modules ## Angular