Tk Source Code

View Ticket
Login
2025-05-29
08:25 Closed ticket [17b509d7]: wm iconbitmap does not support icon files with png images on Windows plus 6 other changes artifact: f21e3e86 user: fvogel
08:24
Fix [17b509d78f]: wm iconbitmap does not support icon files with png images on Windows. check-in: cc7b2999 user: fvogel tags: trunk, main
08:22
Fix [17b509d78f]: wm iconbitmap does not support icon files with png images on Windows. check-in: 42a174a0 user: fvogel tags: core-9-0-branch
07:59
Fix [17b509d78f]: wm iconbitmap does not support icon files with png images on Windows. check-in: b450c42d user: fvogel tags: core-8-6-branch
2025-05-27
23:18 Ticket [17b509d7] wm iconbitmap does not support icon files with png images on Windows status still Open with 3 other changes artifact: 2ec9c4bd user: timminator
2025-05-26
05:44 Ticket [17b509d7]: 3 changes artifact: 6d0776cb user: fvogel
2025-05-25
22:34 Ticket [17b509d7]: 3 changes artifact: 6042855a user: timminator
16:39 Ticket [17b509d7]: 3 changes artifact: e6727c05 user: fvogel
2025-05-24
17:18 Ticket [17b509d7]: 4 changes artifact: 2a973687 user: oehhar
2025-05-23
19:59 Ticket [17b509d7]: 3 changes artifact: 5a8dade6 user: fvogel
2025-05-22
20:34 Ticket [17b509d7]: 3 changes artifact: 46b2c0d6 user: obermeier
2025-05-17
20:49 Ticket [17b509d7]: 5 changes artifact: 0aede269 user: fvogel
20:43
Fix [17b509d78f]: wm iconbitmap does not support icon files with png images on Windows. check-in: 0176f7c0 user: fvogel tags: bug-17b509d78f
2025-05-09
16:11 Ticket [17b509d7] wm iconbitmap does not support icon files with png images on Windows status still Open with 3 other changes artifact: bdc55d34 user: fvogel
07:54 Ticket [17b509d7]: 5 changes artifact: cf3c8afd user: oehhar
2025-05-08
22:21 Ticket [17b509d7]: 3 changes artifact: fe388124 user: obermeier
18:38 Ticket [17b509d7]: 3 changes artifact: 13449b80 user: obermeier
13:38 Ticket [17b509d7]: 3 changes artifact: 3031a742 user: timminator
12:33 Add attachment Correct bitmap header (WindowsUpdateSeeker2).png to ticket [17b509d7] artifact: 58c250ed user: fvogel
12:33 Add attachment Garbage in bitmap header (app.ico).png to ticket [17b509d7] artifact: 1d065be4 user: fvogel
12:33 Ticket [17b509d7] wm iconbitmap does not honor high-resolution icons in multi-resolution .ico files on Windows status still Open with 3 other changes artifact: 64add0c9 user: fvogel
10:19 Ticket [17b509d7]: 3 changes artifact: 8c70f1db user: timminator
09:00 Add attachment WindowsUpdateSeeker2.ico to ticket [17b509d7] artifact: d603bb47 user: fvogel
09:00 Ticket [17b509d7] wm iconbitmap does not honor high-resolution icons in multi-resolution .ico files on Windows status still Open with 3 other changes artifact: 2cf74ed4 user: fvogel
08:46 Add attachment WindowsUpdateSeeker.ico to ticket [17b509d7] artifact: 5fb75296 user: fvogel
08:46 Ticket [17b509d7] wm iconbitmap does not honor high-resolution icons in multi-resolution .ico files on Windows status still Open with 3 other changes artifact: 3f7c4cf2 user: fvogel
2025-05-07
23:15 Ticket [17b509d7]: 3 changes artifact: 4ee4b68b user: timminator
22:56 Add attachment expected result.png to ticket [17b509d7] artifact: 3e52b811 user: timminator
22:56 Add attachment current result.png to ticket [17b509d7] artifact: eaac568c user: timminator
22:55 Add attachment app.ico to ticket [17b509d7] artifact: 6b21713a user: timminator
19:31 Ticket [17b509d7] wm iconbitmap does not honor high-resolution icons in multi-resolution .ico files on Windows status still Open with 3 other changes artifact: a2a2a357 user: fvogel
15:44 New ticket [17b509d7]. artifact: 4f9cfdb8 user: timminator

Ticket UUID: 17b509d78fc529893d618d76428a3feae99a3223
Title: wm iconbitmap does not support icon files with png images on Windows
Type: Bug Version: 8.6.17.5, 9.1a0.0
Submitter: timminator Created on: 2025-05-07 15:44:09
Subsystem: 40. Bitmap Images Assigned To: fvogel
Priority: 5 Medium Severity: Minor
Status: Closed Last Modified: 2025-05-29 08:25:33
Resolution: Fixed Closed By: fvogel
    Closed on: 2025-05-29 08:25:33
Description:

When setting a window icon using wm iconbitmap with a multi-resolution .ico file, Tk only appears to use the first or a low-resolution entry from the icon file. This results in a blurry or pixelated icon in the Windows taskbar and for example in the top left corner of the window, even though the .ico file contains a 256×256 high-resolution version. When using an .ico file only containing a high-resolution like 256x256 the icon is appearing correctly as expected.

Minimal reproducible example:

wm title . "APP title"
wm iconname . APP
wm iconbitmap . app.ico

Expected behavior:

Windows should select the appropriate resolution from the .ico file (e.g., 256×256) based on the display context and DPI.

Actual behavior:

Tk displays a low-resolution icon, leading to a blurry appearance in system UI.

Tested on:

  • Windows 11
  • Tcl/Tk 8.6.17.5 and 9.1a0.0 frome here
  • .ico file contains multiple resolutions (e.g., 16×16 to 256×256)
User Comments: fvogel added on 2025-05-29 08:25:33:
Merged. Thanks to all participants!

timminator added on 2025-05-27 23:18:20:

Ah, I see. Sorry for that silly question. Thanks again for resolving my issue!


fvogel added on 2025-05-26 05:44:35:

The Github repository is a mirror of the main fossil repository. The fix is in branch bug-17b509d78f of the fossil repository, and in branch bug-17b509d78f of the Github mirror. These branches are off core-8-6-branch in each repo. If you took something else, in particular off trunk, then yes you must have a very different tkWinWm.c file.


timminator added on 2025-05-25 22:34:12:

I now had the time to also test your patch. Works! The icon is no longer blurry, awesome!

I just have one more question: I struggled quite a bit to apply the patch you linked after cloning the repo from the github mirror. The file inside the repo differs quite a lot from the one seen in your patch. In the end I manually applied the patch by hand. But then it worked. :-)

Did I miss something?


fvogel added on 2025-05-25 16:39:13:

See [eeaf3858da].

If nobody objects I plan to merge in a few days from now.


oehhar added on 2025-05-24 17:18:38:

Clean-up is always good !

  • Tk 9.1: Win 10
  • Tk 9.0: Win 8

I would prefer, if you do the clean-up from 9.0 and the other method on 8.6.

Thanks for all, Harald


fvogel added on 2025-05-23 19:59:18:
Right.

We could simply remove that entire snippet from the codebase, on the grounds that Windows NT is very very obsolete and CreateIconFromResourceEx should not fail.

Or less intrusive: remove the check on the bit count only, so that CreateIconFromResource can keep beking tried in case CreateIconFromResourceEx failed just above. Who could still be using 16-bits resources in icons nowadays?

I would just go for the second possibility. Opinions?

obermeier added on 2025-05-22 20:34:01:

Patch looks OK. Works for me using different ICO files.

There is still one appearance of using bmiHeader in function MakeIconOrCursorFromResource:

/*
 * It failed, odds are good we're on NT so try the non-Ex way.
 */

if (hIcon == NULL) {
    /*
     * We would break on NT if we try with a 16bpp image.
     */

    if (lpIcon->lpbi->bmiHeader.biBitCount != 16) {
        hIcon = CreateIconFromResource(lpIcon->lpBits, lpIcon->dwNumBytes,
 	    isIcon, 0x00030000);
    }
}

Do not know how to handle that case.


fvogel added on 2025-05-17 20:49:00:

I have proposed a patch [0176f7c06a], implementing this idea that was found on Stackoverflow by Paul Obermeier. See branch bug-17b509d78f.

Could the OP please test?

Could someone (Paul perhaps?) review the patch please? (With commented out debug printfs intentionally left).

Thanks!


fvogel added on 2025-05-09 16:11:27:

OK, so the situation now is clear: PNG images in ico files are not (yet) supported by Tk. The images get interpreted as BMP, which results in totally wrong sizes, which in turn lead to GetIcon() to select the first image of the ico file whatever it is and without taking size into account (reason why it looks blurry in the app.ico example case). The image nevertheless shows up because the Windows OS loads the ico file and the OS known about both BMP and PNG (since Vista) images in ico files.

So the workarounds for the OP are either of:

1. Use BMP images in ico files instead of PNG images
2. Revert the order of the PNG images in the ico file such that the largest image comes first (it will get selected, which results in a not blurred image)

Now, about fixing this and making Tk aware of PNG images in ico files: The .ico format has no embedded switch to let a parser know the format of the images it provides. Paul has provided some hints below about how we could circumvent the problem.


oehhar added on 2025-05-09 07:54:39:

Yes, png was added later on the Windows platform. It features a full alpha channel, instead of only 0/100% like bmp, what is a real change with hidden consequences.

This is not taken into account for TCL.

I allowed me to change the title of the ticket, as this is a valuable and quite old request. We may find this issue in different forms in other tickets.

Paul, would it possible that you have an implementation proposal? I have seen that you have done a similar change in the Img package...

Thanks for all, Harald


obermeier added on 2025-05-08 22:21:10:

Maybe a better solution is to get the image information from the HICON handle, see ex. https://stackoverflow.com/questions/1913468/how-to-determine-the-size-of-an-icon-from-a-hicon


obermeier added on 2025-05-08 18:38:38:
The app.ico contains images in PNG format. 
It generates an error message when reading with the ICO parser of Img, because the ICO parser of Img does not support PNG.

Tk uses the Windows function CreateIconFromResourceEx (in MakeIconOrCursorFromResource), so it can read both BMP and PNG images.
But before reading the image, it tries to retrieve image information in function AdjustIconImagePointers.
The problem is in that function, because it is assumed to read a bitmap header (ex. lpImage->lpbi->bmiHeader.biWidth), while in fact there is a PNG header.
That's why it gets garbage regarding image size.
Do not know about a correct solution right now.
One possibility might be to check for the existence of a PNG header in AdjustIconImagePointers and retrieve the needed image information from that header.

timminator added on 2025-05-08 13:38:12:

"Your app.ico encodes 6 images, each of them in BMP format. The BMP header contains garbage."

This sentence of yours caught my eye. The website allows you to select the internal file format for the ico. You can select PNG or BMP. I selected PNG, so my .ico file that causes this issue stores all 6 images as PNG and not as BMP.

I've used the website again but this time I selected BMP as the internal file format. With this .ico selected the icon in the taskbar was also not blurry.

The icon from the other website where it worked aswell contained 1 PNG and 5 BMP images, so that it explains maybe because it worked there aswell. I've used a simple python script to determine the internal image type. Unfortunately I could not find another tool that allows me to select this internal file format - I will keep looking, to check if the issue can be replicated with these particular settings.

So maybe there is an issue with parsing .ico files that only contain PNG images in Tk? Of course the .ico file can still be incorrect, but I wanted to update you with my findings.


fvogel added on 2025-05-08 12:33:24:

What you describe, unless I miss something, points to the creation tool to be faulty, isn't it? You tell the following two things that seem to prove it:

* redketchup.io/icon-converter creates a blurry icon
* using another online tool and this time the icon was not blurry

Yes the icon file opens with GIMP. This does not mean it is fully correct, it only means the GIMP may be tolerant to the ico format being imperfectly filled in.

The ico files format is simple. It is composed of a header and an image directory. The image directory has entries (ICONDIRENTRY structures), and each such entry encodes an image. Your app.ico encodes 6 images, each of them in BMP format. The BMP header contains garbage.

I'm attaching a debugging session snapshot with your app.ico, and another one with WindowsUpdateSeeker2.ico, see the difference?


timminator added on 2025-05-08 10:19:23:

Very interesting. I indeed did not think that my .ico file is special. I used an online tool to create it, you can find it here. I've tested it again by using another online tool and this time the icon was not blurry as you reported aswell. The order was the other way around, but that seems to be not the issue as seen by your two attachments.

I've created another icon with this website by using the largest png out of your windowsupdateseeker.ico and it was again blurry now...

I cannot see anything that is wrong with the .ico file from this website. I can open it perfectly fine with GIMP - all resolution and layers show up. I also tried under Linux the icotool - it can read all dimensions of the resolutions (because you reported the returned values by Tk were garbage for this).

icotool -l app.ico
--icon --index=1 --width=16 --height=16 --bit-depth=32 --palette-size=0
--icon --index=2 --width=32 --height=32 --bit-depth=32 --palette-size=0
--icon --index=3 --width=48 --height=48 --bit-depth=32 --palette-size=0
--icon --index=4 --width=64 --height=64 --bit-depth=32 --palette-size=0
--icon --index=5 --width=128 --height=128 --bit-depth=32 --palette-size=0
--icon --index=6 --width=256 --height=256 --bit-depth=32 --palette-size=0

So I don't think my .ico file is broken... Maybe it's a compression setting. I noticed the .ico file created by another website (convertico) was three times larger? But that's just guessing from my side. I hope knowing the source of my .ico file can help you a bit.


fvogel added on 2025-05-08 09:00:07:
One more note: The WindowsUpdateSeeker.ico I have attached has images in reverse size order (larger first) compared to your app.ico. I'm attaching WindowsUpdateSeeker2.ico which is just WindowsUpdateSeeker.ico with the image order reversed (smallest first) as in your app.ico, and this WindowsUpdateSeeker2.ico works OK for me. So the problem is not due to the order of the images within the ico file.

fvogel added on 2025-05-08 08:46:15:

Thanks for your input. Using your app.ico file I can reproduce.

The code here returns the first image because the values of lpIR->IconImages[i].Height|Width a few lines above look like garbage for all 6 images of the icon file.

Checking then how the ico file is read in ReadIconOrCursorFromFile(), I see that the image icon size is set here. And there is garbage in lpImage->lpbi->bmiHeader.biWidth|biHeight.

I'm starting to suspect your app.ico file to be a bit incorrect. Where does this ico file come from? Are you 100 % sure its format it 100% correct? Can you perhaps try with another multi-resolution ico file coming from another icon designer or .ico file source?

I have tried other random multiple resolution icons I have found on my Win11 disk and I'm not seeing the issue. I'm attaching one of those random icons form your test and review of differences with respect to yours (see WindowsUpdateSeeker.ico).


timminator added on 2025-05-07 23:15:51:
Thank you for taking a look at my issue. I attached an app.ico file and also added two pictures - what im currently seeing and what I would expect. On my Laptop where the DPI is set to 1.5 it is especially noticable.
The low resolution ico can also be seen in the top left corner of the window but that is not so easy to see in a snapshot.

The code snippet you linked seems to reflect exactly what I am seeing. But I am not sure what the best way is to fix this. Tk could let Windows load the .ico itself. Then it could handle DPI-aware selection natively. Or maybe Tk could replicate the resolution-selection logic based on current DPI? Both seem not that easy... But I'm just brainstorming.
I hope you can come up with a good solution. I would appreciate it a lot. :-)

fvogel added on 2025-05-07 19:31:01:

As a first very quick analysis I believe the issue is here.

Would you be so kind as to provide (attach) an example app.ico file containing multiple resolutions, that we could use to reproduce the problem (and later check that the fix is correct)?

In addition, a snapshot of the current result and of the expected result of [wm iconbitmap] would be great.


Attachments: