mirror of
https://github.com/microsoft/PowerToys.git
synced 2024-12-12 02:09:24 +08:00
commit
b9b60a1346
10
.github/pull_request_template.md
vendored
10
.github/pull_request_template.md
vendored
@ -6,11 +6,11 @@
|
|||||||
|
|
||||||
<!-- Please review the items on the PR checklist before submitting-->
|
<!-- Please review the items on the PR checklist before submitting-->
|
||||||
## PR Checklist
|
## PR Checklist
|
||||||
* [ ] Closes #xxx
|
* [] Applies to #xxx
|
||||||
* [ ] CLA signed. If not, go over [here](https://cla.opensource.microsoft.com/microsoft/PowerToys) and sign the CLA
|
* [] CLA signed. If not, go over [here](https://cla.opensource.microsoft.com/microsoft/PowerToys) and sign the CLA
|
||||||
* [ ] Tests added/passed
|
* [] Tests added/passed
|
||||||
* [ ] Requires documentation to be updated
|
* [] Requires documentation to be updated
|
||||||
* [ ] I've discussed this with core contributors already. If not checked, I'm ready to accept this work might be rejected in favor of a different grand plan. Issue number where discussion took place: #xxx
|
* [] I've discussed this with core contributors already. If not checked, I'm ready to accept this work might be rejected in favor of a different grand plan. Issue number where discussion took place: #xxx
|
||||||
|
|
||||||
<!-- Provide a more detailed description of the PR, other things fixed or any additional comments/features here -->
|
<!-- Provide a more detailed description of the PR, other things fixed or any additional comments/features here -->
|
||||||
## Detailed Description of the Pull Request / Additional comments
|
## Detailed Description of the Pull Request / Additional comments
|
||||||
|
@ -6,7 +6,6 @@ The list below is the set of utilities we're considering and the rough priority
|
|||||||
|
|
||||||
* Maximize to new desktop widget - The MTND widget shows a pop-up button when a user hovers over the maximize / restore button on any window. Clicking it creates a new desktop, sends the app to that desktop and maximizes the app on the new desktop.
|
* Maximize to new desktop widget - The MTND widget shows a pop-up button when a user hovers over the maximize / restore button on any window. Clicking it creates a new desktop, sends the app to that desktop and maximizes the app on the new desktop.
|
||||||
* [Process terminate tool](https://github.com/indierawk2k2/PowerToys-1/blob/master/specs/Terminate%20Spec.md)
|
* [Process terminate tool](https://github.com/indierawk2k2/PowerToys-1/blob/master/specs/Terminate%20Spec.md)
|
||||||
* [Batch file renamer](https://github.com/indierawk2k2/PowerToys-1/blob/master/specs/File%20Classification%20Spec.md)
|
|
||||||
* [Animated gif screen recorder](https://github.com/indierawk2k2/PowerToys-1/blob/master/specs/GIF%20Maker%20Spec.md)
|
* [Animated gif screen recorder](https://github.com/indierawk2k2/PowerToys-1/blob/master/specs/GIF%20Maker%20Spec.md)
|
||||||
|
|
||||||
## Backlog
|
## Backlog
|
||||||
|
@ -98,6 +98,7 @@
|
|||||||
<ClInclude Include="d2d_window.h" />
|
<ClInclude Include="d2d_window.h" />
|
||||||
<ClInclude Include="dpi_aware.h" />
|
<ClInclude Include="dpi_aware.h" />
|
||||||
<ClInclude Include="monitors.h" />
|
<ClInclude Include="monitors.h" />
|
||||||
|
<ClInclude Include="on_thread_executor.h" />
|
||||||
<ClInclude Include="pch.h" />
|
<ClInclude Include="pch.h" />
|
||||||
<ClInclude Include="settings_helpers.h" />
|
<ClInclude Include="settings_helpers.h" />
|
||||||
<ClInclude Include="settings_objects.h" />
|
<ClInclude Include="settings_objects.h" />
|
||||||
@ -117,6 +118,7 @@
|
|||||||
<ClCompile Include="d2d_window.cpp" />
|
<ClCompile Include="d2d_window.cpp" />
|
||||||
<ClCompile Include="dpi_aware.cpp" />
|
<ClCompile Include="dpi_aware.cpp" />
|
||||||
<ClCompile Include="monitors.cpp" />
|
<ClCompile Include="monitors.cpp" />
|
||||||
|
<ClCompile Include="on_thread_executor.cpp" />
|
||||||
<ClCompile Include="pch.cpp">
|
<ClCompile Include="pch.cpp">
|
||||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Create</PrecompiledHeader>
|
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Create</PrecompiledHeader>
|
||||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Create</PrecompiledHeader>
|
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Create</PrecompiledHeader>
|
||||||
|
@ -69,6 +69,9 @@
|
|||||||
<ClInclude Include="version.h">
|
<ClInclude Include="version.h">
|
||||||
<Filter>Header Files</Filter>
|
<Filter>Header Files</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
<ClInclude Include="on_thread_executor.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClCompile Include="d2d_svg.cpp">
|
<ClCompile Include="d2d_svg.cpp">
|
||||||
@ -108,5 +111,8 @@
|
|||||||
<ClCompile Include="dpi_aware.cpp">
|
<ClCompile Include="dpi_aware.cpp">
|
||||||
<Filter>Source Files</Filter>
|
<Filter>Source Files</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
<ClCompile Include="on_thread_executor.cpp">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
</Project>
|
</Project>
|
@ -38,3 +38,7 @@ void DPIAware::Convert(HMONITOR monitor_handle, int &width, int &height) {
|
|||||||
height = height * dpi_y / DEFAULT_DPI;
|
height = height * dpi_y / DEFAULT_DPI;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void DPIAware::EnableDPIAwarenessForThisProcess() {
|
||||||
|
SetProcessDpiAwarenessContext(DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2);
|
||||||
|
}
|
||||||
|
@ -1,12 +1,11 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include "windef.h"
|
#include "windef.h"
|
||||||
|
|
||||||
class DPIAware {
|
struct DPIAware {
|
||||||
private:
|
static constexpr int DEFAULT_DPI = 96;
|
||||||
static const int DEFAULT_DPI = 96;
|
|
||||||
|
|
||||||
public:
|
|
||||||
static HRESULT GetScreenDPIForWindow(HWND hwnd, UINT & dpi_x, UINT & dpi_y);
|
static HRESULT GetScreenDPIForWindow(HWND hwnd, UINT & dpi_x, UINT & dpi_y);
|
||||||
static HRESULT GetScreenDPIForPoint(POINT p, UINT& dpi_x, UINT& dpi_y);
|
static HRESULT GetScreenDPIForPoint(POINT p, UINT& dpi_x, UINT& dpi_y);
|
||||||
static void Convert(HMONITOR monitor_handle, int &width, int &height);
|
static void Convert(HMONITOR monitor_handle, int &width, int &height);
|
||||||
|
static void EnableDPIAwarenessForThisProcess();
|
||||||
};
|
};
|
||||||
|
38
src/common/on_thread_executor.cpp
Normal file
38
src/common/on_thread_executor.cpp
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
#include "pch.h"
|
||||||
|
|
||||||
|
#include "on_thread_executor.h"
|
||||||
|
|
||||||
|
OnThreadExecutor::OnThreadExecutor()
|
||||||
|
:_worker_thread{[this]() { worker_thread(); }}
|
||||||
|
{}
|
||||||
|
|
||||||
|
std::future<void> OnThreadExecutor::submit(task_t task) {
|
||||||
|
auto future = task.get_future();
|
||||||
|
std::lock_guard lock{_task_mutex};
|
||||||
|
_task_queue.emplace(std::move(task));
|
||||||
|
_task_cv.notify_one();
|
||||||
|
return future;
|
||||||
|
}
|
||||||
|
|
||||||
|
void OnThreadExecutor::worker_thread() {
|
||||||
|
while(_active) {
|
||||||
|
task_t task;
|
||||||
|
{
|
||||||
|
std::unique_lock task_lock{_task_mutex};
|
||||||
|
_task_cv.wait(task_lock, [this] { return !_task_queue.empty() || !_active; });
|
||||||
|
if(!_active) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
task = std::move(_task_queue.front());
|
||||||
|
_task_queue.pop();
|
||||||
|
}
|
||||||
|
task();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
OnThreadExecutor::~OnThreadExecutor() {
|
||||||
|
_active = false;
|
||||||
|
_task_cv.notify_one();
|
||||||
|
_worker_thread.join();
|
||||||
|
}
|
||||||
|
|
30
src/common/on_thread_executor.h
Normal file
30
src/common/on_thread_executor.h
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <future>
|
||||||
|
#include <thread>
|
||||||
|
#include <functional>
|
||||||
|
#include <queue>
|
||||||
|
#include <atomic>
|
||||||
|
|
||||||
|
// OnThreadExecutor allows its caller to off-load some work to a persistently running background thread.
|
||||||
|
// This might come in handy if you use the API which sets thread-wide global state and the state needs
|
||||||
|
// to be isolated.
|
||||||
|
|
||||||
|
class OnThreadExecutor final {
|
||||||
|
public:
|
||||||
|
using task_t = std::packaged_task<void()>;
|
||||||
|
|
||||||
|
OnThreadExecutor();
|
||||||
|
~OnThreadExecutor();
|
||||||
|
std::future<void> submit(task_t task);
|
||||||
|
|
||||||
|
private:
|
||||||
|
void worker_thread();
|
||||||
|
|
||||||
|
std::thread _worker_thread;
|
||||||
|
|
||||||
|
std::mutex _task_mutex;
|
||||||
|
std::condition_variable _task_cv;
|
||||||
|
std::atomic_bool _active;
|
||||||
|
std::queue<std::packaged_task<void()>> _task_queue;
|
||||||
|
};
|
@ -220,6 +220,7 @@ private:
|
|||||||
void MoveSizeEnd(HWND window, POINT const& ptScreen) noexcept;
|
void MoveSizeEnd(HWND window, POINT const& ptScreen) noexcept;
|
||||||
void MoveSizeUpdate(POINT const& ptScreen) noexcept;
|
void MoveSizeUpdate(POINT const& ptScreen) noexcept;
|
||||||
|
|
||||||
|
HANDLE m_movedWindow = nullptr;
|
||||||
winrt::com_ptr<IFancyZones> m_app;
|
winrt::com_ptr<IFancyZones> m_app;
|
||||||
winrt::com_ptr<IFancyZonesSettings> m_settings;
|
winrt::com_ptr<IFancyZonesSettings> m_settings;
|
||||||
};
|
};
|
||||||
@ -298,6 +299,7 @@ void FancyZonesModule::MoveSizeStart(HWND window, POINT const& ptScreen) noexcep
|
|||||||
{
|
{
|
||||||
if (auto monitor = MonitorFromPoint(ptScreen, MONITOR_DEFAULTTONULL))
|
if (auto monitor = MonitorFromPoint(ptScreen, MONITOR_DEFAULTTONULL))
|
||||||
{
|
{
|
||||||
|
m_movedWindow = window;
|
||||||
m_app.as<IFancyZonesCallback>()->MoveSizeStart(window, monitor, ptScreen);
|
m_app.as<IFancyZonesCallback>()->MoveSizeStart(window, monitor, ptScreen);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -305,8 +307,9 @@ void FancyZonesModule::MoveSizeStart(HWND window, POINT const& ptScreen) noexcep
|
|||||||
|
|
||||||
void FancyZonesModule::MoveSizeEnd(HWND window, POINT const& ptScreen) noexcept
|
void FancyZonesModule::MoveSizeEnd(HWND window, POINT const& ptScreen) noexcept
|
||||||
{
|
{
|
||||||
if (IsInterestingWindow(window))
|
if (IsInterestingWindow(window) || (window != nullptr && window == m_movedWindow))
|
||||||
{
|
{
|
||||||
|
m_movedWindow = nullptr;
|
||||||
m_app.as<IFancyZonesCallback>()->MoveSizeEnd(window, ptScreen);
|
m_app.as<IFancyZonesCallback>()->MoveSizeEnd(window, ptScreen);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -23,6 +23,9 @@ namespace FancyZonesEditor
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public partial class MainWindow : MetroWindow
|
public partial class MainWindow : MetroWindow
|
||||||
{
|
{
|
||||||
|
// TODO: share the constants b/w C# Editor and FancyZoneLib
|
||||||
|
public static int MAX_ZONES = 40;
|
||||||
|
|
||||||
public MainWindow()
|
public MainWindow()
|
||||||
{
|
{
|
||||||
InitializeComponent();
|
InitializeComponent();
|
||||||
@ -57,7 +60,7 @@ namespace FancyZonesEditor
|
|||||||
|
|
||||||
private void IncrementZones_Click(object sender, RoutedEventArgs e)
|
private void IncrementZones_Click(object sender, RoutedEventArgs e)
|
||||||
{
|
{
|
||||||
if (_settings.ZoneCount < 40)
|
if (_settings.ZoneCount < MAX_ZONES)
|
||||||
{
|
{
|
||||||
_settings.ZoneCount++;
|
_settings.ZoneCount++;
|
||||||
}
|
}
|
||||||
|
@ -279,7 +279,7 @@ namespace FancyZonesEditor
|
|||||||
// 1 = unique key for per-monitor settings
|
// 1 = unique key for per-monitor settings
|
||||||
// 2 = layoutid used to generate current layout (used to pick the default layout to show)
|
// 2 = layoutid used to generate current layout (used to pick the default layout to show)
|
||||||
// 3 = handle to monitor (passed back to engine to persist data)
|
// 3 = handle to monitor (passed back to engine to persist data)
|
||||||
// 4 = X_Y_Width_Height (where EditorOverlay shows up)
|
// 4 = X_Y_Width_Height in a dpi-scaled-but-unaware coords (where EditorOverlay shows up)
|
||||||
// 5 = resolution key (passed back to engine to persist data)
|
// 5 = resolution key (passed back to engine to persist data)
|
||||||
// 6 = monitor DPI (float)
|
// 6 = monitor DPI (float)
|
||||||
|
|
||||||
|
@ -1,13 +1,14 @@
|
|||||||
#include "pch.h"
|
#include "pch.h"
|
||||||
#include "common/dpi_aware.h"
|
#include "common/dpi_aware.h"
|
||||||
|
#include "common/on_thread_executor.h"
|
||||||
|
|
||||||
struct FancyZones : public winrt::implements<FancyZones, IFancyZones, IFancyZonesCallback, IZoneWindowHost>
|
struct FancyZones : public winrt::implements<FancyZones, IFancyZones, IFancyZonesCallback, IZoneWindowHost>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
FancyZones(HINSTANCE hinstance, IFancyZonesSettings* settings) noexcept
|
FancyZones(HINSTANCE hinstance, IFancyZonesSettings* settings) noexcept
|
||||||
: m_hinstance(hinstance)
|
: m_hinstance(hinstance)
|
||||||
|
, m_settings(settings)
|
||||||
{
|
{
|
||||||
m_settings.attach(settings);
|
|
||||||
m_settings->SetCallback(this);
|
m_settings->SetCallback(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -84,10 +85,12 @@ private:
|
|||||||
bool m_dragEnabled{}; // True if we should be showing zone hints while dragging
|
bool m_dragEnabled{}; // True if we should be showing zone hints while dragging
|
||||||
std::map<HMONITOR, winrt::com_ptr<IZoneWindow>> m_zoneWindowMap; // Map of monitor to ZoneWindow (one per monitor)
|
std::map<HMONITOR, winrt::com_ptr<IZoneWindow>> m_zoneWindowMap; // Map of monitor to ZoneWindow (one per monitor)
|
||||||
winrt::com_ptr<IZoneWindow> m_zoneWindowMoveSize; // "Active" ZoneWindow, where the move/size is happening. Will update as drag moves between monitors.
|
winrt::com_ptr<IZoneWindow> m_zoneWindowMoveSize; // "Active" ZoneWindow, where the move/size is happening. Will update as drag moves between monitors.
|
||||||
winrt::com_ptr<IFancyZonesSettings> m_settings;
|
IFancyZonesSettings* m_settings{};
|
||||||
GUID m_currentVirtualDesktopId{};
|
GUID m_currentVirtualDesktopId{};
|
||||||
wil::unique_handle m_terminateEditorEvent;
|
wil::unique_handle m_terminateEditorEvent;
|
||||||
|
|
||||||
|
OnThreadExecutor m_dpiUnawareThread;
|
||||||
|
|
||||||
static UINT WM_PRIV_VDCHANGED;
|
static UINT WM_PRIV_VDCHANGED;
|
||||||
static UINT WM_PRIV_EDITOR;
|
static UINT WM_PRIV_EDITOR;
|
||||||
|
|
||||||
@ -120,13 +123,18 @@ IFACEMETHODIMP_(void) FancyZones::Run() noexcept
|
|||||||
|
|
||||||
RegisterHotKey(m_window, 1, m_settings->GetSettings().editorHotkey.get_modifiers(), m_settings->GetSettings().editorHotkey.get_code());
|
RegisterHotKey(m_window, 1, m_settings->GetSettings().editorHotkey.get_modifiers(), m_settings->GetSettings().editorHotkey.get_code());
|
||||||
VirtualDesktopChanged();
|
VirtualDesktopChanged();
|
||||||
|
|
||||||
|
m_dpiUnawareThread.submit(OnThreadExecutor::task_t{[]{
|
||||||
|
SetThreadDpiAwarenessContext(DPI_AWARENESS_CONTEXT_UNAWARE);
|
||||||
|
SetThreadDpiHostingBehavior(DPI_HOSTING_BEHAVIOR_MIXED);
|
||||||
|
}}).wait();
|
||||||
}
|
}
|
||||||
|
|
||||||
// IFancyZones
|
// IFancyZones
|
||||||
IFACEMETHODIMP_(void) FancyZones::Destroy() noexcept
|
IFACEMETHODIMP_(void) FancyZones::Destroy() noexcept
|
||||||
{
|
{
|
||||||
std::unique_lock writeLock(m_lock);
|
std::unique_lock writeLock(m_lock);
|
||||||
|
m_zoneWindowMap.clear();
|
||||||
BufferedPaintUnInit();
|
BufferedPaintUnInit();
|
||||||
if (m_window)
|
if (m_window)
|
||||||
{
|
{
|
||||||
@ -239,22 +247,22 @@ void FancyZones::ToggleEditor() noexcept
|
|||||||
}
|
}
|
||||||
|
|
||||||
HMONITOR monitor{};
|
HMONITOR monitor{};
|
||||||
UINT dpi_x = 96;
|
HWND foregroundWindow{};
|
||||||
UINT dpi_y = 96;
|
|
||||||
|
|
||||||
if (m_settings->GetSettings().use_cursorpos_editor_startupscreen)
|
UINT dpi_x = DPIAware::DEFAULT_DPI;
|
||||||
{
|
UINT dpi_y = DPIAware::DEFAULT_DPI;
|
||||||
|
|
||||||
|
const bool use_cursorpos_editor_startupscreen = m_settings->GetSettings().use_cursorpos_editor_startupscreen;
|
||||||
POINT currentCursorPos{};
|
POINT currentCursorPos{};
|
||||||
|
if (use_cursorpos_editor_startupscreen)
|
||||||
|
{
|
||||||
GetCursorPos(¤tCursorPos);
|
GetCursorPos(¤tCursorPos);
|
||||||
|
|
||||||
monitor = MonitorFromPoint(currentCursorPos, MONITOR_DEFAULTTOPRIMARY);
|
monitor = MonitorFromPoint(currentCursorPos, MONITOR_DEFAULTTOPRIMARY);
|
||||||
DPIAware::GetScreenDPIForPoint(currentCursorPos, dpi_x, dpi_y);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
const HWND foregroundWindow = GetForegroundWindow();
|
foregroundWindow = GetForegroundWindow();
|
||||||
monitor = MonitorFromWindow(foregroundWindow, MONITOR_DEFAULTTOPRIMARY);
|
monitor = MonitorFromWindow(foregroundWindow, MONITOR_DEFAULTTOPRIMARY);
|
||||||
DPIAware::GetScreenDPIForWindow(foregroundWindow, dpi_x, dpi_y);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -272,21 +280,33 @@ void FancyZones::ToggleEditor() noexcept
|
|||||||
|
|
||||||
MONITORINFOEX mi;
|
MONITORINFOEX mi;
|
||||||
mi.cbSize = sizeof(mi);
|
mi.cbSize = sizeof(mi);
|
||||||
|
|
||||||
|
m_dpiUnawareThread.submit(OnThreadExecutor::task_t{[&]{
|
||||||
GetMonitorInfo(monitor, &mi);
|
GetMonitorInfo(monitor, &mi);
|
||||||
|
}}).wait();
|
||||||
|
|
||||||
// X/Y need to start in unscaled screen coordinates to get to the proper top/left of the monitor
|
if(use_cursorpos_editor_startupscreen)
|
||||||
// From there, we need to scale the difference between the monitor and workarea rects to get the
|
{
|
||||||
// appropriate offset where the overlay should appear.
|
DPIAware::GetScreenDPIForPoint(currentCursorPos, dpi_x, dpi_y);
|
||||||
// This covers the cases where the taskbar is not at the bottom of the screen.
|
}
|
||||||
const auto x = mi.rcMonitor.left + MulDiv(mi.rcWork.left - mi.rcMonitor.left, 96, dpi_x);
|
else
|
||||||
const auto y = mi.rcMonitor.top + MulDiv(mi.rcWork.top - mi.rcMonitor.top, 96, dpi_y);
|
{
|
||||||
|
DPIAware::GetScreenDPIForWindow(foregroundWindow, dpi_x, dpi_y);
|
||||||
|
}
|
||||||
|
|
||||||
// Location that the editor should occupy, scaled by DPI
|
const auto taskbar_x_offset = MulDiv(mi.rcWork.left - mi.rcMonitor.left, DPIAware::DEFAULT_DPI, dpi_x);
|
||||||
std::wstring editorLocation =
|
const auto taskbar_y_offset = MulDiv(mi.rcWork.top - mi.rcMonitor.top, DPIAware::DEFAULT_DPI, dpi_y);
|
||||||
|
|
||||||
|
// Do not scale window params by the dpi, that will be done in the editor - see LayoutModel.Apply
|
||||||
|
const auto x = mi.rcMonitor.left + taskbar_x_offset;
|
||||||
|
const auto y = mi.rcMonitor.top + taskbar_y_offset;
|
||||||
|
const auto width = mi.rcWork.right - mi.rcWork.left;
|
||||||
|
const auto height = mi.rcWork.bottom - mi.rcWork.top;
|
||||||
|
const std::wstring editorLocation =
|
||||||
std::to_wstring(x) + L"_" +
|
std::to_wstring(x) + L"_" +
|
||||||
std::to_wstring(y) + L"_" +
|
std::to_wstring(y) + L"_" +
|
||||||
std::to_wstring(MulDiv(mi.rcWork.right - mi.rcWork.left, 96, dpi_x)) + L"_" +
|
std::to_wstring(width) + L"_" +
|
||||||
std::to_wstring(MulDiv(mi.rcWork.bottom - mi.rcWork.top, 96, dpi_y));
|
std::to_wstring(height);
|
||||||
|
|
||||||
const std::wstring params =
|
const std::wstring params =
|
||||||
iter->second->UniqueId() + L" " +
|
iter->second->UniqueId() + L" " +
|
||||||
@ -294,7 +314,7 @@ void FancyZones::ToggleEditor() noexcept
|
|||||||
std::to_wstring(reinterpret_cast<UINT_PTR>(monitor)) + L" " +
|
std::to_wstring(reinterpret_cast<UINT_PTR>(monitor)) + L" " +
|
||||||
editorLocation + L" " +
|
editorLocation + L" " +
|
||||||
iter->second->WorkAreaKey() + L" " +
|
iter->second->WorkAreaKey() + L" " +
|
||||||
std::to_wstring(static_cast<float>(dpi_x) / 96.0f);
|
std::to_wstring(static_cast<float>(dpi_x) / DPIAware::DEFAULT_DPI);
|
||||||
|
|
||||||
SHELLEXECUTEINFO sei{ sizeof(sei) };
|
SHELLEXECUTEINFO sei{ sizeof(sei) };
|
||||||
sei.fMask = { SEE_MASK_NOCLOSEPROCESS | SEE_MASK_FLAG_NO_UI };
|
sei.fMask = { SEE_MASK_NOCLOSEPROCESS | SEE_MASK_FLAG_NO_UI };
|
||||||
@ -652,18 +672,26 @@ void FancyZones::MoveSizeStartInternal(HWND window, HMONITOR monitor, POINT cons
|
|||||||
RECT windowRect{};
|
RECT windowRect{};
|
||||||
::GetWindowRect(window, &windowRect);
|
::GetWindowRect(window, &windowRect);
|
||||||
|
|
||||||
windowRect.top += 6;
|
const auto padding_x = 8;
|
||||||
windowRect.left += 8;
|
const auto padding_y = 6;
|
||||||
windowRect.right -= 8;
|
windowRect.top += padding_y;
|
||||||
windowRect.bottom -= 6;
|
windowRect.left += padding_x;
|
||||||
|
windowRect.right -= padding_x;
|
||||||
|
windowRect.bottom -= padding_y;
|
||||||
|
|
||||||
if (PtInRect(&windowRect, ptScreen))
|
if (PtInRect(&windowRect, ptScreen) == FALSE)
|
||||||
{
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
m_inMoveSize = true;
|
m_inMoveSize = true;
|
||||||
|
|
||||||
auto iter = m_zoneWindowMap.find(monitor);
|
auto iter = m_zoneWindowMap.find(monitor);
|
||||||
if (iter != m_zoneWindowMap.end())
|
if (iter == end(m_zoneWindowMap))
|
||||||
{
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
m_windowMoveSize = window;
|
m_windowMoveSize = window;
|
||||||
|
|
||||||
// This updates m_dragEnabled depending on if the shift key is being held down.
|
// This updates m_dragEnabled depending on if the shift key is being held down.
|
||||||
@ -679,8 +707,6 @@ void FancyZones::MoveSizeStartInternal(HWND window, HMONITOR monitor, POINT cons
|
|||||||
m_zoneWindowMoveSize->MoveSizeCancel();
|
m_zoneWindowMoveSize->MoveSizeCancel();
|
||||||
m_zoneWindowMoveSize = nullptr;
|
m_zoneWindowMoveSize = nullptr;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void FancyZones::MoveSizeEndInternal(HWND window, POINT const& ptScreen, require_write_lock) noexcept
|
void FancyZones::MoveSizeEndInternal(HWND window, POINT const& ptScreen, require_write_lock) noexcept
|
||||||
|
@ -11,7 +11,7 @@ public:
|
|||||||
LoadSettings(name, true /*fromFile*/);
|
LoadSettings(name, true /*fromFile*/);
|
||||||
}
|
}
|
||||||
|
|
||||||
IFACEMETHODIMP_(void) SetCallback(IFancyZonesCallback* callback) { m_callback.attach(callback); }
|
IFACEMETHODIMP_(void) SetCallback(IFancyZonesCallback* callback) { m_callback = callback; }
|
||||||
IFACEMETHODIMP_(bool) GetConfig(_Out_ PWSTR buffer, _Out_ int *buffer_sizeg) noexcept;
|
IFACEMETHODIMP_(bool) GetConfig(_Out_ PWSTR buffer, _Out_ int *buffer_sizeg) noexcept;
|
||||||
IFACEMETHODIMP_(void) SetConfig(PCWSTR config) noexcept;
|
IFACEMETHODIMP_(void) SetConfig(PCWSTR config) noexcept;
|
||||||
IFACEMETHODIMP_(void) CallCustomAction(PCWSTR action) noexcept;
|
IFACEMETHODIMP_(void) CallCustomAction(PCWSTR action) noexcept;
|
||||||
@ -21,7 +21,7 @@ private:
|
|||||||
void LoadSettings(PCWSTR config, bool fromFile) noexcept;
|
void LoadSettings(PCWSTR config, bool fromFile) noexcept;
|
||||||
void SaveSettings() noexcept;
|
void SaveSettings() noexcept;
|
||||||
|
|
||||||
winrt::com_ptr<IFancyZonesCallback> m_callback;
|
IFancyZonesCallback* m_callback{};
|
||||||
const HINSTANCE m_hinstance;
|
const HINSTANCE m_hinstance;
|
||||||
PCWSTR m_name{};
|
PCWSTR m_name{};
|
||||||
|
|
||||||
|
@ -34,13 +34,15 @@ interface __declspec(uuid("{E4839EB7-669D-49CF-84A9-71A2DFD851A3}")) IZoneSet :
|
|||||||
#define VERSION_PERSISTEDDATA 0x0000F00D
|
#define VERSION_PERSISTEDDATA 0x0000F00D
|
||||||
struct ZoneSetPersistedData
|
struct ZoneSetPersistedData
|
||||||
{
|
{
|
||||||
|
static constexpr inline size_t MAX_ZONES = 40;
|
||||||
|
|
||||||
DWORD Version{VERSION_PERSISTEDDATA};
|
DWORD Version{VERSION_PERSISTEDDATA};
|
||||||
WORD LayoutId{};
|
WORD LayoutId{};
|
||||||
DWORD ZoneCount{};
|
DWORD ZoneCount{};
|
||||||
ZoneSetLayout Layout{};
|
ZoneSetLayout Layout{};
|
||||||
DWORD PaddingInner{};
|
DWORD PaddingInner{};
|
||||||
DWORD PaddingOuter{};
|
DWORD PaddingOuter{};
|
||||||
RECT Zones[40]{};
|
RECT Zones[MAX_ZONES]{};
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ZoneSetConfig
|
struct ZoneSetConfig
|
||||||
|
@ -1,4 +1,6 @@
|
|||||||
#include "pch.h"
|
#include "pch.h"
|
||||||
|
#include <common/dpi_aware.h>
|
||||||
|
|
||||||
#include <ShellScalingApi.h>
|
#include <ShellScalingApi.h>
|
||||||
|
|
||||||
struct ZoneWindow : public winrt::implements<ZoneWindow, IZoneWindow>
|
struct ZoneWindow : public winrt::implements<ZoneWindow, IZoneWindow>
|
||||||
@ -116,8 +118,10 @@ ZoneWindow::ZoneWindow(
|
|||||||
|
|
||||||
MONITORINFO mi{};
|
MONITORINFO mi{};
|
||||||
mi.cbSize = sizeof(mi);
|
mi.cbSize = sizeof(mi);
|
||||||
if (GetMonitorInfoW(m_monitor, &mi))
|
if (!GetMonitorInfoW(m_monitor, &mi))
|
||||||
{
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
const UINT dpi = GetDpiForMonitor();
|
const UINT dpi = GetDpiForMonitor();
|
||||||
const Rect monitorRect(mi.rcMonitor);
|
const Rect monitorRect(mi.rcMonitor);
|
||||||
const Rect workAreaRect(mi.rcWork, dpi);
|
const Rect workAreaRect(mi.rcWork, dpi);
|
||||||
@ -151,13 +155,15 @@ ZoneWindow::ZoneWindow(
|
|||||||
FlashZones();
|
FlashZones();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
IFACEMETHODIMP ZoneWindow::ShowZoneWindow(bool activate, bool fadeIn) noexcept
|
IFACEMETHODIMP ZoneWindow::ShowZoneWindow(bool activate, bool fadeIn) noexcept
|
||||||
{
|
{
|
||||||
if (m_window)
|
if (!m_window)
|
||||||
{
|
{
|
||||||
|
return E_FAIL;
|
||||||
|
}
|
||||||
|
|
||||||
m_flashMode = false;
|
m_flashMode = false;
|
||||||
|
|
||||||
UINT flags = SWP_NOSIZE | SWP_NOMOVE;
|
UINT flags = SWP_NOSIZE | SWP_NOMOVE;
|
||||||
@ -184,10 +190,7 @@ IFACEMETHODIMP ZoneWindow::ShowZoneWindow(bool activate, bool fadeIn) noexcept
|
|||||||
AnimateWindow(m_window.get(), m_showAnimationDuration, AW_BLEND);
|
AnimateWindow(m_window.get(), m_showAnimationDuration, AW_BLEND);
|
||||||
InvalidateRect(m_window.get(), nullptr, true);
|
InvalidateRect(m_window.get(), nullptr, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
|
||||||
return E_FAIL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
IFACEMETHODIMP ZoneWindow::HideZoneWindow() noexcept
|
IFACEMETHODIMP ZoneWindow::HideZoneWindow() noexcept
|
||||||
@ -356,8 +359,11 @@ void ZoneWindow::InitializeZoneSets() noexcept
|
|||||||
|
|
||||||
void ZoneWindow::LoadZoneSetsFromRegistry() noexcept
|
void ZoneWindow::LoadZoneSetsFromRegistry() noexcept
|
||||||
{
|
{
|
||||||
if (wil::unique_hkey key{ RegistryHelpers::OpenKey(m_workArea) })
|
wil::unique_hkey key{RegistryHelpers::OpenKey(m_workArea)};
|
||||||
|
if (!key)
|
||||||
{
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
ZoneSetPersistedData data{};
|
ZoneSetPersistedData data{};
|
||||||
DWORD dataSize = sizeof(data);
|
DWORD dataSize = sizeof(data);
|
||||||
wchar_t value[256]{};
|
wchar_t value[256]{};
|
||||||
@ -387,12 +393,12 @@ void ZoneWindow::LoadZoneSetsFromRegistry() noexcept
|
|||||||
zoneSet->AddZone(MakeZone(data.Zones[j]), false);
|
zoneSet->AddZone(MakeZone(data.Zones[j]), false);
|
||||||
}
|
}
|
||||||
|
|
||||||
m_zoneSets.emplace_back(zoneSet);
|
|
||||||
|
|
||||||
if (zoneSetId == m_activeZoneSetId)
|
if (zoneSetId == m_activeZoneSetId)
|
||||||
{
|
{
|
||||||
UpdateActiveZoneSet(zoneSet.get());
|
UpdateActiveZoneSet(zoneSet.get());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
m_zoneSets.emplace_back(std::move(zoneSet));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -404,7 +410,6 @@ void ZoneWindow::LoadZoneSetsFromRegistry() noexcept
|
|||||||
valueLength = ARRAYSIZE(value);
|
valueLength = ARRAYSIZE(value);
|
||||||
dataSize = sizeof(data);
|
dataSize = sizeof(data);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
winrt::com_ptr<IZoneSet> ZoneWindow::AddZoneSet(ZoneSetLayout layout, int numZones, int paddingOuter, int paddingInner) noexcept
|
winrt::com_ptr<IZoneSet> ZoneWindow::AddZoneSet(ZoneSetLayout layout, int numZones, int paddingOuter, int paddingInner) noexcept
|
||||||
@ -716,8 +721,10 @@ void ZoneWindow::DrawZone(wil::unique_hdc& hdc, ColorSetting const& colorSetting
|
|||||||
}
|
}
|
||||||
FillRectARGB(hdc, &zoneRect, colorSetting.fillAlpha, colorSetting.fill, false);
|
FillRectARGB(hdc, &zoneRect, colorSetting.fillAlpha, colorSetting.fill, false);
|
||||||
|
|
||||||
if (!m_flashMode)
|
if (m_flashMode)
|
||||||
{
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
COLORREF const colorFill = RGB(255, 255, 255);
|
COLORREF const colorFill = RGB(255, 255, 255);
|
||||||
|
|
||||||
size_t const index = zone->Id();
|
size_t const index = zone->Id();
|
||||||
@ -746,7 +753,6 @@ void ZoneWindow::DrawZone(wil::unique_hdc& hdc, ColorSetting const& colorSetting
|
|||||||
|
|
||||||
offset.x = zoneRect.left + padding;
|
offset.x = zoneRect.left + padding;
|
||||||
DrawIndex(hdc, offset, index, padding, size, false, true, colorFill); // bottom left
|
DrawIndex(hdc, offset, index, padding, size, false, true, colorFill); // bottom left
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ZoneWindow::DrawIndex(wil::unique_hdc& hdc, POINT offset, size_t index, int padding, int size, bool flipX, bool flipY, COLORREF colorFill)
|
void ZoneWindow::DrawIndex(wil::unique_hdc& hdc, POINT offset, size_t index, int padding, int size, bool flipX, bool flipY, COLORREF colorFill)
|
||||||
@ -817,11 +823,15 @@ void ZoneWindow::DrawActiveZoneSet(wil::unique_hdc& hdc, RECT const& clientRect)
|
|||||||
ColorSetting const colorFlash { 200, RGB(81, 92, 107), 200, RGB(104, 118, 138), -2 };
|
ColorSetting const colorFlash { 200, RGB(81, 92, 107), 200, RGB(104, 118, 138), -2 };
|
||||||
|
|
||||||
auto zones = m_activeZoneSet->GetZones();
|
auto zones = m_activeZoneSet->GetZones();
|
||||||
size_t colorIndex = zones.size() - 1;
|
const size_t maxColorIndex = min(size(zones) - 1, size(colors) - 1);
|
||||||
|
size_t colorIndex = maxColorIndex;
|
||||||
for (auto iter = zones.rbegin(); iter != zones.rend(); iter++)
|
for (auto iter = zones.rbegin(); iter != zones.rend(); iter++)
|
||||||
{
|
{
|
||||||
if (winrt::com_ptr<IZone> zone = iter->try_as<IZone>())
|
winrt::com_ptr<IZone> zone = iter->try_as<IZone>();
|
||||||
|
if (!zone)
|
||||||
{
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
if (zone != m_highlightZone)
|
if (zone != m_highlightZone)
|
||||||
{
|
{
|
||||||
if (m_flashMode)
|
if (m_flashMode)
|
||||||
@ -842,8 +852,7 @@ void ZoneWindow::DrawActiveZoneSet(wil::unique_hdc& hdc, RECT const& clientRect)
|
|||||||
DrawZone(hdc, colorViewer, zone);
|
DrawZone(hdc, colorViewer, zone);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
colorIndex--;
|
colorIndex = colorIndex != 0 ? colorIndex - 1 : maxColorIndex;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_highlightZone)
|
if (m_highlightZone)
|
||||||
@ -930,7 +939,7 @@ void ZoneWindow::OnPaint(wil::unique_hdc& hdc) noexcept
|
|||||||
RECT clientRect;
|
RECT clientRect;
|
||||||
GetClientRect(m_window.get(), &clientRect);
|
GetClientRect(m_window.get(), &clientRect);
|
||||||
|
|
||||||
wil::unique_hdc hdcMem;;
|
wil::unique_hdc hdcMem;
|
||||||
HPAINTBUFFER bufferedPaint = BeginBufferedPaint(hdc.get(), &clientRect, BPBF_TOPDOWNDIB, nullptr, &hdcMem);
|
HPAINTBUFFER bufferedPaint = BeginBufferedPaint(hdc.get(), &clientRect, BPBF_TOPDOWNDIB, nullptr, &hdcMem);
|
||||||
if (bufferedPaint)
|
if (bufferedPaint)
|
||||||
{
|
{
|
||||||
@ -1284,7 +1293,7 @@ UINT ZoneWindow::GetDpiForMonitor() noexcept
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return (dpi == 0) ? 96 : dpi;
|
return (dpi == 0) ? DPIAware::DEFAULT_DPI : dpi;
|
||||||
}
|
}
|
||||||
#pragma endregion
|
#pragma endregion
|
||||||
|
|
||||||
|
@ -18,7 +18,16 @@ namespace {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Prevent system-wide input lagging while paused in the debugger
|
||||||
|
//#define DISABLE_LOWLEVEL_KBHOOK_WHEN_DEBUGGED
|
||||||
|
|
||||||
void start_lowlevel_keyboard_hook() {
|
void start_lowlevel_keyboard_hook() {
|
||||||
|
#if defined(_DEBUG) && defined(DISABLE_LOWLEVEL_KBHOOK_WHEN_DEBUGGED)
|
||||||
|
if(IsDebuggerPresent()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
if (!hook_handle) {
|
if (!hook_handle) {
|
||||||
hook_handle = SetWindowsHookEx(WH_KEYBOARD_LL, hook_proc, GetModuleHandle(NULL), NULL);
|
hook_handle = SetWindowsHookEx(WH_KEYBOARD_LL, hook_proc, GetModuleHandle(NULL), NULL);
|
||||||
hook_handle_copy = hook_handle;
|
hook_handle_copy = hook_handle;
|
||||||
|
@ -8,6 +8,8 @@
|
|||||||
#include "trace.h"
|
#include "trace.h"
|
||||||
#include "general_settings.h"
|
#include "general_settings.h"
|
||||||
|
|
||||||
|
#include <common/dpi_aware.h>
|
||||||
|
|
||||||
#if _DEBUG && _WIN64
|
#if _DEBUG && _WIN64
|
||||||
#include "unhandled_exception_handler.h"
|
#include "unhandled_exception_handler.h"
|
||||||
#endif
|
#endif
|
||||||
@ -32,6 +34,8 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DPIAware::EnableDPIAwarenessForThisProcess();
|
||||||
|
|
||||||
#if _DEBUG && _WIN64
|
#if _DEBUG && _WIN64
|
||||||
//Global error handlers to diagnose errors.
|
//Global error handlers to diagnose errors.
|
||||||
//We prefer this not not show any longer until there's a bug to diagnose.
|
//We prefer this not not show any longer until there's a bug to diagnose.
|
||||||
|
@ -67,7 +67,7 @@
|
|||||||
<OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
|
<OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
|
||||||
</Link>
|
</Link>
|
||||||
<Manifest>
|
<Manifest>
|
||||||
<EnableDpiAwareness>PerMonitorHighDPIAware</EnableDpiAwareness>
|
<EnableDpiAwareness>false</EnableDpiAwareness>
|
||||||
</Manifest>
|
</Manifest>
|
||||||
</ItemDefinitionGroup>
|
</ItemDefinitionGroup>
|
||||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||||
@ -92,7 +92,7 @@
|
|||||||
<OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
|
<OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
|
||||||
</Link>
|
</Link>
|
||||||
<Manifest>
|
<Manifest>
|
||||||
<EnableDpiAwareness>PerMonitorHighDPIAware</EnableDpiAwareness>
|
<EnableDpiAwareness>false</EnableDpiAwareness>
|
||||||
</Manifest>
|
</Manifest>
|
||||||
</ItemDefinitionGroup>
|
</ItemDefinitionGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
@ -60,6 +60,7 @@
|
|||||||
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
|
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
|
||||||
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
|
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
|
||||||
<AdditionalIncludeDirectories>..;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
<AdditionalIncludeDirectories>..;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||||
|
<AdditionalOptions>/Zm150 %(AdditionalOptions)</AdditionalOptions>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<CustomBuildStep>
|
<CustomBuildStep>
|
||||||
<Command>
|
<Command>
|
||||||
@ -88,6 +89,7 @@
|
|||||||
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
|
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
|
||||||
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||||
<AdditionalIncludeDirectories>..;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
<AdditionalIncludeDirectories>..;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||||
|
<AdditionalOptions>/Zm150 %(AdditionalOptions)</AdditionalOptions>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<Link>
|
<Link>
|
||||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||||
|
Loading…
Reference in New Issue
Block a user