RFR: 8282526: Default icon is not painted properly [v6]

Alexey Ivanov aivanov at openjdk.org
Fri Jul 8 16:03:45 UTC 2022


On Fri, 8 Jul 2022 15:02:08 GMT, Alexey Ivanov <aivanov at openjdk.org> wrote:

>>> > That was the whole purpose of the initial 8182043 issue, to provide a HiDPI(or various DPI) icons for the user. If the user asks for the 16x16 we will provide them the MRI where the base image is 16x16, but that MRI could also provide large images by request. If that 16x16 image renders on scale=1.25 then the MRI should generate the image which looks good on that screen.
>> 
>>> Before JDK-8182043, the icon was either 16×16 or 32×32 and didn't change if the scale was changed. Now the icon gets updated after the scale changes, it's noticeable on folder icons in user's home because a set of icons is fetched.
>> 
>> Before the JDK-8182043 we also used the MRI so it should be changed if the scale was changed from low to hidpi. It adds more variants which could be used by some other DPI, I think one important new variant is the 64x64 because it used as a large icon on HiDPI monitor. But if the dpi is 125% or 150% it will not work even if the user will [try to request](https://github.com/openjdk/jdk/pull/2875#discussion_r641078169) such image.
>> 
>>> There are still two different ways where icons are fetched from the Windows shell: `Java_sun_awt_shell_Win32ShellFolder2_getIcon` and `Java_sun_awt_shell_Win32ShellFolder2_extractIcon`. As @azuev-java notes, at times the returned size doesn't match the requested size.
>> 
>> We had similar "issue" before the latest version of this change, we still have an issue related to the size value [initialization](https://github.com/openjdk/jdk/pull/7805#discussion_r887384908). So it might be other our bug caused that the size is ignored.
>> 
>>> This current proposal handles the situation where the returned icon doesn't have the requested size.
>> 
>> Take a look to the description of 8182043, the user wanted to get some large Icon, now imaging he would like to get a 79x79 icon for some file, did we provide a way to do that? I assume we even do not try to request that size from the operation system so it actually cannot ignore our request? 
>> 
>>> So, there are drawbacks and limitations in the current implementation, and there are opportunities to improve it, some of them are listed in [my comment above](https://github.com/openjdk/jdk/pull/7805#discussion_r893306463). I shall submit them so that we don't forget about them, if no one else has already done it.
>> +1
>> 
>>> Why not? To request the icon of a larger size, the object which stores the icon should keep the reference to the file or folder, folders could have custom icons, and Documents, Downloads, Pictures are the examples of such folders. This must be done on COM thread because the icons are requested from the Windows shell.
>> 
>> Because selection of the proper icon/image will be done during rendering of the component, and waiting of the results on the com thread may slowdown it. Instead we can use default image which we initially loaded, and later use the better one when it will be loaded on the com thread.
>> 
>>> I agree that we should not get all possible resolutions of an icon when only one is needed. But it's out of scope of this particular issue.
>> 
>> Yes, please take a look to these change.
>
>> Before the JDK-8182043 we also used the MRI so it should be changed if the scale was changed from low to hidpi. It adds more variants which could be used by some other DPI, I think one important new variant is the 64x64 because it used as a large icon on HiDPI monitor.
> 
> MRI was used only to accommodate for the fact that shell may return icon of higher resolution according the system settings.
> 
> https://github.com/openjdk/jdk/blob/978bed6c7ff64148474df3dd1ab3b3707005b8fa/src/java.desktop/windows/classes/sun/awt/shell/Win32ShellFolder2.java#L1032-L1034
> 
> If the main monitor scale was set to 200% and 16×16 icon was requested, the system returned 32×32.
> 
> In no way it handled different scale settings.
> 
>>  But if the dpi is 125% or 150% it will not work even if the user will [try to request](https://github.com/openjdk/jdk/pull/2875#discussion_r641078169) such image.
> 
> The current code by @azuev-java handles this situation because the icon returned will contain five variants for the range of 100%, 125%, 150%, 175%, 200%.
> 
> I don't clearly understand your concern here.
> 
>> Take a look to the description of 8182043, the user wanted to get some large Icon, now imaging he would like to get a 79x79 icon for some file, did we provide a way to do that? I assume we even do not try to request that size from the operation system so it actually cannot ignore our request?
> 
> No, we do not request 79×79 because such an icon never exists in Windows because Windows shell does not use such a size to display a file. Well, it may exist if a developer for some reason included it in the app resources but it would rather be an exceptional case.
> 
> So if a Java app developer wants 79×79 icon, it will be scaled down from 96×96 or 128×128.

> > Why not? To request the icon of a larger size, the object which stores the icon should keep the reference to the file or folder, folders could have custom icons, and Documents, Downloads, Pictures are the examples of such folders. This must be done on COM thread because the icons are requested from the Windows shell.
> 
> Because selection of the proper icon/image will be done during rendering of the component, and waiting of the results on the com thread may slowdown it. Instead we can use default image which we initially loaded, and later use the better one when it will be loaded on the com thread.

This sounds reasonable… until you take into account the fact the `Icon` or `ImageIcon` has no reference to a component. When the icon is requested, the scale at which will be rendered is unknown.

When an icon is rendered and the required variant does not exist in the MRI, there's no way to fetch it asynchronously: the icon can't make the component repaint because there's no reference to the component.

The only optimisation that I see is to request only the size which correspond to the current monitor scales. If a different size is needed, a synchronous call to COM thread is required; and for this the icon must keep the path to the file.

-------------

PR: https://git.openjdk.org/jdk/pull/7805



More information about the client-libs-dev mailing list