Files
PowerToys/src/settings-ui/Settings.UI/Views/ShellPage.xaml.cs
Niels Laute c1c14b4f2e [Settings][runner]Quick access system tray launcher (#22408)
* Init

* Fix running settings

* UI design

* Left click trigger
Wire up colorpicker and pt run

* Wire up others

* Update FlyoutWindow.xaml.cs

* Removed comments

* Update FlyoutWindow.xaml

* More work

* Open Settings page

* More UI work

* Resolve conflicts

* [General] SystemTray Flyout: Add update on tray items' visibility when module gets enabled/disabled
Also remove context menu opening on tray icon.

* Adding app list

* Adding more buttons, resolving conflicts

* [General] Flyout: improving opening, closing flyout/settings window. Implementing basic bahaviour on enabling/disabling modules.

* [General] FlyoutWindow: proceed with implementation. GPO works. Main functionallity works (launching and enabling apps).

* [general] flyout: fix exit button

* [general] flyout: implement double click handling

* Localization

* [Generel] Flyout: Re-implement flyout launching, add workaround: disable flyout hiding in case the user switches on modules on the all apps page
+ minor changes

* [general] flyout: restore the context menu when right clicking on system tray icon

* Fix spellchecker

* [installer] fixing missing dll files + suppress error on not signed script

* Fix spell checker

* Fix flyout not focusing when activated

* Refresh Settings UI enabled state when flyout changes

* fix spellcheck

* Remove VCM from the list

* [General] flyout: fix settings window opening. Switch to general page only if there is no page opened

* [general] flyout: add launching hosts app

* Fix CI build

* adding check on elevation when launching hosts

* Use localization strings that already exist

* Remove dll not present in arm64 build

* Adding GPO policy check for the launcher page items

* fix hosts launching

* Add telemetry

* Also hide from all apps list when gpo is force enabling

* fix spellchecker

* Improve focus issues

* Fix flickering Bitmap Icons

* Fix telemetry error

* Fix telemetry call

* Fix wrong comment

---------

Co-authored-by: Stefan Markovic <stefan@janeasystems.com>
Co-authored-by: Laszlo Nemeth <laszlo.nemeth.hu@gmail.com>
Co-authored-by: Jaime Bernardo <jaime@janeasystems.com>
2023-01-30 23:00:11 +00:00

353 lines
12 KiB
C#

// 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 System;
using System.Collections.Generic;
using Microsoft.PowerToys.Settings.UI.Helpers;
using Microsoft.PowerToys.Settings.UI.Services;
using Microsoft.PowerToys.Settings.UI.ViewModels;
using Microsoft.UI.Xaml;
using Microsoft.UI.Xaml.Automation.Peers;
using Microsoft.UI.Xaml.Controls;
using Windows.ApplicationModel.Resources;
using Windows.Data.Json;
using Windows.System;
namespace Microsoft.PowerToys.Settings.UI.Views
{
/// <summary>
/// Root page.
/// </summary>
public sealed partial class ShellPage : UserControl
{
/// <summary>
/// Declaration for the ipc callback function.
/// </summary>
/// <param name="msg">message.</param>
public delegate void IPCMessageCallback(string msg);
/// <summary>
/// Declaration for the opening main window callback function.
/// </summary>
public delegate void MainOpeningCallback();
/// <summary>
/// Declaration for the updating the general settings callback function.
/// </summary>
public delegate bool UpdatingGeneralSettingsCallback(string module, bool isEnabled);
/// <summary>
/// Declaration for the opening oobe window callback function.
/// </summary>
public delegate void OobeOpeningCallback();
/// <summary>
/// Declaration for the opening flyout window callback function.
/// </summary>
public delegate void FlyoutOpeningCallback();
/// <summary>
/// Declaration for the disabling hide of flyout window callback function.
/// </summary>
public delegate void DisablingFlyoutHidingCallback();
/// <summary>
/// Gets or sets a shell handler to be used to update contents of the shell dynamically from page within the frame.
/// </summary>
public static ShellPage ShellHandler { get; set; }
/// <summary>
/// Gets or sets iPC default callback function.
/// </summary>
public static IPCMessageCallback DefaultSndMSGCallback { get; set; }
/// <summary>
/// Gets or sets iPC callback function for restart as admin.
/// </summary>
public static IPCMessageCallback SndRestartAsAdminMsgCallback { get; set; }
/// <summary>
/// Gets or sets iPC callback function for checking updates.
/// </summary>
public static IPCMessageCallback CheckForUpdatesMsgCallback { get; set; }
/// <summary>
/// Gets or sets callback function for opening main window
/// </summary>
public static MainOpeningCallback OpenMainWindowCallback { get; set; }
/// <summary>
/// Gets or sets callback function for updating the general settings
/// </summary>
public static UpdatingGeneralSettingsCallback UpdateGeneralSettingsCallback { get; set; }
/// <summary>
/// Gets or sets callback function for opening oobe window
/// </summary>
public static OobeOpeningCallback OpenOobeWindowCallback { get; set; }
/// <summary>
/// Gets or sets callback function for opening flyout window
/// </summary>
public static FlyoutOpeningCallback OpenFlyoutCallback { get; set; }
/// <summary>
/// Gets or sets callback function for disabling hide of flyout window
/// </summary>
public static DisablingFlyoutHidingCallback DisableFlyoutHidingCallback { get; set; }
/// <summary>
/// Gets view model.
/// </summary>
public ShellViewModel ViewModel { get; } = new ShellViewModel();
/// <summary>
/// Gets a collection of functions that handle IPC responses.
/// </summary>
public List<System.Action<JsonObject>> IPCResponseHandleList { get; } = new List<System.Action<JsonObject>>();
public static bool IsElevated { get; set; }
public static bool IsUserAnAdmin { get; set; }
/// <summary>
/// Initializes a new instance of the <see cref="ShellPage"/> class.
/// Shell page constructor.
/// </summary>
public ShellPage()
{
InitializeComponent();
DataContext = ViewModel;
ShellHandler = this;
ViewModel.Initialize(shellFrame, navigationView, KeyboardAccelerators);
// NL moved navigation to general page to the moment when the window is first activated (to not make flyout window disappear)
// shellFrame.Navigate(typeof(GeneralPage));
IPCResponseHandleList.Add(ReceiveMessage);
}
public static int SendDefaultIPCMessage(string msg)
{
DefaultSndMSGCallback?.Invoke(msg);
return 0;
}
public static int SendCheckForUpdatesIPCMessage(string msg)
{
CheckForUpdatesMsgCallback?.Invoke(msg);
return 0;
}
public static int SendRestartAdminIPCMessage(string msg)
{
SndRestartAsAdminMsgCallback?.Invoke(msg);
return 0;
}
/// <summary>
/// Set Default IPC Message callback function.
/// </summary>
/// <param name="implementation">delegate function implementation.</param>
public static void SetDefaultSndMessageCallback(IPCMessageCallback implementation)
{
DefaultSndMSGCallback = implementation;
}
/// <summary>
/// Set restart as admin IPC callback function.
/// </summary>
/// <param name="implementation">delegate function implementation.</param>
public static void SetRestartAdminSndMessageCallback(IPCMessageCallback implementation)
{
SndRestartAsAdminMsgCallback = implementation;
}
/// <summary>
/// Set check for updates IPC callback function.
/// </summary>
/// <param name="implementation">delegate function implementation.</param>
public static void SetCheckForUpdatesMessageCallback(IPCMessageCallback implementation)
{
CheckForUpdatesMsgCallback = implementation;
}
/// <summary>
/// Set main window opening callback function
/// </summary>
/// <param name="implementation">delegate function implementation.</param>
public static void SetOpenMainWindowCallback(MainOpeningCallback implementation)
{
OpenMainWindowCallback = implementation;
}
/// <summary>
/// Set updating the general settings callback function
/// </summary>
/// <param name="implementation">delegate function implementation.</param>
public static void SetUpdatingGeneralSettingsCallback(UpdatingGeneralSettingsCallback implementation)
{
UpdateGeneralSettingsCallback = implementation;
}
/// <summary>
/// Set oobe opening callback function
/// </summary>
/// <param name="implementation">delegate function implementation.</param>
public static void SetOpenOobeCallback(OobeOpeningCallback implementation)
{
OpenOobeWindowCallback = implementation;
}
/// <summary>
/// Set flyout opening callback function
/// </summary>
/// <param name="implementation">delegate function implementation.</param>
public static void SetOpenFlyoutCallback(FlyoutOpeningCallback implementation)
{
OpenFlyoutCallback = implementation;
}
/// <summary>
/// Set disable flyout hiding callback function
/// </summary>
/// <param name="implementation">delegate function implementation.</param>
public static void SetDisableFlyoutHidingCallback(DisablingFlyoutHidingCallback implementation)
{
DisableFlyoutHidingCallback = implementation;
}
public static void SetElevationStatus(bool isElevated)
{
IsElevated = isElevated;
}
public static void SetIsUserAnAdmin(bool isAdmin)
{
IsUserAnAdmin = isAdmin;
}
public static void Navigate(Type type)
{
NavigationService.Navigate(type);
}
public void Refresh()
{
shellFrame.Navigate(typeof(GeneralPage));
}
// Tell the current page view model to update
public void SignalGeneralDataUpdate()
{
IRefreshablePage currentPage = shellFrame?.Content as IRefreshablePage;
if (currentPage != null)
{
currentPage.RefreshEnabledState();
}
}
private void OobeButton_Click(object sender, RoutedEventArgs e)
{
OpenOobeWindowCallback();
}
private bool navigationViewInitialStateProcessed; // avoid announcing initial state of the navigation pane.
private void NavigationView_PaneOpened(Microsoft.UI.Xaml.Controls.NavigationView sender, object args)
{
if (!navigationViewInitialStateProcessed)
{
navigationViewInitialStateProcessed = true;
return;
}
var peer = FrameworkElementAutomationPeer.FromElement(sender);
if (peer == null)
{
peer = FrameworkElementAutomationPeer.CreatePeerForElement(sender);
}
if (AutomationPeer.ListenerExists(AutomationEvents.MenuOpened))
{
var loader = ResourceLoader.GetForViewIndependentUse();
peer.RaiseNotificationEvent(
AutomationNotificationKind.ActionCompleted,
AutomationNotificationProcessing.ImportantMostRecent,
loader.GetString("Shell_NavigationMenu_Announce_Open"),
"navigationMenuPaneOpened");
}
}
private void NavigationView_PaneClosed(Microsoft.UI.Xaml.Controls.NavigationView sender, object args)
{
if (!navigationViewInitialStateProcessed)
{
navigationViewInitialStateProcessed = true;
return;
}
var peer = FrameworkElementAutomationPeer.FromElement(sender);
if (peer == null)
{
peer = FrameworkElementAutomationPeer.CreatePeerForElement(sender);
}
if (AutomationPeer.ListenerExists(AutomationEvents.MenuClosed))
{
var loader = ResourceLoader.GetForViewIndependentUse();
peer.RaiseNotificationEvent(
AutomationNotificationKind.ActionCompleted,
AutomationNotificationProcessing.ImportantMostRecent,
loader.GetString("Shell_NavigationMenu_Announce_Collapse"),
"navigationMenuPaneClosed");
}
}
private void OOBEItem_Tapped(object sender, Microsoft.UI.Xaml.Input.TappedRoutedEventArgs e)
{
OpenOobeWindowCallback();
}
private async void FeedbackItem_Tapped(object sender, Microsoft.UI.Xaml.Input.TappedRoutedEventArgs e)
{
await Launcher.LaunchUriAsync(new Uri("https://aka.ms/powerToysGiveFeedback"));
}
private void NavigationView_SelectionChanged(NavigationView sender, NavigationViewSelectionChangedEventArgs args)
{
NavigationViewItem selectedItem = args.SelectedItem as NavigationViewItem;
if (selectedItem != null)
{
Type pageType = selectedItem.GetValue(NavHelper.NavigateToProperty) as Type;
NavigationService.Navigate(pageType);
}
}
private void ReceiveMessage(JsonObject json)
{
if (json != null)
{
if (json.ToString().StartsWith("{\"ShowYourself\":"))
{
if (json.ToString().EndsWith("\"flyout\"}"))
{
OpenFlyoutCallback();
}
else if (json.ToString().EndsWith("\"main_page\"}"))
{
OpenMainWindowCallback();
}
}
}
}
internal static void EnsurePageIsSelected()
{
NavigationService.EnsurePageIsSelected(typeof(GeneralPage));
}
}
}