mirror of
https://github.com/microsoft/PowerToys.git
synced 2025-12-29 00:24:42 +01:00
cleanup cursor convertion between coordinate spaces
This commit is contained in:
@@ -68,7 +68,7 @@ template<typename T>
|
||||
inline void StoreWindowParam(HWND window, T data)
|
||||
{
|
||||
static_assert(sizeof(T) <= sizeof(void*));
|
||||
SetWindowLongPtrW(window, GWLP_USERDATA, (LONG_PTR)(data));
|
||||
SetWindowLongPtrW(window, GWLP_USERDATA, reinterpret_cast<LONG_PTR>(data));
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
#include "pch.h"
|
||||
#include "BoundsToolOverlayUI.h"
|
||||
#include "CoordinateSystemConversion.h"
|
||||
#include "Clipboard.h"
|
||||
|
||||
#include <common/utils/window.h>
|
||||
@@ -27,8 +28,7 @@ LRESULT CALLBACK BoundsToolWndProc(HWND window, UINT message, WPARAM wparam, LPA
|
||||
auto toolState = GetWindowParam<BoundsToolState*>(window);
|
||||
if (!toolState)
|
||||
break;
|
||||
POINT cursorPos = toolState->commonState->cursorPos;
|
||||
ScreenToClient(window, &cursorPos);
|
||||
const POINT cursorPos = convert::FromSystemToRelativeForDirect2D(window, toolState->commonState->cursorPosSystemSpace);
|
||||
|
||||
D2D_POINT_2F newRegionStart = { .x = static_cast<float>(cursorPos.x), .y = static_cast<float>(cursorPos.y) };
|
||||
toolState->perScreen[window].currentRegionStart = newRegionStart;
|
||||
@@ -54,8 +54,7 @@ LRESULT CALLBACK BoundsToolWndProc(HWND window, UINT message, WPARAM wparam, LPA
|
||||
|
||||
if (const bool shiftPress = GetKeyState(VK_SHIFT) & 0x8000; shiftPress)
|
||||
{
|
||||
auto cursorPos = toolState->commonState->cursorPos;
|
||||
ScreenToClient(window, &cursorPos);
|
||||
const auto cursorPos = convert::FromSystemToRelativeForDirect2D(window, toolState->commonState->cursorPosSystemSpace);
|
||||
|
||||
D2D1_RECT_F rect;
|
||||
std::tie(rect.left, rect.right) = std::minmax(static_cast<float>(cursorPos.x), toolState->perScreen[window].currentRegionStart->x);
|
||||
@@ -142,7 +141,7 @@ void DrawBoundsToolTick(const CommonState& commonState,
|
||||
const auto it = toolState.perScreen.find(window);
|
||||
if (it == end(toolState.perScreen))
|
||||
return;
|
||||
|
||||
|
||||
d2dState.rt->Clear();
|
||||
|
||||
const auto& perScreen = it->second;
|
||||
@@ -152,8 +151,7 @@ void DrawBoundsToolTick(const CommonState& commonState,
|
||||
if (!perScreen.currentRegionStart.has_value())
|
||||
return;
|
||||
|
||||
POINT cursorPos = commonState.cursorPos;
|
||||
ScreenToClient(window, &cursorPos);
|
||||
const auto cursorPos = convert::FromSystemToRelativeForDirect2D(window, commonState.cursorPosSystemSpace);
|
||||
|
||||
const D2D1_RECT_F rect{ .left = perScreen.currentRegionStart->x,
|
||||
.top = perScreen.currentRegionStart->y,
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
#pragma once
|
||||
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <Windows.h>
|
||||
|
||||
namespace convert
|
||||
{
|
||||
// Converts a given point from multimonitor coordinate system to the one relative to HWND
|
||||
inline POINT FromSystemToRelative(HWND window, POINT p)
|
||||
{
|
||||
ScreenToClient(window, &p);
|
||||
return p;
|
||||
}
|
||||
|
||||
// Converts a given point from multimonitor coordinate system to the one relative to HWND and also ready
|
||||
// to be used in Direct2D calls with AA mode set to aliased
|
||||
inline POINT FromSystemToRelativeForDirect2D(HWND window, POINT p)
|
||||
{
|
||||
ScreenToClient(window, &p);
|
||||
// Submitting DrawLine calls to Direct2D with thickness == 1.f and AA mode set to aliased causes
|
||||
// them to be drawn offset by [1,1] toward upper-left corner, so we must to compensate for that.
|
||||
++p.x;
|
||||
++p.y;
|
||||
return p;
|
||||
}
|
||||
}
|
||||
@@ -1,8 +1,9 @@
|
||||
#include "pch.h"
|
||||
|
||||
#include "BGRATextureView.h"
|
||||
#include "constants.h"
|
||||
#include "Clipboard.h"
|
||||
#include "CoordinateSystemConversion.h"
|
||||
#include "constants.h"
|
||||
#include "MeasureToolOverlayUI.h"
|
||||
|
||||
#include <common/utils/window.h>
|
||||
@@ -216,8 +217,7 @@ void DrawMeasureToolTick(const CommonState& commonState,
|
||||
// Anti-aliasing is creating artifacts. Aliasing is for drawing straight lines.
|
||||
d2dState.rt->SetAntialiasMode(D2D1_ANTIALIAS_MODE_ALIASED);
|
||||
|
||||
POINT cursorPos = commonState.cursorPos;
|
||||
ScreenToClient(window, &cursorPos);
|
||||
const auto cursorPos = convert::FromSystemToRelativeForDirect2D(window, commonState.cursorPosSystemSpace);
|
||||
|
||||
if (drawHorizontalCrossLine)
|
||||
{
|
||||
|
||||
@@ -38,7 +38,7 @@ HWND CreateOverlayUIWindow(const CommonState& commonState,
|
||||
static std::once_flag windowClassesCreatedFlag;
|
||||
std::call_once(windowClassesCreatedFlag, CreateOverlayWindowClasses);
|
||||
|
||||
const auto screenArea = monitor.GetScreenSize(false);
|
||||
const auto screenArea = monitor.GetScreenSize(true);
|
||||
HWND window{ CreateWindowExW(WS_EX_TOOLWINDOW | WS_EX_TOPMOST,
|
||||
windowClass,
|
||||
L"PowerToys.MeasureToolOverlay",
|
||||
@@ -106,7 +106,7 @@ void OverlayUIState::RunUILoop()
|
||||
{
|
||||
_d2dState.rt->BeginDraw();
|
||||
|
||||
const auto cursor = _commonState.cursorPos;
|
||||
const auto cursor = _commonState.cursorPosSystemSpace;
|
||||
const bool cursorOverToolbar = _commonState.toolbarBoundingBox.inside(cursor);
|
||||
if (!cursorOverToolbar)
|
||||
_tickFunc();
|
||||
|
||||
@@ -20,10 +20,10 @@ namespace winrt::PowerToys::MeasureToolCore::implementation
|
||||
{
|
||||
while (!_stopMouseCaptureThreadSignal.is_signaled())
|
||||
{
|
||||
static_assert(sizeof(_commonState.cursorPos) == sizeof(LONG64));
|
||||
static_assert(sizeof(_commonState.cursorPosSystemSpace) == sizeof(LONG64));
|
||||
POINT cursorPos = {};
|
||||
GetCursorPos(&cursorPos);
|
||||
InterlockedExchange64(reinterpret_cast<LONG64*>(&_commonState.cursorPos), std::bit_cast<LONG64>(cursorPos));
|
||||
InterlockedExchange64(reinterpret_cast<LONG64*>(&_commonState.cursorPosSystemSpace), std::bit_cast<LONG64>(cursorPos));
|
||||
std::this_thread::sleep_for(consts::TARGET_FRAME_DURATION);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
#include "pch.h"
|
||||
|
||||
#include "constants.h"
|
||||
#include "ScreenCapturing.h"
|
||||
#include "BGRATextureView.h"
|
||||
#include "constants.h"
|
||||
#include "CoordinateSystemConversion.h"
|
||||
#include "EdgeDetection.h"
|
||||
#include "ScreenCapturing.h"
|
||||
|
||||
#include <common/Display/monitors.h>
|
||||
|
||||
@@ -324,8 +325,7 @@ void UpdateCaptureState(const CommonState& commonState,
|
||||
const MappedTextureView& textureView,
|
||||
const bool continuousCapture)
|
||||
{
|
||||
auto cursorPos = commonState.cursorPos;
|
||||
ScreenToClient(window, &cursorPos);
|
||||
const auto cursorPos = convert::FromSystemToRelative(window, commonState.cursorPosSystemSpace);
|
||||
const bool cursorInLeftScreenHalf = cursorPos.x < textureView.view.width / 2;
|
||||
const bool cursorInTopScreenHalf = cursorPos.y < textureView.view.height / 2;
|
||||
uint8_t pixelTolerance = {};
|
||||
@@ -337,13 +337,6 @@ void UpdateCaptureState(const CommonState& commonState,
|
||||
perColorChannelEdgeDetection = state.global.perColorChannelEdgeDetection;
|
||||
});
|
||||
|
||||
// We must offset mouse cursor, since its position is off by one from its center (TODO: reason?)
|
||||
if (cursorPos.x > 0)
|
||||
--cursorPos.x;
|
||||
|
||||
if (cursorPos.y > 0)
|
||||
--cursorPos.y;
|
||||
|
||||
// Every one of 4 edges is a coordinate of the last similar pixel in a row
|
||||
// Example: given a 5x5 green square on a blue background with its top-left pixel
|
||||
// at 20x100, bounds should be [20,100]-[24,104]. We don't include [25,105] or
|
||||
@@ -424,10 +417,14 @@ std::thread StartCapturingThread(const CommonState& commonState,
|
||||
while (IsWindow(window) && !commonState.closeOnOtherMonitors)
|
||||
{
|
||||
const auto now = std::chrono::high_resolution_clock::now();
|
||||
if (monitorArea.inside(commonState.cursorPos))
|
||||
if (monitorArea.inside(commonState.cursorPosSystemSpace))
|
||||
{
|
||||
#if defined(DEBUG_TEXTURE)
|
||||
auto path = std::filesystem::temp_directory_path() / "frame.bmp";
|
||||
SYSTEMTIME lt{};
|
||||
GetLocalTime(<);
|
||||
char buf[256];
|
||||
sprintf_s(buf, "frame-%02d-%02d-Monitor-%zu.bmp", lt.wHour, lt.wMinute, (uint64_t)window);
|
||||
auto path = std::filesystem::temp_directory_path() / buf;
|
||||
textureView.view.SaveAsBitmap(path.string().c_str());
|
||||
#endif
|
||||
UpdateCaptureState(commonState, state, window, textureView, continuousCapture);
|
||||
|
||||
@@ -28,7 +28,7 @@ struct CommonState
|
||||
Box toolbarBoundingBox;
|
||||
|
||||
mutable Serialized<OverlayBoxText> overlayBoxText;
|
||||
POINT cursorPos = {}; // updated atomically
|
||||
POINT cursorPosSystemSpace = {}; // updated atomically
|
||||
std::atomic_bool closeOnOtherMonitors = false;
|
||||
};
|
||||
|
||||
|
||||
@@ -81,6 +81,7 @@ template<typename Func>
|
||||
return std::thread{ [f = std::move(f), description = std::wstring{ description }] {
|
||||
try
|
||||
{
|
||||
SetThreadDescription(GetCurrentThread(), description.c_str());
|
||||
f();
|
||||
}
|
||||
catch (const std::exception& ex)
|
||||
|
||||
@@ -1,20 +1,11 @@
|
||||
#pragma once
|
||||
|
||||
#define COMPOSITION
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <windows.h>
|
||||
#include <strsafe.h>
|
||||
#include <hIdUsage.h>
|
||||
#include <shellapi.h>
|
||||
|
||||
#ifdef COMPOSITION
|
||||
#include <windows.ui.composition.interop.h>
|
||||
#include <DispatcherQueue.h>
|
||||
#include <winrt/Windows.System.h>
|
||||
#include <winrt/Windows.Foundation.h>
|
||||
#include <winrt/Windows.UI.Composition.Desktop.h>
|
||||
#endif
|
||||
|
||||
#include <thread>
|
||||
|
||||
#include <winrt/Windows.Foundation.Collections.h>
|
||||
|
||||
Reference in New Issue
Block a user