Files
PowerToys/src/settings-ui/Settings.UI/SettingsXAML/Views/AlwaysOnTopPage.xaml
Kai Tao 21f06b8bd0 Always On Top: The opacity should be able to configure the hotkey individually (#46410)
<!-- 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
This pull request adds support for customizing the hotkeys used to
increase and decrease the opacity of pinned windows in the Always On Top
module.
Previously, these shortcuts were hardcoded to use the same modifiers as
the main pin hotkey.

With these changes, users can now independently configure the increase
and decrease opacity shortcuts via the settings UI, and the backend has
been updated to respect and store these new settings.

Another change: If window is not Always On Topped, the opacity change
take no effect, so we should not intercept, we should pass through to
minimize the impact.

<!-- Please review the items on the PR checklist before submitting-->
## PR Checklist

- [X] Closes: #46391, #46387
<!-- - [ ] Closes: #yyy (add separate lines for additional resolved
issues) -->
- [ ] **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

<!-- Describe how you validated the behavior. Add automated tests
wherever possible, but list manual validation steps taken as well -->
## Validation Steps Performed
<img width="1184" height="351" alt="image"
src="https://github.com/user-attachments/assets/5d20ffae-9f0c-4ce3-9d85-2ba1efea6301"
/>

<img width="336" height="244" alt="image"
src="https://github.com/user-attachments/assets/a78cc4a3-9eb3-49f1-bbb9-d6db37554e53"
/>

Verified locally that transparency hotkey will not intercept the normal
hotkey in window if Always on top not enabled

---------

Co-authored-by: Niels Laute <niels.laute@live.nl>
2026-03-24 14:02:36 -04:00

143 lines
9.7 KiB
XML

<local:NavigablePage
x:Class="Microsoft.PowerToys.Settings.UI.Views.AlwaysOnTopPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:controls="using:Microsoft.PowerToys.Settings.UI.Controls"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="using:Microsoft.PowerToys.Settings.UI.Helpers"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:ptcontrols="using:Microsoft.PowerToys.Common.UI.Controls"
xmlns:tkcontrols="using:CommunityToolkit.WinUI.Controls"
xmlns:ui="using:CommunityToolkit.WinUI"
AutomationProperties.LandmarkType="Main"
mc:Ignorable="d">
<local:NavigablePage.Resources />
<controls:SettingsPageControl
x:Uid="AlwaysOnTop"
IsTabStop="False"
ModuleImageSource="ms-appx:///Assets/Settings/Modules/AlwaysOnTop.png">
<controls:SettingsPageControl.ModuleContent>
<StackPanel ChildrenTransitions="{StaticResource SettingsCardsAnimations}" Orientation="Vertical">
<controls:GPOInfoControl ShowWarning="{x:Bind ViewModel.IsEnabledGpoConfigured, Mode=OneWay}">
<tkcontrols:SettingsCard
Name="AlwaysOnTopEnableToggleControlHeaderText"
x:Uid="AlwaysOnTop_EnableToggleControl_HeaderText"
HeaderIcon="{ui:BitmapIcon Source=/Assets/Settings/Icons/AlwaysOnTop.png}">
<ToggleSwitch x:Uid="ToggleSwitch" IsOn="{x:Bind ViewModel.IsEnabled, Mode=TwoWay}" />
</tkcontrols:SettingsCard>
</controls:GPOInfoControl>
<controls:SettingsGroup x:Uid="AlwaysOnTop_Activation_GroupSettings" IsEnabled="{x:Bind ViewModel.IsEnabled, Mode=OneWay}">
<tkcontrols:SettingsExpander
Name="AlwaysOnTopActivationShortcut"
x:Uid="AlwaysOnTop_ActivationShortcut"
HeaderIcon="{ui:FontIcon Glyph=&#xEDA7;}"
IsExpanded="True">
<controls:ShortcutControl HotkeySettings="{x:Bind Path=ViewModel.Hotkey, Mode=TwoWay}" />
<tkcontrols:SettingsExpander.Items>
<!-- HACK: For some weird reason, a ShortcutControl does not work correctly if it's the first or last item in the expander, so we add an invisible card. -->
<tkcontrols:SettingsCard Visibility="Collapsed" />
<tkcontrols:SettingsCard x:Uid="AlwaysOnTop_IncreaseOpacityShortcut">
<controls:ShortcutControl HotkeySettings="{x:Bind Path=ViewModel.IncreaseOpacityHotkey, Mode=TwoWay}" />
</tkcontrols:SettingsCard>
<tkcontrols:SettingsCard x:Uid="AlwaysOnTop_DecreaseOpacityShortcut">
<controls:ShortcutControl HotkeySettings="{x:Bind Path=ViewModel.DecreaseOpacityHotkey, Mode=TwoWay}" />
</tkcontrols:SettingsCard>
<tkcontrols:SettingsCard ContentAlignment="Left">
<CheckBox x:Uid="AlwaysOnTop_GameMode" IsChecked="{x:Bind ViewModel.DoNotActivateOnGameMode, Mode=TwoWay}" />
</tkcontrols:SettingsCard>
<tkcontrols:SettingsCard ContentAlignment="Left">
<ptcontrols:CheckBoxWithDescriptionControl x:Uid="AlwaysOnTop_ContextMenuEnabled" IsChecked="{x:Bind ViewModel.ShowInSystemMenu, Mode=TwoWay}" />
</tkcontrols:SettingsCard>
</tkcontrols:SettingsExpander.Items>
</tkcontrols:SettingsExpander>
</controls:SettingsGroup>
<controls:SettingsGroup x:Uid="AlwaysOnTop_Behavior_GroupSettings" IsEnabled="{x:Bind ViewModel.IsEnabled, Mode=OneWay}">
<tkcontrols:SettingsExpander
Name="AlwaysOnTopFrameEnabled"
x:Uid="AlwaysOnTop_FrameEnabled"
HeaderIcon="{ui:FontIcon Glyph=&#xEB3C;}"
IsExpanded="True">
<ToggleSwitch x:Uid="ToggleSwitch" IsOn="{x:Bind ViewModel.FrameEnabled, Mode=TwoWay}" />
<tkcontrols:SettingsExpander.Items>
<tkcontrols:SettingsCard
Name="AlwaysOnTopFrameColorMode"
x:Uid="AlwaysOnTop_FrameColor_Mode"
IsEnabled="{x:Bind ViewModel.FrameEnabled, Mode=OneWay}">
<ComboBox MinWidth="{StaticResource SettingActionControlMinWidth}" SelectedIndex="{x:Bind ViewModel.FrameAccentColor, Mode=TwoWay, Converter={StaticResource BoolToComboBoxIndexConverter}}">
<ComboBoxItem x:Uid="AlwaysOnTop_Radio_Custom_Color" />
<ComboBoxItem x:Uid="AlwaysOnTop_Radio_Windows_Default" />
</ComboBox>
</tkcontrols:SettingsCard>
<tkcontrols:SettingsCard
Name="AlwaysOnTopFrameColor"
x:Uid="AlwaysOnTop_FrameColor"
IsEnabled="{x:Bind ViewModel.FrameEnabled, Mode=OneWay}"
Visibility="{x:Bind ViewModel.FrameAccentColor, Mode=OneWay, Converter={StaticResource ReverseBoolToVisibilityConverter}}">
<controls:ColorPickerButton SelectedColor="{x:Bind Path=ViewModel.FrameColor, Mode=TwoWay}" />
</tkcontrols:SettingsCard>
<tkcontrols:SettingsCard
Name="AlwaysOnTopFrameOpacity"
x:Uid="AlwaysOnTop_FrameOpacity"
IsEnabled="{x:Bind ViewModel.FrameEnabled, Mode=OneWay}">
<Slider
MinWidth="{StaticResource SettingActionControlMinWidth}"
Maximum="100"
Minimum="0"
Value="{x:Bind ViewModel.FrameOpacity, Mode=TwoWay}" />
</tkcontrols:SettingsCard>
<tkcontrols:SettingsCard
Name="AlwaysOnTopFrameThickness"
x:Uid="AlwaysOnTop_FrameThickness"
IsEnabled="{x:Bind ViewModel.FrameEnabled, Mode=OneWay}">
<Slider
MinWidth="{StaticResource SettingActionControlMinWidth}"
LargeChange="5"
Maximum="30"
Minimum="1"
SmallChange="1"
Value="{x:Bind ViewModel.FrameThickness, Mode=TwoWay}" />
</tkcontrols:SettingsCard>
<tkcontrols:SettingsCard ContentAlignment="Left" Visibility="{x:Bind ViewModel.Windows11, Mode=OneWay, Converter={StaticResource BoolToVisibilityConverter}}">
<CheckBox x:Uid="AlwaysOnTop_RoundCorners" IsChecked="{x:Bind ViewModel.RoundCornersEnabled, Mode=TwoWay}" />
</tkcontrols:SettingsCard>
</tkcontrols:SettingsExpander.Items>
</tkcontrols:SettingsExpander>
<tkcontrols:SettingsCard x:Uid="AlwaysOnTop_Sound" HeaderIcon="{ui:FontIcon Glyph=&#xE7F3;}">
<ToggleSwitch IsOn="{x:Bind ViewModel.SoundEnabled, Mode=TwoWay}" />
</tkcontrols:SettingsCard>
</controls:SettingsGroup>
<controls:SettingsGroup x:Uid="ExcludedApps" IsEnabled="{x:Bind ViewModel.IsEnabled, Mode=OneWay}">
<tkcontrols:SettingsExpander
Name="AlwaysOnTopExcludedApps"
x:Uid="AlwaysOnTop_ExcludedApps"
HeaderIcon="{ui:FontIcon Glyph=&#xECE4;}"
IsExpanded="True">
<tkcontrols:SettingsExpander.Items>
<tkcontrols:SettingsCard HorizontalContentAlignment="Stretch" ContentAlignment="Vertical">
<TextBox
x:Uid="AlwaysOnTop_ExcludedApps_TextBoxControl"
MinWidth="240"
MinHeight="160"
AcceptsReturn="True"
ScrollViewer.IsVerticalRailEnabled="True"
ScrollViewer.VerticalScrollBarVisibility="Visible"
ScrollViewer.VerticalScrollMode="Enabled"
Text="{x:Bind ViewModel.ExcludedApps, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
TextWrapping="Wrap" />
</tkcontrols:SettingsCard>
</tkcontrols:SettingsExpander.Items>
</tkcontrols:SettingsExpander>
</controls:SettingsGroup>
</StackPanel>
</controls:SettingsPageControl.ModuleContent>
<controls:SettingsPageControl.PrimaryLinks>
<controls:PageLink x:Uid="LearnMore_AlwaysOnTop" Link="https://aka.ms/PowerToysOverview_AlwaysOnTop" />
</controls:SettingsPageControl.PrimaryLinks>
</controls:SettingsPageControl>
</local:NavigablePage>