Always on top: Add transparent support for on topped window (#44815)

<!-- 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
Transparency support (best-effort)
> Not every window can be made transparent. Transparency is applied on a
best-effort basis and depends on how the target app/window is built and
rendered.

## When it may not work
* Windows with special rendering pipelines (e.g., certain
hardware-accelerated / compositor-managed surfaces).
* Some tool/popup/owned windows where the foreground window isn’t the
actual surface being drawn.

## How it works (high-level)
* Resolve the best target window (preferring the top-level/root window
over transient children).
* Apply Windows’ standard layered-window alpha mechanism (per-window
opacity) to adjust transparency.
* When unpinned, Restore the original opacity/state when possible.

If transparency doesn’t change, it means the window doesn’t support this
mechanism in its current configuration.
<!-- Please review the items on the PR checklist before submitting-->
## PR Checklist

- [X] Closes: 
#43278 
#42929
#28773

<!-- - [ ] 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


https://github.com/user-attachments/assets/c97a87f2-3126-4e19-990f-8c684dbeb631

<img width="1119" height="426" alt="image"
src="https://github.com/user-attachments/assets/547671ee-81d3-4c94-8199-bf0c4b1b7760"
/>

---------

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
This commit is contained in:
Kai Tao
2026-01-29 13:48:27 +08:00
committed by GitHub
parent 4986915dae
commit 6d4f56cd83
10 changed files with 409 additions and 25 deletions

View File

@@ -5,6 +5,7 @@
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Text.Json;
using global::PowerToys.GPOWrapper;
@@ -133,6 +134,10 @@ namespace Microsoft.PowerToys.Settings.UI.ViewModels
Settings.Properties.Hotkey.Value = _hotkey;
NotifyPropertyChanged();
// Also notify that transparency keys have changed
OnPropertyChanged(nameof(IncreaseOpacityKeysList));
OnPropertyChanged(nameof(DecreaseOpacityKeysList));
// Using InvariantCulture as this is an IPC message
SendConfigMSG(
string.Format(
@@ -289,6 +294,62 @@ namespace Microsoft.PowerToys.Settings.UI.ViewModels
}
}
/// <summary>
/// Gets the keys list for increasing window opacity (modifier keys + "+").
/// </summary>
public List<object> IncreaseOpacityKeysList
{
get
{
var keys = GetModifierKeysList();
keys.Add("+");
return keys;
}
}
/// <summary>
/// Gets the keys list for decreasing window opacity (modifier keys + "-").
/// </summary>
public List<object> DecreaseOpacityKeysList
{
get
{
var keys = GetModifierKeysList();
keys.Add("-");
return keys;
}
}
/// <summary>
/// Gets only the modifier keys from the current hotkey setting.
/// </summary>
private List<object> GetModifierKeysList()
{
var modifierKeys = new List<object>();
if (_hotkey.Win)
{
modifierKeys.Add(92); // The Windows key
}
if (_hotkey.Ctrl)
{
modifierKeys.Add("Ctrl");
}
if (_hotkey.Alt)
{
modifierKeys.Add("Alt");
}
if (_hotkey.Shift)
{
modifierKeys.Add(16); // The Shift key
}
return modifierKeys;
}
public void NotifyPropertyChanged([CallerMemberName] string propertyName = null)
{
OnPropertyChanged(propertyName);