#include "pch.h" #include "shortcut_guide.h" #include "target_state.h" #include "trace.h" #include extern "C" IMAGE_DOS_HEADER __ImageBase; OverlayWindow* instance = nullptr; OverlayWindow::OverlayWindow() { init_settings(); } const wchar_t * OverlayWindow::get_name() { return L"Shortcut Guide"; } const wchar_t ** OverlayWindow::get_events() { static const wchar_t* events[2] = { ll_keyboard, 0 }; return events; } bool OverlayWindow::get_config(wchar_t* buffer, int *buffer_size) { HINSTANCE hinstance = reinterpret_cast(&__ImageBase); PowerToysSettings::Settings settings(hinstance, get_name()); settings.set_description(L"Shows a help overlay with Windows shortcuts when the Windows key is pressed."); settings.set_overview_link(L"https://github.com/microsoft/PowerToys/blob/master/src/modules/shortcut_guide/README.md"); settings.set_icon_key(L"pt-shortcut-guide"); settings.add_int_spinner( pressTime.name, pressTime.resourceId, pressTime.value, 100, 10000, 100 ); settings.add_int_spinner( overlayOpacity.name, overlayOpacity.resourceId, overlayOpacity.value, 0, 100, 1 ); settings.add_choice_group( theme.name, theme.resourceId, theme.value, theme.keys_and_texts ); return settings.serialize_to_buffer(buffer, buffer_size); } void OverlayWindow::set_config(const wchar_t * config) { try { PowerToysSettings::PowerToyValues _values = PowerToysSettings::PowerToyValues::from_json_string(config); if (_values.is_int_value(pressTime.name)) { int press_delay_time = _values.get_int_value(pressTime.name); pressTime.value = press_delay_time; if (target_state) { target_state->set_delay(press_delay_time); } } if (_values.is_int_value(overlayOpacity.name)) { int overlay_opacity = _values.get_int_value(overlayOpacity.name); overlayOpacity.value = overlay_opacity; if (winkey_popup) { winkey_popup->apply_overlay_opacity(((float)overlayOpacity.value) / 100.0f); } } if (_values.is_string_value(theme.name)) { theme.value = _values.get_string_value(theme.name); winkey_popup->set_theme(theme.value); } _values.save_to_settings_file(); } catch (std::exception&) { // Improper JSON. } } void OverlayWindow::enable() { if (!_enabled) { winkey_popup = new D2DOverlayWindow(); winkey_popup->apply_overlay_opacity(((float)overlayOpacity.value)/100.0f); winkey_popup->set_theme(theme.value); target_state = new TargetState(pressTime.value); winkey_popup->initialize(); } _enabled = true; } void OverlayWindow::disable() { if (_enabled) { winkey_popup->hide(); target_state->exit(); delete target_state; delete winkey_popup; target_state = nullptr; winkey_popup = nullptr; } _enabled = false; } bool OverlayWindow::is_enabled() { return _enabled; } intptr_t OverlayWindow::signal_event(const wchar_t * name, intptr_t data) { if (_enabled && wcscmp(name, ll_keyboard) == 0) { auto& event = *(reinterpret_cast(data)); if (event.wParam == WM_KEYDOWN || event.wParam == WM_SYSKEYDOWN || event.wParam == WM_KEYUP || event.wParam == WM_SYSKEYUP) { bool supress = target_state->signal_event(event.lParam->vkCode, event.wParam == WM_KEYDOWN || event.wParam == WM_SYSKEYDOWN); return supress ? 1 : 0; } } return 0; } void OverlayWindow::on_held() { auto active_window = get_filtered_active_window(); winkey_popup->show(active_window); } void OverlayWindow::on_held_press(DWORD vkCode) { winkey_popup->animate(vkCode); } void OverlayWindow::was_hidden() { target_state->was_hiden(); } void OverlayWindow::destroy() { delete this; instance = nullptr; } void OverlayWindow::init_settings() { try { PowerToysSettings::PowerToyValues settings = PowerToysSettings::PowerToyValues::load_from_settings_file(OverlayWindow::get_name()); if (settings.is_int_value(pressTime.name)) { pressTime.value = settings.get_int_value(pressTime.name); } if (settings.is_int_value(overlayOpacity.name)) { overlayOpacity.value = settings.get_int_value(overlayOpacity.name); } if (settings.is_string_value(theme.name)) { theme.value = settings.get_string_value(theme.name); } } catch (std::exception&) { // Error while loading from the settings file. Just let default values stay as they are. } }