mirror of
https://github.com/microsoft/PowerToys.git
synced 2026-02-23 19:49:43 +01:00
NOW THIS works well
This commit is contained in:
@@ -205,6 +205,9 @@ public sealed partial class MainWindow : WindowEx,
|
||||
{
|
||||
var hwnd = new HWND(hwndValue != 0 ? hwndValue : _hwnd);
|
||||
|
||||
// Make sure our HWND is cloaked before any possible window manipulations
|
||||
Cloak();
|
||||
|
||||
// Remember, IsIconic == "minimized", which is entirely different state
|
||||
// from "show/hide"
|
||||
// If we're currently minimized, restore us first, before we reveal
|
||||
@@ -218,16 +221,11 @@ public sealed partial class MainWindow : WindowEx,
|
||||
var display = GetScreen(hwnd, target);
|
||||
PositionCentered(display);
|
||||
|
||||
// Just to be sure, SHOW our hwnd.
|
||||
PInvoke.ShowWindow(hwnd, SHOW_WINDOW_CMD.SW_SHOW);
|
||||
|
||||
// instead of showing the window, uncloak it from DWM
|
||||
// This will make it visible to the user, without the animation or frames for
|
||||
// loading XAML with composition
|
||||
unsafe
|
||||
{
|
||||
BOOL value = false;
|
||||
PInvoke.DwmSetWindowAttribute(_hwnd, DWMWINDOWATTRIBUTE.DWMWA_CLOAK, &value, (uint)sizeof(BOOL));
|
||||
}
|
||||
// Once we're done, uncloak to avoid all animations
|
||||
Uncloak();
|
||||
|
||||
PInvoke.SetForegroundWindow(hwnd);
|
||||
PInvoke.SetActiveWindow(hwnd);
|
||||
@@ -286,7 +284,14 @@ public sealed partial class MainWindow : WindowEx,
|
||||
ShowHwnd(message.Hwnd, settings.SummonOn);
|
||||
}
|
||||
|
||||
public void Receive(HideWindowMessage message) => HideWindow();
|
||||
public void Receive(HideWindowMessage message)
|
||||
{
|
||||
// This might come in off the UI thread. Make sure to hop back.
|
||||
DispatcherQueue.TryEnqueue(() =>
|
||||
{
|
||||
HideWindow();
|
||||
});
|
||||
}
|
||||
|
||||
public void Receive(QuitMessage message) =>
|
||||
|
||||
@@ -298,34 +303,24 @@ public sealed partial class MainWindow : WindowEx,
|
||||
|
||||
private void HideWindow()
|
||||
{
|
||||
// First, use EnumWindows to find the first HWND that's not us, and set it as the foreground window
|
||||
PInvoke.EnumWindows(
|
||||
(hwnd, lParam) =>
|
||||
{
|
||||
if (hwnd != _hwnd && PInvoke.IsWindowVisible(hwnd))
|
||||
{
|
||||
// and make sure it's not a tool window
|
||||
var exStyle = (WINDOW_EX_STYLE)PInvoke.GetWindowLong(hwnd, WINDOW_LONG_PTR_INDEX.GWL_EXSTYLE);
|
||||
// Cloak our HWND to avoid all animations.
|
||||
Cloak();
|
||||
|
||||
if (exStyle.HasFlag(WINDOW_EX_STYLE.WS_EX_TOOLWINDOW))
|
||||
{
|
||||
return true; // continue enumerating
|
||||
}
|
||||
// Then hide our HWND, to make sure that the OS gives the FG / focus back to another app
|
||||
// (there's no way for us to guess what the right hwnd might be, only the OS can do it right)
|
||||
this.Hide();
|
||||
|
||||
PInvoke.SetForegroundWindow(hwnd);
|
||||
return false; // stop enumerating
|
||||
}
|
||||
// TRICKY: show our HWND again. This will trick XAML into painting our
|
||||
// HWND again, so that we avoid the "flicker" caused by a WinUI3 app
|
||||
// window being first shown
|
||||
this.Show();
|
||||
|
||||
return true; // continue enumerating
|
||||
},
|
||||
IntPtr.Zero);
|
||||
// Intentionally leave the window cloaked. So our window is "visible",
|
||||
// but also cloaked, so you can't see it.
|
||||
}
|
||||
|
||||
// THEN,
|
||||
// Hide our window by DWM cloaking it
|
||||
|
||||
// Instead of hiding the window, cloak it from DWM
|
||||
// This will make it invisible to the user, such that we can show it again
|
||||
// by uncloaking it, which avoids an unnecessary "flicker in" that XAML does
|
||||
private void Cloak()
|
||||
{
|
||||
unsafe
|
||||
{
|
||||
BOOL value = true;
|
||||
@@ -333,6 +328,15 @@ public sealed partial class MainWindow : WindowEx,
|
||||
}
|
||||
}
|
||||
|
||||
private void Uncloak()
|
||||
{
|
||||
unsafe
|
||||
{
|
||||
BOOL value = false;
|
||||
PInvoke.DwmSetWindowAttribute(_hwnd, DWMWINDOWATTRIBUTE.DWMWA_CLOAK, &value, (uint)sizeof(BOOL));
|
||||
}
|
||||
}
|
||||
|
||||
internal void MainWindow_Closed(object sender, WindowEventArgs args)
|
||||
{
|
||||
var serviceProvider = App.Current.Services;
|
||||
@@ -555,6 +559,7 @@ public sealed partial class MainWindow : WindowEx,
|
||||
PowerToysTelemetry.Log.WriteEvent(new CmdPalHotkeySummoned(isRootHotkey));
|
||||
|
||||
var isVisible = this.Visible;
|
||||
|
||||
unsafe
|
||||
{
|
||||
// We need to check if our window is cloaked or not. A cloaked window is still
|
||||
@@ -584,7 +589,11 @@ public sealed partial class MainWindow : WindowEx,
|
||||
{
|
||||
// ... then manually hide our window. When debugged, we won't get the cool cloaking,
|
||||
// but that's the price to pay for having the HWND not light-dismiss while we're debugging.
|
||||
PInvoke.ShowWindow(_hwnd, SHOW_WINDOW_CMD.SW_HIDE);
|
||||
// PInvoke.ShowWindow(_hwnd, SHOW_WINDOW_CMD.SW_HIDE);
|
||||
Cloak();
|
||||
this.Hide();
|
||||
|
||||
// Uncloak();
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user