This commit is contained in:
Enrico Giordani
2019-12-11 15:39:05 +01:00
committed by Enrico Giordani
parent 4c7de77bfb
commit 5a3c852b32

View File

@@ -17,20 +17,25 @@
TwoWayPipeMessageIPC* current_settings_ipc = NULL; TwoWayPipeMessageIPC* current_settings_ipc = NULL;
json::JsonObject get_power_toys_settings() { json::JsonObject get_power_toys_settings()
{
json::JsonObject result; json::JsonObject result;
for (const auto&[name, powertoy] : modules()) { for (const auto& [name, powertoy] : modules())
try { {
try
{
result.SetNamedValue(name, powertoy.json_config()); result.SetNamedValue(name, powertoy.json_config());
} }
catch (...) { catch (...)
{
// TODO: handle malformed JSON. // TODO: handle malformed JSON.
} }
} }
return result; return result;
} }
json::JsonObject get_all_settings() { json::JsonObject get_all_settings()
{
json::JsonObject result; json::JsonObject result;
result.SetNamedValue(L"general", get_general_settings()); result.SetNamedValue(L"general", get_general_settings());
@@ -38,73 +43,95 @@ json::JsonObject get_all_settings() {
return result; return result;
} }
void dispatch_json_action_to_module(const json::JsonObject& powertoys_configs) { void dispatch_json_action_to_module(const json::JsonObject& powertoys_configs)
for (const auto& powertoy_element : powertoys_configs) { {
const std::wstring name{powertoy_element.Key().c_str()}; for (const auto& powertoy_element : powertoys_configs)
if (modules().find(name) != modules().end()) { {
const std::wstring name{ powertoy_element.Key().c_str() };
if (modules().find(name) != modules().end())
{
const auto element = powertoy_element.Value().Stringify(); const auto element = powertoy_element.Value().Stringify();
modules().at(name).call_custom_action(element.c_str()); modules().at(name).call_custom_action(element.c_str());
} }
} }
} }
void send_json_config_to_module(const std::wstring& module_key, const std::wstring& settings) { void send_json_config_to_module(const std::wstring& module_key, const std::wstring& settings)
if (modules().find(module_key) != modules().end()) { {
if (modules().find(module_key) != modules().end())
{
modules().at(module_key).set_config(settings.c_str()); modules().at(module_key).set_config(settings.c_str());
} }
} }
void dispatch_json_config_to_modules(const json::JsonObject& powertoys_configs) { void dispatch_json_config_to_modules(const json::JsonObject& powertoys_configs)
for (const auto& powertoy_element : powertoys_configs) { {
for (const auto& powertoy_element : powertoys_configs)
{
const auto element = powertoy_element.Value().Stringify(); const auto element = powertoy_element.Value().Stringify();
send_json_config_to_module(powertoy_element.Key().c_str(), element.c_str()); send_json_config_to_module(powertoy_element.Key().c_str(), element.c_str());
} }
}; };
void dispatch_received_json(const std::wstring &json_to_parse) { void dispatch_received_json(const std::wstring& json_to_parse)
{
const json::JsonObject j = json::JsonObject::Parse(json_to_parse); const json::JsonObject j = json::JsonObject::Parse(json_to_parse);
for(const auto & base_element : j) { for (const auto& base_element : j)
{
const auto name = base_element.Key(); const auto name = base_element.Key();
const auto value = base_element.Value(); const auto value = base_element.Value();
if (name == L"general") { if (name == L"general")
{
apply_general_settings(value.GetObjectW()); apply_general_settings(value.GetObjectW());
if (current_settings_ipc != nullptr) { if (current_settings_ipc != nullptr)
const std::wstring settings_string{get_all_settings().Stringify().c_str()}; {
const std::wstring settings_string{ get_all_settings().Stringify().c_str() };
current_settings_ipc->send(settings_string); current_settings_ipc->send(settings_string);
} }
} else if (name == L"powertoys") { }
else if (name == L"powertoys")
{
dispatch_json_config_to_modules(value.GetObjectW()); dispatch_json_config_to_modules(value.GetObjectW());
if (current_settings_ipc != nullptr) { if (current_settings_ipc != nullptr)
const std::wstring settings_string{get_all_settings().Stringify().c_str()}; {
const std::wstring settings_string{ get_all_settings().Stringify().c_str() };
current_settings_ipc->send(settings_string); current_settings_ipc->send(settings_string);
} }
} else if (name == L"refresh") { }
if (current_settings_ipc != nullptr) { else if (name == L"refresh")
const std::wstring settings_string{get_all_settings().Stringify().c_str()}; {
if (current_settings_ipc != nullptr)
{
const std::wstring settings_string{ get_all_settings().Stringify().c_str() };
current_settings_ipc->send(settings_string); current_settings_ipc->send(settings_string);
} }
} else if (name == L"action") { }
else if (name == L"action")
{
dispatch_json_action_to_module(value.GetObjectW()); dispatch_json_action_to_module(value.GetObjectW());
} }
} }
return; return;
} }
void dispatch_received_json_callback(PVOID data) { void dispatch_received_json_callback(PVOID data)
{
std::wstring* msg = (std::wstring*)data; std::wstring* msg = (std::wstring*)data;
dispatch_received_json(*msg); dispatch_received_json(*msg);
delete msg; delete msg;
} }
void receive_json_send_to_main_thread(const std::wstring &msg) { void receive_json_send_to_main_thread(const std::wstring& msg)
{
std::wstring* copy = new std::wstring(msg); std::wstring* copy = new std::wstring(msg);
dispatch_run_on_main_ui_thread(dispatch_received_json_callback, copy); dispatch_run_on_main_ui_thread(dispatch_received_json_callback, copy);
} }
DWORD g_settings_process_id = 0; DWORD g_settings_process_id = 0;
void run_settings_window() { void run_settings_window()
{
STARTUPINFO startup_info = { sizeof(startup_info) }; STARTUPINFO startup_info = { sizeof(startup_info) };
PROCESS_INFORMATION process_info = { 0 }; PROCESS_INFORMATION process_info = { 0 };
HANDLE process = NULL; HANDLE process = NULL;
@@ -117,9 +144,10 @@ void run_settings_window() {
wcscat_s(executable_path, L"\\PowerToysSettings.exe"); wcscat_s(executable_path, L"\\PowerToysSettings.exe");
WCHAR executable_args[MAX_PATH * 3]; WCHAR executable_args[MAX_PATH * 3];
const std::wstring settings_theme_setting{get_general_settings().GetNamedString(L"theme").c_str()}; const std::wstring settings_theme_setting{ get_general_settings().GetNamedString(L"theme").c_str() };
std::wstring settings_theme; std::wstring settings_theme;
if (settings_theme_setting == L"dark" || (settings_theme_setting == L"system" && WindowsColors::is_dark_mode())) { if (settings_theme_setting == L"dark" || (settings_theme_setting == L"system" && WindowsColors::is_dark_mode()))
{
settings_theme = L" dark"; // Include arg separating space settings_theme = L" dark"; // Include arg separating space
} }
// Generate unique names for the pipes, if getting a UUID is possible // Generate unique names for the pipes, if getting a UUID is possible
@@ -130,7 +158,8 @@ void run_settings_window() {
UuidCreate(&temp_uuid); UuidCreate(&temp_uuid);
wchar_t* uuid_chars; wchar_t* uuid_chars;
UuidToString(&temp_uuid, (RPC_WSTR*)&uuid_chars); UuidToString(&temp_uuid, (RPC_WSTR*)&uuid_chars);
if (uuid_chars != NULL) { if (uuid_chars != NULL)
{
powertoys_pipe_name += std::wstring(uuid_chars); powertoys_pipe_name += std::wstring(uuid_chars);
settings_pipe_name += std::wstring(uuid_chars); settings_pipe_name += std::wstring(uuid_chars);
RpcStringFree((RPC_WSTR*)&uuid_chars); RpcStringFree((RPC_WSTR*)&uuid_chars);
@@ -157,24 +186,28 @@ void run_settings_window() {
// Run the Settings process with non-elevated privileges // Run the Settings process with non-elevated privileges
HWND hwnd = GetShellWindow(); HWND hwnd = GetShellWindow();
if (!hwnd) { if (!hwnd)
{
goto LExit; goto LExit;
} }
DWORD pid; DWORD pid;
GetWindowThreadProcessId(hwnd, &pid); GetWindowThreadProcessId(hwnd, &pid);
process = OpenProcess(PROCESS_CREATE_PROCESS, FALSE, pid); process = OpenProcess(PROCESS_CREATE_PROCESS, FALSE, pid);
if (!process) { if (!process)
{
goto LExit; goto LExit;
} }
InitializeProcThreadAttributeList(nullptr, 1, 0, &size); InitializeProcThreadAttributeList(nullptr, 1, 0, &size);
pptal = (PPROC_THREAD_ATTRIBUTE_LIST)new char[size]; pptal = (PPROC_THREAD_ATTRIBUTE_LIST) new char[size];
if (!pptal) { if (!pptal)
{
goto LExit; goto LExit;
} }
if (!InitializeProcThreadAttributeList(pptal, 1, 0, &size)) { if (!InitializeProcThreadAttributeList(pptal, 1, 0, &size))
{
goto LExit; goto LExit;
} }
@@ -184,7 +217,8 @@ void run_settings_window() {
&process, &process,
sizeof(process), sizeof(process),
nullptr, nullptr,
nullptr)) { nullptr))
{
goto LExit; goto LExit;
} }
@@ -200,11 +234,13 @@ void run_settings_window() {
nullptr, nullptr,
nullptr, nullptr,
&siex.StartupInfo, &siex.StartupInfo,
&process_info)) { &process_info))
{
goto LExit; goto LExit;
} }
if (!OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &hToken)) { if (!OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &hToken))
{
goto LExit; goto LExit;
} }
current_settings_ipc = new TwoWayPipeMessageIPC(powertoys_pipe_name, settings_pipe_name, receive_json_send_to_main_thread); current_settings_ipc = new TwoWayPipeMessageIPC(powertoys_pipe_name, settings_pipe_name, receive_json_send_to_main_thread);
@@ -212,47 +248,54 @@ void run_settings_window() {
g_settings_process_id = process_info.dwProcessId; g_settings_process_id = process_info.dwProcessId;
WaitForSingleObject(process_info.hProcess, INFINITE); WaitForSingleObject(process_info.hProcess, INFINITE);
if (WaitForSingleObject(process_info.hProcess, INFINITE) != WAIT_OBJECT_0) { if (WaitForSingleObject(process_info.hProcess, INFINITE) != WAIT_OBJECT_0)
{
show_last_error_message(L"Couldn't wait on the Settings Window to close.", GetLastError()); show_last_error_message(L"Couldn't wait on the Settings Window to close.", GetLastError());
} }
LExit: LExit:
if (process_info.hProcess) { if (process_info.hProcess)
{
CloseHandle(process_info.hProcess); CloseHandle(process_info.hProcess);
} }
if (process_info.hThread) { if (process_info.hThread)
{
CloseHandle(process_info.hThread); CloseHandle(process_info.hThread);
} }
if (pptal) { if (pptal)
delete[](char*)pptal; {
delete[](char*) pptal;
} }
if (process) { if (process)
{
CloseHandle(process); CloseHandle(process);
} }
if (current_settings_ipc) { if (current_settings_ipc)
{
current_settings_ipc->end(); current_settings_ipc->end();
delete current_settings_ipc; delete current_settings_ipc;
current_settings_ipc = NULL; current_settings_ipc = NULL;
} }
if (hToken) { if (hToken)
{
CloseHandle(hToken); CloseHandle(hToken);
} }
g_settings_process_id = 0; g_settings_process_id = 0;
} }
void bring_settings_to_front() { void bring_settings_to_front()
{
auto callback = [](HWND hwnd, LPARAM data) -> BOOL auto callback = [](HWND hwnd, LPARAM data) -> BOOL {
{
DWORD processId; DWORD processId;
if (GetWindowThreadProcessId(hwnd, &processId) && processId == g_settings_process_id) { if (GetWindowThreadProcessId(hwnd, &processId) && processId == g_settings_process_id)
{
ShowWindow(hwnd, SW_NORMAL); ShowWindow(hwnd, SW_NORMAL);
SetForegroundWindow(hwnd); SetForegroundWindow(hwnd);
return FALSE; return FALSE;
@@ -264,10 +307,14 @@ void bring_settings_to_front() {
EnumWindows(callback, 0); EnumWindows(callback, 0);
} }
void open_settings_window() { void open_settings_window()
if (g_settings_process_id != 0) { {
if (g_settings_process_id != 0)
{
bring_settings_to_front(); bring_settings_to_front();
} else { }
else
{
std::thread(run_settings_window).detach(); std::thread(run_settings_window).detach();
} }
} }