mirror of
https://github.com/microsoft/PowerToys.git
synced 2026-04-05 10:46:33 +02:00
[MouseJump][CQ]Refactor "common" classes into a separate project (#34333)
* [Mouse Jump] - moving common code to MouseJump.Common project - #25482 * [Mouse Jump] - fixing warnings in MouseJump.Common - #25482 * [MouseJump] - cherrypick 5653b4 - Exclude MouseJump Common tests from the checks # Conflicts: # src/modules/MouseUtils/MouseJump.Common.UnitTests/MouseJump.Common.UnitTests.csproj * [mOuSEjUMP] - cherry pick 61aab9 - Fix ci build issues # Conflicts: # src/modules/MouseUtils/MouseJump.Common.UnitTests/MouseJump.Common.UnitTests.csproj * [Mouse Jump] - remove project type guids - #25482 * [Mouse Jump] - simplify mousejump *.csproj files - #25482 * [Mouse Jump] - fixing broken tests - #25482 * [Mouse Jump] - fixing broken build - #25482 * [Mouse Jump] - editing MouseJump.Common.UnitTests.csproj - #25482 * [Mouse Jump] - editing MouseJump.Common.csproj (UseWindowsForms=true) - #25482 * [Mouse Jump] - fixing spellcheck - #25482 * [MouseJump] - enabled implicit usings - #25482 * [Mouse Jump] - re-add csproj attributes - #27511 * ci: Fix signing of Common dll --------- Co-authored-by: Clayton <mike.clayton@delinian.com>
This commit is contained in:
144
src/modules/MouseUtils/MouseJump.Common/Helpers/MouseHelper.cs
Normal file
144
src/modules/MouseUtils/MouseJump.Common/Helpers/MouseHelper.cs
Normal file
@@ -0,0 +1,144 @@
|
||||
// Copyright (c) Microsoft Corporation
|
||||
// The Microsoft Corporation licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
using System.ComponentModel;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
using MouseJump.Common.Models.Drawing;
|
||||
using MouseJump.Common.NativeMethods;
|
||||
using static MouseJump.Common.NativeMethods.Core;
|
||||
using static MouseJump.Common.NativeMethods.User32;
|
||||
|
||||
namespace MouseJump.Common.Helpers;
|
||||
|
||||
public static class MouseHelper
|
||||
{
|
||||
/// <summary>
|
||||
/// Calculates where to move the cursor to by projecting a point from
|
||||
/// the preview image onto the desktop and using that as the target location.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// The preview image origin is (0, 0) but the desktop origin may be non-zero,
|
||||
/// or even negative if the primary monitor is not the at the top-left of the
|
||||
/// entire desktop rectangle, so results may contain negative coordinates.
|
||||
/// </remarks>
|
||||
public static PointInfo GetJumpLocation(PointInfo previewLocation, SizeInfo previewSize, RectangleInfo desktopBounds)
|
||||
{
|
||||
return previewLocation
|
||||
.Scale(previewSize.ScaleToFitRatio(desktopBounds.Size))
|
||||
.Offset(desktopBounds.Location);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get the current position of the cursor.
|
||||
/// </summary>
|
||||
public static PointInfo GetCursorPosition()
|
||||
{
|
||||
var lpPoint = new LPPOINT(new POINT(0, 0));
|
||||
var result = User32.GetCursorPos(lpPoint);
|
||||
if (!result)
|
||||
{
|
||||
throw new Win32Exception(
|
||||
Marshal.GetLastWin32Error());
|
||||
}
|
||||
|
||||
var point = lpPoint.ToStructure();
|
||||
lpPoint.Free();
|
||||
|
||||
return new PointInfo(
|
||||
point.x, point.y);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Moves the cursor to the specified location.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// See https://github.com/mikeclayton/FancyMouse/pull/3
|
||||
/// </remarks>
|
||||
public static void SetCursorPosition(PointInfo location)
|
||||
{
|
||||
// set the new cursor position *twice* - the cursor sometimes end up in
|
||||
// the wrong place if we try to cross the dead space between non-aligned
|
||||
// monitors - e.g. when trying to move the cursor from (a) to (b) we can
|
||||
// *sometimes* - for no clear reason - end up at (c) instead.
|
||||
//
|
||||
// +----------------+
|
||||
// |(c) (b) |
|
||||
// | |
|
||||
// | |
|
||||
// | |
|
||||
// +---------+ |
|
||||
// | (a) | |
|
||||
// +---------+----------------+
|
||||
//
|
||||
// setting the position a second time seems to fix this and moves the
|
||||
// cursor to the expected location (b)
|
||||
var target = location.ToPoint();
|
||||
for (var i = 0; i < 2; i++)
|
||||
{
|
||||
var result = User32.SetCursorPos(target.X, target.Y);
|
||||
if (!result)
|
||||
{
|
||||
throw new Win32Exception(
|
||||
Marshal.GetLastWin32Error());
|
||||
}
|
||||
|
||||
var current = MouseHelper.GetCursorPosition();
|
||||
if ((current.X == target.X) || (current.Y == target.Y))
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// temporary workaround for issue #1273
|
||||
MouseHelper.SimulateMouseMovementEvent(location);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sends an input simulating an absolute mouse move to the new location.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// See https://github.com/microsoft/PowerToys/issues/24523
|
||||
/// https://github.com/microsoft/PowerToys/pull/24527
|
||||
/// </remarks>
|
||||
internal static void SimulateMouseMovementEvent(PointInfo location)
|
||||
{
|
||||
var inputs = new User32.INPUT[]
|
||||
{
|
||||
new(
|
||||
type: INPUT_TYPE.INPUT_MOUSE,
|
||||
data: new INPUT.DUMMYUNIONNAME(
|
||||
mi: new MOUSEINPUT(
|
||||
dx: (int)MouseHelper.CalculateAbsoluteCoordinateX(location.X),
|
||||
dy: (int)MouseHelper.CalculateAbsoluteCoordinateY(location.Y),
|
||||
mouseData: 0,
|
||||
dwFlags: MOUSE_EVENT_FLAGS.MOUSEEVENTF_MOVE | MOUSE_EVENT_FLAGS.MOUSEEVENTF_ABSOLUTE,
|
||||
time: 0,
|
||||
dwExtraInfo: ULONG_PTR.Null))),
|
||||
};
|
||||
var result = User32.SendInput(
|
||||
(UINT)inputs.Length,
|
||||
new LPINPUT(inputs),
|
||||
INPUT.Size * inputs.Length);
|
||||
if (result != inputs.Length)
|
||||
{
|
||||
throw new Win32Exception(
|
||||
Marshal.GetLastWin32Error());
|
||||
}
|
||||
}
|
||||
|
||||
private static decimal CalculateAbsoluteCoordinateX(decimal x)
|
||||
{
|
||||
// If MOUSEEVENTF_ABSOLUTE value is specified, dx and dy contain normalized absolute coordinates between 0 and 65,535.
|
||||
// see https://learn.microsoft.com/en-us/windows/win32/api/winuser/ns-winuser-mouseinput
|
||||
return (x * 65535) / User32.GetSystemMetrics(SYSTEM_METRICS_INDEX.SM_CXSCREEN);
|
||||
}
|
||||
|
||||
private static decimal CalculateAbsoluteCoordinateY(decimal y)
|
||||
{
|
||||
// If MOUSEEVENTF_ABSOLUTE value is specified, dx and dy contain normalized absolute coordinates between 0 and 65,535.
|
||||
// see https://learn.microsoft.com/en-us/windows/win32/api/winuser/ns-winuser-mouseinput
|
||||
return (y * 65535) / User32.GetSystemMetrics(SYSTEM_METRICS_INDEX.SM_CYSCREEN);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user