mirror of
https://github.com/microsoft/PowerToys.git
synced 2026-08-29 10:09:43 +02:00
CmdPal: make dialogs prevent compact mode from being collapsed (#49451)
ContentDialogs we present for CommandResult.Confirm need to be visible. When the window is clipped for compact mode, the dialog is predictably also collapsed. This makes sure that content dialogs are always visible, by forcing us out of compact mode when dialogs are shown. Closes: quite sure it was filed somewhere, right?
This commit is contained in:
@@ -57,6 +57,7 @@ public sealed partial class MainWindow : WindowEx,
|
||||
IRecipient<ToggleDevRibbonMessage>,
|
||||
IRecipient<GetHwndMessage>,
|
||||
IRecipient<ExpandCompactModeMessage>,
|
||||
IRecipient<MaximizeForDialogMessage>,
|
||||
IDisposable,
|
||||
IHostWindow
|
||||
{
|
||||
@@ -112,6 +113,15 @@ public sealed partial class MainWindow : WindowEx,
|
||||
private bool _preventHideWhenDeactivated;
|
||||
private bool _isLoadedFromDock;
|
||||
|
||||
// While a modal dialog (e.g. a confirmation) is showing, the card is forced to fill the
|
||||
// whole window so the dialog — which renders in the window's popup layer and is clipped to
|
||||
// the card's HWND region — isn't cut off. Cleared when the dialog closes.
|
||||
private bool _dialogFullExpandActive;
|
||||
|
||||
// The most recent expand/collapse request, remembered so the correct compact layout can be
|
||||
// restored once a dialog-driven full expansion ends.
|
||||
private bool _lastExpandRequested;
|
||||
|
||||
private DevRibbon? _devRibbon;
|
||||
|
||||
private MainWindowViewModel ViewModel { get; }
|
||||
@@ -184,6 +194,7 @@ public sealed partial class MainWindow : WindowEx,
|
||||
WeakReferenceMessenger.Default.Register<ToggleDevRibbonMessage>(this);
|
||||
WeakReferenceMessenger.Default.Register<GetHwndMessage>(this);
|
||||
WeakReferenceMessenger.Default.Register<ExpandCompactModeMessage>(this);
|
||||
WeakReferenceMessenger.Default.Register<MaximizeForDialogMessage>(this);
|
||||
|
||||
// Hide our titlebar.
|
||||
// We need to both ExtendsContentIntoTitleBar, then set the height to Collapsed
|
||||
@@ -1918,16 +1929,32 @@ public sealed partial class MainWindow : WindowEx,
|
||||
this.DispatcherQueue.TryEnqueue(() => HandleExpandCompactOnUiThread(message.Expanded));
|
||||
}
|
||||
|
||||
public void Receive(MaximizeForDialogMessage message)
|
||||
{
|
||||
this.DispatcherQueue.TryEnqueue(() =>
|
||||
{
|
||||
_dialogFullExpandActive = message.Maximize;
|
||||
|
||||
// Re-run with the last requested state: when maximizing this fills the window; when
|
||||
// the dialog closes it restores the normal compact/expanded layout.
|
||||
HandleExpandCompactOnUiThread(_lastExpandRequested);
|
||||
});
|
||||
}
|
||||
|
||||
// The HWND is already as large as it will ever need to be (and it's transparent), so
|
||||
// instead of resizing the window we simply shrink or grow the visible card inside it.
|
||||
private void HandleExpandCompactOnUiThread(bool expanded)
|
||||
{
|
||||
_lastExpandRequested = expanded;
|
||||
|
||||
var settings = App.Current.Services.GetRequiredService<ISettingsService>().Settings;
|
||||
|
||||
if (!settings.CompactMode)
|
||||
var preventCompactMode = _dialogFullExpandActive || !settings.CompactMode;
|
||||
if (preventCompactMode)
|
||||
{
|
||||
// When compact mode is off the card is always static and fills the entire window,
|
||||
// regardless of how much content is currently displayed.
|
||||
// When compact mode is off, or a dialog is active, the card is
|
||||
// always static and fills the entire window, regardless of how much
|
||||
// content is currently displayed.
|
||||
RootElement.SetCardStretch(true);
|
||||
RootElement.SetCardMaxHeight(double.PositiveInfinity);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
// Copyright (c) Microsoft Corporation
|
||||
// The Microsoft Corporation licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
namespace Microsoft.CmdPal.UI.Messages;
|
||||
|
||||
/// <summary>
|
||||
/// Asks the host window to temporarily make the visible card fill the entire window,
|
||||
/// ignoring the compact-mode clamps, so a modal dialog (e.g. a confirmation) isn't clipped
|
||||
/// by the card's HWND region. Sent with <see cref="Maximize"/> = <see langword="true"/> while
|
||||
/// the dialog is showing and <see langword="false"/> once it closes to restore the normal
|
||||
/// compact/expanded behavior.
|
||||
/// </summary>
|
||||
public record MaximizeForDialogMessage(bool Maximize);
|
||||
@@ -361,7 +361,26 @@ public sealed partial class ShellPage : Microsoft.UI.Xaml.Controls.Page,
|
||||
// };
|
||||
}
|
||||
|
||||
var result = await dialog.ShowAsync();
|
||||
// In compact mode the palette may be collapsed to just the search box. The confirmation
|
||||
// dialog renders in the host window's popup layer, which is clipped to the card's HWND
|
||||
// region, so merely expanding our own content isn't enough - the card must fill the whole
|
||||
// window or the dialog is clipped. Ask the host window to maximize the card while the
|
||||
// dialog is up (and expand our own content to match), then restore the normal compact
|
||||
// behavior once it closes.
|
||||
WeakReferenceMessenger.Default.Send(new MaximizeForDialogMessage(true));
|
||||
HandleExpandCompactOnUiThread(true);
|
||||
|
||||
ContentDialogResult result;
|
||||
try
|
||||
{
|
||||
result = await dialog.ShowAsync();
|
||||
}
|
||||
finally
|
||||
{
|
||||
WeakReferenceMessenger.Default.Send(new MaximizeForDialogMessage(false));
|
||||
UpdateCompactModeForCurrentPage();
|
||||
}
|
||||
|
||||
if (result == ContentDialogResult.Primary)
|
||||
{
|
||||
var performMessage = new PerformCommandMessage(vm);
|
||||
|
||||
Reference in New Issue
Block a user