-
Notifications
You must be signed in to change notification settings - Fork 7.6k
[UX] New dashboard & refactored KeyVisual #40214
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
Eliminated the DashboardModuleKBMItem, its template, and associated logic from the dashboard. This simplifies the DashboardViewModel and DashboardPage.xaml by removing the display and dynamic updating of Keyboard Manager remappings.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
|
/azp run |
|
Azure Pipelines successfully started running 1 pipeline(s). |
This comment has been minimized.
This comment has been minimized.
|
There is one last a11y issue that will be fixed when this is merged and we update CommunityToolkit/Windows#702 |
src/settings-ui/Settings.UI/SettingsXAML/Controls/KeyVisual.xaml.cs
Outdated
Show resolved
Hide resolved
src/settings-ui/Settings.UI/SettingsXAML/Controls/Dashboard/ShortcutConflictControl.xaml
Show resolved
Hide resolved
src/settings-ui/Settings.UI/SettingsXAML/Controls/Dashboard/ShortcutConflictControl.xaml
Show resolved
Hide resolved
src/settings-ui/Settings.UI/SettingsXAML/Controls/Dashboard/ShortcutConflictControl.xaml.cs
Show resolved
Hide resolved
src/settings-ui/Settings.UI/SettingsXAML/Controls/SettingsPageControl/SettingsPageControl.xaml
Show resolved
Hide resolved
src/settings-ui/Settings.UI/SettingsXAML/Controls/KeyVisual.xaml.cs
Outdated
Show resolved
Hide resolved
src/settings-ui/Settings.UI/SettingsXAML/Controls/KeyVisual.xaml.cs
Outdated
Show resolved
Hide resolved
src/settings-ui/Settings.UI/SettingsXAML/Views/DashboardPage.xaml.cs
Outdated
Show resolved
Hide resolved
| IsOpen="True" | ||
| Severity="Informational" | ||
| Visibility="{x:Bind ViewModel.IsAnimationEnabledBySystem, Mode=OneWay, Converter={StaticResource BoolToInvertedVisibilityConverter}}"> | ||
| Visibility="{x:Bind ViewModel.IsAnimationEnabledBySystem, Mode=OneWay, Converter={StaticResource BoolToReverseVisibilityConverter}}"> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good catch. Same question on review.
src/settings-ui/Settings.UI/SettingsXAML/Controls/KeyVisual.xaml.cs
Outdated
Show resolved
Hide resolved
We had 2 issues with the refactoring of KeyVisual that happened in #40214: - We had little control over the pixel perfection of the Windows + text + glyph KeyVisual templates, which resulted into subpar vertical alignments. - When changing theme, the Windows key foreground brush was not updating. With this PR - a new control with dedicated templates is introduced; this allows us to have full control over the individual templates, and doing all of the styling in XAML vs in C#. - I've removed setting the accessible names because those should be set on the parent container, as Narrator is supposed to announce these shortcuts in its totality vs individual keys. - A new property `RenderKeyAsGlyph` has been introduced to render a key as an icon (to save space in certain scenarios) or to show the full text (default) <img width="133" height="147" alt="image" src="https://github.com/user-attachments/assets/66a342da-fdcf-4c97-80b6-93b9955ebdd3" /> <img width="242" height="58" alt="image" src="https://github.com/user-attachments/assets/0b41cfee-8a7d-409a-83b4-72d13e0b131c" />
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull Request Overview
This PR introduces a new dashboard UX design and refactors the KeyVisual component for better customization. The changes focus on improving the user experience by replacing the old module layout with an organized dashboard featuring separate sections for quick access actions and shortcuts overview, while also updating the KeyVisual control to use a more flexible style-based approach.
- New dashboard UX with organized sections for actions and shortcuts
- Refactored KeyVisual component to remove redundant properties and enable style-based customization
- Consolidated converters and updated resource references for consistency
Reviewed Changes
Copilot reviewed 36 out of 43 changed files in this pull request and generated 5 comments.
Show a summary per file
| File | Description |
|---|---|
| src/settings-ui/Settings.UI/ViewModels/DashboardViewModel.cs | Refactored to support new dashboard layout with separate collections for shortcuts and actions |
| src/settings-ui/Settings.UI/ViewModels/DashboardModuleItem.cs | Replaced complex KBM item with simpler activation item model |
| src/settings-ui/Settings.UI/SettingsXAML/Views/DashboardPage.xaml | Complete redesign of dashboard layout with card-based sections |
| src/settings-ui/Settings.UI/SettingsXAML/Controls/KeyVisual/* | Refactored KeyVisual control with new templating system and styles |
| src/settings-ui/Settings.UI/Strings/en-us/Resources.resw | Updated UI strings to match new dashboard terminology |
| var list = new List<DashboardModuleItem> | ||
| { | ||
| new DashboardModuleButtonItem() { ButtonTitle = resourceLoader.GetString("EnvironmentVariables_LaunchButtonControl/Header"), IsButtonDescriptionVisible = true, ButtonDescription = resourceLoader.GetString("EnvironmentVariables_LaunchButtonControl/Description"), ButtonGlyph = "\uEA37", ButtonClickHandler = EnvironmentVariablesLaunchClicked }, | ||
| new DashboardModuleButtonItem() { ButtonTitle = resourceLoader.GetString("EnvironmentVariables_LaunchButtonControl/Header"), IsButtonDescriptionVisible = true, ButtonDescription = resourceLoader.GetString("EnvironmentVariables_LaunchButtonControl/Description"), ButtonGlyph = "ms-appx:///Assets/Settings/Icons/EnvironmentVariables.png", ButtonClickHandler = EnvironmentVariablesLaunchClicked }, |
Copilot
AI
Aug 5, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This line is extremely long and difficult to read. Consider breaking it into multiple lines for better readability.
| new DashboardModuleButtonItem() { ButtonTitle = resourceLoader.GetString("EnvironmentVariables_LaunchButtonControl/Header"), IsButtonDescriptionVisible = true, ButtonDescription = resourceLoader.GetString("EnvironmentVariables_LaunchButtonControl/Description"), ButtonGlyph = "ms-appx:///Assets/Settings/Icons/EnvironmentVariables.png", ButtonClickHandler = EnvironmentVariablesLaunchClicked }, | |
| new DashboardModuleButtonItem() | |
| { | |
| ButtonTitle = resourceLoader.GetString("EnvironmentVariables_LaunchButtonControl/Header"), | |
| IsButtonDescriptionVisible = true, | |
| ButtonDescription = resourceLoader.GetString("EnvironmentVariables_LaunchButtonControl/Description"), | |
| ButtonGlyph = "ms-appx:///Assets/Settings/Icons/EnvironmentVariables.png", | |
| ButtonClickHandler = EnvironmentVariablesLaunchClicked | |
| }, |
| if (this != null) | ||
| { | ||
| if (IsInvalid) | ||
| { | ||
| VisualStateManager.GoToState(this, InvalidState, true); | ||
| } | ||
| else if (!IsEnabled) | ||
| { | ||
| VisualStateManager.GoToState(this, DisabledState, true); | ||
| } | ||
| else | ||
| { | ||
| VisualStateManager.GoToState(this, NormalState, true); | ||
| } | ||
| } |
Copilot
AI
Aug 5, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The condition 'if (this != null)' is redundant since 'this' can never be null within an instance method. This check should be removed.
| if (this != null) | |
| { | |
| if (IsInvalid) | |
| { | |
| VisualStateManager.GoToState(this, InvalidState, true); | |
| } | |
| else if (!IsEnabled) | |
| { | |
| VisualStateManager.GoToState(this, DisabledState, true); | |
| } | |
| else | |
| { | |
| VisualStateManager.GoToState(this, NormalState, true); | |
| } | |
| } | |
| if (IsInvalid) | |
| { | |
| VisualStateManager.GoToState(this, InvalidState, true); | |
| } | |
| else if (!IsEnabled) | |
| { | |
| VisualStateManager.GoToState(this, DisabledState, true); | |
| } | |
| else | |
| { | |
| VisualStateManager.GoToState(this, NormalState, true); | |
| } |
| } | ||
|
|
||
| private void Update() | ||
| { |
Copilot
AI
Aug 5, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The Update method checks if Content is null but doesn't handle the case where _keyPresenter is null, which could cause a NullReferenceException when trying to set properties on it.
| { | |
| { | |
| if (_keyPresenter == null) | |
| { | |
| return; | |
| } |
|
|
||
| public static readonly DependencyProperty AllowDisableProperty = DependencyProperty.Register("AllowDisable", typeof(bool), typeof(ShortcutControl), new PropertyMetadata(false, OnAllowDisableChanged)); | ||
|
|
||
| private static ResourceLoader resourceLoader = Helpers.ResourceLoaderInstance.ResourceLoader; |
Copilot
AI
Aug 5, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Static field should be readonly since it's never reassigned after initialization. Consider making it 'private static readonly ResourceLoader resourceLoader'.
| private static ResourceLoader resourceLoader = Helpers.ResourceLoaderInstance.ResourceLoader; | |
| private static readonly ResourceLoader resourceLoader = Helpers.ResourceLoaderInstance.ResourceLoader; |
| { | ||
| public sealed partial class CheckUpdateControl : UserControl | ||
| { | ||
| public bool UpdateAvailable { get; set; } |
Copilot
AI
Aug 5, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Property UpdateAvailable should be readonly since it's only set in the constructor. Consider using a private setter or making it a get-only property.
| public bool UpdateAvailable { get; set; } | |
| public bool UpdateAvailable { get; } |
<!-- Enter a brief description/summary of your PR here. What does it fix/what does it change/how was it tested (even manually, if necessary)? --> ## Summary of the Pull Request Fix a crash in settings page due to not found converter <!-- Please review the items on the PR checklist before submitting--> ## AI Summary This pull request makes a small update to the `MouseUtilsPage.xaml` file to use the correct resource for converting boolean values to visibility states in the UI. - Updated the `Visibility` binding on an `InfoBar` to use the `ReverseBoolToVisibilityConverter` instead of the incorrect `BoolToReverseVisibilityConverter` resource. ## PR Checklist - [ ] Closes: #xxx - [ ] **Communication:** I've discussed this with core contributors already. If the work hasn't been agreed, this work might be rejected - [ ] **Tests:** Added/updated and all pass - [ ] **Localization:** All end-user-facing strings can be localized - [ ] **Dev docs:** Added/updated - [ ] **New binaries:** Added on the required places - [ ] [JSON for signing](https://github.com/microsoft/PowerToys/blob/main/.pipelines/ESRPSigning_core.json) for new binaries - [ ] [WXS for installer](https://github.com/microsoft/PowerToys/blob/main/installer/PowerToysSetup/Product.wxs) for new binaries and localization folder - [ ] [YML for CI pipeline](https://github.com/microsoft/PowerToys/blob/main/.pipelines/ci/templates/build-powertoys-steps.yml) for new test projects - [ ] [YML for signed pipeline](https://github.com/microsoft/PowerToys/blob/main/.pipelines/release.yml) - [ ] **Documentation updated:** If checked, please file a pull request on [our docs repo](https://github.com/MicrosoftDocs/windows-uwp/tree/docs/hub/powertoys) and link it here: #xxx <!-- Provide a more detailed description of the PR, other things fixed, or any additional comments/features here --> ## Detailed Description of the Pull Request / Additional comments Regression caused by #40214 <!-- Describe how you validated the behavior. Add automated tests wherever possible, but list manual validation steps taken as well --> ## Validation Steps Performed <img width="1983" height="1072" alt="image" src="https://github.com/user-attachments/assets/13c806c3-e7af-4615-a649-6d58d8fe877b" />
<!-- Enter a brief description/summary of your PR here. What does it fix/what does it change/how was it tested (even manually, if necessary)? --> ## Summary of the Pull Request Fixed toggle switch not working issue. ## AI Summary This pull request refactors how `DashboardListItem` objects are created and added to collections in the `DashboardViewModel`. The main improvement is to separate the instantiation of each `DashboardListItem` from the assignment of its `EnabledChangedCallback` property, which is now set after the object is added to the relevant collection. This change improves clarity and may help prevent issues related to object initialization order. Refactoring of `DashboardListItem` creation and initialization: * In the `AddDashboardListItem` method, the `DashboardListItem` object is now created and added to `AllModules` before its `EnabledChangedCallback` property is set, instead of setting this property during object initialization. * In the `GetShortcutModules` method, both `ShortcutModules` and `ActionModules` collections now receive `DashboardListItem` objects that are instantiated first, added to the collection, and then have their `EnabledChangedCallback` property set. This replaces the previous pattern of setting the callback during object creation. [[1]](diffhunk://#diff-aea3404667e7a3de2750bf9ab7ee8ff5e717892caa68ee1de86713cf8e21b44cL123-R136) [[2]](diffhunk://#diff-aea3404667e7a3de2750bf9ab7ee8ff5e717892caa68ee1de86713cf8e21b44cL144-R159) * <!-- Please review the items on the PR checklist before submitting--> ## PR Checklist - [x] Closes: #41046 - [ ] **Communication:** I've discussed this with core contributors already. If the work hasn't been agreed, this work might be rejected - [ ] **Tests:** Added/updated and all pass - [ ] **Localization:** All end-user-facing strings can be localized - [ ] **Dev docs:** Added/updated - [ ] **New binaries:** Added on the required places - [ ] [JSON for signing](https://github.com/microsoft/PowerToys/blob/main/.pipelines/ESRPSigning_core.json) for new binaries - [ ] [WXS for installer](https://github.com/microsoft/PowerToys/blob/main/installer/PowerToysSetup/Product.wxs) for new binaries and localization folder - [ ] [YML for CI pipeline](https://github.com/microsoft/PowerToys/blob/main/.pipelines/ci/templates/build-powertoys-steps.yml) for new test projects - [ ] [YML for signed pipeline](https://github.com/microsoft/PowerToys/blob/main/.pipelines/release.yml) - [ ] **Documentation updated:** If checked, please file a pull request on [our docs repo](https://github.com/MicrosoftDocs/windows-uwp/tree/docs/hub/powertoys) and link it here: #xxx <!-- Provide a more detailed description of the PR, other things fixed, or any additional comments/features here --> ## Detailed Description of the Pull Request / Additional comments It is an regression from #40214 <!-- Describe how you validated the behavior. Add automated tests wherever possible, but list manual validation steps taken as well --> ## Validation Steps Performed --------- Signed-off-by: Shuai Yuan <[email protected]>
Summary of the Pull Request
New dashboard UX
Dashboard.mp4
Update available:

No update available:

Updated
KeyVisualandShortcutcontrolKeyVisualto remove redundant properties and UI elements, and using Styles for better customization.Other changes
App.xaml.cswith consistent naming..csto.xaml.cs) and moving those to theControlsroot folder vs. individual folders for a better overview.PR Checklist
Detailed Description of the Pull Request / Additional comments
Validation Steps Performed