mirror of
https://github.com/microsoft/PowerToys.git
synced 2026-02-24 04:00:02 +01:00
Add non-updating mode for Crop-And-Lock (#40720)
<!-- 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 Adds a "screenshot" mode to Crop And Lock, which allows creating a window showing a freezed snapshot of the original window. <!-- Please review the items on the PR checklist before submitting--> ## PR Checklist - [x] **Closes:** #31799, #33071 (also requested in the already closed duplicate issues #28633, #33812, #37337, ) - [ ] **Communication:** I've discussed this with core contributors already. If the work hasn't been agreed, this work might be rejected - [x] **Tests:** Added/updated and all pass (crop-and-lock utility doesn't have any tests) - [x] **Localization:** All end-user-facing strings can be localized - [x] **Dev docs:** Added/updated - [x] **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) - [x] **Documentation updated:** https://github.com/MicrosoftDocs/windows-dev-docs/pull/5528 <!-- 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 was asked why this feature is needed at all, because it could be done with snipping tool and just AoT that window as well. While this is true, PowerToys goal always was to improve and speed up workflows. Instead of capturing the screenshot, opening it, and then apply "Crop and Lock" or "Always on Top" on the screenshots window, this PR aims to provide this functionality in a single step. Example use cases: - _when I want to compare between two situations like previous output result and current output result._ (#31799) - _Allow cropping a section of a large code file (say top while working at the bottom) as reference while working elsewhere in the file._ (#33071) - _Can be useful for the work in the same document, like excel or word where you are actively checking the data from the same document._ (#28633) - _In lot's of older applications, if you need to get some information or data from one dialog do another, but because of dialog modality it's not possible to have both windows open at the same time._ (#33812) - _nowadays quite a lot is happening inside the browser. Quite often, I want to keep a small portion of the current website visible and switch to e.g. the writing tool also running in a different tab in the same browser window._ (#31799) I've used win+ctrl+shift+s as the default activation shortcut, as it's not yet used by other powertoys utilities, has similarity with the normal win+shift+s shortcut hotkey and is consistent with the other Crop and Lock shortcuts win+ctrl+shift+r (Reparent Mode) and win+ctrl+shift+t (Thumbnail Mode). <!-- Describe how you validated the behavior. Add automated tests wherever possible, but list manual validation steps taken as well --> ## Validation Steps Performed Compatibility tested manually with a large set of applications I have installed on my computer. However, automated tests don't really make sense as there is not much business logic which could be tested. --------- Co-authored-by: Niels Laute <niels.laute@live.nl> Co-authored-by: vanzue <vanzue@outlook.com>
This commit is contained in:
@@ -4,6 +4,7 @@
|
||||
|
||||
using System;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.CommandPalette.Extensions.Toolkit;
|
||||
using PowerToys.Interop;
|
||||
|
||||
@@ -21,15 +22,20 @@ internal sealed partial class CropAndLockReparentCommand : InvokableCommand
|
||||
|
||||
public override CommandResult Invoke()
|
||||
{
|
||||
try
|
||||
Task.Run(async () =>
|
||||
{
|
||||
using var evt = new EventWaitHandle(false, EventResetMode.AutoReset, Constants.CropAndLockReparentEvent());
|
||||
evt.Set();
|
||||
return CommandResult.Dismiss();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return CommandResult.ShowToast($"Failed to start Crop and Lock (Reparent): {ex.Message}");
|
||||
}
|
||||
await Task.Delay(500);
|
||||
try
|
||||
{
|
||||
using var evt = new EventWaitHandle(false, EventResetMode.AutoReset, Constants.CropAndLockReparentEvent());
|
||||
evt.Set();
|
||||
}
|
||||
catch
|
||||
{
|
||||
// Ignore errors after dismissing
|
||||
}
|
||||
});
|
||||
|
||||
return CommandResult.Dismiss();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
// 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.
|
||||
|
||||
using System;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.CommandPalette.Extensions.Toolkit;
|
||||
using PowerToys.Interop;
|
||||
|
||||
namespace PowerToysExtension.Commands;
|
||||
|
||||
/// <summary>
|
||||
/// Triggers Crop and Lock screenshot mode via the shared event.
|
||||
/// </summary>
|
||||
internal sealed partial class CropAndLockScreenshotCommand : InvokableCommand
|
||||
{
|
||||
public CropAndLockScreenshotCommand()
|
||||
{
|
||||
Name = "Crop and Lock (Screenshot)";
|
||||
}
|
||||
|
||||
public override CommandResult Invoke()
|
||||
{
|
||||
Task.Run(async () =>
|
||||
{
|
||||
await Task.Delay(500);
|
||||
try
|
||||
{
|
||||
using var evt = new EventWaitHandle(false, EventResetMode.AutoReset, Constants.CropAndLockScreenshotEvent());
|
||||
evt.Set();
|
||||
}
|
||||
catch
|
||||
{
|
||||
// Ignore errors after dismissing
|
||||
}
|
||||
});
|
||||
|
||||
return CommandResult.Dismiss();
|
||||
}
|
||||
}
|
||||
@@ -4,6 +4,7 @@
|
||||
|
||||
using System;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.CommandPalette.Extensions.Toolkit;
|
||||
using PowerToys.Interop;
|
||||
|
||||
@@ -21,15 +22,20 @@ internal sealed partial class CropAndLockThumbnailCommand : InvokableCommand
|
||||
|
||||
public override CommandResult Invoke()
|
||||
{
|
||||
try
|
||||
Task.Run(async () =>
|
||||
{
|
||||
using var evt = new EventWaitHandle(false, EventResetMode.AutoReset, Constants.CropAndLockThumbnailEvent());
|
||||
evt.Set();
|
||||
return CommandResult.Dismiss();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return CommandResult.ShowToast($"Failed to start Crop and Lock (Thumbnail): {ex.Message}");
|
||||
}
|
||||
await Task.Delay(500);
|
||||
try
|
||||
{
|
||||
using var evt = new EventWaitHandle(false, EventResetMode.AutoReset, Constants.CropAndLockThumbnailEvent());
|
||||
evt.Set();
|
||||
}
|
||||
catch
|
||||
{
|
||||
// Ignore errors after dismissing
|
||||
}
|
||||
});
|
||||
|
||||
return CommandResult.Dismiss();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -34,6 +34,13 @@ internal sealed class CropAndLockModuleCommandProvider : ModuleCommandProvider
|
||||
Subtitle = Resources.CropAndLock_Thumbnail_Subtitle,
|
||||
Icon = icon,
|
||||
};
|
||||
|
||||
yield return new ListItem(new CropAndLockScreenshotCommand())
|
||||
{
|
||||
Title = Resources.CropAndLock_Screenshot_Title,
|
||||
Subtitle = Resources.CropAndLock_Screenshot_Subtitle,
|
||||
Icon = icon,
|
||||
};
|
||||
}
|
||||
|
||||
yield return new ListItem(new OpenInSettingsCommand(module, title))
|
||||
|
||||
@@ -375,6 +375,24 @@ namespace PowerToysExtension.Properties {
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Crop and Lock (Screenshot).
|
||||
/// </summary>
|
||||
internal static string CropAndLock_Screenshot_Title {
|
||||
get {
|
||||
return ResourceManager.GetString("CropAndLock_Screenshot_Title", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Create a cropped screenshot window.
|
||||
/// </summary>
|
||||
internal static string CropAndLock_Screenshot_Subtitle {
|
||||
get {
|
||||
return ResourceManager.GetString("CropAndLock_Screenshot_Subtitle", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Launch Environment Variables editor.
|
||||
/// </summary>
|
||||
|
||||
@@ -260,6 +260,12 @@
|
||||
<data name="CropAndLock_Thumbnail_Subtitle" xml:space="preserve">
|
||||
<value>Create a cropped thumbnail window</value>
|
||||
</data>
|
||||
<data name="CropAndLock_Screenshot_Title" xml:space="preserve">
|
||||
<value>Crop and Lock (Screenshot)</value>
|
||||
</data>
|
||||
<data name="CropAndLock_Screenshot_Subtitle" xml:space="preserve">
|
||||
<value>Create a cropped screenshot window</value>
|
||||
</data>
|
||||
<data name="CropAndLock_Settings_Subtitle" xml:space="preserve">
|
||||
<value>Open Crop and Lock settings</value>
|
||||
</data>
|
||||
|
||||
Reference in New Issue
Block a user