diff --git a/src/modules/keyboardmanager/KeyboardManagerEditor/Resources.resx b/src/modules/keyboardmanager/KeyboardManagerEditor/Resources.resx
index 84fdcfa84f3f..a6fe6f2d62a7 100644
--- a/src/modules/keyboardmanager/KeyboardManagerEditor/Resources.resx
+++ b/src/modules/keyboardmanager/KeyboardManagerEditor/Resources.resx
@@ -220,6 +220,15 @@
All apps
+
+ Path to program
+
+
+ Arguments for program
+
+
+ Start in direcotry
+
Remapping successful
diff --git a/src/modules/keyboardmanager/KeyboardManagerEditorLibrary/KeyboardManagerEditorStrings.h b/src/modules/keyboardmanager/KeyboardManagerEditorLibrary/KeyboardManagerEditorStrings.h
index d64207540256..38e7d2bdfae8 100644
--- a/src/modules/keyboardmanager/KeyboardManagerEditorLibrary/KeyboardManagerEditorStrings.h
+++ b/src/modules/keyboardmanager/KeyboardManagerEditorLibrary/KeyboardManagerEditorStrings.h
@@ -27,6 +27,21 @@ namespace KeyboardManagerEditorStrings
return GET_RESOURCE_STRING(IDS_MAPPING_TYPE_DROPDOWN_RUN_PROGRAM);
}
+ inline std::wstring EditShortcutsPathToProgram()
+ {
+ return GET_RESOURCE_STRING(IDS_EDITSHORTCUTS_PATHTOPROGRAM);
+ }
+
+ inline std::wstring EditShortcutsArgsForProgram()
+ {
+ return GET_RESOURCE_STRING(IDS_EDITSHORTCUTS_ARGSFORPROGRAM);
+ }
+
+ inline std::wstring EditShortcutsStartInDirForProgram()
+ {
+ return GET_RESOURCE_STRING(IDS_EDITSHORTCUTS_STARTINDIRFORPROGRAM);
+ }
+
// Function to return the error message
winrt::hstring GetErrorMessage(ShortcutErrorType errorType);
-}
+}
\ No newline at end of file
diff --git a/src/modules/keyboardmanager/KeyboardManagerEditorLibrary/ShortcutControl.cpp b/src/modules/keyboardmanager/KeyboardManagerEditorLibrary/ShortcutControl.cpp
index cac259aa9687..3681b65334b4 100644
--- a/src/modules/keyboardmanager/KeyboardManagerEditorLibrary/ShortcutControl.cpp
+++ b/src/modules/keyboardmanager/KeyboardManagerEditorLibrary/ShortcutControl.cpp
@@ -158,11 +158,14 @@ void ShortcutControl::AddNewShortcutControlRow(StackPanel& parent, std::vector();
- auto text = textbox.Text();
- uint32_t rowIndex = -1;
+ auto runProgramArgsForProgramInput = TextBox();
+ //runProgramArgsForProgramInput.PlaceholderText(KeyboardManagerEditorStrings::EditShortcutsArgsForProgram());
+ //runProgramArgsForProgramInput.Margin(runProgramPathInputMargin);
+
+ //runProgramArgsForProgramInput.AcceptsReturn(false);
+ //runProgramArgsForProgramInput.Visibility(Visibility::Collapsed);
+ //runProgramArgsForProgramInput.Width(EditorConstants::TableDropDownHeight);
+ //controlStackPanel.Children().Append(runProgramArgsForProgramInput);
+ //runProgramArgsForProgramInput.HorizontalAlignment(HorizontalAlignment::Left);
+
+ //auto runProgramStartInDirInput = TextBox();
+ //runProgramPathInput.PlaceholderText(KeyboardManagerEditorStrings::EditShortcutsStartInDirForProgram());
+ //runProgramStartInDirInput.Margin(runProgramPathInputMargin);
+ //runProgramStartInDirInput.AcceptsReturn(false);
+ //runProgramStartInDirInput.Visibility(Visibility::Collapsed);
+ //runProgramStartInDirInput.Width(EditorConstants::TableDropDownHeight);
+ //controlStackPanel.Children().Append(runProgramStartInDirInput);
+ //runProgramStartInDirInput.HorizontalAlignment(HorizontalAlignment::Left);
+
+ runProgramPathInput.TextChanged([parent, row, runProgramPathInput, runProgramArgsForProgramInput](winrt::Windows::Foundation::IInspectable const& sender, winrt::Windows::UI::Xaml::Controls::TextChangedEventArgs const& e) mutable {
+ uint32_t rowIndex = -1;
if (!parent.Children().IndexOf(row, rowIndex))
{
return;
@@ -183,11 +203,51 @@ void ShortcutControl::AddNewShortcutControlRow(StackPanel& parent, std::vectorshortcutDropDownVariableSizedWrapGrid.as();
auto gridMargin = Windows::UI::Xaml::Thickness();
@@ -245,13 +305,9 @@ void ShortcutControl::AddNewShortcutControlRow(StackPanel& parent, std::vector(newKeys);
if (shortCut.isRunProgram)
{
- Shortcut tempShortcut;
isRunProgram = true;
- tempShortcut.isRunProgram = true;
- tempShortcut.runProgramPath = runProgramPathInput.Text().c_str();
- // Assign instead of setting the value in the buffer since the previous value may not be a Shortcut
- //shortcutRemapBuffer[index].first[1] = tempShortcut;
- runProgramPathInput.Text(shortCut.runProgramPath);
+ runProgramPathInput.Text(shortCut.runProgramFilePath);
+ runProgramArgsForProgramInput.Text(shortCut.runProgramArgs);
typeCombo.SelectedIndex(2);
}
else
@@ -469,6 +525,29 @@ void ShortcutControl::AddNewShortcutControlRow(StackPanel& parent, std::vector& keys);
diff --git a/src/runner/centralized_kb_hook.cpp b/src/runner/centralized_kb_hook.cpp
index 9cbd860ac537..3620686e1a76 100644
--- a/src/runner/centralized_kb_hook.cpp
+++ b/src/runner/centralized_kb_hook.cpp
@@ -18,13 +18,12 @@
namespace CentralizedKeyboardHook
{
-
- class RunProgramSpec2
+ class RunProgramSpec
{
private:
// Function to split a wstring based on a delimiter and return a vector of split strings
-
+
std::vector splitwstring(const std::wstring& input, wchar_t delimiter);
inline auto comparator() const
@@ -32,7 +31,7 @@ namespace CentralizedKeyboardHook
return std::make_tuple(winKey, ctrlKey, altKey, shiftKey, actionKey);
}
- std::vector RunProgramSpec2::splitwstringOnChar(const std::wstring& input, wchar_t delimiter)
+ std::vector RunProgramSpec::splitwstringOnChar(const std::wstring& input, wchar_t delimiter)
{
std::wstringstream ss(input);
std::wstring item;
@@ -45,7 +44,7 @@ namespace CentralizedKeyboardHook
return splittedStrings;
}
- bool RunProgramSpec2::SetKey(const DWORD input)
+ bool RunProgramSpec::SetKey(const DWORD input)
{
// Since there isn't a key for a common Win key we use the key code defined by us
if (input == CommonSharedConstants::VK_WIN_BOTH)
@@ -188,7 +187,6 @@ namespace CentralizedKeyboardHook
}
public:
-
ModifierKey winKey = ModifierKey::Disabled;
ModifierKey ctrlKey = ModifierKey::Disabled;
ModifierKey altKey = ModifierKey::Disabled;
@@ -201,7 +199,7 @@ namespace CentralizedKeyboardHook
std::vector keys;
DWORD actionKey = {};
- RunProgramSpec2::RunProgramSpec2(const std::wstring& shortcutVK, const std::wstring& targetAppSpec) :
+ RunProgramSpec::RunProgramSpec(const std::wstring& shortcutVK, const std::wstring& runProgram, const std::wstring& runProgramArgs, const std::wstring& runProgramStartInDir) :
winKey(ModifierKey::Disabled), ctrlKey(ModifierKey::Disabled), altKey(ModifierKey::Disabled), shiftKey(ModifierKey::Disabled), actionKey(NULL)
{
auto _keys = splitwstringOnChar(shortcutVK, ';');
@@ -211,12 +209,9 @@ namespace CentralizedKeyboardHook
SetKey(vkKeyCode);
}
- //auto KBM_RUN_PROGRAM_DELIMITER = L"<|||>";
- //auto targetParts = splitwStringOnString(targetAppSpec, KBM_RUN_PROGRAM_DELIMITER, false);
-
- path = targetAppSpec;
- //args = targetParts[1];
- //dir = targetParts[2];
+ path = runProgram;
+ args = runProgramArgs;
+ dir = runProgramStartInDir;
}
};
@@ -419,7 +414,7 @@ namespace CentralizedKeyboardHook
bool getConfigInit = false;
bool runProgramEnabled = true;
- std::vector runProgramSpecs;
+ std::vector runProgramSpecs;
void SetRunProgramEnabled(bool enabled)
{
@@ -479,8 +474,11 @@ namespace CentralizedKeyboardHook
if (isRunProgram)
{
- auto runProgram = it.GetObjectW().GetNamedString(KeyboardManagerConstants::RunProgramSettingName, L"");
- auto runProgramSpec = RunProgramSpec2(originalKeys.c_str(), runProgram.c_str());
+ auto runProgram = it.GetObjectW().GetNamedString(KeyboardManagerConstants::RunProgramFilePathSettingName, L"");
+ auto runProgramArgs = it.GetObjectW().GetNamedString(KeyboardManagerConstants::RunProgramArgsSettingName, L"");
+ auto runProgramStartInDir = it.GetObjectW().GetNamedString(KeyboardManagerConstants::RunProgramStartInDirSettingName, L"");
+
+ auto runProgramSpec = RunProgramSpec(originalKeys.c_str(), runProgram.c_str(), runProgramArgs.c_str(), runProgramStartInDir.c_str());
runProgramSpecs.push_back(runProgramSpec);
}
}
@@ -497,7 +495,7 @@ namespace CentralizedKeyboardHook
bool isPartOfAnyRunProgramSpec2(DWORD key)
{
- for (RunProgramSpec2 runProgramSpec : runProgramSpecs)
+ for (RunProgramSpec runProgramSpec : runProgramSpecs)
{
if (runProgramSpec.actionKey == key)
{
@@ -515,7 +513,7 @@ namespace CentralizedKeyboardHook
return false;
}
- bool isPartOfThisRunProgramSpec2(RunProgramSpec2 runProgramSpec, DWORD key)
+ bool isPartOfThisRunProgramSpec2(RunProgramSpec runProgramSpec, DWORD key)
{
for (DWORD c : runProgramSpec.keys)
{
@@ -528,8 +526,7 @@ namespace CentralizedKeyboardHook
}
void HandleCreateProcessHotKeysAndChords(LocalKey hotkey)
- {
-
+ {
if (!runProgramEnabled)
{
return;
@@ -550,7 +547,7 @@ namespace CentralizedKeyboardHook
return;
}
- for (RunProgramSpec2 runProgramSpec : runProgramSpecs)
+ for (RunProgramSpec runProgramSpec : runProgramSpecs)
{
if (
(runProgramSpec.winKey == ModifierKey::Disabled || (runProgramSpec.winKey == ModifierKey::Left && hotkey.l_win)) && (runProgramSpec.shiftKey == ModifierKey::Disabled || (runProgramSpec.shiftKey == ModifierKey::Left && hotkey.l_shift)) && (runProgramSpec.altKey == ModifierKey::Disabled || (runProgramSpec.altKey == ModifierKey::Left && hotkey.l_alt)) && (runProgramSpec.ctrlKey == ModifierKey::Disabled || (runProgramSpec.ctrlKey == ModifierKey::Left && hotkey.l_control)))
diff --git a/src/runner/centralized_kb_hook.h b/src/runner/centralized_kb_hook.h
index 522498d29d10..69a415cdfd05 100644
--- a/src/runner/centralized_kb_hook.h
+++ b/src/runner/centralized_kb_hook.h
@@ -33,6 +33,7 @@ namespace CentralizedKeyboardHook
void AddPressedKeyAction(const std::wstring& moduleName, const DWORD vk, const UINT milliseconds, std::function&& action) noexcept;
void ClearModuleHotkeys(const std::wstring& moduleName) noexcept;
void RegisterWindow(HWND hwnd) noexcept;
+ void RefreshConfig();
DWORD GetProcessIdByName(const std::wstring& processName);
std::wstring GetFileNameFromPath(const std::wstring& fullPath);
HWND find_main_window(unsigned long process_id);
diff --git a/src/runner/main.cpp b/src/runner/main.cpp
index 7749fc9f171c..a46e1b05500a 100644
--- a/src/runner/main.cpp
+++ b/src/runner/main.cpp
@@ -47,6 +47,8 @@
#include
#include
+#include
+
// disabling warning 4458 - declaration of 'identifier' hides class member
// to avoid warnings from GDI files - can't add winRT directory to external code
// in the Cpp.Build.props
@@ -89,6 +91,71 @@ void open_menu_from_another_instance(std::optional settings_window)
PostMessageW(hwnd_main, WM_COMMAND, ID_SETTINGS_MENU_COMMAND, msg);
}
+DWORD WINAPI WatchKeyboardManagerConfigs(LPVOID lpParameter)
+{
+ // don't need but can't not use
+ if (lpParameter)
+ {
+ }
+
+ //HANDLE PowertoyModule::hWatchDirectory = nullptr;
+
+ //// make sure we don't have more than one
+ //if (PowertoyModule::hWatchDirectory != nullptr)
+ //{
+ // return 1;
+ //}
+
+ auto directoryPath = PTSettingsHelper::get_module_save_folder_location(KeyboardManagerConstants::ModuleName);
+
+ auto hWatchDirectory = CreateFile(
+ directoryPath.c_str(),
+ FILE_LIST_DIRECTORY,
+ FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
+ NULL,
+ OPEN_EXISTING,
+ FILE_FLAG_BACKUP_SEMANTICS,
+ NULL);
+
+ if (hWatchDirectory == INVALID_HANDLE_VALUE)
+ {
+ Logger::trace(L"Error: Unable to open directory {}", directoryPath);
+ return 1;
+ }
+
+ DWORD dwBufferSize = 4096;
+ BYTE* pbBuffer = new BYTE[dwBufferSize];
+ DWORD bytesReturned;
+
+ while (true)
+ {
+ // ReadDirectoryChangesW is fired twice per write and in this case it does not matter since we're just doing a reset of data, no real work.
+ if (ReadDirectoryChangesW(
+ hWatchDirectory,
+ pbBuffer,
+ sizeof(pbBuffer),
+ FALSE,
+ FILE_NOTIFY_CHANGE_LAST_WRITE,
+ &bytesReturned,
+ NULL,
+ NULL))
+ {
+ // we don't really care what changed, just refresh
+ CentralizedKeyboardHook::RefreshConfig();
+ continue;
+ }
+ else
+ {
+ Logger::trace(L"Error: Unable to read directory changes.");
+ break;
+ }
+ }
+
+ CloseHandle(hWatchDirectory);
+
+ return 0;
+}
+
int runner(bool isProcessElevated, bool openSettings, std::string settingsWindow, bool openOobe, bool openScoobe)
{
Logger::info("Runner is starting. Elevated={} openOobe={} openScoobe={}", isProcessElevated, openOobe, openScoobe);
@@ -210,6 +277,10 @@ int runner(bool isProcessElevated, bool openSettings, std::string settingsWindow
}
settings_telemetry::init();
+
+ // start WatchKeyboardManagerConfigs
+ CreateThread(NULL, 0, WatchKeyboardManagerConfigs, 0, 0, NULL);
+
result = run_message_loop();
}
catch (std::runtime_error& err)