tauri icon indicating copy to clipboard operation
tauri copied to clipboard

[bug] [Windows] Window icon appears blurry - question about ICO multi-size handling

Open exusiaiwei opened this issue 2 months ago • 1 comments

Describe the bug

On Windows, I noticed that the runtime window icon (displayed in taskbar and titlebar) appears blurry/pixelated, even when using a properly formatted ICO file containing multiple size entries (16x16, 24x24, 32x32, 48x48, 64x64, 256x256).

What I found in the code:

Looking at crates/tauri-codegen/src/image.rs, the new_ico() function (lines 49-72) seems to only read the first entry from the ICO file:

pub fn new_ico(root: &TokenStream, icon: &Path) -> EmbeddedAssetsResult<Self> {
    let buf = Self::open(icon);

    let icon_dir = ico::IconDir::read(Cursor::new(&buf))
        .unwrap_or_else(|e| panic!("failed to parse icon {}: {}", icon.display(), e));

    let entry = &icon_dir.entries()[0];  // Only takes the first entry
    let rgba = entry
        .decode()
        .unwrap_or_else(|e| panic!("failed to decode icon {}: {}", icon.display(), e))
        .rgba_data()
        .to_vec();

    Cached::try_from(rgba).map(|cache| Self {
        cache,
        root: root.clone(),
        format: IconFormat::Image {
            width: entry.width(),
            height: entry.height(),
        },
    })
}

It appears that only entries()[0] is read from the ICO file, and the other size entries are not used. This single RGBA image seems to be used for all icon contexts at runtime.

My understanding of Windows icon behavior:

As far as I know, Windows uses different icon sizes for different contexts (e.g., small icons for titlebar, larger icons for taskbar). ICO files support multiple embedded sizes for this reason. I'm wondering if this might be related to the blurry icon issue I'm seeing.

Is this intentional? I'd appreciate any clarification on whether this is by design (perhaps for memory/performance reasons) or if it's something that could be improved.

Reproduction

  1. Create an ICO file with multiple sizes (16, 24, 32, 48, 64, 256) using a tool like ImageMagick:

    magick icon.png -define icon:auto-resize=256,64,48,32,24,16 icon.ico
    
  2. Use this ICO as window icon in a Tauri app

  3. Build and run on Windows

  4. Observe: The titlebar icon appears blurry/pixelated

  5. Compare: Right-click the EXE in Explorer - the file icon is sharp (Windows reads the ICO resource correctly)

Workaround discovered:

Creating a Windows shortcut (.lnk) pointing to the EXE makes the taskbar icon clear, because Windows shortcuts read the icon from the EXE's embedded resource (which preserves all ICO sizes). However, the titlebar icon remains blurry as it uses the runtime RGBA data.

Expected behavior

I expected the window icon to appear sharp/crisp, similar to how the file icon appears in Windows Explorer (which reads the ICO resource directly and displays the appropriate size).

Full tauri info output

[✔] Environment
    - OS: Windows 10.0.26200 x86_64 (X64)
    ✔ WebView2: 142.0.3595.94
    ✔ MSVC: Visual Studio Build Tools 2022
    ✔ rustc: 1.91.1 (ed61e7d7e 2025-11-07)
    ✔ cargo: 1.91.1 (ea2d97820 2025-10-10)
    ✔ rustup: 1.28.2 (e4f3ad6f8 2025-04-28)
    ✔ Rust toolchain: 1.91.1-x86_64-pc-windows-msvc
    - node: 24.11.1
    - pnpm: 10.20.0
    - npm: 11.6.2

[-] Packages
    - @tauri-apps/cli: ^2.9.0
    - @tauri-apps/api: ^2.9.0
    (via Pake CLI v3.5.3)

[-] Plugins

[-] App

Stack trace


Additional context

No response

exusiaiwei avatar Dec 02 '25 18:12 exusiaiwei

I think this is just how our Image type works internally, it uses raw RGBA pixels

Legend-Master avatar Dec 03 '25 11:12 Legend-Master