Opened 2 months ago

Closed 2 months ago

#18588 closed defect (fixed)

wxTaskBarIcon - TaskbarCreated message handling fails when the icon isn't removed from the taskbar

Reported by: dominic Owned by: Vadim Zeitlin <vadim@…>
Priority: normal Milestone: 3.1.4
Component: wxMSW Version: dev-latest
Keywords: wxTaskBarIcon Cc: dominic.arseneau@…
Blocked By: Blocking:
Patch: yes

Description

In some instances, Windows is sending the "TaskbarCreated" message without removing the icons from the taskbar. I have seen this behavior at least on Windows 10 whenever the display DPI scaling settings are changed or if multiple monitors are connected that have a different scaling value applied to them and some are turned off/on. I'm not sure if there are other instances where this will happen.

This causes the "Shell_NotifyIcon" call in wxTaskBarIcon::SetIcon to fail with the "0x80004005" error code returned when it's trying to re-add the icon to the taskbar with the "NIM_ADD" message when handling the "TaskbarCreated" message. This will cause the "m_iconAdded" flag to remain false and will prevent further updates to the icon since wxTaskBarIcon will continue to try to re-add the icon which will always fail due to the icon already being on the taskbar. The only way to get out of this would be to kill the explorer process so that the icon can finally be re-added.

Steps to reproduce:

  1. Open the taskbar sample (samples\taskbar)
  2. In the Windows display settings, change the scale option to a different one that's currently being used.
  3. Right click on the taskbar sample's taskbar icon and select the "Set New Icon" option from the popup menu.
  4. Instead of seeing the updated icon with the yellow smiley face, the icon won't be updated and the "Could not set new icon." error message is displayed.

I was able to reproduce this on Windows 10 on at least the versions 1903 and 1703.

To emulate this behavior, I attached a patch (repro.patch) that adds a new button to the taskbar sample which will send the "TaskbarCreated" message when pressed. With that button, step 2 above can be replaced to simply press the "Send event" button on the right side of the main window.

I was able to fix this issue by trying to update the icon in the event that the add fails in the wxTaskBarIcon::SetIcon. I only tested the patch on Windows 10.

Attachments (2)

fix.patch download (645 bytes) - added by dominic 2 months ago.
Patch for the issue
repro.patch download (1.7 KB) - added by dominic 2 months ago.
Adds new button to the taskbar sample

Download all attachments as: .zip

Change History (5)

Changed 2 months ago by dominic

Patch for the issue

Changed 2 months ago by dominic

Adds new button to the taskbar sample

comment:1 Changed 2 months ago by vadz

  • Milestone set to 3.1.4

Thanks for the patch! Your explanation makes perfect sense to me, but I'd like to make the logic here a bit more explicit, so I've done this change instead. I didn't have time to test it under Windows 10 yet, could you please check if it works for you? And if you have any comments on it, they are welcome too, of course (I'm not happy about having to duplicate Shell_NotifyIcon() calls, but it looked like the most clear variant to me).

comment:2 Changed 2 months ago by dominic

  • Cc dominic.arseneau@… added

I checked out your suggested change and it works on Windows 10. Thanks!

comment:3 Changed 2 months ago by Vadim Zeitlin <vadim@…>

  • Owner set to Vadim Zeitlin <vadim@…>
  • Resolution set to fixed
  • Status changed from new to closed

In 5cf9c735c/git-wxWidgets:

Handle taskbar updates not removing notification icons from it

Fix bug with not being able to update wxTaskBarIcon under MSW after a
DPI scale change or [dis]connection of another monitor using different
DPI: this resulted in "TaskbarCreated" message being sent by the system,
which we handled by trying to create the taskbar icon again. However in
this case, recreating it failed, presumably because it still existed, as
modifying the existing icon still worked.

Change the handle of "TaskbarCreated" to try both adding and updating
the icon, as it seems that we can't be sure whether we still have it or
not when we get this message.

Refactor the existing code to specify the operation to perform when
calling the new DoSetIcon(). This actually makes things slightly simpler
for it, as it doesn't need to update m_iconAdded inside it any more.

Closes #18588.

Note: See TracTickets for help on using tickets.