Skip to content

Use custom application icon on Windows, if present.#2274

Merged
xStrom merged 3 commits intolinebender:masterfrom
tay64:dev_winicon
Dec 4, 2022
Merged

Use custom application icon on Windows, if present.#2274
xStrom merged 3 commits intolinebender:masterfrom
tay64:dev_winicon

Conversation

@tay64
Copy link
Contributor

@tay64 tay64 commented Oct 13, 2022

On Windows, if the executable contains an icon resource with id 1, this icon will be used in the Taskbar and in the titlebar of Druid windows. If there is no such icon resource, the default application icon IDI_APPLICATION will be used (as before this change).

Adding a custom icon: one way is to use the winres crate and follow the guide in its README; winres::WindowsResource::set_icon() adds an icon with id 1.

Non-Windows back-ends are not modified.


This is a very small change that improves on status-quo a little; it is not an attempt in adding proper support for icons. The new behavior is a strict superset of the previous behavior and should have no negative effects. The users that do not take special steps to embed a Windows icon won't be affected.

What happens if there is no icon resource #⁠1?

It will fall back to use the standard icon IDI_APPLICATION, matching the original behavior without this PR.

  1. LoadIconW will return NULL:
    If the function fails, the return value is NULL.
  2. WNDCLASSW::hIcon, being NULL, causes Windows to use a default icon:
    If this member is NULL, the system provides a default icon.

I was unable to find any document that explicitly says that the default icon is IDI_APPLICATION, but in practice it has been this way since Windows 3.1.

Why use the hard-coded icon id #⁠1?

The icon used by Windows for the executable file (in Explorer etc) is the first icon resource in the resource section. It does not have to be specifically #⁠1, but it is a common practice to use #⁠1 for the application icon, because the Resource Compiler orders icons by id and using 1 guarantees it to be the first one.

Also, one of the convenient methods of adding an icon to a Rust binary, the winres crate, uses the id #⁠1 by default.

I think this justifies the use of a hard-coded id in this case. This PR is intended as a very small change and any additional complexity wouldn't be welcome. Also, this will be superseded by a proper support for window icons, if and when it arrives in Druid (something like WindowDesc::set_icon).

On Windows, if the executable contains an icon resource with id 1,
this icon will be used in the Taskbar and in the titlebar of Druid windows.
If there is no such icon resource, the default application icon IDI_APPLICATION
will be used (as before this change).

Adding a custom icon: one way is to use the [winres crate](https://crates.io/crates/winres)
and follow the guide in its README; `winres::WindowsResource::set_icon()` adds
an icon with id 1.

Non-Windows back-ends are not modified.
@tay64 tay64 marked this pull request as ready for review October 13, 2022 22:10
@tay64

This comment was marked as outdated.

@xStrom xStrom added shell/win concerns the Windows backend port-to-glazier labels Dec 4, 2022
Copy link
Member

@xStrom xStrom left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you! This is clearly an improvement and you've described it well.

I am somewhat uneasy with now having two unsafe function calls without error handling. Yes as the code stands today it should degrade gracefully. However future code might not expect that results might be null pointers. Anyway we can address that in a future update, so for now lets get this merged.

@xStrom xStrom merged commit ac38151 into linebender:master Dec 4, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

port-to-glazier shell/win concerns the Windows backend

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants