Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.

Send scroll events from the macOS shell #8056

Merged
merged 2 commits into from
Mar 6, 2019
Merged
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
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,14 @@ @interface FLEViewController ()
*/
@property(nonatomic) NSTrackingArea* trackingArea;

/**
* Whether or not a kAdd event has been sent for the mouse (or sent again since
* the last kRemove was sent if tracking is enabled). Used to determine whether
* to send an Add event before sending an incoming mouse event, since Flutter
* expects a pointers to be added before events are sent for them.
*/
@property(nonatomic) BOOL mouseCurrentlyAdded;

/**
* Updates |trackingArea| for the current tracking settings, creating it with
* the correct mode if tracking is enabled, or removing it if not.
Expand Down Expand Up @@ -416,16 +424,54 @@ - (void)handlePlatformMessage:(const FlutterPlatformMessage*)message {
}

- (void)dispatchMouseEvent:(NSEvent*)event phase:(FlutterPointerPhase)phase {
// If a pointer added event hasn't been sent, synthesize one using this event for the basic
// information.
if (!_mouseCurrentlyAdded && phase != kAdd) {
// Only the values extracted for use in flutterEvent below matter, the rest are dummy values.
NSEvent* addEvent = [NSEvent enterExitEventWithType:NSEventTypeMouseEntered
location:event.locationInWindow
modifierFlags:0
timestamp:event.timestamp
windowNumber:event.windowNumber
context:nil
eventNumber:0
trackingNumber:0
userData:NULL];
[self dispatchMouseEvent:addEvent phase:kAdd];
}

NSPoint locationInView = [self.view convertPoint:event.locationInWindow fromView:nil];
NSPoint locationInBackingCoordinates = [self.view convertPointToBacking:locationInView];
const FlutterPointerEvent flutterEvent = {
FlutterPointerEvent flutterEvent = {
.struct_size = sizeof(flutterEvent),
.phase = phase,
.x = locationInBackingCoordinates.x,
.y = -locationInBackingCoordinates.y, // convertPointToBacking makes this negative.
.timestamp = static_cast<size_t>(event.timestamp * NSEC_PER_MSEC),
};

if (event.type == NSEventTypeScrollWheel) {
flutterEvent.signal_kind = kFlutterPointerSignalKindScroll;

double pixelsPerLine = 1.0;
if (!event.hasPreciseScrollingDeltas) {
CGEventSourceRef source = CGEventCreateSourceFromEvent(event.CGEvent);
pixelsPerLine = CGEventSourceGetPixelsPerLine(source);
if (source) {
CFRelease(source);
}
}
double scaleFactor = self.view.layer.contentsScale;
flutterEvent.scroll_delta_x = event.scrollingDeltaX * pixelsPerLine * scaleFactor;
flutterEvent.scroll_delta_y = -event.scrollingDeltaY * pixelsPerLine * scaleFactor;
}
FlutterEngineSendPointerEvent(_engine, &flutterEvent, 1);

if (phase == kAdd) {
_mouseCurrentlyAdded = YES;
} else if (phase == kRemove) {
_mouseCurrentlyAdded = NO;
}
}

- (void)dispatchKeyEvent:(NSEvent*)event ofType:(NSString*)type {
Expand Down Expand Up @@ -539,4 +585,10 @@ - (void)mouseMoved:(NSEvent*)event {
[self dispatchMouseEvent:event phase:kHover];
}

- (void)scrollWheel:(NSEvent*)event {
// TODO: Add gesture-based (trackpad) scroll support once it's supported by the engine rather
// than always using kHover.
[self dispatchMouseEvent:event phase:kHover];
}

@end