Skip to content

Commit

Permalink
Almost working!
Browse files Browse the repository at this point in the history
  • Loading branch information
jefflord committed Oct 20, 2023
1 parent f57c8c2 commit b28f87b
Show file tree
Hide file tree
Showing 7 changed files with 259 additions and 28 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -225,11 +225,16 @@ namespace LoadingAndSavingRemappingHelper
for (int i = 0; i < remappings.size(); i++)
{
Shortcut originalRunProgram = std::get<Shortcut>(remappings[i].first[0]);
KeyShortcutUnion newRunProgram = remappings[i].first[1];
//KeyShortcutUnion newRunProgram = remappings[i].first[1];

if (EditorHelpers::IsValidShortcut(originalRunProgram) && ((newRunProgram.index() == 0 && std::get<DWORD>(newRunProgram) != NULL)))
//if (EditorHelpers::IsValidShortcut(originalRunProgram) && ((newRunProgram.index() == 0 && std::get<DWORD>(newRunProgram) != NULL)))

auto shortCutIsValid = EditorHelpers::IsValidShortcut(originalRunProgram);
//auto newRunProgramIndex = newRunProgram.index();
//auto newRunProgramIsNotNull = (std::get<DWORD>(newRunProgram) != NULL);
if (shortCutIsValid)
{
bool result = mappingConfiguration.AddAppSpecificRunProgram(remappings[i].second, originalRunProgram, newRunProgram);
bool result = mappingConfiguration.AddAppSpecificRunProgram(remappings[i].second, originalRunProgram, originalRunProgram);
if (result)
{
successfulAppSpecificRunProgramToRunProgramRemapCount += 1;
Expand Down
4 changes: 3 additions & 1 deletion src/modules/keyboardmanager/common/MappingConfiguration.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,13 @@
#include <common/SettingsAPI/settings_helpers.h>
#include <common/logger/logger.h>


#include "KeyboardManagerConstants.h"
#include "Shortcut.h"
#include "RemapShortcut.h"
#include "Helpers.h"


// Function to clear the OS Level shortcut remapping table
void MappingConfiguration::ClearOSLevelShortcuts()
{
Expand Down Expand Up @@ -510,7 +512,7 @@ bool MappingConfiguration::SaveSettingsToFile()
configJson.SetNamedValue(KeyboardManagerConstants::RemapShortcutsSettingName, remapShortcuts);

try
{
{
json::to_file((PTSettingsHelper::get_module_save_folder_location(KeyboardManagerConstants::ModuleName) + L"\\" + currentConfig + L".json"), configJson);
}
catch (...)
Expand Down
17 changes: 2 additions & 15 deletions src/runner/centralized_kb_hook.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -387,31 +387,18 @@ namespace CentralizedKeyboardHook
return;
}

std::wstring currentConfig = KeyboardManagerConstants::DefaultConfiguration;

currentConfig = *current_config;

// Read the config file and load the remaps.
auto configFile = json::from_file(PTSettingsHelper::get_module_save_folder_location(KeyboardManagerConstants::ModuleName) + L"\\" + *current_config + L".json");
if (!configFile)
{
return;
}

auto jsonData = json::from_file(PTSettingsHelper::get_module_save_folder_location(KeyboardManagerConstants::ModuleName) + L"\\" + *current_config + L".json");

//auto jsonData = json::from_file(L"c:\\Temp\\keyboardManagerConfig.json");

if (!jsonData)
{
return;
}

auto keyboardManagerConfig = jsonData->GetNamedObject(L"remapShortcuts");
auto keyboardManagerConfig = jsonData->GetNamedObject(KeyboardManagerConstants::RemapShortcutsSettingName);

if (keyboardManagerConfig)
{
auto global = keyboardManagerConfig.GetNamedArray(L"runProgram");
auto global = keyboardManagerConfig.GetNamedArray(KeyboardManagerConstants::AppSpecificRemapRunProgramsSettingName);
for (const auto& it : global)
{
try
Expand Down
15 changes: 10 additions & 5 deletions src/runner/general_settings.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ json::JsonObject load_general_settings()
}
run_as_elevated = loaded.GetNamedBoolean(L"run_elevated", false);
download_updates_automatically = loaded.GetNamedBoolean(L"download_updates_automatically", true) && check_user_is_admin();
enable_experimentation = loaded.GetNamedBoolean(L"enable_experimentation",true);
enable_experimentation = loaded.GetNamedBoolean(L"enable_experimentation", true);

return loaded;
}
Expand Down Expand Up @@ -159,10 +159,14 @@ void apply_general_settings(const json::JsonObject& general_configs, bool save)
target_enabled = gpo_rule == powertoys_gpo::gpo_rule_configured_enabled;
}

if (module_inst_enabled == target_enabled)
if (name != L"Keyboard Manager")
{
continue;
if (module_inst_enabled == target_enabled)
{
continue;
}
}

if (target_enabled)
{
Logger::info(L"apply_general_settings: Enabling powertoy {}", name);
Expand All @@ -173,7 +177,9 @@ void apply_general_settings(const json::JsonObject& general_configs, bool save)
Logger::info(L"apply_general_settings: Disabling powertoy {}", name);
powertoy->disable();
}

// Sync the hotkey state with the module state, so it can be removed for disabled modules.
powertoy.add_run_program_shortcuts();
powertoy.UpdateHotkeyEx();
}
}
Expand Down Expand Up @@ -224,8 +230,7 @@ void start_enabled_powertoys()
{
std::wstring disable_module_name{ static_cast<std::wstring_view>(disabled_element.Key()) };

if (powertoys_gpo_configuration.find(disable_module_name)!=powertoys_gpo_configuration.end()
&& (powertoys_gpo_configuration[disable_module_name]==powertoys_gpo::gpo_rule_configured_enabled || powertoys_gpo_configuration[disable_module_name]==powertoys_gpo::gpo_rule_configured_disabled))
if (powertoys_gpo_configuration.find(disable_module_name) != powertoys_gpo_configuration.end() && (powertoys_gpo_configuration[disable_module_name] == powertoys_gpo::gpo_rule_configured_enabled || powertoys_gpo_configuration[disable_module_name] == powertoys_gpo::gpo_rule_configured_disabled))
{
// If gpo forces the enabled setting, no need to check the setting for this PowerToy. It will be applied later on this function.
continue;
Expand Down
207 changes: 207 additions & 0 deletions src/runner/powertoy_module.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,167 @@
#include <common/logger/logger.h>
#include <common/utils/winapi_error.h>

#include <common/SettingsAPI/settings_objects.h>
#include <common/SettingsAPI/settings_helpers.h>
#include <modules/keyboardmanager/common/Shortcut.h>
#include <modules/keyboardmanager/common/RemapShortcut.h>
#include <modules/keyboardmanager/common/KeyboardManagerConstants.h>
#include <common/interop/shared_constants.h>

std::map<std::wstring, PowertoyModule>& modules()
{
static std::map<std::wstring, PowertoyModule> modules;
return modules;
}

class RunProgramSpec
{
public:
ModifierKey winKey = ModifierKey::Disabled;
ModifierKey ctrlKey = ModifierKey::Disabled;
ModifierKey altKey = ModifierKey::Disabled;
ModifierKey shiftKey = ModifierKey::Disabled;
DWORD actionKey = {};

std::wstring path = L"";
std::vector<DWORD> keys;

RunProgramSpec(const std::wstring& shortcutVK) :
winKey(ModifierKey::Disabled), ctrlKey(ModifierKey::Disabled), altKey(ModifierKey::Disabled), shiftKey(ModifierKey::Disabled), actionKey(NULL)
{
auto _keys = splitwstring(shortcutVK, ';');
for (auto it : _keys)
{
auto vkKeyCode = std::stoul(it);
SetKey(vkKeyCode);
}
}

std::vector<std::wstring> splitwstring(const std::wstring& input, wchar_t delimiter)
{
std::wstringstream ss(input);
std::wstring item;
std::vector<std::wstring> splittedStrings;
while (std::getline(ss, item, delimiter))
{
splittedStrings.push_back(item);
}

return splittedStrings;
}

bool 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)
{
if (winKey == ModifierKey::Both)
{
return false;
}
winKey = ModifierKey::Both;
}
else if (input == VK_LWIN)
{
if (winKey == ModifierKey::Left)
{
return false;
}
winKey = ModifierKey::Left;
}
else if (input == VK_RWIN)
{
if (winKey == ModifierKey::Right)
{
return false;
}
winKey = ModifierKey::Right;
}
else if (input == VK_LCONTROL)
{
if (ctrlKey == ModifierKey::Left)
{
return false;
}
ctrlKey = ModifierKey::Left;
}
else if (input == VK_RCONTROL)
{
if (ctrlKey == ModifierKey::Right)
{
return false;
}
ctrlKey = ModifierKey::Right;
}
else if (input == VK_CONTROL)
{
if (ctrlKey == ModifierKey::Both)
{
return false;
}
ctrlKey = ModifierKey::Both;
}
else if (input == VK_LMENU)
{
if (altKey == ModifierKey::Left)
{
return false;
}
altKey = ModifierKey::Left;
}
else if (input == VK_RMENU)
{
if (altKey == ModifierKey::Right)
{
return false;
}
altKey = ModifierKey::Right;
}
else if (input == VK_MENU)
{
if (altKey == ModifierKey::Both)
{
return false;
}
altKey = ModifierKey::Both;
}
else if (input == VK_LSHIFT)
{
if (shiftKey == ModifierKey::Left)
{
return false;
}
shiftKey = ModifierKey::Left;
}
else if (input == VK_RSHIFT)
{
if (shiftKey == ModifierKey::Right)
{
return false;
}
shiftKey = ModifierKey::Right;
}
else if (input == VK_SHIFT)
{
if (shiftKey == ModifierKey::Both)
{
return false;
}
shiftKey = ModifierKey::Both;
}
else
{
if (actionKey == input)
{
return false;
}
actionKey = input;
}

return true;
}
};

PowertoyModule load_powertoy(const std::wstring_view filename)
{
auto handle = winrt::check_pointer(LoadLibraryW(filename.data()));
Expand Down Expand Up @@ -87,6 +242,57 @@ void PowertoyModule::add_run_program_shortcuts()

try
{
PowerToysSettings::PowerToyValues settings = PowerToysSettings::PowerToyValues::load_from_settings_file(KeyboardManagerConstants::ModuleName);
auto current_config = settings.get_string_value(KeyboardManagerConstants::ActiveConfigurationSettingName);

if (!current_config)
{
return;
}

auto jsonData = json::from_file(PTSettingsHelper::get_module_save_folder_location(KeyboardManagerConstants::ModuleName) + L"\\" + *current_config + L".json");

if (!jsonData)
{
return;
}

auto keyboardManagerConfig = jsonData->GetNamedObject(KeyboardManagerConstants::RemapShortcutsSettingName);

if (keyboardManagerConfig)
{
auto global = keyboardManagerConfig.GetNamedArray(KeyboardManagerConstants::AppSpecificRemapRunProgramsSettingName);
for (const auto& it : global)
{
try
{
auto originalKeys = it.GetObjectW().GetNamedString(KeyboardManagerConstants::OriginalKeysSettingName);

auto path = it.GetObjectW().GetNamedString(L"targetApp");

auto runProgramSpec = RunProgramSpec(originalKeys.c_str());

// auto isChord = it.GetObjectW().GetNamedBoolean(L"isChord");
hotkey.win = (runProgramSpec.winKey == ModifierKey::Left || runProgramSpec.winKey == ModifierKey::Right);
hotkey.shift = (runProgramSpec.shiftKey == ModifierKey::Left || runProgramSpec.shiftKey == ModifierKey::Right);
hotkey.alt = (runProgramSpec.altKey == ModifierKey::Left || runProgramSpec.altKey == ModifierKey::Right);
hotkey.ctrl = (runProgramSpec.ctrlKey == ModifierKey::Left || runProgramSpec.ctrlKey == ModifierKey::Right);


hotkey.key = static_cast<UCHAR>(runProgramSpec.actionKey);
CentralizedKeyboardHook::SetHotkeyAction(pt_module->get_key(), hotkey, [modulePtr, emptyValue] {
Logger::trace(L"{} hotkey is invoked from Centralized keyboard hook", modulePtr->get_key());
return true;
});
}
catch (...)
{
Logger::error(L"Improper Key Data JSON. Try the next remap.");
}
}
}

/*
auto jsonData = json::from_file(L"c:\\Temp\\keyboardManagerConfig.json");
if (!jsonData)
Expand Down Expand Up @@ -128,6 +334,7 @@ void PowertoyModule::add_run_program_shortcuts()
}
}
}
*/
}
catch (...)
{
Expand Down
5 changes: 4 additions & 1 deletion src/runner/settings_window.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
#include <Sddl.h>
#include <sstream>
#include <aclapi.h>
#include <chrono>

#include "powertoy_module.h"
#include <common/interop/two_way_pipe_message_ipc.h>
Expand Down Expand Up @@ -165,8 +166,10 @@ void dispatch_json_config_to_modules(const json::JsonObject& powertoys_configs)
}
};

auto last_dispatch_received_json_ms = static_cast<long long>(0);

void dispatch_received_json(const std::wstring& json_to_parse)
{
{
json::JsonObject j;
const bool ok = json::JsonObject::TryParse(json_to_parse, j);
if (!ok)
Expand Down
Loading

1 comment on commit b28f87b

@github-actions
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@check-spelling-bot Report

🔴 Please review

See the 📜action log for details.

Unrecognized words (3)

EDITRUNPROGRAMS
JLO
Programtool

Previously acknowledged words that are now absent administra RSAT systemroot sysvol :arrow_right:
To accept ✔️ these unrecognized words as correct and remove the previously acknowledged and now absent words, run the following commands

... in a clone of the git@github.com:jefflord/PowerToys.git repository
on the run-program-shortcuts branch (ℹ️ how do I use this?):

curl -s -S -L 'https://raw.githubusercontent.com/check-spelling/check-spelling/v0.0.21/apply.pl' |
perl - 'https://github.com/jefflord/PowerToys/actions/runs/6588314618/attempts/1'
Available 📚 dictionaries could cover words not in the 📘 dictionary

This includes both expected items (2287) from .github/actions/spell-check/expect.txt and unrecognized words (3)

Dictionary Entries Covers
cspell:win32/src/win32.txt 53509 139
cspell:cpp/src/cpp.txt 30216 132
cspell:python/src/python/python-lib.txt 3873 29
cspell:php/php.txt 2597 20
cspell:node/node.txt 1768 15
cspell:typescript/typescript.txt 1211 13
cspell:java/java.txt 7642 12
cspell:python/src/python/python.txt 453 10
cspell:aws/aws.txt 218 9
cspell:python/src/common/extra.txt 741 8

Consider adding them using (in .github/workflows/spelling2.yml):

      with:
        extra_dictionaries:
          cspell:win32/src/win32.txt
          cspell:cpp/src/cpp.txt
          cspell:python/src/python/python-lib.txt
          cspell:php/php.txt
          cspell:node/node.txt
          cspell:typescript/typescript.txt
          cspell:java/java.txt
          cspell:python/src/python/python.txt
          cspell:aws/aws.txt
          cspell:python/src/common/extra.txt

To stop checking additional dictionaries, add:

      with:
        check_extra_dictionaries: ''
If the flagged items are 🤯 false positives

If items relate to a ...

  • binary file (or some other file you wouldn't want to check at all).

    Please add a file path to the excludes.txt file matching the containing file.

    File paths are Perl 5 Regular Expressions - you can test yours before committing to verify it will match your files.

    ^ refers to the file's path from the root of the repository, so ^README\.md$ would exclude README.md (on whichever branch you're using).

  • well-formed pattern.

    If you can write a pattern that would match it,
    try adding it to the patterns.txt file.

    Patterns are Perl 5 Regular Expressions - you can test yours before committing to verify it will match your lines.

    Note that patterns can't match multiline strings.

Please sign in to comment.