mirror of
https://github.com/microsoft/PowerToys.git
synced 2026-01-17 01:27:48 +01:00
Compare commits
1 Commits
main
...
user/yeela
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4511a2024e |
@@ -60,6 +60,7 @@ namespace
|
||||
const wchar_t JSON_KEY_IS_AI_ENABLED[] = L"IsAIEnabled";
|
||||
const wchar_t JSON_KEY_IS_OPEN_AI_ENABLED[] = L"IsOpenAIEnabled";
|
||||
const wchar_t JSON_KEY_SHOW_CUSTOM_PREVIEW[] = L"ShowCustomPreview";
|
||||
const wchar_t JSON_KEY_AUTO_COPY_SELECTION_CUSTOM_ACTION[] = L"AutoCopySelectionForCustomActionHotkey";
|
||||
const wchar_t JSON_KEY_PASTE_AI_CONFIGURATION[] = L"paste-ai-configuration";
|
||||
const wchar_t JSON_KEY_PROVIDERS[] = L"providers";
|
||||
const wchar_t JSON_KEY_SERVICE_TYPE[] = L"service-type";
|
||||
@@ -102,6 +103,7 @@ private:
|
||||
bool m_is_ai_enabled = false;
|
||||
bool m_is_advanced_ai_enabled = false;
|
||||
bool m_preview_custom_format_output = true;
|
||||
bool m_auto_copy_selection_custom_action = false;
|
||||
|
||||
// Event listening for external triggers (e.g., from CmdPal extension)
|
||||
EventWaiter m_triggerEventWaiter;
|
||||
@@ -348,6 +350,11 @@ private:
|
||||
{
|
||||
m_preview_custom_format_output = propertiesObject.GetNamedObject(JSON_KEY_SHOW_CUSTOM_PREVIEW).GetNamedBoolean(JSON_KEY_VALUE);
|
||||
}
|
||||
|
||||
if (propertiesObject.HasKey(JSON_KEY_AUTO_COPY_SELECTION_CUSTOM_ACTION))
|
||||
{
|
||||
m_auto_copy_selection_custom_action = propertiesObject.GetNamedObject(JSON_KEY_AUTO_COPY_SELECTION_CUSTOM_ACTION).GetNamedBoolean(JSON_KEY_VALUE, false);
|
||||
}
|
||||
}
|
||||
|
||||
if (old_data_migrated)
|
||||
@@ -481,6 +488,88 @@ private:
|
||||
}
|
||||
}
|
||||
|
||||
bool try_send_copy_message()
|
||||
{
|
||||
GUITHREADINFO gui_info = {};
|
||||
gui_info.cbSize = sizeof(GUITHREADINFO);
|
||||
|
||||
if (!GetGUIThreadInfo(0, &gui_info))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
HWND target = gui_info.hwndFocus ? gui_info.hwndFocus : gui_info.hwndActive;
|
||||
if (!target)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
DWORD_PTR result = 0;
|
||||
return SendMessageTimeout(target,
|
||||
WM_COPY,
|
||||
0,
|
||||
0,
|
||||
SMTO_ABORTIFHUNG | SMTO_BLOCK,
|
||||
100,
|
||||
&result) != 0;
|
||||
}
|
||||
|
||||
void send_copy_selection()
|
||||
{
|
||||
if (try_send_copy_message())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
std::vector<INPUT> inputs;
|
||||
|
||||
// send Ctrl+C (key downs and key ups)
|
||||
{
|
||||
INPUT input_event = {};
|
||||
input_event.type = INPUT_KEYBOARD;
|
||||
input_event.ki.wVk = VK_CONTROL;
|
||||
input_event.ki.dwExtraInfo = CENTRALIZED_KEYBOARD_HOOK_DONT_TRIGGER_FLAG;
|
||||
inputs.push_back(input_event);
|
||||
}
|
||||
|
||||
{
|
||||
INPUT input_event = {};
|
||||
input_event.type = INPUT_KEYBOARD;
|
||||
input_event.ki.wVk = 0x43; // C
|
||||
// Avoid triggering detection by the centralized keyboard hook.
|
||||
input_event.ki.dwExtraInfo = CENTRALIZED_KEYBOARD_HOOK_DONT_TRIGGER_FLAG;
|
||||
inputs.push_back(input_event);
|
||||
}
|
||||
|
||||
{
|
||||
INPUT input_event = {};
|
||||
input_event.type = INPUT_KEYBOARD;
|
||||
input_event.ki.wVk = 0x43; // C
|
||||
input_event.ki.dwFlags = KEYEVENTF_KEYUP;
|
||||
// Avoid triggering detection by the centralized keyboard hook.
|
||||
input_event.ki.dwExtraInfo = CENTRALIZED_KEYBOARD_HOOK_DONT_TRIGGER_FLAG;
|
||||
inputs.push_back(input_event);
|
||||
}
|
||||
|
||||
{
|
||||
INPUT input_event = {};
|
||||
input_event.type = INPUT_KEYBOARD;
|
||||
input_event.ki.wVk = VK_CONTROL;
|
||||
input_event.ki.dwFlags = KEYEVENTF_KEYUP;
|
||||
input_event.ki.dwExtraInfo = CENTRALIZED_KEYBOARD_HOOK_DONT_TRIGGER_FLAG;
|
||||
inputs.push_back(input_event);
|
||||
}
|
||||
|
||||
auto uSent = SendInput(static_cast<UINT>(inputs.size()), inputs.data(), sizeof(INPUT));
|
||||
if (uSent != inputs.size())
|
||||
{
|
||||
DWORD errorCode = GetLastError();
|
||||
auto errorMessage = get_last_error_message(errorCode);
|
||||
Logger::error(L"SendInput failed for Ctrl+C. Expected to send {} inputs and sent only {}. {}", inputs.size(), uSent, errorMessage.has_value() ? errorMessage.value() : L"");
|
||||
Trace::AdvancedPaste_Error(errorCode, errorMessage.has_value() ? errorMessage.value() : L"", L"input.SendInput");
|
||||
}
|
||||
}
|
||||
|
||||
void try_to_paste_as_plain_text()
|
||||
{
|
||||
std::wstring clipboard_text;
|
||||
@@ -826,6 +915,25 @@ public:
|
||||
Logger::trace(L"AdvancedPaste hotkey pressed");
|
||||
if (m_enabled)
|
||||
{
|
||||
size_t additional_action_index = 0;
|
||||
size_t custom_action_index = 0;
|
||||
bool is_custom_action_hotkey = false;
|
||||
|
||||
if (hotkeyId >= NUM_DEFAULT_HOTKEYS)
|
||||
{
|
||||
additional_action_index = hotkeyId - NUM_DEFAULT_HOTKEYS;
|
||||
if (additional_action_index >= m_additional_actions.size())
|
||||
{
|
||||
custom_action_index = additional_action_index - m_additional_actions.size();
|
||||
is_custom_action_hotkey = custom_action_index < m_custom_actions.size();
|
||||
}
|
||||
}
|
||||
|
||||
if (is_custom_action_hotkey && m_auto_copy_selection_custom_action)
|
||||
{
|
||||
send_copy_selection();
|
||||
}
|
||||
|
||||
m_process_manager.start();
|
||||
|
||||
// hotkeyId in same order as set by get_hotkeys
|
||||
@@ -868,7 +976,6 @@ public:
|
||||
}
|
||||
|
||||
|
||||
const auto additional_action_index = hotkeyId - NUM_DEFAULT_HOTKEYS;
|
||||
if (additional_action_index < m_additional_actions.size())
|
||||
{
|
||||
const auto& id = m_additional_actions.at(additional_action_index).id;
|
||||
@@ -881,7 +988,6 @@ public:
|
||||
return true;
|
||||
}
|
||||
|
||||
const auto custom_action_index = additional_action_index - m_additional_actions.size();
|
||||
if (custom_action_index < m_custom_actions.size())
|
||||
{
|
||||
const auto id = m_custom_actions.at(custom_action_index).id;
|
||||
|
||||
@@ -28,6 +28,7 @@ namespace Microsoft.PowerToys.Settings.UI.Library
|
||||
ShowCustomPreview = true;
|
||||
CloseAfterLosingFocus = false;
|
||||
EnableClipboardPreview = true;
|
||||
AutoCopySelectionForCustomActionHotkey = false;
|
||||
PasteAIConfiguration = new();
|
||||
}
|
||||
|
||||
@@ -79,6 +80,9 @@ namespace Microsoft.PowerToys.Settings.UI.Library
|
||||
[JsonConverter(typeof(BoolPropertyJsonConverter))]
|
||||
public bool EnableClipboardPreview { get; set; }
|
||||
|
||||
[JsonConverter(typeof(BoolPropertyJsonConverter))]
|
||||
public bool AutoCopySelectionForCustomActionHotkey { get; set; }
|
||||
|
||||
[JsonPropertyName("advanced-paste-ui-hotkey")]
|
||||
public HotkeySettings AdvancedPasteUIShortcut { get; set; }
|
||||
|
||||
|
||||
@@ -171,6 +171,11 @@
|
||||
<tkcontrols:SettingsCard Name="AdvancedPasteEnableClipboardPreview" ContentAlignment="Left">
|
||||
<controls:CheckBoxWithDescriptionControl x:Uid="AdvancedPaste_EnableClipboardPreview" IsChecked="{x:Bind ViewModel.EnableClipboardPreview, Mode=TwoWay}" />
|
||||
</tkcontrols:SettingsCard>
|
||||
<tkcontrols:SettingsCard Name="AdvancedPasteAutoCopySelectionCustomAction" ContentAlignment="Left">
|
||||
<controls:CheckBoxWithDescriptionControl
|
||||
x:Uid="AdvancedPaste_AutoCopySelectionForCustomActionHotkey"
|
||||
IsChecked="{x:Bind ViewModel.AutoCopySelectionForCustomActionHotkey, Mode=TwoWay}" />
|
||||
</tkcontrols:SettingsCard>
|
||||
<tkcontrols:SettingsCard
|
||||
Name="AdvancedPasteClipboardHistoryEnabledSettingsCard"
|
||||
ContentAlignment="Left"
|
||||
|
||||
@@ -4631,6 +4631,14 @@ Activate by holding the key for the character you want to add an accent to, then
|
||||
<value>Show clipboard preview</value>
|
||||
<comment>Enables display of clipboard contents preview in the Advanced Paste window</comment>
|
||||
</data>
|
||||
<data name="AdvancedPaste_AutoCopySelectionForCustomActionHotkey.Header" xml:space="preserve">
|
||||
<value>Auto-copy selection for custom action hotkeys</value>
|
||||
<comment>Advanced Paste is a product name</comment>
|
||||
</data>
|
||||
<data name="AdvancedPaste_AutoCopySelectionForCustomActionHotkey.Description" xml:space="preserve">
|
||||
<value>Boost productivity with a single shortcut that copies the selection and runs Advanced Paste</value>
|
||||
<comment>Advanced Paste is a product name</comment>
|
||||
</data>
|
||||
<data name="GPO_CommandNotFound_ForceDisabled.Title" xml:space="preserve">
|
||||
<value>The Command Not Found module is disabled by your organization.</value>
|
||||
<comment>"Command Not Found" is a product name</comment>
|
||||
|
||||
@@ -555,6 +555,19 @@ namespace Microsoft.PowerToys.Settings.UI.ViewModels
|
||||
}
|
||||
}
|
||||
|
||||
public bool AutoCopySelectionForCustomActionHotkey
|
||||
{
|
||||
get => _advancedPasteSettings.Properties.AutoCopySelectionForCustomActionHotkey;
|
||||
set
|
||||
{
|
||||
if (value != _advancedPasteSettings.Properties.AutoCopySelectionForCustomActionHotkey)
|
||||
{
|
||||
_advancedPasteSettings.Properties.AutoCopySelectionForCustomActionHotkey = value;
|
||||
NotifySettingsChanged();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsConflictingCopyShortcut =>
|
||||
_customActions.Select(customAction => customAction.Shortcut)
|
||||
.Concat([PasteAsPlainTextShortcut, AdvancedPasteUIShortcut, PasteAsMarkdownShortcut, PasteAsJsonShortcut])
|
||||
@@ -1219,6 +1232,12 @@ namespace Microsoft.PowerToys.Settings.UI.ViewModels
|
||||
OnPropertyChanged(nameof(EnableClipboardPreview));
|
||||
}
|
||||
|
||||
if (target.AutoCopySelectionForCustomActionHotkey != source.AutoCopySelectionForCustomActionHotkey)
|
||||
{
|
||||
target.AutoCopySelectionForCustomActionHotkey = source.AutoCopySelectionForCustomActionHotkey;
|
||||
OnPropertyChanged(nameof(AutoCopySelectionForCustomActionHotkey));
|
||||
}
|
||||
|
||||
var incomingConfig = source.PasteAIConfiguration ?? new PasteAIConfiguration();
|
||||
if (ShouldReplacePasteAIConfiguration(target.PasteAIConfiguration, incomingConfig))
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user