Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 6 additions & 2 deletions docs/src/content/docs/concepts/build-system.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -227,12 +227,16 @@ wails3 task --list

### Icons and packaging

Generate platform icons (`build/icons.icns`, `build/icon.ico`, etc.) from a source PNG:
Generate Windows, macOS, and Linux hicolor icons from the canonical source PNG:

```bash
wails3 generate icons -input appicon.png
wails3 generate icons \
-input build/appicon.png \
-linuxoutputdir build/linux/icons
```

Linux PNGs are reproducible generated assets. Fixed-size files are installed into matching hicolor directories by the default DEB, RPM, and Arch package configuration.

Build platform-specific installers/packages:

```bash
Expand Down
13 changes: 13 additions & 0 deletions docs/src/content/docs/guides/build/linux.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,19 @@ homepage: https://example.com
license: MIT
```

### Desktop Icons

`build/appicon.png` is the canonical icon source. The shared `generate:icons` task creates deterministic PNGs in `build/linux/icons/` at 16, 32, 48, 64, 128, 256, and 512 pixels. DEB, RPM, and Arch packages install each generated image into the matching `/usr/share/icons/hicolor/<size>x<size>/apps/` directory.

The generated nFPM configuration expects that default size set. If you customize `-linuxsizes`, update the icon entries in `build/linux/nfpm/nfpm.yaml` to match.

Projects created before Linux icon generation keep their compatible legacy package mapping when `update build-assets` runs, because Wails does not overwrite a project's Taskfile. To opt in, update the common `generate:icons` task from a current project so that it passes `-linuxoutputdir linux/icons`, declares every Linux PNG under `generates`, and then run:

```bash
wails3 task common:generate:icons
wails3 task common:update:build-assets
```

### AppImage

AppImage configuration is in `build/linux/appimage/`. The app icon comes from `build/appicon.png`.
Expand Down
4 changes: 2 additions & 2 deletions docs/src/content/docs/guides/build/macos.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ The app icon is generated from assets in the `build/` directory. Use the `genera
wails3 task common:generate:icons
```

This uses `build/appicon.png` to produce `darwin/icons.icns` and `windows/icon.ico`. On macOS you can also provide `build/appicon.icon` (Icon Composer format): the task passes `-iconcomposerinput appicon.icon -macassetdir darwin`, which produces `Assets.car` and `darwin/icons.icns` from the `.icon` file (skipped on non-macOS platforms). When `Assets.car` is present, run the `update:build-assets` task so that `Info.plist` and `CFBundleIconName` are updated accordingly:
This uses `build/appicon.png` to produce `darwin/icons.icns`, `windows/icon.ico`, and the Linux hicolor PNG set. On macOS you can also provide `build/appicon.icon` (Icon Composer format): the task passes `-iconcomposerinput appicon.icon -macassetdir darwin`, which produces `Assets.car` and `darwin/icons.icns` from the `.icon` file (skipped on non-macOS platforms). When `Assets.car` is present, run the `update:build-assets` task so that `Info.plist` and `CFBundleIconName` are updated accordingly:

```bash
wails3 task common:update:build-assets
Expand All @@ -56,7 +56,7 @@ To run the icon command manually from the `build/` directory:

```bash
cd build
wails3 generate icons -input appicon.png -macfilename darwin/icons.icns -windowsfilename windows/icon.ico -iconcomposerinput appicon.icon -macassetdir darwin
wails3 generate icons -input appicon.png -macfilename darwin/icons.icns -windowsfilename windows/icon.ico -iconcomposerinput appicon.icon -macassetdir darwin -linuxoutputdir linux/icons -linuxsizes 16,32,48,64,128,256,512
```

## Code Signing
Expand Down
37 changes: 28 additions & 9 deletions docs/src/content/docs/guides/cli.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -272,15 +272,34 @@ wails3 generate icons [flags]
```

#### Flags
| Flag | Description | Default |
|------------------------|------------------------------------------------------|-----------------------|
| `-input` | Input PNG file | Required |
| `-windowsfilename` | Windows output filename | |
| `-macfilename` | macOS output filename | |
| `-sizes` | Icon sizes (comma-separated) | `256,128,64,48,32,16` |
| `-example` | Generate example icon | `false` |
| `-iconcomposerinput` | Input Icon Composer file (`.icon`) | |
| `-macassetdir` | Output directory for Mac assets (Assets.car + icns) | |
| Flag | Description | Default |
|------------------------|-------------------------------------------------------|-------------------------------|
| `-input` | Input PNG file | `build/appicon.png` |
| `-windowsfilename` | Windows output filename | `build/windows/icon.ico` |
| `-macfilename` | macOS output filename | `build/darwin/icon.icns` |
| `-sizes` | Windows ICO sizes (comma-separated) | `256,128,64,48,32,16` |
| `-linuxoutputdir` | Output directory for Linux hicolor PNGs | |
| `-linuxsizes` | Linux PNG sizes (comma-separated) | `16,32,48,64,128,256,512` |
| `-example` | Generate example icon | `false` |
| `-iconcomposerinput` | Input Icon Composer file (`.icon`) | |
| `-macassetdir` | Output directory for Mac assets (`Assets.car` + icns) | |

#### Linux hicolor icons

Generate a complete Linux desktop icon set without ImageMagick or another external image tool:

```bash
wails3 generate icons \
-input build/appicon.png \
-linuxoutputdir build/linux/icons \
-linuxsizes 16,32,48,64,128,256,512
```

The command writes files such as `48x48.png` and `128x128.png` to the output directory. Each PNG is an exact square; non-square source images retain their aspect ratio and receive transparent centered padding. Generation is byte-deterministic on every supported build host.

Treat `build/appicon.png` as the canonical source and the Linux output directory as a disposable generated set. The default `generate:icons` task declares every size as an output, so deleting any one of them regenerates the complete set.

The default DEB, RPM, and Arch package configuration references all seven default sizes. If you customize `-linuxsizes` in the generated task, update `build/linux/nfpm/nfpm.yaml` to install the same set.

#### Icon Composer (macOS)

Expand Down
5 changes: 4 additions & 1 deletion docs/src/content/docs/guides/dev/project-structure.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ This page is a simple reference to the files created when you initiate a new pro
│ ├── darwin/ # macOS build config
│ ├── windows/ # Windows build config
│ ├── linux/ # Linux build config
│ │ └── icons/ # Generated hicolor PNG icon set
│ ├── android/ # Android build config
│ ├── ios/ # iOS build config
│ └── docker/ # Containerized build environment
Expand All @@ -37,6 +38,8 @@ This page is a simple reference to the files created when you initiate a new pro
└── .task/ # Task runner cache
```

Generated directories such as `frontend/dist`, `frontend/bindings`, and `build/linux/icons` appear after their corresponding build or generation task first runs.

:::note[Frontend project files]
If you choose to use a different starter template, contents of `frontend/src` will differ depending on your chosen framework
:::
:::
2 changes: 1 addition & 1 deletion docs/src/content/docs/reference/cli.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ wails3 <command> --help
| Subcommand | Description |
|------------|-------------|
| `generate bindings` | Generate Go-to-frontend bindings. Flags: `-d` (output dir), `-models`, `-index`, `-ts`, `-i` (interfaces), `-b` (bundle), `-names` (emit `Call.ByName`), `-noevents`, `-noindex`, `-dry`, `-silent`, `-v`, `-clean` (default `true`), `-f`, `-obfuscated` (generate `wails_obfuscated.gen.go` with stable binding IDs for Garble builds; see [Obfuscated Builds](/guides/build/obfuscation)), `-obfuscated-output` (directory for the generated file; defaults to the main package directory). Accepts package patterns (e.g. `./...`); falls back to the current directory if none given. |
| `generate icons` | Convert a source PNG into the platform icon formats. Flags: `-input`, `-windowsfilename`, `-macfilename`, `-iconcomposerinput`, `-macassetdir`. |
| `generate icons` | Convert a source PNG into Windows, macOS, and Linux icon formats. Flags: `-input`, `-windowsfilename`, `-macfilename`, `-sizes` (ICO sizes), `-linuxoutputdir`, `-linuxsizes`, `-iconcomposerinput`, `-macassetdir`. |
| `generate build-assets` | Generate the `build/` directory contents (Taskfile snippets, NSIS files, `Info.plist`, `.desktop` template, etc.) from `build/config.yml`. |
| `generate runtime` | Regenerate the pre-built `/wails/runtime.js` shipped to the webview. |
| `generate syso` | Generate the Windows `.syso` resource file (icon + manifest + version info). |
Expand Down
37 changes: 22 additions & 15 deletions v3/cmd/wails3/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,24 +17,31 @@ It can be used to generate many things including:
- resource files for Windows applications
- Info.plist files for macOS deployments

#### icon

The `icon` command generates icons for your project.

| Flag | Type | Description | Default |
|--------------------|--------|------------------------------------------------------|----------------------|
| `-example` | bool | Generates example icon file (appicon.png) | |
| `-input` | string | The input image file | |
| `-sizes` | string | The sizes to generate in .ico file (comma separated) | "256,128,64,48,32,16" |
| `-windowsFilename` | string | The output filename for the Windows icon | icon.ico |
| `-macFilename` | string | The output filename for the Mac icon bundle | icons.icns |
#### icons

The `icons` command generates icons for your project.

| Flag | Type | Description | Default |
|----------------------|--------|----------------------------------------------------------|-------------------------------|
| `-example` | bool | Generate example icon file (`appicon.png`) | |
| `-input` | string | Input PNG file | `build/appicon.png` |
| `-sizes` | string | Windows ICO sizes (comma-separated) | `256,128,64,48,32,16` |
| `-windowsfilename` | string | Windows icon output | `build/windows/icon.ico` |
| `-macfilename` | string | macOS icon bundle output | `build/darwin/icon.icns` |
| `-iconcomposerinput` | string | Input Icon Composer file (`.icon`) | |
| `-macassetdir` | string | Output directory for macOS `Assets.car` and `icons.icns` | |
| `-linuxoutputdir` | string | Output directory for Linux hicolor PNGs | |
| `-linuxsizes` | string | Linux PNG sizes (comma-separated) | `16,32,48,64,128,256,512` |

```bash
wails3 generate icon -input myicon.png -sizes "32,64,128" -windowsFilename myicon.ico -macFilename myicon.icns
wails3 generate icons \
-input build/appicon.png \
-windowsfilename build/windows/icon.ico \
-macfilename build/darwin/icons.icns \
-linuxoutputdir build/linux/icons
```

This will generate icons for mac and windows and save them in the current directory as `myicon.ico`
and `myicons.icns`.
Linux images are resized without stretching: non-square input is centered on a transparent square canvas. The PNG output is deterministic and can be regenerated from `build/appicon.png` on any supported build host.

#### syso

Expand Down Expand Up @@ -80,4 +87,4 @@ This will generate all the default assets and resources in the current directory
wails3 generate bindings
```

Generates bindings and models for your bound Go methods and structs.
Generates bindings and models for your bound Go methods and structs.
25 changes: 25 additions & 0 deletions v3/internal/commands/build-assets.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,9 @@ type BuildAssetsOptions struct {
type TemplateEnrichment struct {
Cls string `description:"A helper for using close template tags safely }}" default:"}}"`
Opn string `description:"A helper for using open template tags safely {{" default:"{{"`
// LinuxHicolorIcons indicates that the project's preserved common Taskfile
// generates the complete Linux hicolor icon set used by the nfpm template.
LinuxHicolorIcons bool `yaml:"-"`
// BackgroundModes feeds the iOS Info.plist template's UIBackgroundModes block.
// It's populated by the iOS Xcode generator from ios.backgroundModes in
// build/config.yml; the generic build-assets path leaves it empty (like
Expand Down Expand Up @@ -113,6 +116,7 @@ func GenerateBuildAssets(options *BuildAssetsOptions) error {
var config BuildConfig
config.Cls = "}}"
config.Opn = "{{"
config.LinuxHicolorIcons = true

if options.ProductComments == "" {
options.ProductComments = fmt.Sprintf("(c) %d %s", time.Now().Year(), options.ProductCompany)
Expand Down Expand Up @@ -278,6 +282,7 @@ func UpdateBuildAssets(options *UpdateBuildAssetsOptions) error {

config.Cls = "}}"
config.Opn = "{{"
config.LinuxHicolorIcons = taskfileSupportsLinuxHicolorIcons(options.Dir)

// If directory doesn't exist, create it
if _, err := os.Stat(options.Dir); os.IsNotExist(err) {
Expand Down Expand Up @@ -332,6 +337,26 @@ func UpdateBuildAssets(options *UpdateBuildAssetsOptions) error {
return nil
}

func taskfileSupportsLinuxHicolorIcons(buildDir string) bool {
data, err := os.ReadFile(filepath.Join(buildDir, "Taskfile.yml"))
if err != nil {
return false
}
content := string(data)
if !strings.Contains(content, "-linuxoutputdir linux/icons") {
return false
}
if strings.Contains(content, "-linuxsizes") && !strings.Contains(content, "-linuxsizes "+defaultLinuxIconSizes) {
return false
}
for _, size := range strings.Split(defaultLinuxIconSizes, ",") {
if !strings.Contains(content, "linux/icons/"+size+"x"+size+".png") {
return false
}
}
return true
}

func normaliseName(name string) string {
return strings.ToLower(strings.ReplaceAll(name, " ", "-"))
}
Expand Down
11 changes: 9 additions & 2 deletions v3/internal/commands/build_assets/Taskfile.tmpl.yml
Original file line number Diff line number Diff line change
Expand Up @@ -191,7 +191,7 @@ tasks:
- wails3 generate bindings -f '{{.Opn}}.BUILD_FLAGS{{.Cls}}' -clean=true{{if not (and .UseInterfaces .Typescript)}} -time-type=Date{{end}}{{.Opn}}if eq .OBFUSCATED "true"{{.Cls}} -obfuscated{{.Opn}}end{{.Cls}}{{if .Typescript}} -ts{{end}}{{if and .UseInterfaces .Typescript}} -i{{end}}

generate:icons:
summary: Generates Windows `.ico` and Mac `.icns` from an image; on macOS, `-iconcomposerinput appicon.icon -macassetdir darwin` also produces `Assets.car` from a `.icon` file (skipped on other platforms).
summary: Generates Windows `.ico`, Mac `.icns`, and Linux hicolor PNGs from an image; on macOS, `-iconcomposerinput appicon.icon -macassetdir darwin` also produces `Assets.car` from a `.icon` file (skipped on other platforms).
run: once
dir: build
sources:
Expand All @@ -200,8 +200,15 @@ tasks:
generates:
- "darwin/icons.icns"
- "windows/icon.ico"
- "linux/icons/16x16.png"
- "linux/icons/32x32.png"
- "linux/icons/48x48.png"
- "linux/icons/64x64.png"
- "linux/icons/128x128.png"
- "linux/icons/256x256.png"
- "linux/icons/512x512.png"
cmds:
- wails3 generate icons -input appicon.png -macfilename darwin/icons.icns -windowsfilename windows/icon.ico -iconcomposerinput appicon.icon -macassetdir darwin
- wails3 generate icons -input appicon.png -macfilename darwin/icons.icns -windowsfilename windows/icon.ico -iconcomposerinput appicon.icon -macassetdir darwin -linuxoutputdir linux/icons -linuxsizes 16,32,48,64,128,256,512

dev:frontend:
summary: Runs the frontend in development mode
Expand Down
23 changes: 21 additions & 2 deletions v3/internal/commands/icons.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@ type IconsOptions struct {
MacFilename string `description:"The output filename for the Mac icon bundle" default:"build/darwin/icon.icns"`
IconComposerInput string `description:"The input Icon Composer file (.icon)"`
MacAssetDir string `description:"The output directory for the Mac assets (Assets.car and icons.icns)"`
LinuxOutputDir string `description:"The output directory for Linux hicolor PNG icons"`
LinuxSizes string `description:"The sizes to generate as Linux PNG icons (comma separated)" default:"16,32,48,64,128,256,512"`
}

func GenerateIcons(options *IconsOptions) error {
Expand All @@ -50,9 +52,12 @@ func GenerateIcons(options *IconsOptions) error {
if options.Input == "" && options.IconComposerInput == "" {
return fmt.Errorf("either input or icon composer input is required")
}
if options.LinuxOutputDir != "" && options.Input == "" {
return fmt.Errorf("input is required for Linux icon generation")
}

if options.Input != "" && options.WindowsFilename == "" && options.MacFilename == "" {
return fmt.Errorf("either windows filename or mac filename is required")
if options.Input != "" && options.WindowsFilename == "" && options.MacFilename == "" && options.LinuxOutputDir == "" {
return fmt.Errorf("at least one Windows, Mac, or Linux output is required")
}

if options.IconComposerInput != "" && options.MacAssetDir == "" {
Expand All @@ -69,6 +74,14 @@ func GenerateIcons(options *IconsOptions) error {
}
}

var linuxSizes []int
if options.LinuxOutputDir != "" {
linuxSizes, err = parseLinuxIconSizes(options.LinuxSizes)
if err != nil {
return err
}
}

// Generate Icons from Icon Composer input
macIconsGenerated := false
if options.IconComposerInput != "" {
Expand Down Expand Up @@ -112,6 +125,12 @@ func GenerateIcons(options *IconsOptions) error {
return err
}
}

if options.LinuxOutputDir != "" {
if err := generateLinuxIcons(iconData, linuxSizes, options.LinuxOutputDir); err != nil {
return err
}
}
}

return nil
Expand Down
Loading
Loading