5
0
mirror of https://github.com/wailsapp/wails.git synced 2025-05-02 20:03:01 +08:00

[v3] Add starlight website (#3917)

* init docs

* add few categories

* add more

* update home

* add blog

* update favicon

* fix few links and

* untouch

* untouch more

* add some icons

* add icons

* move ggetting started at the top and collapse the rest

* actually collapse

* format

* remove includes

* more format

* remove includes

* move assets

* add i18n

* fix i18n

* formatting

* order

* Prevent sidebar from making the page shake during load

* Prevent sidebar from making the page shake during load

* organize docs

* fix link

* expand a bit

* add credits page

* update all contributors file

* remove underlines

* add alternative

* use html

* lets get the first success build

* add latest entry

* remove example file

* fix examples

* more fixes

* fix grammar

* grammar

* remove dupes

* fix link

* grammar

* typo

* typo

* typo

* Logo update. Minor changes.

* update changelog

* update changelog

* rabbit is right

---------

Co-authored-by: Lea Anthony <lea.anthony@gmail.com>
This commit is contained in:
Stavros Kois 2024-12-08 03:09:13 +02:00 committed by GitHub
parent 2e4fce7c67
commit b6c8d9a90a
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
95 changed files with 15925 additions and 1 deletions

View File

@ -1,6 +1,7 @@
{
"files": [
"website/src/pages/credits.mdx"
"website/src/pages/credits.mdx",
"docs/src/assets/contributors.html"
],
"imageSize": 75,
"commit": false,

View File

@ -1,6 +1,7 @@
overrides:
- files:
- "**/*.md"
- "**/*.mdx"
options:
printWidth: 80
proseWrap: always

21
docs/.gitignore vendored Normal file
View File

@ -0,0 +1,21 @@
# build output
dist/
# generated types
.astro/
# dependencies
node_modules/
# logs
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*
# environment variables
.env
.env.production
# macOS-specific files
.DS_Store

4
docs/.vscode/extensions.json vendored Normal file
View File

@ -0,0 +1,4 @@
{
"recommendations": ["astro-build.astro-vscode"],
"unwantedRecommendations": []
}

11
docs/.vscode/launch.json vendored Normal file
View File

@ -0,0 +1,11 @@
{
"version": "0.2.0",
"configurations": [
{
"command": "./node_modules/.bin/astro dev",
"name": "Development server",
"request": "launch",
"type": "node-terminal"
}
]
}

60
docs/README.md Normal file
View File

@ -0,0 +1,60 @@
# Starlight Starter Kit: Basics
[![Built with Starlight](https://astro.badg.es/v2/built-with-starlight/tiny.svg)](https://starlight.astro.build)
```sh
npm create astro@latest -- --template starlight
```
[![Open in StackBlitz](https://developer.stackblitz.com/img/open_in_stackblitz.svg)](https://stackblitz.com/github/withastro/starlight/tree/main/examples/basics)
[![Open with CodeSandbox](https://assets.codesandbox.io/github/button-edit-lime.svg)](https://codesandbox.io/p/sandbox/github/withastro/starlight/tree/main/examples/basics)
[![Deploy to Netlify](https://www.netlify.com/img/deploy/button.svg)](https://app.netlify.com/start/deploy?repository=https://github.com/withastro/starlight&create_from_path=examples/basics)
[![Deploy with Vercel](https://vercel.com/button)](https://vercel.com/new/clone?repository-url=https%3A%2F%2Fgithub.com%2Fwithastro%2Fstarlight%2Ftree%2Fmain%2Fexamples%2Fbasics&project-name=my-starlight-docs&repository-name=my-starlight-docs)
> 🧑‍🚀 **Seasoned astronaut?** Delete this file. Have fun!
## 🚀 Project Structure
Inside of your Astro + Starlight project, you'll see the following folders and
files:
```sh
.
├── public/
├── src/
│ ├── assets/
│ ├── content/
│ │ ├── docs/
│ │ └── config.ts
│ └── env.d.ts
├── astro.config.mjs
├── package.json
└── tsconfig.json
```
Starlight looks for `.md` or `.mdx` files in the `src/content/docs/` directory.
Each file is exposed as a route based on its file name.
Images can be added to `src/assets/` and embedded in Markdown with a relative
link.
Static assets, like favicons, can be placed in the `public/` directory.
## 🧞 Commands
All commands are run from the root of the project, from a terminal:
| Command | Action |
| :------------------------ | :----------------------------------------------- |
| `npm install` | Installs dependencies |
| `npm run dev` | Starts local dev server at `localhost:4321` |
| `npm run build` | Build your production site to `./dist/` |
| `npm run preview` | Preview your build locally, before deploying |
| `npm run astro ...` | Run CLI commands like `astro add`, `astro check` |
| `npm run astro -- --help` | Get help using the Astro CLI |
## 👀 Want to learn more?
Check out [Starlights docs](https://starlight.astro.build/), read
[the Astro documentation](https://docs.astro.build), or jump into the
[Astro Discord server](https://astro.build/chat).

123
docs/astro.config.mjs Normal file
View File

@ -0,0 +1,123 @@
// @ts-check
import { defineConfig } from "astro/config";
import starlight from "@astrojs/starlight";
import sitemap from "@astrojs/sitemap";
import starlightLinksValidator from "starlight-links-validator";
import starlightImageZoom from "starlight-image-zoom";
import starlightBlog from "starlight-blog";
import { authors } from "./src/content/authors";
// https://astro.build/config
export default defineConfig({
// TODO: update this
site: "https://wails.io",
trailingSlash: "ignore",
compressHTML: true,
output: "static",
build: { format: "directory" },
devToolbar: { enabled: true },
integrations: [
sitemap(),
starlight({
title: "",
logo: {
dark: "./src/assets/wails-logo-horizontal-dark.svg",
light: "./src/assets/wails-logo-horizontal-light.svg",
},
favicon: "./public/favicon.svg",
description: "Build desktop applications using Go & Web Technologies.",
pagefind: true,
customCss: ["./src/stylesheets/extra.css"],
lastUpdated: true, // Note, this needs git clone with fetch depth 0 to work
pagination: true,
editLink: {
// TODO: update this
baseUrl: "https://github.com/wailsapp/wails/edit/v3-alpha/docs",
},
social: {
github: "https://github.com/wailsapp/wails",
discord: "https://discord.gg/JDdSxwjhGf",
"x.com": "https://x.com/wailsapp",
},
defaultLocale: "root",
locales: {
root: { label: "English", lang: "en", dir: "ltr" },
// Example of how a new language is added.
// After this, you create a directory named after the language inside content/docs/
// with the same structure as the root language
// eg content/docs/gr/changelog.md or content/docs/gr/api/application.mdx
// gr: { label: "Greek", lang: "el", dir: "ltr" },
},
plugins: [
// https://starlight-links-validator.vercel.app/configuration/
starlightLinksValidator({
exclude: [
// TODO: Fix these links in the blog/wails-v2-released file
// "/docs/reference/options#theme",
// "/docs/reference/options#customtheme",
// "/docs/guides/application-development#application-menu",
// "/docs/reference/runtime/dialog",
// "/docs/reference/options#windowistranslucent",
// "/docs/reference/options#windowistranslucent-1",
// "/docs/guides/windows-installer",
// "/docs/reference/runtime/intro",
// "/docs/guides/obfuscated",
// "/docs/howdoesitwork#calling-bound-go-methods",
],
}),
// https://starlight-image-zoom.vercel.app/configuration/
starlightImageZoom(),
// https://starlight-blog-docs.vercel.app/configuration
starlightBlog({
title: "Wails Blog",
authors: authors,
}),
],
sidebar: [
{ label: "Home", link: "/" },
{
label: "Getting Started",
autogenerate: { directory: "getting-started", collapsed: false },
},
{ label: "Feedback", link: "/getting-started/feedback" },
{
label: "Learn",
collapsed: true,
autogenerate: { directory: "learn", collapsed: true },
},
{
label: "Guides",
collapsed: true,
autogenerate: { directory: "guides", collapsed: true },
},
{
label: "What's New",
link: "/whats-new",
badge: { text: "New", variant: "tip" },
},
{
label: "API",
collapsed: true,
autogenerate: { directory: "api", collapsed: true },
},
{
label: "Development",
collapsed: true,
autogenerate: { directory: "development", collapsed: true },
},
{ label: "Status", link: "/status" },
{ label: "Changelog", link: "/changelog" },
{
label: "Sponsor",
link: "https://github.com/sponsors/leaanthony",
badge: { text: "❤️" },
},
{
label: "Credits",
link: "/credits",
badge: { text: "👑" },
},
],
}),
],
});

8383
docs/package-lock.json generated Normal file

File diff suppressed because it is too large Load Diff

22
docs/package.json Normal file
View File

@ -0,0 +1,22 @@
{
"name": "wails-docs",
"type": "module",
"version": "0.0.1",
"scripts": {
"dev": "astro dev",
"start": "astro dev",
"build": "astro check && astro build",
"preview": "astro preview",
"astro": "astro"
},
"dependencies": {
"@astrojs/check": "^0.9.4",
"@astrojs/starlight": "^0.29.2",
"astro": "^4.16.10",
"sharp": "^0.32.5",
"starlight-blog": "0.15.0",
"starlight-image-zoom": "0.9.0",
"starlight-links-validator": "0.13.2",
"typescript": "^5.7.2"
}
}

1
docs/public/favicon.svg Normal file
View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="100%" height="100%" version="1.1" viewBox="0 0 550 310" xml:space="preserve" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:2"><g><path d="M0.883,-0.081L0.121,0.081L0.256,-0.063L0.883,-0.081Z" transform="matrix(-166.599,4.57132,4.57132,166.599,147.403,167.648)" style="fill:url(#_Linear1);fill-rule:nonzero"/></g><g><path d="M0.878,-0.285L-0.073,0.71L-1.186,0.542L0.015,0.207L-0.846,0.077L0.355,-0.258L-0.505,-0.388L0.649,-0.71L0.878,-0.285Z" transform="matrix(-106.443,-16.0669,-16.0669,106.443,428.19,188.033)" style="fill:url(#_Linear2);fill-rule:nonzero"/></g><g><path d="M0.44,-0.04L0.265,-0.056L0.177,0.437L-0.311,-0.255L0.262,-0.437L0.568,-0.437L0.44,-0.04Z" transform="matrix(-114.484,-162.408,-162.408,114.484,333.291,285.804)" style="fill:url(#_Linear3);fill-rule:nonzero"/></g><g><path d="M0.622,-0.115L0.761,-0.115L0.806,-0.013L0.826,0.182L0.622,-0.115Z" transform="matrix(238.126,298.893,298.893,-238.126,113.516,-150.536)" style="fill:url(#_Linear4);fill-rule:nonzero"/></g><g><path d="M0.467,0.005L0.49,0.062L0.271,-0.062L0.467,0.005Z" transform="matrix(-369.529,-97.4118,-97.4118,369.529,582.38,94.027)" style="fill:url(#_Linear5);fill-rule:nonzero"/></g><g><path d="M0.2,0.001L0.219,-0.018L0.614,0.012L0.519,0.089L0.282,0.068L0.2,0.135L0.463,0.194L0.374,0.266L0.138,0.186L0.047,0.033L-0.131,-0.266L0.2,0.001Z" transform="matrix(-496.156,-53.9751,-53.9751,496.156,367.888,125.085)" style="fill:url(#_Linear6);fill-rule:nonzero"/></g><g><path d="M269.095,104.527L287.764,111.419L263.632,106.75L269.095,104.527Z" transform="matrix(0.436503,-1.22916,4.88651,1.73532,-368.043,253.619)" style="fill:#fff"/></g><defs><linearGradient id="_Linear1" x1="0" x2="1" y1="0" y2="0" gradientTransform="matrix(1,-3.46945e-18,3.46945e-18,1,0,-3.05761e-06)" gradientUnits="userSpaceOnUse"><stop offset="0" style="stop-color:#e33232;stop-opacity:1"/><stop offset="1" style="stop-color:#6b000d;stop-opacity:1"/></linearGradient><linearGradient id="_Linear2" x1="0" x2="1" y1="0" y2="0" gradientTransform="matrix(1,0,0,1,0,-2.75467e-06)" gradientUnits="userSpaceOnUse"><stop offset="0" style="stop-color:#e33232;stop-opacity:1"/><stop offset="1" style="stop-color:#6b000d;stop-opacity:1"/></linearGradient><linearGradient id="_Linear3" x1="0" x2="1" y1="0" y2="0" gradientTransform="matrix(1,-1.11022e-16,1.11022e-16,1,0,-2.61861e-06)" gradientUnits="userSpaceOnUse"><stop offset="0" style="stop-color:#e33232;stop-opacity:1"/><stop offset="1" style="stop-color:#6b000d;stop-opacity:1"/></linearGradient><linearGradient id="_Linear4" x1="0" x2="1" y1="0" y2="0" gradientTransform="matrix(-0.801899,-0.59746,0.59746,-0.801899,1.3495,0.447457)" gradientUnits="userSpaceOnUse"><stop offset="0" style="stop-color:#e33232;stop-opacity:1"/><stop offset="1" style="stop-color:#6b000d;stop-opacity:1"/></linearGradient><linearGradient id="_Linear5" x1="0" x2="1" y1="0" y2="0" gradientTransform="matrix(1,-2.77556e-17,2.77556e-17,1,0,-1.92826e-06)" gradientUnits="userSpaceOnUse"><stop offset="0" style="stop-color:#e33232;stop-opacity:1"/><stop offset="1" style="stop-color:#6b000d;stop-opacity:1"/></linearGradient><linearGradient id="_Linear6" x1="0" x2="1" y1="0" y2="0" gradientTransform="matrix(1,0,0,1,0,9.68429e-07)" gradientUnits="userSpaceOnUse"><stop offset="0" style="stop-color:#e33232;stop-opacity:1"/><stop offset="1" style="stop-color:#6b000d;stop-opacity:1"/></linearGradient></defs></svg>

After

Width:  |  Height:  |  Size: 3.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.6 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 235 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 76 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 37 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 37 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 31 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 177 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 269 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 29 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 36 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 43 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 36 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

View File

@ -0,0 +1,246 @@
<div class="container">
<!--GAMFC_DELIMITER-->
<table>
<tbody>
<tr>
<td align="center" valign="top" width="12.5%"><a href="https://github.com/leaanthony"><img src="https://avatars.githubusercontent.com/u/1943904?v=4?s=75" width="75px;" alt="Lea Anthony"/><br /><sub><b>Lea Anthony</b></sub></a><br /><a href="https://github.com/wailsapp/wails/commits?author=leaanthony" title="Code">💻</a> <a href="#ideas-leaanthony" title="Ideas, Planning, & Feedback">🤔</a> <a href="#design-leaanthony" title="Design">🎨</a> <a href="#content-leaanthony" title="Content">🖋</a> <a href="#example-leaanthony" title="Examples">💡</a> <a href="#mentoring-leaanthony" title="Mentoring">🧑‍🏫</a> <a href="#projectManagement-leaanthony" title="Project Management">📆</a> <a href="#tool-leaanthony" title="Tools">🔧</a> <a href="https://github.com/wailsapp/wails/yssues?q=author%3Aleaanthony" title="Bug reports">🐛</a> <a href="#blog-leaanthony" title="Blogposts">📝</a> <a href="#maintenance-leaanthony" title="Maintenance">🚧</a> <a href="#platform-leaanthony" title="Packaging/porting to new platform">📦</a> <a href="https://github.com/wailsapp/wails/pulls?q=is%3Apr+reviewed-by%3Aleaanthony" title="Reviewed Pull Requests">👀</a> <a href="#question-leaanthony" title="Answering Questions">💬</a> <a href="#research-leaanthony" title="Research">🔬</a> <a href="https://github.com/wailsapp/wails/commits?author=leaanthony" title="Tests">⚠️</a> <a href="#tutorial-leaanthony" title="Tutorials"></a> <a href="#talk-leaanthony" title="Talks">📢</a> <a href="https://github.com/wailsapp/wails/pulls?q=is%3Apr+reviewed-by%3Aleaanthony" title="Reviewed Pull Requests">👀</a> <a href="https://github.com/wailsapp/wails/commits?author=leaanthony" title="Documentation">📖</a></td>
<td align="center" valign="top" width="12.5%"><a href="https://github.com/stffabi"><img src="https://avatars.githubusercontent.com/u/9464631?v=4?s=75" width="75px;" alt="stffabi"/><br /><sub><b>stffabi</b></sub></a><br /><a href="https://github.com/wailsapp/wails/commits?author=stffabi" title="Code">💻</a> <a href="#ideas-stffabi" title="Ideas, Planning, & Feedback">🤔</a> <a href="#design-stffabi" title="Design">🎨</a> <a href="https://github.com/wailsapp/wails/issues?q=author%3Astffabi" title="Bug reports">🐛</a> <a href="#maintenance-stffabi" title="Maintenance">🚧</a> <a href="#platform-stffabi" title="Packaging/porting to new platform">📦</a> <a href="https://github.com/wailsapp/wails/pulls?q=is%3Apr+reviewed-by%3Astffabi" title="Reviewed Pull Requests">👀</a> <a href="#question-stffabi" title="Answering Questions">💬</a> <a href="#research-stffabi" title="Research">🔬</a> <a href="https://github.com/wailsapp/wails/pulls?q=is%3Apr+reviewed-by%3Astffabi" title="Reviewed Pull Requests">👀</a> <a href="https://github.com/wailsapp/wails/commits?author=stffabi" title="Documentation">📖</a> <a href="https://github.com/wailsapp/wails/commits?author=stffabi" title="Tests">⚠️</a></td>
<td align="center" valign="top" width="12.5%"><a href="https://github.com/tmclane"><img src="https://avatars.githubusercontent.com/u/511975?v=4?s=75" width="75px;" alt="Travis McLane"/><br /><sub><b>Travis McLane</b></sub></a><br /><a href="https://github.com/wailsapp/wails/commits?author=tmclane" title="Code">💻</a> <a href="#research-tmclane" title="Research">🔬</a> <a href="#platform-tmclane" title="Packaging/porting to new platform">📦</a> <a href="#ideas-tmclane" title="Ideas, Planning, & Feedback">🤔</a> <a href="https://github.com/wailsapp/wails/issues?q=author%3Atmclane" title="Bug reports">🐛</a> <a href="https://github.com/wailsapp/wails/pulls?q=is%3Apr+reviewed-by%3Atmclane" title="Reviewed Pull Requests">👀</a> <a href="https://github.com/wailsapp/wails/commits?author=tmclane" title="Tests">⚠️</a> <a href="#question-tmclane" title="Answering Questions">💬</a> <a href="https://github.com/wailsapp/wails/commits?author=tmclane" title="Documentation">📖</a></td>
<td align="center" valign="top" width="12.5%"><a href="https://misitebao.com/"><img src="https://avatars.githubusercontent.com/u/28185258?v=4?s=75" width="75px;" alt="Misite Bao"/><br /><sub><b>Misite Bao</b></sub></a><br /><a href="https://github.com/wailsapp/wails/commits?author=misitebao" title="Documentation">📖</a> <a href="#translation-misitebao" title="Translation">🌍</a> <a href="#research-misitebao" title="Research">🔬</a> <a href="#maintenance-misitebao" title="Maintenance">🚧</a></td>
<td align="center" valign="top" width="12.5%"><a href="https://github.com/bh90210"><img src="https://avatars.githubusercontent.com/u/22690219?v=4?s=75" width="75px;" alt="Byron Chris"/><br /><sub><b>Byron Chris</b></sub></a><br /><a href="https://github.com/wailsapp/wails/commits?author=bh90210" title="Code">💻</a> <a href="#research-bh90210" title="Research">🔬</a> <a href="#maintenance-bh90210" title="Maintenance">🚧</a> <a href="https://github.com/wailsapp/wails/issues?q=author%3Abh90210" title="Bug reports">🐛</a> <a href="https://github.com/wailsapp/wails/pulls?q=is%3Apr+reviewed-by%3Abh90210" title="Reviewed Pull Requests">👀</a> <a href="https://github.com/wailsapp/wails/commits?author=bh90210" title="Tests">⚠️</a> <a href="#question-bh90210" title="Answering Questions">💬</a> <a href="#ideas-bh90210" title="Ideas, Planning, & Feedback">🤔</a> <a href="#design-bh90210" title="Design">🎨</a> <a href="#platform-bh90210" title="Packaging/porting to new platform">📦</a> <a href="#infra-bh90210" title="Infrastructure (Hosting, Build-Tools, etc)">🚇</a></td>
<td align="center" valign="top" width="12.5%"><a href="https://github.com/konez2k"><img src="https://avatars.githubusercontent.com/u/32417933?v=4?s=75" width="75px;" alt="konez2k"/><br /><sub><b>konez2k</b></sub></a><br /><a href="https://github.com/wailsapp/wails/commits?author=konez2k" title="Code">💻</a> <a href="#platform-konez2k" title="Packaging/porting to new platform">📦</a> <a href="#ideas-konez2k" title="Ideas, Planning, & Feedback">🤔</a></td>
<td align="center" valign="top" width="12.5%"><a href="https://github.com/dedo1911"><img src="https://avatars.githubusercontent.com/u/1364496?v=4?s=75" width="75px;" alt="Dario Emerson"/><br /><sub><b>Dario Emerson</b></sub></a><br /><a href="https://github.com/wailsapp/wails/commits?author=dedo1911" title="Code">💻</a> <a href="https://github.com/wailsapp/wails/issues?q=author%3Adedo1911" title="Bug reports">🐛</a> <a href="#ideas-dedo1911" title="Ideas, Planning, & Feedback">🤔</a> <a href="https://github.com/wailsapp/wails/commits?author=dedo1911" title="Tests">⚠️</a></td>
<td align="center" valign="top" width="12.5%"><a href="https://ianmjones.com/"><img src="https://avatars.githubusercontent.com/u/4710?v=4?s=75" width="75px;" alt="Ian M. Jones"/><br /><sub><b>Ian M. Jones</b></sub></a><br /><a href="https://github.com/wailsapp/wails/commits?author=ianmjones" title="Code">💻</a> <a href="https://github.com/wailsapp/wails/issues?q=author%3Aianmjones" title="Bug reports">🐛</a> <a href="#ideas-ianmjones" title="Ideas, Planning, & Feedback">🤔</a> <a href="https://github.com/wailsapp/wails/commits?author=ianmjones" title="Tests">⚠️</a> <a href="https://github.com/wailsapp/wails/pulls?q=is%3Apr+reviewed-by%3Aianmjones" title="Reviewed Pull Requests">👀</a> <a href="#platform-ianmjones" title="Packaging/porting to new platform">📦</a></td>
</tr>
<tr>
<td align="center" valign="top" width="12.5%"><a href="https://github.com/marktohark"><img src="https://avatars.githubusercontent.com/u/19359934?v=4?s=75" width="75px;" alt="marktohark"/><br /><sub><b>marktohark</b></sub></a><br /><a href="https://github.com/wailsapp/wails/commits?author=marktohark" title="Code">💻</a></td>
<td align="center" valign="top" width="12.5%"><a href="https://github.com/rh12503"><img src="https://avatars.githubusercontent.com/u/48951973?v=4?s=75" width="75px;" alt="Ryan H"/><br /><sub><b>Ryan H</b></sub></a><br /><a href="https://github.com/wailsapp/wails/commits?author=rh12503" title="Code">💻</a></td>
<td align="center" valign="top" width="12.5%"><a href="https://codybentley.dev/"><img src="https://avatars.githubusercontent.com/u/6968902?v=4?s=75" width="75px;" alt="Cody Bentley"/><br /><sub><b>Cody Bentley</b></sub></a><br /><a href="https://github.com/wailsapp/wails/commits?author=codydbentley" title="Code">💻</a> <a href="#platform-codydbentley" title="Packaging/porting to new platform">📦</a> <a href="#ideas-codydbentley" title="Ideas, Planning, & Feedback">🤔</a> <a href="#financial-codydbentley" title="Financial">💵</a></td>
<td align="center" valign="top" width="12.5%"><a href="https://github.com/napalu"><img src="https://avatars.githubusercontent.com/u/6690378?v=4?s=75" width="75px;" alt="Florent"/><br /><sub><b>Florent</b></sub></a><br /><a href="https://github.com/wailsapp/wails/commits?author=napalu" title="Code">💻</a> <a href="https://github.com/wailsapp/wails/issues?q=author%3Anapalu" title="Bug reports">🐛</a></td>
<td align="center" valign="top" width="12.5%"><a href="https://github.com/akhudek"><img src="https://avatars.githubusercontent.com/u/147633?v=4?s=75" width="75px;" alt="Alexander Hudek"/><br /><sub><b>Alexander Hudek</b></sub></a><br /><a href="https://github.com/wailsapp/wails/commits?author=akhudek" title="Code">💻</a> <a href="#financial-akhudek" title="Financial">💵</a></td>
<td align="center" valign="top" width="12.5%"><a href="https://twitter.com/timkippdev"><img src="https://avatars.githubusercontent.com/u/37030721?v=4?s=75" width="75px;" alt="Tim Kipp"/><br /><sub><b>Tim Kipp</b></sub></a><br /><a href="https://github.com/wailsapp/wails/commits?author=timkippdev" title="Code">💻</a></td>
<td align="center" valign="top" width="12.5%"><a href="https://github.com/gelleson"><img src="https://avatars.githubusercontent.com/u/44272887?v=4?s=75" width="75px;" alt="Altynbek Kaliakbarov"/><br /><sub><b>Altynbek Kaliakbarov</b></sub></a><br /><a href="https://github.com/wailsapp/wails/commits?author=gelleson" title="Code">💻</a></td>
<td align="center" valign="top" width="12.5%"><a href="https://github.com/Chronophylos"><img src="https://avatars.githubusercontent.com/u/14890588?v=4?s=75" width="75px;" alt="Nikolai Zimmermann"/><br /><sub><b>Nikolai Zimmermann</b></sub></a><br /><a href="https://github.com/wailsapp/wails/commits?author=Chronophylos" title="Code">💻</a></td>
</tr>
<tr>
<td align="center" valign="top" width="12.5%"><a href="https://github.com/k-muchmore"><img src="https://avatars.githubusercontent.com/u/16393095?v=4?s=75" width="75px;" alt="k-muchmore"/><br /><sub><b>k-muchmore</b></sub></a><br /><a href="https://github.com/wailsapp/wails/commits?author=k-muchmore" title="Code">💻</a></td>
<td align="center" valign="top" width="12.5%"><a href="https://peakd.com/@snider"><img src="https://avatars.githubusercontent.com/u/631881?v=4?s=75" width="75px;" alt="Snider"/><br /><sub><b>Snider</b></sub></a><br /><a href="https://github.com/wailsapp/wails/commits?author=Snider" title="Code">💻</a> <a href="#ideas-Snider" title="Ideas, Planning, & Feedback">🤔</a> <a href="https://github.com/wailsapp/wails/commits?author=Snider" title="Documentation">📖</a> <a href="#financial-Snider" title="Financial">💵</a></td>
<td align="center" valign="top" width="12.5%"><a href="https://github.com/albert-sun"><img src="https://avatars.githubusercontent.com/u/54585592?v=4?s=75" width="75px;" alt="Albert Sun"/><br /><sub><b>Albert Sun</b></sub></a><br /><a href="https://github.com/wailsapp/wails/commits?author=albert-sun" title="Code">💻</a> <a href="https://github.com/wailsapp/wails/commits?author=albert-sun" title="Tests">⚠️</a></td>
<td align="center" valign="top" width="12.5%"><a href="https://github.com/adalessa"><img src="https://avatars.githubusercontent.com/u/7914601?v=4?s=75" width="75px;" alt="Ariel"/><br /><sub><b>Ariel</b></sub></a><br /><a href="https://github.com/wailsapp/wails/commits?author=adalessa" title="Code">💻</a> <a href="https://github.com/wailsapp/wails/issues?q=author%3Aadalessa" title="Bug reports">🐛</a></td>
<td align="center" valign="top" width="12.5%"><a href="https://triplebits.com/"><img src="https://avatars.githubusercontent.com/u/4365245?v=4?s=75" width="75px;" alt="Ilgıt Yıldırım"/><br /><sub><b>Ilgıt Yıldırım</b></sub></a><br /><a href="https://github.com/wailsapp/wails/commits?author=ilgityildirim" title="Code">💻</a> <a href="https://github.com/wailsapp/wails/issues?q=author%3Ailgityildirim" title="Bug reports">🐛</a> <a href="#financial-ilgityildirim" title="Financial">💵</a></td>
<td align="center" valign="top" width="12.5%"><a href="https://github.com/Vaelatern"><img src="https://avatars.githubusercontent.com/u/7906072?v=4?s=75" width="75px;" alt="Toyam Cox"/><br /><sub><b>Toyam Cox</b></sub></a><br /><a href="https://github.com/wailsapp/wails/commits?author=Vaelatern" title="Code">💻</a> <a href="#platform-Vaelatern" title="Packaging/porting to new platform">📦</a> <a href="https://github.com/wailsapp/wails/issues?q=author%3AVaelatern" title="Bug reports">🐛</a></td>
<td align="center" valign="top" width="12.5%"><a href="https://github.com/hi019"><img src="https://avatars.githubusercontent.com/u/65871571?v=4?s=75" width="75px;" alt="hi019"/><br /><sub><b>hi019</b></sub></a><br /><a href="https://github.com/wailsapp/wails/commits?author=hi019" title="Code">💻</a> <a href="https://github.com/wailsapp/wails/issues?q=author%3Ahi019" title="Bug reports">🐛</a></td>
<td align="center" valign="top" width="12.5%"><a href="https://artooro.com/"><img src="https://avatars.githubusercontent.com/u/393395?v=4?s=75" width="75px;" alt="Arthur Wiebe"/><br /><sub><b>Arthur Wiebe</b></sub></a><br /><a href="https://github.com/wailsapp/wails/commits?author=artooro" title="Code">💻</a> <a href="https://github.com/wailsapp/wails/issues?q=author%3Aartooro" title="Bug reports">🐛</a></td>
</tr>
<tr>
<td align="center" valign="top" width="12.5%"><a href="https://sectcs.com/"><img src="https://avatars.githubusercontent.com/u/16898783?v=4?s=75" width="75px;" alt="Balakrishna Prasad Ganne"/><br /><sub><b>Balakrishna Prasad Ganne</b></sub></a><br /><a href="https://github.com/wailsapp/wails/commits?author=aayush420" title="Code">💻</a></td>
<td align="center" valign="top" width="12.5%"><a href="https://github.com/BillBuilt"><img src="https://avatars.githubusercontent.com/u/28831382?v=4?s=75" width="75px;" alt="BillBuilt"/><br /><sub><b>BillBuilt</b></sub></a><br /><a href="https://github.com/wailsapp/wails/commits?author=BillBuilt" title="Code">💻</a> <a href="#platform-BillBuilt" title="Packaging/porting to new platform">📦</a> <a href="#ideas-BillBuilt" title="Ideas, Planning, & Feedback">🤔</a> <a href="#question-BillBuilt" title="Answering Questions">💬</a> <a href="#financial-BillBuilt" title="Financial">💵</a></td>
<td align="center" valign="top" width="12.5%"><a href="https://github.com/Juneezee"><img src="https://avatars.githubusercontent.com/u/20135478?v=4?s=75" width="75px;" alt="Eng Zer Jun"/><br /><sub><b>Eng Zer Jun</b></sub></a><br /><a href="#maintenance-Juneezee" title="Maintenance">🚧</a> <a href="https://github.com/wailsapp/wails/commits?author=Juneezee" title="Code">💻</a></td>
<td align="center" valign="top" width="12.5%"><a href="https://lgiki.net/"><img src="https://avatars.githubusercontent.com/u/20807713?v=4?s=75" width="75px;" alt="LGiki"/><br /><sub><b>LGiki</b></sub></a><br /><a href="https://github.com/wailsapp/wails/commits?author=LGiki" title="Documentation">📖</a></td>
<td align="center" valign="top" width="12.5%"><a href="https://github.com/lontten"><img src="https://avatars.githubusercontent.com/u/30745595?v=4?s=75" width="75px;" alt="Lontten"/><br /><sub><b>Lontten</b></sub></a><br /><a href="https://github.com/wailsapp/wails/commits?author=lontten" title="Documentation">📖</a></td>
<td align="center" valign="top" width="12.5%"><a href="https://github.com/phoenix147"><img src="https://avatars.githubusercontent.com/u/809358?v=4?s=75" width="75px;" alt="Lukas Crepaz"/><br /><sub><b>Lukas Crepaz</b></sub></a><br /><a href="https://github.com/wailsapp/wails/commits?author=phoenix147" title="Code">💻</a> <a href="https://github.com/wailsapp/wails/issues?q=author%3Aphoenix147" title="Bug reports">🐛</a></td>
<td align="center" valign="top" width="12.5%"><a href="https://utf9k.net/"><img src="https://avatars.githubusercontent.com/u/14816406?v=4?s=75" width="75px;" alt="Marcus Crane"/><br /><sub><b>Marcus Crane</b></sub></a><br /><a href="https://github.com/wailsapp/wails/issues?q=author%3Amarcus-crane" title="Bug reports">🐛</a> <a href="https://github.com/wailsapp/wails/commits?author=marcus-crane" title="Documentation">📖</a> <a href="#financial-marcus-crane" title="Financial">💵</a></td>
<td align="center" valign="top" width="12.5%"><a href="https://qaisjp.com/"><img src="https://avatars.githubusercontent.com/u/923242?v=4?s=75" width="75px;" alt="Qais Patankar"/><br /><sub><b>Qais Patankar</b></sub></a><br /><a href="https://github.com/wailsapp/wails/commits?author=qaisjp" title="Documentation">📖</a></td>
</tr>
<tr>
<td align="center" valign="top" width="12.5%"><a href="https://wakefulcloud.dev/"><img src="https://avatars.githubusercontent.com/u/38930607?v=4?s=75" width="75px;" alt="Wakeful-Cloud"/><br /><sub><b>Wakeful-Cloud</b></sub></a><br /><a href="https://github.com/wailsapp/wails/commits?author=Wakeful-Cloud" title="Code">💻</a> <a href="https://github.com/wailsapp/wails/issues?q=author%3AWakeful-Cloud" title="Bug reports">🐛</a></td>
<td align="center" valign="top" width="12.5%"><a href="https://github.com/Lyimmi"><img src="https://avatars.githubusercontent.com/u/8627125?v=4?s=75" width="75px;" alt="Zámbó, Levente"/><br /><sub><b>Zámbó, Levente</b></sub></a><br /><a href="https://github.com/wailsapp/wails/commits?author=Lyimmi" title="Code">💻</a> <a href="#platform-Lyimmi" title="Packaging/porting to new platform">📦</a> <a href="https://github.com/wailsapp/wails/issues?q=author%3ALyimmi" title="Bug reports">🐛</a> <a href="https://github.com/wailsapp/wails/commits?author=Lyimmi" title="Tests">⚠️</a></td>
<td align="center" valign="top" width="12.5%"><a href="https://github.com/Ironpark"><img src="https://avatars.githubusercontent.com/u/4973597?v=4?s=75" width="75px;" alt="Ironpark"/><br /><sub><b>Ironpark</b></sub></a><br /><a href="https://github.com/wailsapp/wails/commits?author=Ironpark" title="Code">💻</a> <a href="#ideas-Ironpark" title="Ideas, Planning, & Feedback">🤔</a></td>
<td align="center" valign="top" width="12.5%"><a href="https://github.com/mondy"><img src="https://avatars.githubusercontent.com/u/3961824?v=4?s=75" width="75px;" alt="mondy"/><br /><sub><b>mondy</b></sub></a><br /><a href="https://github.com/wailsapp/wails/commits?author=mondy" title="Code">💻</a> <a href="https://github.com/wailsapp/wails/commits?author=mondy" title="Documentation">📖</a></td>
<td align="center" valign="top" width="12.5%"><a href="https://ryben.dev/"><img src="https://avatars.githubusercontent.com/u/6241454?v=4?s=75" width="75px;" alt="Benjamin Ryan"/><br /><sub><b>Benjamin Ryan</b></sub></a><br /><a href="https://github.com/wailsapp/wails/issues?q=author%3Aredraskal" title="Bug reports">🐛</a></td>
<td align="center" valign="top" width="12.5%"><a href="https://github.com/fallendusk"><img src="https://avatars.githubusercontent.com/u/565631?v=4?s=75" width="75px;" alt="fallendusk"/><br /><sub><b>fallendusk</b></sub></a><br /><a href="#platform-fallendusk" title="Packaging/porting to new platform">📦</a> <a href="https://github.com/wailsapp/wails/commits?author=fallendusk" title="Code">💻</a></td>
<td align="center" valign="top" width="12.5%"><a href="https://twitter.com/matryer"><img src="https://avatars.githubusercontent.com/u/101659?v=4?s=75" width="75px;" alt="Mat Ryer"/><br /><sub><b>Mat Ryer</b></sub></a><br /><a href="https://github.com/wailsapp/wails/commits?author=matryer" title="Code">💻</a> <a href="#ideas-matryer" title="Ideas, Planning, & Feedback">🤔</a> <a href="https://github.com/wailsapp/wails/issues?q=author%3Amatryer" title="Bug reports">🐛</a></td>
<td align="center" valign="top" width="12.5%"><a href="https://github.com/abtin"><img src="https://avatars.githubusercontent.com/u/441372?v=4?s=75" width="75px;" alt="Abtin"/><br /><sub><b>Abtin</b></sub></a><br /><a href="https://github.com/wailsapp/wails/commits?author=abtin" title="Code">💻</a> <a href="https://github.com/wailsapp/wails/issues?q=author%3Aabtin" title="Bug reports">🐛</a></td>
</tr>
<tr>
<td align="center" valign="top" width="12.5%"><a href="https://github.com/lanzafame"><img src="https://avatars.githubusercontent.com/u/5924712?v=4?s=75" width="75px;" alt="Adrian Lanzafame"/><br /><sub><b>Adrian Lanzafame</b></sub></a><br /><a href="#platform-lanzafame" title="Packaging/porting to new platform">📦</a> <a href="https://github.com/wailsapp/wails/commits?author=lanzafame" title="Code">💻</a></td>
<td align="center" valign="top" width="12.5%"><a href="https://github.com/polikow"><img src="https://avatars.githubusercontent.com/u/58259700?v=4?s=75" width="75px;" alt="Aleksey Polyakov"/><br /><sub><b>Aleksey Polyakov</b></sub></a><br /><a href="https://github.com/wailsapp/wails/issues?q=author%3Apolikow" title="Bug reports">🐛</a> <a href="https://github.com/wailsapp/wails/commits?author=polikow" title="Code">💻</a></td>
<td align="center" valign="top" width="12.5%"><a href="https://github.com/alexmat"><img src="https://avatars.githubusercontent.com/u/745421?v=4?s=75" width="75px;" alt="Alexander Matviychuk"/><br /><sub><b>Alexander Matviychuk</b></sub></a><br /><a href="https://github.com/wailsapp/wails/commits?author=alexmat" title="Code">💻</a> <a href="#platform-alexmat" title="Packaging/porting to new platform">📦</a></td>
<td align="center" valign="top" width="12.5%"><a href="https://github.com/AlienRecall"><img src="https://avatars.githubusercontent.com/u/68950287?v=4?s=75" width="75px;" alt="AlienRecall"/><br /><sub><b>AlienRecall</b></sub></a><br /><a href="https://github.com/wailsapp/wails/commits?author=AlienRecall" title="Code">💻</a> <a href="#platform-AlienRecall" title="Packaging/porting to new platform">📦</a></td>
<td align="center" valign="top" width="12.5%"><a href="https://blog.checkyo.tech/"><img src="https://avatars.githubusercontent.com/u/17457975?v=4?s=75" width="75px;" alt="Aman"/><br /><sub><b>Aman</b></sub></a><br /><a href="https://github.com/wailsapp/wails/commits?author=achhabra2" title="Documentation">📖</a></td>
<td align="center" valign="top" width="12.5%"><a href="https://github.com/amaury-tobias"><img src="https://avatars.githubusercontent.com/u/37311888?v=4?s=75" width="75px;" alt="Amaury Tobias Quiroz"/><br /><sub><b>Amaury Tobias Quiroz</b></sub></a><br /><a href="https://github.com/wailsapp/wails/commits?author=amaury-tobias" title="Code">💻</a> <a href="https://github.com/wailsapp/wails/issues?q=author%3Aamaury-tobias" title="Bug reports">🐛</a></td>
<td align="center" valign="top" width="12.5%"><a href="http://blog.nms.de/"><img src="https://avatars.githubusercontent.com/u/51517?v=4?s=75" width="75px;" alt="Andreas Wenk"/><br /><sub><b>Andreas Wenk</b></sub></a><br /><a href="https://github.com/wailsapp/wails/commits?author=andywenk" title="Documentation">📖</a></td>
<td align="center" valign="top" width="12.5%"><a href="https://github.com/stankovic98"><img src="https://avatars.githubusercontent.com/u/29852655?v=4?s=75" width="75px;" alt="Antonio Stanković"/><br /><sub><b>Antonio Stanković</b></sub></a><br /><a href="https://github.com/wailsapp/wails/commits?author=stankovic98" title="Code">💻</a> <a href="#platform-stankovic98" title="Packaging/porting to new platform">📦</a></td>
</tr>
<tr>
<td align="center" valign="top" width="12.5%"><a href="https://github.com/antimatter96"><img src="https://avatars.githubusercontent.com/u/12068176?v=4?s=75" width="75px;" alt="Arpit Jain"/><br /><sub><b>Arpit Jain</b></sub></a><br /><a href="https://github.com/wailsapp/wails/commits?author=antimatter96" title="Documentation">📖</a></td>
<td align="center" valign="top" width="12.5%"><a href="https://github.com/aschey"><img src="https://avatars.githubusercontent.com/u/5882266?v=4?s=75" width="75px;" alt="Austin Schey"/><br /><sub><b>Austin Schey</b></sub></a><br /><a href="https://github.com/wailsapp/wails/commits?author=aschey" title="Code">💻</a> <a href="https://github.com/wailsapp/wails/issues?q=author%3Aaschey" title="Bug reports">🐛</a></td>
<td align="center" valign="top" width="12.5%"><a href="https://github.com/benjamin-thomas"><img src="https://avatars.githubusercontent.com/u/1557738?v=4?s=75" width="75px;" alt="Benjamin Thomas"/><br /><sub><b>Benjamin Thomas</b></sub></a><br /><a href="https://github.com/wailsapp/wails/commits?author=benjamin-thomas" title="Code">💻</a> <a href="#platform-benjamin-thomas" title="Packaging/porting to new platform">📦</a> <a href="#ideas-benjamin-thomas" title="Ideas, Planning, & Feedback">🤔</a></td>
<td align="center" valign="top" width="12.5%"><a href="https://www.bertramtruong.com/"><img src="https://avatars.githubusercontent.com/u/1100843?v=4?s=75" width="75px;" alt="Bertram Truong"/><br /><sub><b>Bertram Truong</b></sub></a><br /><a href="https://github.com/wailsapp/wails/commits?author=bt" title="Code">💻</a> <a href="https://github.com/wailsapp/wails/issues?q=author%3Abt" title="Bug reports">🐛</a></td>
<td align="center" valign="top" width="12.5%"><a href="http://techwizworld.net/"><img src="https://avatars.githubusercontent.com/u/175873?v=4?s=75" width="75px;" alt="Blake Bourque"/><br /><sub><b>Blake Bourque</b></sub></a><br /><a href="https://github.com/wailsapp/wails/commits?author=TechplexEngineer" title="Documentation">📖</a></td>
<td align="center" valign="top" width="12.5%"><a href="http://vk.com/raitonoberu"><img src="https://avatars.githubusercontent.com/u/64320078?v=4?s=75" width="75px;" alt="Denis"/><br /><sub><b>Denis</b></sub></a><br /><a href="https://github.com/wailsapp/wails/commits?author=raitonoberu" title="Documentation">📖</a></td>
<td align="center" valign="top" width="12.5%"><a href="https://github.com/diogox"><img src="https://avatars.githubusercontent.com/u/13244408?v=4?s=75" width="75px;" alt="diogox"/><br /><sub><b>diogox</b></sub></a><br /><a href="https://github.com/wailsapp/wails/commits?author=diogox" title="Code">💻</a> <a href="#platform-diogox" title="Packaging/porting to new platform">📦</a></td>
<td align="center" valign="top" width="12.5%"><a href="https://github.com/kyoto44"><img src="https://avatars.githubusercontent.com/u/17720761?v=4?s=75" width="75px;" alt="Dmitry Gomzyakov"/><br /><sub><b>Dmitry Gomzyakov</b></sub></a><br /><a href="https://github.com/wailsapp/wails/commits?author=kyoto44" title="Code">💻</a> <a href="#platform-kyoto44" title="Packaging/porting to new platform">📦</a></td>
</tr>
<tr>
<td align="center" valign="top" width="12.5%"><a href="https://github.com/edwardbrowncross"><img src="https://avatars.githubusercontent.com/u/35063432?v=4?s=75" width="75px;" alt="Edward Browncross"/><br /><sub><b>Edward Browncross</b></sub></a><br /><a href="https://github.com/wailsapp/wails/commits?author=edwardbrowncross" title="Code">💻</a></td>
<td align="center" valign="top" width="12.5%"><a href="http://pr0gramming.ca/"><img src="https://avatars.githubusercontent.com/u/14944216?v=4?s=75" width="75px;" alt="Elie Grenon"/><br /><sub><b>Elie Grenon</b></sub></a><br /><a href="https://github.com/wailsapp/wails/commits?author=elie-g" title="Code">💻</a></td>
<td align="center" valign="top" width="12.5%"><a href="https://github.com/fdidron"><img src="https://avatars.githubusercontent.com/u/1848786?v=4?s=75" width="75px;" alt="Florian Didron"/><br /><sub><b>Florian Didron</b></sub></a><br /><a href="https://github.com/wailsapp/wails/commits?author=fdidron" title="Code">💻</a> <a href="https://github.com/wailsapp/wails/issues?q=author%3Afdidron" title="Bug reports">🐛</a> <a href="#ideas-fdidron" title="Ideas, Planning, & Feedback">🤔</a> <a href="https://github.com/wailsapp/wails/commits?author=fdidron" title="Tests">⚠️</a> <a href="https://github.com/wailsapp/wails/pulls?q=is%3Apr+reviewed-by%3Afdidron" title="Reviewed Pull Requests">👀</a> <a href="#platform-fdidron" title="Packaging/porting to new platform">📦</a></td>
<td align="center" valign="top" width="12.5%"><a href="https://github.com/GargantuaX"><img src="https://avatars.githubusercontent.com/u/14013111?v=4?s=75" width="75px;" alt="GargantuaX"/><br /><sub><b>GargantuaX</b></sub></a><br /><a href="#financial-GargantuaX" title="Financial">💵</a></td>
<td align="center" valign="top" width="12.5%"><a href="https://bednya.ga/"><img src="https://avatars.githubusercontent.com/u/12101721?v=4?s=75" width="75px;" alt="Igor Minin"/><br /><sub><b>Igor Minin</b></sub></a><br /><a href="https://github.com/wailsapp/wails/commits?author=Igogrek" title="Code">💻</a> <a href="https://github.com/wailsapp/wails/issues?q=author%3AIgogrek" title="Bug reports">🐛</a></td>
<td align="center" valign="top" width="12.5%"><a href="https://www.jae-sung.com/"><img src="https://avatars.githubusercontent.com/u/39658806?v=4?s=75" width="75px;" alt="Jae-Sung Lee"/><br /><sub><b>Jae-Sung Lee</b></sub></a><br /><a href="https://github.com/wailsapp/wails/commits?author=jaesung9507" title="Code">💻</a> <a href="#ideas-jaesung9507" title="Ideas, Planning, & Feedback">🤔</a></td>
<td align="center" valign="top" width="12.5%"><a href="https://github.com/Jarek-SRT"><img src="https://avatars.githubusercontent.com/u/3391365?v=4?s=75" width="75px;" alt="Jarek"/><br /><sub><b>Jarek</b></sub></a><br /><a href="https://github.com/wailsapp/wails/commits?author=Jarek-SRT" title="Code">💻</a> <a href="#platform-Jarek-SRT" title="Packaging/porting to new platform">📦</a></td>
<td align="center" valign="top" width="12.5%"><a href="https://github.com/Junkher"><img src="https://avatars.githubusercontent.com/u/85776620?v=4?s=75" width="75px;" alt="Junker"/><br /><sub><b>Junker</b></sub></a><br /><a href="https://github.com/wailsapp/wails/commits?author=Junkher" title="Documentation">📖</a></td>
</tr>
<tr>
<td align="center" valign="top" width="12.5%"><a href="https://github.com/kraney"><img src="https://avatars.githubusercontent.com/u/5760081?v=4?s=75" width="75px;" alt="Kris Raney"/><br /><sub><b>Kris Raney</b></sub></a><br /><a href="https://github.com/wailsapp/wails/commits?author=kraney" title="Code">💻</a> <a href="https://github.com/wailsapp/wails/issues?q=author%3Akraney" title="Bug reports">🐛</a></td>
<td align="center" valign="top" width="12.5%"><a href="https://github.com/LukenSkyne"><img src="https://avatars.githubusercontent.com/u/29918069?v=4?s=75" width="75px;" alt="Luken"/><br /><sub><b>Luken</b></sub></a><br /><a href="https://github.com/wailsapp/wails/commits?author=LukenSkyne" title="Documentation">📖</a></td>
<td align="center" valign="top" width="12.5%"><a href="https://markstenglein.com/"><img src="https://avatars.githubusercontent.com/u/9255772?v=4?s=75" width="75px;" alt="Mark Stenglein"/><br /><sub><b>Mark Stenglein</b></sub></a><br /><a href="https://github.com/wailsapp/wails/commits?author=ocelotsloth" title="Code">💻</a> <a href="https://github.com/wailsapp/wails/issues?q=author%3Aocelotsloth" title="Bug reports">🐛</a></td>
<td align="center" valign="top" width="12.5%"><a href="https://github.com/buddyabaddon"><img src="https://avatars.githubusercontent.com/u/33861511?v=4?s=75" width="75px;" alt="buddyabaddon"/><br /><sub><b>buddyabaddon</b></sub></a><br /><a href="https://github.com/wailsapp/wails/commits?author=buddyabaddon" title="Code">💻</a></td>
<td align="center" valign="top" width="12.5%"><a href="https://github.com/MikeSchaap"><img src="https://avatars.githubusercontent.com/u/35368821?v=4?s=75" width="75px;" alt="MikeSchaap"/><br /><sub><b>MikeSchaap</b></sub></a><br /><a href="https://github.com/wailsapp/wails/commits?author=MikeSchaap" title="Code">💻</a> <a href="https://github.com/wailsapp/wails/issues?q=author%3AMikeSchaap" title="Bug reports">🐛</a></td>
<td align="center" valign="top" width="12.5%"><a href="https://github.com/Orijhins"><img src="https://avatars.githubusercontent.com/u/47521598?v=4?s=75" width="75px;" alt="NYSSEN Michaël"/><br /><sub><b>NYSSEN Michaël</b></sub></a><br /><a href="https://github.com/wailsapp/wails/commits?author=Orijhins" title="Code">💻</a> <a href="https://github.com/wailsapp/wails/issues?q=author%3AOrijhins" title="Bug reports">🐛</a></td>
<td align="center" valign="top" width="12.5%"><a href="https://github.com/NanoNik"><img src="https://avatars.githubusercontent.com/u/11991329?v=4?s=75" width="75px;" alt="Nan0"/><br /><sub><b>Nan0</b></sub></a><br /><a href="https://github.com/wailsapp/wails/commits?author=NanoNik" title="Code">💻</a> <a href="#ideas-NanoNik" title="Ideas, Planning, & Feedback">🤔</a> <a href="https://github.com/wailsapp/wails/commits?author=NanoNik" title="Tests">⚠️</a> <a href="https://github.com/wailsapp/wails/pulls?q=is%3Apr+reviewed-by%3ANanoNik" title="Reviewed Pull Requests">👀</a></td>
<td align="center" valign="top" width="12.5%"><a href="https://github.com/marcio199226"><img src="https://avatars.githubusercontent.com/u/10244404?v=4?s=75" width="75px;" alt="oskar"/><br /><sub><b>oskar</b></sub></a><br /><a href="https://github.com/wailsapp/wails/commits?author=marcio199226" title="Documentation">📖</a></td>
</tr>
<tr>
<td align="center" valign="top" width="12.5%"><a href="https://github.com/pierrejoye"><img src="https://avatars.githubusercontent.com/u/282408?v=4?s=75" width="75px;" alt="Pierre Joye"/><br /><sub><b>Pierre Joye</b></sub></a><br /><a href="https://github.com/wailsapp/wails/commits?author=pierrejoye" title="Code">💻</a> <a href="https://github.com/wailsapp/wails/issues?q=author%3Apierrejoye" title="Bug reports">🐛</a> <a href="#ideas-pierrejoye" title="Ideas, Planning, & Feedback">🤔</a> <a href="https://github.com/wailsapp/wails/commits?author=pierrejoye" title="Tests">⚠️</a></td>
<td align="center" valign="top" width="12.5%"><a href="https://github.com/Rested"><img src="https://avatars.githubusercontent.com/u/2003608?v=4?s=75" width="75px;" alt="Reuben Thomas-Davis"/><br /><sub><b>Reuben Thomas-Davis</b></sub></a><br /><a href="https://github.com/wailsapp/wails/commits?author=Rested" title="Code">💻</a> <a href="https://github.com/wailsapp/wails/issues?q=author%3ARested" title="Bug reports">🐛</a></td>
<td align="center" valign="top" width="12.5%"><a href="https://github.com/mewmew"><img src="https://avatars.githubusercontent.com/u/1414531?v=4?s=75" width="75px;" alt="Robin"/><br /><sub><b>Robin</b></sub></a><br /><a href="https://github.com/wailsapp/wails/commits?author=mewmew" title="Code">💻</a> <a href="https://github.com/wailsapp/wails/issues?q=author%3Amewmew" title="Bug reports">🐛</a></td>
<td align="center" valign="top" width="12.5%"><a href="https://threema.id/YSB3TVF7"><img src="https://avatars.githubusercontent.com/u/70367451?v=4?s=75" width="75px;" alt="Sebastian Bauer"/><br /><sub><b>Sebastian Bauer</b></sub></a><br /><a href="https://github.com/wailsapp/wails/commits?author=sebastian0x62" title="Code">💻</a> <a href="#ideas-sebastian0x62" title="Ideas, Planning, & Feedback">🤔</a> <a href="https://github.com/wailsapp/wails/commits?author=sebastian0x62" title="Tests">⚠️</a> <a href="https://github.com/wailsapp/wails/pulls?q=is%3Apr+reviewed-by%3Asebastian0x62" title="Reviewed Pull Requests">👀</a> <a href="#question-sebastian0x62" title="Answering Questions">💬</a></td>
<td align="center" valign="top" width="12.5%"><a href="https://github.com/sidwebworks"><img src="https://avatars.githubusercontent.com/u/58144379?v=4?s=75" width="75px;" alt="Sidharth Rathi"/><br /><sub><b>Sidharth Rathi</b></sub></a><br /><a href="https://github.com/wailsapp/wails/commits?author=sidwebworks" title="Documentation">📖</a> <a href="https://github.com/wailsapp/wails/issues?q=author%3Asidwebworks" title="Bug reports">🐛</a></td>
<td align="center" valign="top" width="12.5%"><a href="https://github.com/sithembiso"><img src="https://avatars.githubusercontent.com/u/6559905?v=4?s=75" width="75px;" alt="Sithembiso Khumalo"/><br /><sub><b>Sithembiso Khumalo</b></sub></a><br /><a href="https://github.com/wailsapp/wails/commits?author=sithembiso" title="Code">💻</a> <a href="https://github.com/wailsapp/wails/issues?q=author%3Asithembiso" title="Bug reports">🐛</a></td>
<td align="center" valign="top" width="12.5%"><a href="https://github.com/LanguageAgnostic"><img src="https://avatars.githubusercontent.com/u/19310562?v=4?s=75" width="75px;" alt="Soheib El-Harrache"/><br /><sub><b>Soheib El-Harrache</b></sub></a><br /><a href="https://github.com/wailsapp/wails/commits?author=LanguageAgnostic" title="Code">💻</a> <a href="https://github.com/wailsapp/wails/issues?q=author%3ALanguageAgnostic" title="Bug reports">🐛</a> <a href="#financial-LanguageAgnostic" title="Financial">💵</a></td>
<td align="center" valign="top" width="12.5%"><a href="https://www.sophieau.com/"><img src="https://avatars.githubusercontent.com/u/11145039?v=4?s=75" width="75px;" alt="Sophie Au"/><br /><sub><b>Sophie Au</b></sub></a><br /><a href="https://github.com/wailsapp/wails/commits?author=SophieAu" title="Code">💻</a> <a href="https://github.com/wailsapp/wails/issues?q=author%3ASophieAu" title="Bug reports">🐛</a></td>
</tr>
<tr>
<td align="center" valign="top" width="12.5%"><a href="https://github.com/stefpap"><img src="https://avatars.githubusercontent.com/u/22637722?v=4?s=75" width="75px;" alt="Stefanos Papadakis"/><br /><sub><b>Stefanos Papadakis</b></sub></a><br /><a href="https://github.com/wailsapp/wails/commits?author=stefpap" title="Code">💻</a> <a href="https://github.com/wailsapp/wails/issues?q=author%3Astefpap" title="Bug reports">🐛</a></td>
<td align="center" valign="top" width="12.5%"><a href="https://github.com/s12chung"><img src="https://avatars.githubusercontent.com/u/263394?v=4?s=75" width="75px;" alt="Steve Chung"/><br /><sub><b>Steve Chung</b></sub></a><br /><a href="https://github.com/wailsapp/wails/commits?author=s12chung" title="Code">💻</a> <a href="https://github.com/wailsapp/wails/issues?q=author%3As12chung" title="Bug reports">🐛</a></td>
<td align="center" valign="top" width="12.5%"><a href="https://tortloff.de/"><img src="https://avatars.githubusercontent.com/u/41272726?v=4?s=75" width="75px;" alt="Timm Ortloff"/><br /><sub><b>Timm Ortloff</b></sub></a><br /><a href="https://github.com/wailsapp/wails/commits?author=TAINCER" title="Documentation">📖</a></td>
<td align="center" valign="top" width="12.5%"><a href="https://github.com/tomanagle"><img src="https://avatars.githubusercontent.com/u/8683577?v=4?s=75" width="75px;" alt="Tom"/><br /><sub><b>Tom</b></sub></a><br /><a href="https://github.com/wailsapp/wails/commits?author=tomanagle" title="Code">💻</a></td>
<td align="center" valign="top" width="12.5%"><a href="https://www.linkedin.com/in/valentintrinque"><img src="https://avatars.githubusercontent.com/u/4662842?v=4?s=75" width="75px;" alt="Valentin Trinqué"/><br /><sub><b>Valentin Trinqué</b></sub></a><br /><a href="https://github.com/wailsapp/wails/commits?author=ValentinTrinque" title="Code">💻</a> <a href="https://github.com/wailsapp/wails/issues?q=author%3AValentinTrinque" title="Bug reports">🐛</a></td>
<td align="center" valign="top" width="12.5%"><a href="https://mattn.kaoriya.net/"><img src="https://avatars.githubusercontent.com/u/10111?v=4?s=75" width="75px;" alt="mattn"/><br /><sub><b>mattn</b></sub></a><br /><a href="https://github.com/wailsapp/wails/commits?author=mattn" title="Code">💻</a> <a href="https://github.com/wailsapp/wails/issues?q=author%3Amattn" title="Bug reports">🐛</a></td>
<td align="center" valign="top" width="12.5%"><a href="https://github.com/bearsh"><img src="https://avatars.githubusercontent.com/u/1089356?v=4?s=75" width="75px;" alt="bearsh"/><br /><sub><b>bearsh</b></sub></a><br /><a href="https://github.com/wailsapp/wails/commits?author=bearsh" title="Code">💻</a> <a href="#ideas-bearsh" title="Ideas, Planning, & Feedback">🤔</a> <a href="https://github.com/wailsapp/wails/commits?author=bearsh" title="Documentation">📖</a></td>
<td align="center" valign="top" width="12.5%"><a href="https://github.com/chenxiao1990"><img src="https://avatars.githubusercontent.com/u/16933565?v=4?s=75" width="75px;" alt="chenxiao"/><br /><sub><b>chenxiao</b></sub></a><br /><a href="https://github.com/wailsapp/wails/commits?author=chenxiao1990" title="Code">💻</a> <a href="#ideas-chenxiao1990" title="Ideas, Planning, & Feedback">🤔</a> <a href="https://github.com/wailsapp/wails/commits?author=chenxiao1990" title="Documentation">📖</a></td>
</tr>
<tr>
<td align="center" valign="top" width="12.5%"><a href="https://github.com/fengweiqiang"><img src="https://avatars.githubusercontent.com/u/22905300?v=4?s=75" width="75px;" alt="fengweiqiang"/><br /><sub><b>fengweiqiang</b></sub></a><br /><a href="https://github.com/wailsapp/wails/commits?author=fengweiqiang" title="Code">💻</a> <a href="#platform-fengweiqiang" title="Packaging/porting to new platform">📦</a></td>
<td align="center" valign="top" width="12.5%"><a href="https://github.com/flin7"><img src="https://avatars.githubusercontent.com/u/58138185?v=4?s=75" width="75px;" alt="flin7"/><br /><sub><b>flin7</b></sub></a><br /><a href="https://github.com/wailsapp/wails/commits?author=flin7" title="Documentation">📖</a></td>
<td align="center" valign="top" width="12.5%"><a href="https://github.com/fred21O4"><img src="https://avatars.githubusercontent.com/u/67189813?v=4?s=75" width="75px;" alt="fred21O4"/><br /><sub><b>fred21O4</b></sub></a><br /><a href="https://github.com/wailsapp/wails/commits?author=fred21O4" title="Documentation">📖</a></td>
<td align="center" valign="top" width="12.5%"><a href="https://github.com/gardc"><img src="https://avatars.githubusercontent.com/u/41453409?v=4?s=75" width="75px;" alt="gardc"/><br /><sub><b>gardc</b></sub></a><br /><a href="https://github.com/wailsapp/wails/commits?author=gardc" title="Documentation">📖</a> <a href="#tutorial-gardc" title="Tutorials"></a></td>
<td align="center" valign="top" width="12.5%"><a href="https://github.com/rayshoo"><img src="https://avatars.githubusercontent.com/u/52561899?v=4?s=75" width="75px;" alt="rayshoo"/><br /><sub><b>rayshoo</b></sub></a><br /><a href="https://github.com/wailsapp/wails/commits?author=rayshoo" title="Documentation">📖</a></td>
<td align="center" valign="top" width="12.5%"><a href="https://github.com/Yz4230"><img src="https://avatars.githubusercontent.com/u/38999742?v=4?s=75" width="75px;" alt="Ishiyama Yuzuki"/><br /><sub><b>Ishiyama Yuzuki</b></sub></a><br /><a href="https://github.com/wailsapp/wails/commits?author=Yz4230" title="Code">💻</a> <a href="https://github.com/wailsapp/wails/issues?q=author%3AYz4230" title="Bug reports">🐛</a></td>
<td align="center" valign="top" width="12.5%"><a href="https://baiyue.one/"><img src="https://avatars.githubusercontent.com/u/43716063?v=4?s=75" width="75px;" alt="佰阅"/><br /><sub><b>佰阅</b></sub></a><br /><a href="https://github.com/wailsapp/wails/commits?author=Baiyuetribe" title="Code">💻</a></td>
<td align="center" valign="top" width="12.5%"><a href="https://github.com/daodao97"><img src="https://avatars.githubusercontent.com/u/15009280?v=4?s=75" width="75px;" alt="刀刀"/><br /><sub><b>刀刀</b></sub></a><br /><a href="https://github.com/wailsapp/wails/commits?author=daodao97" title="Documentation">📖</a> <a href="https://github.com/wailsapp/wails/issues?q=author%3Adaodao97" title="Bug reports">🐛</a></td>
</tr>
<tr>
<td align="center" valign="top" width="12.5%"><a href="https://github.com/jicg"><img src="https://avatars.githubusercontent.com/u/6479672?v=4?s=75" width="75px;" alt="归位"/><br /><sub><b>归位</b></sub></a><br /><a href="https://github.com/wailsapp/wails/commits?author=jicg" title="Code">💻</a> <a href="https://github.com/wailsapp/wails/issues?q=author%3Ajicg" title="Bug reports">🐛</a></td>
<td align="center" valign="top" width="12.5%"><a href="https://github.com/skamensky"><img src="https://avatars.githubusercontent.com/u/19151369?v=4?s=75" width="75px;" alt="skamensky"/><br /><sub><b>skamensky</b></sub></a><br /><a href="https://github.com/wailsapp/wails/commits?author=skamensky" title="Code">💻</a> <a href="#ideas-skamensky" title="Ideas, Planning, & Feedback">🤔</a> <a href="https://github.com/wailsapp/wails/commits?author=skamensky" title="Documentation">📖</a></td>
<td align="center" valign="top" width="12.5%"><a href="https://github.com/apps/dependabot"><img src="https://avatars.githubusercontent.com/in/29110?v=4?s=75" width="75px;" alt="dependabot[bot]"/><br /><sub><b>dependabot[bot]</b></sub></a><br /><a href="https://github.com/wailsapp/wails/commits?author=dependabot[bot]" title="Code">💻</a> <a href="#maintenance-dependabot[bot]" title="Maintenance">🚧</a></td>
<td align="center" valign="top" width="12.5%"><a href="https://www.linkedin.com/in/dsieradzki/"><img src="https://avatars.githubusercontent.com/u/10297559?v=4?s=75" width="75px;" alt="Damian Sieradzki"/><br /><sub><b>Damian Sieradzki</b></sub></a><br /><a href="#financial-dsieradzki" title="Financial">💵</a></td>
<td align="center" valign="top" width="12.5%"><a href="https://github.com/boostchicken"><img src="https://avatars.githubusercontent.com/u/427295?v=4?s=75" width="75px;" alt="John Dorman"/><br /><sub><b>John Dorman</b></sub></a><br /><a href="#financial-boostchicken" title="Financial">💵</a></td>
<td align="center" valign="top" width="12.5%"><a href="https://blog.iansinnott.com/"><img src="https://avatars.githubusercontent.com/u/3154865?v=4?s=75" width="75px;" alt="Ian Sinnott"/><br /><sub><b>Ian Sinnott</b></sub></a><br /><a href="#financial-iansinnott" title="Financial">💵</a></td>
<td align="center" valign="top" width="12.5%"><a href="https://github.com/Shackelford-Arden"><img src="https://avatars.githubusercontent.com/u/7362263?v=4?s=75" width="75px;" alt="Arden Shackelford"/><br /><sub><b>Arden Shackelford</b></sub></a><br /><a href="#financial-Shackelford-Arden" title="Financial">💵</a></td>
<td align="center" valign="top" width="12.5%"><a href="https://github.com/Bironou"><img src="https://avatars.githubusercontent.com/u/107761511?v=4?s=75" width="75px;" alt="Bironou"/><br /><sub><b>Bironou</b></sub></a><br /><a href="#financial-Bironou" title="Financial">💵</a></td>
</tr>
<tr>
<td align="center" valign="top" width="12.5%"><a href="https://github.com/CharlieGo19"><img src="https://avatars.githubusercontent.com/u/62405980?v=4?s=75" width="75px;" alt="CharlieGo_"/><br /><sub><b>CharlieGo_</b></sub></a><br /><a href="#financial-CharlieGo19" title="Financial">💵</a></td>
<td align="center" valign="top" width="12.5%"><a href="https://github.com/overnet"><img src="https://avatars.githubusercontent.com/u/6376126?v=4?s=75" width="75px;" alt="overnet"/><br /><sub><b>overnet</b></sub></a><br /><a href="#financial-overnet" title="Financial">💵</a></td>
<td align="center" valign="top" width="12.5%"><a href="https://jugglingjsons.dev/"><img src="https://avatars.githubusercontent.com/u/20739064?v=4?s=75" width="75px;" alt="jugglingjsons"/><br /><sub><b>jugglingjsons</b></sub></a><br /><a href="#financial-jugglingjsons" title="Financial">💵</a></td>
<td align="center" valign="top" width="12.5%"><a href="https://selvin.dev/"><img src="https://avatars.githubusercontent.com/u/1922523?v=4?s=75" width="75px;" alt="Selvin Ortiz"/><br /><sub><b>Selvin Ortiz</b></sub></a><br /><a href="#financial-selvindev" title="Financial">💵</a></td>
<td align="center" valign="top" width="12.5%"><a href="https://github.com/zandercodes"><img src="https://avatars.githubusercontent.com/u/46308805?v=4?s=75" width="75px;" alt="ZanderCodes"/><br /><sub><b>ZanderCodes</b></sub></a><br /><a href="#financial-zandercodes" title="Financial">💵</a></td>
<td align="center" valign="top" width="12.5%"><a href="https://github.com/DonTomato"><img src="https://avatars.githubusercontent.com/u/1098084?v=4?s=75" width="75px;" alt="Michael Voronov"/><br /><sub><b>Michael Voronov</b></sub></a><br /><a href="#financial-DonTomato" title="Financial">💵</a></td>
<td align="center" valign="top" width="12.5%"><a href="https://lt.hn/"><img src="https://avatars.githubusercontent.com/u/83868036?v=4?s=75" width="75px;" alt="letheanVPN"/><br /><sub><b>letheanVPN</b></sub></a><br /><a href="#financial-letheanVPN" title="Financial">💵</a></td>
<td align="center" valign="top" width="12.5%"><a href="https://taigrr.com/"><img src="https://avatars.githubusercontent.com/u/8261498?v=4?s=75" width="75px;" alt="Tai Groot"/><br /><sub><b>Tai Groot</b></sub></a><br /><a href="#financial-taigrr" title="Financial">💵</a></td>
</tr>
<tr>
<td align="center" valign="top" width="12.5%"><a href="https://github.com/easy-web-it"><img src="https://avatars.githubusercontent.com/u/95484991?v=4?s=75" width="75px;" alt="easy-web-it"/><br /><sub><b>easy-web-it</b></sub></a><br /><a href="#financial-easy-web-it" title="Financial">💵</a></td>
<td align="center" valign="top" width="12.5%"><a href="https://michaelolson1996.github.io/portfolio"><img src="https://avatars.githubusercontent.com/u/45323107?v=4?s=75" width="75px;" alt="Michael Olson"/><br /><sub><b>Michael Olson</b></sub></a><br /><a href="#financial-michaelolson1996" title="Financial">💵</a></td>
<td align="center" valign="top" width="12.5%"><a href="https://eden.network/"><img src="https://avatars.githubusercontent.com/u/4912777?v=4?s=75" width="75px;" alt="EdenNetwork Italia"/><br /><sub><b>EdenNetwork Italia</b></sub></a><br /><a href="#financial-EdenNetworkItalia" title="Financial">💵</a></td>
<td align="center" valign="top" width="12.5%"><a href="https://github.com/ondoki"><img src="https://avatars.githubusercontent.com/u/88536792?v=4?s=75" width="75px;" alt="ondoki"/><br /><sub><b>ondoki</b></sub></a><br /><a href="#financial-ondoki" title="Financial">💵</a></td>
<td align="center" valign="top" width="12.5%"><a href="https://github.com/questrail"><img src="https://avatars.githubusercontent.com/u/3536569?v=4?s=75" width="75px;" alt="QuEST Rail LLC"/><br /><sub><b>QuEST Rail LLC</b></sub></a><br /><a href="#financial-questrail" title="Financial">💵</a></td>
<td align="center" valign="top" width="12.5%"><a href="https://github.com/Gilgames000"><img src="https://avatars.githubusercontent.com/u/22778436?v=4?s=75" width="75px;" alt="Gilgameš"/><br /><sub><b>Gilgameš</b></sub></a><br /><a href="#financial-Gilgames000" title="Financial">💵</a></td>
<td align="center" valign="top" width="12.5%"><a href="https://github.com/bbergshaven"><img src="https://avatars.githubusercontent.com/u/4091634?v=4?s=75" width="75px;" alt="Bernt-Johan Bergshaven"/><br /><sub><b>Bernt-Johan Bergshaven</b></sub></a><br /><a href="#financial-bbergshaven" title="Financial">💵</a></td>
<td align="center" valign="top" width="12.5%"><a href="https://github.com/bglw"><img src="https://avatars.githubusercontent.com/u/40188355?v=4?s=75" width="75px;" alt="Liam Bigelow"/><br /><sub><b>Liam Bigelow</b></sub></a><br /><a href="#financial-bglw" title="Financial">💵</a></td>
</tr>
<tr>
<td align="center" valign="top" width="12.5%"><a href="https://github.com/nickarellano"><img src="https://avatars.githubusercontent.com/u/13930605?v=4?s=75" width="75px;" alt="Nick Arellano"/><br /><sub><b>Nick Arellano</b></sub></a><br /><a href="#financial-nickarellano" title="Financial">💵</a></td>
<td align="center" valign="top" width="12.5%"><a href="https://github.com/fcjr"><img src="https://avatars.githubusercontent.com/u/2053002?v=4?s=75" width="75px;" alt="Frank Chiarulli Jr."/><br /><sub><b>Frank Chiarulli Jr.</b></sub></a><br /><a href="#financial-fcjr" title="Financial">💵</a></td>
<td align="center" valign="top" width="12.5%"><a href="https://github.com/tylertravisty"><img src="https://avatars.githubusercontent.com/u/8620352?v=4?s=75" width="75px;" alt="Tyler"/><br /><sub><b>Tyler</b></sub></a><br /><a href="#financial-tylertravisty" title="Financial">💵</a></td>
<td align="center" valign="top" width="12.5%"><a href="https://github.com/trea"><img src="https://avatars.githubusercontent.com/u/1181448?v=4?s=75" width="75px;" alt="Trea Hauet"/><br /><sub><b>Trea Hauet</b></sub></a><br /><a href="#financial-trea" title="Financial">💵</a></td>
<td align="center" valign="top" width="12.5%"><a href="https://picatz.github.io/"><img src="https://avatars.githubusercontent.com/u/14850816?v=4?s=75" width="75px;" alt="Kent 'picat' Gruber"/><br /><sub><b>Kent 'picat' Gruber</b></sub></a><br /><a href="#financial-picatz" title="Financial">💵</a></td>
<td align="center" valign="top" width="12.5%"><a href="https://github.com/tc-hib"><img src="https://avatars.githubusercontent.com/u/55949036?v=4?s=75" width="75px;" alt="tc-hib"/><br /><sub><b>tc-hib</b></sub></a><br /><a href="#financial-tc-hib" title="Financial">💵</a></td>
<td align="center" valign="top" width="12.5%"><a href="https://github.com/acheong08"><img src="https://avatars.githubusercontent.com/u/36258159?v=4?s=75" width="75px;" alt="Antonio"/><br /><sub><b>Antonio</b></sub></a><br /><a href="https://github.com/wailsapp/wails/commits?author=acheong08" title="Documentation">📖</a></td>
<td align="center" valign="top" width="12.5%"><a href="https://github.com/MyNameIsAres"><img src="https://avatars.githubusercontent.com/u/32432637?v=4?s=75" width="75px;" alt="MyNameIsAres"/><br /><sub><b>MyNameIsAres</b></sub></a><br /><a href="https://github.com/wailsapp/wails/commits?author=MyNameIsAres" title="Documentation">📖</a></td>
</tr>
<tr>
<td align="center" valign="top" width="12.5%"><a href="http://mai.car.ons"><img src="https://avatars.githubusercontent.com/u/101958587?v=4?s=75" width="75px;" alt="Maicarons J"/><br /><sub><b>Maicarons J</b></sub></a><br /><a href="https://github.com/wailsapp/wails/commits?author=Maicarons2022" title="Documentation">📖</a></td>
<td align="center" valign="top" width="12.5%"><a href="https://github.com/KiddoV"><img src="https://avatars.githubusercontent.com/u/28552977?v=4?s=75" width="75px;" alt="kiddov"/><br /><sub><b>kiddov</b></sub></a><br /><a href="https://github.com/wailsapp/wails/commits?author=KiddoV" title="Documentation">📖</a> <a href="#financial-KiddoV" title="Financial">💵</a> <a href="https://github.com/wailsapp/wails/commits?author=KiddoV" title="Tests">⚠️</a> <a href="#ideas-KiddoV" title="Ideas, Planning, & Feedback">🤔</a></td>
<td align="center" valign="top" width="12.5%"><a href="https://nicolas-coutin.com/"><img src="https://avatars.githubusercontent.com/u/6564012?v=4?s=75" width="75px;" alt="Nicolas Coutin"/><br /><sub><b>Nicolas Coutin</b></sub></a><br /><a href="#financial-Ilshidur" title="Financial">💵</a></td>
<td align="center" valign="top" width="12.5%"><a href="https://github.com/ParvinEyvazov"><img src="https://avatars.githubusercontent.com/u/32189770?v=4?s=75" width="75px;" alt="Parvin Eyvazov"/><br /><sub><b>Parvin Eyvazov</b></sub></a><br /><a href="https://github.com/wailsapp/wails/commits?author=ParvinEyvazov" title="Documentation">📖</a></td>
<td align="center" valign="top" width="12.5%"><a href="https://github.com/apps/github-actions"><img src="https://avatars.githubusercontent.com/in/15368?v=4?s=75" width="75px;" alt="github-actions[bot]"/><br /><sub><b>github-actions[bot]</b></sub></a><br /><a href="https://github.com/wailsapp/wails/commits?author=github-actions[bot]" title="Code">💻</a></td>
<td align="center" valign="top" width="12.5%"><a href="https://github.com/OlegGulevskyy"><img src="https://avatars.githubusercontent.com/u/43781031?v=4?s=75" width="75px;" alt="Oleg Gulevskyy"/><br /><sub><b>Oleg Gulevskyy</b></sub></a><br /><a href="https://github.com/wailsapp/wails/commits?author=OlegGulevskyy" title="Code">💻</a> <a href="https://github.com/wailsapp/wails/commits?author=OlegGulevskyy" title="Documentation">📖</a> <a href="#maintenance-OlegGulevskyy" title="Maintenance">🚧</a> <a href="#platform-OlegGulevskyy" title="Packaging/porting to new platform">📦</a></td>
<td align="center" valign="top" width="12.5%"><a href="http://www.customct.com/"><img src="https://avatars.githubusercontent.com/u/2487495?v=4?s=75" width="75px;" alt="Richard Guay"/><br /><sub><b>Richard Guay</b></sub></a><br /><a href="https://github.com/wailsapp/wails/commits?author=raguay" title="Documentation">📖</a></td>
<td align="center" valign="top" width="12.5%"><a href="https://github.com/ATenderholt"><img src="https://avatars.githubusercontent.com/u/740623?v=4?s=75" width="75px;" alt="Adam Tenderholt"/><br /><sub><b>Adam Tenderholt</b></sub></a><br /><a href="https://github.com/wailsapp/wails/commits?author=ATenderholt" title="Code">💻</a></td>
</tr>
<tr>
<td align="center" valign="top" width="12.5%"><a href="https://github.com/JulioDRF"><img src="https://avatars.githubusercontent.com/u/15677708?v=4?s=75" width="75px;" alt="JulioDRF"/><br /><sub><b>JulioDRF</b></sub></a><br /><a href="https://github.com/wailsapp/wails/commits?author=JulioDRF" title="Code">💻</a></td>
<td align="center" valign="top" width="12.5%"><a href="http://scottopell.com/"><img src="https://avatars.githubusercontent.com/u/996472?v=4?s=75" width="75px;" alt="Scott Opell"/><br /><sub><b>Scott Opell</b></sub></a><br /><a href="https://github.com/wailsapp/wails/commits?author=scottopell" title="Code">💻</a></td>
<td align="center" valign="top" width="12.5%"><a href="https://aven.dev/"><img src="https://avatars.githubusercontent.com/u/2055581?v=4?s=75" width="75px;" alt="Vadim Shchepotev"/><br /><sub><b>Vadim Shchepotev</b></sub></a><br /><a href="https://github.com/wailsapp/wails/commits?author=avengerweb" title="Code">💻</a></td>
<td align="center" valign="top" width="12.5%"><a href="https://willdot.net/"><img src="https://avatars.githubusercontent.com/u/4906530?v=4?s=75" width="75px;" alt="Will Andrews"/><br /><sub><b>Will Andrews</b></sub></a><br /><a href="https://github.com/wailsapp/wails/commits?author=willdot" title="Code">💻</a></td>
<td align="center" valign="top" width="12.5%"><a href="https://github.com/gwynforthewyn"><img src="https://avatars.githubusercontent.com/u/434656?v=4?s=75" width="75px;" alt="Gwyn"/><br /><sub><b>Gwyn</b></sub></a><br /><a href="https://github.com/wailsapp/wails/commits?author=gwynforthewyn" title="Code">💻</a> <a href="https://github.com/wailsapp/wails/pulls?q=is%3Apr+reviewed-by%3Agwynforthewyn" title="Reviewed Pull Requests">👀</a> <a href="#question-gwynforthewyn" title="Answering Questions">💬</a> <a href="#research-gwynforthewyn" title="Research">🔬</a></td>
<td align="center" valign="top" width="12.5%"><a href="https://github.com/xijaja"><img src="https://avatars.githubusercontent.com/u/47017666?v=4?s=75" width="75px;" alt="希嘉嘉"/><br /><sub><b>希嘉嘉</b></sub></a><br /><a href="https://github.com/wailsapp/wails/commits?author=xijaja" title="Code">💻</a></td>
<td align="center" valign="top" width="12.5%"><a href="https://www.almas.cc/"><img src="https://avatars.githubusercontent.com/u/9382335?v=4?s=75" width="75px;" alt="ALMAS"/><br /><sub><b>ALMAS</b></sub></a><br /><a href="https://github.com/wailsapp/wails/commits?author=almas1992" title="Code">💻</a></td>
<td align="center" valign="top" width="12.5%"><a href="https://stdout.com.cn/"><img src="https://avatars.githubusercontent.com/u/20666153?v=4?s=75" width="75px;" alt="Alex"/><br /><sub><b>Alex</b></sub></a><br /><a href="https://github.com/wailsapp/wails/commits?author=o8x" title="Code">💻</a></td>
</tr>
<tr>
<td align="center" valign="top" width="12.5%"><a href="https://github.com/arifali123"><img src="https://avatars.githubusercontent.com/u/51419655?v=4?s=75" width="75px;" alt="Arif Ali"/><br /><sub><b>Arif Ali</b></sub></a><br /><a href="https://github.com/wailsapp/wails/commits?author=arifali123" title="Code">💻</a></td>
<td align="center" valign="top" width="12.5%"><a href="https://github.com/hotafrika"><img src="https://avatars.githubusercontent.com/u/18332839?v=4?s=75" width="75px;" alt="Artur Siarohau"/><br /><sub><b>Artur Siarohau</b></sub></a><br /><a href="https://github.com/wailsapp/wails/commits?author=hotafrika" title="Code">💻</a></td>
<td align="center" valign="top" width="12.5%"><a href="https://binyam.in/"><img src="https://avatars.githubusercontent.com/u/39805353?v=4?s=75" width="75px;" alt="Binyamin Aron Green"/><br /><sub><b>Binyamin Aron Green</b></sub></a><br /><a href="https://github.com/wailsapp/wails/commits?author=binyamin" title="Code">💻</a></td>
<td align="center" valign="top" width="12.5%"><a href="http://bdwyertech.net/"><img src="https://avatars.githubusercontent.com/u/2973273?v=4?s=75" width="75px;" alt="Brian Dwyer"/><br /><sub><b>Brian Dwyer</b></sub></a><br /><a href="https://github.com/wailsapp/wails/commits?author=bdwyertech" title="Code">💻</a></td>
<td align="center" valign="top" width="12.5%"><a href="http://www.cilb.de/"><img src="https://avatars.githubusercontent.com/u/7283097?v=4?s=75" width="75px;" alt="Christian Kilb"/><br /><sub><b>Christian Kilb</b></sub></a><br /><a href="https://github.com/wailsapp/wails/commits?author=ckilb" title="Code">💻</a></td>
<td align="center" valign="top" width="12.5%"><a href="https://github.com/edwargix"><img src="https://avatars.githubusercontent.com/u/22877007?v=4?s=75" width="75px;" alt="David Florness"/><br /><sub><b>David Florness</b></sub></a><br /><a href="https://github.com/wailsapp/wails/commits?author=edwargix" title="Documentation">📖</a></td>
<td align="center" valign="top" width="12.5%"><a href="https://github.com/BuckeyeCoder"><img src="https://avatars.githubusercontent.com/u/95933880?v=4?s=75" width="75px;" alt="David Walton"/><br /><sub><b>David Walton</b></sub></a><br /><a href="https://github.com/wailsapp/wails/commits?author=BuckeyeCoder" title="Code">💻</a></td>
<td align="center" valign="top" width="12.5%"><a href="https://github.com/Debdut"><img src="https://avatars.githubusercontent.com/u/7561070?v=4?s=75" width="75px;" alt="Debdut Karmakar"/><br /><sub><b>Debdut Karmakar</b></sub></a><br /><a href="https://github.com/wailsapp/wails/commits?author=Debdut" title="Code">💻</a></td>
</tr>
<tr>
<td align="center" valign="top" width="12.5%"><a href="https://github.com/gotid"><img src="https://avatars.githubusercontent.com/u/4010854?v=4?s=75" width="75px;" alt="Dieter Zhu"/><br /><sub><b>Dieter Zhu</b></sub></a><br /><a href="https://github.com/wailsapp/wails/commits?author=gotid" title="Code">💻</a></td>
<td align="center" valign="top" width="12.5%"><a href="https://fredrikholmqvist.com/"><img src="https://avatars.githubusercontent.com/u/22743750?v=4?s=75" width="75px;" alt="Fredrik Holmqvist"/><br /><sub><b>Fredrik Holmqvist</b></sub></a><br /><a href="https://github.com/wailsapp/wails/commits?author=Holmqvist1990" title="Code">💻</a></td>
<td align="center" valign="top" width="12.5%"><a href="https://github.com/giopalma"><img src="https://avatars.githubusercontent.com/u/33783684?v=4?s=75" width="75px;" alt="Giovanni Palma"/><br /><sub><b>Giovanni Palma</b></sub></a><br /><a href="https://github.com/wailsapp/wails/commits?author=giopalma" title="Code">💻</a></td>
<td align="center" valign="top" width="12.5%"><a href="https://github.com/Nexus26404"><img src="https://avatars.githubusercontent.com/u/83110373?v=4?s=75" width="75px;" alt="Hao"/><br /><sub><b>Hao</b></sub></a><br /><a href="https://github.com/wailsapp/wails/commits?author=Nexus26404" title="Code">💻</a></td>
<td align="center" valign="top" width="12.5%"><a href="https://github.com/i7tsov"><img src="https://avatars.githubusercontent.com/u/44977153?v=4?s=75" width="75px;" alt="Igor Sementsov"/><br /><sub><b>Igor Sementsov</b></sub></a><br /><a href="https://github.com/wailsapp/wails/commits?author=i7tsov" title="Code">💻</a></td>
<td align="center" valign="top" width="12.5%"><a href="https://github.com/derhasi"><img src="https://avatars.githubusercontent.com/u/118502?v=4?s=75" width="75px;" alt="Johannes Haseitl"/><br /><sub><b>Johannes Haseitl</b></sub></a><br /><a href="https://github.com/wailsapp/wails/commits?author=derhasi" title="Code">💻</a></td>
<td align="center" valign="top" width="12.5%"><a href="https://github.com/joshbuddy"><img src="https://avatars.githubusercontent.com/u/8898?v=4?s=75" width="75px;" alt="Joshua Hull"/><br /><sub><b>Joshua Hull</b></sub></a><br /><a href="https://github.com/wailsapp/wails/commits?author=joshbuddy" title="Code">💻</a></td>
<td align="center" valign="top" width="12.5%"><a href="https://github.com/joshm998"><img src="https://avatars.githubusercontent.com/u/1779737?v=4?s=75" width="75px;" alt="Joshua Mangiola"/><br /><sub><b>Joshua Mangiola</b></sub></a><br /><a href="https://github.com/wailsapp/wails/commits?author=joshm998" title="Documentation">📖</a></td>
</tr>
<tr>
<td align="center" valign="top" width="12.5%"><a href="https://github.com/prurigro"><img src="https://avatars.githubusercontent.com/u/1149238?v=4?s=75" width="75px;" alt="Kevin MacMartin"/><br /><sub><b>Kevin MacMartin</b></sub></a><br /><a href="https://github.com/wailsapp/wails/commits?author=prurigro" title="Code">💻</a></td>
<td align="center" valign="top" width="12.5%"><a href="https://github.com/liang-li-dev"><img src="https://avatars.githubusercontent.com/u/112530363?v=4?s=75" width="75px;" alt="Liang Li"/><br /><sub><b>Liang Li</b></sub></a><br /><a href="https://github.com/wailsapp/wails/commits?author=liang-li-dev" title="Code">💻</a></td>
<td align="center" valign="top" width="12.5%"><a href="https://appslab.co.ke/"><img src="https://avatars.githubusercontent.com/u/7722584?v=4?s=75" width="75px;" alt="Marvin Collins Hosea"/><br /><sub><b>Marvin Collins Hosea</b></sub></a><br /><a href="https://github.com/wailsapp/wails/commits?author=marvinhosea" title="Code">💻</a></td>
<td align="center" valign="top" width="12.5%"><a href="https://matt.life/"><img src="https://avatars.githubusercontent.com/u/1128849?v=4?s=75" width="75px;" alt="Matt Holt"/><br /><sub><b>Matt Holt</b></sub></a><br /><a href="https://github.com/wailsapp/wails/commits?author=mholt" title="Code">💻</a></td>
<td align="center" valign="top" width="12.5%"><a href="https://github.com/Gurkengewuerz"><img src="https://avatars.githubusercontent.com/u/10966337?v=4?s=75" width="75px;" alt="Niklas"/><br /><sub><b>Niklas</b></sub></a><br /><a href="https://github.com/wailsapp/wails/commits?author=Gurkengewuerz" title="Code">💻</a></td>
<td align="center" valign="top" width="12.5%"><a href="https://github.com/Xhofe"><img src="https://avatars.githubusercontent.com/u/36558727?v=4?s=75" width="75px;" alt="Andy Hsu"/><br /><sub><b>Andy Hsu</b></sub></a><br /><a href="https://github.com/wailsapp/wails/commits?author=Xhofe" title="Code">💻</a></td>
<td align="center" valign="top" width="12.5%"><a href="https://github.com/NullCode1337"><img src="https://avatars.githubusercontent.com/u/70959549?v=4?s=75" width="75px;" alt="NullCode"/><br /><sub><b>NullCode</b></sub></a><br /><a href="https://github.com/wailsapp/wails/commits?author=NullCode1337" title="Code">💻</a></td>
<td align="center" valign="top" width="12.5%"><a href="https://github.com/oSethoum"><img src="https://avatars.githubusercontent.com/u/88779394?v=4?s=75" width="75px;" alt="Oussama Sethoum"/><br /><sub><b>Oussama Sethoum</b></sub></a><br /><a href="https://github.com/wailsapp/wails/commits?author=oSethoum" title="Code">💻</a></td>
</tr>
<tr>
<td align="center" valign="top" width="12.5%"><a href="https://github.com/ParkourLiu"><img src="https://avatars.githubusercontent.com/u/33681340?v=4?s=75" width="75px;" alt="ParkourLiu"/><br /><sub><b>ParkourLiu</b></sub></a><br /><a href="https://github.com/wailsapp/wails/commits?author=ParkourLiu" title="Code">💻</a></td>
<td align="center" valign="top" width="12.5%"><a href="https://github.com/zllovesuki"><img src="https://avatars.githubusercontent.com/u/298453?v=4?s=75" width="75px;" alt="Rachel Chen"/><br /><sub><b>Rachel Chen</b></sub></a><br /><a href="https://github.com/wailsapp/wails/commits?author=zllovesuki" title="Code">💻</a></td>
<td align="center" valign="top" width="12.5%"><a href="https://github.com/rnice01"><img src="https://avatars.githubusercontent.com/u/11394384?v=4?s=75" width="75px;" alt="Rob Nice"/><br /><sub><b>Rob Nice</b></sub></a><br /><a href="https://github.com/wailsapp/wails/commits?author=rnice01" title="Code">💻</a></td>
<td align="center" valign="top" width="12.5%"><a href="https://github.com/RyoTagami"><img src="https://avatars.githubusercontent.com/u/9672589?v=4?s=75" width="75px;" alt="Ryo TAGAMI"/><br /><sub><b>Ryo TAGAMI</b></sub></a><br /><a href="https://github.com/wailsapp/wails/commits?author=RyoTagami" title="Code">💻</a></td>
<td align="center" valign="top" width="12.5%"><a href="https://github.com/SamHennessy"><img src="https://avatars.githubusercontent.com/u/119867?v=4?s=75" width="75px;" alt="Sam Hennessy"/><br /><sub><b>Sam Hennessy</b></sub></a><br /><a href="https://github.com/wailsapp/wails/commits?author=SamHennessy" title="Code">💻</a></td>
<td align="center" valign="top" width="12.5%"><a href="https://albinodrought.com/"><img src="https://avatars.githubusercontent.com/u/852873?v=4?s=75" width="75px;" alt="Sean"/><br /><sub><b>Sean</b></sub></a><br /><a href="https://github.com/wailsapp/wails/commits?author=AlbinoDrought" title="Code">💻</a></td>
<td align="center" valign="top" width="12.5%"><a href="https://github.com/sgosiaco"><img src="https://avatars.githubusercontent.com/u/212341?v=4?s=75" width="75px;" alt="Sean Gosiaco"/><br /><sub><b>Sean Gosiaco</b></sub></a><br /><a href="https://github.com/wailsapp/wails/commits?author=sgosiaco" title="Code">💻</a></td>
<td align="center" valign="top" width="12.5%"><a href="https://sheetjs.com/"><img src="https://avatars.githubusercontent.com/u/6070939?v=4?s=75" width="75px;" alt="Eric P Sheets"/><br /><sub><b>Eric P Sheets</b></sub></a><br /><a href="https://github.com/wailsapp/wails/commits?author=SheetJSDev" title="Code">💻</a></td>
</tr>
<tr>
<td align="center" valign="top" width="12.5%"><a href="https://www.octopy.dev/"><img src="https://avatars.githubusercontent.com/u/37969970?v=4?s=75" width="75px;" alt="Supian M"/><br /><sub><b>Supian M</b></sub></a><br /><a href="https://github.com/wailsapp/wails/commits?author=SupianIDz" title="Code">💻</a></td>
<td align="center" valign="top" width="12.5%"><a href="https://github.com/Watson-Sei"><img src="https://avatars.githubusercontent.com/u/55475145?v=4?s=75" width="75px;" alt="Watson-Sei"/><br /><sub><b>Watson-Sei</b></sub></a><br /><a href="https://github.com/wailsapp/wails/commits?author=Watson-Sei" title="Code">💻</a> <a href="https://github.com/wailsapp/wails/commits?author=Watson-Sei" title="Documentation">📖</a></td>
<td align="center" valign="top" width="12.5%"><a href="https://shinshin86.com/"><img src="https://avatars.githubusercontent.com/u/8216064?v=4?s=75" width="75px;" alt="Yuki Shindo"/><br /><sub><b>Yuki Shindo</b></sub></a><br /><a href="https://github.com/wailsapp/wails/commits?author=shinshin86" title="Code">💻</a></td>
<td align="center" valign="top" width="12.5%"><a href="https://github.com/cuigege"><img src="https://avatars.githubusercontent.com/u/26080122?v=4?s=75" width="75px;" alt="cuigege"/><br /><sub><b>cuigege</b></sub></a><br /><a href="https://github.com/wailsapp/wails/commits?author=cuigege" title="Code">💻</a></td>
<td align="center" valign="top" width="12.5%"><a href="https://cybertramp.net/"><img src="https://avatars.githubusercontent.com/u/30935096?v=4?s=75" width="75px;" alt="cybertramp"/><br /><sub><b>cybertramp</b></sub></a><br /><a href="https://github.com/wailsapp/wails/commits?author=cybertramp" title="Code">💻</a></td>
<td align="center" valign="top" width="12.5%"><a href="https://github.com/h8gi"><img src="https://avatars.githubusercontent.com/u/10811057?v=4?s=75" width="75px;" alt="hiroki yagi"/><br /><sub><b>hiroki yagi</b></sub></a><br /><a href="https://github.com/wailsapp/wails/commits?author=h8gi" title="Code">💻</a></td>
<td align="center" valign="top" width="12.5%"><a href="https://github.com/apps/imgbot"><img src="https://avatars.githubusercontent.com/in/4706?v=4?s=75" width="75px;" alt="imgbot[bot]"/><br /><sub><b>imgbot[bot]</b></sub></a><br /><a href="https://github.com/wailsapp/wails/commits?author=imgbot[bot]" title="Code">💻</a></td>
<td align="center" valign="top" width="12.5%"><a href="https://github.com/tong3jie"><img src="https://avatars.githubusercontent.com/u/14191774?v=4?s=75" width="75px;" alt="juju"/><br /><sub><b>juju</b></sub></a><br /><a href="https://github.com/wailsapp/wails/commits?author=tong3jie" title="Code">💻</a></td>
</tr>
<tr>
<td align="center" valign="top" width="12.5%"><a href="http://meatherly.github.io/"><img src="https://avatars.githubusercontent.com/u/1327960?v=4?s=75" width="75px;" alt="Michael Eatherly"/><br /><sub><b>Michael Eatherly</b></sub></a><br /><a href="https://github.com/wailsapp/wails/commits?author=meatherly" title="Code">💻</a></td>
<td align="center" valign="top" width="12.5%"><a href="https://github.com/tk103331"><img src="https://avatars.githubusercontent.com/u/4404609?v=4?s=75" width="75px;" alt="tk"/><br /><sub><b>tk</b></sub></a><br /><a href="https://github.com/wailsapp/wails/commits?author=tk103331" title="Code">💻</a></td>
<td align="center" valign="top" width="12.5%"><a href="https://github.com/apps/allcontributors"><img src="https://avatars.githubusercontent.com/in/23186?v=4?s=75" width="75px;" alt="allcontributors[bot]"/><br /><sub><b>allcontributors[bot]</b></sub></a><br /><a href="https://github.com/wailsapp/wails/commits?author=allcontributors[bot]" title="Documentation">📖</a></td>
<td align="center" valign="top" width="12.5%"><a href="https://www.ffactory.org/"><img src="https://avatars.githubusercontent.com/u/77320953?v=4?s=75" width="75px;" alt="wander"/><br /><sub><b>wander</b></sub></a><br /><a href="https://github.com/wailsapp/wails/commits?author=wandercn" title="Documentation">📖</a></td>
</tr>
</tbody>
</table>
<!--GAMFC_DELIMITER-END-->
</div>

View File

@ -0,0 +1,54 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg width="100%" height="100%" viewBox="0 0 551 436" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" xmlns:serif="http://www.serif.com/" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:2;">
<path d="M260.266,104.287L301.929,93.442L268.858,115.754L260.266,104.287Z" style="fill:rgb(235,235,235);"/>
<g transform="matrix(1,0,0,1,116.615,393.181)">
<path d="M0,-51.891L14.429,-51.891L13.043,-21.183L22.568,-51.891L34.226,-51.891L34.084,-21.183L42.365,-51.891L56.794,-51.891L38.526,0L25.198,0L25.34,-32.45L15.211,0L1.919,0L0,-51.891Z" style="fill:white;fill-rule:nonzero;"/>
</g>
<g transform="matrix(1,0,0,1,226.834,359.416)">
<path d="M0,15.639L5.793,15.639L5.971,-3.589L0,15.639ZM-20.187,33.765L-0.675,-18.126L16.42,-18.126L20.08,33.765L5.437,33.765L5.509,26.123L-3.057,26.123L-5.332,33.765L-20.187,33.765Z" style="fill:white;fill-rule:nonzero;"/>
</g>
<g transform="matrix(0.156272,-0.987714,-0.987714,-0.156272,327.042,382.506)">
<path d="M-16.046,33.107L36.491,33.107L38.757,18.784L-13.785,18.82L-16.046,33.107Z" style="fill:white;fill-rule:nonzero;"/>
</g>
<g transform="matrix(1,0,0,1,360.484,341.289)">
<path d="M0,51.891L8.246,0L22.781,0L16.597,39.024L27.224,39.024L25.199,51.891L0,51.891Z" style="fill:white;fill-rule:nonzero;"/>
</g>
<g transform="matrix(1,0,0,1,432.623,357.391)">
<path d="M0,19.83C1.611,21.181 3.305,22.224 5.083,22.959C6.859,23.693 8.565,24.06 10.2,24.06C11.645,24.06 12.794,23.663 13.647,22.87C14.5,22.076 14.927,20.992 14.927,19.617C14.927,18.434 14.571,17.254 13.861,16.081C13.15,14.908 11.775,13.351 9.738,11.408C7.273,9.015 5.58,6.906 4.655,5.081C3.731,3.257 3.27,1.243 3.27,-0.96C3.27,-5.912 4.839,-9.846 7.979,-12.76C11.118,-15.674 15.377,-17.132 20.756,-17.132C22.936,-17.132 25.008,-16.889 26.975,-16.403C28.941,-15.917 30.943,-15.165 32.982,-14.146L30.92,-1.493C29.356,-2.583 27.834,-3.412 26.354,-3.981C24.872,-4.551 23.457,-4.835 22.106,-4.835C20.898,-4.835 19.943,-4.521 19.245,-3.894C18.546,-3.265 18.196,-2.406 18.196,-1.316C18.196,0.154 19.535,2.215 22.213,4.868C22.544,5.2 22.805,5.46 22.995,5.649C25.696,8.304 27.473,10.578 28.326,12.475C29.179,14.37 29.605,16.56 29.605,19.049C29.605,24.594 27.893,28.965 24.469,32.163C21.046,35.361 16.36,36.962 10.413,36.962C7.877,36.962 5.479,36.66 3.216,36.056C0.953,35.45 -0.948,34.615 -2.488,33.549L0,19.83Z" style="fill:white;fill-rule:nonzero;"/>
</g>
<g transform="matrix(-166.599,4.57132,4.57132,166.599,147.403,167.648)">
<path d="M0.883,-0.081L0.121,0.081L0.256,-0.063L0.883,-0.081Z" style="fill:url(#_Linear1);fill-rule:nonzero;"/>
</g>
<g transform="matrix(-106.443,-16.0669,-16.0669,106.443,428.19,188.033)">
<path d="M0.878,-0.285L-0.073,0.71L-1.186,0.542L0.015,0.207L-0.846,0.077L0.355,-0.258L-0.505,-0.388L0.649,-0.71L0.878,-0.285Z" style="fill:url(#_Linear2);fill-rule:nonzero;"/>
</g>
<g transform="matrix(-114.484,-162.408,-162.408,114.484,333.291,285.804)">
<path d="M0.44,-0.04L0.44,-0.04L0.44,-0.04L0.265,-0.056L0.177,0.437L-0.311,-0.255L0.262,-0.437L0.568,-0.437L0.44,-0.04Z" style="fill:url(#_Linear3);fill-rule:nonzero;"/>
</g>
<g transform="matrix(61.6919,58.8091,58.8091,-61.6919,258.631,180.413)">
<path d="M0.5,0L0.5,-0L0.5,0L0.5,0Z" style="fill:url(#_Linear4);fill-rule:nonzero;"/>
</g>
<g transform="matrix(238.126,298.893,298.893,-238.126,113.516,-150.536)">
<path d="M0.622,-0.115L0.761,-0.115L0.806,-0.013L0.826,0.182L0.622,-0.115Z" style="fill:url(#_Linear5);fill-rule:nonzero;"/>
</g>
<g transform="matrix(-369.529,-97.4118,-97.4118,369.529,582.38,94.027)">
<path d="M0.467,0.005L0.49,0.062L0.271,-0.062L0.467,0.005Z" style="fill:url(#_Linear6);fill-rule:nonzero;"/>
</g>
<g transform="matrix(-496.156,-53.9751,-53.9751,496.156,367.888,125.085)">
<path d="M0.2,0.001L0.219,-0.018L0.614,0.012L0.519,0.089L0.282,0.068L0.2,0.135L0.463,0.194L0.374,0.266L0.138,0.186L0.138,0.186L0.138,0.186L0.047,0.033L-0.131,-0.266L0.2,0.001Z" style="fill:url(#_Linear7);fill-rule:nonzero;"/>
</g>
<g transform="matrix(185.076,176.427,176.427,-185.076,153.446,80.1488)">
<path d="M0.735,-0L0.735,-0L0.735,0L0.735,-0Z" style="fill:url(#_Linear8);fill-rule:nonzero;"/>
</g>
<defs>
<linearGradient id="_Linear1" x1="0" y1="0" x2="1" y2="0" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,-3.46945e-18,-3.46945e-18,-1,0,-3.05761e-06)"><stop offset="0" style="stop-color:rgb(227,50,50);stop-opacity:1"/><stop offset="1" style="stop-color:rgb(107,0,13);stop-opacity:1"/></linearGradient>
<linearGradient id="_Linear2" x1="0" y1="0" x2="1" y2="0" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,-1,0,-2.75467e-06)"><stop offset="0" style="stop-color:rgb(227,50,50);stop-opacity:1"/><stop offset="1" style="stop-color:rgb(107,0,13);stop-opacity:1"/></linearGradient>
<linearGradient id="_Linear3" x1="0" y1="0" x2="1" y2="0" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,-1.11022e-16,-1.11022e-16,-1,0,-2.61861e-06)"><stop offset="0" style="stop-color:rgb(227,50,50);stop-opacity:1"/><stop offset="1" style="stop-color:rgb(107,0,13);stop-opacity:1"/></linearGradient>
<linearGradient id="_Linear4" x1="0" y1="0" x2="1" y2="0" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,-5.55112e-17,-5.55112e-17,-1,0,-1.57562e-06)"><stop offset="0" style="stop-color:rgb(227,50,50);stop-opacity:1"/><stop offset="1" style="stop-color:rgb(107,0,13);stop-opacity:1"/></linearGradient>
<linearGradient id="_Linear5" x1="0" y1="0" x2="1" y2="0" gradientUnits="userSpaceOnUse" gradientTransform="matrix(-0.801899,-0.59746,-0.59746,0.801899,1.3495,0.447457)"><stop offset="0" style="stop-color:rgb(227,50,50);stop-opacity:1"/><stop offset="1" style="stop-color:rgb(107,0,13);stop-opacity:1"/></linearGradient>
<linearGradient id="_Linear6" x1="0" y1="0" x2="1" y2="0" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,-2.77556e-17,-2.77556e-17,-1,0,-1.92826e-06)"><stop offset="0" style="stop-color:rgb(227,50,50);stop-opacity:1"/><stop offset="1" style="stop-color:rgb(107,0,13);stop-opacity:1"/></linearGradient>
<linearGradient id="_Linear7" x1="0" y1="0" x2="1" y2="0" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,-1,0,9.68429e-07)"><stop offset="0" style="stop-color:rgb(227,50,50);stop-opacity:1"/><stop offset="1" style="stop-color:rgb(107,0,13);stop-opacity:1"/></linearGradient>
<linearGradient id="_Linear8" x1="0" y1="0" x2="1" y2="0" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,-1,0,1.43665e-07)"><stop offset="0" style="stop-color:rgb(227,50,50);stop-opacity:1"/><stop offset="1" style="stop-color:rgb(107,0,13);stop-opacity:1"/></linearGradient>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 6.9 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 5.4 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 5.4 KiB

View File

@ -0,0 +1,54 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg width="100%" height="100%" viewBox="0 0 551 436" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" xmlns:serif="http://www.serif.com/" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:2;">
<path d="M260.266,104.287L301.929,93.442L268.858,115.754L260.266,104.287Z" style="fill:rgb(235,235,235);"/>
<g transform="matrix(1,0,0,1,116.615,393.181)">
<path d="M0,-51.891L14.429,-51.891L13.043,-21.183L22.568,-51.891L34.226,-51.891L34.084,-21.183L42.365,-51.891L56.794,-51.891L38.526,0L25.198,0L25.34,-32.45L15.211,0L1.919,0L0,-51.891Z" style="fill:rgb(14,0,0);fill-rule:nonzero;"/>
</g>
<g transform="matrix(1,0,0,1,226.834,359.416)">
<path d="M0,15.639L5.793,15.639L5.971,-3.589L0,15.639ZM-20.187,33.765L-0.675,-18.126L16.42,-18.126L20.08,33.765L5.437,33.765L5.509,26.123L-3.057,26.123L-5.332,33.765L-20.187,33.765Z" style="fill:rgb(14,0,0);fill-rule:nonzero;"/>
</g>
<g transform="matrix(0.156272,-0.987714,-0.987714,-0.156272,327.042,382.506)">
<path d="M-16.046,33.107L36.491,33.107L38.757,18.784L-13.785,18.82L-16.046,33.107Z" style="fill:rgb(14,0,0);fill-rule:nonzero;"/>
</g>
<g transform="matrix(1,0,0,1,360.484,341.289)">
<path d="M0,51.891L8.246,0L22.781,0L16.597,39.024L27.224,39.024L25.199,51.891L0,51.891Z" style="fill:rgb(14,0,0);fill-rule:nonzero;"/>
</g>
<g transform="matrix(1,0,0,1,432.623,357.391)">
<path d="M0,19.83C1.611,21.181 3.305,22.224 5.083,22.959C6.859,23.693 8.565,24.06 10.2,24.06C11.645,24.06 12.794,23.663 13.647,22.87C14.5,22.076 14.927,20.992 14.927,19.617C14.927,18.434 14.571,17.254 13.861,16.081C13.15,14.908 11.775,13.351 9.738,11.408C7.273,9.015 5.58,6.906 4.655,5.081C3.731,3.257 3.27,1.243 3.27,-0.96C3.27,-5.912 4.839,-9.846 7.979,-12.76C11.118,-15.674 15.377,-17.132 20.756,-17.132C22.936,-17.132 25.008,-16.889 26.975,-16.403C28.941,-15.917 30.943,-15.165 32.982,-14.146L30.92,-1.493C29.356,-2.583 27.834,-3.412 26.354,-3.981C24.872,-4.551 23.457,-4.835 22.106,-4.835C20.898,-4.835 19.943,-4.521 19.245,-3.894C18.546,-3.265 18.196,-2.406 18.196,-1.316C18.196,0.154 19.535,2.215 22.213,4.868C22.544,5.2 22.805,5.46 22.995,5.649C25.696,8.304 27.473,10.578 28.326,12.475C29.179,14.37 29.605,16.56 29.605,19.049C29.605,24.594 27.893,28.965 24.469,32.163C21.046,35.361 16.36,36.962 10.413,36.962C7.877,36.962 5.479,36.66 3.216,36.056C0.953,35.45 -0.948,34.615 -2.488,33.549L0,19.83Z" style="fill:rgb(14,0,0);fill-rule:nonzero;"/>
</g>
<g transform="matrix(-166.599,4.57132,4.57132,166.599,147.403,167.648)">
<path d="M0.883,-0.081L0.121,0.081L0.256,-0.063L0.883,-0.081Z" style="fill:url(#_Linear1);fill-rule:nonzero;"/>
</g>
<g transform="matrix(-106.443,-16.0669,-16.0669,106.443,428.19,188.033)">
<path d="M0.878,-0.285L-0.073,0.71L-1.186,0.542L0.015,0.207L-0.846,0.077L0.355,-0.258L-0.505,-0.388L0.649,-0.71L0.878,-0.285Z" style="fill:url(#_Linear2);fill-rule:nonzero;"/>
</g>
<g transform="matrix(-114.484,-162.408,-162.408,114.484,333.291,285.804)">
<path d="M0.44,-0.04L0.44,-0.04L0.44,-0.04L0.265,-0.056L0.177,0.437L-0.311,-0.255L0.262,-0.437L0.568,-0.437L0.44,-0.04Z" style="fill:url(#_Linear3);fill-rule:nonzero;"/>
</g>
<g transform="matrix(61.6919,58.8091,58.8091,-61.6919,258.631,180.413)">
<path d="M0.5,0L0.5,-0L0.5,0L0.5,0Z" style="fill:url(#_Linear4);fill-rule:nonzero;"/>
</g>
<g transform="matrix(238.126,298.893,298.893,-238.126,113.516,-150.536)">
<path d="M0.622,-0.115L0.761,-0.115L0.806,-0.013L0.826,0.182L0.622,-0.115Z" style="fill:url(#_Linear5);fill-rule:nonzero;"/>
</g>
<g transform="matrix(-369.529,-97.4118,-97.4118,369.529,582.38,94.027)">
<path d="M0.467,0.005L0.49,0.062L0.271,-0.062L0.467,0.005Z" style="fill:url(#_Linear6);fill-rule:nonzero;"/>
</g>
<g transform="matrix(-496.156,-53.9751,-53.9751,496.156,367.888,125.085)">
<path d="M0.2,0.001L0.219,-0.018L0.614,0.012L0.519,0.089L0.282,0.068L0.2,0.135L0.463,0.194L0.374,0.266L0.138,0.186L0.138,0.186L0.138,0.186L0.047,0.033L-0.131,-0.266L0.2,0.001Z" style="fill:url(#_Linear7);fill-rule:nonzero;"/>
</g>
<g transform="matrix(185.076,176.427,176.427,-185.076,153.446,80.1488)">
<path d="M0.735,-0L0.735,-0L0.735,0L0.735,-0Z" style="fill:url(#_Linear8);fill-rule:nonzero;"/>
</g>
<defs>
<linearGradient id="_Linear1" x1="0" y1="0" x2="1" y2="0" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,-3.46945e-18,-3.46945e-18,-1,0,-3.05761e-06)"><stop offset="0" style="stop-color:rgb(227,50,50);stop-opacity:1"/><stop offset="1" style="stop-color:rgb(107,0,13);stop-opacity:1"/></linearGradient>
<linearGradient id="_Linear2" x1="0" y1="0" x2="1" y2="0" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,-1,0,-2.75467e-06)"><stop offset="0" style="stop-color:rgb(227,50,50);stop-opacity:1"/><stop offset="1" style="stop-color:rgb(107,0,13);stop-opacity:1"/></linearGradient>
<linearGradient id="_Linear3" x1="0" y1="0" x2="1" y2="0" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,-1.11022e-16,-1.11022e-16,-1,0,-2.61861e-06)"><stop offset="0" style="stop-color:rgb(227,50,50);stop-opacity:1"/><stop offset="1" style="stop-color:rgb(107,0,13);stop-opacity:1"/></linearGradient>
<linearGradient id="_Linear4" x1="0" y1="0" x2="1" y2="0" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,-5.55112e-17,-5.55112e-17,-1,0,-1.57562e-06)"><stop offset="0" style="stop-color:rgb(227,50,50);stop-opacity:1"/><stop offset="1" style="stop-color:rgb(107,0,13);stop-opacity:1"/></linearGradient>
<linearGradient id="_Linear5" x1="0" y1="0" x2="1" y2="0" gradientUnits="userSpaceOnUse" gradientTransform="matrix(-0.801899,-0.59746,-0.59746,0.801899,1.3495,0.447457)"><stop offset="0" style="stop-color:rgb(227,50,50);stop-opacity:1"/><stop offset="1" style="stop-color:rgb(107,0,13);stop-opacity:1"/></linearGradient>
<linearGradient id="_Linear6" x1="0" y1="0" x2="1" y2="0" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,-2.77556e-17,-2.77556e-17,-1,0,-1.92826e-06)"><stop offset="0" style="stop-color:rgb(227,50,50);stop-opacity:1"/><stop offset="1" style="stop-color:rgb(107,0,13);stop-opacity:1"/></linearGradient>
<linearGradient id="_Linear7" x1="0" y1="0" x2="1" y2="0" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,-1,0,9.68429e-07)"><stop offset="0" style="stop-color:rgb(227,50,50);stop-opacity:1"/><stop offset="1" style="stop-color:rgb(107,0,13);stop-opacity:1"/></linearGradient>
<linearGradient id="_Linear8" x1="0" y1="0" x2="1" y2="0" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,-1,0,1.43665e-07)"><stop offset="0" style="stop-color:rgb(227,50,50);stop-opacity:1"/><stop offset="1" style="stop-color:rgb(107,0,13);stop-opacity:1"/></linearGradient>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 6.9 KiB

View File

@ -0,0 +1,11 @@
import type { StarlightBlogUserConfig } from "starlight-blog";
type Authors = NonNullable<StarlightBlogUserConfig>["authors"];
export const authors: Authors = {
leaanthony: {
name: "Lea Anthony",
title: "Maintainer of Wails",
url: "https://github.com/leaanthony",
picture: "https://github.com/leaanthony.png",
},
};

View File

@ -0,0 +1,10 @@
import { defineCollection } from "astro:content";
import { docsSchema, i18nSchema } from "@astrojs/starlight/schema";
import { blogSchema } from "starlight-blog/schema";
export const collections = {
i18n: defineCollection({ type: "data", schema: i18nSchema() }),
docs: defineCollection({
schema: docsSchema({ extend: (context) => blogSchema(context) }),
}),
};

View File

@ -0,0 +1,193 @@
---
title: Application
sidebar:
order: 10
---
The application API assists in creating an application using the Wails
framework.
### New
API: `New(appOptions Options) *App`
`New(appOptions Options)` creates a new application using the given application
options . It applies default values for unspecified options, merges them with
the provided ones, initializes and returns an instance of the application.
In case of an error during initialization, the application is stopped with the
error message provided.
It should be noted that if a global application instance already exists, that
instance will be returned instead of creating a new one.
```go "main.go" {6-9}
package main
import "github.com/wailsapp/wails/v3/pkg/application"
func main() {
app := application.New(application.Options{
Name: "WebviewWindow Demo",
// Other options
})
// Rest of application
}
```
### Get
`Get()` returns the global application instance. It's useful when you need to
access the application from different parts of your code.
```go
// Get the application instance
app := application.Get()
```
### Capabilities
API: `Capabilities() capabilities.Capabilities`
`Capabilities()` retrieves a map of capabilities that the application currently
has. Capabilities can be about different features the operating system provides,
like webview features.
```go
// Get the application capabilities
capabilities := app.Capabilities()
if capabilities.HasNativeDrag {
// Do something
}
```
### GetPID
API: `GetPID() int`
`GetPID()` returns the Process ID of the application.
```go
pid := app.GetPID()
```
### Run
API: `Run() error`
`Run()` starts the execution of the application and its components.
```go
app := application.New(application.Options{
//options
})
// Run the application
err := app.Run()
if err != nil {
// Handle error
}
```
### Quit
API: `Quit()`
`Quit()` quits the application by destroying windows and potentially other
components.
```go
// Quit the application
app.Quit()
```
### IsDarkMode
API: `IsDarkMode() bool`
`IsDarkMode()` checks if the application is running in dark mode. It returns a
boolean indicating whether dark mode is enabled.
```go
// Check if dark mode is enabled
if app.IsDarkMode() {
// Do something
}
```
### Hide
API: `Hide()`
`Hide()` hides the application window.
```go
// Hide the application window
app.Hide()
```
### Show
API: `Show()`
`Show()` shows the application window.
```go
// Show the application window
app.Show()
```
### Path
API: `Path(selector Path) string`
`Path(selector Path)` returns the full path for the given path type. It provides
a cross-platform way to query common application directories.
The `Path` type is an enum with the following values:
- `PathHome`: Returns the user's home directory
- `PathDataHome`: Returns the path to the user's data directory
- `PathConfigHome`: Returns the path to the user's configuration directory
- `PathStateHome`: Returns the path to the user's state directory
- `PathCacheHome`: Returns the path to the user's cache directory
- `PathRuntimeDir`: Returns the path to the user's runtime directory
- `PathDesktop`: Returns the path to the user's desktop directory
- `PathDownload`: Returns the path to the user's download directory
- `PathDocuments`: Returns the path to the user's documents directory
- `PathMusic`: Returns the path to the user's music directory
- `PathPictures`: Returns the path to the user's pictures directory
- `PathVideos`: Returns the path to the user's videos directory
- `PathTemplates`: Returns the path to the user's templates directory
- `PathPublicShare`: Returns the path to the user's public share directory
```go
// Get the data home directory path
dataHomePath := app.Path(application.PathDataHome)
fmt.Println("DataHome path:", dataHomePath)
// Output: DataHome path: /home/username/.local/share // Linux
// Output: DataHome path: /Users/username/Library/Application Support // macOS
// Output: DataHome path: C:\Users\Username\AppData\Roaming // Windows
// Get the CacheHome directory path
cacheHomePath := app.Path(application.PathCacheHome)
fmt.Println("CacheHome path:", cacheHomePath)
// Output: CacheHome path: /home/username/.cache // Linux
// Output: CacheHome path: /Users/username/Library/Caches // macOS
// Output: CacheHome path: C:\Users\Username\AppData\Local\Temp // Windows
```
## Paths
API: `Paths(selector Paths) []string` `Paths(selector Path)` returns a list of
paths for the given path type. It provides a cross-platform way to query common
directory paths.
The `Paths` type is an enum with the following values:
- `PathsDataDirs`: Returns the list of data directories
- `PathsConfigDirs`: Returns the list of configuration directories
- `PathsCacheDirs`: Returns the list of cache directories
- `PathsRuntimeDirs`: Returns the list of runtime directories

View File

@ -0,0 +1,107 @@
---
title: Application Dialogs
sidebar:
order: 40
---
:::caution[MacOS Dialogs and Application Lifecycle]
If you show dialogs during application startup or file open events, you should
set `ApplicationShouldTerminateAfterLastWindowClosed` to `false` to prevent the
application from terminating when those dialogs close. Otherwise, the
application may quit before your main window appears.
```go
app := application.New(application.Options{
Mac: application.MacOptions{
ApplicationShouldTerminateAfterLastWindowClosed: false,
},
// ... rest of options
})
```
Alternatively, you can show startup dialogs after the main window has been
displayed:
```go
var filename string
app.OnApplicationEvent(events.Common.ApplicationOpenedWithFile, func(event *application.ApplicationEvent) {
filename = event.Context().Filename()
})
window.OnWindowEvent(events.Common.WindowShow, func(event *application.WindowEvent) {
application.InfoDialog().
SetTitle("File Opened").
SetMessage("Application opened with file: " + filename).
Show()
})
```
:::
### ShowAboutDialog
API: `ShowAboutDialog()`
`ShowAboutDialog()` shows an "About" dialog box. It can show the application's
name, description and icon.
```go
// Show the about dialog
app.ShowAboutDialog()
```
### Info
API: `InfoDialog()`
`InfoDialog()` creates and returns a new instance of `MessageDialog` with an
`InfoDialogType`. This dialog is typically used to display informational
messages to the user.
### Question
API: `QuestionDialog()`
`QuestionDialog()` creates and returns a new instance of `MessageDialog` with a
`QuestionDialogType`. This dialog is often used to ask a question to the user
and expect a response.
### Warning
API: `WarningDialog()`
`WarningDialog()` creates and returns a new instance of `MessageDialog` with a
`WarningDialogType`. As the name suggests, this dialog is primarily used to
display warning messages to the user.
### Error
API: `ErrorDialog()`
`ErrorDialog()` creates and returns a new instance of `MessageDialog` with an
`ErrorDialogType`. This dialog is designed to be used when you need to display
an error message to the user.
### OpenFile
API: `OpenFileDialog()`
`OpenFileDialog()` creates and returns a new `OpenFileDialogStruct`. This dialog
prompts the user to select one or more files from their file system.
### SaveFile
API: `SaveFileDialog()`
`SaveFileDialog()` creates and returns a new `SaveFileDialogStruct`. This dialog
prompts the user to choose a location on their file system where a file should
be saved.
### OpenDirectory
API: `OpenDirectoryDialog()`
`OpenDirectoryDialog()` creates and returns a new instance of `MessageDialog`
with an `OpenDirectoryDialogType`. This dialog enables the user to choose a
directory from their file system.

View File

@ -0,0 +1,60 @@
---
title: Application Events
sidebar:
order: 50
---
### OnEvent
API: `OnEvent(name string, callback func(event *CustomEvent)) func()`
`OnEvent()` registers an event listener for specific application events. The
callback function provided will be triggered when the corresponding event
occurs.
### OffEvent
API: `OffEvent(name string)`
`OffEvent()` removes an event listener for a specific named event specified.
### OnMultipleEvent
API:
`OnMultipleEvent(name string, callback func(event *CustomEvent), counter int) func()`
`OnMultipleEvent()` registers an event listener for X number of Events. The
callback function provided will be triggered `counter` times when the
corresponding event occurs.
### ResetEvents
API: `ResetEvents()`
`ResetEvents()` removes all event listeners for all application events.
### OnApplicationEvent
API:
`OnApplicationEvent(eventType events.ApplicationEventType, callback func(event *ApplicationEvent)) func()`
`OnApplicationEvent()` registers an event listener for specific application
events. The `eventType` is based on events.ApplicationEventType. See
[ApplicationEventType](/api/event_types/#applicationevent)
### RegisterApplicationHook
API:
`RegisterApplicationEventHook(eventType events.ApplicationEventType, callback func(event *ApplicationEvent)) func()`
`RegisterApplicationEventHook()` registers a callback to be triggered based on
specific application events.
### RegisterHook
API:
`RegisterHook(eventType events.ApplicationEventType, callback func(event *Event)) func()`
`RegisterHook()` registers a callback to be run as a hook during specific
events. These hooks are run before listeners attached with `On()`. The function
returns a function that can be called to remove the hook.

View File

@ -0,0 +1,36 @@
---
title: Application Menu
sidebar:
order: 30
---
### RegisterContextMenu
API: `RegisterContextMenu(name string, menu *Menu)`
`RegisterContextMenu()` registers a context menu with a given name. This menu
can be used later in the application.
```go
// Create a new menu
ctxmenu := app.NewMenu()
// Register the menu as a context menu
app.RegisterContextMenu("MyContextMenu", ctxmenu)
```
### SetMenu
API: `SetMenu(menu *Menu)`
`SetMenu()` sets the menu for the application. On Mac, this will be the global
menu. For Windows and Linux, this will be the default menu for any new window
created.
```go
// Create a new menu
menu := app.NewMenu()
// Set the menu for the application
app.SetMenu(menu)
```

View File

@ -0,0 +1,14 @@
---
title: Application Options
sidebar:
order: 70
---
import { Code } from "@astrojs/starlight/components";
import application_options from "../../../../../v3/pkg/application/application_options.go?raw";
<Code
code={application_options}
lang="go"
title="pkg/application/application_options.go"
/>

View File

@ -0,0 +1,21 @@
---
title: Application Screens
sidebar:
order: 60
---
### GetPrimaryScreen
API: `GetPrimaryScreen() (*Screen, error)`
`GetPrimaryScreen()` returns the primary screen of the system.
### GetScreens
API: `GetScreens() ([]*Screen, error)`
`GetScreens()` returns information about all screens attached to the system.
This is a brief summary of the exported methods in the provided `App` struct. Do
note that for more detailed functionality or considerations, refer to the actual
Go code or further internal documentation.

View File

@ -0,0 +1,73 @@
---
title: Application Window
sidebar:
order: 20
---
### NewWebviewWindow
API: `NewWebviewWindow() *WebviewWindow`
`NewWebviewWindow()` creates a new Webview window with default options, and
returns it.
```go
// Create a new webview window
window := app.NewWebviewWindow()
```
### NewWebviewWindowWithOptions
API:
`NewWebviewWindowWithOptions(windowOptions WebviewWindowOptions) *WebviewWindow`
`NewWebviewWindowWithOptions()` creates a new webview window with custom
options. The newly created window is added to a map of windows managed by the
application.
```go
// Create a new webview window with custom options
window := app.NewWebviewWindowWithOptions(WebviewWindowOptions{
Name: "Main",
Title: "My Window",
Width: 800,
Height: 600,
})
```
### OnWindowCreation
API: `OnWindowCreation(callback func(window *WebviewWindow))`
`OnWindowCreation()` registers a callback function to be called when a window is
created.
```go
// Register a callback to be called when a window is created
app.OnWindowCreation(func(window *WebviewWindow) {
// Do something
})
```
### GetWindowByName
API: `GetWindowByName(name string) *WebviewWindow`
`GetWindowByName()` fetches and returns a window with a specific name.
```go
// Get a window by name
window := app.GetWindowByName("Main")
```
### CurrentWindow
API: `CurrentWindow() *WebviewWindow`
`CurrentWindow()` fetches and returns a pointer to the currently active window
in the application. If there is no window, it returns nil.
```go
// Get the current window
window := app.CurrentWindow()
```

View File

@ -0,0 +1,152 @@
---
title: Event Hooks
tableOfContents:
maxHeadingLevel: 4
sidebar:
order: 90
---
wails3 provides an event system that allows for hooking into application and
window events
```go
// Notification of application start
application.RegisterApplicationEventHook(events.Common.ApplicationStarted, func(event *application.ApplicationEvent) {
app.Logger.Info("Application started!")
})
```
```go
// Notification of system theme change
application.OnApplicationEvent(events.Common.ThemeChanged, func(event *application.ApplicationEvent) {
app.Logger.Info("System theme changed!")
if event.Context().IsDarkMode() {
app.Logger.Info("System is now using dark mode!")
} else {
app.Logger.Info("System is now using light mode!")
}
})
```
```go
// Disable window closing by canceling the event
window.RegisterHook(events.Common.WindowClosing, func(e *application.WindowEvent) {
app.Logger.Info("Window 1 Closing? Nope! Not closing!")
e.Cancel()
})
```
```go
// Notification of window focus
window.OnWindowEvent(events.Common.WindowFocus, func(e *application.WindowEvent) {
app.Logger.Info("[ApplicationEvent] Window focus!")
})
```
### Application Events
Application events are hookable events that can be registered with
`application.RegisterApplicationEventHook()` and
`application.OnApplicationEvent()`.
These events are based on `events.ApplicationEventType`.
#### `events.Common.ApplicationStarted`
Triggered when the application starts
#### `events.Common.ThemeChanged`
Triggered when the application theme changes
### Window Events
#### `events.Common.WindowMaximised`
Triggered when the window is maximised
#### `events.Common.WindowUnmaximised`
Triggered when the window is unmaximised
#### `events.Common.WindowMinimised`
Triggered when the window is minimised
#### `events.Common.WindowUnminimised`
Triggered when the window is unminimised
#### `events.Common.WindowFullscreen`
Triggered when the window is set to fullscreen
#### `events.Common.WindowUnfullscreen`
Triggered when the window is unfullscreened
#### `events.Common.WindowRestored`
Triggered when the window is restored
#### `events.Common.WindowClosing`
Triggered before the window closes
#### `events.Common.WindowZoom`
Triggered when the window is zoomed
#### `events.Common.WindowZoomOut`
Triggered when the window is zoomed out
#### `events.Common.WindowZoomIn`
Triggered when the window is zoomed in
#### `events.Common.WindowZoomReset`
Triggered when the window zoom is reset
#### `events.Common.WindowFocus`
Triggered when the window gains focus
#### `events.Common.WindowLostFocus`
Triggered when the window loses focus
#### `events.Common.WindowShow`
Triggered when the window is shown
#### `events.Common.WindowHide`
Triggered when the window is hidden
#### `events.Common.WindowDPIChanged`
Triggered when the window DPI changes
#### `events.Common.WindowFilesDropped`
Triggered when files are dropped on the window
#### `events.Common.WindowRuntimeReady`
Triggered when the window runtime is ready
#### `events.Common.WindowDidMove`
Triggered when the window is moved
#### `events.Common.WindowDidResize`
Triggered when the window is resized
### OS Specific Events
- [Mac Events](/api/events_mac)
- [Windows Events](/api/events_windows)
- [Linux Events](/api/events_linux)

View File

@ -0,0 +1,55 @@
---
title: Event Types
sidebar:
order: 140
---
### ApplicationEvent
Returned when an application hook event is triggered. The event can be cancelled
by calling the `Cancel()` method on the event.
```go
type ApplicationEvent struct {
Id uint
ctx *ApplicationEventContext
Cancelled bool
}
// Cancel the event
func (a *ApplicationEvent) Cancel() {}
```
### WindowEvent
Returned when a window hook event is triggered. The event can be cancelled by
calling the `Cancel()` method on the event.
```go
type WindowEvent struct {
ctx *WindowEventContext
Cancelled bool
}
// Cancel the event
func (w *WindowEvent) Cancel() {}
```
### CustomEvent
CustomEvent is returned when an event is being received it includes the name of
the event, the data that was sent with the event, the sender of the event,
application or a specific window. The event can be cancelled by calling the
`Cancel()` method on the event.
```go
type CustomEvent struct {
Name string `json:"name"`
Data any `json:"data"`
Sender string `json:"sender"`
Cancelled bool
}
// Cancel the event
func (c *CustomEvent) Cancel() {}
```

View File

@ -0,0 +1,147 @@
---
title: Events (Custom)
tableOfContents:
maxHeadingLevel: 4
sidebar:
order: 130
---
import { Tabs, TabItem } from "@astrojs/starlight/components";
## Custom Events
You can create your own custom events that can be emitted and received on both
the frontend and backend. Events are able to emitted at both the application and
the window level. The receiver of the event gets data of where the event was
emitted from along with the data that was sent with the event. Events can be
cancelled by the receiver.
<Tabs syncKey="language">
<TabItem label="Go" icon="seti:go">
```go
app.OnEvent("event1", func(e \*application.CustomEvent) {
app.Logger.Info("[Go] CustomEvent received", "name", e.Name, "data", e.Data,
"sender", e.Sender, "cancelled", e.Cancelled) app.Logger.Info("[Go]",
e.Data[0].(string)) // Logs "Hello from JS" to the terminal })
window.EmitEvent("event2", "Hello from Go")
}
```
</TabItem>
<TabItem label="JS" icon="seti:javascript">
```js
wails.Events.Emit("event1", "Hello from JS");
wails.Events.On("event2", function (event) {
console.log("[JS] CustomEvent received", event);
console.log(event.data); // prints "Hello from Go" to the webview console
});
```
</TabItem>
</Tabs>
### Emitting Events
<Tabs syncKey="language">
<TabItem label="Go" icon="seti:go">
#### `application.EmitEvent(name string, data ...any)`
Emits an event from the application instance
</TabItem>
<TabItem label="JS" icon="seti:javascript">
#### `window.EmitEvent(name string, data ...any)`
Emits an event from the window instance
#### `wails.Events.Emit(event:wails.Events.EventData)`
Emits an event from the frontend sending an object with `name` and `data`
properties or the typescript type WailsEvent
</TabItem>
</Tabs>
### Receiving Events
Events can be received on the application instance and the frontend with a
couple options of how you chose to receive them. You can register a single event
listener that will trigger every time the event is emitted or you can register
an event listener that will only trigger a specific number of times.
<Tabs syncKey="language">
<TabItem label="Go" icon="seti:go">
#### `application.OnEvent(name string, handler func(data ...any))`
Registers an event on the application instance this will trigger every time the
event is emitted
#### `application.OnMultipleEvent(name string, handler func(data ...any), count int)`
Registers an event on the application instance this will trigger every time the
event is emitted up to the count specified
</TabItem>
<TabItem label="JS" icon="seti:javascript">
#### `wails.Events.On(name: string, callback: ()=>void)`,
Registers an event on the frontend, this function returns a function that can be
called to remove the event listener
#### `wails.Events.Once(name: string, callback: ()=>void)`,
Registers an event on the frontend that will only be called once, this function
returns a function that can be called to remove the event listener
#### `wails.Events.OnMultiple(name: string, callback: ()=>void, count: number)`,
Registers an event on the frontend that will only be called `count` times, this
function returns a function that can be called to remove the event listener
</TabItem>
</Tabs>
### Removing Events
There are a few ways to remove events that are registered. All of the
registration functions return a function that can be called to remove the event
listener in the frontend. There are additional functions provided to help remove
events as well.
<Tabs syncKey="language">
<TabItem label="Go" icon="seti:go">
#### `application.OffEvent(name string, ...additionalNames string)`
Removes an event listener with the specified name
#### `application.ResetEvents()`
Removes all registered events and hooks
</TabItem>
<TabItem label="JS" icon="seti:javascript">
#### `wails.Events.OffAll()`
Removes all registered events
#### `wails.Events.Off(name: string)`
Removes an event listener with the specified name
</TabItem>
</Tabs>

View File

@ -0,0 +1,43 @@
---
title: Events (Linux)
tableOfContents:
maxHeadingLevel: 4
sidebar:
order: 120
---
## Application Events
#### `events.Linux.ApplicationStartup`
Triggered when the application starts
#### `events.Linux.SystemThemeChanged`
Triggered when the system theme changes
### Window Events
#### `events.Linux.WindowLoadChanged`
Triggered when the window load changes
#### `events.Linux.WindowDeleteEvent`
Triggered when the window is deleted
#### `events.Linux.WindowDidMove`
Triggered when the window is moved
#### `events.Linux.WindowDidResize`
Triggered when the window is resized
#### `events.Linux.WindowFocusIn`
Triggered when the window gains focus
#### `events.Linux.WindowFocusOut`
Triggered when the window loses focus

View File

@ -0,0 +1,500 @@
---
title: Events (macOS)
tableOfContents:
maxHeadingLevel: 4
sidebar:
order: 100
---
## Application Events
#### `events.Mac.ApplicationDidBecomeActive`
Triggered when the application becomes active
#### `events.Mac.ApplicationDidChangeBackingProperties`
Triggered when the application changes backing properties
#### `events.Mac.ApplicationDidChangeEffectiveAppearance`
Triggered when the application changes effective appearance
#### `events.Mac.ApplicationDidChangeIcon`
Triggered when the application changes icon
#### `events.Mac.ApplicationDidChangeOcclusionState`
Triggered when the application changes occlusion state
#### `events.Mac.ApplicationDidChangeScreenParameters`
Triggered when the application changes screen parameters
#### `events.Mac.ApplicationDidChangeStatusBarFrame`
Triggered when the application changes status bar frame
#### `events.Mac.ApplicationDidChangeStatusBarOrientation`
Triggered when the application changes status bar orientation
#### `events.Mac.ApplicationDidFinishLaunching`
Triggered when the application finishes launching
#### `events.Mac.ApplicationDidResignActiveNotification`
Triggered when the application is no longer active
#### `events.Mac.ApplicationDidHide`
Triggered when the application is hidden
#### `events.Mac.ApplicationDidUpdate`
Triggered when the application updates
#### `events.Mac.ApplicationWillBecomeActive`
Triggered when the application is about to become active
#### `events.Mac.ApplicationWillFinishLaunching`
Triggered when the application is about to finish launching
#### `events.Mac.ApplicationWillHide`
Triggered when the application is about to hide
#### `events.Mac.ApplicationWillResignActive`
Triggered when the application is about to lose focus
#### `events.Mac.ApplicationWillTerminate`
Triggered when the application is about to terminate
#### `events.Mac.ApplicationWillUnhide`
Triggered when the application is about to unhide
#### `events.Mac.ApplicationWillUpdate`
Triggered when the application is about to update
#### `events.Mac.ApplicationDidChangeTheme`
Triggered when the application changes theme
#### `events.Mac.MenuWillOpen`
Triggered when the menu is about to open
#### `events.Mac.MenuDidOpen`
Triggered when the menu opens
#### `events.Mac.MenuDidClose`
Triggered when the menu closes
#### `events.Mac.MenuWillSendAction`
Triggered when the menu is about to send an action
#### `events.Mac.MenuDidSendAction`
Triggered when the menu sends an action
#### `events.Mac.MenuWillHighlightItem`
Triggered when the menu is about to highlight an item
#### `events.Mac.MenuDidHighlightItem`
Triggered when the menu highlights an item
#### `events.Mac.MenuWillDisplayItem`
Triggered when the menu is about to display an item
#### `events.Mac.MenuDidDisplayItem`
Triggered when the menu displays an item
#### `events.Mac.MenuWillAddItem`
Triggered when the menu is about to add an item
#### `events.Mac.MenuDidAddItem`
Triggered when the menu adds an item
#### `events.Mac.MenuWillRemoveItem`
Triggered when the menu is about to remove an item
#### `events.Mac.MenuDidRemoveItem`
Triggered when the menu removes an item
#### `events.Mac.MenuWillBeginTracking`
Triggered when the menu is about to begin tracking
#### `events.Mac.MenuDidBeginTracking`
Triggered when the menu begins tracking
#### `events.Mac.MenuWillEndTracking`
Triggered when the menu is about to end tracking
#### `events.Mac.MenuDidEndTracking`
Triggered when the menu ends tracking
#### `events.Mac.MenuWillUpdate`
Triggered when the menu is about to update
#### `events.Mac.MenuDidUpdate`
Triggered when the menu updates
#### `events.Mac.MenuWillPopUp`
Triggered when the menu is about to pop up
#### `events.Mac.MenuDidPopUp`
Triggered when the menu pops up
#### `events.Mac.MenuWillSendActionToItem`
Triggered when the menu is about to send an action to an item
#### `events.Mac.MenuDidSendActionToItem`
Triggered when the menu sends an action to an item
##### Window Events
#### `events.Mac.WindowDidBecomeKey`
Triggered when the window becomes key
#### `events.Mac.WindowDidBecomeMain`
Triggered when the window becomes main
#### `events.Mac.WindowDidBeginSheet`
Triggered when the window begins a sheet
#### `events.Mac.WindowDidChangeAlpha`
Triggered when the window alpha changes
#### `events.Mac.WindowDidChangeBackingLocation`
Triggered when the window backing location changes
#### `events.Mac.WindowDidChangeBackingProperties`
Triggered when the window backing properties change
#### `events.Mac.WindowDidChangeCollectionBehavior`
Triggered when the window collection behavior changes
#### `events.Mac.WindowDidChangeEffectiveAppearance`
Triggered when the window effective appearance changes
#### `events.Mac.WindowDidChangeOcclusionState`
Triggered when the window occlusion state changes
#### `events.Mac.WindowDidChangeOrderingMode`
Triggered when the window ordering mode changes
#### `events.Mac.WindowDidChangeScreen`
Triggered when the window screen changes
#### `events.Mac.WindowDidChangeScreenParameters`
Triggered when the window screen parameters change
#### `events.Mac.WindowDidChangeScreenProfile`
Triggered when the window screen profile changes
#### `events.Mac.WindowDidChangeScreenSpace`
Triggered when the window screen space changes
#### `events.Mac.WindowDidChangeScreenSpaceProperties`
Triggered when the window screen space properties change
#### `events.Mac.WindowDidChangeSharingType`
Triggered when the window sharing type changes
#### `events.Mac.WindowDidChangeSpace`
Triggered when the window space changes
#### `events.Mac.WindowDidChangeSpaceOrderingMode`
Triggered when the window space ordering mode changes
#### `events.Mac.WindowDidChangeTitle`
Triggered when the window title changes
#### `events.Mac.WindowDidChangeToolbar`
Triggered when the window toolbar changes
#### `events.Mac.WindowDidChangeVisibility`
Triggered when the window visibility changes
#### `events.Mac.WindowDidDeminiaturize`
Triggered when the window is deminiaturized
#### `events.Mac.WindowDidEndSheet`
Triggered when the window ends a sheet
#### `events.Mac.WindowDidEnterFullScreen`
Triggered when the window enters fullscreen
#### `events.Mac.WindowDidEnterVersionBrowser`
Triggered when the window enters version browser
#### `events.Mac.WindowDidExitFullScreen`
Triggered when the window exits fullscreen
#### `events.Mac.WindowDidExitVersionBrowser`
Triggered when the window exits version browser
#### `events.Mac.WindowDidExpose`
Triggered when the window is exposed
#### `events.Mac.WindowDidFocus`
Triggered when the window is focused
#### `events.Mac.WindowDidMiniaturize`
Triggered when the window is miniaturized
#### `events.Mac.WindowDidMove`
Triggered when the window is moved
#### `events.Mac.WindowDidOrderOffScreen`
Triggered when the window is ordered off-screen
#### `events.Mac.WindowDidOrderOnScreen`
Triggered when the window is ordered on screen
#### `events.Mac.WindowDidResignKey`
Triggered when the window resigns key
#### `events.Mac.WindowDidResignMain`
Triggered when the window resigns main
#### `events.Mac.WindowDidResize`
Triggered when the window is resized
#### `events.Mac.WindowDidUpdate`
Triggered when the window updates
#### `events.Mac.WindowDidUpdateAlpha`
Triggered when the window alpha updates
#### `events.Mac.WindowDidUpdateCollectionBehavior`
Triggered when the window collection behavior updates
#### `events.Mac.WindowDidUpdateCollectionProperties`
Triggered when the window collection properties update
#### `events.Mac.WindowDidUpdateShadow`
Triggered when the window shadow updates
#### `events.Mac.WindowDidUpdateTitle`
Triggered when the window title updates
#### `events.Mac.WindowDidUpdateToolbar`
Triggered when the window toolbar updates
#### `events.Mac.WindowDidUpdateVisibility`
Triggered when the window visibility updates
#### `events.Mac.WindowShouldClose`
Triggered when the window should close
#### `events.Mac.WindowWillBecomeKey`
Triggered when the window will become key
#### `events.Mac.WindowWillBecomeMain`
Triggered when the window will become main
#### `events.Mac.WindowWillBeginSheet`
Triggered when the window will begin a sheet
#### `events.Mac.WindowWillChangeOrderingMode`
Triggered when the window will change ordering mode
#### `events.Mac.WindowWillClose`
Triggered when the window will close
#### `events.Mac.WindowWillDeminiaturize`
Triggered when the window will deminiaturize
#### `events.Mac.WindowWillEnterFullScreen`
Triggered when the window will enter fullscreen
#### `events.Mac.WindowWillEnterVersionBrowser`
Triggered when the window will enter version browser
#### `events.Mac.WindowWillExitFullScreen`
Triggered when the window will exit fullscreen
#### `events.Mac.WindowWillExitVersionBrowser`
Triggered when the window will exit version browser
#### `events.Mac.WindowWillFocus`
Triggered when the window will focus
#### `events.Mac.WindowWillMiniaturize`
Triggered when the window will miniaturize
#### `events.Mac.WindowWillMove`
Triggered when the window will move
#### `events.Mac.WindowWillOrderOffScreen`
Triggered when the window will order off-screen
#### `events.Mac.WindowWillOrderOnScreen`
Triggered when the window will order on screen
#### `events.Mac.WindowWillResignMain`
Triggered when the window will resign main
#### `events.Mac.WindowWillResize`
Triggered when the window will resize
#### `events.Mac.WindowWillUnfocus`
Triggered when the window will unfocus
#### `events.Mac.WindowWillUpdate`
Triggered when the window will update
#### `events.Mac.WindowWillUpdateAlpha`
Triggered when the window will update alpha
#### `events.Mac.WindowWillUpdateCollectionBehavior`
Triggered when the window will update collection behavior
#### `events.Mac.WindowWillUpdateCollectionProperties`
Triggered when the window will update collection properties
#### `events.Mac.WindowWillUpdateShadow`
Triggered when the window will update shadow
#### `events.Mac.WindowWillUpdateTitle`
Triggered when the window will update title
#### `events.Mac.WindowWillUpdateToolbar`
Triggered when the window will update toolbar
#### `events.Mac.WindowWillUpdateVisibility`
Triggered when the window will update visibility
#### `events.Mac.WindowWillUseStandardFrame`
Triggered when the window will use standard frame
#### `events.Mac.WebviewDidStartProvisionalNavigation`
Triggered when the webview starts a provisional navigation
#### `events.Mac.WebviewDidReceiveServerRedirectForProvisionalNavigation`
Triggered when the webview receives a server redirect for a provisional
navigation
#### `events.Mac.WebviewDidFinishNavigation`
Triggered when the webview finishes navigation
#### `events.Mac.WebviewDidCommitNavigation`
Triggered when the webview commits navigation
#### `events.Mac.WindowFileDraggingEntered`
Triggered when files are dragged into the window
#### `events.Mac.WindowFileDraggingPerformed`
Triggered when files are dragged in the window
#### `events.Mac.WindowFileDraggingExited`
Triggered when files are dragged out of the window

View File

@ -0,0 +1,112 @@
---
title: Events (Windows)
tableOfContents:
maxHeadingLevel: 4
sidebar:
order: 110
---
## Application Events
#### `events.Windows.ApplicationStarted`
Triggered when the application starts
#### `events.Windows.SystemThemeChanged`
Triggered when the system theme changes
#### `events.Windows.APMPowerStatusChange`
Triggered when the system power status changes
#### `events.Windows.APMSuspend`
Triggered when the system suspends
#### `events.Windows.APMResumeAutomatic`
Triggered when the system resumes after a sleep
#### `events.Windows.APMResumeSuspend`
Triggered when the system resumes after a suspend and resume was triggered by
the user
## Window Events
#### `events.Windows.WebviewNavigationCompleted`
Triggered when the webview navigation is completed
#### `events.Windows.WindowInactive`
Triggered when the window is inactive
#### `events.Windows.WindowActive`
Triggered when the window is active
#### `events.Windows.ClickActive`
Triggered when the window is activated via a click
#### `events.Windows.MaximiseActive`
Triggered when the window is maximised
#### `events.Windows.UnMaximise`
Triggered when the window is unmaximised
#### `events.Windows.Fullscreen`
Triggered when the window is set to fullscreen
#### `events.Windows.UnFullscreen`
Triggered when the window exits fullscreen mode
#### `events.Windows.WindowRestore`
Triggered when the window is restored
#### `events.Windows.WindowMinimise`
Triggered when the window is minimised
#### `events.Windows.WindowUnminimise`
Triggered when the window is minimised
#### `events.Windows.WindowClose`
Triggered before the window closes
#### `events.Windows.WindowSetFocus`
Triggered when the window gains keyboard focus
#### `events.Windows.WindowKillFocus`
Triggered when the window loses keyboard focus
#### `events.Windows.WindowDragDrop`
Triggered when files are dropped on the window
#### `events.Windows.WindowDragEnter`
Triggered when a drag enters the window
#### `events.Windows.WindowDragLeave`
Triggered when a drag leaves the window
#### `events.Windows.WindowDragOver`
Triggered when a drag is over the window
#### `events.Windows.WindowDidMove`
Triggered after a window has moved

View File

@ -0,0 +1,58 @@
---
title: Main Thread Functions
sidebar:
order: 170
---
These methods are utility functions to run code on the main thread. This is
required when you want to run custom code on the UI thread.
### InvokeSync
API: `InvokeSync(fn func())`
This function runs the passed function (`fn`) synchronously. It uses a WaitGroup
(`wg`) to ensure that the main thread waits for the `fn` function to finish
before it continues. If a panic occurs inside `fn`, it will be passed to the
handler function `PanicHandler`, defined in the application options.
### InvokeSyncWithResult
API: `InvokeSyncWithResult[T any](fn func() T) (res T)`
This function works similarly to `InvokeSync(fn func())`, however, it yields a
result. Use this for calling any function with a single return.
### InvokeSyncWithError
API: `InvokeSyncWithError(fn func() error) (err error)`
This function runs `fn` synchronously and returns any error that `fn` produces.
Note that this function will recover from a panic if one occurs during `fn`'s
execution.
### InvokeSyncWithResultAndError
API:
`InvokeSyncWithResultAndError[T any](fn func() (T, error)) (res T, err error)`
This function runs `fn` synchronously and returns both a result of type `T` and
an error.
### InvokeAsync
API: `InvokeAsync(fn func())`
This function runs `fn` asynchronously. It runs the given function on the main
thread. If a panic occurs inside `fn`, it will be passed to the handler function
`PanicHandler`, defined in the application options.
---
:::tip
These functions will block execution until `fn` has finished. It's critical to
ensure that `fn` doesn't block. If you need to run a function that blocks, use
`InvokeAsync` instead.
:::

View File

@ -0,0 +1,73 @@
---
title: Menu
sidebar:
order: 160
---
Menus can be created and added to the application. They can be used to create
context menus, system tray menus and application menus.
To create a new menu, call:
```go
// Create a new menu
menu := app.NewMenu()
```
The following operations are then available on the `Menu` type:
### Add
API: `Add(label string) *MenuItem`
This method takes a `label` of type `string` as an input and adds a new
`MenuItem` with the given label to the menu. It returns the `MenuItem` added.
### AddSeparator
API: `AddSeparator()`
This method adds a new separator `MenuItem` to the menu.
### AddCheckbox
API: `AddCheckbox(label string, enabled bool) *MenuItem`
This method takes a `label` of type `string` and `enabled` of type `bool` as
inputs and adds a new checkbox `MenuItem` with the given label and enabled state
to the menu. It returns the `MenuItem` added.
### AddRadio
API: `AddRadio(label string, enabled bool) *MenuItem`
This method takes a `label` of type `string` and `enabled` of type `bool` as
inputs and adds a new radio `MenuItem` with the given label and enabled state to
the menu. It returns the `MenuItem` added.
### Update
API: `Update()`
This method processes any radio groups and updates the menu if a menu
implementation is not initialized.
### AddSubmenu
API: `AddSubmenu(s string) *Menu`
This method takes a `s` of type `string` as input and adds a new submenu
`MenuItem` with the given label to the menu. It returns the submenu added.
### AddRole
API: `AddRole(role Role) *Menu`
This method takes `role` of type `Role` as input, adds it to the menu if it is
not `nil` and returns the `Menu`.
### SetLabel
API: `SetLabel(label string)`
This method sets the `label` of the `Menu`.

View File

@ -0,0 +1,116 @@
---
title: System Tray
sidebar:
order: 150
---
The system tray houses notification area on a desktop environment, which can
contain both icons of currently-running applications and specific system
notifications.
You create a system tray by calling `app.NewSystemTray()`:
```go
// Create a new system tray
tray := app.NewSystemTray()
```
The following methods are available on the `SystemTray` type:
### SetLabel
API: `SetLabel(label string)`
The `SetLabel` method sets the tray's label.
### Label
API: `Label() string`
The `Label` method retrieves the tray's label.
### PositionWindow
API: `PositionWindow(*WebviewWindow, offset int) error`
The `PositionWindow` method calls both `AttachWindow` and `WindowOffset`
methods.
### SetIcon
API: `SetIcon(icon []byte) *SystemTray`
The `SetIcon` method sets the system tray's icon.
### SetDarkModeIcon
API: `SetDarkModeIcon(icon []byte) *SystemTray`
The `SetDarkModeIcon` method sets the system tray's icon when in dark mode.
### SetMenu
API: `SetMenu(menu *Menu) *SystemTray`
The `SetMenu` method sets the system tray's menu.
### Destroy
API: `Destroy()`
The `Destroy` method destroys the system tray instance.
### OnClick
API: `OnClick(handler func()) *SystemTray`
The `OnClick` method sets the function to execute when the tray icon is clicked.
### OnRightClick
API: `OnRightClick(handler func()) *SystemTray`
The `OnRightClick` method sets the function to execute when right-clicking the
tray icon.
### OnDoubleClick
API: `OnDoubleClick(handler func()) *SystemTray`
The `OnDoubleClick` method sets the function to execute when double-clicking the
tray icon.
### OnRightDoubleClick
API: `OnRightDoubleClick(handler func()) *SystemTray`
The `OnRightDoubleClick` method sets the function to execute when right
double-clicking the tray icon.
### AttachWindow
API: `AttachWindow(window *WebviewWindow) *SystemTray`
The `AttachWindow` method attaches a window to the system tray. The window will
be shown when the system tray icon is clicked.
### WindowOffset
API: `WindowOffset(offset int) *SystemTray`
The `WindowOffset` method sets the gap in pixels between the system tray and the
window.
### WindowDebounce
API: `WindowDebounce(debounce time.Duration) *SystemTray`
The `WindowDebounce` method sets a debounce time. In the context of Windows,
this is used to specify how long to wait before responding to a mouse up event
on the notification icon.
### OpenMenu
API: `OpenMenu()`
The `OpenMenu` method opens the menu associated with the system tray.

View File

@ -0,0 +1,118 @@
---
title: Window
sidebar:
order: 80
---
To create a window, use
[Application.NewWebviewWindow](/api/application_window#newwebviewwindow) or
[Application.NewWebviewWindowWithOptions](/api/application_window#newwebviewwindowwithoptions).
The former creates a window with default options, while the latter allows you to
specify custom options.
These methods are callable on the returned WebviewWindow object:
### SetTitle
API: `SetTitle(title string) *WebviewWindow`
This method updates the window title to the provided string. It returns the
WebviewWindow object, allowing for method chaining.
### Name
API: `Name() string`
This function returns the name of the WebviewWindow.
### SetSize
API: `SetSize(width, height int) *WebviewWindow`
This method sets the size of the WebviewWindow to the provided width and height
parameters. If the dimensions provided exceed the constraints, they are adjusted
appropriately.
### SetAlwaysOnTop
API: `SetAlwaysOnTop(b bool) *WebviewWindow`
This function sets the window to stay on top based on the boolean flag provided.
### Show
API: `Show() *WebviewWindow`
`Show` method is used to make the window visible. If the window is not running,
it first invokes the `run` method to start the window and then makes it visible.
### Hide
API: `Hide() *WebviewWindow`
`Hide` method is used to hide the window. It sets the hidden status of the
window to true and emits the window hide event.
### SetURL
API: `SetURL(s string) *WebviewWindow`
`SetURL` method is used to set the URL of the window to the given URL string.
### SetZoom
API: `SetZoom(magnification float64) *WebviewWindow`
`SetZoom` method sets the zoom level of the window content to the provided
magnification level.
### GetZoom
API: `GetZoom() float64`
`GetZoom` function returns the current zoom level of the window content.
### GetScreen
API: `GetScreen() (*Screen, error)`
`GetScreen` method returns the screen on which the window is displayed.
### SetFrameless
API: `SetFrameless(frameless bool) *WebviewWindow`
This function is used to remove the window frame and title bar. It toggles the
framelessness of the window according to the boolean value provided (true for
frameless, false for framed).
### RegisterContextMenu
API: `RegisterContextMenu(name string, menu *Menu)`
This function is used to register a context menu and assigns it the given name.
### NativeWindowHandle
API: `NativeWindowHandle() (uintptr, error)`
This function is used to fetch the platform native window handle for the window.
### Focus
API: `Focus()`
This function is used to focus the window.
### SetEnabled
API: `SetEnabled(enabled bool)`
This function is used to enable/disable the window based on the provided boolean
value.
### SetPosition
API: `SetPosition(x int, y int)`
This function sets the absolute position of the window in the screen.

View File

@ -0,0 +1,206 @@
---
slug: blog/wails-v2-beta-for-windows
title: Wails v2 Beta for Windows
authors: [leaanthony]
tags: [wails, v2]
date: 2021-09-27
---
![wails screenshot](../../../assets/blog-images/wails.webp)
When I first announced Wails on Reddit, just over 2 years ago from a train in
Sydney, I did not expect it to get much attention. A few days later, a prolific
tech vlogger released a tutorial video, gave it a positive review and from that
point on, interest in the project has skyrocketed.
It was clear that people were excited about adding web frontends to their Go
projects, and almost immediately pushed the project beyond the proof of concept
that I had created. At the time, Wails used the
[webview](https://github.com/webview/webview) project to handle the frontend,
and the only option for Windows was the IE11 renderer. Many bug reports were
rooted in this limitation: poor JavaScript/CSS support and no dev tools to debug
it. This was a frustrating development experience but there wasn't much that
could have been done to rectify it.
For a long time, I'd firmly believed that Microsoft would eventually have to
sort out their browser situation. The world was moving on, frontend development
was booming and IE wasn't cutting it. When Microsoft announced the move to using
Chromium as the basis for their new browser direction, I knew it was only a
matter of time until Wails could use it, and move the Windows developer
experience to the next level.
Today, I am pleased to announce: **Wails v2 Beta for Windows**! There's a huge
amount to unpack in this release, so grab a drink, take a seat and we'll
begin...
### No CGO Dependency!
No, I'm not joking: _No_ _CGO_ _dependency_ 🤯! The thing about Windows is that,
unlike MacOS and Linux, it doesn't come with a default compiler. In addition,
CGO requires a mingw compiler and there's a ton of different installation
options. Removing the CGO requirement has massively simplified setup, as well as
making debugging an awful lot easier. Whilst I have put a fair bit of effort in
getting this working, the majority of the credit should go to
[John Chadwick](https://github.com/jchv) for not only starting a couple of
projects to make this possible, but also being open to someone taking those
projects and building on them. Credit also to
[Tad Vizbaras](https://github.com/tadvi) whose
[winc](https://github.com/tadvi/winc) project started me down this path.
### WebView2 Chromium Renderer
![devtools screenshot](../../../assets/blog-images/devtools.png)
Finally, Windows developers get a first class rendering engine for their
applications! Gone are the days of contorting your frontend code to work on
Windows. On top of that, you get a first-class developer tools experience!
The WebView2 component does, however, have a requirement to have the
`WebView2Loader.dll` sitting alongside the binary. This makes distribution just
that little bit more painful than we gophers are used to. All solutions and
libraries (that I know of) that use WebView2 have this dependency.
However, I'm really excited to announce that Wails applications _have no such
requirement_! Thanks to the wizardry of
[John Chadwick](https://github.com/jchv), we are able to bundle this dll inside
the binary and get Windows to load it as if it were present on disk.
Gophers rejoice! The single binary dream lives on!
### New Features
![wails-menus screenshot](../../../assets/blog-images/wails-menus.webp)
There were a lot of requests for native menu support. Wails has finally got you
covered. Application menus are now available and include support for most native
menu features. This includes standard menu items, checkboxes, radio groups,
submenus and separators.
There were a huge number of requests in v1 for the ability to have greater
control of the window itself. I'm happy to announce that there's new runtime
APIs specifically for this. It's feature-rich and supports multi-monitor
configurations. There is also an improved dialogs API: Now, you can have modern,
native dialogs with rich configuration to cater for all your dialog needs.
There is now the option to generate IDE configuration along with your project.
This means that if you open your project in a supported IDE, it will already be
configured for building and debugging your application. Currently VSCode is
supported but we hope to support other IDEs such as Goland soon.
![vscode screenshot](../../../assets/blog-images/vscode.webp)
### No requirement to bundle assets
A huge pain-point of v1 was the need to condense your entire application down to
single JS & CSS files. I'm happy to announce that for v2, there is no
requirement to bundle assets, in any way, shape or form. Want to load a local
image? Use an `<img>` tag with a local src path. Want to use a cool font? Copy
it in and add the path to it in your CSS.
> Wow, that sounds like a webserver...
Yes, it works just like a webserver, except it isn't.
> So how do I include my assets?
You just pass a single `embed.FS` that contains all your assets into your
application configuration. They don't even need to be in the top directory -
Wails will just work it out for you.
### New Development Experience
![browser screenshot](../../../assets/blog-images/browser.webp)
Now that assets don't need to be bundled, it's enabled a whole new development
experience. The new `wails dev` command will build and run your application, but
instead of using the assets in the `embed.FS`, it loads them directly from disk.
It also provides the additional features:
- Hot reload - Any changes to frontend assets will trigger and auto reload of
the application frontend
- Auto rebuild - Any changes to your Go code will rebuild and relaunch your
application
In addition to this, a webserver will start on port 34115. This will serve your
application to any browser that connects to it. All connected web browsers will
respond to system events like hot reload on asset change.
In Go, we are used to dealing with structs in our applications. It's often
useful to send structs to our frontend and use them as state in our application.
In v1, this was a very manual process and a bit of a burden on the developer.
I'm happy to announce that in v2, any application run in dev mode will
automatically generate TypeScript models for all structs that are input or
output parameters to bound methods. This enables seamless interchange of data
models between the two worlds.
In addition to this, another JS module is dynamically generated wrapping all
your bound methods. This provides JSDoc for your methods, providing code
completion and hinting in your IDE. It's really cool when you get data models
auto-imported when hitting tab in an auto-generated module wrapping your Go
code!
### Remote Templates
![remote screenshot](../../../assets/blog-images/remote.webp)
Getting an application up and running quickly was always a key goal for the
Wails project. When we launched, we tried to cover a lot of the modern
frameworks at the time: react, vue and angular. The world of frontend
development is very opinionated, fast moving and hard to keep on top of! As a
result, we found our base templates getting out of date pretty quickly and this
caused a maintenance headache. It also meant that we didn't have cool modern
templates for the latest and greatest tech stacks.
With v2, I wanted to empower the community by giving you the ability to create
and host templates yourselves, rather than rely on the Wails project. So now you
can create projects using community supported templates! I hope this will
inspire developers to create a vibrant ecosystem of project templates. I'm
really quite excited about what our developer community can create!
### In Conclusion
Wails v2 represents a new foundation for the project. The aim of this release is
to get feedback on the new approach, and to iron out any bugs before a full
release. Your input would be most welcome. Please direct any feedback to the
[v2 Beta](https://github.com/wailsapp/wails/discussions/828) discussion board.
There were many twists and turns, pivots and u-turns to get to this point. This
was due partly to early technical decisions that needed changing, and partly
because some core problems we had spent time building workarounds for were fixed
upstream: Gos embed feature is a good example. Fortunately, everything came
together at the right time, and today we have the very best solution that we can
have. I believe the wait has been worth it - this would not have been possible
even 2 months ago.
I also need to give a huge thank you :pray: to the following people because
without them, this release just wouldn't exist:
- [Misite Bao](https://github.com/misitebao) - An absolute workhorse on the
Chinese translations and an incredible bug finder.
- [John Chadwick](https://github.com/jchv) - His amazing work on
[go-webview2](https://github.com/jchv/go-webview2) and
[go-winloader](https://github.com/jchv/go-winloader) have made the Windows
version we have today possible.
- [Tad Vizbaras](https://github.com/tadvi) - Experimenting with his
[winc](https://github.com/tadvi/winc) project was the first step down the path
to a pure Go Wails.
- [Mat Ryer](https://github.com/matryer) - His support, encouragement and
feedback has really helped drive the project forward.
And finally, I'd like to give a special thank you to all the
[project sponsors](/credits#sponsors), including
[JetBrains](https://www.jetbrains.com?from=Wails), whose support drives the
project in many ways behind the scenes.
I look forward to seeing what people build with Wails in this next exciting
phase of the project!
Lea.
PS: MacOS and Linux users need not feel left out - porting to this new
foundation is actively under way and most of the hard work has already been
done. Hang in there!
PPS: If you or your company find Wails useful, please consider
[sponsoring the project](https://github.com/sponsors/leaanthony). Thanks!

View File

@ -0,0 +1,166 @@
---
slug: blog/wails-v2-beta-for-mac
title: Wails v2 Beta for MacOS
authors: [leaanthony]
tags: [wails, v2]
date: 2021-11-08
---
![wails-mac screenshot](../../../assets/blog-images/wails-mac.webp)
Today marks the first beta release of Wails v2 for Mac! It's taken quite a while
to get to this point and I'm hoping that today's release will give you something
that's reasonably useful. There have been a number of twists and turns to get to
this point and I'm hoping, with your help, to iron out the crinkles and get the
Mac port polished for the final v2 release.
You mean this isn't ready for production? For your use case, it may well be
ready, but there are still a number of known issues so keep your eye on
[this project board](https://github.com/wailsapp/wails/projects/7) and if you
would like to contribute, you'd be very welcome!
So what's new for Wails v2 for Mac vs v1? Hint: It's pretty similar to the
Windows Beta :wink:
### New Features
![wails-menus-mac screenshot](../../../assets/blog-images/wails-menus-mac.webp)
There were a lot of requests for native menu support. Wails has finally got you
covered. Application menus are now available and include support for most native
menu features. This includes standard menu items, checkboxes, radio groups,
submenus and separators.
There were a huge number of requests in v1 for the ability to have greater
control of the window itself. I'm happy to announce that there's new runtime
APIs specifically for this. It's feature-rich and supports multi-monitor
configurations. There is also an improved dialogs API: Now, you can have modern,
native dialogs with rich configuration to cater for all your dialog needs.
### Mac Specific Options
In addition to the normal application options, Wails v2 for Mac also brings some
Mac extras:
- Make your window all funky and translucent, like all the pretty swift apps!
- Highly customisable titlebar
- We support the NSAppearance options for the application
- Simple config to auto-create an "About" menu
### No requirement to bundle assets
A huge pain-point of v1 was the need to condense your entire application down to
single JS & CSS files. I'm happy to announce that for v2, there is no
requirement to bundle assets, in any way, shape or form. Want to load a local
image? Use an `<img>` tag with a local src path. Want to use a cool font? Copy
it in and add the path to it in your CSS.
> Wow, that sounds like a webserver...
Yes, it works just like a webserver, except it isn't.
> So how do I include my assets?
You just pass a single `embed.FS` that contains all your assets into your
application configuration. They don't even need to be in the top directory -
Wails will just work it out for you.
### New Development Experience
Now that assets don't need to be bundled, it's enabled a whole new development
experience. The new `wails dev` command will build and run your application, but
instead of using the assets in the `embed.FS`, it loads them directly from disk.
It also provides the additional features:
- Hot reload - Any changes to frontend assets will trigger and auto reload of
the application frontend
- Auto rebuild - Any changes to your Go code will rebuild and relaunch your
application
In addition to this, a webserver will start on port 34115. This will serve your
application to any browser that connects to it. All connected web browsers will
respond to system events like hot reload on asset change.
In Go, we are used to dealing with structs in our applications. It's often
useful to send structs to our frontend and use them as state in our application.
In v1, this was a very manual process and a bit of a burden on the developer.
I'm happy to announce that in v2, any application run in dev mode will
automatically generate TypeScript models for all structs that are input or
output parameters to bound methods. This enables seamless interchange of data
models between the two worlds.
In addition to this, another JS module is dynamically generated wrapping all
your bound methods. This provides JSDoc for your methods, providing code
completion and hinting in your IDE. It's really cool when you get data models
auto-imported when hitting tab in an auto-generated module wrapping your Go
code!
### Remote Templates
![remote-mac screenshot](../../../assets/blog-images/remote-mac.webp)
Getting an application up and running quickly was always a key goal for the
Wails project. When we launched, we tried to cover a lot of the modern
frameworks at the time: react, vue and angular. The world of frontend
development is very opinionated, fast moving and hard to keep on top of! As a
result, we found our base templates getting out of date pretty quickly and this
caused a maintenance headache. It also meant that we didn't have cool modern
templates for the latest and greatest tech stacks.
With v2, I wanted to empower the community by giving you the ability to create
and host templates yourselves, rather than rely on the Wails project. So now you
can create projects using community supported templates! I hope this will
inspire developers to create a vibrant ecosystem of project templates. I'm
really quite excited about what our developer community can create!
### Native M1 Support
Thanks to the amazing support of [Mat Ryer](https://github.com/matryer/), the
Wails project now supports M1 native builds:
![build-darwin-arm screenshot](../../../assets/blog-images/build-darwin-arm.webp)
You can also specify `darwin/amd64` as a target too:
![build-darwin-amd screenshot](../../../assets/blog-images/build-darwin-amd.webp)
Oh, I almost forgot.... you can also do `darwin/universal`.... :wink:
![build-darwin-universal screenshot](../../../assets/blog-images/build-darwin-universal.webp)
### Cross Compilation to Windows
Because Wails v2 for Windows is pure Go, you can target Windows builds without
docker.
![build-cross-windows screenshot](../../../assets/blog-images/build-cross-windows.webp)
bu
### WKWebView Renderer
V1 relied on a (now deprecated) WebView component. V2 uses the most recent
WKWebKit component so expect the latest and greatest from Apple.
### In Conclusion
As I'd said in the Windows release notes, Wails v2 represents a new foundation
for the project. The aim of this release is to get feedback on the new approach,
and to iron out any bugs before a full release. Your input would be most
welcome! Please direct any feedback to the
[v2 Beta](https://github.com/wailsapp/wails/discussions/828) discussion board.
And finally, I'd like to give a special thank you to all the
[project sponsors](/credits#sponsors), including
[JetBrains](https://www.jetbrains.com?from=Wails), whose support drive the
project in many ways behind the scenes.
I look forward to seeing what people build with Wails in this next exciting
phase of the project!
Lea.
PS: Linux users, you're next!
PPS: If you or your company find Wails useful, please consider
[sponsoring the project](https://github.com/sponsors/leaanthony). Thanks!

View File

@ -0,0 +1,129 @@
---
slug: blog/wails-v2-beta-for-linux
title: Wails v2 Beta for Linux
authors: [leaanthony]
tags: [wails, v2]
date: 2022-02-22
---
![wails-linux screenshot](../../../assets/blog-images/wails-linux.webp)
I'm pleased to finally announce that Wails v2 is now in beta for Linux! It is
somewhat ironic that the very first experiments with v2 was on Linux and yet it
has ended up as the last release. That being said, the v2 we have today is very
different from those first experiments. So without further ado, let's go over
the new features:
### New Features
![wails-menus-linux screenshot](../../../assets/blog-images/wails-menus-linux.webp)
There were a lot of requests for native menu support. Wails has finally got you
covered. Application menus are now available and include support for most native
menu features. This includes standard menu items, checkboxes, radio groups,
submenus and separators.
There were a huge number of requests in v1 for the ability to have greater
control of the window itself. I'm happy to announce that there's new runtime
APIs specifically for this. It's feature-rich and supports multi-monitor
configurations. There is also an improved dialogs API: Now, you can have modern,
native dialogs with rich configuration to cater for all your dialog needs.
### No requirement to bundle assets
A huge pain-point of v1 was the need to condense your entire application down to
single JS & CSS files. I'm happy to announce that for v2, there is no
requirement to bundle assets, in any way, shape or form. Want to load a local
image? Use an `<../../../assets/blog-images>` tag with a local src path. Want to
use a cool font? Copy it in and add the path to it in your CSS.
> Wow, that sounds like a webserver...
Yes, it works just like a webserver, except it isn't.
> So how do I include my assets?
You just pass a single `embed.FS` that contains all your assets into your
application configuration. They don't even need to be in the top directory -
Wails will just work it out for you.
### New Development Experience
Now that assets don't need to be bundled, it's enabled a whole new development
experience. The new `wails dev` command will build and run your application, but
instead of using the assets in the `embed.FS`, it loads them directly from disk.
It also provides the additional features:
- Hot reload - Any changes to frontend assets will trigger an auto reload of the
application frontend
- Auto rebuild - Any changes to your Go code will rebuild and relaunch your
application
In addition to this, a webserver will start on port 34115. This will serve your
application to any browser that connects to it. All connected web browsers will
respond to system events like hot reload on asset change.
In Go, we are used to dealing with structs in our applications. It's often
useful to send structs to our frontend and use them as state in our application.
In v1, this was a very manual process and a bit of a burden on the developer.
I'm happy to announce that in v2, any application run in dev mode will
automatically generate TypeScript models for all structs that are input or
output parameters to bound methods. This enables seamless interchange of data
models between the two worlds.
In addition to this, another JS module is dynamically generated wrapping all
your bound methods. This provides JSDoc for your methods, providing code
completion and hinting in your IDE. It's really cool when you get data models
auto-imported when hitting tab in an auto-generated module wrapping your Go
code!
### Remote Templates
![remote-linux screenshot](../../../assets/blog-images/remote-linux.webp)
Getting an application up and running quickly was always a key goal for the
Wails project. When we launched, we tried to cover a lot of the modern
frameworks at the time: react, vue and angular. The world of frontend
development is very opinionated, fast moving and hard to keep on top of! As a
result, we found our base templates getting out of date pretty quickly and this
caused a maintenance headache. It also meant that we didn't have cool modern
templates for the latest and greatest tech stacks.
With v2, I wanted to empower the community by giving you the ability to create
and host templates yourselves, rather than rely on the Wails project. So now you
can create projects using community supported templates! I hope this will
inspire developers to create a vibrant ecosystem of project templates. I'm
really quite excited about what our developer community can create!
### Cross Compilation to Windows
Because Wails v2 for Windows is pure Go, you can target Windows builds without
docker.
![build-cross-windows screenshot](../../../assets/blog-images/linux-build-cross-windows.webp)
### In Conclusion
As I'd said in the Windows release notes, Wails v2 represents a new foundation
for the project. The aim of this release is to get feedback on the new approach,
and to iron out any bugs before a full release. Your input would be most
welcome! Please direct any feedback to the
[v2 Beta](https://github.com/wailsapp/wails/discussions/828) discussion board.
Linux is **hard** to support. We expect there to be a number of quirks with the
beta. Please help us to help you by filing detailed bug reports!
Finally, I'd like to give a special thank you to all the
[project sponsors](/credits#sponsors) whose support drives the project in many
ways behind the scenes.
I look forward to seeing what people build with Wails in this next exciting
phase of the project!
Lea.
PS: The v2 release isn't far off now!
PPS: If you or your company find Wails useful, please consider
[sponsoring the project](https://github.com/sponsors/leaanthony). Thanks!

View File

@ -0,0 +1,198 @@
---
slug: blog/wails-v2-released
title: Wails v2 Released
authors: [leaanthony]
tags: [wails, v2]
date: 2022-09-22
---
![montage screenshot](../../../assets/blog-images/montage.png)
# It's here!
Today marks the release of [Wails](https://wails.io) v2. It's been about 18
months since the first v2 alpha and about a year from the first beta release.
I'm truly grateful to everyone involved in the evolution of the project.
Part of the reason it took that long was due to wanting to get to some
definition of completeness before officially calling it v2. The truth is,
there's never a perfect time to tag a release - there's always outstanding
issues or "just one more" feature to squeeze in. What tagging an imperfect major
release does do, however, is to provide a bit of stability for users of the
project, as well as a bit of a reset for the developers.
This release is more than I'd ever expected it to be. I hope it gives you as
much pleasure as it has given us to develop it.
# What _is_ Wails?
If you are unfamiliar with Wails, it is a project that enables Go programmers to
provide rich frontends for their Go programs using familiar web technologies.
It's a lightweight, Go alternative to Electron. Much more information can be
found on the [official site](https://wails.io/docs/introduction).
# What's new?
The v2 release is a huge leap forward for the project, addressing many of the
pain points of v1. If you have not read any of the blog posts on the Beta
releases for [macOS](/blog/wails-v2-beta-for-mac),
[Windows](/blog/wails-v2-beta-for-windows) or
[Linux](/blog/wails-v2-beta-for-linux), then I encourage you to do so as it
covers all the major changes in more detail. In summary:
- Webview2 component for Windows that supports modern web standards and
debugging capabilities.
- [Dark / Light theme](https://wails.io/docs/reference/options#theme) +
[custom theming](https://wails.io/docs/reference/options#customtheme) on Windows.
- Windows now has no CGO requirements.
- Out-of-the-box support for Svelte, Vue, React, Preact, Lit & Vanilla project
templates.
- [Vite](https://vitejs.dev/) integration providing a hot-reload development
environment for your application.
- Native application
[menus](https://wails.io/docs/guides/application-development#application-menu) and
[dialogs](https://wails.io/docs/reference/runtime/dialog).
- Native window translucency effects for
[Windows](https://wails.io/docs/reference/options#windowistranslucent) and
[macOS](https://wails.io/docs/reference/options#windowistranslucent-1). Support for Mica &
Acrylic backdrops.
- Easily generate an [NSIS installer](https://wails.io/docs/guides/windows-installer) for
Windows deployments.
- A rich [runtime library](https://wails.io/docs/reference/runtime/intro) providing utility
methods for window manipulation, eventing, dialogs, menus and logging.
- Support for [obfuscating](https://wails.io/docs/guides/obfuscated) your application using
[garble](https://github.com/burrowers/garble).
- Support for compressing your application using [UPX](https://upx.github.io/).
- Automatic TypeScript generation of Go structs. More info
[here](https://wails.io/docs/howdoesitwork#calling-bound-go-methods).
- No extra libraries or DLLs are required to be shipped with your application.
For any platform.
- No requirement to bundle frontend assets. Just develop your application like
any other web application.
# Credit & Thanks
Getting to v2 has been a huge effort. There have been ~2.2K commits by 89
contributors between the initial alpha and the release today, and many, many
more that have provided translations, testing, feedback and help on the
discussion forums as well as the issue tracker. I'm so unbelievably grateful to
each one of you. I'd also like to give an extra special thank you to all the
project sponsors who have provided guidance, advice and feedback. Everything you
do is hugely appreciated.
There are a few people I'd like to give special mention to:
Firstly, a **huge** thank you to [@stffabi](https://github.com/stffabi) who has
provided so many contributions which we all benefit from, as well as providing a
lot of support on many issues. He has provided some key features such as the
external dev server support which transformed our dev mode offering by allowing
us to hook into [Vite](https://vitejs.dev/)'s superpowers. It's fair to say that
Wails v2 would be a far less exciting release without his
[incredible contributions](https://github.com/wailsapp/wails/commits?author=stffabi&since=2020-01-04).
Thank you so much @stffabi!
I'd also like to give a huge shout-out to
[@misitebao](https://github.com/misitebao) who has tirelessly been maintaining
the website, as well as providing Chinese translations, managing Crowdin and
helping new translators get up to speed. This is a hugely important task, and
I'm extremely grateful for all the time and effort put into this! You rock!
Last, but not least, a huge thank you to Mat Ryer who has provided advice and
support during the development of v2. Writing xBar together using an early Alpha
of v2 was helpful in shaping the direction of v2, as well as give me an
understanding of some design flaws in the early releases. I'm happy to announce
that as of today, we will start to port xBar to Wails v2, and it will become the
flagship application for the project. Cheers Mat!
# Lessons Learnt
There are a number of lessons learnt in getting to v2 that will shape
development moving forward.
## Smaller, Quicker, Focused Releases
In the course of developing v2, there were many features and bug fixes that were
developed on an ad-hoc basis. This led to longer release cycles and were harder
to debug. Moving forward, we are going to create releases more often that will
include a reduced number of features. A release will involve updates to
documentation as well as thorough testing. Hopefully, these smaller, quicker,
focussed releases will lead to fewer regressions and better quality
documentation.
## Encourage Engagement
When starting this project, I wanted to immediately help everyone who had a
problem. Issues were "personal" and I wanted them resolved as quickly as
possible. This is unsustainable and ultimately works against the longevity of
the project. Moving forward, I will be giving more space for people to get
involved in answering questions and triaging issues. It would be good to get
some tooling to help with this so if you have any suggestions, please join in
the discussion [here](https://github.com/wailsapp/wails/discussions/1855).
## Learning to say No
The more people that engage with an Open Source project, the more requests there
will be for additional features that may or may not be useful to the majority of
people. These features will take an initial amount of time to develop and debug,
and incur an ongoing maintenance cost from that point on. I myself am the most
guilty of this, often wanting to "boil the sea" rather than provide the minimum
viable feature. Moving forward, we will need to say "No" a bit more to adding
core features and focus our energies on a way to empower developers to provide
that functionality themselves. We are looking seriously into plugins for this
scenario. This will allow anyone to extend the project as they see fit, as well
as providing an easy way to contribute towards the project.
# Looking to the Future
There are so many core features we are looking at to add to Wails in the next
major development cycle already. The
[roadmap](https://github.com/wailsapp/wails/discussions/1484) is full of
interesting ideas, and I'm keen to start work on them. One of the big asks has
been for multiple window support. It's a tricky one and to do it right, and we
may need to look at providing an alternative API, as the current one was not
designed with this in mind. Based on some preliminary ideas and feedback, I
think you'll like where we're looking to go with it.
I'm personally very excited at the prospect of getting Wails apps running on
mobile. We already have a demo project showing that it is possible to run a
Wails app on Android, so I'm really keen to explore where we can go with this!
A final point I'd like to raise is that of feature parity. It has long been a
core principle that we wouldn't add anything to the project without there being
full cross-platform support for it. Whilst this has proven to be (mainly)
achievable so far, it has really held the project back in releasing new
features. Moving forward, we will be adopting a slightly different approach: any
new feature that cannot be immediately released for all platforms will be
released under an experimental configuration or API. This allows early adopters
on certain platforms to try the feature and provide feedback that will feed into
the final design of the feature. This, of course, means that there are no
guarantees of API stability until it is fully supported by all the platforms it
can be supported on, but at least it will unblock development.
# Final Words
I'm really proud of what we've been able to achieve with the V2 release. It's
amazing to see what people have already been able to build using the beta
releases so far. Quality applications like [Varly](https://varly.app/),
[Surge](https://getsurge.io/) and [October](https://october.utf9k.net/). I
encourage you to check them out.
This release was achieved through the hard work of many contributors. Whilst it
is free to download and use, it has not come about through zero cost. Make no
mistakes, this project has come at considerable cost. It has not only been my
time and the time of each and every contributor, but also the cost of absence
from friends and families of each of those people too. That's why I'm extremely
grateful for every second that has been dedicated to making this project happen.
The more contributors we have, the more this effort can be spread out and the
more we can achieve together. I'd like to encourage you all to pick one thing
that you can contribute, whether it is confirming someone's bug, suggesting a
fix, making a documentation change or helping out someone who needs it. All of
these small things have such a huge impact! It would be so awesome if you too
were part of the story in getting to v3.
Enjoy!
&dash; Lea
PS: If you or your company find Wails useful, please consider
[sponsoring the project](https://github.com/sponsors/leaanthony). Thanks!

View File

@ -0,0 +1,256 @@
---
slug: blog/the-road-to-wails-v3
title: The Road to Wails v3
authors: [leaanthony]
tags: [wails, v3]
date: 2023-01-17
---
![multiwindow screenshot](../../../assets/blog-images/multiwindow.webp)
# Introduction
Wails is a project that simplifies the ability to write cross-platform desktop
applications using Go. It uses native webview components for the frontend (not
embedded browsers), bringing the power of the world's most popular UI system to
Go, whilst remaining lightweight.
Version 2 was released on the 22nd of September 2022 and brought with it a lot
of enhancements including:
- Live development, leveraging the popular Vite project
- Rich functionality for managing windows and creating menus
- Microsoft's WebView2 component
- Generation of Typescript models that mirror your Go structs
- Creating of NSIS Installer
- Obfuscated builds
Right now, Wails v2 provides powerful tooling for creating rich, cross-platform
desktop applications.
This blog post aims to look at where the project is at right now and what we can
improve on moving forward.
# Where are we now?
It's been incredible to see the popularity of Wails rising since the v2 release.
I'm constantly amazed by the creativity of the community and the wonderful
things that are being built with it. With more popularity, comes more eyes on
the project. And with that, more feature requests and bug reports.
Over time, I've been able to identify some of the most pressing issues facing
the project. I've also been able to identify some of the things that are holding
the project back.
## Current issues
I've identified the following areas that I feel are holding the project back:
- The API
- Bindings generation
- The Build System
### The API
The API to build a Wails application currently consists of 2 parts:
- The Application API
- The Runtime API
The Application API famously has only 1 function: `Run()` which takes a heap of
options which govern how the application will work. Whilst this is very simple
to use, it is also very limiting. It is a "declarative" approach which hides a
lot of the underlying complexity. For instance, there is no handle to the main
window, so you can't interact with it directly. For that, you need to use the
Runtime API. This is a problem when you start to want to do more complex things
like create multiple windows.
The Runtime API provides a lot of utility functions for the developer. This
includes:
- Window management
- Dialogs
- Menus
- Events
- Logs
There are a number of things I am not happy with the Runtime API. The first is
that it requires a "context" to be passed around. This is both frustrating and
confusing for new developers who pass in a context and then get a runtime error.
The biggest issue with the Runtime API is that it was designed for applications
that only use a single window. Over time, the demand for multiple windows has
grown and the API is not well suited to this.
### Thoughts on the v3 API
Wouldn't it be great if we could do something like this?
```go
func main() {
app := wails.NewApplication(options.App{})
myWindow := app.NewWindow(options.Window{})
myWindow.SetTitle("My Window")
myWindow.On(events.Window.Close, func() {
app.Quit()
})
app.Run()
}
```
This programmatic approach is far more intuitive and allows the developer to
interact with the application elements directly. All current runtime methods for
windows would simply be methods on the window object. For the other runtime
methods, we could move them to the application object like so:
```go
app := wails.NewApplication(options.App{})
app.NewInfoDialog(options.InfoDialog{})
app.Log.Info("Hello World")
```
This is a much more powerful API which will allow for more complex applications
to be built. It also allows for the creation of multiple windows,
[the most up-voted feature on GitHub](https://github.com/wailsapp/wails/issues/1480):
```go
func main() {
app := wails.NewApplication(options.App{})
myWindow := app.NewWindow(options.Window{})
myWindow.SetTitle("My Window")
myWindow.On(events.Window.Close, func() {
app.Quit()
})
myWindow2 := app.NewWindow(options.Window{})
myWindow2.SetTitle("My Window 2")
myWindow2.On(events.Window.Close, func() {
app.Quit()
})
app.Run()
}
```
### Bindings generation
One of the key features of Wails is generating bindings for your Go methods so
they may be called from Javascript. The current method for doing this is a bit
of a hack. It involves building the application with a special flag and then
running the resultant binary which uses reflection to determine what has been
bound. This leads to a bit of a chicken and egg situation: You can't build the
application without the bindings and you can't generate the bindings without
building the application. There are many ways around this but the best one would
be not to use this approach at all.
There were a number of attempts at writing a static analyser for Wails projects
but they didn't get very far. In more recent times, it has become slightly
easier to do this with more material available on the subject.
Compared to reflection, the AST approach is much faster however it is
significantly more complicated. To start with, we may need to impose certain
constraints on how to specify bindings in the code. The goal is to support the
most common use cases and then expand it later on.
### The Build System
Like the declarative approach to the API, the build system was created to hide
the complexities of building a desktop application. When you run `wails build`,
it does a lot of things behind the scenes:
- Builds the backend binary for bindings and generates the bindings
- Installs the frontend dependencies
- Builds the frontend assets
- Determines if the application icon is present and if so, embeds it
- Builds the final binary
- If the build is for `darwin/universal` it builds 2 binaries, one for
`darwin/amd64` and one for `darwin/arm64` and then creates a fat binary using
`lipo`
- If compression is required, it compresses the binary with UPX
- Determines if this binary is to be packaged and if so:
- Ensures the icon and application manifest are compiled into the binary
(Windows)
- Builds out the application bundle, generates the icon bundle and copies it,
the binary and Info.plist to the application bundle (Mac)
- If an NSIS installer is required, it builds it
This entire process, whilst very powerful, is also very opaque. It is very
difficult to customise it and it is very difficult to debug.
To address this in v3, I would like to move to a build system that exists
outside of Wails. After using [Task](https://taskfile.dev/) for a while, I am a
big fan of it. It is a great tool for configuring build systems and should be
reasonably familiar to anyone who has used Makefiles.
The build system would be configured using a `Taskfile.yml` file which would be
generated by default with any of the supported templates. This would have all of
the steps required to do all the current tasks, such as building or packaging
the application, allowing for easy customisation.
There will be no external requirement for this tooling as it would form part of
the Wails CLI. This means that you can still use `wails build` and it will do
all the things it does today. However, if you want to customise the build
process, you can do so by editing the `Taskfile.yml` file. It also means you can
easily understand the build steps and use your own build system if you wish.
The missing piece in the build puzzle is the atomic operations in the build
process, such as icon generation, compression and packaging. To require a bunch
of external tooling would not be a great experience for the developer. To
address this, the Wails CLI will provide all these capabilities as part of the
CLI. This means that the builds still work as expected, with no extra external
tooling, however you can replace any step of the build with any tool you like.
This will be a much more transparent build system which will allow for easier
customisation and address a lot of the issues that have been raised around it.
## The Payoff
These positive changes will be a huge benefit to the project:
- The new API will be much more intuitive and will allow for more complex
applications to be built.
- Using static analysis for bindings generation will be much faster and reduce a
lot of the complexity around the current process.
- Using an established, external build system will make the build process
completely transparent, allowing for powerful customisation.
Benefits to the project maintainers are:
- The new API will be much easier to maintain and adapt to new features and
platforms.
- The new build system will be much easier to maintain and extend. I hope this
will lead to a new ecosystem of community driven build pipelines.
- Better separation of concerns within the project. This will make it easier to
add new features and platforms.
## The Plan
A lot of the experimentation for this has already been done and it's looking
good. There is no current timeline for this work but I'm hoping by the end of Q1
2023, there will be an alpha release for Mac to allow the community to test,
experiment with and provide feedback.
## Summary
- The v2 API is declarative, hides a lot from the developer and not suitable for
features such as multiple windows. A new API will be created which will be
simpler, intuitive and more powerful.
- The build system is opaque and difficult to customise so we will move to an
external build system which will open it all up.
- The bindings generation is slow and complex so we will move to static analysis
which will remove a lot of the complexity the current method has.
There has been a lot of work put into the guts of v2 and it's solid. It's now
time to address the layer on top of it and make it a much better experience for
the developer.
I hope you are as excited about this as I am. I'm looking forward to hearing
your thoughts and feedback.
Regards,
&dash; Lea
PS: If you or your company find Wails useful, please consider
[sponsoring the project](https://github.com/sponsors/leaanthony). Thanks!
PPS: Yes, that's a genuine screenshot of a multi-window application built with
Wails. It's not a mockup. It's real. It's awesome. It's coming soon.

View File

@ -0,0 +1,432 @@
---
title: Changelog
---
<!--
All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
- `Added` for new features.
- `Changed` for changes in existing functionality.
- `Deprecated` for soon-to-be removed features.
- `Removed` for now removed features.
- `Fixed` for any bug fixes.
- `Security` in case of vulnerabilities.
-->
## [Unreleased]
### Added
- `app.OpenDirectory(dir string)` to open the system file explorer to the
directory `dir` by [@leaanthony](https://github.com/leaanthony)
### Fixed
- [darwin] Ensure `windowDidBecomeKey` callback is running on main thread by
[@leaanthony](https://github.com/leaanthony)
- Ensure key callbacks in window run() are called on the main thread by
[@leaanthony](https://github.com/leaanthony)
- [darwin] Support fullscreen for frameless windows by
[@leaanthony](https://github.com/leaanthony)
## v3.0.0-alpha.8.3 - 2024-12-07
### Changed
- Ensure for of taskfile is used by @leaanthony
## v3.0.0-alpha.8.2 - 2024-12-07
### Changed
- Update fork of Taskfile to fix version issues when installing using
`go install` by @leaanthony
## v3.0.0-alpha.8.1 - 2024-12-07
### Changed
- Using fork of Taskfile to fix version issues when installing using
`go install` by @leaanthony
## v3.0.0-alpha.8 - 2024-12-06
### Added
- Support of linux packaging of deb,rpm, and arch linux packager builds by
@atterpac in [#3909](https://github.com/wailsapp/wails/3909)
- Added Support for darwin universal builds and packages by
[ansxuman](https://github.com/ansxuman) in
[#3902](https://github.com/wailsapp/wails/pull/3902)
- Events documentation to the mkdocs webite by
[atterpac](https://github.com/atterpac) in
[#3867](https://github.com/wailsapp/wails/pull/3867)
- Templates for sveltekit and sveltekit-ts that are set for non-SSR development
by [atterpac](https://github.com/atterpac) in
[#3829](https://github.com/wailsapp/wails/pull/3829)
- Update build assets using new `wails3 update build-assets` command by
[leaanthony](https://github.com/leaanthony)
- Example to test the HTML Drag and Drop API by
[FerroO2000](https://github.com/FerroO2000) in
[#3856](https://github.com/wailsapp/wails/pull/3856)
- File Association support by [leaanthony](https://github.com/leaanthony) in
[#3873](https://github.com/wailsapp/wails/pull/3873)
- New `wails3 generate runtime` command by
[leaanthony](https://github.com/leaanthony)
- New `InitialPosition` option to specify if the window should be centered or
positioned at the given X/Y location by
[leaanthony](https://github.com/leaanthony) in
[#3885](https://github.com/wailsapp/wails/pull/3885)
- Add `Path` & `Paths` methods to `application` package by
[ansxuman](https://github.com/ansxuman) and
[leaanthony](https://github.com/leaanthony) in
[#3823](https://github.com/wailsapp/wails/pull/3823)
- Added `GeneralAutofillEnabled` and `PasswordAutosaveEnabled` Windows options
by [leaanthony](https://github.com/leaanthony) in
[#3766](https://github.com/wailsapp/wails/pull/3766)
- Added the ability to retrieve the window calling a service method by
[leaanthony](https://github.com/leaanthony) in
[#3888](https://github.com/wailsapp/wails/pull/3888)
- Added `EnabledFeatures` and `DisabledFeatures` options for Webview2 by
[leaanthony](https://github.com/leaanthony).
-
### Changed
- `service.OnStartup` now shutdowns the application on error and runs
`service.OnShutdown`for any prior services that started by @atterpac in
[#3920](https://github.com/wailsapp/wails/pull/3920)
- Refactored systray click messaging to better align with user interactions by
@atterpac in [#3907](https://github.com/wailsapp/wails/pull/3907)
- Asset embed to include `all:frontend/dist` to support frameworks that generate
subfolders by @atterpac in
[#3887](https://github.com/wailsapp/wails/pull/3887)
- Taskfile refactor by [leaanthony](https://github.com/leaanthony) in
[#3748](https://github.com/wailsapp/wails/pull/3748)
- Upgrade to `go-webview2` v1.0.16 by
[leaanthony](https://github.com/leaanthony)
- Fixed `Screen` type to include `ID` not `Id` by
[etesam913](https://github.com/etesam913) in
[#3778](https://github.com/wailsapp/wails/pull/3778)
- Update `go.mod.tmpl` wails version to support `application.ServiceOptions` by
[northes](https://github.com/northes) in
[#3836](https://github.com/wailsapp/wails/pull/3836)
- Fixed service name determination by [windom](https://github.com/windom/) in
[#3827](https://github.com/wailsapp/wails/pull/3827)
- mkdocs serve now uses docker by [leaanthony](https://github.com/leaanthony)
- Consolidated dev config into `config.yml` by
[leaanthony](https://github.com/leaanthony)
- Systray dialog now defaults to the application icon if available (Windows) by
[@leaanthony](https://github.com/leaanthony)
- Better reporting of GPU + Memory for macOS by
[@leaanthony](https://github.com/leaanthony)
- Removed `WebviewGpuIsDisabled` and `EnableFraudulentWebsiteWarnings`
(superseded by `EnabledFeatures` and `DisabledFeatures` options) by
[leaanthony](https://github.com/leaanthony)
### Fixed
- Fixed deadlock in Linux dialog for multiple selections caused by unclosed
channel variable by @michael-freling in
[#3925](https://github.com/wailsapp/wails/pull/3925)
- Fixed cross-platform cleanup for .syso files during Windows build by
[ansxuman](https://github.com/ansxuman) in
[#3924](https://github.com/wailsapp/wails/pull/3924)
- Fixed amd64 appimage compile by @atterpac in
[#3898](https://github.com/wailsapp/wails/pull/3898)
- Fixed build assets update by @ansxuman in
[#3901](https://github.com/wailsapp/wails/pull/3901)
- Fixed Linux systray `OnClick` and `OnRightClick` implementation by @atterpac
in [#3886](https://github.com/wailsapp/wails/pull/3886)
- Fixed `AlwaysOnTop` not working on Mac by
[leaanthony](https://github.com/leaanthony) in
[#3841](https://github.com/wailsapp/wails/pull/3841)
- [darwin] Fixed `application.NewEditMenu` including a duplicate
`PasteAndMatchStyle` role in the edit menu on Darwin by
[johnmccabe](https://github.com/johnmccabe) in
[#3839](https://github.com/wailsapp/wails/pull/3839)
- [linux] Fixed aarch64 compilation
[#3840](https://github.com/wailsapp/wails/issues/3840) in
[#3854](https://github.com/wailsapp/wails/pull/3854) by
[kodflow](https://github.com/kodflow)
- [windows] Fixed radio group menu items by
[@leaanthony](https://github.com/leaanthony)
- Fix error on building runnable .app on MacOS when 'name' and 'outputfilename'
are different. by @nickisworking in
[#3789](https://github.com/wailsapp/wails/pull/3789)
## v3.0.0-alpha.7 - 2024-09-18
### Added
- [windows] New DIP system for Enhanced High DPI Monitor Support by
[mmghv](https://github.com/mmghv) in
[#3665](https://github.com/wailsapp/wails/pull/3665)
- [windows] Window class name option by [windom](https://github.com/windom/) in
[#3682](https://github.com/wailsapp/wails/pull/3682)
- Services have been expanded to provide plugin functionality. By
[atterpac](https://github.com/atterpac) and
[leaanthony](https://github.com/leaanthony) in
[#3570](https://github.com/wailsapp/wails/pull/3570)
### Changed
- Events API change: `On`/`Emit` -> user events, `OnApplicationEvent` ->
Application Events `OnWindowEvent` -> Window Events, by
[leaanthony](https://github.com/leaanthony)
- Fix for Events API on Linux by [TheGB0077](https://github.com/TheGB0077) in
[#3734](https://github.com/wailsapp/wails/pull/3734)
- [CI] improvements to actions & enable to run actions also in forks and
branches prefixed with `v3/` or `v3-` by
[stendler](https://github.com/stendler) in
[#3747](https://github.com/wailsapp/wails/pull/3747)
### Fixed
- Fixed bug with usage of customEventProcessor in drag-n-drop example by
[etesam913](https://github.com/etesam913) in
[#3742](https://github.com/wailsapp/wails/pull/3742)
- [linux] Fixed linux compile error introduced by IgnoreMouseEvents addition by
[atterpac](https://github.com/atterpac) in
[#3721](https://github.com/wailsapp/wails/pull/3721)
- [windows] Fixed syso icon file generation bug by
[atterpac](https://github.com/atterpac) in
[#3675](https://github.com/wailsapp/wails/pull/3675)
- [linux] Fix to run natively in wayland incorporated from
[#1811](https://github.com/wailsapp/wails/pull/1811) in
[#3614](https://github.com/wailsapp/wails/pull/3614) by
[@stendler](https://github.com/stendler)
- Do not bind internal service methods in
[#3720](https://github.com/wailsapp/wails/pull/3720) by
[leaanthony](https://github.com/leaanthony)
- [windows] Fixed system tray startup panic in
[#3693](https://github.com/wailsapp/wails/issues/3693) by
[@DeltaLaboratory](https://github.com/DeltaLaboratory)
- Do not bind internal service methods in
[#3720](https://github.com/wailsapp/wails/pull/3720) by
[leaanthony](https://github.com/leaanthony)
- [windows] Fixed system tray startup panic in
[#3693](https://github.com/wailsapp/wails/issues/3693) by
[@DeltaLaboratory](https://github.com/DeltaLaboratory)
- Major menu item refactor and event handling. Mainly improves macOS for now. By
[leaanthony](https://github.com/leaanthony)
- Fix tests after plugins and event refactor in
[#3746](https://github.com/wailsapp/wails/pull/3746) by
[@stendler](https://github.com/stendler)
- [windows] Fixed `Failed to unregister class Chrome_WidgetWin_0` warning. By
[leaanthony](https://github.com/leaanthony)
## v3.0.0-alpha.6 - 2024-07-30
### Fixed
- Module issues
## v3.0.0-alpha.5 - 2024-07-30
### Added
- [linux] WindowDidMove / WindowDidResize events in
[#3580](https://github.com/wailsapp/wails/pull/3580)
- [windows] WindowDidResize event in
[#3580](https://github.com/wailsapp/wails/pull/3580)
- [darwin] add Event ApplicationShouldHandleReopen to be able to handle dock
icon click by @5aaee9 in [#2991](https://github.com/wailsapp/wails/pull/2991)
- [darwin] add getPrimaryScreen/getScreens to impl by @tmclane in
[#2618](https://github.com/wailsapp/wails/pull/2618)
- [darwin] add option for showing the toolbar in fullscreen mode on macOS by
[@fbbdev](https://github.com/fbbdev) in
[#3282](https://github.com/wailsapp/wails/pull/3282)
- [linux] add onKeyPress logic to convert linux keypress into an accelerator
@[Atterpac](https://github.com/Atterpac)
in[#3022](https://github.com/wailsapp/wails/pull/3022])
- [linux] add task `run:linux` by
[@marcus-crane](https://github.com/marcus-crane) in
[#3146](https://github.com/wailsapp/wails/pull/3146)
- Export `SetIcon` method by @almas1992 in
[PR](https://github.com/wailsapp/wails/pull/3147)
- Improve `OnShutdown` by @almas1992 in
[PR](https://github.com/wailsapp/wails/pull/3189)
- Restore `ToggleMaximise` method in `Window` interface by
[@fbbdev](https://github.com/fbbdev) in
[#3281](https://github.com/wailsapp/wails/pull/3281)
- Added more information to `Environment()`. By @leaanthony in
[aba82cc](https://github.com/wailsapp/wails/commit/aba82cc52787c97fb99afa58b8b63a0004b7ff6c)
based on [PR](https://github.com/wailsapp/wails/pull/2044) by @Mai-Lapyst
- Expose the `WebviewWindow.IsFocused` method on the `Window` interface by
[@fbbdev](https://github.com/fbbdev) in
[#3295](https://github.com/wailsapp/wails/pull/3295)
- Support multiple space-separated trigger events in the WML system by
[@fbbdev](https://github.com/fbbdev) in
[#3295](https://github.com/wailsapp/wails/pull/3295)
- Add ESM exports from the bundled JS runtime script by
[@fbbdev](https://github.com/fbbdev) in
[#3295](https://github.com/wailsapp/wails/pull/3295)
- Add binding generator flag for using the bundled JS runtime script instead of
the npm package by [@fbbdev](https://github.com/fbbdev) in
[#3334](https://github.com/wailsapp/wails/pull/3334)
- Implement `setIcon` on linux by [@abichinger](https://github.com/abichinger)
in [#3354](https://github.com/wailsapp/wails/pull/3354)
- Add flag `-port` to dev command and support environment variable
`WAILS_VITE_PORT` by [@abichinger](https://github.com/abichinger) in
[#3429](https://github.com/wailsapp/wails/pull/3429)
- Add tests for bound method calls by
[@abichinger](https://github.com/abichinger) in
[#3431](https://github.com/wailsapp/wails/pull/3431)
- [windows] add `SetIgnoreMouseEvents` for already created window by
[@bruxaodev](https://github.com/bruxaodev) in
[#3667](https://github.com/wailsapp/wails/pull/3667)
- [darwin] Add ability to set a window's stacking level (order) by
[@OlegGulevskyy](https://github.com/OlegGulevskyy) in
[#3674](https://github.com/wailsapp/wails/pull/3674)
### Fixed
- Fixed resize event messaging by [atterpac](https://github.com/atterpac) in
[#3606](https://github.com/wailsapp/wails/pull/3606)
- [linux] Fixed theme handling error on NixOS by
[tmclane](https://github.com/tmclane) in
[#3515](https://github.com/wailsapp/wails/pull/3515)
- Fixed cross volume project install for windows by
[atterpac](https://github.com/atterac) in
[#3512](https://github.com/wailsapp/wails/pull/3512)
- Fixed react template css to show footer by
[atterpac](https://github.com/atterpac) in
[#3477](https://github.com/wailsapp/wails/pull/3477)
- Fixed zombie processes when working in devmode by updating to latest refresh
by [Atterpac](https://github.com/atterpac) in
[#3320](https://github.com/wailsapp/wails/pull/3320).
- Fixed appimage webkit file sourcing by [Atterpac](https://github.com/atterpac)
in [#3306](https://github.com/wailsapp/wails/pull/3306).
- Fixed Doctor apt package verify by [Atterpac](https://github.com/Atterpac) in
[#2972](https://github.com/wailsapp/wails/pull/2972).
- Fixed application frozen when quit (Darwin) by @5aaee9 in
[#2982](https://github.com/wailsapp/wails/pull/2982)
- Fixed background colours of examples on Windows by
[mmghv](https://github.com/mmghv) in
[#2750](https://github.com/wailsapp/wails/pull/2750).
- Fixed default context menus by [mmghv](https://github.com/mmghv) in
[#2753](https://github.com/wailsapp/wails/pull/2753).
- Fixed hex values for arrow keys on Darwin by
[jaybeecave](https://github.com/jaybeecave) in
[#3052](https://github.com/wailsapp/wails/pull/3052).
- Set drag-n-drop for windows to working. Added by
[@pylotlight](https://github.com/pylotlight) in
[PR](https://github.com/wailsapp/wails/pull/3039)
- Fixed bug for linux in doctor in the event user doesn't have proper drivers
installed. Added by [@pylotlight](https://github.com/pylotlight) in
[PR](https://github.com/wailsapp/wails/pull/3032)
- Fix dpi scaling on start up (windows). Changed by @almas1992 in
[PR](https://github.com/wailsapp/wails/pull/3145)
- Fix replace line in `go.mod` to use relative paths. Fixes Windows paths with
spaces - @leaanthony.
- Fix MacOS systray click handling when no attached window by
[thomas-senechal](https://github.com/thomas-senechal) in PR
[#3207](https://github.com/wailsapp/wails/pull/3207)
- Fix failing Windows build due to unknown option by
[thomas-senechal](https://github.com/thomas-senechal) in PR
[#3208](https://github.com/wailsapp/wails/pull/3208)
- Fix crash on windows left clicking the systray icon when not having an
attached window [tw1nk](https://github.com/tw1nk) in PR
[#3271](https://github.com/wailsapp/wails/pull/3271)
- Fix wrong baseURL when open window twice by @5aaee9 in PR
[#3273](https://github.com/wailsapp/wails/pull/3273)
- Fix ordering of if branches in `WebviewWindow.Restore` method by
[@fbbdev](https://github.com/fbbdev) in
[#3279](https://github.com/wailsapp/wails/pull/3279)
- Correctly compute `startURL` across multiple `GetStartURL` invocations when
`FRONTEND_DEVSERVER_URL` is present.
[#3299](https://github.com/wailsapp/wails/pull/3299)
- Fix the JS type of the `Screen` struct to match its Go counterpart by
[@fbbdev](https://github.com/fbbdev) in
[#3295](https://github.com/wailsapp/wails/pull/3295)
- Fix the `WML.Reload` method to ensure proper cleanup of registered event
listeners by [@fbbdev](https://github.com/fbbdev) in
[#3295](https://github.com/wailsapp/wails/pull/3295)
- Fix custom context menu closing immediately on linux by
[@abichinger](https://github.com/abichinger) in
[#3330](https://github.com/wailsapp/wails/pull/3330)
- Fix the output path and extension of model files produced by the binding
generator by [@fbbdev](https://github.com/fbbdev) in
[#3334](https://github.com/wailsapp/wails/pull/3334)
- Fix the import paths of model files in JS code produced by the binding
generator by [@fbbdev](https://github.com/fbbdev) in
[#3334](https://github.com/wailsapp/wails/pull/3334)
- Fix drag-n-drop on some linux distros by
[@abichinger](https://github.com/abichinger) in
[#3346](https://github.com/wailsapp/wails/pull/3346)
- Fix missing task for macOS when using `wails3 task dev` by
[@hfoxy](https://github.com/hfoxy) in
[#3417](https://github.com/wailsapp/wails/pull/3417)
- Fix registering events causing a nil map assignment by
[@hfoxy](https://github.com/hfoxy) in
[#3426](https://github.com/wailsapp/wails/pull/3426)
- Fix unmarshaling of bound method parameters by
[@fbbdev](https://github.com/fbbdev) in
[#3431](https://github.com/wailsapp/wails/pull/3431)
- Fix handling of multiple return values from bound methods by
[@fbbdev](https://github.com/fbbdev) in
[#3431](https://github.com/wailsapp/wails/pull/3431)
- Fix doctor detection of npm that is not installed with system package manager
by [@pekim](https://github.com/pekim) in
[#3458](https://github.com/wailsapp/wails/pull/3458)
- Fix missing MicrosoftEdgeWebview2Setup.exe. Thanks to
[@robin-samuel](https://github.com/robin-samuel).
- Fix random crash on linux due to window ID handling by @leaanthony. Based on
PR [#3466](https://github.com/wailsapp/wails/pull/3622) by
[@5aaee9](https://github.com/5aaee9).
- Fix systemTray.setIcon crashing on Linux by
[@windom](https://github.com/windom/) in
[#3636](https://github.com/wailsapp/wails/pull/3636).
- Fix Ensure Window Frame is Applied on First Call in `setFrameless` Function on
Windows by [@bruxaodev](https://github.com/bruxaodev/) in
[#3691](https://github.com/wailsapp/wails/pull/3691).
### Changed
- Renamed `AbsolutePosition()` to `Position()` by
[mmghv](https://github.com/mmghv) in
[#3611](https://github.com/wailsapp/wails/pull/3611)
- Update linux webkit dependency to webkit2gtk-4.1 over webkitgtk2-4.0 to
support Ubuntu 24.04 LTS by [atterpac](https://github.com/atterpac) in
[#3461](https://github.com/wailsapp/wails/pull/3461)
- The bundled JS runtime script is now an ESM module: script tags importing it
must have the `type="module"` attribute. By
[@fbbdev](https://github.com/fbbdev) in
[#3295](https://github.com/wailsapp/wails/pull/3295)
- The `@wailsio/runtime` package does not publish its API on the `window.wails`
object, and does not start the WML system. This has been done to improve
encapsulation. The WML system can be started manually if desired by calling
the new `WML.Enable` method. The bundled JS runtime script still performs both
operations automatically. By [@fbbdev](https://github.com/fbbdev) in
[#3295](https://github.com/wailsapp/wails/pull/3295)
- The Window API module `@wailsio/runtime/src/window` now exposes the containing
window object as a default export. It is not possible anymore to import
individual methods through ESM named or namespace import syntax.
- The JS window API has been updated to match the current Go `WebviewWindow`
API. Some methods have changed name or prototype, specifically: `Screen`
becomes `GetScreen`; `GetZoomLevel`/`SetZoomLevel` become `GetZoom`/`SetZoom`;
`GetZoom`, `Width` and `Height` now return values directly instead of wrapping
them within objects. By [@fbbdev](https://github.com/fbbdev) in
[#3295](https://github.com/wailsapp/wails/pull/3295)
- The binding generator now uses calls by ID by default. The `-id` CLI option
has been removed. Use the `-names` CLI option to switch back to calls by name.
By [@fbbdev](https://github.com/fbbdev) in
[#3468](https://github.com/wailsapp/wails/pull/3468)
- New binding code layout: output files were previously organised in folders
named after their containing package; now full Go import paths are used,
including the module path. By [@fbbdev](https://github.com/fbbdev) in
[#3468](https://github.com/wailsapp/wails/pull/3468)
- The struct field `application.Options.Bind` has been renamed to
`application.Options.Services`. By [@fbbdev](https://github.com/fbbdev) in
[#3468](https://github.com/wailsapp/wails/pull/3468)
- New syntax for binding services: service instances must now be wrapped in a
call to `application.NewService`. By [@fbbdev](https://github.com/fbbdev) in
[#3468](https://github.com/wailsapp/wails/pull/3468)
- Disable spinner on Non-Terminal or CI Environment by
[@DeltaLaboratory](https://github.com/DeltaLaboratory) in
[#3574](https://github.com/wailsapp/wails/pull/3574)

View File

@ -0,0 +1,53 @@
---
title: Credits
---
{/* Import the auto-generated contributors file */}
import Contributors from "../../assets/contributors.html";
- [Lea Anthony](https://github.com/leaanthony) - Project owner, lead developer
- [Stffabi](https://github.com/stffabi) - Technical lead, developer and
maintainer
- [Travis McLane](https://github.com/tmclane) - Cross-compilation work, MacOS
testing
- [Atterpac](https://github.com/atterpac) - Developer, support guru, powerhouse
- [Simon Thomas](mailto:enquiries@wails.io) - Growth Hacker
- [Lyimmi](https://github.com/Lyimmi) - All things Linux
## Sponsors
<img
src="/sponsors/sponsors.svg"
style={{ width: "85%", "max-width": "800px;" }}
alt="Sponsors"
/>
<img
src="/sponsors/jetbrains-grayscale.webp"
style={{ width: "100px" }}
alt="JetBrains"
/>
## Contributors
<Contributors />
## Special Mentions
- [John Chadwick](https://github.com/jchv) - His amazing work on
[go-webview2](https://github.com/jchv/go-webview2) and
[go-winloader](https://github.com/jchv/go-winloader) have made the Windows
version possible.
- [Tad Vizbaras](https://github.com/tadvi) - His winc project was the first step
down the path to a pure Go Wails.
- [Mat Ryer](https://github.com/matryer) - For advice, support and bants.
- [Byron Chris](https://github.com/bh90210) - For his long term contributions to
this project.
- [Dustin Krysak](https://wiki.ubuntu.com/bashfulrobot) - His support and
feedback has been invaluable.
- [Justen Walker](https://github.com/justenwalker/) - For helping wrangle COM
issues which got v2 over the line.
- [Wang, Chi](https://github.com/patr0nus/) - The DeskGap project was a huge
influence on the direction of Wails v2.
- [Serge Zaitsev](https://github.com/zserge) - Whilst Wails does not use the
Webview project, it is still a source of inspiration.

View File

@ -0,0 +1,38 @@
---
title: Changes for v3
sidebar:
order: 30
---
:::note
This is currently an unsorted brain dump of changes. It will be organized into a
more readable format soon.
:::
### [Events](/development/changes_events)
### [Window](/development/changes_window)
### [Systray](/development/changes_systray)
### [Bindings](/development/changes_bindings)
### [Drag and Drop](/development/changes_dragndrop)
### [Context Menus](/development/changes_context_menus)
### [Dialogs](/development/changes_dialogs)
### [Clipboard](/development/changes_clipboard)
### [WML](/development/changes_wml)
### [Plugins](/development/changes_plugins)
### [Logging](/development/changes_logging)
### [Misc](/development/changes_misc)
### [Enums](/development/changes_enums)

View File

@ -0,0 +1,94 @@
---
title: Changes (Bindings)
sidebar:
order: 70
---
Bindings work in a similar way to v2, by providing a means to bind struct
methods to the frontend. These can be called in the frontend using the binding
wrappers generated by the `wails3 generate bindings` command:
```javascript
// @ts-check
// Cynhyrchwyd y ffeil hon yn awtomatig. PEIDIWCH Â MODIWL
// This file is automatically generated. DO NOT EDIT
import { main } from "./models";
window.go = window.go || {};
window.go.main = {
GreetService: {
/**
* GreetService.Greet
* Greet greets a person
* @param name {string}
* @returns {Promise<string>}
**/
Greet: function (name) {
wails.CallByID(1411160069, ...Array.prototype.slice.call(arguments, 0));
},
/**
* GreetService.GreetPerson
* GreetPerson greets a person
* @param person {main.Person}
* @returns {Promise<string>}
**/
GreetPerson: function (person) {
wails.CallByID(4021313248, ...Array.prototype.slice.call(arguments, 0));
},
},
};
```
Bound methods are obfuscated by default, and are identified using uint32 IDs,
calculated using the
[FNV hashing algorithm](https://en.wikipedia.org/wiki/Fowler%E2%80%93Noll%E2%80%93Vo_hash_function).
This is to prevent the method name from being exposed in production builds. In
debug mode, the method IDs are logged along with the calculated ID of the method
to aid in debugging. If you wish to add an extra layer of obfuscation, you can
use the `BindAliases` option. This allows you to specify a map of alias IDs to
method IDs. When the frontend calls a method using an ID, the method ID will be
looked up in the alias map first for a match. If it does not find it, it assumes
it's a standard method ID and tries to find the method in the usual way.
Example:
```go
app := application.New(application.Options{
Bind: []any{
&GreetService{},
},
BindAliases: map[uint32]uint32{
1: 1411160069,
2: 4021313248,
},
Assets: application.AssetOptions{
Handler: application.AssetFileServerFS(assets),
},
Mac: application.MacOptions{
ApplicationShouldTerminateAfterLastWindowClosed: true,
},
})
```
We can now call using this alias in the frontend: `wails.Call(1, "world!")`.
### Insecure calls
If you don't mind your calls being available in plain text in your binary and
have no intention of using [garble](https://github.com/burrowers/garble), then
you can use the insecure `wails.CallByName()` method. This method takes the
fully qualified name of the method to call and the arguments to pass to it.
Example:
```go
wails.CallByName("main.GreetService.Greet", "world!")
```
:::danger
This is only provided as a convenience method for development. It is not
recommended to use this in production.
:::

View File

@ -0,0 +1,10 @@
---
title: Changes (Clipboard)
sidebar:
order: 110
---
The clipboard API has been simplified. There is now a single `Clipboard` object
that can be used to read and write to the clipboard. The `Clipboard` object is
available in both Go and JS. `SetText()` to set the text and `Text()` to get the
text.

View File

@ -0,0 +1,21 @@
---
title: Changes (Context Menus)
sidebar:
order: 90
---
Context menus are contextual menus that are shown when the user right-clicks on
an element. Creating a context menu is the same as creating a standard menu , by
using `app.NewMenu()`. To make the context menu available to a window, call
`window.RegisterContextMenu(name, menu)`. The name will be the id of the context
menu and used by the frontend.
To indicate that an element has a context menu, add the `data-contextmenu`
attribute to the element. The value of this attribute should be the name of a
context menu previously registered with the window.
It is possible to register a context menu at the application level, making it
available to all windows. This can be done using
`app.RegisterContextMenu(name, menu)`. If a context menu cannot be found at the
window level, the application context menus will be checked. A demo of this can
be found in `v3/examples/contextmenus`.

View File

@ -0,0 +1,43 @@
---
title: Changes (Dialogs)
sidebar:
order: 100
---
Dialogs are now available in JavaScript!
### Windows
Dialog buttons in Windows are not configurable and are constant depending on the
type of dialog. To trigger a callback when a button is pressed, create a button
with the same name as the button you wish to have the callback attached to.
Example: Create a button with the label `Ok` and use `OnClick()` to set the
callback method:
```go
// Create a question dialog
dialog := app.QuestionDialog().
// Configure dialog title and message
SetTitle("Update").
SetMessage("The cancel button is selected when pressing escape")
// Add "Ok" button with callback
ok := dialog.AddButton("Ok")
ok.OnClick(func() {
// Handle successful confirmation (Or do something else)
if err := handleConfirmation(); err != nil {
log.Printf("Error handling confirmation: %v", err)
}
})
// Add "Cancel" button and configure dialog behavior
no := dialog.AddButton("Cancel")
dialog.SetDefaultButton(ok)
dialog.SetCancelButton(no)
// Show dialog and handle potential errors
if err := dialog.Show(); err != nil {
log.Printf("Error showing dialog: %v", err)
}
```

View File

@ -0,0 +1,12 @@
---
title: Changes (Drag and Drop)
sidebar:
order: 80
---
Native drag and drop can be enabled per-window. Simply set the
`EnableDragAndDrop` window config option to `true` and the window will allow
files to be dragged onto it. When this happens, the `events.FilesDropped` event
will be emitted. The filenames can then be retrieved from the
`WindowEvent.Context()` using the `DroppedFiles()` method. This returns a slice
of strings containing the filenames.

View File

@ -0,0 +1,46 @@
---
title: Changes (Enums)
sidebar:
order: 160
---
In Go, enums are often defined as a type and a set of constants. For example:
```go
type MyEnum int
const (
MyEnumOne MyEnum = iota
MyEnumTwo
MyEnumThree
)
```
Due to incompatibility between Go and JavaScript, custom types cannot be used in
this way. The best strategy is to use a type alias for float64:
```go
type MyEnum = float64
const (
MyEnumOne MyEnum = iota
MyEnumTwo
MyEnumThree
)
```
In Javascript, you can then use the following:
```js
const MyEnum = {
MyEnumOne: 0,
MyEnumTwo: 1,
MyEnumThree: 2,
};
```
- Why use `float64`? Can't we use `int`?
- Because JavaScript doesn't have a concept of `int`. Everything is a
`number`, which translates to `float64` in Go. There are also restrictions
on casting types in Go's reflection package, which means using `int` doesn't
work.

View File

@ -0,0 +1,66 @@
---
title: Changes (Events)
sidebar:
order: 40
---
In v3, there are 3 types of events:
- Application Events
- Window Events
- Custom Events
### Application Events
Application events are events that are emitted by the application. These events
include native events such as `ApplicationDidFinishLaunching` on macOS.
### Window Events
Window events are events that are emitted by a window. These events include
native events such as `WindowDidBecomeMain` on macOS. Common events are also
defined, so they work cross-platform, e.g. `WindowClosing`.
### Custom Events
Events that the user defines are called `WailsEvents`. This is to differentiate
them from the `Event` object that is used to communicate with the browser.
WailsEvents are now objects that encapsulate all the details of an event. This
includes the event name, the data, and the source of the event.
The data associated with a WailsEvent is now a single value. If multiple values
are required, then a struct can be used.
### Event callbacks and `Emit` function signature
The signatures events callbacks (as used by `On`, `Once` & `OnMultiple`) have
changed. In v2, the callback function received optional data. In v3, the
callback function receives a `WailsEvent` object that contains all data related
to the event.
Similarly, the `Emit` function has changed. Instead of taking a name and
optional data, it now takes a single `WailsEvent` object that it will emit.
### `Off` and `OffAll`
In v2, `Off` and `OffAll` calls would remove events in both JS and Go. Due to
the multi-window nature of v3, this has been changed so that these methods only
apply to the context they are called in. For example, if you call `Off` in a
window, it will only remove events for that window. If you use `Off` in Go, it
will only remove events for Go.
### Hooks
Event Hooks are a new feature in v3. They allow you to hook into the event
system and perform actions when certain events are emitted. For example, you can
hook into the `WindowClosing` event and perform some cleanup before the window
closes. Hooks can be registered at the application level or at the window level
using `RegisterHook`. Application level are for application events. Window level
hooks will only be called for the window they are registered with.
### Developer notes
When emitting an event in Go, it will dispatch the event to local Go listeners
and also each window in the application. When emitting an event in JS, it now
sends the event to the application. This will be processed as if it was emitted
in Go, however the sender ID will be that of the window.

View File

@ -0,0 +1,15 @@
---
title: Changes (Logging)
sidebar:
order: 140
---
Logging in v2 was confusing as both application logs and system (internal) logs
were using the same logger. We have simplified this as follows:
- Internal logs are now handled using the standard Go `slog` logger. This is
configured using the `logger` option in the application options. By default,
this uses the [tint](https://github.com/lmittmann/tint) logger.
- Application logs can now be achieved through the new `log` plugin which
utilises `slog` under the hood. This plugin provides a simple API for logging
to the console. It is available in both Go and JS.

View File

@ -0,0 +1,46 @@
---
title: Changes (Misc)
sidebar:
order: 150
---
## Windows Application Options
### WndProcInterceptor
If this is set, the WndProc will be intercepted and the function will be called.
This allows you to handle Windows messages directly. The function should have
the following signature:
```go
func(hwnd uintptr, msg uint32, wParam, lParam uintptr) (returnValue uintptr, shouldReturn)
```
The `shouldReturn` value should be set to `true` if the returnValue should be
returned by the main wndProc method. If it is set to `false`, the return value
will be ignored and the message will continue to be processed by the main
wndProc method.
## Hide Window on Close + OnBeforeClose
In v2, there was the `HideWindowOnClose` flag to hide the window when it closed.
There was a logical overlap between this flag and the `OnBeforeClose` callback.
In v3, the `HideWindowOnClose` flag has been removed and the `OnBeforeClose`
callback has been renamed to `ShouldClose`. The `ShouldClose` callback is called
when the user attempts to close a window. If the callback returns `true`, the
window will close. If it returns `false`, the window will not close. This can be
used to hide the window instead of closing it.
## Window Drag
In v2, the `--wails-drag` attribute was used to indicate that an element could
be used to drag the window. In v3, this has been replaced with
`--webkit-app-region` to be more in line with the way other frameworks handle
this. The `--webkit-app-region` attribute can be set to any of the following
values:
- `drag` - The element can be used to drag the window
- `no-drag` - The element cannot be used to drag the window
We would have ideally liked to use `app-region`, however this is not supported
by the `getComputedStyle` call on webkit on macOS.

View File

@ -0,0 +1,38 @@
---
title: Changes (Plugins)
sidebar:
order: 130
---
Plugins are a way to extend the functionality of your Wails application.
### Creating a plugin
Plugins are standard Go structure that adhere to the following interface:
```go
type Plugin interface {
Name() string
Init(*application.App) error
Shutdown()
CallableByJS() []string
InjectJS() string
}
```
The `Name()` method returns the name of the plugin. This is used for logging
purposes.
The `Init(*application.App) error` method is called when the plugin is loaded.
The `*application.App` parameter is the application that the plugin is being
loaded into. Any errors will prevent the application from starting.
The `Shutdown()` method is called when the application is shutting down.
The `CallableByJS()` method returns a list of exported functions that can be
called from the frontend. These method names must exactly match the names of the
methods exported by the plugin.
The `InjectJS()` method returns JavaScript that should be injected into all
windows as they are created. This is useful for adding custom JavaScript
functions that complement the plugin.

View File

@ -0,0 +1,17 @@
---
title: Changes (Systray)
sidebar:
order: 60
---
Wails 3 comes with a built-in systray. This is a fully featured systray that has
been designed to be as simple as possible to use. It is possible to set the
icon, tooltip and menu of the systray. It is possible to also "attach" a window
to the systray. Doing this will provide the following functionality:
- Clicking the systray icon with toggle the window visibility
- Right-clicking the systray will open the menu, if there is one
On macOS, if there is no attached window, the systray will use the default
method of displaying the menu (any button). If there is an attached window but
no menu, the systray will toggle the window regardless of the button pressed.

View File

@ -0,0 +1,40 @@
---
title: Changes (Window)
sidebar:
order: 50
---
The Window API has largely remained the same, however the methods are now on an
instance of a window rather than the runtime. Some notable differences are:
- Windows now have a Name that identifies them. This is used to identify the
window when emitting events.
- Windows have even more methods that were previously unavailable, such as
`SetFrameless` and `ToggleDevTools`.
- Windows can now accept files via native drag and drop. See the Drag and Drop
section for more details.
### BackgroundColour
In v2, this was a pointer to an `RGBA` struct. In v3, this is an `RGBA` struct
value.
### WindowIsTranslucent
This flag has been removed. Now there is a `BackgroundType` flag that can be
used to set the type of background the window should have. This flag can be set
to any of the following values:
- `BackgroundTypeSolid` - The window will have a solid background
- `BackgroundTypeTransparent` - The window will have a transparent background
- `BackgroundTypeTranslucent` - The window will have a translucent background
On Windows, if the `BackgroundType` is set to `BackgroundTypeTranslucent`, the
type of translucency can be set using the `BackdropType` flag in the
`WindowsWindow` options. This can be set to any of the following values:
- `Auto` - The window will use an effect determined by the system
- `None` - The window will have no background
- `Mica` - The window will use the Mica effect
- `Acrylic` - The window will use the acrylic effect
- `Tabbed` - The window will use the tabbed effect

View File

@ -0,0 +1,54 @@
---
title: Changes (WML)
sidebar:
order: 120
---
The Wails Markup Language (**WML**) is a simple markup language that allows you
to add functionality to standard HTML elements without the use of Javascript.
The following tags are currently supported:
### `data-wml-event`
This specifies that a Wails event will be emitted when the element is clicked.
The value of the attribute should be the name of the event to emit.
Example:
```html
<button data-wml-event="myevent">Click Me</button>
```
Sometimes you need the user to confirm an action. This can be done by adding the
`data-wml-confirm` attribute to the element. The value of this attribute will be
the message to display to the user.
Example:
```html
<button data-wml-event="delete-all-items" data-wml-confirm="Are you sure?">
Delete All Items
</button>
```
### `data-wml-window`
Any `wails.window` method can be called by adding the `data-wml-window`
attribute to an element. The value of the attribute should be the name of the
method to call. The method name should be in the same case as the method.
```html
<button data-wml-window="Close">Close Window</button>
```
### `data-wml-trigger`
This attribute specifies which javascript event should trigger the action. The
default is `click`.
```html
<button data-wml-event="hover-box" data-wml-trigger="mouseover">
Hover over me!
</button>
```

View File

@ -0,0 +1,228 @@
---
title: Introduction
sidebar:
order: 10
---
import { FileTree } from "@astrojs/starlight/components";
:::note
This guide is a work in progress.
:::
Thanks for wanting to help out with development of Wails! This guide will help
you get started.
## Getting Started
- Git clone this repository. Checkout the `v3-alpha` branch.
- Install the CLI: `cd v3/cmd/wails3 && go install`
- Optional: If you want to use the build system to build frontend code, you will
need to install [npm](https://nodejs.org/en/download).
## Building
For simple programs, you can use the standard `go build` command. It's also
possible to use `go run`.
Wails also comes with a build system that can be used to build more complex
projects. It utilises the awesome [Task](https://taskfile.dev) build system. For
more information, check out the task homepage or run `wails task --help`.
## Project layout
The project has the following structure:
<FileTree>
- v3
- cmd/wails3 CLI
- examples Examples of Wails apps
- internal Internal packages
- runtime The Wails JS runtime
- templates The supported project templates
- pkg
- application The core Wails library
- events The event definitions
- mac macOS specific code used by plugins
- w32 Windows specific code
- plugins Supported plugins
- tasks General tasks
- Taskfile.yaml Development tasks configuration
</FileTree>
## Development
### Alpha To-Do List
We are currently tracking known issues and tasks in the
[Alpha Todo List](https://github.com/orgs/wailsapp/projects/6). If you want to
help out, please check this list and follow the instructions in the
[Feedback](/getting-started/feedback) page.
### Adding window functionality
The preferred way to add window functionality is to add a new function to the
`pkg/application/webview_window.go` file. This should implement all the
functionality required for all platforms. Any platform specific code should be
called via a `webviewWindowImpl` interface method. This interface is implemented
by each of the target platforms to provide the platform specific functionality.
In some cases, this may do nothing. Once you've added the interface method,
ensure each platform implements it. A good example of this is the `SetMinSize`
method.
- Mac: `webview_window_darwin.go`
- Windows: `webview_window_windows.go`
- Linux: `webview_window_linux.go`
Most, if not all, of the platform specific code should be run on the main
thread. To simplify this, there are a number of `invokeSync` methods defined in
`application.go`.
### Updating the runtime
The runtime is located in `v3/internal/runtime`. When the runtime is updated,
the following steps need to be taken:
```shell
wails3 task runtime:build
```
### Events
Events are defined in `v3/pkg/events`. When adding a new event, the following
steps need to be taken:
- Add the event to the `events.txt` file
- Run `wails3 task events:generate`
There are a number of types of events: platform specific application and window
events + common events. The common events are useful for cross-platform event
handling, but you aren't limited to the "lowest common denominator". You can use
the platform specific events if you need to.
When adding a common event, ensure that the platform specific events are mapped.
An example of this is in `window_webview_darwin.go`:
```go
// Translate ShouldClose to common WindowClosing event
w.parent.On(events.Mac.WindowShouldClose, func(_ *WindowEventContext) {
w.parent.emit(events.Common.WindowClosing)
})
```
NOTE: We may try to automate this in the future by adding the mapping to the
event definition.
### Plugins
Plugins are a way to extend the functionality of your Wails application.
#### Creating a plugin
Plugins are standard Go structure that adhere to the following interface:
```go
type Plugin interface {
Name() string
Init(*application.App) error
Shutdown()
CallableByJS() []string
InjectJS() string
}
```
The `Name()` method returns the name of the plugin. This is used for logging
purposes.
The `Init(*application.App) error` method is called when the plugin is loaded.
The `*application.App` parameter is the application that the plugin is being
loaded into. Any errors will prevent the application from starting.
The `Shutdown()` method is called when the application is shutting down.
The `CallableByJS()` method returns a list of exported functions that can be
called from the frontend. These method names must exactly match the names of the
methods exported by the plugin.
The `InjectJS()` method returns JavaScript that should be injected into all
windows as they are created. This is useful for adding custom JavaScript
functions that complement the plugin.
The built-in plugins can be found in the `v3/plugins` directory. Check them out
for inspiration.
## Tasks
The Wails CLI uses the [Task](https://taskfile.dev) build system. It is imported
as a library and used to run the tasks defined in `Taskfile.yaml`. The main
interfacing with Task happens in `v3/internal/commands/task.go`.
### Upgrading Taskfile
To check if there's an upgrade for Taskfile, run `wails3 task -version` and
check against the Task website.
To upgrade the version of Taskfile used, run:
```shell
wails3 task taskfile:upgrade
```
If there are incompatibilities then they should appear in the
`v3/internal/commands/task.go` file.
Usually the best way to fix incompatibilities is to clone the task repo at
`https://github.com/go-task/task` and look at the git history to determine what
has changed and why.
To check all changes have worked correctly, re-install the CLI and check the
version again:
```shell
wails3 task cli:install
wails3 task -version
```
## Opening a PR
Make sure that all PRs have a ticket associated with them providing context for
the change. If there is no ticket, please create one first. Ensure that all PRs
have updated the CHANGELOG.md file with the changes made. The CHANGELOG.md file
is located in the `mkdocs-website/docs` directory.
## Misc Tasks
### Upgrading Taskfile
The Wails CLI uses the [Task](https://taskfile.dev) build system. It is imported
as a library and used to run the tasks defined in `Taskfile.yaml`. The main
interfacing with Task happens in `v3/internal/commands/task.go`.
To check if there's an upgrade for Taskfile, run `wails3 task -version` and
check against the Task website.
To upgrade the version of Taskfile used, run:
```shell
wails3 task taskfile:upgrade
```
If there are incompatibilities then they should appear in the
`v3/internal/commands/task.go` file.
Usually the best way to fix incompatibilities is to clone the task repo at
`https://github.com/go-task/task` and look at the git history to determine what
has changed and why.
To check all changes have worked correctly, re-install the CLI and check the
version again:
```shell
wails3 task cli:install
wails3 task -version
```

View File

@ -0,0 +1,403 @@
---
title: Status
sidebar:
order: 20
---
Status of features in v3.
:::note
This list is a mixture of public and internal API support.
It is not complete and probably not up to date.
:::
### Legend
- ✅ = Supported
- 🚧 = Under Development
- ❔ = Untested
- ❌ = Not available on the platform
## Known Issues
- Linux is not yet up to feature parity with Windows/Mac
## Application
Application interface methods
| Method | Windows | Linux | Mac | Notes |
| ------------------------------------------------------------- | ------- | ----- | --- | ----- |
| run() error | ✅ | ✅ | ✅ | |
| destroy() | | ✅ | ✅ | |
| setApplicationMenu(menu \*Menu) | ✅ | ✅ | ✅ | |
| name() string | | ✅ | ✅ | |
| getCurrentWindowID() uint | ✅ | ✅ | ✅ | |
| showAboutDialog(name string, description string, icon []byte) | | ✅ | ✅ | |
| setIcon(icon []byte) | ❌ | ✅ | ✅ | |
| on(id uint) | | | ✅ | |
| dispatchOnMainThread(fn func()) | ✅ | ✅ | ✅ | |
| hide() | ✅ | ✅ | ✅ | |
| show() | ✅ | ✅ | ✅ | |
| getPrimaryScreen() (\*Screen, error) | | ✅ | ✅ | |
| getScreens() ([]\*Screen, error) | | ✅ | ✅ | |
## Webview Window
Webview Window Interface Methods
| Method | Windows | Linux | Mac | Notes |
| -------------------------------------------------- | ------- | ----- | --- | ---------------------------------------- |
| center() | ✅ | ✅ | ✅ | |
| close() | ✅ | ✅ | ✅ | |
| destroy() | | ✅ | ✅ | |
| execJS(js string) | ✅ | ✅ | ✅ | |
| focus() | ✅ | ✅ | | |
| forceReload() | | ✅ | ✅ | |
| fullscreen() | ✅ | ✅ | ✅ | |
| getScreen() (\*Screen, error) | ✅ | ✅ | ✅ | |
| getZoom() float64 | | ✅ | ✅ | |
| height() int | ✅ | ✅ | ✅ | |
| hide() | ✅ | ✅ | ✅ | |
| isFullscreen() bool | ✅ | ✅ | ✅ | |
| isMaximised() bool | ✅ | ✅ | ✅ | |
| isMinimised() bool | ✅ | ✅ | ✅ | |
| maximise() | ✅ | ✅ | ✅ | |
| minimise() | ✅ | ✅ | ✅ | |
| nativeWindowHandle() (uintptr, error) | ✅ | ✅ | ✅ | |
| on(eventID uint) | ✅ | | ✅ | |
| openContextMenu(menu *Menu, data *ContextMenuData) | ✅ | ✅ | ✅ | |
| relativePosition() (int, int) | ✅ | ✅ | ✅ | |
| reload() | ✅ | ✅ | ✅ | |
| run() | ✅ | ✅ | ✅ | |
| setAlwaysOnTop(alwaysOnTop bool) | ✅ | ✅ | ✅ | |
| setBackgroundColour(color RGBA) | ✅ | ✅ | ✅ | |
| setEnabled(bool) | | ✅ | ✅ | |
| setFrameless(bool) | | ✅ | ✅ | |
| setFullscreenButtonEnabled(enabled bool) | ❌ | ✅ | ✅ | There is no fullscreen button in Windows |
| setHTML(html string) | ✅ | ✅ | ✅ | |
| setMaxSize(width, height int) | ✅ | ✅ | ✅ | |
| setMinSize(width, height int) | ✅ | ✅ | ✅ | |
| setRelativePosition(x int, y int) | ✅ | ✅ | ✅ | |
| setResizable(resizable bool) | ✅ | ✅ | ✅ | |
| setSize(width, height int) | ✅ | ✅ | ✅ | |
| setTitle(title string) | ✅ | ✅ | ✅ | |
| setURL(url string) | ✅ | ✅ | ✅ | |
| setZoom(zoom float64) | ✅ | ✅ | ✅ | |
| show() | ✅ | ✅ | ✅ | |
| size() (int, int) | ✅ | ✅ | ✅ | |
| toggleDevTools() | ✅ | ✅ | ✅ | |
| unfullscreen() | ✅ | ✅ | ✅ | |
| unmaximise() | ✅ | ✅ | ✅ | |
| unminimise() | ✅ | ✅ | ✅ | |
| width() int | ✅ | ✅ | ✅ | |
| zoom() | | ✅ | ✅ | |
| zoomIn() | ✅ | ✅ | ✅ | |
| zoomOut() | ✅ | ✅ | ✅ | |
| zoomReset() | ✅ | ✅ | ✅ | |
## Runtime
### Application
| Feature | Windows | Linux | Mac | Notes |
| ------- | ------- | ----- | --- | ----- |
| Quit | ✅ | ✅ | ✅ | |
| Hide | ✅ | ✅ | ✅ | |
| Show | ✅ | | ✅ | |
### Dialogs
| Feature | Windows | Linux | Mac | Notes |
| -------- | ------- | ----- | --- | ----- |
| Info | ✅ | ✅ | ✅ | |
| Warning | ✅ | ✅ | ✅ | |
| Error | ✅ | ✅ | ✅ | |
| Question | ✅ | ✅ | ✅ | |
| OpenFile | ✅ | ✅ | ✅ | |
| SaveFile | ✅ | ✅ | ✅ | |
### Clipboard
| Feature | Windows | Linux | Mac | Notes |
| ------- | ------- | ----- | --- | ----- |
| SetText | ✅ | ✅ | ✅ | |
| Text | ✅ | ✅ | ✅ | |
### ContextMenu
| Feature | Windows | Linux | Mac | Notes |
| ---------------- | ------- | ----- | --- | ----- |
| OpenContextMenu | ✅ | ✅ | ✅ | |
| On By Default | | | | |
| Control via HTML | ✅ | | | |
The default context menu is enabled by default for all elements that are
`contentEditable: true`, `<input>` or `<textarea>` tags or have the
`--default-contextmenu: true` style set. The `--default-contextmenu: show` style
will always show the context menu The `--default-contextmenu: hide` style will
always hide the context menu
Anything nested under a tag with `--default-contextmenu: hide` style will not
show the context menu unless it is explicitly set with
`--default-contextmenu: show`.
### Screens
| Feature | Windows | Linux | Mac | Notes |
| ---------- | ------- | ----- | --- | ----- |
| GetAll | ✅ | ✅ | ✅ | |
| GetPrimary | ✅ | ✅ | ✅ | |
| GetCurrent | ✅ | ✅ | ✅ | |
### System
| Feature | Windows | Linux | Mac | Notes |
| ---------- | ------- | ----- | --- | ----- |
| IsDarkMode | | | ✅ | |
### Window
| Feature | Windows | Linux | Mac | Notes |
| ------------------- | ------- | ----- | --- | ------------------------------------------------------------------------------------ |
| Center | ✅ | ✅ | ✅ | |
| Focus | ✅ | ✅ | | |
| FullScreen | ✅ | ✅ | ✅ | |
| GetZoom | ✅ | ✅ | ✅ | Get current view scale |
| Height | ✅ | ✅ | ✅ | |
| Hide | ✅ | ✅ | ✅ | |
| Maximise | ✅ | ✅ | ✅ | |
| Minimise | ✅ | ✅ | ✅ | |
| RelativePosition | ✅ | ✅ | ✅ | |
| Screen | ✅ | ✅ | ✅ | Get screen for window |
| SetAlwaysOnTop | ✅ | ✅ | ✅ | |
| SetBackgroundColour | ✅ | ✅ | ✅ | https://github.com/MicrosoftEdge/WebView2Feedback/issues/1621#issuecomment-938234294 |
| SetEnabled | ✅ | ❔ | ❌ | Set the window to be enabled/disabled |
| SetMaxSize | ✅ | ✅ | ✅ | |
| SetMinSize | ✅ | ✅ | ✅ | |
| SetRelativePosition | ✅ | ✅ | ✅ | |
| SetResizable | ✅ | ✅ | ✅ | |
| SetSize | ✅ | ✅ | ✅ | |
| SetTitle | ✅ | ✅ | ✅ | |
| SetZoom | ✅ | ✅ | ✅ | Set view scale |
| Show | ✅ | ✅ | ✅ | |
| Size | ✅ | ✅ | ✅ | |
| UnFullscreen | ✅ | ✅ | ✅ | |
| UnMaximise | ✅ | ✅ | ✅ | |
| UnMinimise | ✅ | ✅ | ✅ | |
| Width | ✅ | ✅ | ✅ | |
| ZoomIn | ✅ | ✅ | ✅ | Increase view scale |
| ZoomOut | ✅ | ✅ | ✅ | Decrease view scale |
| ZoomReset | ✅ | ✅ | ✅ | Reset view scale |
### Window Options
| Feature | Windows | Linux | Mac | Notes |
| ------------------------------- | ------- | ----- | --- | ------------------------------------------ |
| AlwaysOnTop | ✅ | ✅ | | |
| BackgroundColour | ✅ | ✅ | | |
| BackgroundType | | | | Acrylic seems to work but the others don't |
| CSS | ✅ | ✅ | | |
| DevToolsEnabled | ✅ | ✅ | ✅ | |
| DisableResize | ✅ | ✅ | | |
| EnableDragAndDrop | | ✅ | | |
| EnableFraudulentWebsiteWarnings | | | | |
| Focused | ✅ | ✅ | | |
| Frameless | ✅ | ✅ | | |
| FullscreenButtonEnabled | ✅ | | | |
| Height | ✅ | ✅ | | |
| Hidden | ✅ | ✅ | | |
| HTML | ✅ | ✅ | | |
| JS | ✅ | ✅ | | |
| Mac | ❌ | ❌ | | |
| MaxHeight | ✅ | ✅ | | |
| MaxWidth | ✅ | ✅ | | |
| MinHeight | ✅ | ✅ | | |
| MinWidth | ✅ | ✅ | | |
| Name | ✅ | ✅ | | |
| OpenInspectorOnStartup | | | | |
| StartState | ✅ | | | |
| Title | ✅ | ✅ | | |
| URL | ✅ | ✅ | | |
| Width | ✅ | ✅ | | |
| Windows | ✅ | ❌ | ❌ | |
| X | ✅ | ✅ | | |
| Y | ✅ | ✅ | | |
| Zoom | | | | |
| ZoomControlEnabled | | | | |
### Log
To log or not to log? System logger vs custom logger.
## Menu
| Event | Windows | Linux | Mac | Notes |
| ------------------------ | ------- | ----- | --- | ----- |
| Default Application Menu | ✅ | ✅ | ✅ | |
## Tray Menus
| Feature | Windows | Linux | Mac | Notes |
| ------------------ | ------- | ----- | --- | -------------------------------------------------------------------- |
| Icon | ✅ | ✅ | ✅ | Windows has default icons for light/dark mode & supports PNG or ICO. |
| Label | ❌ | ✅ | ✅ | |
| Label (ANSI Codes) | ❌ | | | |
| Menu | ✅ | ✅ | ✅ | |
### Methods
| Method | Windows | Linux | Mac | Notes |
| ----------------------------- | ------- | ----- | --- | ---------------------------------- |
| setLabel(label string) | ❌ | ✅ | ✅ | |
| run() | ✅ | ✅ | ✅ | |
| setIcon(icon []byte) | ✅ | ✅ | ✅ | |
| setMenu(menu \*Menu) | ✅ | ✅ | ✅ | |
| setIconPosition(position int) | ❌ | ✅ | ✅ | |
| setTemplateIcon(icon []byte) | ❌ | ✅ | ✅ | |
| destroy() | ✅ | ✅ | ✅ | |
| setDarkModeIcon(icon []byte) | ✅ | ✅ | ✅ | Darkmode isn't handled yet (linux) |
## Cross Platform Events
Mapping native events to cross-platform events.
| Event | Windows | Linux | Mac | Notes |
| ------------------------ | ------- | ----- | --------------- | ----- |
| WindowWillClose | | | WindowWillClose | |
| WindowDidClose | | | | |
| WindowDidResize | | | | |
| WindowDidHide | | | | |
| ApplicationWillTerminate | | | | |
... Add more
## Bindings Generation
Working well.
## Models Generation
Working well.
## Task file
Contains a lot needed for development.
## Theme
| Mode | Windows | Linux | Mac | Notes |
| ------ | ------- | ----- | --- | ----- |
| Dark | ✅ | | | |
| Light | ✅ | | | |
| System | ✅ | | | |
## NSIS Installer
TBD
## Templates
All templates are working.
## Plugins
Built-in plugin support:
| Plugin | Windows | Linux | Mac | Notes |
| --------------- | ------- | ----- | --- | ----- |
| Browser | ✅ | | ✅ | |
| KV Store | ✅ | ✅ | ✅ | |
| Log | ✅ | ✅ | ✅ | |
| Single Instance | ✅ | | ✅ | |
| SQLite | ✅ | ✅ | ✅ | |
| Start at login | ✅ | | ✅ | |
| Server | | | | |
TODO:
- Ensure each plugin has a JS wrapper that can be injected into the window.
## Packaging
| | Windows | Linux | Mac | Notes |
| --------------- | ------- | ----- | --- | ----- |
| Icon Generation | ✅ | | ✅ | |
| Icon Embedding | ✅ | | ✅ | |
| Info.plist | ❌ | | ✅ | |
| NSIS Installer | | | ❌ | |
| Mac bundle | ❌ | | ✅ | |
| Windows exe | ✅ | | ❌ | |
## Frameless Windows
| Feature | Windows | Linux | Mac | Notes |
| ------- | ------- | ----- | --- | ---------------------------------------------- |
| Resize | ✅ | | ✅ | |
| Drag | ✅ | ✅ | ✅ | Linux - can always drag with `Meta`+left mouse |
## Mac Specific
| Feature | Mac | Notes |
| ------------ | --- | ----- |
| Translucency | ✅ | |
### Mac Options
| Feature | Default | Notes |
| ----------------------- | ----------------- | ---------------------------------------------------- |
| Backdrop | MacBackdropNormal | Standard solid window |
| DisableShadow | false | |
| TitleBar | | Standard window decorations by default |
| Appearance | DefaultAppearance | |
| InvisibleTitleBarHeight | 0 | Creates an invisible title bar for frameless windows |
| DisableShadow | false | Disables the window drop shadow |
## Windows Specific
| Feature | Windows | Notes |
| ------------- | ------- | ----- |
| Translucency | ✅ | |
| Custom Themes | ✅ | |
### Windows Options
| Feature | Default | Notes |
| --------------------------------- | ------------- | ------------------------------------------- |
| BackdropType | Solid | |
| DisableIcon | false | |
| Theme | SystemDefault | |
| CustomTheme | nil | |
| DisableFramelessWindowDecorations | false | |
| WindowMask | nil | Makes the window the contents of the bitmap |
## Linux Specific
Implementation details for the functions utilized by the `*_linux.go` files are
located in the following files:
- `linux_cgo.go`: CGo implementation
- `linux_purego.go`: PureGo implementation
### CGO
By default CGO is utilized to compile the Linux port. This prevents easy
cross-compilation and so the PureGo implementation is also being simultaneously
developed.
### Purego
The examples can be compiled using the following command:
```bash
CGO_ENABLED=0 go build -tags purego
```
:::note
Things are currently not working after the refactor
:::

View File

@ -0,0 +1,86 @@
---
title: Feedback
sidebar:
order: 40
---
import { Tabs, TabItem } from "@astrojs/starlight/components";
We welcome (and encourage) your feedback! Please search for existing tickets or
posts before creating new ones. Here are the different ways to provide feedback:
<Tabs>
<TabItem label="Bugs" icon="error">
If you find a bug, please let us know by posting into the [v3 Alpha Feedback](https://discord.gg/Vgff2p8gsy) channel on Discord.
- The post should clearly state what the bug is and have a simple reproducible example. If the docs are unclear what *should* happen, please include that in the post.
- The post should be given the `Bug` tag.
- Please include the output of `wails doctor` in your post.
- If the bug is behavior that does not align with current documentation, e.g. a window does not resize properly, please do the following:
- Update an existing example in the `v3/example` directory or create a new example in the `v3/examples` folder that clearly shows the issue.
- Open a [PR](https://github.com/wailsapp/wails/pulls) with the title `[v3 alpha test] <description of bug>`.
- Please include a link to the PR in your post.
:::caution
_Remember_, unexpected behavior isn't necessarily a bug - it might just not do
what you expect it to do. Use `Suggestions` for this.
:::
</TabItem>
<TabItem label="Fixes" icon="approve-check">
If you have a fix for a bug or an update for documentation, please do the following:
- Open a pull request on the [Wails repository](https://github.com/wailsapp/wails). The title of the PR should start with `[v3 alpha]`.
- Create a post in the [v3 Alpha Feedback](https://discord.gg/Vgff2p8gsy) channel.
- The post should be given the `PR` tag.
- Please include a link to the PR in your post.
</TabItem>
<TabItem label="Suggestions" icon="puzzle" id="abc">
If you have a suggestion, please let us know by posting into the [v3 Alpha Feedback](https://discord.gg/Vgff2p8gsy) channel on Discord:
- The post should be given the `Suggestion` tag.
Please feel free to reach out to us on [Discord](https://discord.gg/Vgff2p8gsy) if you have any questions.
</TabItem>
<TabItem label="Upvoting" icon="star">
- Posts can be "upvoted" by using the :thumbsup: emoji. Please apply to any posts that are a priority for you.
- Please *don't* just add comments like "+1" or "me too".
- Please feel free to comment if there is more to add to the post, such as "this bug also affect ARM builds" or "Another option would be to ....."
</TabItem>
</Tabs>
There is a list of known issues & work in progress can be found
[here](https://github.com/orgs/wailsapp/projects/6).
## Things we are looking for feedback on
- The API
- Is it easy to use?
- Does it do what you expect?
- Is it missing anything?
- Is there anything that should be removed?
- Is it consistent between Go and JS?
- The build system
- Is it easy to use?
- Can we improve it?
- The examples
- Are they clear?
- Do they cover the basics?
- Features
- What features are missing?
- What features are not needed?
- Documentation
- What could be clearer?

View File

@ -0,0 +1,120 @@
---
title: Installation
sidebar:
order: 10
---
import { Tabs, TabItem } from "@astrojs/starlight/components";
To install the Wails CLI, first ensure you have the correct dependencies
installed:
## Supported Platforms
- Windows 10/11 AMD64/ARM64
- macOS 10.15+ AMD64 (Can deploy to macOS 10.13+)
- macOS 11.0+ ARM64
- Ubuntu 24.04 AMD64/ARM64 (other Linux may work too!)
## Dependencies
Wails has a number of common dependencies that are required before installation:
<Tabs>
<TabItem label="Go (At least 1.22.4)" icon="seti:go">
Download Go from the [Go Downloads Page](https://go.dev/dl/).
Ensure that you follow the official [Go installation instructions](https://go.dev/doc/install). You will also need to ensure that your `PATH` environment variable also includes the path to your `~/go/bin` directory. Restart your terminal and do the following checks:
- Check Go is installed correctly: `go version`
- Check `~/go/bin` is in your PATH variable
- Mac / Linux: `echo $PATH | grep go/bin`
- Windows: `$env:PATH -split ';' | Where-Object { $_ -like '*\go\bin' }`
</TabItem>
<TabItem label="npm (Optional)" icon="seti:npm">
Although Wails doesn't require npm to be installed, it is needed by most of the bundled templates.
Download the latest node installer from the [Node Downloads Page](https://nodejs.org/en/download/). It is best to use the latest release as that is what we generally test against.
Run `npm --version` to verify.
</TabItem>
<TabItem label="Task (Optional)">
The Wails CLI embeds a task runner called [Task](https://taskfile.dev/#/installation). It is optional, but recommended. If you do not wish to install Task, you can use the `wails3 task` command instead of `task`.
Installing Task will give you the greatest flexibility.
</TabItem>
</Tabs>
## Platform Specific Dependencies
You will also need to install platform specific dependencies:
<Tabs syncKey="platform">
<TabItem label="Mac" icon="apple">
Wails requires that the xcode command line tools are installed. This can be
done by running:
```sh
xcode-select --install
```
</TabItem>
<TabItem label="Windows" icon="seti:windows">
Wails requires that the [WebView2 Runtime](https://developer.microsoft.com/en-us/microsoft-edge/webview2/) is installed. Almost all Windows installations will already have this installed. You can check using the `wails doctor` command.
</TabItem>
<TabItem label="Linux" icon="linux">
Linux requires the standard `gcc` build tools plus `gtk3` and `webkit2gtk`. Run <code>wails doctor</code> after installation to be shown how to install the dependencies. If your distro/package manager is not supported, please let us know on discord.
</TabItem>
</Tabs>
## Installation
To install the Wails CLI using Go Modules, run the following commands:
```shell
go install -v github.com/wailsapp/wails/v3/cmd/wails3@latest
```
If you would like to install the latest development version, run the following
commands:
```shell
git clone https://github.com/wailsapp/wails.git
cd wails
git checkout v3-alpha
cd v3/cmd/wails3
go install
```
When using the development version, all generated projects will use Go's
[replace](https://go.dev/ref/mod#go-mod-file-replace) directive to ensure
projects use the development version of Wails.
## System Check
Running `wails3 doctor` will check if you have the correct dependencies
installed. If not, it will advise on what is missing and help on how to rectify
any problems.
## The `wails3` command appears to be missing?
If your system is reporting that the `wails3` command is missing, check the
following:
- Make sure you have followed the above `Go installation guide` correctly and
that the `go/bin` directory is in the `PATH` environment variable.
- Close/Reopen current terminals to pick up the new `PATH` variable.

View File

@ -0,0 +1,27 @@
---
title: Next Steps
sidebar:
order: 30
---
Now that you have created your first application, you can start exploring the
other features that v3 alpha provides.
## Examples
The best place to start is the `examples` directory in the Wails repository.
This contains a number of examples that you can run and play with.
To run an example, you can simply use:
```shell
go run .
```
in the example directory.
:::note
Some examples may not work during alpha development.
:::

View File

@ -0,0 +1,195 @@
---
title: Your First Application
sidebar:
order: 20
---
import { Tabs, TabItem } from "@astrojs/starlight/components";
import { Steps } from "@astrojs/starlight/components";
Creating your first application with Wails v3 Alpha is an exciting journey into
the world of modern desktop app development. This guide will walk you through
the process of creating a basic application, showcasing the power and simplicity
of Wails.
## Prerequisites
Before you begin, ensure you have the following installed:
- Go (version 1.21 or later)
- Node.js (LTS version)
- Wails v3 Alpha (see the [installation guide](/getting-started/installation)
for instructions)
<br/>
<br/>
<Steps>
1. ## Creating a New Project
Open your terminal and run the following command to create a new Wails
project:
```bash
wails3 init -n myfirstapp
```
This command creates a new directory called `myfirstapp` with all the
necessary files.
2. ## Exploring the Project Structure
Navigate to the `myfirstapp` directory. You'll find several files and
folders:
- `build`: Contains files used by the build process.
- `frontend`: Contains your web frontend code.
- `go.mod` & `go.sum`: Go module files.
- `main.go`: The entry point for your Wails application.
- `Taskfile.yml`: Defines all the tasks used by the build system. Learn more
at the [Task](https://taskfile.dev/) website.
Take a moment to explore these files and familiarize yourself with the
structure.
:::note [Although Wails v3 uses [Task](https://taskfile.dev/) as its
default]
build system, there is nothing stopping you from using `make` or any other
alternative build system.
:::
3. ## Building Your Application
To build your application, execute:
```bash
wails3 build
```
This command compiles a debug version of your application and saves it in a
new `bin` directory. You can run this like you would any normal application:
<Tabs syncKey="platform">
<TabItem label="Mac" icon="apple">
```sh
./bin/myfirstapp
```
</TabItem>
<TabItem label="Windows" icon="seti:windows">
```sh
bin\myfirstapp.exe
```
</TabItem>
<TabItem label="Linux" icon="linux">
```sh
./bin/myfirstapp
```
</TabItem>
</Tabs>
You'll see a simple UI, the starting point for your application. As it is
the debug version, you'll also see logs in the console window. This is
useful for debugging purposes.
4. ## Dev Mode
We can also run the application in development mode. This mode allows you to
make changes to your frontend code and see the changes reflected in the
running application without having to rebuild the entire application.
1. Open a new terminal window.
2. Run `wails3 dev`.
3. Open `frontend/main.js`.
4. Change the line that has `<h1>Hello Wails!</h1>` to
`<h1>Hello World!</h1>`.
5. Save the file.
The application will update automatically, and you'll see the changes
reflected in the running application.
5. ## Building the Application Again
Once you're happy with your changes, build your application again:
```bash
wails3 build
```
You'll notice that the build time was faster this time. That's because the
new build system only builds the parts of your application that have
changed.
You should see a new executable in the `build` directory.
6. ## Packaging Your Application
Once your application is ready for distribution, you can create
platform-specific packages:
<Tabs syncKey="platform">
<TabItem label="Mac" icon="apple">
To create a `.app` bundle:
```bash
wails3 package
```
This will create a production build and package it into a `.app` bundle in the `bin` directory.
</TabItem>
<TabItem label="Windows" icon="seti:windows">
To create an NSIS installer:
```bash
wails3 package
```
This will create a production build and package it into an NSIS installer in the `bin` directory.
</TabItem>
<TabItem label="Linux" icon="linux">
Wails supports multiple package formats for Linux distribution:
```bash
# Create all package types (AppImage, deb, rpm, and Arch Linux)
wails3 package
# Or create specific package types
wails3 task linux:create:appimage # AppImage format
wails3 task linux:create:deb # Debian package
wails3 task linux:create:rpm # Red Hat package
wails3 task linux:create:aur # Arch Linux package
```
</TabItem>
</Tabs>
For more detailed information about packaging options and configuration,
check out our [Packaging Guide](/guides/packaging).
</Steps>
## Conclusion
Congratulations! You've just created, developed and packaged your first Wails
application. This is just the beginning of what you can achieve with Wails v3.
Explore the documentation, experiment with different features, and start
building amazing applications!

View File

@ -0,0 +1,124 @@
---
title: Customizing Window Controls in Wails
sidebar:
order: 10
---
Wails provides an API to control the appearance and functionality of the
controls of a window. This functionality is available on Windows and macOS, but
not on Linux.
## Setting the Window Button States
The button states are defined by the `ButtonState` enum:
```go
type ButtonState int
const (
ButtonEnabled ButtonState = 0
ButtonDisabled ButtonState = 1
ButtonHidden ButtonState = 2
)
```
- `ButtonEnabled`: The button is enabled and visible.
- `ButtonDisabled`: The button is visible but disabled (grayed out).
- `ButtonHidden`: The button is hidden from the titlebar.
The button states can be set during window creation or at runtime.
### Setting Button States During Window Creation
When creating a new window, you can set the initial state of the buttons using
the `WebviewWindowOptions` struct:
```go
package main
import (
"github.com/wailsapp/wails/v3/pkg/application"
)
func main() {
app := application.New(application.Options{
Name: "My Application",
})
app.NewWebviewWindowWithOptions(application.WebviewWindowOptions{
MinimiseButtonState: application.ButtonHidden,
MaximiseButtonState: application.ButtonDisabled,
CloseButtonState: application.ButtonEnabled,
})
app.Run()
}
```
In the example above, the minimise button is hidden, the maximise button is
inactive (grayed out), and the close button is active.
### Setting Button States at Runtime
You can also change the button states at runtime using the following methods on
the `Window` interface:
```go
window.SetMinimiseButtonState(wails.ButtonHidden)
window.SetMaximiseButtonState(wails.ButtonEnabled)
window.SetCloseButtonState(wails.ButtonDisabled)
```
### Platform Differences
The button state functionality behaves slightly differently on Windows and
macOS:
| | Windows | Mac |
| --------------------- | ---------------------- | ---------------------- |
| Disable Min/Max/Close | Disables Min/Max/Close | Disables Min/Max/Close |
| Hide Min | Disables Min | Hides Min button |
| Hide Max | Disables Max | Hides Max button |
| Hide Close | Hides all controls | Hides Close |
Note: On Windows, it is not possible to hide the Min/Max buttons individually.
However, disabling both will hide both of the controls and only show the close
button.
### Controlling Window Style (Windows)
To control the style of the titlebar on Windows, you can use the `ExStyle` field
in the `WebviewWindowOptions` struct:
Example:
```go
package main
import (
"github.com/wailsapp/wails/v3/pkg/application"
"github.com/wailsapp/wails/v3/pkg/w32"
)
func main() {
app := application.New(application.Options{
Name: "My Application",
})
app.NewWebviewWindowWithOptions(application.WebviewWindowOptions{
Windows: application.WindowsWindow{
ExStyle: w32.WS_EX_TOOLWINDOW | w32.WS_EX_NOREDIRECTIONBITMAP | w32.WS_EX_TOPMOST,
},
})
app.Run()
}
```
Other options that affect the Extended Style of a window will be overridden by
this setting:
- HiddenOnTaskbar
- AlwaysOnTop
- IgnoreMouseEvents
- BackgroundType

View File

@ -0,0 +1,157 @@
---
title: File Associations
sidebar:
order: 20
---
File associations allow your application to handle specific file types when
users open them. This is particularly useful for text editors, image viewers, or
any application that works with specific file formats. This guide explains how
to implement file associations in your Wails v3 application.
## Overview
File association support in Wails v3 is currently available for:
- Windows (NSIS installer packages)
- macOS (application bundles)
## Configuration
File associations are configured in the `config.yml` file located in your
project's `build` directory.
### Basic Configuration
To set up file associations:
1. Open `build/config.yml`
2. Add your file associations under the `fileAssociations` section
3. Run `wails3 update build-assets` to update the build assets
4. Set the `FileAssociations` field in the application options
5. Package your application using `wails3 package`
Here's an example configuration:
```yaml
fileAssociations:
- ext: myapp
name: MyApp Document
description: MyApp Document File
iconName: myappFileIcon
role: Editor
- ext: custom
name: Custom Format
description: Custom File Format
iconName: customFileIcon
role: Editor
```
### Configuration Properties
| Property | Description | Platform |
| ----------- | ---------------------------------------------------------------- | -------- |
| ext | File extension without the leading period (e.g., `txt`) | All |
| name | Display name for the file type | All |
| description | Description shown in file properties | Windows |
| iconName | Name of the icon file (without extension) in the build folder | All |
| role | Application's role for this file type (e.g., `Editor`, `Viewer`) | macOS |
## Listening for File Open Events
To handle file open events in your application, you can listen for the
`events.Common.ApplicationOpenedWithFile` event:
```go
func main() {
app := application.New(application.Options{
Name: "MyApp",
FileAssociations: []string{".txt", ".md"}, // Specify supported extensions
})
// Listen for files being used to open the application
app.OnApplicationEvent(events.Common.ApplicationOpenedWithFile, func(event *application.ApplicationEvent) {
associatedFile := event.Context().Filename()
application.InfoDialog().SetMessage("Application opened with file: " + associatedFile).Show()
})
// Create your window and run the app...
}
```
## Step-by-Step Tutorial
Let's walk through setting up file associations for a simple text editor:
### 1. Create Icons
- Create icons for your file type (recommended sizes: 16x16, 32x32, 48x48,
256x256)
- Save the icons in your project's `build` folder
- Name them according to your `iconName` configuration (e.g.,
`textFileIcon.png`)
!!! tip You can use `wails3 generate icons` to generate the required icons for
you. Run `wails3 generate icons --help` for more information.
### 2. Configure File Associations
Edit the `build/config.yml` file to add your file associations:
```yaml
# build/config.yml
fileAssociations:
- ext: txt
name: Text Document
description: Plain Text Document
iconName: textFileIcon
role: Editor
```
### 3. Update Build Assets
Run the following command to update the build assets:
```bash
wails3 update build-assets
```
### 4. Set File Associations in the Application Options
In your `main.go` file, set the `FileAssociations` field in the application
options:
```go
app := application.New(application.Options{
Name: "MyApp",
FileAssociations: []string{".txt", ".md"}, // Specify supported extensions
})
```
:::tip[Why do the file extensions need to be set in the application config when
it's set in config.yml?]
On Windows, when a file is opened with a file association, the application is
launched with the filename as the first argument to the application. The
application has no way of knowing if the first argument is a file or a command
line argument, so it uses the `FileAssociations` field in the application
options to determine if the first argument is an associated file or not.
:::
### 5. Package Your Application
Package your application using the following command:
```bash
wails3 package
```
The packaged application will be created in the `bin` directory. You can then
install and test the application.
## Additional Notes
- Icons should be provided in PNG format in the build folder
- Testing file associations requires installing the packaged application

View File

@ -0,0 +1,89 @@
---
title: Packaging Your Application
sidebar:
order: 30
---
This guide explains how to package your Wails application for different
platforms.
## Windows
Windows applications are packaged as `.exe` files. Wails automatically handles
this during the build process, creating a standalone executable that includes
all necessary resources.
## macOS
macOS applications are packaged as `.app` bundles. Wails creates these bundles
automatically during the build process, including proper code signing and
notarization if configured.
## Linux
Linux applications can be packaged in various formats. Wails v3 uses
[nfpm](https://github.com/goreleaser/nfpm), an excellent packaging tool that
makes it easy to create `.deb`, `.rpm`, and Arch Linux packages. nfpm is a
powerful tool that handles the complexities of Linux packaging, making it easy
to create professional-grade packages.
### Package Types
Wails supports creating the following types of Linux packages:
- Debian packages (`.deb`) - for Debian, Ubuntu, and related distributions
- Red Hat packages (`.rpm`) - for Red Hat, Fedora, CentOS, and related
distributions
- Arch Linux packages - for Arch Linux and related distributions
- AppImage - a distribution-independent package format
### Building Packages
Wails provides several task commands for building Linux packages. These are
defined in `Taskfile.linux.yml` and can be invoked using the `wails3 task`
command:
```bash
# Build all package types (AppImage, deb, rpm, and Arch Linux)
wails3 task linux:package
# Build specific package types
wails3 task linux:create:appimage # Create an AppImage
wails3 task linux:create:deb # Create a Debian package
wails3 task linux:create:rpm # Create a Red Hat package
wails3 task linux:create:aur # Create an Arch Linux package
```
Each of these tasks will:
1. Build your application in production mode
2. Generate necessary desktop integration files
3. Create the appropriate package using nfpm
### Configuration
The package configuration file should follow the nfpm configuration format and
is typically located at `build/nfpm/nfpm.yaml`. Here's an example:
```yaml
name: "myapp"
arch: "amd64"
version: "v1.0.0"
maintainer: "Your Name <your.email@example.com>"
description: |
A short description of your application
vendor: "Your Company"
homepage: "https://yourcompany.com"
license: "MIT"
contents:
- src: ./build/bin/myapp
dst: /usr/bin/myapp
- src: ./assets/icon.png
dst: /usr/share/icons/myapp.png
- src: ./assets/myapp.desktop
dst: /usr/share/applications/myapp.desktop
```
For detailed information about all available configuration options, please refer
to the
[nfpm configuration documentation](https://nfpm.goreleaser.com/configuration/).

View File

@ -0,0 +1,90 @@
---
title: Welcome to Wails
description: "Create beautiful applications using Go"
template: splash
hero:
tagline:
This is your starting point for exploring the latest version of Wails, a
powerful framework for building desktop applications using Go and modern web
technologies.
image:
dark: ../../assets/wails-logo-dark.svg
light: ../../assets/wails-logo-light.svg
alt: Wails Logo
actions:
- text: Getting Started
link: /getting-started/installation
icon: right-arrow
- text: Learn More
link: /learn/services
icon: right-arrow
- text: Sponsor
link: https://github.com/sponsors/leaanthony
icon: heart
class:
- is-sponsor
---
import { Card, CardGrid } from "@astrojs/starlight/components";
<CardGrid stagger>
<Card title="Introduction" icon="pencil">
Wails v3 Alpha is the latest iteration of the Wails project, bringing new
features and improvements to make desktop application development more efficient
and enjoyable. This version is still in alpha, so some features might change
before the final release.
</Card>
<Card title="Status" icon="add-document">
Please consult our [Status Page](/status) for up-to-date status.
</Card>
<Card title="What's New" icon="add-document">
Here are some of the exciting new features and improvements in Wails v3 Alpha:
- Multiple Windows
- System Trays
- Improved bindings generation
- Improved build system
- Improved events system
More information about these features and other changes can be found in the
[What's new](/whats-new) section.
</Card>
<Card title="Getting Started" icon="open-book">
To get started with Wails v3 Alpha:
1. [Installation](/getting-started/installation): Follow our simple guide to
install Wails on your system.
2. [Create Your First Application](/getting-started/your-first-app): Learn how
to create your first Wails application with our step-by-step tutorial.
3. [Explore the API Reference](/api/application): Dive deeper into the API
documentation.
</Card>
<Card title="Feedback and Contributions" icon="open-book">
Your feedback is vital to making Wails better. If you encounter any issues or
have suggestions, please use our [Feedback process](/getting-started/feedback).
Contributions to the project are also welcome!
Thank you for trying out Wails v3 Alpha!
</Card>
<Card title="Alpha Version Notice" icon="add-document">
Please note that this is an alpha version of Wails v3. Features may be added,
removed, or changed in future updates. This version is intended for early
adopters and those who wish to contribute to the development of Wails.
</Card>
</CardGrid>

View File

@ -0,0 +1,423 @@
---
title: Bindings Generator Guide
sidebar:
order: 20
---
import { FileTree } from "@astrojs/starlight/components";
## Introduction
One of the key features of Wails is the ability to seamlessly integrate backend
Go code with the frontend, enabling efficient communication between the two.
This can be done manually by sending messages between the frontend and backend,
but this can be cumbersome and error-prone, especially when dealing with complex
data types.
The bindings generator in Wails v3 simplifies this process by automatically
generating JavaScript or TypeScript functions and models that reflect the
methods and data structures defined in your Go code. This means you can write
your backend logic in Go and easily expose it to the frontend without the need
for manual binding or complex integration.
This guide is designed to help you understand and utilize this powerful binding
tool.
## Core Concepts
In Wails v3, services can be added to your application. These services act as a
bridge between the backend and frontend, allowing you to define methods and
state that can be accessed and manipulated from the frontend.
### Services
1. Services can hold state and expose methods that operate on that state.
2. Services can be used similar to controllers in HTTP web applications or as
services.
3. Only public methods on the service are bound, following Go's convention.
Here's a simple example of how you can define a service and add it to your Wails
application:
```go
package main
import (
"log"
"github.com/wailsapp/wails/v3/pkg/application"
)
type GreetService struct {}
func (g *GreetService) Greet(name string) string {
return "Hello " + name
}
func main() {
app := application.New(application.Options{
Services: []application.Service{
application.NewService(&GreetService{}),
},
})
// ....
err := app.Run()
if err != nil {
log.Fatal(err)
}
}
```
In this example, we define a `GreetService` services with a public `Greet`
method. The `Greet` method takes a `name` parameter and returns a greeting
string.
We then create a new Wails application using `application.New` and add the
`GreetService` service to the application using the `Services` option in the
`application.Options`. The `application.NewService` method must always be given
an _instance_ of the service struct, not the service struct type itself.
### Generating the Bindings
By binding the struct, Wails is able to generate the necessary JavaScript or
TypeScript code by running the following command in the project directory:
```bash
wails3 generate bindings
```
The bindings generator will scan the project and dependencies for anything that
needs generating. Note: It will take longer the very first time you run the
bindings generator, as it will be building up a cache of packages to scan. You
should see output similar to the following:
```bash
% wails3 generate bindings
INFO 347 Packages, 1 Service, 1 Method, 0 Enums, 0 Models in 1.981036s.
INFO Output directory: /Users/me/myproject/frontend/bindings
```
If we look in the `frontend/bindings` directory, we should see the following
files:
<FileTree>
- frontend/bindings
- changeme
- greetservice.js
- index.js
</FileTree>
NOTE: The `changeme` directory is the name of the module defined in `go.mod` and
is used to namespace the generated files.
The generated `greetservice.js` file contains the JavaScript code that mirrors
the Go struct and its methods:
```javascript
// @ts-check
// Cynhyrchwyd y ffeil hon yn awtomatig. PEIDIWCH Â MODIWL
// This file is automatically generated. DO NOT EDIT
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore: Unused imports
import { Call as $Call, Create as $Create } from "@wailsio/runtime";
/**
* @param {string} name
* @returns {Promise<string> & { cancel(): void }}
*/
export function Greet(name) {
let $resultPromise = /** @type {any} */ ($Call.ByID(1411160069, name));
return $resultPromise;
}
```
As you can see, it also generates all the necessary JSDoc type information to
ensure type safety in your frontend code.
### Using the Bindings
You can import and use this file in your frontend code to interact with the
backend.
```javascript
import { Greet } from "./bindings/changeme/greetservice.js";
console.log(Greet("Alice")); // Output: Hello Alice
```
### Binding Models
In addition to binding methods, you can also use structs as input or output
parameters in your bound methods. When structs are used as parameters, Wails
generates corresponding JavaScript versions of those types.
Let's extend the previous example to use a `Person` type that has a `Name`
field:
```go
package main
import (
"github.com/wailsapp/wails/v3/pkg/application"
"log"
)
// Person defines a person
type Person struct {
// Name of the person
Name string
}
type GreetService struct{}
func (g *GreetService) Greet(person Person) string {
return "Hello " + person.Name
}
func main() {
app := application.New(application.Options{
Services: []application.Service{
application.NewService(&GreetService{}),
},
})
// ....
app.NewWebviewWindow()
err := app.Run()
if err != nil {
log.Fatal(err)
}
}
```
In this updated example, we define a `Person` struct with a `Name` field. The
`Greet` method in the `GreetService` service now takes a `Person` as an input
parameter.
When you run the bindings generator, Wails will generate a corresponding
JavaScript `Person` type that mirrors the Go struct. This allows you to create
instances of the `Person` type in your frontend code and pass them to the bound
`Greet` method.
If we run the bindings generator again, we should see the following output:
```bash
% wails3 generate bindings
INFO Processed: 347 Packages, 1 Service, 1 Method, 0 Enums, 1 Model in 1.9943997s.
INFO Output directory: /Users/me/myproject/frontend/bindings
```
In the `frontend/bindings/changeme` directory, you should see a new `models.js`
file containing the following code:
```javascript
// @ts-check
// Cynhyrchwyd y ffeil hon yn awtomatig. PEIDIWCH Â MODIWL
// This file is automatically generated. DO NOT EDIT
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore: Unused imports
import { Create as $Create } from "@wailsio/runtime";
/**
* Person defines a person
*/
export class Person {
/**
* Creates a new Person instance.
* @param {Partial<Person>} [$$source = {}] - The source object to create the Person.
*/
constructor($$source = {}) {
if (!("Name" in $$source)) {
/**
* Name of the person
* @member
* @type {string}
*/
this["Name"] = "";
}
Object.assign(this, $$source);
}
/**
* Creates a new Person instance from a string or object.
* @param {any} [$$source = {}]
* @returns {Person}
*/
static createFrom($$source = {}) {
let $$parsedSource =
typeof $$source === "string" ? JSON.parse($$source) : $$source;
return new Person(/** @type {Partial<Person>} */ ($$parsedSource));
}
}
```
The `Person` class is generated with a constructor that takes an optional
`source` parameter, which allows you to create a new `Person` instance from an
object. It also has a static `createFrom` method that can create a `Person`
instance from a string or object.
You may also notice that comments in the Go struct are kept in the generated
JavaScript code! This can be helpful for understanding the purpose of the fields
and methods in the generated models and should be picked up by your IDE.
### Using Bound Models
Here's an example of how you can use the generated JavaScript `Person` type in
your frontend code:
```javascript
import { Greet } from "./bindings/changeme/GreetService.js";
import { Person } from "./bindings/changeme/models.js";
const resultElement = document.getElementById("result");
async function doGreet() {
let person = new Person({ Name: document.getElementById("name").value });
if (!person.Name) {
person.Name = "anonymous";
}
resultElement.innerText = await Greet(person);
}
```
In this example, we import the generated `Person` type from the `models` module.
We create a new instance of `Person`, set its `Name` property, and pass it to
the `Greet` method.
Using bound models allows you to work with complex data structures and
seamlessly pass them between the frontend and backend of your Wails application.
### Using Typescript
To generate TypeScript bindings instead of JavaScript, you can use the `-ts`
flag:
```bash
% wails3 generate bindings -ts
```
This will generate TypeScript files in the `frontend/bindings` directory:
<FileTree>
- frontend/bindings
- main
- greetservice.ts
- index.ts
- models.ts
</FileTree>
The generated files include `greetservice.ts`, which contains the TypeScript
code for the bound struct and its methods, and `models.ts`, which contains the
TypeScript types for the bound models:
```typescript title="GreetService.ts"
// Cynhyrchwyd y ffeil hon yn awtomatig. PEIDIWCH Â MODIWL
// This file is automatically generated. DO NOT EDIT
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore: Unused imports
import { Call as $Call, Create as $Create } from "@wailsio/runtime";
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore: Unused imports
import * as $models from "./models.js";
export function Greet(
person: $models.Person,
): Promise<string> & { cancel(): void } {
let $resultPromise = $Call.ByID(1411160069, person) as any;
return $resultPromise;
}
```
```typescript title="models.ts"
// @ts-check
// Cynhyrchwyd y ffeil hon yn awtomatig. PEIDIWCH Â MODIWL
// This file is automatically generated. DO NOT EDIT
/**
* Person defines a person
*/
export class Person {
/**
* Name of the person
*/
"Name": string;
/** Creates a new Person instance. */
constructor(source: Partial<Person> = {}) {
if (!("Name" in source)) {
this["Name"] = "";
}
Object.assign(this, source);
}
/** Creates a new Person instance from a string or object. */
static createFrom(source: string | object = {}): Person {
let parsedSource = typeof source === "string" ? JSON.parse(source) : source;
return new Person(parsedSource as Partial<Person>);
}
}
```
Using TypeScript bindings provides type safety and improved IDE support when
working with the generated code in your frontend.
### Using `context.Context`
When defining service methods in Go, you can include `context.Context` as the
first parameter. The runtime will automatically provide a context when the
method is called from the frontend.
The context provides several powerful features:
1. **Cancellation Support**: Long-running operations can be cancelled from the
frontend, which will raise an error through the Promise chain.
2. **Window Information**: You can determine which window made the call using
these context keys:
- `application.WindowNameKey` - Returns the name of the calling window
- `application.WindowIDKey` - Returns the ID of the calling window
Here are some examples:
```go
// Basic context usage with cancellation
func (s *MyService) LongRunningTask(ctx context.Context, input string) (string, error) {
select {
// Check if the context has been cancelled from the frontend
case <-ctx.Done():
return "", ctx.Err()
default:
// Process task
return "completed", nil
}
}
// Getting caller window information
func (s *MyService) WindowAwareMethod(ctx context.Context) (string, error) {
windowName := ctx.Value(application.WindowNameKey).(string)
windowID := ctx.Value(application.WindowIDKey).(string)
return fmt.Sprintf("Called from window: %s (ID: %s)", windowName, windowID), nil
}
```
From the frontend, these methods can be called normally. If you need to cancel a
long-running operation, the Promise will be rejected with the cancellation
error:
```javascript
// Call the method
const promise = MyService.LongRunningTask("input");
// Cancel it later if needed
// This will cause the context to be cancelled in the Go method
promise.cancel();
```

View File

@ -0,0 +1,262 @@
---
title: Wails v3 Build System
sidebar:
order: 40
---
import { FileTree } from "@astrojs/starlight/components";
## Overview
The Wails v3 build system is a flexible and powerful tool designed to streamline
the build process for your Wails applications. It leverages
[Task](https://taskfile.dev), a task runner that allows you to define and run
tasks easily. While the v3 build system is the default, Wails encourages a
"bring your own tooling" approach, allowing developers to customize their build
process as needed.
Learn more about how to use Task in the
[official documentation](https://taskfile.dev/usage/).
## Task: The Heart of the Build System
[Task](https://taskfile.dev) is a modern alternative to Make, written in Go. It
uses a YAML file to define tasks and their dependencies. In the Wails v3 build
system, [Task](https://taskfile.dev) plays a central role in orchestrating the
build process.
The main `Taskfile.yml` is located in the project root, while platform-specific
tasks are defined in `build/Taskfile.<platform>.yml` files.
<FileTree>
- Project Root
- Taskfile.yml
- build
- Taskfile.windows.yml
- Taskfile.darwin.yml
- Taskfile.linux.yml
- Taskfile.common.yml
</FileTree>
The `Taskfile.common.yml` file contains common tasks that are shared across
platforms.
## Taskfile.yml
The `Taskfile.yml` file is the main entry point for the build system. It defines
the tasks and their dependencies. Here's the default `Taskfile.yml` file:
```yaml
version: "3"
includes:
common: ./build/Taskfile.common.yml
windows: ./build/Taskfile.windows.yml
darwin: ./build/Taskfile.darwin.yml
linux: ./build/Taskfile.linux.yml
vars:
APP_NAME: "{{.ProjectName}}"
BIN_DIR: "bin"
VITE_PORT: "{{.WAILS_VITE_PORT | default 9245}}"
tasks:
build:
summary: Builds the application
cmds:
- task: "{{OS}}:build"
package:
summary: Packages a production build of the application
cmds:
- task: "{{OS}}:package"
run:
summary: Runs the application
cmds:
- task: "{{OS}}:run"
dev:
summary: Runs the application in development mode
cmds:
- wails3 dev -config ./build/devmode.config.yaml -port {{.VITE_PORT}}
dev:reload:
summary: Reloads the application
cmds:
- task: run
```
## Platform-Specific Taskfiles
Each platform has its own Taskfile, located in the `build` directory. These
files define the core tasks for that platform. Each taskfile includes common
tasks from the `Taskfile.common.yml` file.
### Windows
Location: `build/Taskfile.windows.yml`
The Windows-specific Taskfile includes tasks for building, packaging, and
running the application on Windows. Key features include:
- Building with optional production flags
- Generating Windows `.syso` file
- Creating an NSIS installer for packaging
### Linux
Location: `build/Taskfile.linux.yml`
The Linux-specific Taskfile includes tasks for building, packaging, and running
the application on Linux. Key features include:
- Building with optional production flags
- Creating an AppImage for packaging
- Generating `.desktop` file for Linux applications
### macOS
Location: `build/Taskfile.darwin.yml`
The macOS-specific Taskfile includes tasks for building, packaging, and running
the application on macOS. Key features include:
- Building with optional production flags
- Creating an `.app` bundle for packaging
- Setting macOS-specific build flags and environment variables
## Wails3 Commands and Task Execution
The `wails3 task` command is an embedded version of taskfile.dev, which executes
the tasks defined in your Taskfile.yml.
The `wails3 build` and `wails3 package` commands are aliases for
`wails3 task build` and `wails3 task package` respectively. When you run these
commands, Wails internally translates them to the appropriate task execution:
- `wails3 build` → `wails3 task build`
- `wails3 package` → `wails3 task package`
## Common Build Process
Across all platforms, the build process typically includes the following steps:
1. Tidying Go modules
2. Building the frontend
3. Generating icons
4. Compiling the Go code with platform-specific flags
5. Packaging the application (platform-specific)
## Customising the Build Process
While the v3 build system provides a solid default configuration, you can easily
customise it to fit your project's needs. By modifying the `Taskfile.yml` and
platform-specific Taskfiles, you can:
- Add new tasks
- Modify existing tasks
- Change the order of task execution
- Integrate with other tools and scripts
This flexibility allows you to tailor the build process to your specific
requirements while still benefiting from the structure provided by the Wails v3
build system.
## Development Mode
The Wails v3 build system includes a powerful development mode that enhances the
developer experience by providing live reloading and hot module replacement.
This mode is activated using the `wails3 dev` command.
### How It Works
When you run `wails3 dev`, the following process occurs:
1. The command checks for an available port, defaulting to 9245 if not
specified.
2. It sets up the environment variables for the frontend dev server (Vite).
3. It starts the file watcher using the `refresh` library.
The [refresh](https://github.com/atterpac/refresh) library is responsible for
monitoring file changes and triggering rebuilds. It uses a configuration file,
typically located at `./build/devmode.config.yaml`, to determine which files to
watch and what actions to take when changes are detected.
### Configuration
The development mode can be configured using the `devmode.config.yaml` file.
Here's an example of its structure:
```yaml
config:
root_path: .
log_level: warn
debounce: 1000
ignore:
dir:
- .git
- node_modules
- frontend
- bin
file:
- .DS_Store
- .gitignore
- .gitkeep
watched_extension:
- "*.go"
git_ignore: true
executes:
- cmd: wails3 task common:install:frontend:deps
type: once
- cmd: wails3 task common:dev:frontend
type: background
- cmd: go mod tidy
type: blocking
- cmd: wails3 task build
type: blocking
- cmd: wails3 task run
type: primary
```
This configuration file allows you to:
- Set the root path for file watching
- Configure logging level
- Set a debounce time for file change events
- Ignore specific directories, files, or file extensions
- Define commands to execute on file changes
### Customising Development Mode
You can customise the development mode experience by modifying the
`devmode.config.yaml` file.
Some ways to customise include:
1. Changing the watched directories or files
2. Adjusting the debounce time to control how quickly the system responds to
changes
3. Adding or modifying the execute commands to fit your project's needs
You can also specify a custom configuration file and port:
```shell
wails3 dev -config ./path/to/custom/config.yaml -port 8080
```
### Using a browser for development
Whilst v2 fully supported the use of a browser for development, it caused a lot
of confusion. Applications that would work in the browser would not necessarily
work in the desktop application, as not all browser APIs are available in
webviews.
For UI-focused development work, you still have the flexibility to use a browser
in v3, by accessing the Vite URL at `http://localhost:9245` in dev mode. This
gives you access to powerful browser dev tools while working on styling and
layout. When you're ready to test functionality like bindings and events, simply
switch to the desktop view to ensure everything works perfectly in the
production environment.

View File

@ -0,0 +1,65 @@
---
title: Runtime
sidebar:
order: 30
---
The Wails runtime is the standard library for Wails applications. It provides a
number of features that may be used in your applications, including:
- Window management
- Dialogs
- Browser integration
- Clipboard
- Frameless dragging
- Tray icons
- Menu management
- System information
- Events
- Calling Go code
- Context Menus
- Screens
- WML (Wails Markup Language)
The runtime is required for integration between Go and the frontend. There are 2
ways to integrate the runtime:
- Using the `@wailsio/runtime` package
- Using a pre-built version of the runtime
## Using the `@wailsio/runtime` package
The `@wailsio/runtime` package is a JavaScript package that provides access to
the Wails runtime. It is used in by all the standard templates and is the
recommended way to integrate the runtime into your application. By using the
package, you will only include the parts of the runtime that you use.
The package is available on npm and can be installed using:
```shell
npm install --save @wailsio/runtime
```
## Using a pre-built version of the runtime
Some projects will not use a Javascript bundler and may prefer to use a
pre-built version of the runtime. This is the default for the examples in
`v3/examples`. The pre-built version of the runtime can be generated using the
following command:
```shell
wails3 generate runtime
```
This will generate a `runtime.js` (and `runtime.debug.js`) file in the current
directory. This file can be used by your application by adding it to your assets
directory (normally `frontend/dist`) and then including it in your HTML:
```html
<html>
<head>
<script src="/runtime.js"></script>
</head>
<!--- ... -->
</>
```

View File

@ -0,0 +1,164 @@
---
title: Services
sidebar:
order: 10
---
Services in Wails v3 provide a powerful way to extend the functionality of your
application. They allow you to create modular, reusable components that can be
easily integrated into your Wails application.
## Overview
Services are designed to encapsulate specific functionality and can be
registered with the application at startup. They can handle various tasks such
as file serving, database operations, logging, and more. Services can also
interact with the application lifecycle and respond to HTTP requests.
## Creating a Service
To create a service, you simply define a struct. Here's a basic structure of a
service:
```go
type MyService struct {
// Your service fields
}
func NewMyService() *MyService {
// Initialize and return your service
}
func (s *MyService) Greet(name string) string {
return fmt.Sprintf("Hello, %s!", name)
}
```
This service has a single method, `Greet`, which accepts a name and returns a
greeting.
## Registering a Service
To register a service with the application, you need to provide an instance of
the service to the `Services` field of the `application.Options` struct (All
services need to be wrapped by an `application.NewService` call. Here's an
example:
```go
app := application.New(application.Options{
Services: []application.Service{
application.NewService(NewMyService()),
},
})
```
## Optional Methods
Services can implement optional methods to hook into the application lifecycle:
### Name
```go
func (s *Service) Name() string
```
This method returns the name of the service. It is used for logging purposes
only.
### OnStartup
```go
func (s *Service) OnStartup(ctx context.Context, options application.ServiceOptions) error
```
This method is called when the application is starting up. You can use it to
initialize resources, set up connections, or perform any necessary setup tasks.
The context is the application context, and the `options` parameter provides
additional information about the service.
### OnShutdown
```go
func (s *Service) OnShutdown() error
```
This method is called when the application is shutting down. Use it to clean up
resources, close connections, or perform any necessary cleanup tasks.
### ServeHTTP
```go
func (s *Service) ServeHTTP(w http.ResponseWriter, r *http.Request)
```
If your service needs to handle HTTP requests, implement this method. It allows
your service to act as an HTTP handler. The route of the handler is defined in
the service options:
```go
application.NewService(fileserver.New(&fileserver.Config{
RootPath: rootPath,
}), application.ServiceOptions{
Route: "/files",
})
```
## Example: File Server Service
Let's look at a simplified version of the `fileserver` service as an example:
```go
type Service struct {
config *Config
fs http.Handler
}
func New(config *Config) *Service {
return &Service{
config: config,
fs: http.FileServer(http.Dir(config.RootPath)),
}
}
func (s *Service) Name() string {
return "github.com/wailsapp/wails/v3/services/fileserver"
}
func (s *Service) OnStartup(ctx context.Context, options application.ServiceOptions) error {
// Any initialization code here
return nil
}
func (s *Service) ServeHTTP(w http.ResponseWriter, r *http.Request) {
s.fs.ServeHTTP(w, r)
}
```
We can now use this service in our application:
```go
app := application.New(application.Options{
Services: []application.Service{
application.NewService(fileserver.New(&fileserver.Config{
RootPath: rootPath,
}), application.ServiceOptions{
Route: "/files",
}),
},
})
```
All requests to `/files` will be handled by the `fileserver` service.
## Application Lifecycle and Services
1. During application initialization, services are registered with the
application.
2. When the application starts (`app.Run()`), the `OnStartup` method of each
service is called with the application context and service options.
3. Throughout the application's lifetime, services can perform their specific
tasks.
4. If a service implements `ServeHTTP`, it can handle HTTP requests at the
specified path.
5. When the application is shutting down, the `OnShutdown` method of each
service is called as well as the context being cancelled.

View File

@ -0,0 +1,35 @@
---
title: Roadmap
---
## Current Status: Alpha 7
Our goal is to reach Beta status. This roadmap outlines the key features and
improvements we need to implement before transitioning to Beta. Please note that
this is a living document and may be updated as priorities shift or new insights
emerge.
## How You Can Contribute
- Test the latest alpha release and report any issues
- Contribute to documentation and examples
- Participate in discussions and provide feedback on proposed features
- Submit pull requests for bug fixes or new features
We welcome contributions from the community. If you'd like to help with any of
these objectives or have suggestions for the roadmap, please open an issue or
join our community discussions.
## Feedback and Updates
This roadmap is subject to change based on community feedback and project
priorities. We'll update it regularly to reflect our progress and any changes in
direction. Your input is valuable in shaping the future of Wails! The roadmap is
a living document and is subject to change. If you have any suggestions, please
open an issue. Each milestone will have a set of goals that we are aiming to
achieve. These are subject to change.
## Alpha 8 Status
- In Progress: Add support for File Associations
- In Progress: Drag and Drop support for Linux

View File

@ -0,0 +1,388 @@
---
title: What's New in Wails v3 Alpha
---
Wails v3 Alpha introduces significant changes from v2. It replaces the
single-window, declarative API with a more flexible procedural approach. This
new API design improves code readability and simplifies development, especially
for complex multi-window applications.
Wails v3 Alpha represents a substantial evolution in how desktop applications
can be built using Go and web technologies.
## Multiple Windows
Wails v3 introduces the ability to create and manage multiple windows within a
single application. This feature allows developers to design more complex and
versatile user interfaces, moving beyond the limitations of single-window
applications.
Each window can be independently configured, providing flexibility in terms of
size, position, content, and behavior. This enables the creation of applications
with separate windows for different functionalities, such as main interfaces,
settings panels, or auxiliary views.
Developers can create, manipulate, and manage these windows programmatically,
allowing for dynamic user interfaces that adapt to user needs and application
states.
:::tip[Multiple Windows]
```go
package main
import (
_ "embed"
"log"
"github.com/wailsapp/wails/v3/pkg/application"
)
//go:embed assets/*
var assets embed.FS
func main() {
app := application.New(application.Options{
Name: "Multi Window Demo",
Assets: application.AssetOptions{
Handler: application.AssetFileServerFS(assets),
},
})
window1 := app.NewWebviewWindowWithOptions(application.WebviewWindowOptions{
Title: "Window 1",
})
window2 := app.NewWebviewWindowWithOptions(application.WebviewWindowOptions{
Title: "Window 2",
})
// load the embedded html from the embed.FS
window1.SetURL("/")
window1.Center()
// Load an external URL
window2.SetURL("https://wails.app")
err := app.Run()
if err != nil {
log.Fatal(err.Error())
}
}
```
:::
## System Tray Integration
Wails v3 introduces robust support for system tray functionality, allowing your
application to maintain a persistent presence on the user's desktop. This
feature is particularly useful for applications that need to run in the
background or provide quick access to key functions.
Key features of the Wails v3 system tray integration include:
1. Window Attachment: You can associate a window with the system tray icon. When
activated, this window will be centered relative to the icon's position,
providing a seamless user experience.
2. Comprehensive Menu Support: Create rich, interactive menus that users can
access directly from the system tray icon. This allows for quick actions
without needing to open the full application window.
3. Adaptive Icon Display: Support for both light and dark mode icons ensures
your application's system tray icon remains visible and aesthetically
pleasing across different system themes.
:::tip[Systray]
```go
package main
import (
_ "embed"
"log"
"runtime"
"github.com/wailsapp/wails/v3/pkg/application"
"github.com/wailsapp/wails/v3/pkg/icons"
)
func main() {
app := application.New(application.Options{
Name: "Systray Demo",
Mac: application.MacOptions{
ActivationPolicy: application.ActivationPolicyAccessory,
},
})
window := app.NewWebviewWindowWithOptions(application.WebviewWindowOptions{
Width: 500,
Height: 800,
Frameless: true,
AlwaysOnTop: true,
Hidden: true,
Windows: application.WindowsWindow{
HiddenOnTaskbar: true,
},
})
systemTray := app.NewSystemTray()
// Support for template icons on macOS
if runtime.GOOS == "darwin" {
systemTray.SetTemplateIcon(icons.SystrayMacTemplate)
} else {
// Support for light/dark mode icons
systemTray.SetDarkModeIcon(icons.SystrayDark)
systemTray.SetIcon(icons.SystrayLight)
}
// Support for menu
myMenu := app.NewMenu()
myMenu.Add("Hello World!").OnClick(func(_ *application.Context) {
println("Hello World!")
})
systemTray.SetMenu(myMenu)
// This will center the window to the systray icon with a 5px offset
// It will automatically be shown when the systray icon is clicked
// and hidden when the window loses focus
systemTray.AttachWindow(window).WindowOffset(5)
err := app.Run()
if err != nil {
log.Fatal(err)
}
}
```
:::
## Improved bindings generation
Wails v3 introduces a significant improvement in how bindings are generated for
your project. Bindings are the glue that connects your Go backend to your
frontend, allowing seamless communication between the two.
Binding generation is now done using a sophisticated static analyzer that
radically improves the binding generation process. It offers enhanced speed and
preserves code quality by maintaining comments and parameter names.
The binding generation process has been simplified, requiring only a single
command: `wails3 generate bindings`.
:::tip[Bindings]
```js
// @ts-check
// Cynhyrchwyd y ffeil hon yn awtomatig. PEIDIWCH Â MODIWL
// This file is automatically generated. DO NOT EDIT
import { main } from "./models";
window.go = window.go || {};
window.go.main = {
GreetService: {
/**
* GreetService.Greet
* Greet greets a person
* @param name {string}
* @returns {Promise<string>}
**/
Greet: function (name) {
wails.CallByID(1411160069, ...Array.prototype.slice.call(arguments, 0));
},
/**
* GreetService.GreetPerson
* GreetPerson greets a person
* @param person {main.Person}
* @returns {Promise<string>}
**/
GreetPerson: function (person) {
wails.CallByID(4021313248, ...Array.prototype.slice.call(arguments, 0));
},
},
};
```
:::
## Improved build system
Wails v3 introduces a more flexible and transparent build system, addressing the
limitations of its predecessor. In v2, the build process was largely opaque and
difficult to customise, which could be frustrating for developers seeking more
control over their project's build process.
All the heavy lifting that the v2 build system did, such as icon generation and
manifest creation, have been added as tool commands in the CLI. We have
incorporated [Taskfile](https://taskfile.dev) into the CLI to orchestrate these
calls to bring the same developer experience as v2. However, this approach
brings the ultimate balance of flexibility and ease of use as you can now
customise the build process to your needs.
You can even use make if that's your thing!
:::tip[Taskfile.yml]
```yaml "Snippet from Taskfile.yml"
build:darwin:
summary: Builds the application
platforms:
- darwin
cmds:
- task: pre-build
- task: build-frontend
- go build -gcflags=all="-N -l" -o bin/{{.APP_NAME}}
- task: post-build
env:
CGO_CFLAGS: "-mmacosx-version-min=10.13"
CGO_LDFLAGS: "-mmacosx-version-min=10.13"
MACOSX_DEPLOYMENT_TARGET: "10.13"
```
:::
## Improved events
Wails now emits events for various runtime operations and system activities.
This allows your application to respond to these events in real-time.
Additionally, cross-platform (common) events are available, enabling you to
write consistent event handling methods that work across different operating
systems.
Event hooks can be registered to handle specific events synchronously. Unlike
the `On` method, these hooks allow you to cancel the event if needed. A common
use case is displaying a confirmation dialog before closing a window. This gives
you more control over the event flow and user experience.
:::tip[Example of event handling]
```go
package main
import (
_ "embed"
"log"
"time"
"github.com/wailsapp/wails/v3/pkg/application"
"github.com/wailsapp/wails/v3/pkg/events"
)
//go:embed assets
var assets embed.FS
func main() {
app := application.New(application.Options{
Name: "Events Demo",
Description: "A demo of the Events API",
Assets: application.AssetOptions{
Handler: application.AssetFileServerFS(assets),
},
Mac: application.MacOptions{
ApplicationShouldTerminateAfterLastWindowClosed: true,
},
})
// Custom event handling
app.Events.On("myevent", func(e *application.WailsEvent) {
log.Printf("[Go] WailsEvent received: %+v\n", e)
})
// OS specific application events
app.On(events.Mac.ApplicationDidFinishLaunching, func(event *application.Event) {
println("events.Mac.ApplicationDidFinishLaunching fired!")
})
// Platform agnostic events
app.On(events.Common.ApplicationStarted, func(event *application.Event) {
println("events.Common.ApplicationStarted fired!")
})
win1 := app.NewWebviewWindowWithOptions(application.WebviewWindowOptions{
Title: "Takes 3 attempts to close me!",
})
var countdown = 3
// Register a hook to cancel the window closing
win1.RegisterHook(events.Common.WindowClosing, func(e *application.WindowEvent) {
countdown--
if countdown == 0 {
println("Closing!")
return
}
println("Nope! Not closing!")
e.Cancel()
})
win1.On(events.Common.WindowFocus, func(e *application.WindowEvent) {
println("[Event] Window focus!")
})
err := app.Run()
if err != nil {
log.Fatal(err.Error())
}
}
```
:::
## Wails Markup Language (wml)
An experimental feature to call runtime methods using plain html, similar to
[htmx](https://htmx.org).
:::tip[Example of wml]
```html
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>Wails ML Demo</title>
</head>
<body style="margin-top:50px; color: white; background-color: #191919">
<h2>Wails ML Demo</h2>
<p>This application contains no Javascript!</p>
<button wml-event="button-pressed">Press me!</button>
<button wml-event="delete-things" wml-confirm="Are you sure?">
Delete all the things!
</button>
<button wml-window="Close" wml-confirm="Are you sure?">
Close the Window?
</button>
<button wml-window="Center">Center</button>
<button wml-window="Minimise">Minimise</button>
<button wml-window="Maximise">Maximise</button>
<button wml-window="UnMaximise">UnMaximise</button>
<button wml-window="Fullscreen">Fullscreen</button>
<button wml-window="UnFullscreen">UnFullscreen</button>
<button wml-window="Restore">Restore</button>
<div
style="width: 200px; height: 200px; border: 2px solid white;"
wml-event="hover"
wml-trigger="mouseover"
>
Hover over me
</div>
</body>
</html>
```
:::
## Examples
There are more examples available in the
[examples](https://github.com/wailsapp/wails/tree/v3-alpha/v3/examples)
directory. Check them out!

2
docs/src/env.d.ts vendored Normal file
View File

@ -0,0 +1,2 @@
/// <reference path="../.astro/types.d.ts" />
/// <reference types="astro/client" />

View File

@ -0,0 +1,4 @@
html {
scrollbar-gutter: stable;
overflow-y: scroll; /* Show vertical scrollbar */
}

3
docs/tsconfig.json Normal file
View File

@ -0,0 +1,3 @@
{
"extends": "astro/tsconfigs/strict"
}