-
Notifications
You must be signed in to change notification settings - Fork 6.2k
8182043: Access to Windows Large Icons #380
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
8182043: Access to Windows Large Icons #380
Conversation
|
👋 Welcome back kizune! A progress list of the required criteria for merging this PR into |
|
@azuev-java The following labels will be automatically applied to this pull request:
When this pull request is ready to be reviewed, an "RFR" email will be sent to the corresponding mailing lists. If you would like to change these labels, use the /label pull request command. |
|
@mrserb Can you review this? |
|
@aivanov-jdk Can you review this? |
|
I still suggest to try the approach recommended here: On 29.05.2020 14:35, Alexey Ivanov wrote:
If an approach above works then we could request the icon of the exact existed size, and if that size is unknown we could request some predefined size like 16,24. etc Some additional comment was sent here: |
I agree that using On the other hand, I think the current approach is good enough. It provides access to larger set of icons and improves I'd like to comment on this part from previous discussion:
I'd rather agree that no icon contains 100×100 size only. Yet it's pretty common that some sizes are not available in
Yet if the requested size differs from the above set, the icon will be scaled twice: by the OS and then by Java. In such a case, the result of scaling the original icon will likely be better than scaling an already scaled icon.
And I am still wondering why it happens. I can imagine a situation where an icon for a file is generated on the fly by the The usage of different APIs can be the reason why drives lost their customised icons. As for the additional comment:
It talks about tray icons. It depends on the way the icon is extracted, and to support High DPI environment, the icon must be an MRI. So I'd say the comment is not strictly relevant to the current discussion. However, this new implementation may improve the display of tray icons too if this new API is used to get the icon. |
| hres = pIcon->Extract(szBuf, index, &hIcon, &hIconLow, (16 << 16) + size); | ||
| if (size < 24) { | ||
| fn_DestroyIcon((HICON)hIcon); | ||
| hIcon = hIconLow; | ||
| } else { | ||
| fn_DestroyIcon((HICON)hIconLow); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wonder why you extract two icons, you never use both. This adds a delay: only one of the extracted icons is ever used. If the idea is to limit the size by 16, then min(16, size) passed as the icon size would do the trick.
Each time we use this function, we request two icons but we never use both of them.
| hres = pIcon->Extract(szBuf, index, &hIcon, &hIconLow, (16 << 16) + size); | |
| if (size < 24) { | |
| fn_DestroyIcon((HICON)hIcon); | |
| hIcon = hIconLow; | |
| } else { | |
| fn_DestroyIcon((HICON)hIconLow); | |
| if (size < 24) { | |
| size = 16; | |
| } | |
| hres = pIcon->Extract(szBuf, index, &hIcon, NULL, size); |
And hIconLow can be removed.
| * Icon for a file, directory, or folder as it would be displayed in | ||
| * a system file browser for the requested size. | ||
| * | ||
| * The default implementation gets information from the |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| * The default implementation gets information from the | |
| * <p>The default implementation gets information from the |
| * a system file browser for the requested size. | ||
| * | ||
| * The default implementation gets information from the | ||
| * <code>ShellFolder</code> class. Whenever possible the icon |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| * <code>ShellFolder</code> class. Whenever possible the icon | |
| * <code>ShellFolder</code> class. Whenever possible, the icon |
Do we continue using <code> elements? I thought that {@code} is the preferred way to markup class names.
| * which will allow better scaling with different | ||
| * magnification factors. | ||
| * | ||
| * Example: <pre> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| * Example: <pre> | |
| * <p>Example: <pre> |
| /** | ||
| * Returns the icon of the specified size used to display this shell folder. | ||
| * | ||
| * @param size size of the icon > 0(Valid range: 1 to 256) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| * @param size size of the icon > 0(Valid range: 1 to 256) | |
| * @param size size of the icon > 0 (Valid range: 1 to 256) |
| new BufferedImage(iconSize, iconSize, BufferedImage.TYPE_INT_ARGB); | ||
| img.setRGB(0, 0, iconSize, iconSize, iconBits, 0, iconSize); | ||
| return img; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There are cases where the size of the buffered image is different from the requested size. It could affect the layout because it breaks the assumption that the returned image has the requested size but it may be larger.
| newIcon2 = imageCache.get(Integer.valueOf(index)); | ||
| if (newIcon2 == null) { | ||
| long hIcon = getIcon(getAbsolutePath(), !getLargeIcon); | ||
| newIcon2 = makeIcon(hIcon, getLargeIcon ? SMALL_ICON_SIZE | ||
| : LARGE_ICON_SIZE); | ||
| disposeIcon(hIcon); | ||
| } | ||
| } | ||
|
|
||
| if (newIcon2 != null) { | ||
| Map<Integer, Image> bothIcons = new HashMap<>(2); | ||
| bothIcons.put(getLargeIcon? LARGE_ICON_SIZE : SMALL_ICON_SIZE, newIcon); | ||
| bothIcons.put(getLargeIcon? SMALL_ICON_SIZE : LARGE_ICON_SIZE, newIcon2); | ||
| newIcon = new MultiResolutionIconImage(getLargeIcon ? LARGE_ICON_SIZE | ||
| : SMALL_ICON_SIZE, bothIcons); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I propose to refactor this code into a separate method which always fetches small and large icon and puts into a corresponding cache.
However, I still think there's not much value in getting smaller icon size in addition to larger one. Or does it provide an alternative image for the case where the system scaling is 200% and the window is moved to a monitor with scaling of 100%?
| disposeIcon(hIcon); | ||
|
|
||
| multiResolutionIcon.put(s, newIcon); | ||
| if (size < 8 || size > 256) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| if (size < 8 || size > 256) { | |
| if (size < MIN_QUALITY_ICON || size > MAX_QUALITY_ICON) { |
| if (i >= 0) { | ||
| return Win32ShellFolder2.getShell32Icon(i, key.startsWith("shell32LargeIcon ")); | ||
| return Win32ShellFolder2.getShell32Icon(i, | ||
| key.startsWith("shell32LargeIcon ")?LARGE_ICON_SIZE : SMALL_ICON_SIZE); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| key.startsWith("shell32LargeIcon ")?LARGE_ICON_SIZE : SMALL_ICON_SIZE); | |
| key.startsWith("shell32LargeIcon ") ? LARGE_ICON_SIZE : SMALL_ICON_SIZE); |
| icon.getIconWidth() + " when requested " + size); | ||
| } | ||
| } | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does it make sense to check that the icon is a multi-resolution image with the expected sizes?
|
@azuev-java This pull request has been inactive for more than 4 weeks and will be automatically closed if another 4 weeks passes without any activity. To avoid this, simply add a new comment to the pull request. Feel free to ask for assistance if you need help with progressing this pull request towards integration! |
|
@azuev-java This pull request has been inactive for more than 8 weeks and will now be automatically closed. If you would like to continue working on this pull request in the future, feel free to reopen it! |
Moving review from Mercurial. See https://mail.openjdk.java.net/pipermail/awt-dev/2020-August/016078.html for previous iteration.
Progress
Issue
Download
$ git fetch https://git.openjdk.java.net/jdk pull/380/head:pull/380$ git checkout pull/380