diff --git a/src/runner/settings_window.cpp b/src/runner/settings_window.cpp index 69917cb30..f25bdd0fc 100644 --- a/src/runner/settings_window.cpp +++ b/src/runner/settings_window.cpp @@ -17,257 +17,304 @@ TwoWayPipeMessageIPC* current_settings_ipc = NULL; -json::JsonObject get_power_toys_settings() { - json::JsonObject result; - for (const auto&[name, powertoy] : modules()) { - try { - result.SetNamedValue(name, powertoy.json_config()); +json::JsonObject get_power_toys_settings() +{ + json::JsonObject result; + for (const auto& [name, powertoy] : modules()) + { + try + { + result.SetNamedValue(name, powertoy.json_config()); + } + catch (...) + { + // TODO: handle malformed JSON. + } } - catch (...) { - // TODO: handle malformed JSON. + return result; +} + +json::JsonObject get_all_settings() +{ + json::JsonObject result; + + result.SetNamedValue(L"general", get_general_settings()); + result.SetNamedValue(L"powertoys", get_power_toys_settings()); + return result; +} + +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() }; + if (modules().find(name) != modules().end()) + { + const auto element = powertoy_element.Value().Stringify(); + modules().at(name).call_custom_action(element.c_str()); + } } - } - return result; } -json::JsonObject get_all_settings() { - json::JsonObject result; - - result.SetNamedValue(L"general", get_general_settings()); - result.SetNamedValue(L"powertoys", get_power_toys_settings()); - return result; -} - -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()}; - if (modules().find(name) != modules().end()) { - const auto element = powertoy_element.Value().Stringify(); - modules().at(name).call_custom_action(element.c_str()); +void send_json_config_to_module(const std::wstring& module_key, const std::wstring& settings) +{ + if (modules().find(module_key) != modules().end()) + { + modules().at(module_key).set_config(settings.c_str()); } - } } -void send_json_config_to_module(const std::wstring& module_key, const std::wstring& settings) { - if (modules().find(module_key) != modules().end()) { - modules().at(module_key).set_config(settings.c_str()); - } -} - -void dispatch_json_config_to_modules(const json::JsonObject& powertoys_configs) { - for (const auto& powertoy_element : powertoys_configs) { - const auto element = powertoy_element.Value().Stringify(); - send_json_config_to_module(powertoy_element.Key().c_str(), element.c_str()); - } +void dispatch_json_config_to_modules(const json::JsonObject& powertoys_configs) +{ + for (const auto& powertoy_element : powertoys_configs) + { + const auto element = powertoy_element.Value().Stringify(); + send_json_config_to_module(powertoy_element.Key().c_str(), element.c_str()); + } }; -void dispatch_received_json(const std::wstring &json_to_parse) { - const json::JsonObject j = json::JsonObject::Parse(json_to_parse); - for(const auto & base_element : j) { - const auto name = base_element.Key(); - const auto value = base_element.Value(); +void dispatch_received_json(const std::wstring& json_to_parse) +{ + const json::JsonObject j = json::JsonObject::Parse(json_to_parse); + for (const auto& base_element : j) + { + const auto name = base_element.Key(); + const auto value = base_element.Value(); - if (name == L"general") { - apply_general_settings(value.GetObjectW()); - if (current_settings_ipc != nullptr) { - const std::wstring settings_string{get_all_settings().Stringify().c_str()}; - current_settings_ipc->send(settings_string); - } - } else if (name == L"powertoys") { - dispatch_json_config_to_modules(value.GetObjectW()); - if (current_settings_ipc != nullptr) { - const std::wstring settings_string{get_all_settings().Stringify().c_str()}; - current_settings_ipc->send(settings_string); - } - } else if (name == L"refresh") { - if (current_settings_ipc != nullptr) { - const std::wstring settings_string{get_all_settings().Stringify().c_str()}; - current_settings_ipc->send(settings_string); - } - } else if (name == L"action") { - dispatch_json_action_to_module(value.GetObjectW()); + if (name == L"general") + { + apply_general_settings(value.GetObjectW()); + if (current_settings_ipc != nullptr) + { + const std::wstring settings_string{ get_all_settings().Stringify().c_str() }; + current_settings_ipc->send(settings_string); + } + } + else if (name == L"powertoys") + { + dispatch_json_config_to_modules(value.GetObjectW()); + if (current_settings_ipc != nullptr) + { + const std::wstring settings_string{ get_all_settings().Stringify().c_str() }; + current_settings_ipc->send(settings_string); + } + } + else if (name == L"refresh") + { + if (current_settings_ipc != nullptr) + { + const std::wstring settings_string{ get_all_settings().Stringify().c_str() }; + current_settings_ipc->send(settings_string); + } + } + else if (name == L"action") + { + dispatch_json_action_to_module(value.GetObjectW()); + } } - } - return; + return; } -void dispatch_received_json_callback(PVOID data) { - std::wstring* msg = (std::wstring*)data; - dispatch_received_json(*msg); - delete msg; +void dispatch_received_json_callback(PVOID data) +{ + std::wstring* msg = (std::wstring*)data; + dispatch_received_json(*msg); + delete msg; } -void receive_json_send_to_main_thread(const std::wstring &msg) { - std::wstring* copy = new std::wstring(msg); - dispatch_run_on_main_ui_thread(dispatch_received_json_callback, copy); +void receive_json_send_to_main_thread(const std::wstring& msg) +{ + std::wstring* copy = new std::wstring(msg); + dispatch_run_on_main_ui_thread(dispatch_received_json_callback, copy); } DWORD g_settings_process_id = 0; -void run_settings_window() { - STARTUPINFO startup_info = { sizeof(startup_info) }; - PROCESS_INFORMATION process_info = { 0 }; - HANDLE process = NULL; - HANDLE hToken = NULL; - STARTUPINFOEX siex = { 0 }; - PPROC_THREAD_ATTRIBUTE_LIST pptal = NULL; - WCHAR executable_path[MAX_PATH]; - GetModuleFileName(NULL, executable_path, MAX_PATH); - PathRemoveFileSpec(executable_path); - wcscat_s(executable_path, L"\\PowerToysSettings.exe"); - WCHAR executable_args[MAX_PATH * 3]; +void run_settings_window() +{ + STARTUPINFO startup_info = { sizeof(startup_info) }; + PROCESS_INFORMATION process_info = { 0 }; + HANDLE process = NULL; + HANDLE hToken = NULL; + STARTUPINFOEX siex = { 0 }; + PPROC_THREAD_ATTRIBUTE_LIST pptal = NULL; + WCHAR executable_path[MAX_PATH]; + GetModuleFileName(NULL, executable_path, MAX_PATH); + PathRemoveFileSpec(executable_path); + wcscat_s(executable_path, L"\\PowerToysSettings.exe"); + WCHAR executable_args[MAX_PATH * 3]; - const std::wstring settings_theme_setting{get_general_settings().GetNamedString(L"theme").c_str()}; - std::wstring settings_theme; - if (settings_theme_setting == L"dark" || (settings_theme_setting == L"system" && WindowsColors::is_dark_mode())) { - settings_theme = L" dark"; // Include arg separating space - } - // Generate unique names for the pipes, if getting a UUID is possible - std::wstring powertoys_pipe_name(L"\\\\.\\pipe\\powertoys_runner_"); - std::wstring settings_pipe_name(L"\\\\.\\pipe\\powertoys_settings_"); - SIZE_T size = 0; - UUID temp_uuid; - UuidCreate(&temp_uuid); - wchar_t* uuid_chars; - UuidToString(&temp_uuid, (RPC_WSTR*)&uuid_chars); - if (uuid_chars != NULL) { - powertoys_pipe_name += std::wstring(uuid_chars); - settings_pipe_name += std::wstring(uuid_chars); - RpcStringFree((RPC_WSTR*)&uuid_chars); - uuid_chars = NULL; - } - DWORD powertoys_pid = GetCurrentProcessId(); - // Arguments for calling the settings executable: - // C:\powertoys_path\PowerToysSettings.exe powertoys_pipe settings_pipe powertoys_pid - // powertoys_pipe - PowerToys pipe server. - // settings_pipe - Settings pipe server. - // powertoys_pid - PowerToys process pid. - // settings_theme - pass "dark" to start the settings window in dark mode - wcscpy_s(executable_args, L"\""); - wcscat_s(executable_args, executable_path); - wcscat_s(executable_args, L"\""); - wcscat_s(executable_args, L" "); - wcscat_s(executable_args, powertoys_pipe_name.c_str()); - wcscat_s(executable_args, L" "); - wcscat_s(executable_args, settings_pipe_name.c_str()); - wcscat_s(executable_args, L" "); - wcscat_s(executable_args, std::to_wstring(powertoys_pid).c_str()); - wcscat_s(executable_args, settings_theme.c_str()); + const std::wstring settings_theme_setting{ get_general_settings().GetNamedString(L"theme").c_str() }; + std::wstring settings_theme; + if (settings_theme_setting == L"dark" || (settings_theme_setting == L"system" && WindowsColors::is_dark_mode())) + { + settings_theme = L" dark"; // Include arg separating space + } + // Generate unique names for the pipes, if getting a UUID is possible + std::wstring powertoys_pipe_name(L"\\\\.\\pipe\\powertoys_runner_"); + std::wstring settings_pipe_name(L"\\\\.\\pipe\\powertoys_settings_"); + SIZE_T size = 0; + UUID temp_uuid; + UuidCreate(&temp_uuid); + wchar_t* uuid_chars; + UuidToString(&temp_uuid, (RPC_WSTR*)&uuid_chars); + if (uuid_chars != NULL) + { + powertoys_pipe_name += std::wstring(uuid_chars); + settings_pipe_name += std::wstring(uuid_chars); + RpcStringFree((RPC_WSTR*)&uuid_chars); + uuid_chars = NULL; + } + DWORD powertoys_pid = GetCurrentProcessId(); + // Arguments for calling the settings executable: + // C:\powertoys_path\PowerToysSettings.exe powertoys_pipe settings_pipe powertoys_pid + // powertoys_pipe - PowerToys pipe server. + // settings_pipe - Settings pipe server. + // powertoys_pid - PowerToys process pid. + // settings_theme - pass "dark" to start the settings window in dark mode + wcscpy_s(executable_args, L"\""); + wcscat_s(executable_args, executable_path); + wcscat_s(executable_args, L"\""); + wcscat_s(executable_args, L" "); + wcscat_s(executable_args, powertoys_pipe_name.c_str()); + wcscat_s(executable_args, L" "); + wcscat_s(executable_args, settings_pipe_name.c_str()); + wcscat_s(executable_args, L" "); + wcscat_s(executable_args, std::to_wstring(powertoys_pid).c_str()); + wcscat_s(executable_args, settings_theme.c_str()); - // Run the Settings process with non-elevated privileges + // Run the Settings process with non-elevated privileges - HWND hwnd = GetShellWindow(); - if (!hwnd) { - goto LExit; - } - DWORD pid; - GetWindowThreadProcessId(hwnd, &pid); + HWND hwnd = GetShellWindow(); + if (!hwnd) + { + goto LExit; + } + DWORD pid; + GetWindowThreadProcessId(hwnd, &pid); - process = OpenProcess(PROCESS_CREATE_PROCESS, FALSE, pid); - if (!process) { - goto LExit; - } + process = OpenProcess(PROCESS_CREATE_PROCESS, FALSE, pid); + if (!process) + { + goto LExit; + } - InitializeProcThreadAttributeList(nullptr, 1, 0, &size); - pptal = (PPROC_THREAD_ATTRIBUTE_LIST)new char[size]; - if (!pptal) { - goto LExit; - } + InitializeProcThreadAttributeList(nullptr, 1, 0, &size); + pptal = (PPROC_THREAD_ATTRIBUTE_LIST) new char[size]; + if (!pptal) + { + goto LExit; + } - if (!InitializeProcThreadAttributeList(pptal, 1, 0, &size)) { - goto LExit; - } + if (!InitializeProcThreadAttributeList(pptal, 1, 0, &size)) + { + goto LExit; + } - if (!UpdateProcThreadAttribute(pptal, - 0, - PROC_THREAD_ATTRIBUTE_PARENT_PROCESS, - &process, - sizeof(process), - nullptr, - nullptr)) { - goto LExit; - } + if (!UpdateProcThreadAttribute(pptal, + 0, + PROC_THREAD_ATTRIBUTE_PARENT_PROCESS, + &process, + sizeof(process), + nullptr, + nullptr)) + { + goto LExit; + } - siex.lpAttributeList = pptal; - siex.StartupInfo.cb = sizeof(siex); + siex.lpAttributeList = pptal; + siex.StartupInfo.cb = sizeof(siex); - if (!CreateProcessW(executable_path, - executable_args, - nullptr, - nullptr, - FALSE, - EXTENDED_STARTUPINFO_PRESENT, - nullptr, - nullptr, - &siex.StartupInfo, - &process_info)) { - goto LExit; - } + if (!CreateProcessW(executable_path, + executable_args, + nullptr, + nullptr, + FALSE, + EXTENDED_STARTUPINFO_PRESENT, + nullptr, + nullptr, + &siex.StartupInfo, + &process_info)) + { + goto LExit; + } - if (!OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &hToken)) { - goto LExit; - } - current_settings_ipc = new TwoWayPipeMessageIPC(powertoys_pipe_name, settings_pipe_name, receive_json_send_to_main_thread); - current_settings_ipc->start(hToken); - g_settings_process_id = process_info.dwProcessId; + if (!OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &hToken)) + { + goto LExit; + } + current_settings_ipc = new TwoWayPipeMessageIPC(powertoys_pipe_name, settings_pipe_name, receive_json_send_to_main_thread); + current_settings_ipc->start(hToken); + g_settings_process_id = process_info.dwProcessId; - WaitForSingleObject(process_info.hProcess, INFINITE); - if (WaitForSingleObject(process_info.hProcess, INFINITE) != WAIT_OBJECT_0) { - show_last_error_message(L"Couldn't wait on the Settings Window to close.", GetLastError()); - } + WaitForSingleObject(process_info.hProcess, INFINITE); + if (WaitForSingleObject(process_info.hProcess, INFINITE) != WAIT_OBJECT_0) + { + show_last_error_message(L"Couldn't wait on the Settings Window to close.", GetLastError()); + } LExit: - if (process_info.hProcess) { - CloseHandle(process_info.hProcess); - } - - if (process_info.hThread) { - CloseHandle(process_info.hThread); - } - - if (pptal) { - delete[](char*)pptal; - } - - if (process) { - CloseHandle(process); - } - - if (current_settings_ipc) { - current_settings_ipc->end(); - delete current_settings_ipc; - current_settings_ipc = NULL; - } - - if (hToken) { - CloseHandle(hToken); - } - - g_settings_process_id = 0; -} - -void bring_settings_to_front() { - - auto callback = [](HWND hwnd, LPARAM data) -> BOOL - { - DWORD processId; - if (GetWindowThreadProcessId(hwnd, &processId) && processId == g_settings_process_id) { - ShowWindow(hwnd, SW_NORMAL); - SetForegroundWindow(hwnd); - return FALSE; + if (process_info.hProcess) + { + CloseHandle(process_info.hProcess); } - return TRUE; - }; + if (process_info.hThread) + { + CloseHandle(process_info.hThread); + } - EnumWindows(callback, 0); + if (pptal) + { + delete[](char*) pptal; + } + + if (process) + { + CloseHandle(process); + } + + if (current_settings_ipc) + { + current_settings_ipc->end(); + delete current_settings_ipc; + current_settings_ipc = NULL; + } + + if (hToken) + { + CloseHandle(hToken); + } + + g_settings_process_id = 0; } -void open_settings_window() { - if (g_settings_process_id != 0) { - bring_settings_to_front(); - } else { - std::thread(run_settings_window).detach(); - } +void bring_settings_to_front() +{ + auto callback = [](HWND hwnd, LPARAM data) -> BOOL { + DWORD processId; + if (GetWindowThreadProcessId(hwnd, &processId) && processId == g_settings_process_id) + { + ShowWindow(hwnd, SW_NORMAL); + SetForegroundWindow(hwnd); + return FALSE; + } + + return TRUE; + }; + + EnumWindows(callback, 0); +} + +void open_settings_window() +{ + if (g_settings_process_id != 0) + { + bring_settings_to_front(); + } + else + { + std::thread(run_settings_window).detach(); + } }