mirror of
https://github.com/microsoft/PowerToys.git
synced 2025-12-15 19:27:56 +01:00
<!-- 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)? --> <img width="629" height="767" alt="image" src="https://github.com/user-attachments/assets/bc093640-db9d-4bc8-bc33-53729e692850" /> ## Summary of the Pull Request This is a PR for issue **#42260**. It targets **CmdPal’s WindowWalker** and changes the icon retrieval to use **SendMessage** to obtain the window’s actual icon, instead of using the **process icon**. To support this, I added a new configuration option. <img width="400" height="401" alt="image" src="https://github.com/user-attachments/assets/1a2d97a8-ff95-40b0-be42-746c2b1409d4" /> <!-- Please review the items on the PR checklist before submitting--> ## PR Checklist - [ ] Closes: #42260 - [ ] **Communication:** @jiripolasek - [ ] **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 Actully, The `ThumbnailHelper` already contains code that converts an `IntPtr` `hIcon` into an `IRandomAccessStream`, as shown below: ``` private static MemoryStream GetMemoryStreamFromIcon(IntPtr hIcon) { var memoryStream = new MemoryStream(); // Ensure disposing the icon before freeing the handle using (var icon = Icon.FromHandle(hIcon)) { icon.ToBitmap().Save(memoryStream, System.Drawing.Imaging.ImageFormat.Png); } // Clean up the unmanaged handle without risking a use-after-free. NativeMethods.DestroyIcon(hIcon); memoryStream.Position = 0; return memoryStream; } private static async Task<IRandomAccessStream?> FromHIconToStream(IntPtr hIcon) { var stream = new InMemoryRandomAccessStream(); using var memoryStream = GetMemoryStreamFromIcon(hIcon); // this will DestroyIcon hIcon using var outputStream = stream.GetOutputStreamAt(0); using var dataWriter = new DataWriter(outputStream); dataWriter.WriteBytes(memoryStream.ToArray()); await dataWriter.StoreAsync(); await dataWriter.FlushAsync(); return stream; } ``` Without modifying (or using) this code, I implemented the almost same logic directly in `SwitchToWindowCommand` (calling the async code with `Wait` to block synchronously). The reasons are: 1. I wanted to limit changes to the **WindowWalker** project area. I don’t expect other extensions to need this behavior. 2. Because this is resource-related work, exposing a public helper that pulls memory from an `hIcon` pointer seems risky—especially in a class like `ThumbnailHelper`. Therefore, I implemented behavior that is nearly identical to the snippet above. I did use `using`/`Dispose` where appropriate, but the `InMemoryRandomAccessStream` created for `IconInfo.FromStream` appears to use internal referencing; disposing it would be incorrect. For that reason I didn’t wrap it in a `using`. I’m not entirely sure whether GC will handle this cleanly. However, based on the implementation of `FromStream` itself and its usage elsewhere (e.g., in `ThumbnailHelper`), this seems to be the correct usage pattern, though I’m not entirely sure. <!-- Describe how you validated the behavior. Add automated tests wherever possible, but list manual validation steps taken as well --> ## Validation Steps Performed --------- Co-authored-by: Jiří Polášek <me@jiripolasek.com>
check-spelling/check-spelling configuration
| File | Purpose | Format | Info |
|---|---|---|---|
| allow.txt | Add words to the dictionary | one word per line (only letters and 's allowed) |
allow |
| reject.txt | Remove words from the dictionary (after allow) | grep pattern matching whole dictionary words | reject |
| excludes.txt | Files to ignore entirely | perl regular expression | excludes |
| only.txt | Only check matching files (applied after excludes) | perl regular expression | only |
| patterns.txt | Patterns to ignore from checked lines | perl regular expression (order matters, first match wins) | patterns |
| candidate.patterns | Patterns that might be worth adding to patterns.txt | perl regular expression with optional comment block introductions (all matches will be suggested) | candidates |
| line_forbidden.patterns | Patterns to flag in checked lines | perl regular expression (order matters, first match wins) | patterns |
| expect.txt | Expected words that aren't in the dictionary | one word per line (sorted, alphabetically) | expect |
| advice.md | Supplement for GitHub comment when unrecognized words are found | GitHub Markdown | advice |
Note: you can replace any of these files with a directory by the same name (minus the suffix) and then include multiple files inside that directory (with that suffix) to merge multiple files together.