Skip to content

Commit f0d9aef

Browse files
Update the docs for version 7.1.0
1 parent 1266a3e commit f0d9aef

File tree

6 files changed

+143
-17
lines changed

6 files changed

+143
-17
lines changed

CHANGELOG.md

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,28 @@
11
# SharpHook Changelog
22

3+
## [v7.1.0](https://github.com/TolikPylypchuk/SharpHook/releases/tag/v7.1.0) (November 16, 2025)
4+
5+
- A sequence of events can now be simulated together using `IEventSimulator.Sequence`,
6+
`IEventSimulationSequenceBuilder`, and `IEventSimulationSequenceTemplate`.
7+
8+
- When simulating mouse wheel events on Windows, the rotation value is not flipped anymore if the scrolling direction is
9+
reversed in settings.
10+
11+
- `KeyCode.VcKanji` and `KeyCode.VcHangul` were marked as obsolete - instead, `KeyCode.VcHanja` and `KeyCode.VcKana`
12+
should be used respectively.
13+
14+
- .NET 10 was added as a target.
15+
16+
- `net8.0-maccatalyst` was removed as a target since .NET refuses to compile the project if it's present.
17+
18+
- SharpHook.Reactive now depends on Rx.NET 6.1.0.
19+
20+
- The Mac Catalyst targets can now be conditionally skipped when building SharpHook which makes it possible to build it
21+
on Linux.
22+
23+
- libuiohook was updated to commit
24+
[57a8f17](https://github.com/TolikPylypchuk/libuiohook/tree/57a8f17cb4ec78bb6a33ea1668fa87ebedcefac7).
25+
326
## [v7.0.3](https://github.com/TolikPylypchuk/SharpHook/releases/tag/v7.0.3) (October 5, 2025)
427

528
- Mouse button release events for button 4 and 5 are now correctly dispatched on macOS.

README.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -328,6 +328,9 @@ simulator.SimulateKeyPress(KeyCode.VcC);
328328
simulator.SimulateKeyRelease(KeyCode.VcC);
329329
simulator.SimulateKeyRelease(KeyCode.VcLeftControl);
330330

331+
// Simulate pressing Ctrl, then pressing C, then releasing C, then releasing Ctrl
332+
simulator.SimulateKeyStroke(KeyCode.VcLeftControl, KeyCode.VcC);
333+
331334
// Press the left mouse button
332335
simulator.SimulateMousePress(MouseButton.Button1);
333336

docs/articles/about.md

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ I'm not giving up on this library any time soon.
1212
In order to build this library, you'll first need to get libuiohook binaries. You you can get a
1313
[nightly build from this repository](https://github.com/TolikPylypchuk/SharpHook/actions/workflows/build.yml), or you
1414
can build them yourself as instructed in the [libuiohook fork](https://github.com/TolikPylypchuk/libuiohook) that
15-
SharpHook uses (not recommended as it's non-trivial, and you should most probably use the same options that the build in
15+
SharpHook uses (not recommended as it's non-trivial and you should most probably use the same options that the build in
1616
this repository uses anyway).
1717

1818
Place the binaries into the appropriate directories in the `SharpHook` project, as described in the following table:
@@ -51,10 +51,36 @@ Place the binaries into the appropriate directories in the `SharpHook` project,
5151
</table>
5252

5353
With libuiohook in place, you can build SharpHook using your usual methods, e.g. with Visual Studio or the `dotnet` CLI.
54-
You need .NET 9 to build SharpHook.
54+
You need .NET 10 with the `maccatalyst` workload to build SharpHook. If you are building on Linux where the
55+
`maccatalyst` workload is not supported, or if you don't want to install this workload, you can set the
56+
`SHARPHOOK_SKIP_MACCATALYST` environment variable to anything other than `false` (case-insensitive), and the Mac
57+
Catalyst targets will be skipped.
5558

5659
## Changelog
5760

61+
### [v7.1.0](https://github.com/TolikPylypchuk/SharpHook/releases/tag/v7.1.0) (November 16, 2025)
62+
63+
- A sequence of events can now be simulated together using `IEventSimulator.Sequence`,
64+
`IEventSimulationSequenceBuilder`, and `IEventSimulationSequenceTemplate`.
65+
66+
- When simulating mouse wheel events on Windows, the rotation value is not flipped anymore if the scrolling direction is
67+
reversed in settings.
68+
69+
- `KeyCode.VcKanji` and `KeyCode.VcHangul` were marked as obsolete - instead, `KeyCode.VcHanja` and `KeyCode.VcKana`
70+
should be used respectively.
71+
72+
- .NET 10 was added as a target.
73+
74+
- `net8.0-maccatalyst` was removed as a target since .NET refuses to compile the project if it's present.
75+
76+
- SharpHook.Reactive now depends on Rx.NET 6.1.0.
77+
78+
- The Mac Catalyst targets can now be conditionally skipped when building SharpHook which makes it possible to build it
79+
on Linux.
80+
81+
- libuiohook was updated to commit
82+
[57a8f17](https://github.com/TolikPylypchuk/libuiohook/tree/57a8f17cb4ec78bb6a33ea1668fa87ebedcefac7).
83+
5884
### [v7.0.3](https://github.com/TolikPylypchuk/SharpHook/releases/tag/v7.0.3) (October 5, 2025)
5985

6086
- Mouse button release events for button 4 and 5 are now correctly dispatched on macOS.

docs/articles/keycodes.md

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,9 @@ Sources:
1313
- X11: `/usr/share/X11/xkb/keycodes/evdev` as defined in Kubuntu 22.04
1414
- Evdev: `input-event-codes.h` from the Linux source code.
1515

16+
> [!NOTE]
17+
> Key codes marked with <sup>O</sup> are obsolete.
18+
1619
<table>
1720
<thead>
1821
<tr>
@@ -1106,22 +1109,22 @@ Sources:
11061109
<td><code>VcKana</code></td>
11071110
<td><code>VK_KANA</code></td>
11081111
<td><code>kVK_JIS_Kana</code></td>
1109-
<td>-</td>
1110-
<td>-</td>
1112+
<td><code>HNGL</code></td>
1113+
<td><code>KEY_HANGEUL</code></td>
11111114
</tr>
11121115
<tr>
1113-
<td><code>VcKanji</code></td>
1114-
<td><code>VK_KANJI</code></td>
1116+
<td><code>VcKanji</code><sup>O</sup></td>
1117+
<td><code>VK_KANJI</code> and <code>VK_HANJA</code></td>
11151118
<td>-</td>
11161119
<td>-</td>
11171120
<td>-</td>
11181121
</tr>
11191122
<tr>
1120-
<td><code>VcHangul</code></td>
1121-
<td><code>VK_HANGUL</code></td>
1123+
<td><code>VcHangul</code><sup>O</sup></td>
1124+
<td><code>VK_HANGUL</code> and <code>VK_KANA</code></td>
1125+
<td>-</td>
1126+
<td>-</td>
11221127
<td>-</td>
1123-
<td><code>HNGL</code></td>
1124-
<td><code>KEY_HANGEUL</code></td>
11251128
</tr>
11261129
<tr>
11271130
<td><code>VcJunja</code></td>
@@ -1139,7 +1142,7 @@ Sources:
11391142
</tr>
11401143
<tr>
11411144
<td><code>VcHanja</code></td>
1142-
<td><code>VK_HANJA</code></td>
1145+
<td><code>VK_HANJA</code> and <code>VK_KANJI</code></td>
11431146
<td>-</td>
11441147
<td><code>HJCV</code></td>
11451148
<td><code>KEY_HANJA</code></td>

docs/articles/native.md

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -108,11 +108,18 @@ contains the `KeyTypedEnabled` property which can also be used to control this b
108108
## Simulating Input Events
109109

110110
`UioHook` contains the `PostEvent` method for simulating input events. It accepts a `UioHookEvent`, but it doesn't need
111-
all its fields. Only `Type` and `Keyboard`/`Mouse`/`Wheel` should be present.
112-
113-
`PostEvent` returns `UioHookResult` to indicate whether it was successful or not.
114-
115-
This method is also defined in the `SharpHook.Providers.IEventSimulationProvider` interface.
111+
all its fields. Only `Type` and `Keyboard`/`Mouse`/`Wheel` should be present. `PostEvent` returns `UioHookResult` to
112+
indicate whether it was successful or not.
113+
114+
`UioHook` also contains the `PostEvents` method for simulating sequences of input events. It accepts an array of
115+
`UioHookEvent` and its size. This method should be preferred to multiple calls to `PostEvent` when simulating multiple
116+
events. On Windows, it simulates all events using a single Windows API call. On macOS and Linux, it simulates each event
117+
one-by-one, but it's still slightly more efficient than multiple `PostEvent` calls as some structures are only
118+
initialized once for all events. `PostEvent` also returns `UioHookResult` to indicate whether it was successful or not.
119+
On Windows, either all events are simulated, or none are. On macOS and Linux, if a failure occurs in the middle of the
120+
simulation sequence, then further events will not be simulated.
121+
122+
These methods are also defined in the `SharpHook.Providers.IEventSimulationProvider` interface.
116123

117124
The following table describes the specifics of simulating each event type.
118125

docs/articles/simulation.md

Lines changed: 65 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,15 @@
33
SharpHook provides the ability to simulate keyboard and mouse events, as well as text entry, in a cross-platform way as
44
well. It provides the `IEventSimulator` interface, and the default implementation, `EventSimulator`, which calls
55
`UioHook.PostEvent` to simulate the events by default (though it's configurable). The methods in this interface return
6-
a `UioHookResult` to specify whether the event was simulated successfully, or not.
6+
a `UioHookResult` to specify whether the events were simulated successfully or not.
77

88
Simulated events can be distinguished from real ones in a global hook handler with the `HookEventArgs.IsEventSimulated`
99
property.
1010

1111
## Event Simulation
1212

13+
### Example
14+
1315
Input event simulation is quite straightforward. Here's a quick example:
1416

1517
```csharp
@@ -28,6 +30,9 @@ simulator.SimulateKeyPress(KeyCode.VcC);
2830
simulator.SimulateKeyRelease(KeyCode.VcC);
2931
simulator.SimulateKeyRelease(KeyCode.VcLeftControl);
3032

33+
// Simulate pressing Ctrl, then pressing C, then releasing C, then releasing Ctrl
34+
simulator.SimulateKeyStroke(KeyCode.VcLeftControl, KeyCode.VcC);
35+
3136
// Press the left mouse button
3237
simulator.SimulateMousePress(MouseButton.Button1);
3338

@@ -53,6 +58,8 @@ simulator.SimulateMouseWheel(
5358
type: MouseWheelScrollType.UnitScroll); // UnitScroll by default
5459
```
5560

61+
### Mouse Wheel Simulation
62+
5663
Mouse wheel simulation is a little more complex than other events.
5764

5865
A positive `rotation` value indicates scrolling up or left, and a negative value indicates scrolling down or right.
@@ -65,6 +72,63 @@ scrolling, so `MouseWheelScrollType.BlockScroll` is recommended for line scrolli
6572

6673
On Linux, there is no fixed recommendation, but multiples of 100 can be used. The value of `type` is ignored.
6774

75+
### Simulating a Sequence of Events
76+
77+
`IEventSimulator` contains the `Sequence` method which returns an `IEventSimulationSequenceBuilder`. This object can be
78+
used to build a sequence of events that will be simulated together. If contains several methods like `AddKeyPress` and
79+
`AddMouseMovement` which add specific events to the sequence. It also contains general-purpose methods: `AddEvent` and
80+
`AddEvents` which can add any event, as well as `RemoveEvent` and `RemoveEvents` which remove specific events from the
81+
sequence. The events can be simulated using the `Simulate` method. For example:
82+
83+
```csharp
84+
simulator.Sequence()
85+
.AddMouseMovementRelative(20, 20)
86+
.AddMousePress(MouseButton.Button1)
87+
.AddMouseRelease(MouseButton.Button1)
88+
.AddMouseMovementRelative(-20, -20)
89+
.Simulate();
90+
```
91+
92+
Using `Sequence` should be preferred to multiple calls to various `SimulateXXX` when simulating multiple events. On
93+
Windows, all events will be simulated using a single Windows API call. On macOS and Linux, each event will be simulated
94+
one-by-one, but it's still slightly more efficient than multiple `PostEvent` calls as some structures will only be
95+
initialized once for all events. `IEventSimulationSequenceBuilder.Simulate` also returns `UioHookResult` to indicate
96+
whether it was successful or not. On Windows, either all events are simulated, or none are. On macOS and Linux, if a
97+
failure occurs in the middle of the simulation sequence, then further events will not be simulated.
98+
99+
`IEventSimulationSequenceBuilder` also contains the `CreateTemplate` method which returns an
100+
`IEventSimulationSequenceTemplate`. This object represents an immutable template for simulating a predetermined sequence
101+
of events and contains only a single method - `Simulate`. For example:
102+
103+
```csharp
104+
var diagonalScrollTemplate = simulator.Sequence()
105+
.AddMouseWheel(rotation: -120, direction: MouseWheelScrollDirection.Vertical)
106+
.AddMouseWheel(rotation: -120, direction: MouseWheelScrollDirection.Horizontal)
107+
.CreateTemplate();
108+
109+
diagonalScrollTemplate.Simulate();
110+
diagonalScrollTemplate.Simulate();
111+
diagonalScrollTemplate.Simulate();
112+
```
113+
114+
`IEventSimulationSequenceBuilder` has the `AddKeyStroke` extension method which adds a sequence of key presses and a
115+
reversed sequence of key releases. For example, these two snippets will have equivalent results:
116+
117+
```csharp
118+
builder.AddKeyStroke(KeyCode.VcLeftControl, KeyCode.VcC);
119+
```
120+
121+
```csharp
122+
builder
123+
.AddKeyPress(KeyCode.VcLeftControl)
124+
.AddKeyPress(KeyCode.VcC)
125+
.AddKeyRelease(KeyCode.VcC)
126+
.AddKeyRelease(KeyCode.VcLeftControl);
127+
```
128+
129+
`IEventSimulator` has the `SimulateKeyStroke` extension method which creates a sequence builder, calls `AddKeyStroke`
130+
for it, and simulates this sequence of events.
131+
68132
## Text Entry Simulation
69133

70134
SharpHook also provides text entry simulation. `IEventSimulator` contains the `SimulateTextEntry` method which accepts

0 commit comments

Comments
 (0)