Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Support pressure and tilt on macos #18082

Merged
merged 3 commits into from
Feb 1, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 35 additions & 1 deletion native/Avalonia.Native/src/OSX/AvnView.mm
Original file line number Diff line number Diff line change
Expand Up @@ -290,6 +290,40 @@ - (void)mouseEvent:(NSEvent *)event withType:(AvnRawMouseEventType) type
delta.Y = [event deltaY];
}

float pressure = 0.5f;
float xTilt = 0.0f;
float yTilt = 0.0f;
AvnPointerDeviceType pointerType = AvnPointerDeviceType::Mouse;

switch(event.subtype)
{
case NSEventSubtypeTabletPoint:
switch(event.type)
{
case NSEventTypeLeftMouseDown:
case NSEventTypeLeftMouseDragged:
case NSEventTypeRightMouseDown:
case NSEventTypeRightMouseDragged:
case NSEventTypeOtherMouseDown:
case NSEventTypeOtherMouseDragged:
pressure = event.pressure;
break;
default:
pressure = 0.0f;
break;
}
xTilt = event.tilt.x * 90;
yTilt = -event.tilt.y * 90;
MrJul marked this conversation as resolved.
Show resolved Hide resolved
pointerType = AvnPointerDeviceType::Pen;
break;
case NSEventSubtypeTabletProximity:
pressure = 0.0f;
pointerType = AvnPointerDeviceType::Pen;
break;
default:
break;
}

uint64_t timestamp = static_cast<uint64_t>([event timestamp] * 1000);
auto modifiers = [self getModifiers:[event modifierFlags]];

Expand Down Expand Up @@ -322,7 +356,7 @@ - (void)mouseEvent:(NSEvent *)event withType:(AvnRawMouseEventType) type
auto parent = _parent.tryGet();
if(parent != nullptr)
{
parent->TopLevelEvents->RawMouseEvent(type, timestamp, modifiers, point, delta);
parent->TopLevelEvents->RawMouseEvent(type, pointerType, timestamp, modifiers, point, delta, pressure, xTilt, yTilt);
}

[super mouseMoved:event];
Expand Down
2 changes: 1 addition & 1 deletion native/Avalonia.Native/src/OSX/AvnWindow.mm
Original file line number Diff line number Diff line change
Expand Up @@ -492,7 +492,7 @@ - (void)sendEvent:(NSEvent *_Nonnull)event
auto point = [self translateLocalPoint:avnPoint];
AvnVector delta = { 0, 0 };

parent->BaseEvents->RawMouseEvent(NonClientLeftButtonDown, static_cast<uint64>([event timestamp] * 1000), AvnInputModifiersNone, point, delta);
parent->BaseEvents->RawMouseEvent(NonClientLeftButtonDown, AvnPointerDeviceType::Mouse, static_cast<uint64>([event timestamp] * 1000), AvnInputModifiersNone, point, delta, .5f, .0f, .0f);
}

if(!_isTransitioningToFullScreen)
Expand Down
20 changes: 15 additions & 5 deletions src/Avalonia.Native/TopLevelImpl.cs
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,8 @@ internal class TopLevelImpl : ITopLevelImpl, IFramebufferPlatformSurface
private PlatformBehaviorInhibition? _platformBehaviorInhibition;

private readonly MouseDevice? _mouse;
private readonly PenDevice? _pen;

private readonly IKeyboardDevice? _keyboard;
private readonly ICursorFactory? _cursorFactory;

Expand All @@ -88,6 +90,7 @@ public TopLevelImpl(IAvaloniaNativeFactory factory)

_keyboard = AvaloniaLocator.Current.GetService<IKeyboardDevice>();
_mouse = new MouseDevice();
_pen = new PenDevice();
_cursorFactory = AvaloniaLocator.Current.GetService<ICursorFactory>();
}

Expand Down Expand Up @@ -213,7 +216,7 @@ public bool RawKeyEvent(
return args.Handled;
}

public void RawMouseEvent(AvnRawMouseEventType type, ulong timeStamp, AvnInputModifiers modifiers, AvnPoint point, AvnVector delta)
public void RawMouseEvent(AvnRawMouseEventType type, AvnPointerDeviceType deviceType, ulong timeStamp, AvnInputModifiers modifiers, AvnPoint point, AvnVector delta, float pressure, float xTilt, float yTilt)
{
if (_inputRoot is null)
return;
Expand Down Expand Up @@ -248,8 +251,15 @@ public void RawMouseEvent(AvnRawMouseEventType type, ulong timeStamp, AvnInputMo
break;

default:
var e = new RawPointerEventArgs(_mouse, timeStamp, _inputRoot, (RawPointerEventType)type,
point.ToAvaloniaPoint(), (RawInputModifiers)modifiers);
IInputDevice device = deviceType == AvnPointerDeviceType.Pen && _pen != null ? _pen : _mouse;
var e = new RawPointerEventArgs(device, timeStamp, _inputRoot, (RawPointerEventType)type,
new RawPointerPoint
{
Position = point.ToAvaloniaPoint(),
Pressure = pressure,
XTilt = xTilt,
YTilt = yTilt
}, (RawInputModifiers)modifiers);

if (!ChromeHitTest(e))
{
Expand Down Expand Up @@ -435,9 +445,9 @@ void IAvnTopLevelEvents.Resized(AvnSize* size, AvnPlatformResizeReason reason)
_parent.Resized?.Invoke(s, (WindowResizeReason)reason);
}

void IAvnTopLevelEvents.RawMouseEvent(AvnRawMouseEventType type, ulong timeStamp, AvnInputModifiers modifiers, AvnPoint point, AvnVector delta)
void IAvnTopLevelEvents.RawMouseEvent(AvnRawMouseEventType type, AvnPointerDeviceType pointerDeviceType, ulong timeStamp, AvnInputModifiers modifiers, AvnPoint point, AvnVector delta, float pressure, float xTilt, float yTilt)
{
_parent.RawMouseEvent(type, timeStamp, modifiers, point, delta);
_parent.RawMouseEvent(type, pointerDeviceType, timeStamp, modifiers, point, delta, pressure, xTilt, yTilt);
}

int IAvnTopLevelEvents.RawKeyEvent(AvnRawKeyEventType type, ulong timeStamp, AvnInputModifiers modifiers, AvnKey key, AvnPhysicalKey physicalKey, string keySymbol)
Expand Down
13 changes: 12 additions & 1 deletion src/Avalonia.Native/avn.idl
Original file line number Diff line number Diff line change
Expand Up @@ -667,6 +667,12 @@ enum AvnPlatformThemeVariant
HighContrastDark,
}

enum AvnPointerDeviceType
{
Mouse,
Pen,
}

[uuid(809c652e-7396-11d2-9771-00a0c9b4d50c)]
interface IAvaloniaNativeFactory : IUnknown
{
Expand Down Expand Up @@ -786,10 +792,15 @@ interface IAvnTopLevelEvents : IUnknown
HRESULT Paint();
void Resized([const] AvnSize& size, AvnPlatformResizeReason reason);
void RawMouseEvent(AvnRawMouseEventType type,
AvnPointerDeviceType deviceType,
u_int64_t timeStamp,
AvnInputModifiers modifiers,
AvnPoint point,
AvnVector delta);
AvnVector delta,
float pressure,
float xTilt,
float yTilt
);
bool RawKeyEvent(AvnRawKeyEventType type, u_int64_t timeStamp, AvnInputModifiers modifiers,
AvnKey key, AvnPhysicalKey physicalKey, [const] char* keySymbol);
bool RawTextInputEvent(u_int64_t timeStamp, [const] char* text);
Expand Down