Format shortcut_guide according to .clang-format

This commit is contained in:
yuyoyuppe 2019-12-06 14:07:54 +03:00 committed by yuyoyuppe
parent 946e74a918
commit f22a30ca87
10 changed files with 1395 additions and 1171 deletions

View File

@ -5,8 +5,10 @@
#include "overlay_window.h" #include "overlay_window.h"
#include "trace.h" #include "trace.h"
BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved) { BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved)
switch (ul_reason_for_call) { {
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH: case DLL_PROCESS_ATTACH:
Trace::RegisterProvider(); Trace::RegisterProvider();
break; break;
@ -20,11 +22,15 @@ BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReser
return TRUE; return TRUE;
} }
extern "C" __declspec(dllexport) PowertoyModuleIface* __cdecl powertoy_create() { extern "C" __declspec(dllexport) PowertoyModuleIface* __cdecl powertoy_create()
if (!instance) { {
if (!instance)
{
instance = new OverlayWindow(); instance = new OverlayWindow();
return instance; return instance;
} else { }
else
{
return nullptr; return nullptr;
} }
} }

View File

@ -1,18 +1,21 @@
#include "pch.h" #include "pch.h"
#include "keyboard_state.h" #include "keyboard_state.h"
bool winkey_held() { bool winkey_held()
{
auto left = GetAsyncKeyState(VK_LWIN); auto left = GetAsyncKeyState(VK_LWIN);
auto right = GetAsyncKeyState(VK_RWIN); auto right = GetAsyncKeyState(VK_RWIN);
return (left & 0x8000) || (right & 0x8000); return (left & 0x8000) || (right & 0x8000);
} }
bool only_winkey_key_held() { bool only_winkey_key_held()
{
/* There are situations, when some of the keys are not registered correctly by /* There are situations, when some of the keys are not registered correctly by
GetKeyboardState. The M key can get stuck as "pressed" after Win+M, and GetKeyboardState. The M key can get stuck as "pressed" after Win+M, and
Shift etc. keys are not always reported as expected. Shift etc. keys are not always reported as expected.
*/ */
for (int vk = 0; vk <= VK_OEM_CLEAR; ++vk) { for (int vk = 0; vk <= VK_OEM_CLEAR; ++vk)
{
if (vk == VK_LWIN || vk == VK_RWIN) if (vk == VK_LWIN || vk == VK_RWIN)
continue; continue;
if (GetAsyncKeyState(vk) & 0x8000) if (GetAsyncKeyState(vk) & 0x8000)

View File

@ -7,7 +7,8 @@
#include "shortcut_guide.h" #include "shortcut_guide.h"
#include "trace.h" #include "trace.h"
D2DOverlaySVG& D2DOverlaySVG::load(const std::wstring& filename, ID2D1DeviceContext5* d2d_dc) { D2DOverlaySVG& D2DOverlaySVG::load(const std::wstring& filename, ID2D1DeviceContext5* d2d_dc)
{
D2DSVG::load(filename, d2d_dc); D2DSVG::load(filename, d2d_dc);
window_group = nullptr; window_group = nullptr;
thumbnail_top_left = {}; thumbnail_top_left = {};
@ -16,9 +17,11 @@ D2DOverlaySVG& D2DOverlaySVG::load(const std::wstring& filename, ID2D1DeviceCont
return *this; return *this;
} }
D2DOverlaySVG& D2DOverlaySVG::resize(int x, int y, int width, int height, float fill, float max_scale) { D2DOverlaySVG& D2DOverlaySVG::resize(int x, int y, int width, int height, float fill, float max_scale)
{
D2DSVG::resize(x, y, width, height, fill, max_scale); D2DSVG::resize(x, y, width, height, fill, max_scale);
if (thumbnail_bottom_right.x != 0 && thumbnail_bottom_right.y != 0) { if (thumbnail_bottom_right.x != 0 && thumbnail_bottom_right.y != 0)
{
auto scaled_top_left = transform.TransformPoint(thumbnail_top_left); auto scaled_top_left = transform.TransformPoint(thumbnail_top_left);
auto scanled_bottom_right = transform.TransformPoint(thumbnail_bottom_right); auto scanled_bottom_right = transform.TransformPoint(thumbnail_bottom_right);
thumbnail_scaled_rect.left = (int)scaled_top_left.x; thumbnail_scaled_rect.left = (int)scaled_top_left.x;
@ -29,7 +32,8 @@ D2DOverlaySVG& D2DOverlaySVG::resize(int x, int y, int width, int height, float
return *this; return *this;
} }
D2DOverlaySVG& D2DOverlaySVG::find_thumbnail(const std::wstring& id) { D2DOverlaySVG& D2DOverlaySVG::find_thumbnail(const std::wstring& id)
{
winrt::com_ptr<ID2D1SvgElement> thumbnail_box; winrt::com_ptr<ID2D1SvgElement> thumbnail_box;
winrt::check_hresult(svg->FindElementById(id.c_str(), thumbnail_box.put())); winrt::check_hresult(svg->FindElementById(id.c_str(), thumbnail_box.put()));
winrt::check_hresult(thumbnail_box->GetAttributeValue(L"x", &thumbnail_top_left.x)); winrt::check_hresult(thumbnail_box->GetAttributeValue(L"x", &thumbnail_top_left.x));
@ -41,20 +45,24 @@ D2DOverlaySVG& D2DOverlaySVG::find_thumbnail(const std::wstring& id) {
return *this; return *this;
} }
D2DOverlaySVG& D2DOverlaySVG::find_window_group(const std::wstring& id) { D2DOverlaySVG& D2DOverlaySVG::find_window_group(const std::wstring& id)
{
window_group = nullptr; window_group = nullptr;
winrt::check_hresult(svg->FindElementById(id.c_str(), window_group.put())); winrt::check_hresult(svg->FindElementById(id.c_str(), window_group.put()));
return *this; return *this;
} }
ScaleResult D2DOverlaySVG::get_thumbnail_rect_and_scale(int x_offset, int y_offset, int window_cx, int window_cy, float fill) { ScaleResult D2DOverlaySVG::get_thumbnail_rect_and_scale(int x_offset, int y_offset, int window_cx, int window_cy, float fill)
if (thumbnail_bottom_right.x == 0 && thumbnail_bottom_right.y == 0) { {
if (thumbnail_bottom_right.x == 0 && thumbnail_bottom_right.y == 0)
{
return {}; return {};
} }
int thumbnail_scaled_rect_width = thumbnail_scaled_rect.right - thumbnail_scaled_rect.left; int thumbnail_scaled_rect_width = thumbnail_scaled_rect.right - thumbnail_scaled_rect.left;
int thumbnail_scaled_rect_heigh = thumbnail_scaled_rect.bottom - thumbnail_scaled_rect.top; int thumbnail_scaled_rect_heigh = thumbnail_scaled_rect.bottom - thumbnail_scaled_rect.top;
if (thumbnail_scaled_rect_heigh == 0 || thumbnail_scaled_rect_width == 0 || if (thumbnail_scaled_rect_heigh == 0 || thumbnail_scaled_rect_width == 0 ||
window_cx == 0 || window_cy == 0) { window_cx == 0 || window_cy == 0)
{
return {}; return {};
} }
float scale_h = fill * thumbnail_scaled_rect_width / window_cx; float scale_h = fill * thumbnail_scaled_rect_width / window_cx;
@ -71,29 +79,36 @@ ScaleResult D2DOverlaySVG::get_thumbnail_rect_and_scale(int x_offset, int y_offs
return result; return result;
} }
winrt::com_ptr<ID2D1SvgElement> D2DOverlaySVG::find_element(const std::wstring& id) { winrt::com_ptr<ID2D1SvgElement> D2DOverlaySVG::find_element(const std::wstring& id)
{
winrt::com_ptr<ID2D1SvgElement> element; winrt::com_ptr<ID2D1SvgElement> element;
winrt::check_hresult(svg->FindElementById(id.c_str(), element.put())); winrt::check_hresult(svg->FindElementById(id.c_str(), element.put()));
return element; return element;
} }
D2DOverlaySVG& D2DOverlaySVG::toggle_window_group(bool active) { D2DOverlaySVG& D2DOverlaySVG::toggle_window_group(bool active)
if (window_group) { {
if (window_group)
{
window_group->SetAttributeValue(L"fill-opacity", active ? 1.0f : 0.3f); window_group->SetAttributeValue(L"fill-opacity", active ? 1.0f : 0.3f);
} }
return *this; return *this;
} }
D2D1_RECT_F D2DOverlaySVG::get_maximize_label() const { D2D1_RECT_F D2DOverlaySVG::get_maximize_label() const
{
D2D1_RECT_F result; D2D1_RECT_F result;
auto height = (float)(thumbnail_scaled_rect.bottom - thumbnail_scaled_rect.top); auto height = (float)(thumbnail_scaled_rect.bottom - thumbnail_scaled_rect.top);
auto width = (float)(thumbnail_scaled_rect.right - thumbnail_scaled_rect.left); auto width = (float)(thumbnail_scaled_rect.right - thumbnail_scaled_rect.left);
if (width >= height) { if (width >= height)
{
result.top = thumbnail_scaled_rect.bottom + height * 0.210f; result.top = thumbnail_scaled_rect.bottom + height * 0.210f;
result.bottom = thumbnail_scaled_rect.bottom + height * 0.310f; result.bottom = thumbnail_scaled_rect.bottom + height * 0.310f;
result.left = thumbnail_scaled_rect.left + width * 0.009f; result.left = thumbnail_scaled_rect.left + width * 0.009f;
result.right = thumbnail_scaled_rect.right + width * 0.009f; result.right = thumbnail_scaled_rect.right + width * 0.009f;
} else { }
else
{
result.top = thumbnail_scaled_rect.top + height * 0.323f; result.top = thumbnail_scaled_rect.top + height * 0.323f;
result.bottom = thumbnail_scaled_rect.top + height * 0.398f; result.bottom = thumbnail_scaled_rect.top + height * 0.398f;
result.left = (float)thumbnail_scaled_rect.right; result.left = (float)thumbnail_scaled_rect.right;
@ -101,16 +116,20 @@ D2D1_RECT_F D2DOverlaySVG::get_maximize_label() const {
} }
return result; return result;
} }
D2D1_RECT_F D2DOverlaySVG::get_minimize_label() const { D2D1_RECT_F D2DOverlaySVG::get_minimize_label() const
{
D2D1_RECT_F result; D2D1_RECT_F result;
auto height = (float)(thumbnail_scaled_rect.bottom - thumbnail_scaled_rect.top); auto height = (float)(thumbnail_scaled_rect.bottom - thumbnail_scaled_rect.top);
auto width = (float)(thumbnail_scaled_rect.right - thumbnail_scaled_rect.left); auto width = (float)(thumbnail_scaled_rect.right - thumbnail_scaled_rect.left);
if (width >= height) { if (width >= height)
{
result.top = thumbnail_scaled_rect.bottom + height * 0.8f; result.top = thumbnail_scaled_rect.bottom + height * 0.8f;
result.bottom = thumbnail_scaled_rect.bottom + height * 0.9f; result.bottom = thumbnail_scaled_rect.bottom + height * 0.9f;
result.left = thumbnail_scaled_rect.left + width * 0.009f; result.left = thumbnail_scaled_rect.left + width * 0.009f;
result.right = thumbnail_scaled_rect.right + width * 0.009f; result.right = thumbnail_scaled_rect.right + width * 0.009f;
} else { }
else
{
result.top = thumbnail_scaled_rect.top + height * 0.725f; result.top = thumbnail_scaled_rect.top + height * 0.725f;
result.bottom = thumbnail_scaled_rect.top + height * 0.800f; result.bottom = thumbnail_scaled_rect.top + height * 0.800f;
result.left = (float)thumbnail_scaled_rect.right; result.left = (float)thumbnail_scaled_rect.right;
@ -118,16 +137,20 @@ D2D1_RECT_F D2DOverlaySVG::get_minimize_label() const {
} }
return result; return result;
} }
D2D1_RECT_F D2DOverlaySVG::get_snap_left() const { D2D1_RECT_F D2DOverlaySVG::get_snap_left() const
{
D2D1_RECT_F result; D2D1_RECT_F result;
auto height = (float)(thumbnail_scaled_rect.bottom - thumbnail_scaled_rect.top); auto height = (float)(thumbnail_scaled_rect.bottom - thumbnail_scaled_rect.top);
auto width = (float)(thumbnail_scaled_rect.right - thumbnail_scaled_rect.left); auto width = (float)(thumbnail_scaled_rect.right - thumbnail_scaled_rect.left);
if (width >= height) { if (width >= height)
{
result.top = thumbnail_scaled_rect.bottom + height * 0.5f; result.top = thumbnail_scaled_rect.bottom + height * 0.5f;
result.bottom = thumbnail_scaled_rect.bottom + height * 0.6f; result.bottom = thumbnail_scaled_rect.bottom + height * 0.6f;
result.left = thumbnail_scaled_rect.left + width * 0.009f; result.left = thumbnail_scaled_rect.left + width * 0.009f;
result.right = thumbnail_scaled_rect.left + width * 0.339f; result.right = thumbnail_scaled_rect.left + width * 0.339f;
} else { }
else
{
result.top = thumbnail_scaled_rect.top + height * 0.523f; result.top = thumbnail_scaled_rect.top + height * 0.523f;
result.bottom = thumbnail_scaled_rect.top + height * 0.598f; result.bottom = thumbnail_scaled_rect.top + height * 0.598f;
result.left = (float)thumbnail_scaled_rect.right; result.left = (float)thumbnail_scaled_rect.right;
@ -135,16 +158,20 @@ D2D1_RECT_F D2DOverlaySVG::get_snap_left() const {
} }
return result; return result;
} }
D2D1_RECT_F D2DOverlaySVG::get_snap_right() const { D2D1_RECT_F D2DOverlaySVG::get_snap_right() const
{
D2D1_RECT_F result; D2D1_RECT_F result;
auto height = (float)(thumbnail_scaled_rect.bottom - thumbnail_scaled_rect.top); auto height = (float)(thumbnail_scaled_rect.bottom - thumbnail_scaled_rect.top);
auto width = (float)(thumbnail_scaled_rect.right - thumbnail_scaled_rect.left); auto width = (float)(thumbnail_scaled_rect.right - thumbnail_scaled_rect.left);
if (width >= height) { if (width >= height)
{
result.top = thumbnail_scaled_rect.bottom + height * 0.5f; result.top = thumbnail_scaled_rect.bottom + height * 0.5f;
result.bottom = thumbnail_scaled_rect.bottom + height * 0.6f; result.bottom = thumbnail_scaled_rect.bottom + height * 0.6f;
result.left = thumbnail_scaled_rect.left + width * 0.679f; result.left = thumbnail_scaled_rect.left + width * 0.679f;
result.right = thumbnail_scaled_rect.right + width * 1.009f; result.right = thumbnail_scaled_rect.right + width * 1.009f;
} else { }
else
{
result.top = thumbnail_scaled_rect.top + height * 0.523f; result.top = thumbnail_scaled_rect.top + height * 0.523f;
result.bottom = thumbnail_scaled_rect.top + height * 0.598f; result.bottom = thumbnail_scaled_rect.top + height * 0.598f;
result.left = (float)thumbnail_scaled_rect.right + width; result.left = (float)thumbnail_scaled_rect.right + width;
@ -153,19 +180,23 @@ D2D1_RECT_F D2DOverlaySVG::get_snap_right() const {
return result; return result;
} }
D2DOverlayWindow::D2DOverlayWindow() :
D2DOverlayWindow::D2DOverlayWindow() : total_screen({}), animation(0.3) { total_screen({}), animation(0.3)
{
tasklist_thread = std::thread([&] { tasklist_thread = std::thread([&] {
while (running) { while (running)
{
// Removing <std::mutex> causes C3538 on std::unique_lock lock(mutex); in show(..) // Removing <std::mutex> causes C3538 on std::unique_lock lock(mutex); in show(..)
std::unique_lock<std::mutex> lock(tasklist_cv_mutex); std::unique_lock<std::mutex> lock(tasklist_cv_mutex);
tasklist_cv.wait(lock, [&] { return !running || tasklist_update; }); tasklist_cv.wait(lock, [&] { return !running || tasklist_update; });
if (!running) if (!running)
return; return;
lock.unlock(); lock.unlock();
while (running && tasklist_update) { while (running && tasklist_update)
{
std::vector<TasklistButton> buttons; std::vector<TasklistButton> buttons;
if (tasklist.update_buttons(buttons)) { if (tasklist.update_buttons(buttons))
{
std::unique_lock lock(mutex); std::unique_lock lock(mutex);
tasklist_buttons.swap(buttons); tasklist_buttons.swap(buttons);
} }
@ -175,31 +206,39 @@ D2DOverlayWindow::D2DOverlayWindow() : total_screen({}), animation(0.3) {
}); });
} }
void D2DOverlayWindow::show(HWND active_window) { void D2DOverlayWindow::show(HWND active_window)
{
std::unique_lock lock(mutex); std::unique_lock lock(mutex);
tasklist_buttons.clear(); tasklist_buttons.clear();
this->active_window = active_window; this->active_window = active_window;
auto old_bck = colors.start_color_menu; auto old_bck = colors.start_color_menu;
auto colors_updated = colors.update(); auto colors_updated = colors.update();
auto new_light_mode = (theme_setting == Light) || (theme_setting == System && colors.light_mode); auto new_light_mode = (theme_setting == Light) || (theme_setting == System && colors.light_mode);
if (initialized && (colors_updated || light_mode != new_light_mode)) { if (initialized && (colors_updated || light_mode != new_light_mode))
{
// update background colors // update background colors
landscape.recolor(old_bck, colors.start_color_menu); landscape.recolor(old_bck, colors.start_color_menu);
portrait.recolor(old_bck, colors.start_color_menu); portrait.recolor(old_bck, colors.start_color_menu);
for (auto& arrow : arrows) { for (auto& arrow : arrows)
{
arrow.recolor(old_bck, colors.start_color_menu); arrow.recolor(old_bck, colors.start_color_menu);
} }
light_mode = new_light_mode; light_mode = new_light_mode;
if (light_mode) { if (light_mode)
{
landscape.recolor(0xDDDDDD, 0x222222); landscape.recolor(0xDDDDDD, 0x222222);
portrait.recolor(0xDDDDDD, 0x222222); portrait.recolor(0xDDDDDD, 0x222222);
for (auto& arrow : arrows) { for (auto& arrow : arrows)
{
arrow.recolor(0xDDDDDD, 0x222222); arrow.recolor(0xDDDDDD, 0x222222);
} }
} else { }
else
{
landscape.recolor(0x222222, 0xDDDDDD); landscape.recolor(0x222222, 0xDDDDDD);
portrait.recolor(0x222222, 0xDDDDDD); portrait.recolor(0x222222, 0xDDDDDD);
for (auto& arrow : arrows) { for (auto& arrow : arrows)
{
arrow.recolor(0x222222, 0xDDDDDD); arrow.recolor(0x222222, 0xDDDDDD);
} }
} }
@ -207,7 +246,8 @@ void D2DOverlayWindow::show(HWND active_window) {
monitors = MonitorInfo::GetMonitors(true); monitors = MonitorInfo::GetMonitors(true);
// calculate the rect covering all the screens // calculate the rect covering all the screens
total_screen = ScreenSize(monitors[0].rect); total_screen = ScreenSize(monitors[0].rect);
for (auto& monitor : monitors) { for (auto& monitor : monitors)
{
total_screen.rect.left = min(total_screen.rect.left, monitor.rect.left); total_screen.rect.left = min(total_screen.rect.left, monitor.rect.left);
total_screen.rect.top = min(total_screen.rect.top, monitor.rect.top); total_screen.rect.top = min(total_screen.rect.top, monitor.rect.top);
total_screen.rect.right = max(total_screen.rect.right, monitor.rect.right); total_screen.rect.right = max(total_screen.rect.right, monitor.rect.right);
@ -221,7 +261,8 @@ void D2DOverlayWindow::show(HWND active_window) {
total_screen.rect.top += monitor_dy; total_screen.rect.top += monitor_dy;
total_screen.rect.bottom += monitor_dy; total_screen.rect.bottom += monitor_dy;
tasklist.update(); tasklist.update();
if (active_window) { if (active_window)
{
// Ignore errors, if this fails we will just not show the thumbnail // Ignore errors, if this fails we will just not show the thumbnail
DwmRegisterThumbnail(hwnd, active_window, &thumbnail); DwmRegisterThumbnail(hwnd, active_window, &thumbnail);
} }
@ -234,7 +275,8 @@ void D2DOverlayWindow::show(HWND active_window) {
// Check if taskbar is auto-hidden. If so, don't display the number arrows // Check if taskbar is auto-hidden. If so, don't display the number arrows
APPBARDATA param = {}; APPBARDATA param = {};
param.cbSize = sizeof(APPBARDATA); param.cbSize = sizeof(APPBARDATA);
if ((UINT)SHAppBarMessage(ABM_GETSTATE, &param) != ABS_AUTOHIDE) { if ((UINT)SHAppBarMessage(ABM_GETSTATE, &param) != ABS_AUTOHIDE)
{
tasklist_cv_mutex.lock(); tasklist_cv_mutex.lock();
tasklist_update = true; tasklist_update = true;
tasklist_cv_mutex.unlock(); tasklist_cv_mutex.unlock();
@ -242,31 +284,41 @@ void D2DOverlayWindow::show(HWND active_window) {
} }
} }
void D2DOverlayWindow::animate(int vk_code) { void D2DOverlayWindow::animate(int vk_code)
{
animate(vk_code, 0); animate(vk_code, 0);
} }
void D2DOverlayWindow::animate(int vk_code, int offset) { void D2DOverlayWindow::animate(int vk_code, int offset)
if (!initialized || !use_overlay) { {
if (!initialized || !use_overlay)
{
return; return;
} }
bool done = false; bool done = false;
for (auto& animation : key_animations) { for (auto& animation : key_animations)
if (animation.vk_code == vk_code) { {
if (animation.vk_code == vk_code)
{
animation.animation.reset(0.1, 0, 1); animation.animation.reset(0.1, 0, 1);
done = true; done = true;
} }
} }
if (done) { if (done)
{
return; return;
} }
AnimateKeys animation; AnimateKeys animation;
std::wstring id; std::wstring id;
animation.vk_code = vk_code; animation.vk_code = vk_code;
winrt::com_ptr<ID2D1SvgElement> button_letter, parrent; winrt::com_ptr<ID2D1SvgElement> button_letter, parrent;
if (vk_code >= 0x41 && vk_code <= 0x5A) { if (vk_code >= 0x41 && vk_code <= 0x5A)
{
id.push_back('A' + (vk_code - 0x41)); id.push_back('A' + (vk_code - 0x41));
} else { }
switch (vk_code) { else
{
switch (vk_code)
{
case VK_SNAPSHOT: case VK_SNAPSHOT:
case VK_PRINT: case VK_PRINT:
id = L"PrnScr"; id = L"PrnScr";
@ -307,23 +359,28 @@ void D2DOverlayWindow::animate(int vk_code, int offset) {
} }
} }
if (offset > 0) { if (offset > 0)
{
id += L"_" + std::to_wstring(offset); id += L"_" + std::to_wstring(offset);
} }
button_letter = use_overlay->find_element(id); button_letter = use_overlay->find_element(id);
if (!button_letter) { if (!button_letter)
{
return; return;
} }
button_letter->GetParent(parrent.put()); button_letter->GetParent(parrent.put());
if (!parrent) { if (!parrent)
{
return; return;
} }
parrent->GetPreviousChild(button_letter.get(), animation.button.put()); parrent->GetPreviousChild(button_letter.get(), animation.button.put());
if (!animation.button || !animation.button->IsAttributeSpecified(L"fill")) { if (!animation.button || !animation.button->IsAttributeSpecified(L"fill"))
{
animation.button = nullptr; animation.button = nullptr;
parrent->GetNextChild(button_letter.get(), animation.button.put()); parrent->GetNextChild(button_letter.get(), animation.button.put());
} }
if (!animation.button || !animation.button->IsAttributeSpecified(L"fill")) { if (!animation.button || !animation.button->IsAttributeSpecified(L"fill"))
{
return; return;
} }
winrt::com_ptr<ID2D1SvgPaint> paint; winrt::com_ptr<ID2D1SvgPaint> paint;
@ -336,28 +393,33 @@ void D2DOverlayWindow::animate(int vk_code, int offset) {
key_pressed.push_back(vk_code); key_pressed.push_back(vk_code);
} }
void D2DOverlayWindow::on_show() { void D2DOverlayWindow::on_show()
{
// show override does everything // show override does everything
} }
void D2DOverlayWindow::on_hide() { void D2DOverlayWindow::on_hide()
{
tasklist_cv_mutex.lock(); tasklist_cv_mutex.lock();
tasklist_update = false; tasklist_update = false;
tasklist_cv_mutex.unlock(); tasklist_cv_mutex.unlock();
tasklist_cv.notify_one(); tasklist_cv.notify_one();
if (thumbnail) { if (thumbnail)
{
DwmUnregisterThumbnail(thumbnail); DwmUnregisterThumbnail(thumbnail);
} }
std::chrono::steady_clock::time_point shown_end_time = std::chrono::steady_clock::now(); std::chrono::steady_clock::time_point shown_end_time = std::chrono::steady_clock::now();
// Trace the event only if the overaly window was visible. // Trace the event only if the overaly window was visible.
if (shown_start_time.time_since_epoch().count() > 0) { if (shown_start_time.time_since_epoch().count() > 0)
{
Trace::HideGuide(std::chrono::duration_cast<std::chrono::milliseconds>(shown_end_time - shown_start_time).count(), key_pressed); Trace::HideGuide(std::chrono::duration_cast<std::chrono::milliseconds>(shown_end_time - shown_start_time).count(), key_pressed);
shown_start_time = {}; shown_start_time = {};
} }
key_pressed.clear(); key_pressed.clear();
} }
D2DOverlayWindow::~D2DOverlayWindow() { D2DOverlayWindow::~D2DOverlayWindow()
{
tasklist_cv_mutex.lock(); tasklist_cv_mutex.lock();
running = false; running = false;
tasklist_cv_mutex.unlock(); tasklist_cv_mutex.unlock();
@ -365,22 +427,31 @@ D2DOverlayWindow::~D2DOverlayWindow() {
tasklist_thread.join(); tasklist_thread.join();
} }
void D2DOverlayWindow::apply_overlay_opacity(float opacity) { void D2DOverlayWindow::apply_overlay_opacity(float opacity)
if (opacity <= 0.0f) { {
if (opacity <= 0.0f)
{
opacity = 0.0f; opacity = 0.0f;
} }
if (opacity >= 1.0f) { if (opacity >= 1.0f)
{
opacity = 1.0f; opacity = 1.0f;
} }
overlay_opacity = opacity; overlay_opacity = opacity;
} }
void D2DOverlayWindow::set_theme(const std::wstring& theme) { void D2DOverlayWindow::set_theme(const std::wstring& theme)
if (theme == L"light") { {
if (theme == L"light")
{
theme_setting = Light; theme_setting = Light;
} else if (theme == L"dark") { }
else if (theme == L"dark")
{
theme_setting = Dark; theme_setting = Dark;
} else { }
else
{
theme_setting = System; theme_setting = System;
} }
} }
@ -388,18 +459,22 @@ void D2DOverlayWindow::set_theme(const std::wstring& theme) {
/* Hide the window but do not call on_hide(). Use this to quickly hide the window when needed. /* Hide the window but do not call on_hide(). Use this to quickly hide the window when needed.
Note, that a proper hide should be made after this before showing the window again. Note, that a proper hide should be made after this before showing the window again.
*/ */
void D2DOverlayWindow::quick_hide() { void D2DOverlayWindow::quick_hide()
{
ShowWindow(hwnd, SW_HIDE); ShowWindow(hwnd, SW_HIDE);
if (thumbnail) { if (thumbnail)
{
DwmUnregisterThumbnail(thumbnail); DwmUnregisterThumbnail(thumbnail);
} }
} }
float D2DOverlayWindow::get_overlay_opacity() { float D2DOverlayWindow::get_overlay_opacity()
{
return overlay_opacity; return overlay_opacity;
} }
void D2DOverlayWindow::init() { void D2DOverlayWindow::init()
{
colors.update(); colors.update();
landscape.load(L"svgs\\overlay.svg", d2d_dc.get()) landscape.load(L"svgs\\overlay.svg", d2d_dc.get())
.find_thumbnail(L"path-1") .find_thumbnail(L"path-1")
@ -411,28 +486,34 @@ void D2DOverlayWindow::init() {
.recolor(0x000000, colors.start_color_menu); .recolor(0x000000, colors.start_color_menu);
no_active.load(L"svgs\\no_active_window.svg", d2d_dc.get()); no_active.load(L"svgs\\no_active_window.svg", d2d_dc.get());
arrows.resize(10); arrows.resize(10);
for (unsigned i = 0; i < arrows.size(); ++i) { for (unsigned i = 0; i < arrows.size(); ++i)
arrows[i].load(L"svgs\\" + std::to_wstring((i + 1) % 10) + L".svg", d2d_dc.get()) {
.recolor(0x000000, colors.start_color_menu); arrows[i].load(L"svgs\\" + std::to_wstring((i + 1) % 10) + L".svg", d2d_dc.get()).recolor(0x000000, colors.start_color_menu);
} }
light_mode = (theme_setting == Light) || (theme_setting == System && colors.light_mode); light_mode = (theme_setting == Light) || (theme_setting == System && colors.light_mode);
if (!light_mode) { if (!light_mode)
{
landscape.recolor(0x222222, 0xDDDDDD); landscape.recolor(0x222222, 0xDDDDDD);
portrait.recolor(0x222222, 0xDDDDDD); portrait.recolor(0x222222, 0xDDDDDD);
for (auto& arrow : arrows) { for (auto& arrow : arrows)
{
arrow.recolor(0x222222, 0xDDDDDD); arrow.recolor(0x222222, 0xDDDDDD);
} }
} }
} }
void D2DOverlayWindow::resize() { void D2DOverlayWindow::resize()
{
window_rect = *get_window_pos(hwnd); window_rect = *get_window_pos(hwnd);
float no_active_scale, font; float no_active_scale, font;
if (window_width >= window_height) { // portriat is broke right now if (window_width >= window_height)
{ // portriat is broke right now
use_overlay = &landscape; use_overlay = &landscape;
no_active_scale = 0.3f; no_active_scale = 0.3f;
font = 15.0f; font = 15.0f;
} else { }
else
{
use_overlay = &portrait; use_overlay = &portrait;
no_active_scale = 0.5f; no_active_scale = 0.5f;
font = 16.0f; font = 16.0f;
@ -447,52 +528,67 @@ void D2DOverlayWindow::resize() {
text.resize(font, use_overlay->get_scale()); text.resize(font, use_overlay->get_scale());
} }
void render_arrow(D2DSVG& arrow, TasklistButton& button, RECT window, float max_scale, ID2D1DeviceContext5* d2d_dc) { void render_arrow(D2DSVG& arrow, TasklistButton& button, RECT window, float max_scale, ID2D1DeviceContext5* d2d_dc)
{
int dx = 0, dy = 0; int dx = 0, dy = 0;
// Calculate taskbar orientation // Calculate taskbar orientation
arrow.toggle_element(L"left", false); arrow.toggle_element(L"left", false);
arrow.toggle_element(L"right", false); arrow.toggle_element(L"right", false);
arrow.toggle_element(L"top", false); arrow.toggle_element(L"top", false);
arrow.toggle_element(L"bottom", false); arrow.toggle_element(L"bottom", false);
if (button.x <= window.left) { // taskbar on left if (button.x <= window.left)
{ // taskbar on left
dx = 1; dx = 1;
arrow.toggle_element(L"left", true); arrow.toggle_element(L"left", true);
} }
if (button.x >= window.right) { // taskbar on right if (button.x >= window.right)
{ // taskbar on right
dx = -1; dx = -1;
arrow.toggle_element(L"right", true); arrow.toggle_element(L"right", true);
} }
if (button.y <= window.top) { // taskbar on top if (button.y <= window.top)
{ // taskbar on top
dy = 1; dy = 1;
arrow.toggle_element(L"top", true); arrow.toggle_element(L"top", true);
} }
if (button.y >= window.bottom) { // taskbar on bottom if (button.y >= window.bottom)
{ // taskbar on bottom
dy = -1; dy = -1;
arrow.toggle_element(L"bottom", true); arrow.toggle_element(L"bottom", true);
} }
double arrow_ratio = (double)arrow.height() / arrow.width(); double arrow_ratio = (double)arrow.height() / arrow.width();
if (dy != 0) { if (dy != 0)
{
// assume button is 25% wider than taller, +10% to make room for each of the arrows that are hidden // assume button is 25% wider than taller, +10% to make room for each of the arrows that are hidden
auto render_arrow_width = (int)(button.height * 1.25f * 1.2f); auto render_arrow_width = (int)(button.height * 1.25f * 1.2f);
auto render_arrow_height = (int)(render_arrow_width * arrow_ratio); auto render_arrow_height = (int)(render_arrow_width * arrow_ratio);
arrow.resize(button.x + (button.width - render_arrow_width) / 2, arrow.resize(button.x + (button.width - render_arrow_width) / 2,
dy == -1 ? button.y - render_arrow_height : 0, dy == -1 ? button.y - render_arrow_height : 0,
render_arrow_width, render_arrow_height, 0.95f, max_scale) render_arrow_width,
render_arrow_height,
0.95f,
max_scale)
.render(d2d_dc); .render(d2d_dc);
} }
else { else
{
// same as above - make room for the hidden arrow // same as above - make room for the hidden arrow
auto render_arrow_height = (int)(button.height * 1.2f); auto render_arrow_height = (int)(button.height * 1.2f);
auto render_arrow_width = (int)(render_arrow_height / arrow_ratio); auto render_arrow_width = (int)(render_arrow_height / arrow_ratio);
arrow.resize(dx == -1 ? button.x - render_arrow_width : 0, arrow.resize(dx == -1 ? button.x - render_arrow_width : 0,
button.y + (button.height - render_arrow_height) / 2, button.y + (button.height - render_arrow_height) / 2,
render_arrow_width, render_arrow_height, 0.95f, max_scale) render_arrow_width,
render_arrow_height,
0.95f,
max_scale)
.render(d2d_dc); .render(d2d_dc);
} }
} }
bool D2DOverlayWindow::show_thumbnail(const RECT& rect, double alpha) { bool D2DOverlayWindow::show_thumbnail(const RECT& rect, double alpha)
if (!thumbnail) { {
if (!thumbnail)
{
return false; return false;
} }
DWM_THUMBNAIL_PROPERTIES thumb_properties; DWM_THUMBNAIL_PROPERTIES thumb_properties;
@ -501,21 +597,25 @@ bool D2DOverlayWindow::show_thumbnail(const RECT& rect, double alpha) {
thumb_properties.fVisible = TRUE; thumb_properties.fVisible = TRUE;
thumb_properties.opacity = (BYTE)(255 * alpha); thumb_properties.opacity = (BYTE)(255 * alpha);
thumb_properties.rcDestination = rect; thumb_properties.rcDestination = rect;
if (DwmUpdateThumbnailProperties(thumbnail, &thumb_properties) != S_OK) { if (DwmUpdateThumbnailProperties(thumbnail, &thumb_properties) != S_OK)
{
return false; return false;
} }
return true; return true;
} }
void D2DOverlayWindow::hide_thumbnail() { void D2DOverlayWindow::hide_thumbnail()
{
DWM_THUMBNAIL_PROPERTIES thumb_properties; DWM_THUMBNAIL_PROPERTIES thumb_properties;
thumb_properties.dwFlags = DWM_TNP_VISIBLE; thumb_properties.dwFlags = DWM_TNP_VISIBLE;
thumb_properties.fVisible = FALSE; thumb_properties.fVisible = FALSE;
DwmUpdateThumbnailProperties(thumbnail, &thumb_properties); DwmUpdateThumbnailProperties(thumbnail, &thumb_properties);
} }
void D2DOverlayWindow::render(ID2D1DeviceContext5* d2d_dc) { void D2DOverlayWindow::render(ID2D1DeviceContext5* d2d_dc)
if (!winkey_held() || is_start_visible()) { {
if (!winkey_held() || is_start_visible())
{
hide(); hide();
instance->was_hidden(); instance->was_hidden();
return; return;
@ -525,20 +625,27 @@ void D2DOverlayWindow::render(ID2D1DeviceContext5* d2d_dc) {
auto current_anim_value = (float)animation.value(Animation::AnimFunctions::LINEAR); auto current_anim_value = (float)animation.value(Animation::AnimFunctions::LINEAR);
SetLayeredWindowAttributes(hwnd, 0, (int)(255 * current_anim_value), LWA_ALPHA); SetLayeredWindowAttributes(hwnd, 0, (int)(255 * current_anim_value), LWA_ALPHA);
double pos_anim_value = 1 - animation.value(Animation::AnimFunctions::EASE_OUT_EXPO); double pos_anim_value = 1 - animation.value(Animation::AnimFunctions::EASE_OUT_EXPO);
if (!tasklist_buttons.empty()) { if (!tasklist_buttons.empty())
if (tasklist_buttons[0].x <= window_rect.left) { // taskbar on left {
if (tasklist_buttons[0].x <= window_rect.left)
{ // taskbar on left
x_offset = (int)(-pos_anim_value * use_overlay->width() * use_overlay->get_scale()); x_offset = (int)(-pos_anim_value * use_overlay->width() * use_overlay->get_scale());
} }
if (tasklist_buttons[0].x >= window_rect.right) { // taskbar on right if (tasklist_buttons[0].x >= window_rect.right)
{ // taskbar on right
x_offset = (int)(pos_anim_value * use_overlay->width() * use_overlay->get_scale()); x_offset = (int)(pos_anim_value * use_overlay->width() * use_overlay->get_scale());
} }
if (tasklist_buttons[0].y <= window_rect.top) { // taskbar on top if (tasklist_buttons[0].y <= window_rect.top)
{ // taskbar on top
y_offset = (int)(-pos_anim_value * use_overlay->height() * use_overlay->get_scale()); y_offset = (int)(-pos_anim_value * use_overlay->height() * use_overlay->get_scale());
} }
if (tasklist_buttons[0].y >= window_rect.bottom) { // taskbar on bottom if (tasklist_buttons[0].y >= window_rect.bottom)
{ // taskbar on bottom
y_offset = (int)(pos_anim_value * use_overlay->height() * use_overlay->get_scale()); y_offset = (int)(pos_anim_value * use_overlay->height() * use_overlay->get_scale());
} }
} else { }
else
{
x_offset = 0; x_offset = 0;
y_offset = (int)(pos_anim_value * use_overlay->height() * use_overlay->get_scale()); y_offset = (int)(pos_anim_value * use_overlay->height() * use_overlay->get_scale());
} }
@ -558,7 +665,8 @@ void D2DOverlayWindow::render(ID2D1DeviceContext5* d2d_dc) {
auto thumb_window = get_window_pos(active_window); auto thumb_window = get_window_pos(active_window);
bool minature_shown = active_window != nullptr && thumbnail != nullptr && thumb_window && window_state != MINIMIZED; bool minature_shown = active_window != nullptr && thumbnail != nullptr && thumb_window && window_state != MINIMIZED;
RECT client_rect; RECT client_rect;
if (thumb_window && GetClientRect(active_window, &client_rect)) { if (thumb_window && GetClientRect(active_window, &client_rect))
{
int dx = ((thumb_window->right - thumb_window->left) - (client_rect.right - client_rect.left)) / 2; int dx = ((thumb_window->right - thumb_window->left) - (client_rect.right - client_rect.left)) / 2;
int dy = ((thumb_window->bottom - thumb_window->top) - (client_rect.bottom - client_rect.top)) / 2; int dy = ((thumb_window->bottom - thumb_window->top) - (client_rect.bottom - client_rect.top)) / 2;
thumb_window->left += dx; thumb_window->left += dx;
@ -566,12 +674,14 @@ void D2DOverlayWindow::render(ID2D1DeviceContext5* d2d_dc) {
thumb_window->top += dy; thumb_window->top += dy;
thumb_window->bottom -= dy; thumb_window->bottom -= dy;
} }
if (minature_shown && thumb_window->right - thumb_window->left <= 0 || thumb_window->bottom - thumb_window->top <= 0) { if (minature_shown && thumb_window->right - thumb_window->left <= 0 || thumb_window->bottom - thumb_window->top <= 0)
{
minature_shown = false; minature_shown = false;
} }
bool render_monitors = true; bool render_monitors = true;
auto total_monitor_with_screen = total_screen; auto total_monitor_with_screen = total_screen;
if (thumb_window) { if (thumb_window)
{
total_monitor_with_screen.rect.left = min(total_monitor_with_screen.rect.left, thumb_window->left + monitor_dx); total_monitor_with_screen.rect.left = min(total_monitor_with_screen.rect.left, thumb_window->left + monitor_dx);
total_monitor_with_screen.rect.top = min(total_monitor_with_screen.rect.top, thumb_window->top + monitor_dy); total_monitor_with_screen.rect.top = min(total_monitor_with_screen.rect.top, thumb_window->top + monitor_dy);
total_monitor_with_screen.rect.right = max(total_monitor_with_screen.rect.right, thumb_window->right + monitor_dx); total_monitor_with_screen.rect.right = max(total_monitor_with_screen.rect.right, thumb_window->right + monitor_dx);
@ -579,38 +689,49 @@ void D2DOverlayWindow::render(ID2D1DeviceContext5* d2d_dc) {
} }
// Only allow the new rect beeing slight bigger. // Only allow the new rect beeing slight bigger.
if (total_monitor_with_screen.width() - total_screen.width() > (thumb_window->right - thumb_window->left) / 2 || if (total_monitor_with_screen.width() - total_screen.width() > (thumb_window->right - thumb_window->left) / 2 ||
total_monitor_with_screen.height() - total_screen.height() > (thumb_window->bottom - thumb_window->top) / 2) { total_monitor_with_screen.height() - total_screen.height() > (thumb_window->bottom - thumb_window->top) / 2)
{
render_monitors = false; render_monitors = false;
} }
if (window_state == MINIMIZED) { if (window_state == MINIMIZED)
{
total_monitor_with_screen = total_screen; total_monitor_with_screen = total_screen;
} }
auto rect_and_scale = use_overlay->get_thumbnail_rect_and_scale(0, 0, total_monitor_with_screen.width(), total_monitor_with_screen.height(), 1); auto rect_and_scale = use_overlay->get_thumbnail_rect_and_scale(0, 0, total_monitor_with_screen.width(), total_monitor_with_screen.height(), 1);
if (minature_shown) { if (minature_shown)
{
RECT thumbnail_pos; RECT thumbnail_pos;
if (render_monitors) { if (render_monitors)
{
thumbnail_pos.left = (int)((thumb_window->left + monitor_dx) * rect_and_scale.scale + rect_and_scale.rect.left); thumbnail_pos.left = (int)((thumb_window->left + monitor_dx) * rect_and_scale.scale + rect_and_scale.rect.left);
thumbnail_pos.top = (int)((thumb_window->top + monitor_dy) * rect_and_scale.scale + rect_and_scale.rect.top); thumbnail_pos.top = (int)((thumb_window->top + monitor_dy) * rect_and_scale.scale + rect_and_scale.rect.top);
thumbnail_pos.right = (int)((thumb_window->right + monitor_dx) * rect_and_scale.scale + rect_and_scale.rect.left); thumbnail_pos.right = (int)((thumb_window->right + monitor_dx) * rect_and_scale.scale + rect_and_scale.rect.left);
thumbnail_pos.bottom = (int)((thumb_window->bottom + monitor_dy) * rect_and_scale.scale + rect_and_scale.rect.top); thumbnail_pos.bottom = (int)((thumb_window->bottom + monitor_dy) * rect_and_scale.scale + rect_and_scale.rect.top);
} else { }
else
{
thumbnail_pos = use_overlay->get_thumbnail_rect_and_scale(0, 0, thumb_window->right - thumb_window->left, thumb_window->bottom - thumb_window->top, 1).rect; thumbnail_pos = use_overlay->get_thumbnail_rect_and_scale(0, 0, thumb_window->right - thumb_window->left, thumb_window->bottom - thumb_window->top, 1).rect;
} }
// If the animation is done show the thumbnail // If the animation is done show the thumbnail
// we cannot animate the thumbnail, the animation lags behind // we cannot animate the thumbnail, the animation lags behind
minature_shown = show_thumbnail(thumbnail_pos, current_anim_value); minature_shown = show_thumbnail(thumbnail_pos, current_anim_value);
} else { }
else
{
hide_thumbnail(); hide_thumbnail();
} }
if (window_state == MINIMIZED) { if (window_state == MINIMIZED)
{
render_monitors = true; render_monitors = true;
} }
// render the monitors // render the monitors
if (render_monitors) { if (render_monitors)
{
brushColor = D2D1::ColorF(colors.desktop_fill_color, minature_shown ? current_anim_value : current_anim_value * 0.3f); brushColor = D2D1::ColorF(colors.desktop_fill_color, minature_shown ? current_anim_value : current_anim_value * 0.3f);
brush = nullptr; brush = nullptr;
winrt::check_hresult(d2d_dc->CreateSolidColorBrush(brushColor, brush.put())); winrt::check_hresult(d2d_dc->CreateSolidColorBrush(brushColor, brush.put()));
for (auto& monitor : monitors) { for (auto& monitor : monitors)
{
D2D1_RECT_F monitor_rect; D2D1_RECT_F monitor_rect;
monitor_rect.left = (float)((monitor.rect.left + monitor_dx) * rect_and_scale.scale + rect_and_scale.rect.left); monitor_rect.left = (float)((monitor.rect.left + monitor_dx) * rect_and_scale.scale + rect_and_scale.rect.left);
monitor_rect.top = (float)((monitor.rect.top + monitor_dy) * rect_and_scale.scale + rect_and_scale.rect.top); monitor_rect.top = (float)((monitor.rect.top + monitor_dy) * rect_and_scale.scale + rect_and_scale.rect.top);
@ -622,7 +743,8 @@ void D2DOverlayWindow::render(ID2D1DeviceContext5* d2d_dc) {
} }
// Finalize the overlay - dimm the buttons if no thumbnail is present and show "No active window" // Finalize the overlay - dimm the buttons if no thumbnail is present and show "No active window"
use_overlay->toggle_window_group(minature_shown || window_state == MINIMIZED); use_overlay->toggle_window_group(minature_shown || window_state == MINIMIZED);
if (!minature_shown && window_state != MINIMIZED) { if (!minature_shown && window_state != MINIMIZED)
{
no_active.render(d2d_dc); no_active.render(d2d_dc);
window_state = UNKNONW; window_state = UNKNONW;
} }
@ -632,7 +754,8 @@ void D2DOverlayWindow::render(ID2D1DeviceContext5* d2d_dc) {
d2d_dc->SetTransform(popin); d2d_dc->SetTransform(popin);
// Animate keys // Animate keys
for (unsigned id = 0; id < key_animations.size();) { for (unsigned id = 0; id < key_animations.size();)
{
auto& animation = key_animations[id]; auto& animation = key_animations[id];
D2D1_COLOR_F color; D2D1_COLOR_F color;
auto value = (float)animation.animation.value(Animation::AnimFunctions::EASE_OUT_EXPO); auto value = (float)animation.animation.value(Animation::AnimFunctions::EASE_OUT_EXPO);
@ -641,11 +764,15 @@ void D2DOverlayWindow::render(ID2D1DeviceContext5* d2d_dc) {
color.g = animation.original.g + (1.0f - animation.original.g) * value; color.g = animation.original.g + (1.0f - animation.original.g) * value;
color.b = animation.original.b + (1.0f - animation.original.b) * value; color.b = animation.original.b + (1.0f - animation.original.b) * value;
animation.button->SetAttributeValue(L"fill", color); animation.button->SetAttributeValue(L"fill", color);
if (animation.animation.done()) { if (animation.animation.done())
if (value == 1) { {
if (value == 1)
{
animation.animation.reset(0.05, 1, 0); animation.animation.reset(0.05, 1, 0);
animation.animation.value(Animation::AnimFunctions::EASE_OUT_EXPO); animation.animation.value(Animation::AnimFunctions::EASE_OUT_EXPO);
} else { }
else
{
key_animations.erase(key_animations.begin() + id); key_animations.erase(key_animations.begin() + id);
continue; continue;
} }
@ -660,7 +787,8 @@ void D2DOverlayWindow::render(ID2D1DeviceContext5* d2d_dc) {
bool right_disabled = false; bool right_disabled = false;
bool up_disabled = false; bool up_disabled = false;
bool down_disabled = false; bool down_disabled = false;
switch (window_state) { switch (window_state)
{
case MINIMIZED: case MINIMIZED:
left = L"No action"; left = L"No action";
left_disabled = true; left_disabled = true;
@ -739,8 +867,10 @@ void D2DOverlayWindow::render(ID2D1DeviceContext5* d2d_dc) {
use_overlay->find_element(L"KeyRightGroup")->SetAttributeValue(L"fill-opacity", right_disabled ? 0.3f : 1.0f); use_overlay->find_element(L"KeyRightGroup")->SetAttributeValue(L"fill-opacity", right_disabled ? 0.3f : 1.0f);
text.set_aligment_left().write(d2d_dc, text_color, use_overlay->get_snap_right(), right); text.set_aligment_left().write(d2d_dc, text_color, use_overlay->get_snap_right(), right);
// ... and the arrows with numbers // ... and the arrows with numbers
for (auto&& button : tasklist_buttons) { for (auto&& button : tasklist_buttons)
if ((size_t)(button.keynum) - 1 >= arrows.size()) { {
if ((size_t)(button.keynum) - 1 >= arrows.size())
{
continue; continue;
} }
render_arrow(arrows[(size_t)(button.keynum) - 1], button, window_rect, use_overlay->get_scale(), d2d_dc); render_arrow(arrows[(size_t)(button.keynum) - 1], button, window_rect, use_overlay->get_scale(), d2d_dc);

View File

@ -7,12 +7,14 @@
#include "common/windows_colors.h" #include "common/windows_colors.h"
#include "common/tasklist_positions.h" #include "common/tasklist_positions.h"
struct ScaleResult { struct ScaleResult
{
double scale; double scale;
RECT rect; RECT rect;
}; };
class D2DOverlaySVG : public D2DSVG { class D2DOverlaySVG : public D2DSVG
{
public: public:
D2DOverlaySVG& load(const std::wstring& filename, ID2D1DeviceContext5* d2d_dc); D2DOverlaySVG& load(const std::wstring& filename, ID2D1DeviceContext5* d2d_dc);
D2DOverlaySVG& resize(int x, int y, int width, int height, float fill, float max_scale = -1.0f); D2DOverlaySVG& resize(int x, int y, int width, int height, float fill, float max_scale = -1.0f);
@ -25,6 +27,7 @@ public:
D2D1_RECT_F get_minimize_label() const; D2D1_RECT_F get_minimize_label() const;
D2D1_RECT_F get_snap_left() const; D2D1_RECT_F get_snap_left() const;
D2D1_RECT_F get_snap_right() const; D2D1_RECT_F get_snap_right() const;
private: private:
D2D1_POINT_2F thumbnail_top_left = {}; D2D1_POINT_2F thumbnail_top_left = {};
D2D1_POINT_2F thumbnail_bottom_right = {}; D2D1_POINT_2F thumbnail_bottom_right = {};
@ -32,14 +35,16 @@ private:
winrt::com_ptr<ID2D1SvgElement> window_group; winrt::com_ptr<ID2D1SvgElement> window_group;
}; };
struct AnimateKeys { struct AnimateKeys
{
Animation animation; Animation animation;
D2D1_COLOR_F original; D2D1_COLOR_F original;
winrt::com_ptr<ID2D1SvgElement> button; winrt::com_ptr<ID2D1SvgElement> button;
int vk_code; int vk_code;
}; };
class D2DOverlayWindow : public D2DWindow { class D2DOverlayWindow : public D2DWindow
{
public: public:
D2DOverlayWindow(); D2DOverlayWindow();
void show(HWND active_window); void show(HWND active_window);
@ -48,6 +53,7 @@ public:
void apply_overlay_opacity(float opacity); void apply_overlay_opacity(float opacity);
void set_theme(const std::wstring& theme); void set_theme(const std::wstring& theme);
void quick_hide(); void quick_hide();
private: private:
void animate(int vk_code, int offset); void animate(int vk_code, int offset);
bool show_thumbnail(const RECT& rect, double alpha); bool show_thumbnail(const RECT& rect, double alpha);
@ -84,8 +90,11 @@ private:
std::vector<D2DSVG> arrows; std::vector<D2DSVG> arrows;
std::chrono::steady_clock::time_point shown_start_time; std::chrono::steady_clock::time_point shown_start_time;
float overlay_opacity = 0.9f; float overlay_opacity = 0.9f;
enum { enum
Light, Dark, System {
Light,
Dark,
System
} theme_setting = System; } theme_setting = System;
bool light_mode = true; bool light_mode = true;
}; };

View File

@ -8,20 +8,24 @@ extern "C" IMAGE_DOS_HEADER __ImageBase;
OverlayWindow* instance = nullptr; OverlayWindow* instance = nullptr;
OverlayWindow::OverlayWindow() { OverlayWindow::OverlayWindow()
{
init_settings(); init_settings();
} }
const wchar_t * OverlayWindow::get_name() { const wchar_t* OverlayWindow::get_name()
{
return L"Shortcut Guide"; return L"Shortcut Guide";
} }
const wchar_t ** OverlayWindow::get_events() { const wchar_t** OverlayWindow::get_events()
{
static const wchar_t* events[2] = { ll_keyboard, 0 }; static const wchar_t* events[2] = { ll_keyboard, 0 };
return events; return events;
} }
bool OverlayWindow::get_config(wchar_t* buffer, int *buffer_size) { bool OverlayWindow::get_config(wchar_t* buffer, int* buffer_size)
{
HINSTANCE hinstance = reinterpret_cast<HINSTANCE>(&__ImageBase); HINSTANCE hinstance = reinterpret_cast<HINSTANCE>(&__ImageBase);
PowerToysSettings::Settings settings(hinstance, get_name()); PowerToysSettings::Settings settings(hinstance, get_name());
@ -35,8 +39,7 @@ bool OverlayWindow::get_config(wchar_t* buffer, int *buffer_size) {
pressTime.value, pressTime.value,
100, 100,
10000, 10000,
100 100);
);
settings.add_int_spinner( settings.add_int_spinner(
overlayOpacity.name, overlayOpacity.name,
@ -44,49 +47,57 @@ bool OverlayWindow::get_config(wchar_t* buffer, int *buffer_size) {
overlayOpacity.value, overlayOpacity.value,
0, 0,
100, 100,
1 1);
);
settings.add_choice_group( settings.add_choice_group(
theme.name, theme.name,
theme.resourceId, theme.resourceId,
theme.value, theme.value,
theme.keys_and_texts theme.keys_and_texts);
);
return settings.serialize_to_buffer(buffer, buffer_size); return settings.serialize_to_buffer(buffer, buffer_size);
} }
void OverlayWindow::set_config(const wchar_t * config) { void OverlayWindow::set_config(const wchar_t* config)
try { {
try
{
PowerToysSettings::PowerToyValues _values = PowerToysSettings::PowerToyValues _values =
PowerToysSettings::PowerToyValues::from_json_string(config); PowerToysSettings::PowerToyValues::from_json_string(config);
if (const auto press_delay_time = _values.get_int_value(pressTime.name)) { if (const auto press_delay_time = _values.get_int_value(pressTime.name))
{
pressTime.value = *press_delay_time; pressTime.value = *press_delay_time;
if (target_state) { if (target_state)
{
target_state->set_delay(*press_delay_time); target_state->set_delay(*press_delay_time);
} }
} }
if (const auto overlay_opacity = _values.get_int_value(overlayOpacity.name)) { if (const auto overlay_opacity = _values.get_int_value(overlayOpacity.name))
{
overlayOpacity.value = *overlay_opacity; overlayOpacity.value = *overlay_opacity;
if (winkey_popup) { if (winkey_popup)
{
winkey_popup->apply_overlay_opacity(((float)overlayOpacity.value) / 100.0f); winkey_popup->apply_overlay_opacity(((float)overlayOpacity.value) / 100.0f);
} }
} }
if (auto val = _values.get_string_value(theme.name)) { if (auto val = _values.get_string_value(theme.name))
{
theme.value = std::move(*val); theme.value = std::move(*val);
winkey_popup->set_theme(theme.value); winkey_popup->set_theme(theme.value);
} }
_values.save_to_settings_file(); _values.save_to_settings_file();
Trace::SettingsChanged(pressTime.value, overlayOpacity.value, theme.value); Trace::SettingsChanged(pressTime.value, overlayOpacity.value, theme.value);
} }
catch (...) { catch (...)
{
// Improper JSON. TODO: handle the error. // Improper JSON. TODO: handle the error.
} }
} }
void OverlayWindow::enable() { void OverlayWindow::enable()
if (!_enabled) { {
if (!_enabled)
{
Trace::EnableShortcutGuide(true); Trace::EnableShortcutGuide(true);
winkey_popup = std::make_unique<D2DOverlayWindow>(); winkey_popup = std::make_unique<D2DOverlayWindow>();
winkey_popup->apply_overlay_opacity(((float)overlayOpacity.value) / 100.0f); winkey_popup->apply_overlay_opacity(((float)overlayOpacity.value) / 100.0f);
@ -97,10 +108,13 @@ void OverlayWindow::enable() {
_enabled = true; _enabled = true;
} }
void OverlayWindow::disable(bool trace_event) { void OverlayWindow::disable(bool trace_event)
if (_enabled) { {
if (_enabled)
{
_enabled = false; _enabled = false;
if (trace_event) { if (trace_event)
{
Trace::EnableShortcutGuide(false); Trace::EnableShortcutGuide(false);
} }
winkey_popup->hide(); winkey_popup->hide();
@ -110,21 +124,26 @@ void OverlayWindow::disable(bool trace_event) {
} }
} }
void OverlayWindow::disable() { void OverlayWindow::disable()
{
this->disable(true); this->disable(true);
} }
bool OverlayWindow::is_enabled() { bool OverlayWindow::is_enabled()
{
return _enabled; return _enabled;
} }
intptr_t OverlayWindow::signal_event(const wchar_t * name, intptr_t data) { intptr_t OverlayWindow::signal_event(const wchar_t* name, intptr_t data)
if (_enabled && wcscmp(name, ll_keyboard) == 0) { {
if (_enabled && wcscmp(name, ll_keyboard) == 0)
{
auto& event = *(reinterpret_cast<LowlevelKeyboardEvent*>(data)); auto& event = *(reinterpret_cast<LowlevelKeyboardEvent*>(data));
if (event.wParam == WM_KEYDOWN || if (event.wParam == WM_KEYDOWN ||
event.wParam == WM_SYSKEYDOWN || event.wParam == WM_SYSKEYDOWN ||
event.wParam == WM_KEYUP || event.wParam == WM_KEYUP ||
event.wParam == WM_SYSKEYUP) { event.wParam == WM_SYSKEYUP)
{
bool supress = target_state->signal_event(event.lParam->vkCode, bool supress = target_state->signal_event(event.lParam->vkCode,
event.wParam == WM_KEYDOWN || event.wParam == WM_SYSKEYDOWN); event.wParam == WM_KEYDOWN || event.wParam == WM_SYSKEYDOWN);
return supress ? 1 : 0; return supress ? 1 : 0;
@ -133,44 +152,55 @@ intptr_t OverlayWindow::signal_event(const wchar_t * name, intptr_t data) {
return 0; return 0;
} }
void OverlayWindow::on_held() { void OverlayWindow::on_held()
{
auto active_window = get_filtered_active_window(); auto active_window = get_filtered_active_window();
winkey_popup->show(active_window); winkey_popup->show(active_window);
} }
void OverlayWindow::on_held_press(DWORD vkCode) { void OverlayWindow::on_held_press(DWORD vkCode)
{
winkey_popup->animate(vkCode); winkey_popup->animate(vkCode);
} }
void OverlayWindow::quick_hide() { void OverlayWindow::quick_hide()
{
winkey_popup->quick_hide(); winkey_popup->quick_hide();
} }
void OverlayWindow::was_hidden() { void OverlayWindow::was_hidden()
{
target_state->was_hiden(); target_state->was_hiden();
} }
void OverlayWindow::destroy() { void OverlayWindow::destroy()
{
this->disable(false); this->disable(false);
delete this; delete this;
instance = nullptr; instance = nullptr;
} }
void OverlayWindow::init_settings() { void OverlayWindow::init_settings()
try { {
try
{
PowerToysSettings::PowerToyValues settings = PowerToysSettings::PowerToyValues settings =
PowerToysSettings::PowerToyValues::load_from_settings_file(OverlayWindow::get_name()); PowerToysSettings::PowerToyValues::load_from_settings_file(OverlayWindow::get_name());
if (const auto val = settings.get_int_value(pressTime.name)) { if (const auto val = settings.get_int_value(pressTime.name))
{
pressTime.value = *val; pressTime.value = *val;
} }
if (const auto val = settings.get_int_value(overlayOpacity.name)) { if (const auto val = settings.get_int_value(overlayOpacity.name))
{
overlayOpacity.value = *val; overlayOpacity.value = *val;
} }
if (auto val = settings.get_string_value(theme.name)) { if (auto val = settings.get_string_value(theme.name))
{
theme.value = std::move(*val); theme.value = std::move(*val);
} }
} }
catch (std::exception&) { catch (std::exception&)
{
// Error while loading from the settings file. Just let default values stay as they are. // Error while loading from the settings file. Just let default values stay as they are.
} }
} }

View File

@ -8,7 +8,8 @@ extern class OverlayWindow* instance;
class TargetState; class TargetState;
class OverlayWindow : public PowertoyModuleIface { class OverlayWindow : public PowertoyModuleIface
{
public: public:
OverlayWindow(); OverlayWindow();
virtual const wchar_t* get_name() override; virtual const wchar_t* get_name() override;
@ -39,19 +40,22 @@ private:
void init_settings(); void init_settings();
void disable(bool trace_event); void disable(bool trace_event);
struct PressTime { struct PressTime
{
PCWSTR name = L"press_time"; PCWSTR name = L"press_time";
int value = 900; // ms int value = 900; // ms
int resourceId = IDS_SETTING_DESCRIPTION_PRESS_TIME; int resourceId = IDS_SETTING_DESCRIPTION_PRESS_TIME;
} pressTime; } pressTime;
struct OverlayOpacity { struct OverlayOpacity
{
PCWSTR name = L"overlay_opacity"; PCWSTR name = L"overlay_opacity";
int value = 90; // percent int value = 90; // percent
int resourceId = IDS_SETTING_DESCRIPTION_OVERLAY_OPACITY; int resourceId = IDS_SETTING_DESCRIPTION_OVERLAY_OPACITY;
} overlayOpacity; } overlayOpacity;
struct Theme { struct Theme
{
PCWSTR name = L"theme"; PCWSTR name = L"theme";
std::wstring value = L"system"; std::wstring value = L"system";
int resourceId = IDS_SETTING_DESCRIPTION_THEME; int resourceId = IDS_SETTING_DESCRIPTION_THEME;

View File

@ -3,16 +3,21 @@
#include "common/start_visible.h" #include "common/start_visible.h"
#include "keyboard_state.h" #include "keyboard_state.h"
TargetState::TargetState(int ms_delay) : delay(std::chrono::milliseconds(ms_delay)), thread(&TargetState::thread_proc, this) TargetState::TargetState(int ms_delay) :
{ } delay(std::chrono::milliseconds(ms_delay)), thread(&TargetState::thread_proc, this)
{
}
bool TargetState::signal_event(unsigned vk_code, bool key_down) { bool TargetState::signal_event(unsigned vk_code, bool key_down)
{
std::unique_lock lock(mutex); std::unique_lock lock(mutex);
if (!events.empty() && events.back().key_down == key_down && events.back().vk_code == vk_code) { if (!events.empty() && events.back().key_down == key_down && events.back().vk_code == vk_code)
{
return false; return false;
} }
// Hide the overlay when WinKey + Shift + S is pressed. 0x53 is the VK code of the S key // Hide the overlay when WinKey + Shift + S is pressed. 0x53 is the VK code of the S key
if (key_down && state == Shown && vk_code == 0x53 && (GetKeyState(VK_LSHIFT) || GetKeyState(VK_RSHIFT))) { if (key_down && state == Shown && vk_code == 0x53 && (GetKeyState(VK_LSHIFT) || GetKeyState(VK_RSHIFT)))
{
// We cannot use normal hide() here, there is stuff that needs deinitialization. // We cannot use normal hide() here, there is stuff that needs deinitialization.
// It can be safely done when the user releases the WinKey. // It can be safely done when the user releases the WinKey.
instance->quick_hide(); instance->quick_hide();
@ -21,13 +26,15 @@ bool TargetState::signal_event(unsigned vk_code, bool key_down) {
if (!key_down && (vk_code == VK_LWIN || vk_code == VK_RWIN) && if (!key_down && (vk_code == VK_LWIN || vk_code == VK_RWIN) &&
state == Shown && state == Shown &&
std::chrono::system_clock::now() - singnal_timestamp > std::chrono::milliseconds(300) && std::chrono::system_clock::now() - singnal_timestamp > std::chrono::milliseconds(300) &&
!key_was_pressed) { !key_was_pressed)
{
supress = true; supress = true;
} }
events.push_back({ key_down, vk_code }); events.push_back({ key_down, vk_code });
lock.unlock(); lock.unlock();
cv.notify_one(); cv.notify_one();
if (supress) { if (supress)
{
// Send a fake key-stroke to prevent the start menu from appearing. // Send a fake key-stroke to prevent the start menu from appearing.
// We use 0xCF VK code, which is reserved. It still prevents the // We use 0xCF VK code, which is reserved. It still prevents the
// start menu from appearing, but should not interfere with any // start menu from appearing, but should not interfere with any
@ -46,7 +53,8 @@ bool TargetState::signal_event(unsigned vk_code, bool key_down) {
return supress; return supress;
} }
void TargetState::was_hiden() { void TargetState::was_hiden()
{
std::unique_lock<std::mutex> lock(mutex); std::unique_lock<std::mutex> lock(mutex);
state = Hidden; state = Hidden;
events.clear(); events.clear();
@ -54,7 +62,8 @@ void TargetState::was_hiden() {
cv.notify_one(); cv.notify_one();
} }
void TargetState::exit() { void TargetState::exit()
{
std::unique_lock lock(mutex); std::unique_lock lock(mutex);
events.clear(); events.clear();
state = Exiting; state = Exiting;
@ -63,52 +72,64 @@ void TargetState::exit() {
thread.join(); thread.join();
} }
KeyEvent TargetState::next() { KeyEvent TargetState::next()
{
auto e = events.front(); auto e = events.front();
events.pop_front(); events.pop_front();
return e; return e;
} }
void TargetState::handle_hidden() { void TargetState::handle_hidden()
{
std::unique_lock lock(mutex); std::unique_lock lock(mutex);
if (events.empty()) if (events.empty())
cv.wait(lock); cv.wait(lock);
if (events.empty() || state == Exiting) if (events.empty() || state == Exiting)
return; return;
auto event = next(); auto event = next();
if (event.key_down && (event.vk_code == VK_LWIN || event.vk_code == VK_RWIN)) { if (event.key_down && (event.vk_code == VK_LWIN || event.vk_code == VK_RWIN))
{
state = Timeout; state = Timeout;
winkey_timestamp = std::chrono::system_clock::now(); winkey_timestamp = std::chrono::system_clock::now();
} }
} }
void TargetState::handle_shown() { void TargetState::handle_shown()
{
std::unique_lock lock(mutex); std::unique_lock lock(mutex);
if (events.empty()) { if (events.empty())
{
cv.wait(lock); cv.wait(lock);
} }
if (events.empty() || state == Exiting) { if (events.empty() || state == Exiting)
{
return; return;
} }
auto event = next(); auto event = next();
if (event.key_down && (event.vk_code == VK_LWIN || event.vk_code == VK_RWIN)) { if (event.key_down && (event.vk_code == VK_LWIN || event.vk_code == VK_RWIN))
{
return; return;
} }
if (!event.key_down && (event.vk_code == VK_LWIN || event.vk_code == VK_RWIN) || !winkey_held()) { if (!event.key_down && (event.vk_code == VK_LWIN || event.vk_code == VK_RWIN) || !winkey_held())
{
state = Hidden; state = Hidden;
lock.unlock(); lock.unlock();
return; return;
} }
if (event.key_down) { if (event.key_down)
{
key_was_pressed = true; key_was_pressed = true;
lock.unlock(); lock.unlock();
instance->on_held_press(event.vk_code); instance->on_held_press(event.vk_code);
} }
} }
void TargetState::thread_proc() { void TargetState::thread_proc()
while (true) { {
switch (state) { while (true)
{
switch (state)
{
case Hidden: case Hidden:
handle_hidden(); handle_hidden();
break; break;
@ -125,21 +146,24 @@ void TargetState::thread_proc() {
} }
} }
void TargetState::handle_timeout() { void TargetState::handle_timeout()
{
std::unique_lock lock(mutex); std::unique_lock lock(mutex);
auto wait_time = delay - (std::chrono::system_clock::now() - winkey_timestamp); auto wait_time = delay - (std::chrono::system_clock::now() - winkey_timestamp);
if (events.empty()) if (events.empty())
cv.wait_for(lock, wait_time); cv.wait_for(lock, wait_time);
if (state == Exiting) if (state == Exiting)
return; return;
while (!events.empty()) { while (!events.empty())
{
auto event = events.front(); auto event = events.front();
if (event.key_down && (event.vk_code == VK_LWIN || event.vk_code == VK_RWIN)) if (event.key_down && (event.vk_code == VK_LWIN || event.vk_code == VK_RWIN))
events.pop_front(); events.pop_front();
else else
break; break;
} }
if (!events.empty() || !only_winkey_key_held() || is_start_visible()) { if (!events.empty() || !only_winkey_key_held() || is_start_visible())
{
state = Hidden; state = Hidden;
return; return;
} }
@ -152,6 +176,7 @@ void TargetState::handle_timeout() {
instance->on_held(); instance->on_held();
} }
void TargetState::set_delay(int ms_delay) { void TargetState::set_delay(int ms_delay)
{
delay = std::chrono::milliseconds(ms_delay); delay = std::chrono::milliseconds(ms_delay);
} }

View File

@ -6,18 +6,21 @@
#include <chrono> #include <chrono>
#include "shortcut_guide.h" #include "shortcut_guide.h"
struct KeyEvent { struct KeyEvent
{
bool key_down; bool key_down;
unsigned vk_code; unsigned vk_code;
}; };
class TargetState { class TargetState
{
public: public:
TargetState(int ms_delay); TargetState(int ms_delay);
bool signal_event(unsigned vk_code, bool key_down); bool signal_event(unsigned vk_code, bool key_down);
void was_hiden(); void was_hiden();
void exit(); void exit();
void set_delay(int ms_delay); void set_delay(int ms_delay);
private: private:
KeyEvent next(); KeyEvent next();
void handle_hidden(); void handle_hidden();
@ -29,7 +32,13 @@ private:
std::chrono::system_clock::time_point winkey_timestamp, singnal_timestamp; std::chrono::system_clock::time_point winkey_timestamp, singnal_timestamp;
std::chrono::milliseconds delay; std::chrono::milliseconds delay;
std::deque<KeyEvent> events; std::deque<KeyEvent> events;
enum { Hidden, Timeout, Shown, Exiting } state = Hidden; enum
{
Hidden,
Timeout,
Shown,
Exiting
} state = Hidden;
bool key_was_pressed = false; bool key_was_pressed = false;
std::thread thread; std::thread thread;
}; };

View File

@ -8,20 +8,25 @@ TRACELOGGING_DEFINE_PROVIDER(
(0x38e8889b, 0x9731, 0x53f5, 0xe9, 0x01, 0xe8, 0xa7, 0xc1, 0x75, 0x30, 0x74), (0x38e8889b, 0x9731, 0x53f5, 0xe9, 0x01, 0xe8, 0xa7, 0xc1, 0x75, 0x30, 0x74),
TraceLoggingOptionProjectTelemetry()); TraceLoggingOptionProjectTelemetry());
void Trace::RegisterProvider() noexcept { void Trace::RegisterProvider() noexcept
{
TraceLoggingRegister(g_hProvider); TraceLoggingRegister(g_hProvider);
} }
void Trace::UnregisterProvider() noexcept { void Trace::UnregisterProvider() noexcept
{
TraceLoggingUnregister(g_hProvider); TraceLoggingUnregister(g_hProvider);
} }
void Trace::HideGuide(const __int64 duration_ms, std::vector<int> &key_pressed) noexcept { void Trace::HideGuide(const __int64 duration_ms, std::vector<int>& key_pressed) noexcept
{
std::string vk_codes; std::string vk_codes;
std::vector<int>::iterator it; std::vector<int>::iterator it;
for (it = key_pressed.begin(); it != key_pressed.end(); ) { for (it = key_pressed.begin(); it != key_pressed.end();)
{
vk_codes += std::to_string(*it); vk_codes += std::to_string(*it);
if (++it != key_pressed.end()) { if (++it != key_pressed.end())
{
vk_codes += " "; vk_codes += " ";
} }
} }
@ -37,7 +42,8 @@ void Trace::HideGuide(const __int64 duration_ms, std::vector<int> &key_pressed)
TraceLoggingKeyword(PROJECT_KEYWORD_MEASURE)); TraceLoggingKeyword(PROJECT_KEYWORD_MEASURE));
} }
void Trace::EnableShortcutGuide(const bool enabled) noexcept { void Trace::EnableShortcutGuide(const bool enabled) noexcept
{
TraceLoggingWrite( TraceLoggingWrite(
g_hProvider, g_hProvider,
"ShortcutGuide_EnableGuide", "ShortcutGuide_EnableGuide",
@ -47,7 +53,8 @@ void Trace::EnableShortcutGuide(const bool enabled) noexcept {
TraceLoggingKeyword(PROJECT_KEYWORD_MEASURE)); TraceLoggingKeyword(PROJECT_KEYWORD_MEASURE));
} }
void Trace::SettingsChanged(const int press_delay_time, const int overlay_opacity, const std::wstring& theme) noexcept { void Trace::SettingsChanged(const int press_delay_time, const int overlay_opacity, const std::wstring& theme) noexcept
{
TraceLoggingWrite( TraceLoggingWrite(
g_hProvider, g_hProvider,
"ShortcutGuide_SettingsChanged", "ShortcutGuide_SettingsChanged",

View File

@ -1,6 +1,7 @@
#pragma once #pragma once
class Trace { class Trace
{
public: public:
static void RegisterProvider() noexcept; static void RegisterProvider() noexcept;
static void UnregisterProvider() noexcept; static void UnregisterProvider() noexcept;