Skip to content

Commit

Permalink
Add click count when simulating mouse press/release
Browse files Browse the repository at this point in the history
macOS requires that the current click count be specified when simulating
mouse press/release. E.g. when simulating a double click, the first
press/release pair will have the click count of 1, and the second pair
will have the click count of 2.

The global hook in libuiohook counts the clicks based on time, but
counting clicks the same way when simulating events is problematic so
the click count was added explicitly.

Click count is used only on macOS and is ignored on Windows and Linux
  • Loading branch information
TolikPylypchuk committed Sep 18, 2023
1 parent 26a0ebc commit f234dc6
Show file tree
Hide file tree
Showing 7 changed files with 663 additions and 11 deletions.
195 changes: 195 additions & 0 deletions SharpHook.Tests/EventSimulatorTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,51 @@ public void SimulateMousePressFail(MouseButton button, FailedUioHookResult resul
Assert.Equal(result.Value, actualResult);
}

[Property(DisplayName = "EventSimulator should simulate mouse presses with explicit clicks")]
public void SimulateMousePressExplicitClicks(MouseButton button, ushort clicks)
{
// Arrange

var provider = new TestProvider();
var simulator = new EventSimulator(provider);

// Act

var result = simulator.SimulateMousePress(button, clicks);

// Assert

Assert.Equal(UioHookResult.Success, result);
Assert.Single(provider.PostedEvents);

var postedEvent = provider.PostedEvents[0];
Assert.Equal(EventType.MousePressedIgnoreCoordinates, postedEvent.Type);
Assert.Equal(button, postedEvent.Mouse.Button);
Assert.Equal(clicks, postedEvent.Mouse.Clicks);
}

[Property(DisplayName =
"EventSimulator should return an error if simulating a mouse press with explicit clicks fails")]
public void SimulateMousePressExplicitClicksFail(MouseButton button, ushort clicks, FailedUioHookResult result)
{
// Arrange

var provider = new TestProvider
{
PostEventResult = result.Value
};

var simulator = new EventSimulator(provider);

// Act

var actualResult = simulator.SimulateMousePress(button, clicks);

// Assert

Assert.Equal(result.Value, actualResult);
}

[Property(DisplayName = "EventSimulator should simulate mouse presses with explicit coordinates")]
public void SimulateMousePressExplicitCoordinates(short x, short y, MouseButton button)
{
Expand Down Expand Up @@ -186,6 +231,58 @@ public void SimulateMousePressExplicitCoordinatesFail(
Assert.Equal(result.Value, actualResult);
}

[Property(DisplayName = "EventSimulator should simulate mouse presses with explicit coordinates and clicks")]
public void SimulateMousePressExplicitCoordinatesAndClicks(short x, short y, MouseButton button, ushort clicks)
{
// Arrange

var provider = new TestProvider();
var simulator = new EventSimulator(provider);

// Act

var result = simulator.SimulateMousePress(x, y, button, clicks);

// Assert

Assert.Equal(UioHookResult.Success, result);
Assert.Single(provider.PostedEvents);

var postedEvent = provider.PostedEvents[0];
Assert.Equal(EventType.MousePressed, postedEvent.Type);
Assert.Equal(x, postedEvent.Mouse.X);
Assert.Equal(y, postedEvent.Mouse.Y);
Assert.Equal(button, postedEvent.Mouse.Button);
Assert.Equal(clicks, postedEvent.Mouse.Clicks);
}

[Property(DisplayName =
"EventSimulator should return an error if simulating a mouse press with explicit coordinates and clicks fails")]
public void SimulateMousePressExplicitCoordinatesAndClicksFail(
short x,
short y,
MouseButton button,
ushort clicks,
FailedUioHookResult result)
{
// Arrange

var provider = new TestProvider
{
PostEventResult = result.Value
};

var simulator = new EventSimulator(provider);

// Act

var actualResult = simulator.SimulateMousePress(x, y, button, clicks);

// Assert

Assert.Equal(result.Value, actualResult);
}

[Property(DisplayName = "EventSimulator should simulate mouse releases")]
public void SimulateMouseRelease(MouseButton button)
{
Expand Down Expand Up @@ -229,6 +326,51 @@ public void SimulateMouseReleaseFail(MouseButton button, FailedUioHookResult res
Assert.Equal(result.Value, actualResult);
}

[Property(DisplayName = "EventSimulator should simulate mouse releases with explicit clicks")]
public void SimulateMouseReleaseExplicitClicks(MouseButton button, ushort clicks)
{
// Arrange

var provider = new TestProvider();
var simulator = new EventSimulator(provider);

// Act

var result = simulator.SimulateMouseRelease(button, clicks);

// Assert

Assert.Equal(UioHookResult.Success, result);
Assert.Single(provider.PostedEvents);

var postedEvent = provider.PostedEvents[0];
Assert.Equal(EventType.MouseReleasedIgnoreCoordinates, postedEvent.Type);
Assert.Equal(button, postedEvent.Mouse.Button);
Assert.Equal(clicks, postedEvent.Mouse.Clicks);
}

[Property(DisplayName =
"EventSimulator should return an error if simulating a mouse press with explicit clicks fails")]
public void SimulateMouseReleaseExplicitClicksFail(MouseButton button, ushort clicks, FailedUioHookResult result)
{
// Arrange

var provider = new TestProvider
{
PostEventResult = result.Value
};

var simulator = new EventSimulator(provider);

// Act

var actualResult = simulator.SimulateMousePress(button, clicks);

// Assert

Assert.Equal(result.Value, actualResult);
}

[Property(DisplayName = "EventSimulator should simulate mouse releases with explicit coordinates")]
public void SimulateMouseReleaseExplicitCoordinates(short x, short y, MouseButton button)
{
Expand Down Expand Up @@ -279,6 +421,59 @@ public void SimulateMouseReleaseExplicitCoordinatesFail(
Assert.Equal(result.Value, actualResult);
}

[Property(DisplayName = "EventSimulator should simulate mouse releases with explicit coordinates and clicks")]
public void SimulateMouseReleaseExplicitCoordinatesAndClicks(short x, short y, MouseButton button, ushort clicks)
{
// Arrange

var provider = new TestProvider();
var simulator = new EventSimulator(provider);

// Act

var result = simulator.SimulateMouseRelease(x, y, button, clicks);

// Assert

Assert.Equal(UioHookResult.Success, result);
Assert.Single(provider.PostedEvents);

var postedEvent = provider.PostedEvents[0];
Assert.Equal(EventType.MouseReleased, postedEvent.Type);
Assert.Equal(x, postedEvent.Mouse.X);
Assert.Equal(y, postedEvent.Mouse.Y);
Assert.Equal(button, postedEvent.Mouse.Button);
Assert.Equal(clicks, postedEvent.Mouse.Clicks);
}

[Property(DisplayName =
"EventSimulator should return an error " +
"if simulating a mouse release with explicit coordinates and clicks fails")]
public void SimulateMouseReleaseExplicitCoordinatesAndClicksFail(
short x,
short y,
MouseButton button,
ushort clicks,
FailedUioHookResult result)
{
// Arrange

var provider = new TestProvider
{
PostEventResult = result.Value
};

var simulator = new EventSimulator(provider);

// Act

var actualResult = simulator.SimulateMouseRelease(x, y, button, clicks);

// Assert

Assert.Equal(result.Value, actualResult);
}

[Property(DisplayName = "EventSimulator should simulate mouse movement")]
public void SimulateMouseMovement(short x, short y)
{
Expand Down
Loading

0 comments on commit f234dc6

Please sign in to comment.