mirror of
https://github.com/microsoft/PowerToys.git
synced 2026-04-04 18:26:39 +02:00
common: refactor common library pt2 (#8588)
- remove common lib - split settings, remove common-md - move ipc interop/kb_layout to interop - rename core -> settings, settings -> old_settings - os-detect header-only; interop -> PowerToysInterop - split notifications, move single-use headers where they're used - winstore lib - rename com utils - rename Updating and Telemetry projects - rename core -> settings-ui and remove examples folder - rename settings-ui folder + consisent common/version include
This commit is contained in:
51
src/modules/shortcut_guide/animation.cpp
Normal file
51
src/modules/shortcut_guide/animation.cpp
Normal file
@@ -0,0 +1,51 @@
|
||||
#include "pch.h"
|
||||
#include "animation.h"
|
||||
|
||||
Animation::Animation(double duration, double start, double stop) :
|
||||
duration(duration), start_value(start), end_value(stop), start(std::chrono::high_resolution_clock::now()) {}
|
||||
|
||||
void Animation::reset()
|
||||
{
|
||||
start = std::chrono::high_resolution_clock::now();
|
||||
}
|
||||
void Animation::reset(double duration)
|
||||
{
|
||||
this->duration = duration;
|
||||
reset();
|
||||
}
|
||||
void Animation::reset(double duration, double start, double stop)
|
||||
{
|
||||
start_value = start;
|
||||
end_value = stop;
|
||||
reset(duration);
|
||||
}
|
||||
|
||||
static double ease_out_expo(double t)
|
||||
{
|
||||
return 1 - pow(2, -8 * t);
|
||||
}
|
||||
|
||||
double Animation::apply_animation_function(double t, AnimFunctions apply_function)
|
||||
{
|
||||
switch (apply_function)
|
||||
{
|
||||
case EASE_OUT_EXPO:
|
||||
return ease_out_expo(t);
|
||||
case LINEAR:
|
||||
default:
|
||||
return t;
|
||||
}
|
||||
}
|
||||
|
||||
double Animation::value(AnimFunctions apply_function) const
|
||||
{
|
||||
auto anim_duration = std::chrono::high_resolution_clock::now() - start;
|
||||
double t = std::chrono::duration<double>(anim_duration).count() / duration;
|
||||
if (t >= 1)
|
||||
return end_value;
|
||||
return start_value + (end_value - start_value) * apply_animation_function(t, apply_function);
|
||||
}
|
||||
bool Animation::done() const
|
||||
{
|
||||
return std::chrono::high_resolution_clock::now() - start >= std::chrono::duration<double>(duration);
|
||||
}
|
||||
34
src/modules/shortcut_guide/animation.h
Normal file
34
src/modules/shortcut_guide/animation.h
Normal file
@@ -0,0 +1,34 @@
|
||||
#pragma once
|
||||
#include <chrono>
|
||||
|
||||
/*
|
||||
Usage:
|
||||
When creating animation constructor takes one parameter - how long
|
||||
should the animation take in seconds.
|
||||
|
||||
Call reset() when starting animation.
|
||||
|
||||
When rendering, call value() to get value from 0 to 1 - depending on animation
|
||||
progress.
|
||||
*/
|
||||
class Animation
|
||||
{
|
||||
public:
|
||||
enum AnimFunctions
|
||||
{
|
||||
LINEAR = 0,
|
||||
EASE_OUT_EXPO
|
||||
};
|
||||
|
||||
Animation(double duration = 1, double start = 0, double stop = 1);
|
||||
void reset();
|
||||
void reset(double duration);
|
||||
void reset(double duration, double start, double stop);
|
||||
double value(AnimFunctions apply_function) const;
|
||||
bool done() const;
|
||||
|
||||
private:
|
||||
static double apply_animation_function(double t, AnimFunctions apply_function);
|
||||
std::chrono::high_resolution_clock::time_point start;
|
||||
double start_value, end_value, duration;
|
||||
};
|
||||
@@ -1,7 +1,7 @@
|
||||
#include "pch.h"
|
||||
#include "d2d_window.h"
|
||||
|
||||
extern "C" IMAGE_DOS_HEADER __ImageBase;
|
||||
#include <common/utils/resources.h>
|
||||
|
||||
D2DWindow::D2DWindow(std::optional<std::function<std::remove_pointer_t<WNDPROC>>> _pre_wnd_proc) :
|
||||
pre_wnd_proc(std::move(_pre_wnd_proc))
|
||||
|
||||
@@ -1,15 +1,99 @@
|
||||
#include "pch.h"
|
||||
#include "overlay_window.h"
|
||||
#include <common/common.h>
|
||||
#include <common/monitors.h>
|
||||
#include <common/tasklist_positions.h>
|
||||
#include <common/start_visible.h>
|
||||
#include <common/display/monitors.h>
|
||||
#include "tasklist_positions.h"
|
||||
#include "start_visible.h"
|
||||
#include <common/utils/resources.h>
|
||||
#include <common/utils/window.h>
|
||||
|
||||
#include "keyboard_state.h"
|
||||
#include "shortcut_guide.h"
|
||||
#include "trace.h"
|
||||
#include "Generated Files/resource.h"
|
||||
|
||||
extern "C" IMAGE_DOS_HEADER __ImageBase;
|
||||
namespace
|
||||
{
|
||||
// Gets position of given window.
|
||||
std::optional<RECT> get_window_pos(HWND hwnd)
|
||||
{
|
||||
RECT window;
|
||||
if (DwmGetWindowAttribute(hwnd, DWMWA_EXTENDED_FRAME_BOUNDS, &window, sizeof(window)) == S_OK)
|
||||
{
|
||||
return window;
|
||||
}
|
||||
else
|
||||
{
|
||||
return {};
|
||||
}
|
||||
}
|
||||
|
||||
enum WindowState
|
||||
{
|
||||
UNKNOWN,
|
||||
MINIMIZED,
|
||||
MAXIMIZED,
|
||||
SNAPED_TOP_LEFT,
|
||||
SNAPED_LEFT,
|
||||
SNAPED_BOTTOM_LEFT,
|
||||
SNAPED_TOP_RIGHT,
|
||||
SNAPED_RIGHT,
|
||||
SNAPED_BOTTOM_RIGHT,
|
||||
RESTORED
|
||||
};
|
||||
|
||||
inline WindowState get_window_state(HWND hwnd)
|
||||
{
|
||||
WINDOWPLACEMENT placement;
|
||||
placement.length = sizeof(WINDOWPLACEMENT);
|
||||
|
||||
if (GetWindowPlacement(hwnd, &placement) == 0)
|
||||
{
|
||||
return UNKNOWN;
|
||||
}
|
||||
|
||||
if (placement.showCmd == SW_MINIMIZE || placement.showCmd == SW_SHOWMINIMIZED || IsIconic(hwnd))
|
||||
{
|
||||
return MINIMIZED;
|
||||
}
|
||||
|
||||
if (placement.showCmd == SW_MAXIMIZE || placement.showCmd == SW_SHOWMAXIMIZED)
|
||||
{
|
||||
return MAXIMIZED;
|
||||
}
|
||||
|
||||
auto rectp = get_window_pos(hwnd);
|
||||
if (!rectp)
|
||||
{
|
||||
return UNKNOWN;
|
||||
}
|
||||
|
||||
auto rect = *rectp;
|
||||
MONITORINFO monitor;
|
||||
monitor.cbSize = sizeof(MONITORINFO);
|
||||
auto h_monitor = MonitorFromWindow(hwnd, MONITOR_DEFAULTTONEAREST);
|
||||
GetMonitorInfo(h_monitor, &monitor);
|
||||
bool top_left = monitor.rcWork.top == rect.top && monitor.rcWork.left == rect.left;
|
||||
bool bottom_left = monitor.rcWork.bottom == rect.bottom && monitor.rcWork.left == rect.left;
|
||||
bool top_right = monitor.rcWork.top == rect.top && monitor.rcWork.right == rect.right;
|
||||
bool bottom_right = monitor.rcWork.bottom == rect.bottom && monitor.rcWork.right == rect.right;
|
||||
|
||||
if (top_left && bottom_left)
|
||||
return SNAPED_LEFT;
|
||||
if (top_left)
|
||||
return SNAPED_TOP_LEFT;
|
||||
if (bottom_left)
|
||||
return SNAPED_BOTTOM_LEFT;
|
||||
if (top_right && bottom_right)
|
||||
return SNAPED_RIGHT;
|
||||
if (top_right)
|
||||
return SNAPED_TOP_RIGHT;
|
||||
if (bottom_right)
|
||||
return SNAPED_BOTTOM_RIGHT;
|
||||
|
||||
return RESTORED;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
D2DOverlaySVG& D2DOverlaySVG::load(const std::wstring& filename, ID2D1DeviceContext5* d2d_dc)
|
||||
{
|
||||
|
||||
@@ -1,11 +1,12 @@
|
||||
#pragma once
|
||||
#include "animation.h"
|
||||
#include "d2d_svg.h"
|
||||
#include "d2d_window.h"
|
||||
#include "d2d_text.h"
|
||||
#include <common/monitors.h>
|
||||
#include <common/animation.h>
|
||||
#include <common/windows_colors.h>
|
||||
#include <common/tasklist_positions.h>
|
||||
|
||||
#include <common/display/monitors.h>
|
||||
#include <common/themes/windows_colors.h>
|
||||
#include "tasklist_positions.h"
|
||||
|
||||
struct ScaleResult
|
||||
{
|
||||
|
||||
@@ -26,3 +26,4 @@
|
||||
#include <unordered_set>
|
||||
#include <string>
|
||||
#include <ProjectTelemetry.h>
|
||||
#include <filesystem>
|
||||
Binary file not shown.
@@ -3,18 +3,18 @@
|
||||
#include "target_state.h"
|
||||
#include "trace.h"
|
||||
|
||||
#include <common/common.h>
|
||||
#include <common/settings_objects.h>
|
||||
#include <common/SettingsAPI/settings_objects.h>
|
||||
#include <common/debug_control.h>
|
||||
#include <sstream>
|
||||
#include <modules/shortcut_guide/ShortcutGuideConstants.h>
|
||||
|
||||
#include <common/settings_helpers.cpp>
|
||||
#include <common/SettingsAPI/settings_helpers.h>
|
||||
#include <common/SettingsAPI/settings_objects.h>
|
||||
#include <common/logger/logger.h>
|
||||
|
||||
|
||||
extern "C" IMAGE_DOS_HEADER __ImageBase;
|
||||
|
||||
#include <common/utils/process_path.h>
|
||||
#include <common/utils/resources.h>
|
||||
#include <common/utils/winapi_error.h>
|
||||
#include <common/utils/window.h>
|
||||
// TODO: refactor singleton
|
||||
OverlayWindow* instance = nullptr;
|
||||
|
||||
@@ -242,7 +242,7 @@ void OverlayWindow::enable()
|
||||
Logger::critical("Winkey popup failed to initialize");
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
#if defined(DISABLE_LOWLEVEL_HOOKS_WHEN_DEBUGGED)
|
||||
const bool hook_disabled = IsDebuggerPresent();
|
||||
#else
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
#include "Generated Files/resource.h"
|
||||
|
||||
#include <common/LowlevelKeyboardEvent.h>
|
||||
#include <common/hooks/LowlevelKeyboardEvent.h>
|
||||
|
||||
// We support only one instance of the overlay
|
||||
extern class OverlayWindow* instance;
|
||||
|
||||
@@ -104,6 +104,7 @@
|
||||
</ClCompile>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="animation.h" />
|
||||
<ClInclude Include="d2d_svg.h" />
|
||||
<ClInclude Include="d2d_text.h" />
|
||||
<ClInclude Include="d2d_window.h" />
|
||||
@@ -114,10 +115,12 @@
|
||||
<ClInclude Include="ShortcutGuideConstants.h" />
|
||||
<ClInclude Include="shortcut_guide.h" />
|
||||
<ClInclude Include="pch.h" />
|
||||
<ClInclude Include="start_visible.h" />
|
||||
<ClInclude Include="target_state.h" />
|
||||
<ClInclude Include="trace.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="animation.cpp" />
|
||||
<ClCompile Include="d2d_svg.cpp" />
|
||||
<ClCompile Include="d2d_text.cpp" />
|
||||
<ClCompile Include="d2d_window.cpp" />
|
||||
@@ -128,16 +131,21 @@
|
||||
<ClCompile Include="pch.cpp">
|
||||
<PrecompiledHeader Condition="'$(CIBuild)'!='true'">Create</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="start_visible.cpp" />
|
||||
<ClCompile Include="target_state.cpp" />
|
||||
<ClCompile Include="tasklist_positions.cpp" />
|
||||
<ClCompile Include="trace.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\common\common.vcxproj">
|
||||
<Project>{74485049-c722-400f-abe5-86ac52d929b3}</Project>
|
||||
<ProjectReference Include="..\..\common\Display\Display.vcxproj">
|
||||
<Project>{caba8dfb-823b-4bf2-93ac-3f31984150d9}</Project>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\..\common\logger\logger.vcxproj">
|
||||
<Project>{d9b8fc84-322a-4f9f-bbb9-20915c47ddfd}</Project>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\..\common\Themes\Themes.vcxproj">
|
||||
<Project>{98537082-0fdb-40de-abd8-0dc5a4269bab}</Project>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ResourceCompile Include="Generated Files/shortcut_guide.rc" />
|
||||
|
||||
@@ -27,6 +27,15 @@
|
||||
<ClCompile Include="d2d_window.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="animation.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="start_visible.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="tasklist_positions.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="pch.h" />
|
||||
@@ -58,6 +67,12 @@
|
||||
<ClInclude Include="d2d_window.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="animation.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="start_visible.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Filter Include="Header Files">
|
||||
|
||||
24
src/modules/shortcut_guide/start_visible.cpp
Normal file
24
src/modules/shortcut_guide/start_visible.cpp
Normal file
@@ -0,0 +1,24 @@
|
||||
#include "pch.h"
|
||||
#include "start_visible.h"
|
||||
|
||||
bool is_start_visible()
|
||||
{
|
||||
static const auto app_visibility = []() {
|
||||
winrt::com_ptr<IAppVisibility> result;
|
||||
CoCreateInstance(CLSID_AppVisibility,
|
||||
nullptr,
|
||||
CLSCTX_INPROC_SERVER,
|
||||
__uuidof(result),
|
||||
result.put_void());
|
||||
return result;
|
||||
}();
|
||||
|
||||
if (!app_visibility)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
BOOL visible;
|
||||
auto result = app_visibility->IsLauncherVisible(&visible);
|
||||
return SUCCEEDED(result) && visible;
|
||||
}
|
||||
3
src/modules/shortcut_guide/start_visible.h
Normal file
3
src/modules/shortcut_guide/start_visible.h
Normal file
@@ -0,0 +1,3 @@
|
||||
#pragma once
|
||||
|
||||
bool is_start_visible();
|
||||
@@ -1,8 +1,8 @@
|
||||
#include "pch.h"
|
||||
#include "target_state.h"
|
||||
#include <common/start_visible.h>
|
||||
#include "start_visible.h"
|
||||
#include "keyboard_state.h"
|
||||
#include <common/shared_constants.h>
|
||||
#include <common/interop/shared_constants.h>
|
||||
#include <common/logger/logger.h>
|
||||
|
||||
TargetState::TargetState(int ms_delay) :
|
||||
@@ -162,7 +162,7 @@ void TargetState::thread_proc()
|
||||
{
|
||||
Logger::critical("Shown, handle_shown failed.");
|
||||
}
|
||||
|
||||
|
||||
break;
|
||||
case ForceShown:
|
||||
try
|
||||
@@ -173,7 +173,7 @@ void TargetState::thread_proc()
|
||||
{
|
||||
Logger::critical("ForceShown, handle_shown failed.");
|
||||
}
|
||||
|
||||
|
||||
break;
|
||||
case Exiting:
|
||||
default:
|
||||
|
||||
116
src/modules/shortcut_guide/tasklist_positions.cpp
Normal file
116
src/modules/shortcut_guide/tasklist_positions.cpp
Normal file
@@ -0,0 +1,116 @@
|
||||
#include "pch.h"
|
||||
#include "tasklist_positions.h"
|
||||
|
||||
void Tasklist::update()
|
||||
{
|
||||
// Get HWND of the tasklist
|
||||
auto tasklist_hwnd = FindWindowA("Shell_TrayWnd", nullptr);
|
||||
if (!tasklist_hwnd)
|
||||
return;
|
||||
tasklist_hwnd = FindWindowExA(tasklist_hwnd, 0, "ReBarWindow32", nullptr);
|
||||
if (!tasklist_hwnd)
|
||||
return;
|
||||
tasklist_hwnd = FindWindowExA(tasklist_hwnd, 0, "MSTaskSwWClass", nullptr);
|
||||
if (!tasklist_hwnd)
|
||||
return;
|
||||
tasklist_hwnd = FindWindowExA(tasklist_hwnd, 0, "MSTaskListWClass", nullptr);
|
||||
if (!tasklist_hwnd)
|
||||
return;
|
||||
if (!automation)
|
||||
{
|
||||
winrt::check_hresult(CoCreateInstance(CLSID_CUIAutomation,
|
||||
nullptr,
|
||||
CLSCTX_INPROC_SERVER,
|
||||
IID_IUIAutomation,
|
||||
automation.put_void()));
|
||||
winrt::check_hresult(automation->CreateTrueCondition(true_condition.put()));
|
||||
}
|
||||
element = nullptr;
|
||||
winrt::check_hresult(automation->ElementFromHandle(tasklist_hwnd, element.put()));
|
||||
}
|
||||
|
||||
bool Tasklist::update_buttons(std::vector<TasklistButton>& buttons)
|
||||
{
|
||||
if (!automation || !element)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
winrt::com_ptr<IUIAutomationElementArray> elements;
|
||||
if (element->FindAll(TreeScope_Children, true_condition.get(), elements.put()) < 0)
|
||||
return false;
|
||||
if (!elements)
|
||||
return false;
|
||||
int count;
|
||||
if (elements->get_Length(&count) < 0)
|
||||
return false;
|
||||
winrt::com_ptr<IUIAutomationElement> child;
|
||||
std::vector<TasklistButton> found_buttons;
|
||||
found_buttons.reserve(count);
|
||||
for (int i = 0; i < count; ++i)
|
||||
{
|
||||
child = nullptr;
|
||||
if (elements->GetElement(i, child.put()) < 0)
|
||||
return false;
|
||||
TasklistButton button;
|
||||
if (VARIANT var_rect; child->GetCurrentPropertyValue(UIA_BoundingRectanglePropertyId, &var_rect) >= 0)
|
||||
{
|
||||
if (var_rect.vt == (VT_R8 | VT_ARRAY))
|
||||
{
|
||||
LONG pos;
|
||||
double value;
|
||||
pos = 0;
|
||||
SafeArrayGetElement(var_rect.parray, &pos, &value);
|
||||
button.x = (long)value;
|
||||
pos = 1;
|
||||
SafeArrayGetElement(var_rect.parray, &pos, &value);
|
||||
button.y = (long)value;
|
||||
pos = 2;
|
||||
SafeArrayGetElement(var_rect.parray, &pos, &value);
|
||||
button.width = (long)value;
|
||||
pos = 3;
|
||||
SafeArrayGetElement(var_rect.parray, &pos, &value);
|
||||
button.height = (long)value;
|
||||
}
|
||||
VariantClear(&var_rect);
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (BSTR automation_id; child->get_CurrentAutomationId(&automation_id) >= 0)
|
||||
{
|
||||
button.name = automation_id;
|
||||
SysFreeString(automation_id);
|
||||
}
|
||||
found_buttons.push_back(button);
|
||||
}
|
||||
// assign keynums
|
||||
buttons.clear();
|
||||
for (auto& button : found_buttons)
|
||||
{
|
||||
if (buttons.empty())
|
||||
{
|
||||
button.keynum = 1;
|
||||
buttons.push_back(std::move(button));
|
||||
}
|
||||
else
|
||||
{
|
||||
if (button.x < buttons.back().x || button.y < buttons.back().y) // skip 2nd row
|
||||
break;
|
||||
if (button.name == buttons.back().name)
|
||||
continue; // skip buttons from the same app
|
||||
button.keynum = buttons.back().keynum + 1;
|
||||
buttons.push_back(std::move(button));
|
||||
if (buttons.back().keynum == 10)
|
||||
break; // no more than 10 buttons
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
std::vector<TasklistButton> Tasklist::get_buttons()
|
||||
{
|
||||
std::vector<TasklistButton> buttons;
|
||||
update_buttons(buttons);
|
||||
return buttons;
|
||||
}
|
||||
25
src/modules/shortcut_guide/tasklist_positions.h
Normal file
25
src/modules/shortcut_guide/tasklist_positions.h
Normal file
@@ -0,0 +1,25 @@
|
||||
#pragma once
|
||||
#include <vector>
|
||||
#include <unordered_set>
|
||||
#include <string>
|
||||
#include <Windows.h>
|
||||
#include <UIAutomationClient.h>
|
||||
|
||||
struct TasklistButton
|
||||
{
|
||||
std::wstring name;
|
||||
long x, y, width, height, keynum;
|
||||
};
|
||||
|
||||
class Tasklist
|
||||
{
|
||||
public:
|
||||
void update();
|
||||
std::vector<TasklistButton> get_buttons();
|
||||
bool update_buttons(std::vector<TasklistButton>& buttons);
|
||||
|
||||
private:
|
||||
winrt::com_ptr<IUIAutomation> automation;
|
||||
winrt::com_ptr<IUIAutomationElement> element;
|
||||
winrt::com_ptr<IUIAutomationCondition> true_condition;
|
||||
};
|
||||
Reference in New Issue
Block a user