Merge pull request #4289 from atterpac/v3/deeplink

V3 Deep-link (Port of v2 feature)
This commit is contained in:
Atterpac 2025-07-23 15:24:59 -06:00 committed by GitHub
commit b5ef00fd42
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
56 changed files with 3269 additions and 444 deletions

View file

@ -0,0 +1,167 @@
---
title: Custom Protocol Schemes (Deep Linking)
description: Guide to implementing custom URL schemes for deep linking in Wails applications across macOS, Windows, and Linux.
---
import { Aside } from '@astrojs/starlight/components';
# Custom Protocol Schemes (Deep Linking)
Custom protocol schemes (also known as custom URL schemes or deep linking) allow your Wails application to be launched or brought to the foreground by clicking a URL with a scheme you define (e.g., `myapp://some/data`). This is useful for various purposes, such as:
- OAuth authentication flows.
- Inter-application communication.
- Launching your app with a specific context or to perform a particular action.
Wails provides a unified way to handle these custom URL invocations across macOS, Windows, and Linux through the `events.Common.ApplicationLaunchedWithUrl` event.
## Defining Your Protocols
First, you need to define the custom protocol schemes your application will use. This is done in your `wails.json` project configuration file. Wails reads this file during the build process (`wails build`) to configure the necessary platform-specific assets like `Info.plist` for macOS, NSIS installer scripts for Windows, and `.desktop` files for Linux.
**Example: `wails.json`**
```json title="wails.json"
{
"name": "My App",
"description": "An amazing Wails app!",
"info": {
"companyName": "My Company",
"productName": "My Product",
// ... other info fields ...
"protocols": [
{
"scheme": "myapp",
"description": "My Application Custom Protocol"
},
{
"scheme": "anotherprotocol",
"description": "Another protocol for specific actions"
}
]
}
// ... other wails.json fields ...
}
```
This `info.protocols` array is what Wails uses to generate the necessary entries in platform-specific files. For example, in template files, you might access this via a path like `{{.Info.Protocols}}`.
<Aside type="note">
While `application.Options` in your `main.go` is used for runtime application settings, the definition of custom protocols for build-time asset generation (like `Info.plist`, NSIS scripts, `.desktop` files) should be managed in `wails.json`.
</Aside>
## Handling the Event in Your Application
When your application is launched or activated via a custom URL, Wails emits an `events.Common.ApplicationLaunchedWithUrl` event. You can listen for this event and retrieve the URL that triggered the launch.
```go title="main.go"
import (
"log"
"github.com/wailsapp/wails/v3/pkg/application"
"github.com/wailsapp/wails/v3/pkg/events"
)
func main() {
app := application.New(application.Options{
Name: "My App", // Ensure this matches relevant info from wails.json if needed
Description: "An amazing Wails app!",
// ... other runtime options ...
})
app.OnApplicationEvent(events.Common.ApplicationLaunchedWithUrl, func(e *application.ApplicationEvent) {
launchedURL := e.Context().URL() // Retrieve the URL from the event context
log.Printf("Application launched with URL: %s", launchedURL)
// TODO: Process the URL (e.g., navigate, perform action, etc.)
// Example: app.EmitEvent("frontend:ShowURL", launchedURL)
})
// ... rest of your main function ...
err := app.Run()
if err != nil {
log.Fatal(err)
}
}
```
<Aside type="note">
The `e.Context().URL()` method returns the full URL string that was used to launch the application (e.g., `myapp://some/data?param=value`).
</Aside>
## Platform-Specific Setup and Behavior
While Wails aims for a unified event, the underlying mechanism for custom protocol registration and URL delivery varies by operating system.
### macOS
- **Setup:** Wails automatically configures your application's `Info.plist` file during the build process. It adds `CFBundleURLTypes` entries based on the `info.protocols` defined in your `wails.json` file.
```xml title="Info.plist (excerpt generated by Wails)"
<key>CFBundleURLTypes</key>
<array>
<dict>
<key>CFBundleURLName</key>
<string>My Application Custom Protocol</string> <!-- From Protocol.Description in wails.json -->
<key>CFBundleURLSchemes</key>
<array>
<string>myapp</string> <!-- From Protocol.Scheme in wails.json -->
</array>
</dict>
<!-- ... other protocols ... -->
</array>
```
- **How it Works:** When a URL like `myapp://` is opened, macOS uses LaunchServices to find the application registered for that scheme and sends it an Apple Event (`kAEGetURL`). Wails intercepts this event and translates it into the common `events.Common.ApplicationLaunchedWithUrl` Wails event, providing the URL via `e.Context().URL()`.
### Windows
- **Setup:** Custom protocol schemes on Windows are registered in the Windows Registry. Wails facilitates this through its NSIS installer template.
- When you build your application with the `-nsis` flag, Wails uses the `v3/internal/commands/updatable_build_assets/windows/nsis/wails_tools.nsh.tmpl` file.
- This template contains macros like `CUSTOM_PROTOCOL_ASSOCIATE` and `wails.associateCustomProtocols` which use the `info.protocols` from your `wails.json` (passed as `{{.Info.Protocols}}` to the template) to create the necessary registry entries during installation.
```nsis title="wails_tools.nsh.tmpl (excerpt)"
!macro wails.associateCustomProtocols
; Create custom protocols associations
{{range .Info.Protocols}}
!insertmacro CUSTOM_PROTOCOL_ASSOCIATE "{{.Scheme}}" "{{.Description}}" "$INSTDIR\${PRODUCT_EXECUTABLE},0" "$INSTDIR\${PRODUCT_EXECUTABLE} $\"%1$\""
{{end}}
!macroend
```
- **How it Works:** The installer registers your application executable to be called with the URL as a command-line argument (`%1`). For example, `your_app.exe "myapp://some/data"`.
- The Wails runtime for Windows (`v3/pkg/application/application_windows.go`) has been updated to check `os.Args` upon startup. If it detects an argument that looks like a URL (e.g., `os.Args[1]` contains `"://"`), it now emits the `events.Common.ApplicationLaunchedWithUrl` event with this URL.
<Aside type="important">
For Windows, custom protocol schemes are typically only registered when your application is installed via an installer (like the one generated by Wails with NSIS). Running the bare executable might not have the schemes registered system-wide.
</Aside>
### Linux
- **Setup:** On Linux, custom protocol handling is typically managed via `.desktop` files and the MIME type system.
- Wails uses a `.desktop` file template (e.g., `v3/internal/commands/updatable_build_assets/linux/desktop.tmpl`) which is populated during the build using information from `wails.json`.
```desktop title="desktop.tmpl (excerpt)"
[Desktop Entry]
Name={{.ProductName}}
Exec=/usr/local/bin/{{.BinaryName}} %u
MimeType={{range $index, $protocol := .Info.Protocols}}x-scheme-handler/{{$protocol.Scheme}};{{end}}
```
The `Exec` line uses `%u` which gets replaced by the URL. The `MimeType` line registers your application as a handler for `x-scheme-handler/your-scheme` for each protocol defined in `wails.json` (via `{{.Info.Protocols}}`).
- When packaging for Linux (e.g., using `nfpm`), this `.desktop` file is installed to `/usr/share/applications/`.
- A `postinstall.sh` script (e.g., `v3/internal/commands/build_assets/linux/nfpm/scripts/postinstall.sh`) is used to update the system's application and MIME databases:
```sh title="postinstall.sh (excerpt)"
#!/bin/sh
update-desktop-database -q /usr/share/applications
update-mime-database -n /usr/share/mime
```
- **How it Works:** When a URL like `myapp://` is opened, the desktop environment uses the MIME database to find the associated `.desktop` file and executes the command specified in its `Exec` line, substituting `%u` with the URL. Your application receives this URL as a command-line argument.
- The Wails runtime for Linux (`v3/pkg/application/application_linux.go`) checks `os.Args` on startup. If it detects an argument that looks like a URL, it emits the `events.Common.ApplicationLaunchedWithUrl` event.
## Testing Your Custom Protocols
- **macOS:** Open Terminal and type `open "your-scheme://your/data"`.
- **Linux:** Open a terminal and type `xdg-open "your-scheme://your/data"` (requires `xdg-utils` to be installed and the app to be properly packaged and registered).
- **Windows:** After installation via NSIS:
- You can try running `start your-scheme://your/data` from Command Prompt or PowerShell.
- Create a simple HTML file with a link `<a href="your-scheme://your/data">Test Link</a>` and open it in a browser.
<Aside type="tip">
Always ensure your application is properly built and installed (especially for Windows and Linux) for the system to recognize the custom protocol schemes.
</Aside>
By following this guide, you can effectively use custom protocol schemes to enhance your Wails application's interactivity and integration with other applications or web services.

View file

@ -0,0 +1,6 @@
.task
bin
frontend/dist
frontend/node_modules
build/linux/appimage/build
build/windows/nsis/MicrosoftEdgeWebview2Setup.exe

View file

@ -0,0 +1,59 @@
# Welcome to Your New Wails3 Project!
Congratulations on generating your Wails3 application! This README will guide you through the next steps to get your project up and running.
## Getting Started
1. Navigate to your project directory in the terminal.
2. To run your application in development mode, use the following command:
```
wails3 dev
```
This will start your application and enable hot-reloading for both frontend and backend changes.
3. To build your application for production, use:
```
wails3 build
```
This will create a production-ready executable in the `build` directory.
## Exploring Wails3 Features
Now that you have your project set up, it's time to explore the features that Wails3 offers:
1. **Check out the examples**: The best way to learn is by example. Visit the `examples` directory in the `v3/examples` directory to see various sample applications.
2. **Run an example**: To run any of the examples, navigate to the example's directory and use:
```
go run .
```
Note: Some examples may be under development during the alpha phase.
3. **Explore the documentation**: Visit the [Wails3 documentation](https://v3.wails.io/) for in-depth guides and API references.
4. **Join the community**: Have questions or want to share your progress? Join the [Wails Discord](https://discord.gg/JDdSxwjhGf) or visit the [Wails discussions on GitHub](https://github.com/wailsapp/wails/discussions).
## Project Structure
Take a moment to familiarize yourself with your project structure:
- `frontend/`: Contains your frontend code (HTML, CSS, JavaScript/TypeScript)
- `main.go`: The entry point of your Go backend
- `app.go`: Define your application structure and methods here
- `wails.json`: Configuration file for your Wails project
## Next Steps
1. Modify the frontend in the `frontend/` directory to create your desired UI.
2. Add backend functionality in `main.go`.
3. Use `wails3 dev` to see your changes in real-time.
4. When ready, build your application with `wails3 build`.
Happy coding with Wails3! If you encounter any issues or have questions, don't hesitate to consult the documentation or reach out to the Wails community.

View file

@ -0,0 +1,33 @@
version: '3'
includes:
common: ./build/Taskfile.yml
windows: ./build/windows/Taskfile.yml
darwin: ./build/darwin/Taskfile.yml
linux: ./build/linux/Taskfile.yml
vars:
APP_NAME: "custom-protocol-example"
BIN_DIR: "bin"
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/config.yml

View file

@ -0,0 +1,85 @@
version: '3'
tasks:
go:mod:tidy:
summary: Runs `go mod tidy`
internal: true
cmds:
- go mod tidy
install:frontend:deps:
summary: Install frontend dependencies
dir: frontend
sources:
- package.json
- package-lock.json
generates:
- node_modules/*
preconditions:
- sh: npm version
cmds:
- echo "Skipping frontend dependencies installation"
build:frontend:
label: build:frontend (PRODUCTION={{.PRODUCTION}})
summary: Build the frontend project
dir: frontend
sources:
- "**/*"
generates:
- dist/**/*
deps:
- task: install:frontend:deps
- task: generate:bindings
vars:
BUILD_FLAGS:
ref: .BUILD_FLAGS
cmds:
- npm run {{.BUILD_COMMAND}} -q
env:
PRODUCTION: '{{.PRODUCTION | default "false"}}'
vars:
BUILD_COMMAND: '{{if eq .PRODUCTION "true"}}build{{else}}build{{end}}'
generate:bindings:
label: generate:bindings (BUILD_FLAGS={{.BUILD_FLAGS}})
summary: Generates bindings for the frontend
deps:
- task: go:mod:tidy
sources:
- "**/*.[jt]s"
- exclude: frontend/**/*
- frontend/bindings/**/* # Rerun when switching between dev/production mode causes changes in output
- "**/*.go"
- go.mod
- go.sum
generates:
- frontend/bindings/**/*
cmds:
- wails3 generate bindings -f '{{.BUILD_FLAGS}}' -clean=true
generate:icons:
summary: Generates Windows `.ico` and Mac `.icns` files from an image
dir: build
sources:
- "appicon.png"
generates:
- "darwin/icons.icns"
- "windows/icon.ico"
cmds:
- wails3 generate icons -input appicon.png -macfilename darwin/icons.icns -windowsfilename windows/icon.ico
dev:frontend:
summary: Runs the frontend in development mode
dir: frontend
deps:
- task: install:frontend:deps
cmds:
- echo "Skipping frontend development mode"
update:build-assets:
summary: Updates the build assets
dir: build
cmds:
- wails3 update build-assets -name "{{.APP_NAME}}" -binaryname "{{.APP_NAME}}" -config config.yml -dir .

Binary file not shown.

After

Width:  |  Height:  |  Size: 130 KiB

View file

@ -0,0 +1,67 @@
# This file contains the configuration for this project.
# When you update `info` or `fileAssociations`, run `wails3 task common:update:build-assets` to update the assets.
# Note that this will overwrite any changes you have made to the assets.
version: '3'
# This information is used to generate the build assets.
info:
companyName: "My Company" # The name of the company
productName: "My Product" # The name of the application
productIdentifier: "com.mycompany.myproduct" # The unique product identifier
description: "A program that does X" # The application description
copyright: "(c) 2025, My Company" # Copyright text
comments: "Some Product Comments" # Comments
version: "0.0.1" # The application version
# Dev mode configuration
dev_mode:
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
# File Associations
# More information at: https://v3.wails.io/noit/done/yet
fileAssociations:
# - ext: wails
# name: Wails
# description: Wails Application File
# iconName: wailsFileIcon
# role: Editor
# - ext: jpg
# name: JPEG
# description: Image File
# iconName: jpegFileIcon
# role: Editor
# mimeType: image/jpeg # (optional)
protocols:
- scheme: wailsexample
description: Wails Example Application Custom Protocol
# Other data
other:
- name: My Other Data

View file

@ -0,0 +1,43 @@
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleName</key>
<string>My Product</string>
<key>CFBundleExecutable</key>
<string>custom-protocol-example</string>
<key>CFBundleIdentifier</key>
<string>com.mycompany.myproduct</string>
<key>CFBundleVersion</key>
<string>0.0.1</string>
<key>CFBundleGetInfoString</key>
<string>Some Product Comments</string>
<key>CFBundleShortVersionString</key>
<string>0.0.1</string>
<key>CFBundleIconFile</key>
<string>icons</string>
<key>LSMinimumSystemVersion</key>
<string>10.15.0</string>
<key>NSHighResolutionCapable</key>
<string>true</string>
<key>NSHumanReadableCopyright</key>
<string>(c) 2025, My Company</string>
<key>NSAppTransportSecurity</key>
<dict>
<key>NSAllowsLocalNetworking</key>
<true/>
</dict>
<key>CFBundleURLTypes</key>
<array>
<dict>
<key>CFBundleURLName</key>
<string>wails.com.wailsexample</string>
<key>CFBundleURLSchemes</key>
<array>
<string>wailsexample</string>
</array>
</dict>
</array>
</dict>
</plist>

View file

@ -0,0 +1,38 @@
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleName</key>
<string>My Product</string>
<key>CFBundleExecutable</key>
<string>custom-protocol-example</string>
<key>CFBundleIdentifier</key>
<string>com.mycompany.myproduct</string>
<key>CFBundleVersion</key>
<string>0.0.1</string>
<key>CFBundleGetInfoString</key>
<string>Some Product Comments</string>
<key>CFBundleShortVersionString</key>
<string>0.0.1</string>
<key>CFBundleIconFile</key>
<string>icons</string>
<key>LSMinimumSystemVersion</key>
<string>10.15.0</string>
<key>NSHighResolutionCapable</key>
<string>true</string>
<key>NSHumanReadableCopyright</key>
<string>(c) 2025, My Company</string>
<key>CFBundleURLTypes</key>
<array>
<dict>
<key>CFBundleURLName</key>
<string>wails.com.wailsexample</string>
<key>CFBundleURLSchemes</key>
<array>
<string>wailsexample</string>
</array>
</dict>
</array>
</dict>
</plist>

View file

@ -0,0 +1,76 @@
version: '3'
includes:
common: ../Taskfile.yml
tasks:
build:
summary: Creates a production build of the application
deps:
- task: common:go:mod:tidy
- task: common:generate:icons
- task: common:build:frontend
cmds:
- go build {{.BUILD_FLAGS}} -o {{.OUTPUT}}
vars:
BUILD_FLAGS: '{{if eq .PRODUCTION "true"}}-tags production -trimpath -buildvcs=false -ldflags="-w -s"{{else}}-buildvcs=false -gcflags=all="-l"{{end}}'
DEFAULT_OUTPUT: '{{.BIN_DIR}}/{{.APP_NAME}}'
OUTPUT: '{{ .OUTPUT | default .DEFAULT_OUTPUT }}'
env:
GOOS: darwin
CGO_ENABLED: 1
GOARCH: '{{.ARCH | default ARCH}}'
CGO_CFLAGS: "-mmacosx-version-min=10.15"
CGO_LDFLAGS: "-mmacosx-version-min=10.15"
MACOSX_DEPLOYMENT_TARGET: "10.15"
PRODUCTION: '{{.PRODUCTION | default "false"}}'
build:universal:
summary: Builds darwin universal binary (arm64 + amd64)
deps:
- task: build
vars:
ARCH: amd64
OUTPUT: "{{.BIN_DIR}}/{{.APP_NAME}}-amd64"
- task: build
vars:
ARCH: arm64
OUTPUT: "{{.BIN_DIR}}/{{.APP_NAME}}-arm64"
cmds:
- lipo -create -output "{{.BIN_DIR}}/{{.APP_NAME}}" "{{.BIN_DIR}}/{{.APP_NAME}}-amd64" "{{.BIN_DIR}}/{{.APP_NAME}}-arm64"
- rm "{{.BIN_DIR}}/{{.APP_NAME}}-amd64" "{{.BIN_DIR}}/{{.APP_NAME}}-arm64"
package:
summary: Packages a production build of the application into a `.app` bundle
deps:
- task: build
vars:
PRODUCTION: "false"
cmds:
- task: create:app:bundle
package:universal:
summary: Packages darwin universal binary (arm64 + amd64)
deps:
- task: build:universal
cmds:
- task: create:app:bundle
create:app:bundle:
summary: Creates an `.app` bundle
cmds:
- mkdir -p {{.BIN_DIR}}/{{.APP_NAME}}.app/Contents/{MacOS,Resources}
- cp build/darwin/icons.icns {{.BIN_DIR}}/{{.APP_NAME}}.app/Contents/Resources
- cp {{.BIN_DIR}}/{{.APP_NAME}} {{.BIN_DIR}}/{{.APP_NAME}}.app/Contents/MacOS
- cp build/darwin/Info.plist {{.BIN_DIR}}/{{.APP_NAME}}.app/Contents
- codesign --force --deep --sign - {{.BIN_DIR}}/{{.APP_NAME}}.app
run:
cmds:
- mkdir -p {{.BIN_DIR}}/{{.APP_NAME}}.dev.app/Contents/{MacOS,Resources}
- cp build/darwin/icons.icns {{.BIN_DIR}}/{{.APP_NAME}}.dev.app/Contents/Resources
- cp {{.BIN_DIR}}/{{.APP_NAME}} {{.BIN_DIR}}/{{.APP_NAME}}.dev.app/Contents/MacOS
- cp build/darwin/Info.dev.plist {{.BIN_DIR}}/{{.APP_NAME}}.dev.app/Contents/Info.plist
- codesign --force --deep --sign - {{.BIN_DIR}}/{{.APP_NAME}}.dev.app
- '{{.BIN_DIR}}/{{.APP_NAME}}.dev.app/Contents/MacOS/{{.APP_NAME}}'

View file

@ -0,0 +1,113 @@
version: '3'
includes:
common: ../Taskfile.yml
tasks:
build:
summary: Builds the application for Linux
deps:
- task: common:go:mod:tidy
- task: common:generate:icons
cmds:
- go build {{.BUILD_FLAGS}} -o {{.BIN_DIR}}/{{.APP_NAME}}
vars:
BUILD_FLAGS: '{{if eq .PRODUCTION "true"}}-tags production -trimpath -buildvcs=false -ldflags="-w -s"{{else}}-buildvcs=false -gcflags=all="-l"{{end}}'
env:
GOOS: linux
CGO_ENABLED: 1
GOARCH: '{{.ARCH | default ARCH}}'
PRODUCTION: '{{.PRODUCTION | default "false"}}'
package:
summary: Packages a production build of the application for Linux
deps:
- task: build
vars:
PRODUCTION: "true"
cmds:
- task: create:appimage
- task: create:deb
- task: create:rpm
- task: create:aur
create:appimage:
summary: Creates an AppImage
dir: build/linux/appimage
deps:
- task: build
vars:
PRODUCTION: "true"
- task: generate:dotdesktop
cmds:
- cp {{.APP_BINARY}} {{.APP_NAME}}
- cp ../../appicon.png appicon.png
- wails3 generate appimage -binary {{.APP_NAME}} -icon {{.ICON}} -desktopfile {{.DESKTOP_FILE}} -outputdir {{.OUTPUT_DIR}} -builddir {{.ROOT_DIR}}/build/linux/appimage/build
vars:
APP_NAME: '{{.APP_NAME}}'
APP_BINARY: '../../../bin/{{.APP_NAME}}'
ICON: '../../appicon.png'
DESKTOP_FILE: '../{{.APP_NAME}}.desktop'
OUTPUT_DIR: '../../../bin'
create:deb:
summary: Creates a deb package
deps:
- task: build
vars:
PRODUCTION: "true"
cmds:
- task: generate:dotdesktop
- task: generate:deb
create:rpm:
summary: Creates a rpm package
deps:
- task: build
vars:
PRODUCTION: "true"
cmds:
- task: generate:dotdesktop
- task: generate:rpm
create:aur:
summary: Creates a arch linux packager package
deps:
- task: build
vars:
PRODUCTION: "true"
cmds:
- task: generate:dotdesktop
- task: generate:aur
generate:deb:
summary: Creates a deb package
cmds:
- wails3 tool package -name {{.APP_NAME}} -format deb -config ./build/linux/nfpm/nfpm.yaml -out {{.ROOT_DIR}}/bin
generate:rpm:
summary: Creates a rpm package
cmds:
- wails3 tool package -name {{.APP_NAME}} -format rpm -config ./build/linux/nfpm/nfpm.yaml -out {{.ROOT_DIR}}/bin
generate:aur:
summary: Creates a arch linux packager package
cmds:
- wails3 tool package -name {{.APP_NAME}} -format archlinux -config ./build/linux/nfpm/nfpm.yaml -out {{.ROOT_DIR}}/bin
generate:dotdesktop:
summary: Generates a `.desktop` file
dir: build
cmds:
- mkdir -p {{.ROOT_DIR}}/build/linux/appimage
- wails3 generate .desktop -name "{{.APP_NAME}}" -exec "{{.EXEC}}" -icon "{{.ICON}}" -outputfile {{.ROOT_DIR}}/build/linux/{{.APP_NAME}}.desktop -categories "{{.CATEGORIES}}"
vars:
APP_NAME: '{{.APP_NAME}}'
EXEC: '{{.APP_NAME}}'
ICON: 'appicon'
CATEGORIES: 'Development;'
OUTPUTFILE: '{{.ROOT_DIR}}/build/linux/{{.APP_NAME}}.desktop'
run:
cmds:
- '{{.BIN_DIR}}/{{.APP_NAME}}'

View file

@ -0,0 +1,35 @@
#!/usr/bin/env bash
# Copyright (c) 2018-Present Lea Anthony
# SPDX-License-Identifier: MIT
# Fail script on any error
set -euxo pipefail
# Define variables
APP_DIR="${APP_NAME}.AppDir"
# Create AppDir structure
mkdir -p "${APP_DIR}/usr/bin"
cp -r "${APP_BINARY}" "${APP_DIR}/usr/bin/"
cp "${ICON_PATH}" "${APP_DIR}/"
cp "${DESKTOP_FILE}" "${APP_DIR}/"
if [[ $(uname -m) == *x86_64* ]]; then
# Download linuxdeploy and make it executable
wget -q -4 -N https://github.com/linuxdeploy/linuxdeploy/releases/download/continuous/linuxdeploy-x86_64.AppImage
chmod +x linuxdeploy-x86_64.AppImage
# Run linuxdeploy to bundle the application
./linuxdeploy-x86_64.AppImage --appdir "${APP_DIR}" --output appimage
else
# Download linuxdeploy and make it executable (arm64)
wget -q -4 -N https://github.com/linuxdeploy/linuxdeploy/releases/download/continuous/linuxdeploy-aarch64.AppImage
chmod +x linuxdeploy-aarch64.AppImage
# Run linuxdeploy to bundle the application (arm64)
./linuxdeploy-aarch64.AppImage --appdir "${APP_DIR}" --output appimage
fi
# Rename the generated AppImage
mv "${APP_NAME}*.AppImage" "${APP_NAME}.AppImage"

View file

@ -0,0 +1,50 @@
# Feel free to remove those if you don't want/need to use them.
# Make sure to check the documentation at https://nfpm.goreleaser.com
#
# The lines below are called `modelines`. See `:help modeline`
name: "custom-protocol-example"
arch: ${GOARCH}
platform: "linux"
version: "0.0.1"
section: "default"
priority: "extra"
maintainer: ${GIT_COMMITTER_NAME} <${GIT_COMMITTER_EMAIL}>
description: "A program that does X"
vendor: "My Company"
homepage: "https://wails.io"
license: "MIT"
release: "1"
contents:
- src: "./bin/custom-protocol-example"
dst: "/usr/local/bin/custom-protocol-example"
- src: "./build/appicon.png"
dst: "/usr/share/icons/hicolor/128x128/apps/custom-protocol-example.png"
- src: "./build/linux/custom-protocol-example.desktop"
dst: "/usr/share/applications/custom-protocol-example.desktop"
depends:
- gtk3
- libwebkit2gtk
# replaces:
# - foobar
# provides:
# - bar
# depends:
# - gtk3
# - libwebkit2gtk
# recommends:
# - whatever
# suggests:
# - something-else
# conflicts:
# - not-foo
# - not-bar
# changelog: "changelog.yaml"
# scripts:
# preinstall: ./build/linux/nfpm/scripts/preinstall.sh
# postinstall: ./build/linux/nfpm/scripts/postinstall.sh
# preremove: ./build/linux/nfpm/scripts/preremove.sh
# postremove: ./build/linux/nfpm/scripts/postremove.sh

View file

@ -0,0 +1 @@
#!/bin/bash

View file

@ -0,0 +1 @@
#!/bin/bash

View file

@ -0,0 +1 @@
#!/bin/bash

View file

@ -0,0 +1 @@
#!/bin/bash

View file

@ -0,0 +1,57 @@
version: '3'
includes:
common: ../Taskfile.yml
tasks:
build:
summary: Builds the application for Windows
deps:
- task: common:go:mod:tidy
- task: common:generate:icons
cmds:
- task: generate:syso
- go build {{.BUILD_FLAGS}} -o {{.BIN_DIR}}/{{.APP_NAME}}.exe
- cmd: powershell Remove-item *.syso
platforms: [windows]
- cmd: rm -f *.syso
platforms: [linux, darwin]
vars:
BUILD_FLAGS: '{{if eq .PRODUCTION "true"}}-tags production -trimpath -buildvcs=false -ldflags="-w -s -H windowsgui"{{else}}-buildvcs=false -gcflags=all="-l"{{end}}'
env:
GOOS: windows
CGO_ENABLED: 0
GOARCH: '{{.ARCH | default ARCH}}'
PRODUCTION: '{{.PRODUCTION | default "false"}}'
package:
summary: Packages a production build of the application into a `.exe` bundle
cmds:
- task: create:nsis:installer
generate:syso:
summary: Generates Windows `.syso` file
dir: build
cmds:
- wails3 generate syso -arch {{.ARCH}} -icon windows/icon.ico -manifest windows/wails.exe.manifest -info windows/info.json -out ../wails_windows_{{.ARCH}}.syso
vars:
ARCH: '{{.ARCH | default ARCH}}'
create:nsis:installer:
summary: Creates an NSIS installer
dir: build/windows/nsis
deps:
- task: build
vars:
PRODUCTION: "true"
cmds:
# Create the Microsoft WebView2 bootstrapper if it doesn't exist
- wails3 generate webview2bootstrapper -dir "{{.ROOT_DIR}}/build/windows/nsis"
- makensis -DARG_WAILS_{{.ARG_FLAG}}_BINARY="{{.ROOT_DIR}}/{{.BIN_DIR}}/{{.APP_NAME}}.exe" project.nsi
vars:
ARCH: '{{.ARCH | default ARCH}}'
ARG_FLAG: '{{if eq .ARCH "amd64"}}AMD64{{else}}ARM64{{end}}'
run:
cmds:
- '{{.BIN_DIR}}/{{.APP_NAME}}.exe'

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

View file

@ -0,0 +1,15 @@
{
"fixed": {
"file_version": "0.0.1"
},
"info": {
"0000": {
"ProductVersion": "0.0.1",
"CompanyName": "My Company",
"FileDescription": "A program that does X",
"LegalCopyright": "(c) 2025, My Company",
"ProductName": "My Product",
"Comments": "Some Product Comments"
}
}
}

View file

@ -0,0 +1,112 @@
Unicode true
####
## Please note: Template replacements don't work in this file. They are provided with default defines like
## mentioned underneath.
## If the keyword is not defined, "wails_tools.nsh" will populate them.
## If they are defined here, "wails_tools.nsh" will not touch them. This allows you to use this project.nsi manually
## from outside of Wails for debugging and development of the installer.
##
## For development first make a wails nsis build to populate the "wails_tools.nsh":
## > wails build --target windows/amd64 --nsis
## Then you can call makensis on this file with specifying the path to your binary:
## For a AMD64 only installer:
## > makensis -DARG_WAILS_AMD64_BINARY=..\..\bin\app.exe
## For a ARM64 only installer:
## > makensis -DARG_WAILS_ARM64_BINARY=..\..\bin\app.exe
## For a installer with both architectures:
## > makensis -DARG_WAILS_AMD64_BINARY=..\..\bin\app-amd64.exe -DARG_WAILS_ARM64_BINARY=..\..\bin\app-arm64.exe
####
## The following information is taken from the wails_tools.nsh file, but they can be overwritten here.
####
## !define INFO_PROJECTNAME "my-project" # Default "custom-protocol-example"
## !define INFO_COMPANYNAME "My Company" # Default "My Company"
## !define INFO_PRODUCTNAME "My Product Name" # Default "My Product"
## !define INFO_PRODUCTVERSION "1.0.0" # Default "0.1.0"
## !define INFO_COPYRIGHT "(c) Now, My Company" # Default "© now, My Company"
###
## !define PRODUCT_EXECUTABLE "Application.exe" # Default "${INFO_PROJECTNAME}.exe"
## !define UNINST_KEY_NAME "UninstKeyInRegistry" # Default "${INFO_COMPANYNAME}${INFO_PRODUCTNAME}"
####
## !define REQUEST_EXECUTION_LEVEL "admin" # Default "admin" see also https://nsis.sourceforge.io/Docs/Chapter4.html
####
## Include the wails tools
####
!include "wails_tools.nsh"
# The version information for this two must consist of 4 parts
VIProductVersion "${INFO_PRODUCTVERSION}.0"
VIFileVersion "${INFO_PRODUCTVERSION}.0"
VIAddVersionKey "CompanyName" "${INFO_COMPANYNAME}"
VIAddVersionKey "FileDescription" "${INFO_PRODUCTNAME} Installer"
VIAddVersionKey "ProductVersion" "${INFO_PRODUCTVERSION}"
VIAddVersionKey "FileVersion" "${INFO_PRODUCTVERSION}"
VIAddVersionKey "LegalCopyright" "${INFO_COPYRIGHT}"
VIAddVersionKey "ProductName" "${INFO_PRODUCTNAME}"
# Enable HiDPI support. https://nsis.sourceforge.io/Reference/ManifestDPIAware
ManifestDPIAware true
!include "MUI.nsh"
!define MUI_ICON "..\icon.ico"
!define MUI_UNICON "..\icon.ico"
# !define MUI_WELCOMEFINISHPAGE_BITMAP "resources\leftimage.bmp" #Include this to add a bitmap on the left side of the Welcome Page. Must be a size of 164x314
!define MUI_FINISHPAGE_NOAUTOCLOSE # Wait on the INSTFILES page so the user can take a look into the details of the installation steps
!define MUI_ABORTWARNING # This will warn the user if they exit from the installer.
!insertmacro MUI_PAGE_WELCOME # Welcome to the installer page.
# !insertmacro MUI_PAGE_LICENSE "resources\eula.txt" # Adds a EULA page to the installer
!insertmacro MUI_PAGE_DIRECTORY # In which folder install page.
!insertmacro MUI_PAGE_INSTFILES # Installing page.
!insertmacro MUI_PAGE_FINISH # Finished installation page.
!insertmacro MUI_UNPAGE_INSTFILES # Uninstalling page
!insertmacro MUI_LANGUAGE "English" # Set the Language of the installer
## The following two statements can be used to sign the installer and the uninstaller. The path to the binaries are provided in %1
#!uninstfinalize 'signtool --file "%1"'
#!finalize 'signtool --file "%1"'
Name "${INFO_PRODUCTNAME}"
OutFile "..\..\..\bin\${INFO_PROJECTNAME}-${ARCH}-installer.exe" # Name of the installer's file.
InstallDir "$PROGRAMFILES64\${INFO_COMPANYNAME}\${INFO_PRODUCTNAME}" # Default installing folder ($PROGRAMFILES is Program Files folder).
ShowInstDetails show # This will always show the installation details.
Function .onInit
!insertmacro wails.checkArchitecture
FunctionEnd
Section
!insertmacro wails.setShellContext
!insertmacro wails.webview2runtime
SetOutPath $INSTDIR
!insertmacro wails.files
CreateShortcut "$SMPROGRAMS\${INFO_PRODUCTNAME}.lnk" "$INSTDIR\${PRODUCT_EXECUTABLE}"
CreateShortCut "$DESKTOP\${INFO_PRODUCTNAME}.lnk" "$INSTDIR\${PRODUCT_EXECUTABLE}"
!insertmacro wails.associateFiles
!insertmacro wails.writeUninstaller
SectionEnd
Section "uninstall"
!insertmacro wails.setShellContext
RMDir /r "$AppData\${PRODUCT_EXECUTABLE}" # Remove the WebView2 DataPath
RMDir /r $INSTDIR
Delete "$SMPROGRAMS\${INFO_PRODUCTNAME}.lnk"
Delete "$DESKTOP\${INFO_PRODUCTNAME}.lnk"
!insertmacro wails.unassociateFiles
!insertmacro wails.deleteUninstaller
SectionEnd

View file

@ -0,0 +1,212 @@
# DO NOT EDIT - Generated automatically by `wails build`
!include "x64.nsh"
!include "WinVer.nsh"
!include "FileFunc.nsh"
!ifndef INFO_PROJECTNAME
!define INFO_PROJECTNAME "custom-protocol-example"
!endif
!ifndef INFO_COMPANYNAME
!define INFO_COMPANYNAME "My Company"
!endif
!ifndef INFO_PRODUCTNAME
!define INFO_PRODUCTNAME "My Product"
!endif
!ifndef INFO_PRODUCTVERSION
!define INFO_PRODUCTVERSION "0.0.1"
!endif
!ifndef INFO_COPYRIGHT
!define INFO_COPYRIGHT "(c) 2025, My Company"
!endif
!ifndef PRODUCT_EXECUTABLE
!define PRODUCT_EXECUTABLE "${INFO_PROJECTNAME}.exe"
!endif
!ifndef UNINST_KEY_NAME
!define UNINST_KEY_NAME "${INFO_COMPANYNAME}${INFO_PRODUCTNAME}"
!endif
!define UNINST_KEY "Software\Microsoft\Windows\CurrentVersion\Uninstall\${UNINST_KEY_NAME}"
!ifndef REQUEST_EXECUTION_LEVEL
!define REQUEST_EXECUTION_LEVEL "admin"
!endif
RequestExecutionLevel "${REQUEST_EXECUTION_LEVEL}"
!ifdef ARG_WAILS_AMD64_BINARY
!define SUPPORTS_AMD64
!endif
!ifdef ARG_WAILS_ARM64_BINARY
!define SUPPORTS_ARM64
!endif
!ifdef SUPPORTS_AMD64
!ifdef SUPPORTS_ARM64
!define ARCH "amd64_arm64"
!else
!define ARCH "amd64"
!endif
!else
!ifdef SUPPORTS_ARM64
!define ARCH "arm64"
!else
!error "Wails: Undefined ARCH, please provide at least one of ARG_WAILS_AMD64_BINARY or ARG_WAILS_ARM64_BINARY"
!endif
!endif
!macro wails.checkArchitecture
!ifndef WAILS_WIN10_REQUIRED
!define WAILS_WIN10_REQUIRED "This product is only supported on Windows 10 (Server 2016) and later."
!endif
!ifndef WAILS_ARCHITECTURE_NOT_SUPPORTED
!define WAILS_ARCHITECTURE_NOT_SUPPORTED "This product can't be installed on the current Windows architecture. Supports: ${ARCH}"
!endif
${If} ${AtLeastWin10}
!ifdef SUPPORTS_AMD64
${if} ${IsNativeAMD64}
Goto ok
${EndIf}
!endif
!ifdef SUPPORTS_ARM64
${if} ${IsNativeARM64}
Goto ok
${EndIf}
!endif
IfSilent silentArch notSilentArch
silentArch:
SetErrorLevel 65
Abort
notSilentArch:
MessageBox MB_OK "${WAILS_ARCHITECTURE_NOT_SUPPORTED}"
Quit
${else}
IfSilent silentWin notSilentWin
silentWin:
SetErrorLevel 64
Abort
notSilentWin:
MessageBox MB_OK "${WAILS_WIN10_REQUIRED}"
Quit
${EndIf}
ok:
!macroend
!macro wails.files
!ifdef SUPPORTS_AMD64
${if} ${IsNativeAMD64}
File "/oname=${PRODUCT_EXECUTABLE}" "${ARG_WAILS_AMD64_BINARY}"
${EndIf}
!endif
!ifdef SUPPORTS_ARM64
${if} ${IsNativeARM64}
File "/oname=${PRODUCT_EXECUTABLE}" "${ARG_WAILS_ARM64_BINARY}"
${EndIf}
!endif
!macroend
!macro wails.writeUninstaller
WriteUninstaller "$INSTDIR\uninstall.exe"
SetRegView 64
WriteRegStr HKLM "${UNINST_KEY}" "Publisher" "${INFO_COMPANYNAME}"
WriteRegStr HKLM "${UNINST_KEY}" "DisplayName" "${INFO_PRODUCTNAME}"
WriteRegStr HKLM "${UNINST_KEY}" "DisplayVersion" "${INFO_PRODUCTVERSION}"
WriteRegStr HKLM "${UNINST_KEY}" "DisplayIcon" "$INSTDIR\${PRODUCT_EXECUTABLE}"
WriteRegStr HKLM "${UNINST_KEY}" "UninstallString" "$\"$INSTDIR\uninstall.exe$\""
WriteRegStr HKLM "${UNINST_KEY}" "QuietUninstallString" "$\"$INSTDIR\uninstall.exe$\" /S"
${GetSize} "$INSTDIR" "/S=0K" $0 $1 $2
IntFmt $0 "0x%08X" $0
WriteRegDWORD HKLM "${UNINST_KEY}" "EstimatedSize" "$0"
!macroend
!macro wails.deleteUninstaller
Delete "$INSTDIR\uninstall.exe"
SetRegView 64
DeleteRegKey HKLM "${UNINST_KEY}"
!macroend
!macro wails.setShellContext
${If} ${REQUEST_EXECUTION_LEVEL} == "admin"
SetShellVarContext all
${else}
SetShellVarContext current
${EndIf}
!macroend
# Install webview2 by launching the bootstrapper
# See https://docs.microsoft.com/en-us/microsoft-edge/webview2/concepts/distribution#online-only-deployment
!macro wails.webview2runtime
!ifndef WAILS_INSTALL_WEBVIEW_DETAILPRINT
!define WAILS_INSTALL_WEBVIEW_DETAILPRINT "Installing: WebView2 Runtime"
!endif
SetRegView 64
# If the admin key exists and is not empty then webview2 is already installed
ReadRegStr $0 HKLM "SOFTWARE\WOW6432Node\Microsoft\EdgeUpdate\Clients\{F3017226-FE2A-4295-8BDF-00C3A9A7E4C5}" "pv"
${If} $0 != ""
Goto ok
${EndIf}
${If} ${REQUEST_EXECUTION_LEVEL} == "user"
# If the installer is run in user level, check the user specific key exists and is not empty then webview2 is already installed
ReadRegStr $0 HKCU "Software\Microsoft\EdgeUpdate\Clients\{F3017226-FE2A-4295-8BDF-00C3A9A7E4C5}" "pv"
${If} $0 != ""
Goto ok
${EndIf}
${EndIf}
SetDetailsPrint both
DetailPrint "${WAILS_INSTALL_WEBVIEW_DETAILPRINT}"
SetDetailsPrint listonly
InitPluginsDir
CreateDirectory "$pluginsdir\webview2bootstrapper"
SetOutPath "$pluginsdir\webview2bootstrapper"
File "MicrosoftEdgeWebview2Setup.exe"
ExecWait '"$pluginsdir\webview2bootstrapper\MicrosoftEdgeWebview2Setup.exe" /silent /install'
SetDetailsPrint both
ok:
!macroend
# Copy of APP_ASSOCIATE and APP_UNASSOCIATE macros from here https://gist.github.com/nikku/281d0ef126dbc215dd58bfd5b3a5cd5b
!macro APP_ASSOCIATE EXT FILECLASS DESCRIPTION ICON COMMANDTEXT COMMAND
; Backup the previously associated file class
ReadRegStr $R0 SHELL_CONTEXT "Software\Classes\.${EXT}" ""
WriteRegStr SHELL_CONTEXT "Software\Classes\.${EXT}" "${FILECLASS}_backup" "$R0"
WriteRegStr SHELL_CONTEXT "Software\Classes\.${EXT}" "" "${FILECLASS}"
WriteRegStr SHELL_CONTEXT "Software\Classes\${FILECLASS}" "" `${DESCRIPTION}`
WriteRegStr SHELL_CONTEXT "Software\Classes\${FILECLASS}\DefaultIcon" "" `${ICON}`
WriteRegStr SHELL_CONTEXT "Software\Classes\${FILECLASS}\shell" "" "open"
WriteRegStr SHELL_CONTEXT "Software\Classes\${FILECLASS}\shell\open" "" `${COMMANDTEXT}`
WriteRegStr SHELL_CONTEXT "Software\Classes\${FILECLASS}\shell\open\command" "" `${COMMAND}`
!macroend
!macro APP_UNASSOCIATE EXT FILECLASS
; Backup the previously associated file class
ReadRegStr $R0 SHELL_CONTEXT "Software\Classes\.${EXT}" `${FILECLASS}_backup`
WriteRegStr SHELL_CONTEXT "Software\Classes\.${EXT}" "" "$R0"
DeleteRegKey SHELL_CONTEXT `Software\Classes\${FILECLASS}`
!macroend
!macro wails.associateFiles
; Create file associations
!macroend
!macro wails.unassociateFiles
; Delete app associations
!macroend

View file

@ -0,0 +1,15 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly manifestVersion="1.0" xmlns="urn:schemas-microsoft-com:asm.v1" xmlns:asmv3="urn:schemas-microsoft-com:asm.v3">
<assemblyIdentity type="win32" name="com.mycompany.myproduct" version="0.0.1" processorArchitecture="*"/>
<dependency>
<dependentAssembly>
<assemblyIdentity type="win32" name="Microsoft.Windows.Common-Controls" version="6.0.0.0" processorArchitecture="*" publicKeyToken="6595b64144ccf1df" language="*"/>
</dependentAssembly>
</dependency>
<asmv3:application>
<asmv3:windowsSettings>
<dpiAware xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">true/pm</dpiAware> <!-- fallback for Windows 7 and 8 -->
<dpiAwareness xmlns="http://schemas.microsoft.com/SMI/2016/WindowsSettings">permonitorv2,permonitor</dpiAwareness> <!-- falls back to per-monitor if per-monitor v2 is not supported -->
</asmv3:windowsSettings>
</asmv3:application>
</assembly>

View file

@ -0,0 +1,24 @@
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*
lerna-debug.log*
node_modules
dist
dist-ssr
*.local
# Editor directories and files
.vscode/*
!.vscode/extensions.json
.idea
.DS_Store
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw?

View file

@ -0,0 +1,15 @@
// @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, CancellablePromise as $CancellablePromise, Create as $Create } from "@wailsio/runtime";
/**
* @param {string} name
* @returns {$CancellablePromise<string>}
*/
export function Greet(name) {
return $Call.ByID(1411160069, name);
}

View file

@ -0,0 +1,8 @@
// @ts-check
// Cynhyrchwyd y ffeil hon yn awtomatig. PEIDIWCH Â MODIWL
// This file is automatically generated. DO NOT EDIT
import * as GreetService from "./greetservice.js";
export {
GreetService
};

View file

@ -0,0 +1,24 @@
(function(){const t=document.createElement("link").relList;if(t&&t.supports&&t.supports("modulepreload"))return;for(const i of document.querySelectorAll('link[rel="modulepreload"]'))o(i);new MutationObserver(i=>{for(const r of i)if(r.type==="childList")for(const s of r.addedNodes)s.tagName==="LINK"&&s.rel==="modulepreload"&&o(s)}).observe(document,{childList:!0,subtree:!0});function n(i){const r={};return i.integrity&&(r.integrity=i.integrity),i.referrerPolicy&&(r.referrerPolicy=i.referrerPolicy),i.crossOrigin==="use-credentials"?r.credentials="include":i.crossOrigin==="anonymous"?r.credentials="omit":r.credentials="same-origin",r}function o(i){if(i.ep)return;i.ep=!0;const r=n(i);fetch(i.href,r)}})();const S="useandom-26T198340PX75pxJACKVERYMINDBUSHWOLF_GQZbfghjklqvwyzrict";function R(e=21){let t="",n=e|0;for(;n--;)t+=S[Math.random()*64|0];return t}const U=window.location.origin+"/wails/runtime",_=Object.freeze({Call:0,Clipboard:1,Application:2,Events:3,ContextMenu:4,Dialog:5,Window:6,Screens:7,System:8,Browser:9,CancelCall:10});let T=R();function k(e,t=""){return function(n,o=null){return I(e,n,t,o)}}async function I(e,t,n,o){var i,r;let s=new URL(U);s.searchParams.append("object",e.toString()),s.searchParams.append("method",t.toString()),o&&s.searchParams.append("args",JSON.stringify(o));let c={"x-wails-client-id":T};n&&(c["x-wails-window-name"]=n);let a=await fetch(s,{headers:c});if(!a.ok)throw new Error(await a.text());return((r=(i=a.headers.get("Content-Type"))===null||i===void 0?void 0:i.indexOf("application/json"))!==null&&r!==void 0?r:-1)!==-1?a.json():a.text()}k(_.System);const z=function(){var e,t,n,o,i;try{if(!((t=(e=window.chrome)===null||e===void 0?void 0:e.webview)===null||t===void 0)&&t.postMessage)return window.chrome.webview.postMessage.bind(window.chrome.webview);if(!((i=(o=(n=window.webkit)===null||n===void 0?void 0:n.messageHandlers)===null||o===void 0?void 0:o.external)===null||i===void 0)&&i.postMessage)return window.webkit.messageHandlers.external.postMessage.bind(window.webkit.messageHandlers.external)}catch{}return console.warn(`
%c Browser Environment Detected %c
%cOnly UI previews are available in the browser. For full functionality, please run the application in desktop mode.
More information at: https://v3.wails.io/learn/build/#using-a-browser-for-development
`,"background: #ffffff; color: #000000; font-weight: bold; padding: 4px 8px; border-radius: 4px; border: 2px solid #000000;","background: transparent;","color: #ffffff; font-style: italic; font-weight: bold;"),null}();function h(e){z==null||z(e)}function H(){return window._wails.environment.OS==="windows"}function W(){return!!window._wails.environment.Debug}function B(){return new MouseEvent("mousedown").buttons===0}function P(e){var t;return e.target instanceof HTMLElement?e.target:!(e.target instanceof HTMLElement)&&e.target instanceof Node&&(t=e.target.parentElement)!==null&&t!==void 0?t:document.body}document.addEventListener("DOMContentLoaded",()=>{});window.addEventListener("contextmenu",X);const N=k(_.ContextMenu),j=0;function F(e,t,n,o){N(j,{id:e,x:t,y:n,data:o})}function X(e){const t=P(e),n=window.getComputedStyle(t).getPropertyValue("--custom-contextmenu").trim();if(n){e.preventDefault();const o=window.getComputedStyle(t).getPropertyValue("--custom-contextmenu-data");F(n,e.clientX,e.clientY,o)}else Y(e,t)}function Y(e,t){if(W())return;switch(window.getComputedStyle(t).getPropertyValue("--default-contextmenu").trim()){case"show":return;case"hide":e.preventDefault();return}if(t.isContentEditable)return;const n=window.getSelection(),o=n&&n.toString().length>0;if(o)for(let i=0;i<n.rangeCount;i++){const s=n.getRangeAt(i).getClientRects();for(let c=0;c<s.length;c++){const a=s[c];if(document.elementFromPoint(a.left,a.top)===t)return}}(t instanceof HTMLInputElement||t instanceof HTMLTextAreaElement)&&(o||!t.readOnly&&!t.disabled)||e.preventDefault()}function x(e){try{return window._wails.flags[e]}catch(t){throw new Error("Unable to retrieve flag '"+e+"': "+t,{cause:t})}}let m=!1,g=!1,M=!1,w=!1,p=!1,u="",O="auto",f=0;const E=B();window._wails=window._wails||{};window._wails.setResizable=e=>{M=e,M||(w=p=!1,l())};window.addEventListener("mousedown",D,{capture:!0});window.addEventListener("mousemove",D,{capture:!0});window.addEventListener("mouseup",D,{capture:!0});for(const e of["click","contextmenu","dblclick"])window.addEventListener(e,A,{capture:!0});function A(e){(g||p)&&(e.stopImmediatePropagation(),e.stopPropagation(),e.preventDefault())}const C=0,V=1,L=2;function D(e){let t,n=e.buttons;switch(e.type){case"mousedown":t=C,E||(n=f|1<<e.button);break;case"mouseup":t=V,E||(n=f&~(1<<e.button));break;default:t=L,E||(n=f);break}let o=f&~n,i=n&~f;f=n,t===C&&!(i&e.button)&&(o|=1<<e.button,i|=1<<e.button),(t!==L&&p||g&&(t===C||e.button!==0))&&(e.stopImmediatePropagation(),e.stopPropagation(),e.preventDefault()),o&1&&G(),i&1&&q(e),t===L&&K(e)}function q(e){if(m=!1,w=!1,!H()&&e.type==="mousedown"&&e.button===0&&e.detail!==1)return;if(u){w=!0;return}const t=P(e),n=window.getComputedStyle(t);m=n.getPropertyValue("--wails-draggable").trim()==="drag"&&e.offsetX-parseFloat(n.paddingLeft)<t.clientWidth&&e.offsetY-parseFloat(n.paddingTop)<t.clientHeight}function G(e){m=!1,g=!1,w=!1,p=!1}const J=Object.freeze({"se-resize":"nwse-resize","sw-resize":"nesw-resize","nw-resize":"nwse-resize","ne-resize":"nesw-resize","w-resize":"ew-resize","n-resize":"ns-resize","s-resize":"ns-resize","e-resize":"ew-resize"});function l(e){e?(u||(O=document.body.style.cursor),document.body.style.cursor=J[e]):!e&&u&&(document.body.style.cursor=O),u=e||""}function K(e){if(w&&u?(p=!0,h("wails:resize:"+u)):m&&(g=!0,h("wails:drag")),g||p){m=w=!1;return}if(!M||!H()){u&&l();return}const t=x("system.resizeHandleHeight")||5,n=x("system.resizeHandleWidth")||5,o=x("resizeCornerExtra")||10,i=window.outerWidth-e.clientX<n,r=e.clientX<n,s=e.clientY<t,c=window.outerHeight-e.clientY<t,a=window.outerWidth-e.clientX<n+o,b=e.clientX<n+o,y=e.clientY<t+o,v=window.outerHeight-e.clientY<t+o;!b&&!y&&!v&&!a?l():a&&v?l("se-resize"):b&&v?l("sw-resize"):b&&y?l("nw-resize"):y&&a?l("ne-resize"):r?l("w-resize"):s?l("n-resize"):c?l("s-resize"):i?l("e-resize"):l()}const d=new Map;class Q{constructor(t,n,o){this.eventName=t,this.callback=n,this.maxCallbacks=o||-1}dispatch(t){try{this.callback(t)}catch(n){console.error(n)}return this.maxCallbacks===-1?!1:(this.maxCallbacks-=1,this.maxCallbacks===0)}}function Z(e){let t=d.get(e.eventName);t&&(t=t.filter(n=>n!==e),t.length===0?d.delete(e.eventName):d.set(e.eventName,t))}window._wails=window._wails||{};window._wails.dispatchWailsEvent=ee;k(_.Events);class ${constructor(t,n=null){this.name=t,this.data=n}}function ee(e){let t=d.get(e.name);if(!t)return;let n=new $(e.name,e.data);"sender"in e&&(n.sender=e.sender),t=t.filter(o=>!o.dispatch(n)),t.length===0?d.delete(e.name):d.set(e.name,t)}function te(e,t,n){let o=d.get(e)||[];const i=new Q(e,t,n);return o.push(i),d.set(e,o),()=>Z(i)}function ne(e,t){return te(e,t,-1)}window._wails=window._wails||{};window._wails.invoke=h;h("wails:runtime:ready");document.addEventListener("DOMContentLoaded",()=>{const e=document.getElementById("app");e?e.innerHTML=`
<div class="container">
<h1>Custom Protocol / Deep Link Test</h1>
<p>
This page demonstrates handling custom URL schemes (deep links).
</p>
<p>
<span class="label">Example Link:</span>
Try opening this URL (e.g., by pasting it into your browser's address bar or using <code>open your-app-scheme://...</code> in terminal):
<br>
<a href="wailsexample://test/path?value=123&message=hello" id="example-url">wailsexample://test/path?value=123&message=hello</a>
</p>
<div class="url-display">
<span class="label">Received URL:</span>
<div id="received-url"><em>Waiting for application to be opened via a custom URL...</em></div>
</div>
</div>
`:console.error('Element with ID "app" not found.')});ne("frontend:ShowURL",e=>{console.log("frontend:ShowURL event received, data:",e),displayUrl(e.data)});window.displayUrl=function(e){const t=document.getElementById("received-url");t?t.textContent=e||"No URL received or an error occurred.":console.error("Element with ID 'received-url' not found in displayUrl.")};

View file

@ -0,0 +1 @@
:root{font-family:system-ui,Avenir,Helvetica,Arial,sans-serif;line-height:1.5;font-weight:400;color-scheme:light dark;color:#ffffffde;background-color:#242424;font-synthesis:none;text-rendering:optimizeLegibility;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}a{font-weight:500;color:#646cff;text-decoration:inherit}a:hover{color:#535bf2}body{font-family:system-ui,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen,Ubuntu,Cantarell,Open Sans,Helvetica Neue,sans-serif;margin:0;background-color:#f7f7f7;color:#333;display:flex;justify-content:center;align-items:center;min-height:100vh;padding:20px;box-sizing:border-box}h1{color:#0056b3;font-size:1.8em;margin-bottom:.8em}#app{width:100%;max-width:600px;margin:auto}.container{background-color:#fff;padding:25px 30px;border-radius:8px;box-shadow:0 2px 10px #0000001a;text-align:left}p{line-height:1.6;font-size:1em;margin-bottom:1em}a{color:#007bff;text-decoration:none}a:hover{text-decoration:underline}.url-display{margin-top:25px;padding:15px;background-color:#e9ecef;border:1px solid #ced4da;border-radius:4px;font-family:Courier New,Courier,monospace;font-size:.95em;word-break:break-all}.label{font-weight:700;display:block;margin-bottom:8px;color:#495057}.logo{height:6em;padding:1.5em;will-change:filter;transition:filter .3s}.logo:hover{filter:drop-shadow(0 0 2em #646cffaa)}.logo.vanilla:hover{filter:drop-shadow(0 0 2em #f7df1eaa)}.card{padding:2em}.read-the-docs{color:#888}button{border-radius:8px;border:1px solid transparent;padding:.6em 1.2em;font-size:1em;font-weight:500;font-family:inherit;background-color:#1a1a1a;cursor:pointer;transition:border-color .25s}button:hover{border-color:#646cff}button:focus,button:focus-visible{outline:4px auto -webkit-focus-ring-color}@media (prefers-color-scheme: light){:root{color:#213547;background-color:#fff}a:hover{color:#747bff}button{background-color:#f9f9f9}}

View file

@ -0,0 +1,14 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Vite App</title>
<script type="module" crossorigin src="/assets/index-BS9x21Y4.js"></script>
<link rel="stylesheet" crossorigin href="/assets/index-uDrhEpT0.css">
</head>
<body>
<div id="app"></div>
</body>
</html>

View file

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" class="iconify iconify--logos" width="31.88" height="32" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 257"><defs><linearGradient id="IconifyId1813088fe1fbc01fb466" x1="-.828%" x2="57.636%" y1="7.652%" y2="78.411%"><stop offset="0%" stop-color="#41D1FF"></stop><stop offset="100%" stop-color="#BD34FE"></stop></linearGradient><linearGradient id="IconifyId1813088fe1fbc01fb467" x1="43.376%" x2="50.316%" y1="2.242%" y2="89.03%"><stop offset="0%" stop-color="#FFEA83"></stop><stop offset="8.333%" stop-color="#FFDD35"></stop><stop offset="100%" stop-color="#FFA800"></stop></linearGradient></defs><path fill="url(#IconifyId1813088fe1fbc01fb466)" d="M255.153 37.938L134.897 252.976c-2.483 4.44-8.862 4.466-11.382.048L.875 37.958c-2.746-4.814 1.371-10.646 6.827-9.67l120.385 21.517a6.537 6.537 0 0 0 2.322-.004l117.867-21.483c5.438-.991 9.574 4.796 6.877 9.62Z"></path><path fill="url(#IconifyId1813088fe1fbc01fb467)" d="M185.432.063L96.44 17.501a3.268 3.268 0 0 0-2.634 3.014l-5.474 92.456a3.268 3.268 0 0 0 3.997 3.378l24.777-5.718c2.318-.535 4.413 1.507 3.936 3.838l-7.361 36.047c-.495 2.426 1.782 4.5 4.151 3.78l15.304-4.649c2.372-.72 4.652 1.36 4.15 3.788l-11.698 56.621c-.732 3.542 3.979 5.473 5.943 2.437l1.313-2.028l72.516-144.72c1.215-2.423-.88-5.186-3.54-4.672l-25.505 4.922c-2.396.462-4.435-1.77-3.759-4.114l16.646-57.705c.677-2.35-1.37-4.583-3.769-4.113Z"></path></svg>

After

Width:  |  Height:  |  Size: 1.5 KiB

View file

@ -0,0 +1,13 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Vite App</title>
</head>
<body>
<div id="app"></div>
<script type="module" src="/src/main.js"></script>
</body>
</html>

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,17 @@
{
"name": "frontend",
"private": true,
"version": "0.0.0",
"type": "module",
"scripts": {
"dev": "vite",
"build": "vite build",
"preview": "vite preview"
},
"devDependencies": {
"vite": "^6.3.5"
},
"dependencies": {
"@wailsio/runtime": "^3.0.0-alpha.66"
}
}

View file

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" class="iconify iconify--logos" width="31.88" height="32" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 257"><defs><linearGradient id="IconifyId1813088fe1fbc01fb466" x1="-.828%" x2="57.636%" y1="7.652%" y2="78.411%"><stop offset="0%" stop-color="#41D1FF"></stop><stop offset="100%" stop-color="#BD34FE"></stop></linearGradient><linearGradient id="IconifyId1813088fe1fbc01fb467" x1="43.376%" x2="50.316%" y1="2.242%" y2="89.03%"><stop offset="0%" stop-color="#FFEA83"></stop><stop offset="8.333%" stop-color="#FFDD35"></stop><stop offset="100%" stop-color="#FFA800"></stop></linearGradient></defs><path fill="url(#IconifyId1813088fe1fbc01fb466)" d="M255.153 37.938L134.897 252.976c-2.483 4.44-8.862 4.466-11.382.048L.875 37.958c-2.746-4.814 1.371-10.646 6.827-9.67l120.385 21.517a6.537 6.537 0 0 0 2.322-.004l117.867-21.483c5.438-.991 9.574 4.796 6.877 9.62Z"></path><path fill="url(#IconifyId1813088fe1fbc01fb467)" d="M185.432.063L96.44 17.501a3.268 3.268 0 0 0-2.634 3.014l-5.474 92.456a3.268 3.268 0 0 0 3.997 3.378l24.777-5.718c2.318-.535 4.413 1.507 3.936 3.838l-7.361 36.047c-.495 2.426 1.782 4.5 4.151 3.78l15.304-4.649c2.372-.72 4.652 1.36 4.15 3.788l-11.698 56.621c-.732 3.542 3.979 5.473 5.943 2.437l1.313-2.028l72.516-144.72c1.215-2.423-.88-5.186-3.54-4.672l-25.505 4.922c-2.396.462-4.435-1.77-3.759-4.114l16.646-57.705c.677-2.35-1.37-4.583-3.769-4.113Z"></path></svg>

After

Width:  |  Height:  |  Size: 1.5 KiB

View file

@ -0,0 +1,9 @@
export function setupCounter(element) {
let counter = 0
const setCounter = (count) => {
counter = count
element.innerHTML = `count is ${counter}`
}
element.addEventListener('click', () => setCounter(counter + 1))
setCounter(0)
}

View file

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" class="iconify iconify--logos" width="32" height="32" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 256"><path fill="#F7DF1E" d="M0 0h256v256H0V0Z"></path><path d="m67.312 213.932l19.59-11.856c3.78 6.701 7.218 12.371 15.465 12.371c7.905 0 12.89-3.092 12.89-15.12v-81.798h24.057v82.138c0 24.917-14.606 36.259-35.916 36.259c-19.245 0-30.416-9.967-36.087-21.996m85.07-2.576l19.588-11.341c5.157 8.421 11.859 14.607 23.715 14.607c9.969 0 16.325-4.984 16.325-11.858c0-8.248-6.53-11.17-17.528-15.98l-6.013-2.58c-17.357-7.387-28.87-16.667-28.87-36.257c0-18.044 13.747-31.792 35.228-31.792c15.294 0 26.292 5.328 34.196 19.247l-18.732 12.03c-4.125-7.389-8.591-10.31-15.465-10.31c-7.046 0-11.514 4.468-11.514 10.31c0 7.217 4.468 10.14 14.778 14.608l6.014 2.577c20.45 8.765 31.963 17.7 31.963 37.804c0 21.654-17.012 33.51-39.867 33.51c-22.339 0-36.774-10.654-43.819-24.574"></path></svg>

After

Width:  |  Height:  |  Size: 995 B

View file

@ -0,0 +1,45 @@
import './style.css'
import { Events } from '@wailsio/runtime'
document.addEventListener('DOMContentLoaded', () => {
const appDiv = document.getElementById('app');
if (appDiv) {
appDiv.innerHTML = `
<div class="container">
<h1>Custom Protocol / Deep Link Test</h1>
<p>
This page demonstrates handling custom URL schemes (deep links).
</p>
<p>
<span class="label">Example Link:</span>
Try opening this URL (e.g., by pasting it into your browser's address bar or using <code>open your-app-scheme://...</code> in terminal):
<br>
<a href="wailsexample://test/path?value=123&message=hello" id="example-url">wailsexample://test/path?value=123&message=hello</a>
</p>
<div class="url-display">
<span class="label">Received URL:</span>
<div id="received-url"><em>Waiting for application to be opened via a custom URL...</em></div>
</div>
</div>
`;
} else {
console.error('Element with ID "app" not found.');
}
});
// Listen for the event from Go
Events.On('frontend:ShowURL', (e) => {
console.log('frontend:ShowURL event received, data:', e);
displayUrl(e.data);
});
// Make displayUrl available globally just in case, though direct call from event is better
window.displayUrl = function(url) {
const urlElement = document.getElementById('received-url');
if (urlElement) {
urlElement.textContent = url || "No URL received or an error occurred.";
} else {
console.error("Element with ID 'received-url' not found in displayUrl.");
}
}

View file

@ -0,0 +1,142 @@
:root {
font-family: system-ui, Avenir, Helvetica, Arial, sans-serif;
line-height: 1.5;
font-weight: 400;
color-scheme: light dark;
color: rgba(255, 255, 255, 0.87);
background-color: #242424;
font-synthesis: none;
text-rendering: optimizeLegibility;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
a {
font-weight: 500;
color: #646cff;
text-decoration: inherit;
}
a:hover {
color: #535bf2;
}
body {
font-family: system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif;
margin: 0; /* Reset default margin */
background-color: #f7f7f7;
color: #333;
display: flex; /* Use flexbox to center content */
justify-content: center; /* Center horizontally */
align-items: center; /* Center vertically */
min-height: 100vh; /* Full viewport height */
padding: 20px; /* Add some padding around the content */
box-sizing: border-box; /* Ensure padding doesn't expand body beyond viewport */
}
h1 {
color: #0056b3;
font-size: 1.8em;
margin-bottom: 0.8em;
}
#app {
width: 100%;
max-width: 600px;
margin: auto; /* This also helps in centering if body flex isn't enough or overridden */
}
.container {
background-color: #fff;
padding: 25px 30px;
border-radius: 8px;
box-shadow: 0 2px 10px rgba(0,0,0,0.1);
text-align: left;
}
p {
line-height: 1.6;
font-size: 1em;
margin-bottom: 1em;
}
a {
color: #007bff;
text-decoration: none;
}
a:hover {
text-decoration: underline;
}
.url-display {
margin-top: 25px;
padding: 15px;
background-color: #e9ecef;
border: 1px solid #ced4da;
border-radius: 4px;
font-family: 'Courier New', Courier, monospace;
font-size: 0.95em;
word-break: break-all;
}
.label {
font-weight: bold;
display: block;
margin-bottom: 8px;
color: #495057;
}
.logo {
height: 6em;
padding: 1.5em;
will-change: filter;
transition: filter 300ms;
}
.logo:hover {
filter: drop-shadow(0 0 2em #646cffaa);
}
.logo.vanilla:hover {
filter: drop-shadow(0 0 2em #f7df1eaa);
}
.card {
padding: 2em;
}
.read-the-docs {
color: #888;
}
button {
border-radius: 8px;
border: 1px solid transparent;
padding: 0.6em 1.2em;
font-size: 1em;
font-weight: 500;
font-family: inherit;
background-color: #1a1a1a;
cursor: pointer;
transition: border-color 0.25s;
}
button:hover {
border-color: #646cff;
}
button:focus,
button:focus-visible {
outline: 4px auto -webkit-focus-ring-color;
}
@media (prefers-color-scheme: light) {
:root {
color: #213547;
background-color: #ffffff;
}
a:hover {
color: #747bff;
}
button {
background-color: #f9f9f9;
}
}

View file

@ -0,0 +1,7 @@
package main
type GreetService struct{}
func (g *GreetService) Greet(name string) string {
return "Hello " + name + "!"
}

View file

@ -0,0 +1,82 @@
package main
import (
"embed"
_ "embed"
"log"
"time"
"github.com/wailsapp/wails/v3/pkg/application"
"github.com/wailsapp/wails/v3/pkg/events"
)
// Wails uses Go's `embed` package to embed the frontend files into the binary.
// Any files in the frontend/dist folder will be embedded into the binary and
// made available to the frontend.
// See https://pkg.go.dev/embed for more information.
//go:embed all:frontend/dist
var assets embed.FS
// main function serves as the application's entry point. It initializes the application, creates a window,
// and starts a goroutine that emits a time-based event every second. It subsequently runs the application and
// logs any error that might occur.
func main() {
// Create a new Wails application by providing the necessary options.
// Variables 'Name' and 'Description' are for application metadata.
// 'Assets' configures the asset server with the 'FS' variable pointing to the frontend files.
// 'Bind' is a list of Go struct instances. The frontend has access to the methods of these instances.
// 'Mac' options tailor the application when running an macOS.
app := application.New(application.Options{
Name: "custom-protocol-example",
Description: "A demo of using raw HTML & CSS",
Services: []application.Service{
application.NewService(&GreetService{}),
},
Assets: application.AssetOptions{
Handler: application.AssetFileServerFS(assets),
},
Mac: application.MacOptions{
ApplicationShouldTerminateAfterLastWindowClosed: true,
},
})
// Listen for the system event indicating the app was launched with a URL
app.Event.OnApplicationEvent(events.Common.ApplicationLaunchedWithUrl, func(e *application.ApplicationEvent) {
app.Event.Emit("frontend:ShowURL", e.Context().URL())
})
// Create a new window with the necessary options.
// 'Title' is the title of the window.
// 'Mac' options tailor the window when running on macOS.
// 'BackgroundColour' is the background colour of the window.
// 'URL' is the URL that will be loaded into the webview.
_ = app.Window.NewWithOptions(application.WebviewWindowOptions{
Title: "Window 1",
Mac: application.MacWindow{
InvisibleTitleBarHeight: 50,
Backdrop: application.MacBackdropTranslucent,
TitleBar: application.MacTitleBarHiddenInset,
},
BackgroundColour: application.NewRGB(27, 38, 54),
URL: "/",
})
// Create a goroutine that emits an event containing the current time every second.
// The frontend can listen to this event and update the UI accordingly.
go func() {
for {
now := time.Now().Format(time.RFC1123)
app.Event.Emit("time", now)
time.Sleep(time.Second)
}
}()
// Run the application. This blocks until the application has been exited.
err := app.Run()
// If an error occurred while running the application, log it and exit.
if err != nil {
log.Fatal(err)
}
}

View file

@ -21,8 +21,17 @@ var buildAssets embed.FS
//go:embed updatable_build_assets
var updatableBuildAssets embed.FS
// ProtocolConfig defines the structure for a custom protocol in wails.json/wails.yaml
type ProtocolConfig struct {
Scheme string `yaml:"scheme" json:"scheme"`
Description string `yaml:"description,omitempty" json:"description,omitempty"`
// Future platform-specific fields can be added here if needed by templates.
// E.g., for macOS: CFBundleURLName string `yaml:"cfBundleURLName,omitempty" json:"cfBundleURLName,omitempty"`
}
// BuildAssetsOptions defines the options for generating build assets.
type BuildAssetsOptions struct {
Dir string `description:"The directory to generate the files into" default:"."`
Dir string `description:"The directory to generate the files into" default:"."`
Name string `description:"The name of the project"`
BinaryName string `description:"The name of the binary"`
ProductName string `description:"The name of the product" default:"My Product"`
@ -42,26 +51,30 @@ type BuildAssetsOptions struct {
Typescript bool `description:"Use typescript" default:"false"`
}
// BuildConfig defines the configuration for generating build assets.
type BuildConfig struct {
BuildAssetsOptions
FileAssociations []FileAssociation `yaml:"fileAssociations"`
Protocols []ProtocolConfig `yaml:"protocols,omitempty"`
}
// UpdateBuildAssetsOptions defines the options for updating build assets.
type UpdateBuildAssetsOptions struct {
Dir string `description:"The directory to generate the files into" default:"build"`
Dir string `description:"The directory to generate the files into" default:"build"`
Name string `description:"The name of the project"`
BinaryName string `description:"The name of the binary"`
ProductName string `description:"The name of the product" default:"My Product"`
ProductDescription string `description:"The description of the product" default:"My Product Description"`
ProductVersion string `description:"The version of the product" default:"0.1.0"`
ProductCompany string `description:"The company of the product" default:"My Company"`
ProductCopyright string `description:"The copyright notice" default:"\u00a9 now, My Company"`
ProductComments string `description:"Comments to add to the generated files" default:"This is a comment"`
ProductName string `description:"The name of the product" default:"My Product"`
ProductDescription string `description:"The description of the product" default:"My Product Description"`
ProductVersion string `description:"The version of the product" default:"0.1.0"`
ProductCompany string `description:"The company of the product" default:"My Company"`
ProductCopyright string `description:"The copyright notice" default:"© now, My Company"`
ProductComments string `description:"Comments to add to the generated files" default:"This is a comment"`
ProductIdentifier string `description:"The product identifier, e.g com.mycompany.myproduct"`
Config string `description:"The path to the config file"`
Silent bool `description:"Suppress output to console"`
}
// GenerateBuildAssets generates the build assets for the project.
func GenerateBuildAssets(options *BuildAssetsOptions) error {
DisableFooter = true
@ -144,6 +157,7 @@ func GenerateBuildAssets(options *BuildAssetsOptions) error {
return nil
}
// FileAssociation defines the structure for a file association.
type FileAssociation struct {
Ext string `yaml:"ext"`
Name string `yaml:"name"`
@ -153,11 +167,14 @@ type FileAssociation struct {
MimeType string `yaml:"mimeType"`
}
// UpdateConfig defines the configuration for updating build assets.
type UpdateConfig struct {
UpdateBuildAssetsOptions
FileAssociations []FileAssociation `yaml:"fileAssociations"`
Protocols []ProtocolConfig `yaml:"protocols,omitempty"`
}
// WailsConfig defines the structure for a Wails configuration.
type WailsConfig struct {
Info struct {
CompanyName string `yaml:"companyName"`
@ -168,9 +185,11 @@ type WailsConfig struct {
Comments string `yaml:"comments"`
Version string `yaml:"version"`
} `yaml:"info"`
FileAssociations []FileAssociation `yaml:"fileAssociations"`
FileAssociations []FileAssociation `yaml:"fileAssociations,omitempty"`
Protocols []ProtocolConfig `yaml:"protocols,omitempty"`
}
// UpdateBuildAssets updates the build assets for the project.
func UpdateBuildAssets(options *UpdateBuildAssetsOptions) error {
DisableFooter = true
@ -200,6 +219,7 @@ func UpdateBuildAssets(options *UpdateBuildAssetsOptions) error {
options.ProductComments = wailsConfig.Info.Comments
options.ProductVersion = wailsConfig.Info.Version
config.FileAssociations = wailsConfig.FileAssociations
config.Protocols = wailsConfig.Protocols
}
config.UpdateBuildAssetsOptions = *options

View file

@ -1 +1,21 @@
#!/bin/bash
#!/bin/sh
# Update desktop database for .desktop file changes
# This makes the application appear in application menus and registers its capabilities.
if command -v update-desktop-database >/dev/null 2>&1; then
echo "Updating desktop database..."
update-desktop-database -q /usr/share/applications
else
echo "Warning: update-desktop-database command not found. Desktop file may not be immediately recognized." >&2
fi
# Update MIME database for custom URL schemes (x-scheme-handler)
# This ensures the system knows how to handle your custom protocols.
if command -v update-mime-database >/dev/null 2>&1; then
echo "Updating MIME database..."
update-mime-database -n /usr/share/mime
else
echo "Warning: update-mime-database command not found. Custom URL schemes may not be immediately recognized." >&2
fi
exit 0

View file

@ -51,5 +51,20 @@
<key>NSAllowsLocalNetworking</key>
<true/>
</dict>
{{- if .Protocols}}
<key>CFBundleURLTypes</key>
<array>
{{- range .Protocols}}
<dict>
<key>CFBundleURLName</key>
<string>wails.com.{{.Scheme}}</string>
<key>CFBundleURLSchemes</key>
<array>
<string>{{.Scheme}}</string>
</array>
</dict>
{{- end}}
</array>
{{- end}}
</dict>
</plist>

View file

@ -46,5 +46,20 @@
{{- end}}
</array>
{{- end}}
{{- if .Protocols}}
<key>CFBundleURLTypes</key>
<array>
{{- range .Protocols}}
<dict>
<key>CFBundleURLName</key>
<string>wails.com.{{.Scheme}}</string>
<key>CFBundleURLSchemes</key>
<array>
<string>{{.Scheme}}</string>
</array>
</dict>
{{- end}}
</array>
{{- end}}
</dict>
</plist>

View file

@ -0,0 +1,15 @@
[Desktop Entry]
Version=1.0
Name={{.ProductName}}
Comment={{.ProductDescription}}
# The Exec line includes %u to pass the URL to the application
Exec=/usr/local/bin/{{.BinaryName}} %u
Terminal=false
Type=Application
Icon={{.BinaryName}}
Categories=Utility;
StartupWMClass={{.BinaryName}}
{{if .Protocols -}}
MimeType={{range $index, $protocol := .Info.Protocols}}x-scheme-handler/{{$protocol.Scheme}};{{end}}
{{- end}}

View file

@ -49,6 +49,13 @@ overrides:
- base-devel
- pkgconf
# scripts section to ensure desktop database is updated after install
scripts:
postinstall: "./build/linux/nfpm/scripts/postinstall.sh"
# You can also add preremove, postremove if needed
# preremove: "./build/linux/nfpm/scripts/preremove.sh"
# postremove: "./build/linux/nfpm/scripts/postremove.sh"
# replaces:
# - foobar
# provides:
@ -63,9 +70,4 @@ overrides:
# conflicts:
# - not-foo
# - not-bar
# changelog: "changelog.yaml"
# scripts:
# preinstall: ./build/linux/nfpm/scripts/preinstall.sh
# postinstall: ./build/linux/nfpm/scripts/postinstall.sh
# preremove: ./build/linux/nfpm/scripts/preremove.sh
# postremove: ./build/linux/nfpm/scripts/postremove.sh
# changelog: "changelog.yaml"

View file

@ -205,6 +205,7 @@ export const Types = Object.freeze({
Common: Object.freeze({
ApplicationOpenedWithFile: "common:ApplicationOpenedWithFile",
ApplicationStarted: "common:ApplicationStarted",
ApplicationLaunchedWithUrl: "common:ApplicationLaunchedWithUrl",
ThemeChanged: "common:ThemeChanged",
WindowClosing: "common:WindowClosing",
WindowDidMove: "common:WindowDidMove",

View file

@ -57,6 +57,8 @@ static void init(void) {
NSDistributedNotificationCenter *center = [NSDistributedNotificationCenter defaultCenter];
[center addObserver:appDelegate selector:@selector(themeChanged:) name:@"AppleInterfaceThemeChangedNotification" object:nil];
// Register the custom URL scheme handler
StartCustomProtocolHandler();
}
static bool isDarkMode(void) {
@ -428,3 +430,16 @@ func HandleOpenFile(filePath *C.char) {
ctx: eventContext,
}
}
//export HandleCustomProtocol
func HandleCustomProtocol(urlCString *C.char) {
urlString := C.GoString(urlCString)
eventContext := newApplicationEventContext()
eventContext.setURL(urlString)
// Emit the standard event with the URL string as data
applicationEvents <- &ApplicationEvent{
Id: uint(events.Common.ApplicationLaunchedWithUrl),
ctx: eventContext,
}
}

View file

@ -13,4 +13,13 @@
extern void HandleOpenFile(char *);
#endif
// Declarations for Apple Event based custom URL handling
extern void HandleCustomProtocol(char*);
@interface CustomProtocolSchemeHandler : NSObject
+ (void)handleGetURLEvent:(NSAppleEventDescriptor *)event withReplyEvent:(NSAppleEventDescriptor *)replyEvent;
@end
void StartCustomProtocolHandler(void);
#endif /* appdelegate_h */

View file

@ -1,6 +1,7 @@
//go:build darwin
#import "application_darwin_delegate.h"
#import "../events/events_darwin.h"
#import <CoreServices/CoreServices.h> // For Apple Event constants
extern bool hasListeners(unsigned int);
extern bool shouldQuitApplication();
extern void cleanup();
@ -41,7 +42,7 @@ extern void handleSecondInstanceData(char * message);
return YES;
}
- (BOOL)applicationShouldHandleReopen:(NSNotification *)notification
hasVisibleWindows:(BOOL)flag {
hasVisibleWindows:(BOOL)flag { // Changed from NSApplication to NSNotification
if( hasListeners(EventApplicationShouldHandleReopen) ) {
processApplicationEvent(EventApplicationShouldHandleReopen, @{@"hasVisibleWindows": @(flag)});
}
@ -179,3 +180,19 @@ extern void handleSecondInstanceData(char * message);
// GENERATED EVENTS END
@end
// Implementation for Apple Event based custom URL handling
@implementation CustomProtocolSchemeHandler
+ (void)handleGetURLEvent:(NSAppleEventDescriptor *)event withReplyEvent:(NSAppleEventDescriptor *)replyEvent {
NSString *urlStr = [[event paramDescriptorForKeyword:keyDirectObject] stringValue];
if (urlStr) {
HandleCustomProtocol((char*)[urlStr UTF8String]);
}
}
@end
void StartCustomProtocolHandler(void) {
NSAppleEventManager *appleEventManager = [NSAppleEventManager sharedAppleEventManager];
[appleEventManager setEventHandler:[CustomProtocolSchemeHandler class]
andSelector:@selector(handleGetURLEvent:withReplyEvent:)
forEventClass:kInternetEventClass
andEventID: kAEGetURL];
}

View file

@ -16,9 +16,12 @@ import "C"
import (
"fmt"
"os"
"slices"
"strings"
"sync"
"path/filepath"
"github.com/godbus/dbus/v5"
"github.com/wailsapp/wails/v3/internal/operatingsystem"
"github.com/wailsapp/wails/v3/pkg/events"
@ -27,7 +30,8 @@ import (
func init() {
// FIXME: This should be handled appropriately in the individual files most likely.
// Set GDK_BACKEND=x11 if currently unset and XDG_SESSION_TYPE is unset, unspecified or x11 to prevent warnings
if os.Getenv("GDK_BACKEND") == "" && (os.Getenv("XDG_SESSION_TYPE") == "" || os.Getenv("XDG_SESSION_TYPE") == "unspecified" || os.Getenv("XDG_SESSION_TYPE") == "x11") {
if os.Getenv("GDK_BACKEND") == "" &&
(os.Getenv("XDG_SESSION_TYPE") == "" || os.Getenv("XDG_SESSION_TYPE") == "unspecified" || os.Getenv("XDG_SESSION_TYPE") == "x11") {
_ = os.Setenv("GDK_BACKEND", "x11")
}
}
@ -94,6 +98,39 @@ func (a *linuxApp) setApplicationMenu(menu *Menu) {
func (a *linuxApp) run() error {
if len(os.Args) == 2 { // Case: program + 1 argument
arg1 := os.Args[1]
// Check if the argument is likely a URL from a custom protocol invocation
if strings.Contains(arg1, "://") {
a.parent.info("Application launched with argument, potentially a URL from custom protocol", "url", arg1)
eventContext := newApplicationEventContext()
eventContext.setURL(arg1)
applicationEvents <- &ApplicationEvent{
Id: uint(events.Common.ApplicationLaunchedWithUrl),
ctx: eventContext,
}
} else {
// Check if the argument matches any file associations
if a.parent.options.FileAssociations != nil {
ext := filepath.Ext(arg1)
if slices.Contains(a.parent.options.FileAssociations, ext) {
a.parent.info("File opened via file association", "file", arg1, "extension", ext)
eventContext := newApplicationEventContext()
eventContext.setOpenedWithFile(arg1)
applicationEvents <- &ApplicationEvent{
Id: uint(events.Common.ApplicationOpenedWithFile),
ctx: eventContext,
}
return nil
}
}
a.parent.info("Application launched with single argument (not a URL), potential file open?", "arg", arg1)
}
} else if len(os.Args) > 2 {
// Log if multiple arguments are passed
a.parent.info("Application launched with multiple arguments", "args", os.Args[1:])
}
a.parent.Event.OnApplicationEvent(events.Linux.ApplicationStartup, func(evt *ApplicationEvent) {
// TODO: What should happen here?
})
@ -147,7 +184,10 @@ func (a *linuxApp) monitorThemeChanges() {
defer handlePanic()
conn, err := dbus.ConnectSessionBus()
if err != nil {
a.parent.info("[WARNING] Failed to connect to session bus; monitoring for theme changes will not function:", err)
a.parent.info(
"[WARNING] Failed to connect to session bus; monitoring for theme changes will not function:",
err,
)
return
}
defer conn.Close()

View file

@ -7,6 +7,7 @@ import (
"os"
"path/filepath"
"slices"
"strings"
"sync"
"sync/atomic"
"syscall"
@ -150,20 +151,35 @@ func (m *windowsApp) run() error {
ctx: blankApplicationEventContext,
}
// Check if there is 1 parameter passed to the application
// and if the extension matches the options.FileAssociations string
if len(os.Args) == 2 {
arg := os.Args[1]
ext := filepath.Ext(arg)
if slices.Contains(m.parent.options.FileAssociations, ext) {
if len(os.Args) == 2 { // Case: program + 1 argument
arg1 := os.Args[1]
// Check if the argument is likely a URL from a custom protocol invocation
if strings.Contains(arg1, "://") {
m.parent.info("Application launched with argument, potentially a URL from custom protocol", "url", arg1)
eventContext := newApplicationEventContext()
eventContext.setOpenedWithFile(arg)
// EmitEvent application started event
eventContext.setURL(arg1)
applicationEvents <- &ApplicationEvent{
Id: uint(events.Common.ApplicationOpenedWithFile),
Id: uint(events.Common.ApplicationLaunchedWithUrl),
ctx: eventContext,
}
} else {
// If not a URL-like string, check for file association
if m.parent.options.FileAssociations != nil {
ext := filepath.Ext(arg1)
if slices.Contains(m.parent.options.FileAssociations, ext) {
m.parent.info("Application launched with file via file association", "file", arg1)
eventContext := newApplicationEventContext()
eventContext.setOpenedWithFile(arg1)
applicationEvents <- &ApplicationEvent{
Id: uint(events.Common.ApplicationOpenedWithFile),
ctx: eventContext,
}
}
}
}
} else if len(os.Args) > 2 {
// Log if multiple arguments are passed, though typical protocol/file launch is a single arg.
m.parent.info("Application launched with multiple arguments", "args", os.Args[1:])
}
_ = m.runMainLoop()
@ -383,7 +399,9 @@ func newPlatformApp(app *App) *windowsApp {
func (a *App) logPlatformInfo() {
var args []any
args = append(args, "Go-WebView2Loader", webviewloader.UsingGoWebview2Loader)
webviewVersion, err := webviewloader.GetAvailableCoreWebView2BrowserVersionString(a.options.Windows.WebviewBrowserPath)
webviewVersion, err := webviewloader.GetAvailableCoreWebView2BrowserVersionString(
a.options.Windows.WebviewBrowserPath,
)
if err != nil {
args = append(args, "WebView2", "Error: "+err.Error())
} else {
@ -398,7 +416,9 @@ func (a *App) logPlatformInfo() {
func (a *App) platformEnvironment() map[string]any {
result := map[string]any{}
webviewVersion, _ := webviewloader.GetAvailableCoreWebView2BrowserVersionString(a.options.Windows.WebviewBrowserPath)
webviewVersion, _ := webviewloader.GetAvailableCoreWebView2BrowserVersionString(
a.options.Windows.WebviewBrowserPath,
)
result["Go-WebView2Loader"] = webviewloader.UsingGoWebview2Loader
result["WebView2"] = webviewVersion
return result

View file

@ -1,19 +1,24 @@
package application
import "log"
var blankApplicationEventContext = &ApplicationEventContext{}
const (
openedFiles = "openedFiles"
filename = "filename"
CONTEXT_OPENED_FILES = "openedFiles"
CONTEXT_FILENAME = "filename"
CONTEXT_URL = "url"
)
// ApplicationEventContext is the context of an application event
type ApplicationEventContext struct {
// contains filtered or unexported fields
data map[string]any
}
// OpenedFiles returns the opened files from the event context if it was set
func (c ApplicationEventContext) OpenedFiles() []string {
files, ok := c.data[openedFiles]
files, ok := c.data[CONTEXT_OPENED_FILES]
if !ok {
return nil
}
@ -25,7 +30,7 @@ func (c ApplicationEventContext) OpenedFiles() []string {
}
func (c ApplicationEventContext) setOpenedFiles(files []string) {
c.data[openedFiles] = files
c.data[CONTEXT_OPENED_FILES] = files
}
func (c ApplicationEventContext) setIsDarkMode(mode bool) {
@ -44,24 +49,31 @@ func (c ApplicationEventContext) getBool(key string) bool {
return result
}
// IsDarkMode returns true if the event context has a dark mode
func (c ApplicationEventContext) IsDarkMode() bool {
return c.getBool("isDarkMode")
}
// HasVisibleWindows returns true if the event context has a visible window
func (c ApplicationEventContext) HasVisibleWindows() bool {
return c.getBool("hasVisibleWindows")
}
func (c ApplicationEventContext) setData(data map[string]any) {
func (c *ApplicationEventContext) setData(data map[string]any) {
c.data = data
}
func (c ApplicationEventContext) setOpenedWithFile(filepath string) {
c.data[filename] = filepath
func (c *ApplicationEventContext) setOpenedWithFile(filepath string) {
c.data[CONTEXT_FILENAME] = filepath
}
func (c *ApplicationEventContext) setURL(openedWithURL string) {
c.data[CONTEXT_URL] = openedWithURL
}
// Filename returns the filename from the event context if it was set
func (c ApplicationEventContext) Filename() string {
filename, ok := c.data[filename]
filename, ok := c.data[CONTEXT_FILENAME]
if !ok {
return ""
}
@ -72,6 +84,21 @@ func (c ApplicationEventContext) Filename() string {
return result
}
// URL returns the URL from the event context if it was set
func (c ApplicationEventContext) URL() string {
url, ok := c.data[CONTEXT_URL]
if !ok {
log.Println("URL not found in event context")
return ""
}
result, ok := url.(string)
if !ok {
log.Println("URL not a string in event context")
return ""
}
return result
}
func newApplicationEventContext() *ApplicationEventContext {
return &ApplicationEventContext{
data: make(map[string]any),

View file

@ -1,13 +1,14 @@
package events
type ApplicationEventType uint
type WindowEventType uint
type WindowEventType uint
var Common = newCommonEvents()
type commonEvents struct {
ApplicationOpenedWithFile ApplicationEventType
ApplicationStarted ApplicationEventType
ApplicationLaunchedWithUrl ApplicationEventType
ThemeChanged ApplicationEventType
WindowClosing WindowEventType
WindowDidMove WindowEventType
@ -20,7 +21,6 @@ type commonEvents struct {
WindowLostFocus WindowEventType
WindowMaximise WindowEventType
WindowMinimise WindowEventType
WindowToggleFrameless WindowEventType
WindowRestore WindowEventType
WindowRuntimeReady WindowEventType
WindowShow WindowEventType
@ -37,19 +37,19 @@ func newCommonEvents() commonEvents {
return commonEvents{
ApplicationOpenedWithFile: 1024,
ApplicationStarted: 1025,
ThemeChanged: 1026,
WindowClosing: 1027,
WindowDidMove: 1028,
WindowDidResize: 1029,
WindowDPIChanged: 1030,
WindowFilesDropped: 1031,
WindowFocus: 1032,
WindowFullscreen: 1033,
WindowHide: 1034,
WindowLostFocus: 1035,
WindowMaximise: 1036,
WindowMinimise: 1037,
WindowToggleFrameless: 1038,
ApplicationLaunchedWithUrl: 1026,
ThemeChanged: 1027,
WindowClosing: 1028,
WindowDidMove: 1029,
WindowDidResize: 1030,
WindowDPIChanged: 1031,
WindowFilesDropped: 1032,
WindowFocus: 1033,
WindowFullscreen: 1034,
WindowHide: 1035,
WindowLostFocus: 1036,
WindowMaximise: 1037,
WindowMinimise: 1038,
WindowRestore: 1039,
WindowRuntimeReady: 1040,
WindowShow: 1041,
@ -68,12 +68,12 @@ var Linux = newLinuxEvents()
type linuxEvents struct {
ApplicationStartup ApplicationEventType
SystemThemeChanged ApplicationEventType
WindowDeleteEvent WindowEventType
WindowDidMove WindowEventType
WindowDidResize WindowEventType
WindowFocusIn WindowEventType
WindowFocusOut WindowEventType
WindowLoadChanged WindowEventType
WindowDeleteEvent WindowEventType
WindowDidMove WindowEventType
WindowDidResize WindowEventType
WindowFocusIn WindowEventType
WindowFocusOut WindowEventType
WindowLoadChanged WindowEventType
}
func newLinuxEvents() linuxEvents {
@ -92,138 +92,138 @@ func newLinuxEvents() linuxEvents {
var Mac = newMacEvents()
type macEvents struct {
ApplicationDidBecomeActive ApplicationEventType
ApplicationDidChangeBackingProperties ApplicationEventType
ApplicationDidChangeEffectiveAppearance ApplicationEventType
ApplicationDidChangeIcon ApplicationEventType
ApplicationDidChangeOcclusionState ApplicationEventType
ApplicationDidChangeScreenParameters ApplicationEventType
ApplicationDidChangeStatusBarFrame ApplicationEventType
ApplicationDidChangeStatusBarOrientation ApplicationEventType
ApplicationDidChangeTheme ApplicationEventType
ApplicationDidFinishLaunching ApplicationEventType
ApplicationDidHide ApplicationEventType
ApplicationDidResignActive ApplicationEventType
ApplicationDidUnhide ApplicationEventType
ApplicationDidUpdate ApplicationEventType
ApplicationShouldHandleReopen ApplicationEventType
ApplicationWillBecomeActive ApplicationEventType
ApplicationWillFinishLaunching ApplicationEventType
ApplicationWillHide ApplicationEventType
ApplicationWillResignActive ApplicationEventType
ApplicationWillTerminate ApplicationEventType
ApplicationWillUnhide ApplicationEventType
ApplicationWillUpdate ApplicationEventType
MenuDidAddItem ApplicationEventType
MenuDidBeginTracking ApplicationEventType
MenuDidClose ApplicationEventType
MenuDidDisplayItem ApplicationEventType
MenuDidEndTracking ApplicationEventType
MenuDidHighlightItem ApplicationEventType
MenuDidOpen ApplicationEventType
MenuDidPopUp ApplicationEventType
MenuDidRemoveItem ApplicationEventType
MenuDidSendAction ApplicationEventType
MenuDidSendActionToItem ApplicationEventType
MenuDidUpdate ApplicationEventType
MenuWillAddItem ApplicationEventType
MenuWillBeginTracking ApplicationEventType
MenuWillDisplayItem ApplicationEventType
MenuWillEndTracking ApplicationEventType
MenuWillHighlightItem ApplicationEventType
MenuWillOpen ApplicationEventType
MenuWillPopUp ApplicationEventType
MenuWillRemoveItem ApplicationEventType
MenuWillSendAction ApplicationEventType
MenuWillSendActionToItem ApplicationEventType
MenuWillUpdate ApplicationEventType
WebViewDidCommitNavigation WindowEventType
WebViewDidFinishNavigation WindowEventType
ApplicationDidBecomeActive ApplicationEventType
ApplicationDidChangeBackingProperties ApplicationEventType
ApplicationDidChangeEffectiveAppearance ApplicationEventType
ApplicationDidChangeIcon ApplicationEventType
ApplicationDidChangeOcclusionState ApplicationEventType
ApplicationDidChangeScreenParameters ApplicationEventType
ApplicationDidChangeStatusBarFrame ApplicationEventType
ApplicationDidChangeStatusBarOrientation ApplicationEventType
ApplicationDidChangeTheme ApplicationEventType
ApplicationDidFinishLaunching ApplicationEventType
ApplicationDidHide ApplicationEventType
ApplicationDidResignActive ApplicationEventType
ApplicationDidUnhide ApplicationEventType
ApplicationDidUpdate ApplicationEventType
ApplicationShouldHandleReopen ApplicationEventType
ApplicationWillBecomeActive ApplicationEventType
ApplicationWillFinishLaunching ApplicationEventType
ApplicationWillHide ApplicationEventType
ApplicationWillResignActive ApplicationEventType
ApplicationWillTerminate ApplicationEventType
ApplicationWillUnhide ApplicationEventType
ApplicationWillUpdate ApplicationEventType
MenuDidAddItem ApplicationEventType
MenuDidBeginTracking ApplicationEventType
MenuDidClose ApplicationEventType
MenuDidDisplayItem ApplicationEventType
MenuDidEndTracking ApplicationEventType
MenuDidHighlightItem ApplicationEventType
MenuDidOpen ApplicationEventType
MenuDidPopUp ApplicationEventType
MenuDidRemoveItem ApplicationEventType
MenuDidSendAction ApplicationEventType
MenuDidSendActionToItem ApplicationEventType
MenuDidUpdate ApplicationEventType
MenuWillAddItem ApplicationEventType
MenuWillBeginTracking ApplicationEventType
MenuWillDisplayItem ApplicationEventType
MenuWillEndTracking ApplicationEventType
MenuWillHighlightItem ApplicationEventType
MenuWillOpen ApplicationEventType
MenuWillPopUp ApplicationEventType
MenuWillRemoveItem ApplicationEventType
MenuWillSendAction ApplicationEventType
MenuWillSendActionToItem ApplicationEventType
MenuWillUpdate ApplicationEventType
WebViewDidCommitNavigation WindowEventType
WebViewDidFinishNavigation WindowEventType
WebViewDidReceiveServerRedirectForProvisionalNavigation WindowEventType
WebViewDidStartProvisionalNavigation WindowEventType
WindowDidBecomeKey WindowEventType
WindowDidBecomeMain WindowEventType
WindowDidBeginSheet WindowEventType
WindowDidChangeAlpha WindowEventType
WindowDidChangeBackingLocation WindowEventType
WindowDidChangeBackingProperties WindowEventType
WindowDidChangeCollectionBehavior WindowEventType
WindowDidChangeEffectiveAppearance WindowEventType
WindowDidChangeOcclusionState WindowEventType
WindowDidChangeOrderingMode WindowEventType
WindowDidChangeScreen WindowEventType
WindowDidChangeScreenParameters WindowEventType
WindowDidChangeScreenProfile WindowEventType
WindowDidChangeScreenSpace WindowEventType
WindowDidChangeScreenSpaceProperties WindowEventType
WindowDidChangeSharingType WindowEventType
WindowDidChangeSpace WindowEventType
WindowDidChangeSpaceOrderingMode WindowEventType
WindowDidChangeTitle WindowEventType
WindowDidChangeToolbar WindowEventType
WindowDidDeminiaturize WindowEventType
WindowDidEndSheet WindowEventType
WindowDidEnterFullScreen WindowEventType
WindowDidEnterVersionBrowser WindowEventType
WindowDidExitFullScreen WindowEventType
WindowDidExitVersionBrowser WindowEventType
WindowDidExpose WindowEventType
WindowDidFocus WindowEventType
WindowDidMiniaturize WindowEventType
WindowDidMove WindowEventType
WindowDidOrderOffScreen WindowEventType
WindowDidOrderOnScreen WindowEventType
WindowDidResignKey WindowEventType
WindowDidResignMain WindowEventType
WindowDidResize WindowEventType
WindowDidUpdate WindowEventType
WindowDidUpdateAlpha WindowEventType
WindowDidUpdateCollectionBehavior WindowEventType
WindowDidUpdateCollectionProperties WindowEventType
WindowDidUpdateShadow WindowEventType
WindowDidUpdateTitle WindowEventType
WindowDidUpdateToolbar WindowEventType
WindowDidZoom WindowEventType
WindowFileDraggingEntered WindowEventType
WindowFileDraggingExited WindowEventType
WindowFileDraggingPerformed WindowEventType
WindowHide WindowEventType
WindowMaximise WindowEventType
WindowUnMaximise WindowEventType
WindowMinimise WindowEventType
WindowUnMinimise WindowEventType
WindowShouldClose WindowEventType
WindowShow WindowEventType
WindowWillBecomeKey WindowEventType
WindowWillBecomeMain WindowEventType
WindowWillBeginSheet WindowEventType
WindowWillChangeOrderingMode WindowEventType
WindowWillClose WindowEventType
WindowWillDeminiaturize WindowEventType
WindowWillEnterFullScreen WindowEventType
WindowWillEnterVersionBrowser WindowEventType
WindowWillExitFullScreen WindowEventType
WindowWillExitVersionBrowser WindowEventType
WindowWillFocus WindowEventType
WindowWillMiniaturize WindowEventType
WindowWillMove WindowEventType
WindowWillOrderOffScreen WindowEventType
WindowWillOrderOnScreen WindowEventType
WindowWillResignMain WindowEventType
WindowWillResize WindowEventType
WindowWillUnfocus WindowEventType
WindowWillUpdate WindowEventType
WindowWillUpdateAlpha WindowEventType
WindowWillUpdateCollectionBehavior WindowEventType
WindowWillUpdateCollectionProperties WindowEventType
WindowWillUpdateShadow WindowEventType
WindowWillUpdateTitle WindowEventType
WindowWillUpdateToolbar WindowEventType
WindowWillUpdateVisibility WindowEventType
WindowWillUseStandardFrame WindowEventType
WindowZoomIn WindowEventType
WindowZoomOut WindowEventType
WindowZoomReset WindowEventType
WebViewDidStartProvisionalNavigation WindowEventType
WindowDidBecomeKey WindowEventType
WindowDidBecomeMain WindowEventType
WindowDidBeginSheet WindowEventType
WindowDidChangeAlpha WindowEventType
WindowDidChangeBackingLocation WindowEventType
WindowDidChangeBackingProperties WindowEventType
WindowDidChangeCollectionBehavior WindowEventType
WindowDidChangeEffectiveAppearance WindowEventType
WindowDidChangeOcclusionState WindowEventType
WindowDidChangeOrderingMode WindowEventType
WindowDidChangeScreen WindowEventType
WindowDidChangeScreenParameters WindowEventType
WindowDidChangeScreenProfile WindowEventType
WindowDidChangeScreenSpace WindowEventType
WindowDidChangeScreenSpaceProperties WindowEventType
WindowDidChangeSharingType WindowEventType
WindowDidChangeSpace WindowEventType
WindowDidChangeSpaceOrderingMode WindowEventType
WindowDidChangeTitle WindowEventType
WindowDidChangeToolbar WindowEventType
WindowDidDeminiaturize WindowEventType
WindowDidEndSheet WindowEventType
WindowDidEnterFullScreen WindowEventType
WindowDidEnterVersionBrowser WindowEventType
WindowDidExitFullScreen WindowEventType
WindowDidExitVersionBrowser WindowEventType
WindowDidExpose WindowEventType
WindowDidFocus WindowEventType
WindowDidMiniaturize WindowEventType
WindowDidMove WindowEventType
WindowDidOrderOffScreen WindowEventType
WindowDidOrderOnScreen WindowEventType
WindowDidResignKey WindowEventType
WindowDidResignMain WindowEventType
WindowDidResize WindowEventType
WindowDidUpdate WindowEventType
WindowDidUpdateAlpha WindowEventType
WindowDidUpdateCollectionBehavior WindowEventType
WindowDidUpdateCollectionProperties WindowEventType
WindowDidUpdateShadow WindowEventType
WindowDidUpdateTitle WindowEventType
WindowDidUpdateToolbar WindowEventType
WindowDidZoom WindowEventType
WindowFileDraggingEntered WindowEventType
WindowFileDraggingExited WindowEventType
WindowFileDraggingPerformed WindowEventType
WindowHide WindowEventType
WindowMaximise WindowEventType
WindowUnMaximise WindowEventType
WindowMinimise WindowEventType
WindowUnMinimise WindowEventType
WindowShouldClose WindowEventType
WindowShow WindowEventType
WindowWillBecomeKey WindowEventType
WindowWillBecomeMain WindowEventType
WindowWillBeginSheet WindowEventType
WindowWillChangeOrderingMode WindowEventType
WindowWillClose WindowEventType
WindowWillDeminiaturize WindowEventType
WindowWillEnterFullScreen WindowEventType
WindowWillEnterVersionBrowser WindowEventType
WindowWillExitFullScreen WindowEventType
WindowWillExitVersionBrowser WindowEventType
WindowWillFocus WindowEventType
WindowWillMiniaturize WindowEventType
WindowWillMove WindowEventType
WindowWillOrderOffScreen WindowEventType
WindowWillOrderOnScreen WindowEventType
WindowWillResignMain WindowEventType
WindowWillResize WindowEventType
WindowWillUnfocus WindowEventType
WindowWillUpdate WindowEventType
WindowWillUpdateAlpha WindowEventType
WindowWillUpdateCollectionBehavior WindowEventType
WindowWillUpdateCollectionProperties WindowEventType
WindowWillUpdateShadow WindowEventType
WindowWillUpdateTitle WindowEventType
WindowWillUpdateToolbar WindowEventType
WindowWillUpdateVisibility WindowEventType
WindowWillUseStandardFrame WindowEventType
WindowZoomIn WindowEventType
WindowZoomOut WindowEventType
WindowZoomReset WindowEventType
}
func newMacEvents() macEvents {
@ -366,50 +366,50 @@ func newMacEvents() macEvents {
var Windows = newWindowsEvents()
type windowsEvents struct {
APMPowerSettingChange ApplicationEventType
APMPowerStatusChange ApplicationEventType
APMResumeAutomatic ApplicationEventType
APMResumeSuspend ApplicationEventType
APMSuspend ApplicationEventType
ApplicationStarted ApplicationEventType
SystemThemeChanged ApplicationEventType
APMPowerSettingChange ApplicationEventType
APMPowerStatusChange ApplicationEventType
APMResumeAutomatic ApplicationEventType
APMResumeSuspend ApplicationEventType
APMSuspend ApplicationEventType
ApplicationStarted ApplicationEventType
SystemThemeChanged ApplicationEventType
WebViewNavigationCompleted WindowEventType
WindowActive WindowEventType
WindowBackgroundErase WindowEventType
WindowClickActive WindowEventType
WindowClosing WindowEventType
WindowDidMove WindowEventType
WindowDidResize WindowEventType
WindowDPIChanged WindowEventType
WindowDragDrop WindowEventType
WindowDragEnter WindowEventType
WindowDragLeave WindowEventType
WindowDragOver WindowEventType
WindowEndMove WindowEventType
WindowEndResize WindowEventType
WindowFullscreen WindowEventType
WindowHide WindowEventType
WindowInactive WindowEventType
WindowKeyDown WindowEventType
WindowKeyUp WindowEventType
WindowKillFocus WindowEventType
WindowNonClientHit WindowEventType
WindowNonClientMouseDown WindowEventType
WindowNonClientMouseLeave WindowEventType
WindowNonClientMouseMove WindowEventType
WindowNonClientMouseUp WindowEventType
WindowPaint WindowEventType
WindowRestore WindowEventType
WindowSetFocus WindowEventType
WindowShow WindowEventType
WindowStartMove WindowEventType
WindowStartResize WindowEventType
WindowUnFullscreen WindowEventType
WindowZOrderChanged WindowEventType
WindowMinimise WindowEventType
WindowUnMinimise WindowEventType
WindowMaximise WindowEventType
WindowUnMaximise WindowEventType
WindowActive WindowEventType
WindowBackgroundErase WindowEventType
WindowClickActive WindowEventType
WindowClosing WindowEventType
WindowDidMove WindowEventType
WindowDidResize WindowEventType
WindowDPIChanged WindowEventType
WindowDragDrop WindowEventType
WindowDragEnter WindowEventType
WindowDragLeave WindowEventType
WindowDragOver WindowEventType
WindowEndMove WindowEventType
WindowEndResize WindowEventType
WindowFullscreen WindowEventType
WindowHide WindowEventType
WindowInactive WindowEventType
WindowKeyDown WindowEventType
WindowKeyUp WindowEventType
WindowKillFocus WindowEventType
WindowNonClientHit WindowEventType
WindowNonClientMouseDown WindowEventType
WindowNonClientMouseLeave WindowEventType
WindowNonClientMouseMove WindowEventType
WindowNonClientMouseUp WindowEventType
WindowPaint WindowEventType
WindowRestore WindowEventType
WindowSetFocus WindowEventType
WindowShow WindowEventType
WindowStartMove WindowEventType
WindowStartResize WindowEventType
WindowUnFullscreen WindowEventType
WindowZOrderChanged WindowEventType
WindowMinimise WindowEventType
WindowUnMinimise WindowEventType
WindowMaximise WindowEventType
WindowUnMaximise WindowEventType
}
func newWindowsEvents() windowsEvents {
@ -458,7 +458,6 @@ func newWindowsEvents() windowsEvents {
WindowUnMinimise: 1230,
WindowMaximise: 1231,
WindowUnMaximise: 1232,
}
}
@ -467,213 +466,214 @@ func JSEvent(event uint) string {
}
var eventToJS = map[uint]string{
1024: "common:ApplicationOpenedWithFile",
1025: "common:ApplicationStarted",
1026: "common:ThemeChanged",
1027: "common:WindowClosing",
1028: "common:WindowDidMove",
1029: "common:WindowDidResize",
1030: "common:WindowDPIChanged",
1031: "common:WindowFilesDropped",
1032: "common:WindowFocus",
1033: "common:WindowFullscreen",
1034: "common:WindowHide",
1035: "common:WindowLostFocus",
1036: "common:WindowMaximise",
1037: "common:WindowMinimise",
1038: "common:WindowToggleFrameless",
1039: "common:WindowRestore",
1040: "common:WindowRuntimeReady",
1041: "common:WindowShow",
1042: "common:WindowUnFullscreen",
1043: "common:WindowUnMaximise",
1044: "common:WindowUnMinimise",
1045: "common:WindowZoom",
1046: "common:WindowZoomIn",
1047: "common:WindowZoomOut",
1048: "common:WindowZoomReset",
1049: "linux:ApplicationStartup",
1050: "linux:SystemThemeChanged",
1051: "linux:WindowDeleteEvent",
1052: "linux:WindowDidMove",
1053: "linux:WindowDidResize",
1054: "linux:WindowFocusIn",
1055: "linux:WindowFocusOut",
1056: "linux:WindowLoadChanged",
1057: "mac:ApplicationDidBecomeActive",
1058: "mac:ApplicationDidChangeBackingProperties",
1059: "mac:ApplicationDidChangeEffectiveAppearance",
1060: "mac:ApplicationDidChangeIcon",
1061: "mac:ApplicationDidChangeOcclusionState",
1062: "mac:ApplicationDidChangeScreenParameters",
1063: "mac:ApplicationDidChangeStatusBarFrame",
1064: "mac:ApplicationDidChangeStatusBarOrientation",
1065: "mac:ApplicationDidChangeTheme",
1066: "mac:ApplicationDidFinishLaunching",
1067: "mac:ApplicationDidHide",
1068: "mac:ApplicationDidResignActive",
1069: "mac:ApplicationDidUnhide",
1070: "mac:ApplicationDidUpdate",
1071: "mac:ApplicationShouldHandleReopen",
1072: "mac:ApplicationWillBecomeActive",
1073: "mac:ApplicationWillFinishLaunching",
1074: "mac:ApplicationWillHide",
1075: "mac:ApplicationWillResignActive",
1076: "mac:ApplicationWillTerminate",
1077: "mac:ApplicationWillUnhide",
1078: "mac:ApplicationWillUpdate",
1079: "mac:MenuDidAddItem",
1080: "mac:MenuDidBeginTracking",
1081: "mac:MenuDidClose",
1082: "mac:MenuDidDisplayItem",
1083: "mac:MenuDidEndTracking",
1084: "mac:MenuDidHighlightItem",
1085: "mac:MenuDidOpen",
1086: "mac:MenuDidPopUp",
1087: "mac:MenuDidRemoveItem",
1088: "mac:MenuDidSendAction",
1089: "mac:MenuDidSendActionToItem",
1090: "mac:MenuDidUpdate",
1091: "mac:MenuWillAddItem",
1092: "mac:MenuWillBeginTracking",
1093: "mac:MenuWillDisplayItem",
1094: "mac:MenuWillEndTracking",
1095: "mac:MenuWillHighlightItem",
1096: "mac:MenuWillOpen",
1097: "mac:MenuWillPopUp",
1098: "mac:MenuWillRemoveItem",
1099: "mac:MenuWillSendAction",
1100: "mac:MenuWillSendActionToItem",
1101: "mac:MenuWillUpdate",
1102: "mac:WebViewDidCommitNavigation",
1103: "mac:WebViewDidFinishNavigation",
1104: "mac:WebViewDidReceiveServerRedirectForProvisionalNavigation",
1105: "mac:WebViewDidStartProvisionalNavigation",
1106: "mac:WindowDidBecomeKey",
1107: "mac:WindowDidBecomeMain",
1108: "mac:WindowDidBeginSheet",
1109: "mac:WindowDidChangeAlpha",
1110: "mac:WindowDidChangeBackingLocation",
1111: "mac:WindowDidChangeBackingProperties",
1112: "mac:WindowDidChangeCollectionBehavior",
1113: "mac:WindowDidChangeEffectiveAppearance",
1114: "mac:WindowDidChangeOcclusionState",
1115: "mac:WindowDidChangeOrderingMode",
1116: "mac:WindowDidChangeScreen",
1117: "mac:WindowDidChangeScreenParameters",
1118: "mac:WindowDidChangeScreenProfile",
1119: "mac:WindowDidChangeScreenSpace",
1120: "mac:WindowDidChangeScreenSpaceProperties",
1121: "mac:WindowDidChangeSharingType",
1122: "mac:WindowDidChangeSpace",
1123: "mac:WindowDidChangeSpaceOrderingMode",
1124: "mac:WindowDidChangeTitle",
1125: "mac:WindowDidChangeToolbar",
1126: "mac:WindowDidDeminiaturize",
1127: "mac:WindowDidEndSheet",
1128: "mac:WindowDidEnterFullScreen",
1129: "mac:WindowDidEnterVersionBrowser",
1130: "mac:WindowDidExitFullScreen",
1131: "mac:WindowDidExitVersionBrowser",
1132: "mac:WindowDidExpose",
1133: "mac:WindowDidFocus",
1134: "mac:WindowDidMiniaturize",
1135: "mac:WindowDidMove",
1136: "mac:WindowDidOrderOffScreen",
1137: "mac:WindowDidOrderOnScreen",
1138: "mac:WindowDidResignKey",
1139: "mac:WindowDidResignMain",
1140: "mac:WindowDidResize",
1141: "mac:WindowDidUpdate",
1142: "mac:WindowDidUpdateAlpha",
1143: "mac:WindowDidUpdateCollectionBehavior",
1144: "mac:WindowDidUpdateCollectionProperties",
1145: "mac:WindowDidUpdateShadow",
1146: "mac:WindowDidUpdateTitle",
1147: "mac:WindowDidUpdateToolbar",
1148: "mac:WindowDidZoom",
1149: "mac:WindowFileDraggingEntered",
1150: "mac:WindowFileDraggingExited",
1151: "mac:WindowFileDraggingPerformed",
1152: "mac:WindowHide",
1153: "mac:WindowMaximise",
1154: "mac:WindowUnMaximise",
1155: "mac:WindowMinimise",
1156: "mac:WindowUnMinimise",
1157: "mac:WindowShouldClose",
1158: "mac:WindowShow",
1159: "mac:WindowWillBecomeKey",
1160: "mac:WindowWillBecomeMain",
1161: "mac:WindowWillBeginSheet",
1162: "mac:WindowWillChangeOrderingMode",
1163: "mac:WindowWillClose",
1164: "mac:WindowWillDeminiaturize",
1165: "mac:WindowWillEnterFullScreen",
1166: "mac:WindowWillEnterVersionBrowser",
1167: "mac:WindowWillExitFullScreen",
1168: "mac:WindowWillExitVersionBrowser",
1169: "mac:WindowWillFocus",
1170: "mac:WindowWillMiniaturize",
1171: "mac:WindowWillMove",
1172: "mac:WindowWillOrderOffScreen",
1173: "mac:WindowWillOrderOnScreen",
1174: "mac:WindowWillResignMain",
1175: "mac:WindowWillResize",
1176: "mac:WindowWillUnfocus",
1177: "mac:WindowWillUpdate",
1178: "mac:WindowWillUpdateAlpha",
1179: "mac:WindowWillUpdateCollectionBehavior",
1180: "mac:WindowWillUpdateCollectionProperties",
1181: "mac:WindowWillUpdateShadow",
1182: "mac:WindowWillUpdateTitle",
1183: "mac:WindowWillUpdateToolbar",
1184: "mac:WindowWillUpdateVisibility",
1185: "mac:WindowWillUseStandardFrame",
1186: "mac:WindowZoomIn",
1187: "mac:WindowZoomOut",
1188: "mac:WindowZoomReset",
1189: "windows:APMPowerSettingChange",
1190: "windows:APMPowerStatusChange",
1191: "windows:APMResumeAutomatic",
1192: "windows:APMResumeSuspend",
1193: "windows:APMSuspend",
1194: "windows:ApplicationStarted",
1195: "windows:SystemThemeChanged",
1196: "windows:WebViewNavigationCompleted",
1197: "windows:WindowActive",
1198: "windows:WindowBackgroundErase",
1199: "windows:WindowClickActive",
1200: "windows:WindowClosing",
1201: "windows:WindowDidMove",
1202: "windows:WindowDidResize",
1203: "windows:WindowDPIChanged",
1204: "windows:WindowDragDrop",
1205: "windows:WindowDragEnter",
1206: "windows:WindowDragLeave",
1207: "windows:WindowDragOver",
1208: "windows:WindowEndMove",
1209: "windows:WindowEndResize",
1210: "windows:WindowFullscreen",
1211: "windows:WindowHide",
1212: "windows:WindowInactive",
1213: "windows:WindowKeyDown",
1214: "windows:WindowKeyUp",
1215: "windows:WindowKillFocus",
1216: "windows:WindowNonClientHit",
1217: "windows:WindowNonClientMouseDown",
1218: "windows:WindowNonClientMouseLeave",
1219: "windows:WindowNonClientMouseMove",
1220: "windows:WindowNonClientMouseUp",
1221: "windows:WindowPaint",
1222: "windows:WindowRestore",
1223: "windows:WindowSetFocus",
1224: "windows:WindowShow",
1225: "windows:WindowStartMove",
1226: "windows:WindowStartResize",
1227: "windows:WindowUnFullscreen",
1228: "windows:WindowZOrderChanged",
1229: "windows:WindowMinimise",
1230: "windows:WindowUnMinimise",
1231: "windows:WindowMaximise",
1232: "windows:WindowUnMaximise",
1024: "ApplicationOpenedWithFile",
1025: "ApplicationStarted",
1026: "ApplicationLaunchedWithUrl",
1027: "ThemeChanged",
1028: "WindowClosing",
1029: "WindowDidMove",
1030: "WindowDidResize",
1031: "WindowDPIChanged",
1032: "WindowFilesDropped",
1033: "WindowFocus",
1034: "WindowFullscreen",
1035: "WindowHide",
1036: "WindowLostFocus",
1037: "WindowMaximise",
1038: "WindowMinimise",
1039: "WindowRestore",
1040: "WindowRuntimeReady",
1041: "WindowShow",
1042: "WindowUnFullscreen",
1043: "WindowUnMaximise",
1044: "WindowUnMinimise",
1045: "WindowZoom",
1046: "WindowZoomIn",
1047: "WindowZoomOut",
1048: "WindowZoomReset",
1049: "ApplicationStartup",
1050: "SystemThemeChanged",
1051: "WindowDeleteEvent",
1052: "WindowDidMove",
1053: "WindowDidResize",
1054: "WindowFocusIn",
1055: "WindowFocusOut",
1056: "WindowLoadChanged",
1057: "ApplicationDidBecomeActive",
1058: "ApplicationDidChangeBackingProperties",
1059: "ApplicationDidChangeEffectiveAppearance",
1060: "ApplicationDidChangeIcon",
1061: "ApplicationDidChangeOcclusionState",
1062: "ApplicationDidChangeScreenParameters",
1063: "ApplicationDidChangeStatusBarFrame",
1064: "ApplicationDidChangeStatusBarOrientation",
1065: "ApplicationDidChangeTheme",
1066: "ApplicationDidFinishLaunching",
1067: "ApplicationDidHide",
1068: "ApplicationDidResignActive",
1069: "ApplicationDidUnhide",
1070: "ApplicationDidUpdate",
1071: "ApplicationShouldHandleReopen",
1072: "ApplicationWillBecomeActive",
1073: "ApplicationWillFinishLaunching",
1074: "ApplicationWillHide",
1075: "ApplicationWillResignActive",
1076: "ApplicationWillTerminate",
1077: "ApplicationWillUnhide",
1078: "ApplicationWillUpdate",
1079: "MenuDidAddItem",
1080: "MenuDidBeginTracking",
1081: "MenuDidClose",
1082: "MenuDidDisplayItem",
1083: "MenuDidEndTracking",
1084: "MenuDidHighlightItem",
1085: "MenuDidOpen",
1086: "MenuDidPopUp",
1087: "MenuDidRemoveItem",
1088: "MenuDidSendAction",
1089: "MenuDidSendActionToItem",
1090: "MenuDidUpdate",
1091: "MenuWillAddItem",
1092: "MenuWillBeginTracking",
1093: "MenuWillDisplayItem",
1094: "MenuWillEndTracking",
1095: "MenuWillHighlightItem",
1096: "MenuWillOpen",
1097: "MenuWillPopUp",
1098: "MenuWillRemoveItem",
1099: "MenuWillSendAction",
1100: "MenuWillSendActionToItem",
1101: "MenuWillUpdate",
1102: "WebViewDidCommitNavigation",
1103: "WebViewDidFinishNavigation",
1104: "WebViewDidReceiveServerRedirectForProvisionalNavigation",
1105: "WebViewDidStartProvisionalNavigation",
1106: "WindowDidBecomeKey",
1107: "WindowDidBecomeMain",
1108: "WindowDidBeginSheet",
1109: "WindowDidChangeAlpha",
1110: "WindowDidChangeBackingLocation",
1111: "WindowDidChangeBackingProperties",
1112: "WindowDidChangeCollectionBehavior",
1113: "WindowDidChangeEffectiveAppearance",
1114: "WindowDidChangeOcclusionState",
1115: "WindowDidChangeOrderingMode",
1116: "WindowDidChangeScreen",
1117: "WindowDidChangeScreenParameters",
1118: "WindowDidChangeScreenProfile",
1119: "WindowDidChangeScreenSpace",
1120: "WindowDidChangeScreenSpaceProperties",
1121: "WindowDidChangeSharingType",
1122: "WindowDidChangeSpace",
1123: "WindowDidChangeSpaceOrderingMode",
1124: "WindowDidChangeTitle",
1125: "WindowDidChangeToolbar",
1126: "WindowDidDeminiaturize",
1127: "WindowDidEndSheet",
1128: "WindowDidEnterFullScreen",
1129: "WindowDidEnterVersionBrowser",
1130: "WindowDidExitFullScreen",
1131: "WindowDidExitVersionBrowser",
1132: "WindowDidExpose",
1133: "WindowDidFocus",
1134: "WindowDidMiniaturize",
1135: "WindowDidMove",
1136: "WindowDidOrderOffScreen",
1137: "WindowDidOrderOnScreen",
1138: "WindowDidResignKey",
1139: "WindowDidResignMain",
1140: "WindowDidResize",
1141: "WindowDidUpdate",
1142: "WindowDidUpdateAlpha",
1143: "WindowDidUpdateCollectionBehavior",
1144: "WindowDidUpdateCollectionProperties",
1145: "WindowDidUpdateShadow",
1146: "WindowDidUpdateTitle",
1147: "WindowDidUpdateToolbar",
1148: "WindowDidZoom",
1149: "WindowFileDraggingEntered",
1150: "WindowFileDraggingExited",
1151: "WindowFileDraggingPerformed",
1152: "WindowHide",
1153: "WindowMaximise",
1154: "WindowUnMaximise",
1155: "WindowMinimise",
1156: "WindowUnMinimise",
1157: "WindowShouldClose",
1158: "WindowShow",
1159: "WindowWillBecomeKey",
1160: "WindowWillBecomeMain",
1161: "WindowWillBeginSheet",
1162: "WindowWillChangeOrderingMode",
1163: "WindowWillClose",
1164: "WindowWillDeminiaturize",
1165: "WindowWillEnterFullScreen",
1166: "WindowWillEnterVersionBrowser",
1167: "WindowWillExitFullScreen",
1168: "WindowWillExitVersionBrowser",
1169: "WindowWillFocus",
1170: "WindowWillMiniaturize",
1171: "WindowWillMove",
1172: "WindowWillOrderOffScreen",
1173: "WindowWillOrderOnScreen",
1174: "WindowWillResignMain",
1175: "WindowWillResize",
1176: "WindowWillUnfocus",
1177: "WindowWillUpdate",
1178: "WindowWillUpdateAlpha",
1179: "WindowWillUpdateCollectionBehavior",
1180: "WindowWillUpdateCollectionProperties",
1181: "WindowWillUpdateShadow",
1182: "WindowWillUpdateTitle",
1183: "WindowWillUpdateToolbar",
1184: "WindowWillUpdateVisibility",
1185: "WindowWillUseStandardFrame",
1186: "WindowZoomIn",
1187: "WindowZoomOut",
1188: "WindowZoomReset",
1189: "APMPowerSettingChange",
1190: "APMPowerStatusChange",
1191: "APMResumeAutomatic",
1192: "APMResumeSuspend",
1193: "APMSuspend",
1194: "ApplicationStarted",
1195: "SystemThemeChanged",
1196: "WebViewNavigationCompleted",
1197: "WindowActive",
1198: "WindowBackgroundErase",
1199: "WindowClickActive",
1200: "WindowClosing",
1201: "WindowDidMove",
1202: "WindowDidResize",
1203: "WindowDPIChanged",
1204: "WindowDragDrop",
1205: "WindowDragEnter",
1206: "WindowDragLeave",
1207: "WindowDragOver",
1208: "WindowEndMove",
1209: "WindowEndResize",
1210: "WindowFullscreen",
1211: "WindowHide",
1212: "WindowInactive",
1213: "WindowKeyDown",
1214: "WindowKeyUp",
1215: "WindowKillFocus",
1216: "WindowNonClientHit",
1217: "WindowNonClientMouseDown",
1218: "WindowNonClientMouseLeave",
1219: "WindowNonClientMouseMove",
1220: "WindowNonClientMouseUp",
1221: "WindowPaint",
1222: "WindowRestore",
1223: "WindowSetFocus",
1224: "WindowShow",
1225: "WindowStartMove",
1226: "WindowStartResize",
1227: "WindowUnFullscreen",
1228: "WindowZOrderChanged",
1229: "WindowMinimise",
1230: "WindowUnMinimise",
1231: "WindowMaximise",
1232: "WindowUnMaximise",
}

View file

@ -1,5 +1,6 @@
common:ApplicationOpenedWithFile
common:ApplicationStarted
common:ApplicationLaunchedWithUrl
common:ThemeChanged
common:WindowClosing
common:WindowDidMove