Skip to content

Commit 61c80df

Browse files
committed
feat: Simulate preview key events for tests
1 parent 336d0bf commit 61c80df

File tree

1 file changed

+65
-9
lines changed

1 file changed

+65
-9
lines changed

src/Uno.UI.RuntimeTests/IntegrationTests/common/TestServices.KeyboardHelper.cs

Lines changed: 65 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,9 @@
77
using Windows.UI.Core;
88
using Microsoft.UI.Xaml;
99
using Microsoft.UI.Xaml.Input;
10+
using DirectUI;
11+
using Uno.UI.Xaml.Core;
12+
using Uno.UI.Xaml.Input;
1013

1114
namespace Private.Infrastructure
1215
{
@@ -166,7 +169,15 @@ public static async void PressKeySequence(string keys, UIElement element = null)
166169
var key = keyInstruction.Substring(4, keyInstruction.Length - 4);
167170
if (m_vKeyMapping.TryGetValue(key, out var vKey))
168171
{
169-
await RaiseOnElementDispatcherAsync(element, keyDownCodePos == 0 ? UIElement.KeyDownEvent : UIElement.KeyUpEvent, new KeyRoutedEventArgs(element, vKey, activeModifiers));
172+
var keyArgs = new KeyRoutedEventArgs(element, vKey, activeModifiers);
173+
174+
var previewEvent = keyDownCodePos == 0 ? UIElement.PreviewKeyDownEvent : UIElement.PreviewKeyUpEvent;
175+
var mainEvent = keyDownCodePos == 0 ? UIElement.KeyDownEvent : UIElement.KeyUpEvent;
176+
await RaiseOnElementDispatcherAsync(element, previewEvent, keyArgs, true);
177+
if (!keyArgs.Handled)
178+
{
179+
await RaiseOnElementDispatcherAsync(element, mainEvent, keyArgs);
180+
}
170181
}
171182

172183
// If modifiers were changed, update modifiers variable
@@ -214,22 +225,42 @@ public static async void PressKeySequence(string keys, UIElement element = null)
214225
{
215226
if (m_vKeyMapping.TryGetValue("shift", out var vShiftKey))
216227
{
217-
await RaiseOnElementDispatcherAsync(element, UIElement.KeyDownEvent, new KeyRoutedEventArgs(element, vShiftKey, VirtualKeyModifiers.None));
228+
var keyDownArgs = new KeyRoutedEventArgs(element, vShiftKey, VirtualKeyModifiers.None);
229+
await RaiseOnElementDispatcherAsync(element, UIElement.PreviewKeyDownEvent, keyDownArgs);
230+
if (!keyDownArgs.Handled)
231+
{
232+
await RaiseOnElementDispatcherAsync(element, UIElement.KeyDownEvent, keyDownArgs);
233+
}
218234
}
219235
}
220236

221237
if (m_vKeyMapping.TryGetValue(key, out var vKey))
222238
{
223239
var modifiers = shouldShift ? VirtualKeyModifiers.Shift : VirtualKeyModifiers.None;
224-
await RaiseOnElementDispatcherAsync(element, UIElement.KeyDownEvent, new KeyRoutedEventArgs(element, vKey, modifiers));
225-
await RaiseOnElementDispatcherAsync(element, UIElement.KeyUpEvent, new KeyRoutedEventArgs(element, vKey, modifiers));
240+
var keyDownArgs = new KeyRoutedEventArgs(element, vKey, modifiers);
241+
await RaiseOnElementDispatcherAsync(element, UIElement.PreviewKeyDownEvent, keyDownArgs);
242+
if (!keyDownArgs.Handled)
243+
{
244+
await RaiseOnElementDispatcherAsync(element, UIElement.KeyDownEvent, keyDownArgs);
245+
}
246+
var keyUpArgs = new KeyRoutedEventArgs(element, vKey, modifiers);
247+
await RaiseOnElementDispatcherAsync(element, UIElement.PreviewKeyDownEvent, keyUpArgs);
248+
if (!keyUpArgs.Handled)
249+
{
250+
await RaiseOnElementDispatcherAsync(element, UIElement.KeyUpEvent, keyUpArgs);
251+
}
226252
}
227253

228254
if (shouldShift)
229255
{
230256
if (m_vKeyMapping.TryGetValue("shift", out var vShiftKey))
231257
{
232-
await RaiseOnElementDispatcherAsync(element, UIElement.KeyUpEvent, new KeyRoutedEventArgs(element, vShiftKey, VirtualKeyModifiers.None));
258+
var keyUpArgs = new KeyRoutedEventArgs(element, vShiftKey, VirtualKeyModifiers.None);
259+
await RaiseOnElementDispatcherAsync(element, UIElement.PreviewKeyDownEvent, keyUpArgs);
260+
if (!keyUpArgs.Handled)
261+
{
262+
await RaiseOnElementDispatcherAsync(element, UIElement.KeyUpEvent, keyUpArgs);
263+
}
233264
}
234265
}
235266
}
@@ -239,17 +270,42 @@ public static async void PressKeySequence(string keys, UIElement element = null)
239270
posEnd = keys.IndexOf("#", posStart);
240271
}
241272

242-
async Task RaiseOnElementDispatcherAsync(UIElement element, RoutedEvent routedEvent, RoutedEventArgs args)
273+
async Task RaiseOnElementDispatcherAsync(UIElement element, RoutedEvent routedEvent, KeyRoutedEventArgs args, bool isTunneling = false)
243274
{
244275
bool raiseSynchronously = element.Dispatcher.HasThreadAccess;
245276

246-
if (raiseSynchronously)
277+
// Workaround for not simulating the last input device type correctly yet.
278+
var inputManager = VisualTree.GetContentRootForElement(element).InputManager;
279+
if (XboxUtility.IsGamepadNavigationInput(args.OriginalKey))
247280
{
248-
element.SafeRaiseEvent(routedEvent, args);
281+
inputManager.LastInputDeviceType = InputDeviceType.GamepadOrRemote;
249282
}
250283
else
251284
{
252-
await element.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () => element.SafeRaiseEvent(routedEvent, args));
285+
inputManager.LastInputDeviceType = InputDeviceType.Keyboard;
286+
}
287+
288+
if (isTunneling)
289+
{
290+
if (raiseSynchronously)
291+
{
292+
element.SafeRaiseTunnelingEvent(routedEvent, args);
293+
}
294+
else
295+
{
296+
await element.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () => element.SafeRaiseTunnelingEvent(routedEvent, args));
297+
}
298+
}
299+
else
300+
{
301+
if (raiseSynchronously)
302+
{
303+
element.SafeRaiseEvent(routedEvent, args);
304+
}
305+
else
306+
{
307+
await element.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () => element.SafeRaiseEvent(routedEvent, args));
308+
}
253309
}
254310
}
255311
#endif

0 commit comments

Comments
 (0)