[FEATURE] Tray/Task Support?
What is the request?
Tray and taskbar button support for Windows
Why is it useful?
In order to ditch the default taskbar, which received a very (IMO) terrible rewrite in Windows 11. Calling the tray popup with AHK is rather inconsistent/buggy.
How could it be implemented?
https://github.com/cairoshell/ManagedShell - This repo might be useful in implementing this.
I understand that this is a gargantuan request - just implementing a tray widget would make a world of difference.
Leaving this as a comment for future reference regarding implementation:
https://social.msdn.microsoft.com/Forums/vstudio/en-US/dd2b6360-0077-4b69-8126-fb6d52b7eb20/get-all-tray-icons-in-taskbar-and-display-them-in-wpf?forum=wpf
I've been looking into this. The linked reference from the last message is busted, win11 replaced the system tray with a XAML app. This means that it'll most likely need multiple implementations for different OS versions.
Got somewhere but got stuck. I'll post my findings here in case anybody else has ideas.
So, the new tray app is XAML based, so navigating it with FindWindowEx is not possible after a while. The path to the important window is TopLevelWindowForOverflowXamlIsland/Windows.UI.Composition.DesktopWindowContentBridge/Windows.UI.Input.InputSite.WindowClass
after this point I had to upgrade windows-rs to 0.52.0 for convenience, then I tried using UI Automation. This let me take the InputSite window and convert it to an automation element, from there it's just a tree walk down, code for this so far is:
let hwnd_tray_overflow = FindWindowW(w!("TopLevelWindowForOverflowXamlIsland"), PCWSTR(std::ptr::null()));
if hwnd_tray_overflow.0 == 0 {
return None;
}
let hwnd_content_bridge = FindWindowExW(
hwnd_tray_overflow,
HWND(0),
w!("Windows.UI.Composition.DesktopWindowContentBridge"),
PCWSTR(std::ptr::null()),
);
if hwnd_content_bridge.0 == 0 {
return None;
}
let hwnd_ms_inputsite = FindWindowExW(
hwnd_content_bridge,
HWND(0),
w!("Windows.UI.Input.InputSite.WindowClass"),
PCWSTR(std::ptr::null()),
);
if hwnd_ms_inputsite.0 == 0 {
return None;
}
let automation: IUIAutomation = CoCreateInstance(&CUIAutomation, None, CLSCTX_ALL).unwrap();
let element = automation.ElementFromHandle(hwnd_ms_inputsite).unwrap();
let children = element.FindAll(TreeScope_Children, &automation.CreateTrueCondition().unwrap());
if children.is_err() {
println!("Error finding children");
return None;
}
let children = children.unwrap();
// Discord is index 2 for me
let discord = children.GetElement(2).unwrap();
let image = discord
.FindFirst(TreeScope_Children, &automation.CreateTrueCondition().unwrap())
.unwrap();
This is where I got stuck. There's no apparent way to either
- Get the Source property from the image
- Convert the automation element to a uwp Image object.
If I had more time, I'd check out the source code of UWPSpy: https://github.com/m417z/UWPSpy
This managed to at least tell what the source is set to.