A nasty bug was sometime occurring where both explorer and the widget
host process could hang; this often happened when explorer was
restarted. The reason this happened was because the widget host
process could hang waiting for the "Lock_EPWeather_Instance" lock. This
was a global lock that made sure only one instance of the widget could
be created.
The idea of the global "Lock_EPWeather_Instance" lock was, of course,
pretty bad, but I chose it because I couldn't figure out/didn't want to
deal with passing an EPWeather "this" instance to WebView2 or
NetworkListManagerEvents functions. Bad decision.
This patch addresses this bug, by providing a generic object
which holds a reference to EPWeather "this" on which I build event
handlers for WebView2 and so on. Since these now contain this
reference, they cannot be static anymore, thus I switched to dynamically
allocating them and managing them throughout their lifetime using,
of course, reference counting. This is the proper solution.
Thus, this bug and any similar ones should now be fixed.
This is so that we avoid a situation where the browser was looping on
trying to display the error page. Each navigation request was
erroring out, and the error said something along the lines of
"Your computer went to sleep". Indeed, this bug could be reproduced by
hibernating the computer and then waking it up - it seemed to occur
pretty frequently, especially on battery, when the power budget is more
constrained, and thus the speed of the PC as well. Hopefully, this
commit and the previous one addresses this issue.
Changes in this version:
* [Store layout window flags in single variable](633fb2c51a)
* [Use external variable to detect if desktop is foreground](4b9ff84436)
* [Fix regression when detecting foreground window changes](8ab7a45162)
* [Draw DWM-like placeholder when window has zero width or height](764a2913b4)
* [Enforce a minimum size for a window rectangle](bc8b04e451)
Adds 2 new tags in the settings file that define the start and end of a
logical section, in order to enable the possibility of hiding parts of
the UI based on the current value of some setting:
;s Taskbar_Windows10Section IsOldTaskbar <- SECTION BEGIN
;g Taskbar_Windows10Section <- SECTION END
For s, the parameters represent these:
* Taskbar_Windows10Section = name of the current section
* IsOldTaskbar = if the check associated with this name (function call)
returns FALSE, the section will not be displayed on the screen; that
is, the code will skip drawing whatever is inside the 2 tags
This commit includes support for the Windows spotlight feature from
22000.708+ OS builds.
Related to this, ExplorerPatcher now offers the following functionality:
* Hide the "Learn about this picture" icon
* Choose which items from the Windows spotlight icon context menu to
have replicated in the desktop context menu (legacy context menu only)
* Set a schedule for "Switch to next picture"
* Manipulate the feature from the Properties UI, bypassing the desktop
icon
sign out process when using the weather widget
The hang was happening because the UI thread of explorer was hanging in
`dllmain!PeopleBand_DrawTextWithGlowHook` in a call to `AcquireSRWLockExclusive`
when the host process for the widget terminated (due to the system shutting
down - the case when hr is 0x800706ba aka "RPC server is unavailable"). When the
remote process dies, say we are in `dllmain!PeopleBand_DrawTextWithGlowHook`;
a call to some interface from it hangs for a bit, and during
that time the calling thread is able to continue its lifetime, during which a
subsequent call to `dllmain!PeopleBand_DrawTextWithGlowHook` is made (another
widget redraw is requested). As SRW locks do not really support recursion (calling
the same function from the same thread), this behavior is then expected and the
whole thing hangs, thus hanging the shutdown process (and explorer's UI thread in
turn). That's why when you clicked "Cancel" when the UI to close hung apps was
displayed at shutdown, you returned to a frozen desktop. Apparently, Windows lets
explorer hang indefinitely at shutdown, which made matters even worse.
The solution is two fold:
* Widget destruction is dispatched to the service thread. This is not strictly
necessary, but allows for better control of where the thing is destroyed from.
* Switched from SRW locks to a critical section, which is a per-thread lock. All
this has to do is make sure the program destroys the widget only when no other
routine (usually drawing stuff) uses it.
This should pretty much mitigate the issue, hopefully.