2024-05-09 10:32:03 -04:00
|
|
|
|
// 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.
|
|
|
|
|
|
|
2025-11-05 16:13:55 +08:00
|
|
|
|
using System.Collections.Generic;
|
2024-05-09 10:32:03 -04:00
|
|
|
|
using System.Text.Json;
|
|
|
|
|
|
using System.Text.Json.Serialization;
|
2024-09-16 16:09:43 -04:00
|
|
|
|
|
2024-05-09 10:32:03 -04:00
|
|
|
|
using Settings.UI.Library.Attributes;
|
|
|
|
|
|
|
|
|
|
|
|
namespace Microsoft.PowerToys.Settings.UI.Library
|
|
|
|
|
|
{
|
|
|
|
|
|
public class AdvancedPasteProperties
|
|
|
|
|
|
{
|
|
|
|
|
|
public static readonly HotkeySettings DefaultAdvancedPasteUIShortcut = new HotkeySettings(true, false, false, true, 0x56); // Win+Shift+V
|
|
|
|
|
|
|
|
|
|
|
|
public static readonly HotkeySettings DefaultPasteAsPlainTextShortcut = new HotkeySettings(true, true, true, false, 0x56); // Ctrl+Win+Alt+V
|
|
|
|
|
|
|
|
|
|
|
|
public AdvancedPasteProperties()
|
|
|
|
|
|
{
|
|
|
|
|
|
AdvancedPasteUIShortcut = DefaultAdvancedPasteUIShortcut;
|
|
|
|
|
|
PasteAsPlainTextShortcut = DefaultPasteAsPlainTextShortcut;
|
|
|
|
|
|
PasteAsMarkdownShortcut = new();
|
|
|
|
|
|
PasteAsJsonShortcut = new();
|
2024-08-22 16:17:12 +02:00
|
|
|
|
CustomActions = new();
|
2024-10-18 15:34:09 +02:00
|
|
|
|
AdditionalActions = new();
|
2025-11-05 16:13:55 +08:00
|
|
|
|
IsAIEnabled = false;
|
2024-05-09 10:32:03 -04:00
|
|
|
|
ShowCustomPreview = true;
|
2024-06-24 16:03:46 +02:00
|
|
|
|
CloseAfterLosingFocus = false;
|
2025-11-13 10:18:13 +08:00
|
|
|
|
EnableClipboardPreview = true;
|
feat(advancedpaste): add auto-copy selection for custom action hotkeys (#44767)
<!-- 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
Boosting productivity #2x. Customer mentioned with Custom Action
(Shortcut trigger) "We should not need to do two keyboard actions to
finish this awesome AI data transformation, instead, just single
shortcut should do copy + advanced paste."
This pull request introduces a new feature to the Advanced Paste module
that allows users to automatically copy the current selection when
triggering a custom action hotkey. The changes include backend logic for
sending the copy command, updates to configuration and settings
management, and UI additions to expose this option to users.
### Feature Addition: Auto-Copy Selection for Custom Action Hotkeys
* Added a new boolean setting, `AutoCopySelectionForCustomActionHotkey`,
to both the backend (`dllmain.cpp`, `AdvancedPasteProperties.cs`) and
the settings UI, allowing users to enable or disable automatic copying
of the current selection when a custom action hotkey is pressed.
[[1]](diffhunk://#diff-3866eb99ffe4453e0d03248e11d3560f7f15f4b982e323519d45e282f0fe898dR63)
[[2]](diffhunk://#diff-3866eb99ffe4453e0d03248e11d3560f7f15f4b982e323519d45e282f0fe898dR106)
[[3]](diffhunk://#diff-7f5d34989db7593fa4969a79cf97f709d210c157343d474650d5df4b9bf18114R31)
[[4]](diffhunk://#diff-7f5d34989db7593fa4969a79cf97f709d210c157343d474650d5df4b9bf18114R83-R85)
[[5]](diffhunk://#diff-09c575763019d9108b85a2e7b87a3bb6ed23a835970bf511b1a6bbe9a9f53835R174-R178)
[[6]](diffhunk://#diff-0f8bf95882c074d687f6c4f2673cf9c8b1a904b117c11f75d0c892d809f3cd42R558-R570)
### Backend Logic and Integration
* Implemented the `send_copy_selection()` and `try_send_copy_message()`
methods in `dllmain.cpp` to send a WM_COPY message or simulate a Ctrl+C
keystroke, ensuring the selected content is copied before executing the
custom action.
* Integrated the new setting into the hotkey handler logic so that when
a custom action hotkey is pressed and the setting is enabled, the copy
operation is triggered before running the custom action.
### Configuration and State Management
* Updated serialization/deserialization and property synchronization
logic to support the new setting, ensuring its value is correctly
loaded, saved, and reflected in the UI and runtime behavior.
[[1]](diffhunk://#diff-3866eb99ffe4453e0d03248e11d3560f7f15f4b982e323519d45e282f0fe898dR353-R357)
[[2]](diffhunk://#diff-0f8bf95882c074d687f6c4f2673cf9c8b1a904b117c11f75d0c892d809f3cd42R1235-R1240)
### UI and Localization
* Added a new checkbox to the Advanced Paste settings page in XAML to
allow users to toggle the auto-copy feature.
* Provided localized strings for the new setting, including header and
description, in the resource file for user clarity.
### Refactoring for Hotkey Logic
* Refactored hotkey handling code to correctly calculate indices for
additional and custom actions, supporting the new auto-copy logic and
improving code clarity.
[[1]](diffhunk://#diff-3866eb99ffe4453e0d03248e11d3560f7f15f4b982e323519d45e282f0fe898dR918-R936)
[[2]](diffhunk://#diff-3866eb99ffe4453e0d03248e11d3560f7f15f4b982e323519d45e282f0fe898dL871)
[[3]](diffhunk://#diff-3866eb99ffe4453e0d03248e11d3560f7f15f4b982e323519d45e282f0fe898dL884)
2026-02-06 08:25:10 -08:00
|
|
|
|
AutoCopySelectionForCustomActionHotkey = false;
|
2025-11-05 16:13:55 +08:00
|
|
|
|
PasteAIConfiguration = new();
|
2024-05-09 10:32:03 -04:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
[JsonConverter(typeof(BoolPropertyJsonConverter))]
|
2025-11-05 16:13:55 +08:00
|
|
|
|
public bool IsAIEnabled { get; set; }
|
|
|
|
|
|
|
2025-11-12 16:24:21 +08:00
|
|
|
|
private bool? _legacyAdvancedAIEnabled;
|
|
|
|
|
|
|
|
|
|
|
|
[JsonPropertyName("IsAdvancedAIEnabled")]
|
|
|
|
|
|
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
|
|
|
|
|
|
public BoolProperty LegacyAdvancedAIEnabledProperty
|
|
|
|
|
|
{
|
|
|
|
|
|
get => null;
|
|
|
|
|
|
set
|
|
|
|
|
|
{
|
|
|
|
|
|
if (value is not null)
|
|
|
|
|
|
{
|
|
|
|
|
|
LegacyAdvancedAIEnabled = value.Value;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
[JsonIgnore]
|
|
|
|
|
|
public bool? LegacyAdvancedAIEnabled
|
|
|
|
|
|
{
|
|
|
|
|
|
get => _legacyAdvancedAIEnabled;
|
|
|
|
|
|
private set => _legacyAdvancedAIEnabled = value;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public bool TryConsumeLegacyAdvancedAIEnabled(out bool value)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (_legacyAdvancedAIEnabled is bool flag)
|
|
|
|
|
|
{
|
|
|
|
|
|
value = flag;
|
|
|
|
|
|
_legacyAdvancedAIEnabled = null;
|
|
|
|
|
|
return true;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
value = default;
|
|
|
|
|
|
return false;
|
|
|
|
|
|
}
|
2024-05-09 10:32:03 -04:00
|
|
|
|
|
|
|
|
|
|
[JsonConverter(typeof(BoolPropertyJsonConverter))]
|
2024-12-11 10:28:44 +01:00
|
|
|
|
public bool ShowCustomPreview { get; set; }
|
2024-05-09 10:32:03 -04:00
|
|
|
|
|
2024-06-24 16:03:46 +02:00
|
|
|
|
[JsonConverter(typeof(BoolPropertyJsonConverter))]
|
|
|
|
|
|
public bool CloseAfterLosingFocus { get; set; }
|
|
|
|
|
|
|
2025-11-13 10:18:13 +08:00
|
|
|
|
[JsonConverter(typeof(BoolPropertyJsonConverter))]
|
|
|
|
|
|
public bool EnableClipboardPreview { get; set; }
|
|
|
|
|
|
|
feat(advancedpaste): add auto-copy selection for custom action hotkeys (#44767)
<!-- 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
Boosting productivity #2x. Customer mentioned with Custom Action
(Shortcut trigger) "We should not need to do two keyboard actions to
finish this awesome AI data transformation, instead, just single
shortcut should do copy + advanced paste."
This pull request introduces a new feature to the Advanced Paste module
that allows users to automatically copy the current selection when
triggering a custom action hotkey. The changes include backend logic for
sending the copy command, updates to configuration and settings
management, and UI additions to expose this option to users.
### Feature Addition: Auto-Copy Selection for Custom Action Hotkeys
* Added a new boolean setting, `AutoCopySelectionForCustomActionHotkey`,
to both the backend (`dllmain.cpp`, `AdvancedPasteProperties.cs`) and
the settings UI, allowing users to enable or disable automatic copying
of the current selection when a custom action hotkey is pressed.
[[1]](diffhunk://#diff-3866eb99ffe4453e0d03248e11d3560f7f15f4b982e323519d45e282f0fe898dR63)
[[2]](diffhunk://#diff-3866eb99ffe4453e0d03248e11d3560f7f15f4b982e323519d45e282f0fe898dR106)
[[3]](diffhunk://#diff-7f5d34989db7593fa4969a79cf97f709d210c157343d474650d5df4b9bf18114R31)
[[4]](diffhunk://#diff-7f5d34989db7593fa4969a79cf97f709d210c157343d474650d5df4b9bf18114R83-R85)
[[5]](diffhunk://#diff-09c575763019d9108b85a2e7b87a3bb6ed23a835970bf511b1a6bbe9a9f53835R174-R178)
[[6]](diffhunk://#diff-0f8bf95882c074d687f6c4f2673cf9c8b1a904b117c11f75d0c892d809f3cd42R558-R570)
### Backend Logic and Integration
* Implemented the `send_copy_selection()` and `try_send_copy_message()`
methods in `dllmain.cpp` to send a WM_COPY message or simulate a Ctrl+C
keystroke, ensuring the selected content is copied before executing the
custom action.
* Integrated the new setting into the hotkey handler logic so that when
a custom action hotkey is pressed and the setting is enabled, the copy
operation is triggered before running the custom action.
### Configuration and State Management
* Updated serialization/deserialization and property synchronization
logic to support the new setting, ensuring its value is correctly
loaded, saved, and reflected in the UI and runtime behavior.
[[1]](diffhunk://#diff-3866eb99ffe4453e0d03248e11d3560f7f15f4b982e323519d45e282f0fe898dR353-R357)
[[2]](diffhunk://#diff-0f8bf95882c074d687f6c4f2673cf9c8b1a904b117c11f75d0c892d809f3cd42R1235-R1240)
### UI and Localization
* Added a new checkbox to the Advanced Paste settings page in XAML to
allow users to toggle the auto-copy feature.
* Provided localized strings for the new setting, including header and
description, in the resource file for user clarity.
### Refactoring for Hotkey Logic
* Refactored hotkey handling code to correctly calculate indices for
additional and custom actions, supporting the new auto-copy logic and
improving code clarity.
[[1]](diffhunk://#diff-3866eb99ffe4453e0d03248e11d3560f7f15f4b982e323519d45e282f0fe898dR918-R936)
[[2]](diffhunk://#diff-3866eb99ffe4453e0d03248e11d3560f7f15f4b982e323519d45e282f0fe898dL871)
[[3]](diffhunk://#diff-3866eb99ffe4453e0d03248e11d3560f7f15f4b982e323519d45e282f0fe898dL884)
2026-02-06 08:25:10 -08:00
|
|
|
|
[JsonConverter(typeof(BoolPropertyJsonConverter))]
|
|
|
|
|
|
public bool AutoCopySelectionForCustomActionHotkey { get; set; }
|
|
|
|
|
|
|
2024-05-09 10:32:03 -04:00
|
|
|
|
[JsonPropertyName("advanced-paste-ui-hotkey")]
|
|
|
|
|
|
public HotkeySettings AdvancedPasteUIShortcut { get; set; }
|
|
|
|
|
|
|
|
|
|
|
|
[JsonPropertyName("paste-as-plain-hotkey")]
|
|
|
|
|
|
public HotkeySettings PasteAsPlainTextShortcut { get; set; }
|
|
|
|
|
|
|
|
|
|
|
|
[JsonPropertyName("paste-as-markdown-hotkey")]
|
|
|
|
|
|
public HotkeySettings PasteAsMarkdownShortcut { get; set; }
|
|
|
|
|
|
|
|
|
|
|
|
[JsonPropertyName("paste-as-json-hotkey")]
|
|
|
|
|
|
public HotkeySettings PasteAsJsonShortcut { get; set; }
|
|
|
|
|
|
|
2024-08-22 16:17:12 +02:00
|
|
|
|
[JsonPropertyName("custom-actions")]
|
|
|
|
|
|
[CmdConfigureIgnoreAttribute]
|
2026-01-26 15:28:59 +08:00
|
|
|
|
public AdvancedPasteCustomActions CustomActions { get; set; }
|
2024-10-18 15:34:09 +02:00
|
|
|
|
|
|
|
|
|
|
[JsonPropertyName("additional-actions")]
|
|
|
|
|
|
[CmdConfigureIgnoreAttribute]
|
2026-01-26 15:28:59 +08:00
|
|
|
|
public AdvancedPasteAdditionalActions AdditionalActions { get; set; }
|
2024-08-22 16:17:12 +02:00
|
|
|
|
|
2025-11-05 16:13:55 +08:00
|
|
|
|
[JsonPropertyName("paste-ai-configuration")]
|
|
|
|
|
|
[CmdConfigureIgnoreAttribute]
|
|
|
|
|
|
public PasteAIConfiguration PasteAIConfiguration { get; set; }
|
|
|
|
|
|
|
2024-05-09 10:32:03 -04:00
|
|
|
|
public override string ToString()
|
2025-12-02 16:31:02 +08:00
|
|
|
|
=> JsonSerializer.Serialize(this, SettingsSerializationContext.Default.AdvancedPasteProperties);
|
2024-05-09 10:32:03 -04:00
|
|
|
|
}
|
|
|
|
|
|
}
|