mirror of
https://github.com/microsoft/PowerToys.git
synced 2025-12-15 19:27:56 +01:00
part deux
This commit is contained in:
@@ -14,12 +14,6 @@
|
||||
<NoWarn>SA1313;</NoWarn>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup>
|
||||
<CsWinRTIncludes>AdaptiveCards.ObjectModel.WinUI3;AdaptiveCards.Rendering.WinUI3</CsWinRTIncludes>
|
||||
<CsWinRTAotOptimizerEnabled>true</CsWinRTAotOptimizerEnabled>
|
||||
</PropertyGroup>
|
||||
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="CommunityToolkit.Common" />
|
||||
<PackageReference Include="CommunityToolkit.Mvvm" />
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
// 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.CommandPalette.UI.ViewModels;
|
||||
|
||||
public partial class ToastViewModel : ObservableObject
|
||||
{
|
||||
[ObservableProperty]
|
||||
public partial string ToastMessage { get; set; } = string.Empty;
|
||||
}
|
||||
@@ -164,6 +164,11 @@
|
||||
<ProjectReference Include="..\Microsoft.CommandPalette.UI.Models\Microsoft.CommandPalette.UI.Models.csproj" />
|
||||
<ProjectReference Include="..\Microsoft.CommandPalette.UI.ViewModels\Microsoft.CommandPalette.UI.ViewModels.csproj" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Update="ToastWindow.xaml">
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Page Update="Pages\ShellPage.xaml">
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
|
||||
@@ -2,14 +2,34 @@
|
||||
// The Microsoft Corporation licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
using System.ComponentModel;
|
||||
using System.Text;
|
||||
using Microsoft.CommandPalette.ViewModels;
|
||||
using Microsoft.UI.Xaml.Controls;
|
||||
using Windows.System;
|
||||
|
||||
namespace Microsoft.CommandPalette.UI.Pages;
|
||||
|
||||
public sealed partial class ShellPage : Page
|
||||
{
|
||||
private readonly ShellViewModel viewModel;
|
||||
private readonly DispatcherQueue _queue = DispatcherQueue.GetForCurrentThread();
|
||||
private readonly DispatcherQueueTimer _debounceTimer = DispatcherQueue.GetForCurrentThread().CreateTimer();
|
||||
private readonly TaskScheduler _mainTaskScheduler = TaskScheduler.FromCurrentSynchronizationContext();
|
||||
|
||||
private readonly SlideNavigationTransitionInfo _slideRightTransition = new() { Effect = SlideNavigationTransitionEffect.FromRight };
|
||||
private readonly SuppressNavigationTransitionInfo _noAnimation = new();
|
||||
|
||||
private readonly ToastWindow _toast = new();
|
||||
|
||||
private readonly CompositeFormat _pageNavigatedAnnouncement;
|
||||
|
||||
|
||||
private CancellationTokenSource? _focusAfterLoadedCts;
|
||||
|
||||
public event PropertyChangedEventHandler? PropertyChanged;
|
||||
|
||||
private WeakReference<Page>? _lastNavigatedPageRef;
|
||||
private SettingsWindow? _settingsWindow;
|
||||
|
||||
public ShellPage(ShellViewModel viewModel)
|
||||
{
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<winuiex:WindowEx
|
||||
x:Class="Microsoft.CommandPalette.UI.ToastWindow"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:local="using:Microsoft.CommandPalette.UI"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:ui="using:CommunityToolkit.WinUI"
|
||||
xmlns:winuiex="using:WinUIEx"
|
||||
Title="Command Palette Toast"
|
||||
mc:Ignorable="d">
|
||||
<winuiex:WindowEx.SystemBackdrop>
|
||||
<DesktopAcrylicBackdrop />
|
||||
</winuiex:WindowEx.SystemBackdrop>
|
||||
<Grid x:Name="ToastGrid">
|
||||
<!-- This padding is used to calculate the dimensions of the ToastWindow -->
|
||||
<TextBlock
|
||||
x:Name="ToastText"
|
||||
Padding="12,12,24,20"
|
||||
Text="{x:Bind ViewModel.ToastMessage, Mode=OneWay}"
|
||||
TextAlignment="Center" />
|
||||
</Grid>
|
||||
</winuiex:WindowEx>
|
||||
@@ -0,0 +1,97 @@
|
||||
// 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.
|
||||
|
||||
using ManagedCommon;
|
||||
using Microsoft.CommandPalette.UI.Models.Messages;
|
||||
using Windows.System;
|
||||
using RS_ = Microsoft.CommandPalette.UI.Helpers.ResourceLoaderInstance;
|
||||
|
||||
namespace Microsoft.CommandPalette.UI;
|
||||
|
||||
public sealed partial class ToastWindow : WindowEx,
|
||||
IRecipient<QuitMessage>
|
||||
{
|
||||
private readonly HWND _hwnd;
|
||||
private readonly DispatcherQueueTimer _debounceTimer = DispatcherQueue.GetForCurrentThread().CreateTimer();
|
||||
private readonly HiddenOwnerWindowBehavior _hiddenOwnerWindowBehavior = new();
|
||||
|
||||
public ToastViewModel ViewModel { get; } = new();
|
||||
|
||||
public ToastWindow()
|
||||
{
|
||||
this.InitializeComponent();
|
||||
AppWindow.Hide();
|
||||
ExtendsContentIntoTitleBar = true;
|
||||
AppWindow.SetPresenter(AppWindowPresenterKind.CompactOverlay);
|
||||
this.SetIcon();
|
||||
AppWindow.Title = RS_.GetString("ToastWindowTitle");
|
||||
AppWindow.TitleBar.PreferredHeightOption = TitleBarHeightOption.Collapsed;
|
||||
_hiddenOwnerWindowBehavior.ShowInTaskbar(this, false);
|
||||
|
||||
_hwnd = new HWND(WinRT.Interop.WindowNative.GetWindowHandle(this).ToInt32());
|
||||
PInvoke.EnableWindow(_hwnd, false);
|
||||
|
||||
WeakReferenceMessenger.Default.Register<QuitMessage>(this);
|
||||
}
|
||||
|
||||
private static double GetScaleFactor(HWND hwnd)
|
||||
{
|
||||
try
|
||||
{
|
||||
var monitor = PInvoke.MonitorFromWindow(hwnd, MONITOR_FROM_FLAGS.MONITOR_DEFAULTTONEAREST);
|
||||
_ = PInvoke.GetDpiForMonitor(monitor, MONITOR_DPI_TYPE.MDT_EFFECTIVE_DPI, out var dpiX, out _);
|
||||
return dpiX / 96.0;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logger.LogError($"Failed to get scale factor, error: {ex.Message}");
|
||||
return 1.0;
|
||||
}
|
||||
}
|
||||
|
||||
private void PositionCentered()
|
||||
{
|
||||
this.SetWindowSize(ToastText.ActualWidth, ToastText.ActualHeight);
|
||||
|
||||
var displayArea = DisplayArea.GetFromWindowId(AppWindow.Id, DisplayAreaFallback.Nearest);
|
||||
if (displayArea is not null)
|
||||
{
|
||||
var centeredPosition = AppWindow.Position;
|
||||
centeredPosition.X = (displayArea.WorkArea.Width - AppWindow.Size.Width) / 2;
|
||||
|
||||
var monitorHeight = displayArea.WorkArea.Height;
|
||||
var windowHeight = AppWindow.Size.Height;
|
||||
centeredPosition.Y = monitorHeight - (windowHeight + 8); // Align with other shell toasts, like the volume indicator.
|
||||
AppWindow.Move(centeredPosition);
|
||||
}
|
||||
}
|
||||
|
||||
public void ShowToast(string message)
|
||||
{
|
||||
ViewModel.ToastMessage = message;
|
||||
DispatcherQueue.TryEnqueue(
|
||||
DispatcherQueuePriority.Low,
|
||||
() =>
|
||||
{
|
||||
PositionCentered();
|
||||
|
||||
// SW_SHOWNA prevents us from getting activated (and stealing FG)
|
||||
PInvoke.ShowWindow(_hwnd, SHOW_WINDOW_CMD.SW_SHOWNA);
|
||||
|
||||
_debounceTimer.Debounce(
|
||||
() =>
|
||||
{
|
||||
AppWindow.Hide();
|
||||
},
|
||||
interval: TimeSpan.FromMilliseconds(2500),
|
||||
immediate: false);
|
||||
});
|
||||
}
|
||||
|
||||
public void Receive(QuitMessage message)
|
||||
{
|
||||
// This might come in on a background thread
|
||||
DispatcherQueue.TryEnqueue(() => Close());
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user