2021-03-02 20:56:37 +03:00
|
|
|
|
// 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.
|
|
|
|
|
|
|
2025-08-20 09:31:52 +08:00
|
|
|
|
using System.ComponentModel;
|
2024-10-24 22:04:32 +02:00
|
|
|
|
using global::PowerToys.GPOWrapper;
|
2025-08-20 09:31:52 +08:00
|
|
|
|
using Microsoft.PowerToys.Settings.UI.Helpers;
|
|
|
|
|
|
using Microsoft.PowerToys.Settings.UI.Library;
|
|
|
|
|
|
using Microsoft.PowerToys.Settings.UI.Library.HotkeyConflicts;
|
|
|
|
|
|
using Microsoft.PowerToys.Settings.UI.Library.Interfaces;
|
2021-03-02 20:56:37 +03:00
|
|
|
|
using Microsoft.PowerToys.Settings.UI.OOBE.Enums;
|
|
|
|
|
|
using Microsoft.PowerToys.Settings.UI.OOBE.ViewModel;
|
2025-08-20 09:31:52 +08:00
|
|
|
|
using Microsoft.PowerToys.Settings.UI.Services;
|
|
|
|
|
|
using Microsoft.PowerToys.Settings.UI.SettingsXAML.Controls.Dashboard;
|
2021-03-02 20:56:37 +03:00
|
|
|
|
using Microsoft.PowerToys.Settings.UI.Views;
|
2024-10-24 22:04:32 +02:00
|
|
|
|
using Microsoft.PowerToys.Telemetry;
|
2025-08-20 09:31:52 +08:00
|
|
|
|
using Microsoft.UI;
|
2022-04-19 22:00:28 +02:00
|
|
|
|
using Microsoft.UI.Xaml.Controls;
|
2025-08-20 09:31:52 +08:00
|
|
|
|
using Microsoft.UI.Xaml.Media;
|
2022-04-19 22:00:28 +02:00
|
|
|
|
using Microsoft.UI.Xaml.Navigation;
|
2021-03-02 20:56:37 +03:00
|
|
|
|
|
|
|
|
|
|
namespace Microsoft.PowerToys.Settings.UI.OOBE.Views
|
|
|
|
|
|
{
|
2025-08-20 09:31:52 +08:00
|
|
|
|
public sealed partial class OobeOverview : Page, INotifyPropertyChanged
|
2021-03-02 20:56:37 +03:00
|
|
|
|
{
|
|
|
|
|
|
public OobePowerToysModule ViewModel { get; set; }
|
|
|
|
|
|
|
2024-10-24 22:04:32 +02:00
|
|
|
|
private bool _enableDataDiagnostics;
|
2025-08-20 09:31:52 +08:00
|
|
|
|
private AllHotkeyConflictsData _allHotkeyConflictsData = new AllHotkeyConflictsData();
|
|
|
|
|
|
private Windows.ApplicationModel.Resources.ResourceLoader resourceLoader = Helpers.ResourceLoaderInstance.ResourceLoader;
|
2024-10-24 22:04:32 +02:00
|
|
|
|
|
|
|
|
|
|
public bool EnableDataDiagnostics
|
|
|
|
|
|
{
|
|
|
|
|
|
get
|
|
|
|
|
|
{
|
|
|
|
|
|
return _enableDataDiagnostics;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
set
|
|
|
|
|
|
{
|
|
|
|
|
|
if (_enableDataDiagnostics != value)
|
|
|
|
|
|
{
|
|
|
|
|
|
_enableDataDiagnostics = value;
|
|
|
|
|
|
|
|
|
|
|
|
DataDiagnosticsSettings.SetEnabledValue(_enableDataDiagnostics);
|
|
|
|
|
|
|
|
|
|
|
|
this.DispatcherQueue.TryEnqueue(Microsoft.UI.Dispatching.DispatcherQueuePriority.Normal, () =>
|
|
|
|
|
|
{
|
|
|
|
|
|
ShellPage.ShellHandler?.SignalGeneralDataUpdate();
|
|
|
|
|
|
});
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-08-20 09:31:52 +08:00
|
|
|
|
public AllHotkeyConflictsData AllHotkeyConflictsData
|
|
|
|
|
|
{
|
|
|
|
|
|
get => _allHotkeyConflictsData;
|
|
|
|
|
|
set
|
|
|
|
|
|
{
|
|
|
|
|
|
if (_allHotkeyConflictsData != value)
|
|
|
|
|
|
{
|
|
|
|
|
|
_allHotkeyConflictsData = value;
|
|
|
|
|
|
OnPropertyChanged(nameof(AllHotkeyConflictsData));
|
|
|
|
|
|
OnPropertyChanged(nameof(ConflictCount));
|
|
|
|
|
|
OnPropertyChanged(nameof(ConflictText));
|
|
|
|
|
|
OnPropertyChanged(nameof(ConflictDescription));
|
|
|
|
|
|
OnPropertyChanged(nameof(HasConflicts));
|
|
|
|
|
|
OnPropertyChanged(nameof(IconGlyph));
|
|
|
|
|
|
OnPropertyChanged(nameof(IconForeground));
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public int ConflictCount
|
|
|
|
|
|
{
|
|
|
|
|
|
get
|
|
|
|
|
|
{
|
|
|
|
|
|
if (AllHotkeyConflictsData == null)
|
|
|
|
|
|
{
|
|
|
|
|
|
return 0;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
int count = 0;
|
|
|
|
|
|
if (AllHotkeyConflictsData.InAppConflicts != null)
|
|
|
|
|
|
{
|
|
|
|
|
|
count += AllHotkeyConflictsData.InAppConflicts.Count;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (AllHotkeyConflictsData.SystemConflicts != null)
|
|
|
|
|
|
{
|
|
|
|
|
|
count += AllHotkeyConflictsData.SystemConflicts.Count;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return count;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public string ConflictText
|
|
|
|
|
|
{
|
|
|
|
|
|
get
|
|
|
|
|
|
{
|
|
|
|
|
|
var count = ConflictCount;
|
|
|
|
|
|
if (count == 0)
|
|
|
|
|
|
{
|
|
|
|
|
|
// Return no-conflict message
|
|
|
|
|
|
try
|
|
|
|
|
|
{
|
|
|
|
|
|
return resourceLoader.GetString("ShortcutConflictControl_NoConflictsFound");
|
|
|
|
|
|
}
|
|
|
|
|
|
catch
|
|
|
|
|
|
{
|
|
|
|
|
|
return "No conflicts found";
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
else if (count == 1)
|
|
|
|
|
|
{
|
|
|
|
|
|
// Try to get localized string
|
|
|
|
|
|
try
|
|
|
|
|
|
{
|
|
|
|
|
|
return resourceLoader.GetString("ShortcutConflictControl_SingleConflictFound");
|
|
|
|
|
|
}
|
|
|
|
|
|
catch
|
|
|
|
|
|
{
|
|
|
|
|
|
return "1 shortcut conflict";
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
// Try to get localized string
|
|
|
|
|
|
try
|
|
|
|
|
|
{
|
|
|
|
|
|
var template = resourceLoader.GetString("ShortcutConflictControl_MultipleConflictsFound");
|
|
|
|
|
|
return string.Format(System.Globalization.CultureInfo.CurrentCulture, template, count);
|
|
|
|
|
|
}
|
|
|
|
|
|
catch
|
|
|
|
|
|
{
|
|
|
|
|
|
return $"{count} shortcut conflicts";
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public string ConflictDescription
|
|
|
|
|
|
{
|
|
|
|
|
|
get
|
|
|
|
|
|
{
|
|
|
|
|
|
var count = ConflictCount;
|
|
|
|
|
|
if (count == 0)
|
|
|
|
|
|
{
|
|
|
|
|
|
// Return no-conflict description
|
|
|
|
|
|
try
|
|
|
|
|
|
{
|
|
|
|
|
|
return resourceLoader.GetString("ShortcutConflictWindow_NoConflictsDescription");
|
|
|
|
|
|
}
|
|
|
|
|
|
catch
|
|
|
|
|
|
{
|
|
|
|
|
|
return "All shortcuts function correctly";
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
// Return conflict description
|
|
|
|
|
|
try
|
|
|
|
|
|
{
|
|
|
|
|
|
return resourceLoader.GetString("Oobe_Overview_Hotkey_Conflict_Card_Description");
|
|
|
|
|
|
}
|
|
|
|
|
|
catch
|
|
|
|
|
|
{
|
|
|
|
|
|
return "Shortcuts configured by PowerToys are conflicting";
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public bool HasConflicts => ConflictCount > 0;
|
|
|
|
|
|
|
|
|
|
|
|
public string IconGlyph => HasConflicts ? "\uE814" : "\uE73E";
|
|
|
|
|
|
|
|
|
|
|
|
public SolidColorBrush IconForeground
|
|
|
|
|
|
{
|
|
|
|
|
|
get
|
|
|
|
|
|
{
|
|
|
|
|
|
if (HasConflicts)
|
|
|
|
|
|
{
|
|
|
|
|
|
// Red color for conflicts
|
|
|
|
|
|
return (SolidColorBrush)App.Current.Resources["SystemFillColorCriticalBrush"];
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
// Green color for no conflicts
|
|
|
|
|
|
return (SolidColorBrush)App.Current.Resources["SystemFillColorSuccessBrush"];
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2024-10-24 22:04:32 +02:00
|
|
|
|
public bool ShowDataDiagnosticsSetting => GetIsDataDiagnosticsInfoBarEnabled();
|
|
|
|
|
|
|
2025-08-20 09:31:52 +08:00
|
|
|
|
public event PropertyChangedEventHandler PropertyChanged;
|
|
|
|
|
|
|
2024-10-24 22:04:32 +02:00
|
|
|
|
private bool GetIsDataDiagnosticsInfoBarEnabled()
|
|
|
|
|
|
{
|
|
|
|
|
|
var isDataDiagnosticsGpoDisallowed = GPOWrapper.GetAllowDataDiagnosticsValue() == GpoRuleConfigured.Disabled;
|
|
|
|
|
|
|
|
|
|
|
|
return !isDataDiagnosticsGpoDisallowed;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2021-03-02 20:56:37 +03:00
|
|
|
|
public OobeOverview()
|
|
|
|
|
|
{
|
|
|
|
|
|
this.InitializeComponent();
|
2024-10-24 22:04:32 +02:00
|
|
|
|
|
|
|
|
|
|
_enableDataDiagnostics = DataDiagnosticsSettings.GetEnabledValue();
|
|
|
|
|
|
|
2022-04-19 22:00:28 +02:00
|
|
|
|
ViewModel = new OobePowerToysModule(OobeShellPage.OobeShellHandler.Modules[(int)PowerToysModules.Overview]);
|
2025-08-20 09:31:52 +08:00
|
|
|
|
DataContext = this;
|
|
|
|
|
|
|
|
|
|
|
|
// Subscribe to hotkey conflict updates
|
|
|
|
|
|
if (GlobalHotkeyConflictManager.Instance != null)
|
|
|
|
|
|
{
|
|
|
|
|
|
GlobalHotkeyConflictManager.Instance.ConflictsUpdated += OnConflictsUpdated;
|
|
|
|
|
|
GlobalHotkeyConflictManager.Instance.RequestAllConflicts();
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private void OnConflictsUpdated(object sender, AllHotkeyConflictsEventArgs e)
|
|
|
|
|
|
{
|
|
|
|
|
|
this.DispatcherQueue.TryEnqueue(Microsoft.UI.Dispatching.DispatcherQueuePriority.Normal, () =>
|
|
|
|
|
|
{
|
|
|
|
|
|
AllHotkeyConflictsData = e.Conflicts ?? new AllHotkeyConflictsData();
|
|
|
|
|
|
});
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private void OnPropertyChanged(string propertyName)
|
|
|
|
|
|
{
|
|
|
|
|
|
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
|
2021-03-02 20:56:37 +03:00
|
|
|
|
}
|
|
|
|
|
|
|
2022-04-19 22:00:28 +02:00
|
|
|
|
private void SettingsLaunchButton_Click(object sender, Microsoft.UI.Xaml.RoutedEventArgs e)
|
2021-03-02 20:56:37 +03:00
|
|
|
|
{
|
|
|
|
|
|
if (OobeShellPage.OpenMainWindowCallback != null)
|
|
|
|
|
|
{
|
[Settings]Adding a Dashboard Panel (#29023)
* Dashboard: modifying page content + adding SW version button.
* Visual tweaks and minor viewmodel changes
* Updated spacing
* Adding Settings icon
* Settiing the Dashboard page as the default one. Adding functionality to switch to settings pages from the Dashboard page. Localizing texts.
* fixing csproj file
* Reimplementing Active modules handling, showing only the active modules (and not having invisible inactive modules).
* Removing unneccessary binding
* Fix text wrapping
* Adding Registry previewer launch, adding activation mode for FindMyMouse and QuickAccent, modify File Locksmith description.
* Spell checker fix typo
* Adding GPO-blocked state, modifying buttons: adding description, icon.
* Modifying dashboard button layout
* Use SettingsCard instead of button
* Restructuring the dashboard panel
* Removing togglebuttons from the left panel. Showing only active modules. Adding key remappings (to KBM)
* Removing settings buttons, removing descriptions, icons from buttons. Add update of remapped keys, shortcuts.
* Refactoring dashboard
* Making list always visible and fixing scrolling behavior
* Adding background gradient to cards
* Removing keyboard manager's key mappings, minor changes in texts, fixing enabled state when GPO-enabled.
* Use ListView instead of ItemsRepeater
* Updates
* removing right panel with all modules. Extending "left" panel with toggleswitches, showing all modules.
* Separate lists
* Adding Flyout with key remappings for KBM module, adding IsLocked property, icons
* Visual tweaks
* Tweaks
* Fixing lock icon margin
* Minor fixes.
* Removing unused resources
* Make Dashboard default when coming from the OOBE General
* Removed the Previous, Next Layout buttons from FancyZones. Added activation information
---------
Co-authored-by: Niels Laute <niels.laute@live.nl>
2023-10-20 14:23:25 +02:00
|
|
|
|
OobeShellPage.OpenMainWindowCallback(typeof(DashboardPage));
|
2021-03-02 20:56:37 +03:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
ViewModel.LogOpeningSettingsEvent();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2024-10-24 22:04:32 +02:00
|
|
|
|
private void GeneralSettingsLaunchButton_Click(object sender, Microsoft.UI.Xaml.RoutedEventArgs e)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (OobeShellPage.OpenMainWindowCallback != null)
|
|
|
|
|
|
{
|
|
|
|
|
|
OobeShellPage.OpenMainWindowCallback(typeof(GeneralPage));
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
ViewModel.LogOpeningSettingsEvent();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-08-20 09:31:52 +08:00
|
|
|
|
private void ShortcutConflictBtn_Click(object sender, Microsoft.UI.Xaml.RoutedEventArgs e)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (AllHotkeyConflictsData == null || !HasConflicts)
|
|
|
|
|
|
{
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Create and show the shortcut conflict window
|
|
|
|
|
|
var conflictWindow = new ShortcutConflictWindow();
|
|
|
|
|
|
conflictWindow.Activate();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2021-03-02 20:56:37 +03:00
|
|
|
|
protected override void OnNavigatedTo(NavigationEventArgs e)
|
|
|
|
|
|
{
|
|
|
|
|
|
ViewModel.LogOpeningModuleEvent();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
protected override void OnNavigatedFrom(NavigationEventArgs e)
|
|
|
|
|
|
{
|
|
|
|
|
|
ViewModel.LogClosingModuleEvent();
|
2025-08-20 09:31:52 +08:00
|
|
|
|
|
|
|
|
|
|
// Unsubscribe from conflict updates when leaving the page
|
|
|
|
|
|
if (GlobalHotkeyConflictManager.Instance != null)
|
|
|
|
|
|
{
|
|
|
|
|
|
GlobalHotkeyConflictManager.Instance.ConflictsUpdated -= OnConflictsUpdated;
|
|
|
|
|
|
}
|
2021-03-02 20:56:37 +03:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|