Ultralight icon indicating copy to clipboard operation
Ultralight copied to clipboard

Taskbar button's icon disappears when SHChangeNotify() is used, such as with many installers

Open JohnKlenk opened this issue 11 months ago • 4 comments

When an app notifies Windows that it has made shell-related changes using a method such as SHChangeNotify(), the icon disappears from the taskbar button of Ultralight-based apps.

The problem was first seen when running various MSI installers (at the very end when the deskop updates), but the steps below just use trigger SHChangeNotify() directly in PowerShell. And the problem has been seen even when no user action is taken, apparently from something on the system triggering a refresh.

Does not matter if CPU or GPU mode is used.

This was introduced between 1.4.0a and 1.4.0b.

1.) Have the UL "Sample 8 - Web Browser" app unfocused (does not need to be minimized). 2.) From a PowerShell prompt (admin not needed), run the following and then wait up to a few seconds (you can just paste it all in at once):

Add-Type -TypeDefinition @"
using System;
using System.Runtime.InteropServices;
public class NativeMethods {
    [DllImport("shell32.dll")]
    public static extern void SHChangeNotify(int wEventId, int uFlags, IntPtr dwItem1, IntPtr dwItem2);
}
"@
[NativeMethods]::SHChangeNotify(0x8000000, 0x0, [IntPtr]::Zero, [IntPtr]::Zero)

Bug: The icon disappears from the UL taskbar button. It returns when the app is focused or hovered, or when the app updates its titlebar.

JohnKlenk avatar May 12 '25 21:05 JohnKlenk

Screenshots: Image

JohnKlenk avatar May 12 '25 22:05 JohnKlenk

Attaching a script for the PowerShell command, to make it a bit easier to repro when debugging. You may need to set PowerShell to allow local scripts, which you can do by the following in a PowerShell prompt:

Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope LocalMachine

Then run with by typing the refresh.ps1 path in the PowerShell prompt, or:

powershell -File <path to refresh.ps1>

refresh script.zip

JohnKlenk avatar May 12 '25 22:05 JohnKlenk

Just discovered that as with issue 531, the problem does not happen with the "Sample 7 - OpenGL Integration" app. Apparently related to this code there:

GLFWbool _glfwRegisterWindowClassWin32(void)
{
    WNDCLASSEXW wc;

    ZeroMemory(&wc, sizeof(wc));
    wc.cbSize        = sizeof(wc);
    wc.style         = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;
    wc.lpfnWndProc   = (WNDPROC) windowProc;
    wc.hInstance     = GetModuleHandleW(NULL);
    wc.hCursor       = LoadCursorW(NULL, IDC_ARROW);
    wc.lpszClassName = _GLFW_WNDCLASSNAME;

    // Load user-provided icon if available
    wc.hIcon = LoadImageW(GetModuleHandleW(NULL),
                          L"GLFW_ICON", IMAGE_ICON,
                          0, 0, LR_DEFAULTSIZE | LR_SHARED);
    if (!wc.hIcon)
    {
        // No user-provided icon found, load default icon
        wc.hIcon = LoadImageW(NULL,
                              IDI_APPLICATION, IMAGE_ICON,
                              0, 0, LR_DEFAULTSIZE | LR_SHARED);
    }

    if (!RegisterClassExW(&wc))
    {
        _glfwInputErrorWin32(GLFW_PLATFORM_ERROR,
                             "Win32: Failed to register window class");
        return GLFW_FALSE;
    }

    return GLFW_TRUE;
}

JohnKlenk avatar May 13 '25 16:05 JohnKlenk

Related bug: issue 533

JohnKlenk avatar May 23 '25 20:05 JohnKlenk

Fixed in 1.4.1-f6c121e1 dev build; closing.

JohnKlenk avatar Jul 08 '25 03:07 JohnKlenk