This repository was archived by the owner on Feb 25, 2025. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 6k
i82973 scroll mouse wheel support #44724
Merged
auto-submit
merged 29 commits into
flutter:main
from
reidbaker:i82973-scroll-mouse-wheel-support
Aug 22, 2023
Merged
Changes from 9 commits
Commits
Show all changes
29 commits
Select commit
Hold shift + click to select a range
4fc9130
Pair progress
Piinks 17faa0d
Working mouse scroll wheel, note flutter takes longer to "see" a mous…
reidbaker 95f5aa0
refactor packet method to have an override when context is null
reidbaker 2b9686c
Add unit test for scroll wheel
reidbaker 43619cc
Add unit test for scroll wheel
reidbaker aa01e98
Add unit test for scroll wheel
reidbaker 05420ee
make pointer logic easier to read
reidbaker e14b961
revert unrelated file
reidbaker 9efded6
Merge branch 'main' into i82973-scroll-mouse-wheel-support
reidbaker 2ea445d
Fix merge, add timestamp test, code does not compile
reidbaker 5140201
Merge branch 'main' into i82973-scroll-mouse-wheel-support
reidbaker e76fec0
Make tests compile
reidbaker 22e8a77
Make tests pass
reidbaker e7dfa9d
add device test
reidbaker 53ac277
Add tests for pressure, obscured and synth
reidbaker 02e1176
Add tests for pressure min and max
reidbaker 2c823c7
Add test for stylus distance
reidbaker c2f3c56
Add test for stylus distance
reidbaker 168164f
Add tests for size and radius
reidbaker 06cda9a
Add tests for pan deltax and rotation and scale
reidbaker bb157fb
formatting
reidbaker 01e8ebb
Add test for buttons, specifically stylus
reidbaker 8f3aa72
formatting
reidbaker 4df1fee
Merge branch 'main' into i82973-scroll-mouse-wheel-support
reidbaker eb4dbb0
extract mock event values into function
reidbaker 33be4af
formatting
reidbaker 2cd1f46
Tests for pre 26 scroll behavior
reidbaker 3848a28
Merge branch 'main' into i82973-scroll-mouse-wheel-support
reidbaker ae7439f
Update shell/platform/android/io/flutter/embedding/android/AndroidTou…
Piinks File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -8,8 +8,11 @@ | |
| import static org.mockito.Mockito.when; | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. These tests! 🤌 Thanks for shaving this down and adding all this coverage. |
||
|
|
||
| import android.annotation.TargetApi; | ||
| import android.content.Context; | ||
| import android.view.InputDevice; | ||
| import android.view.MotionEvent; | ||
| import android.view.ViewConfiguration; | ||
| import androidx.test.core.app.ApplicationProvider; | ||
| import androidx.test.ext.junit.runners.AndroidJUnit4; | ||
| import io.flutter.embedding.engine.renderer.FlutterRenderer; | ||
| import java.nio.ByteBuffer; | ||
|
|
@@ -58,6 +61,14 @@ private double readPointerPhysicalY(ByteBuffer buffer) { | |
| return buffer.getDouble(8 * AndroidTouchProcessor.BYTES_PER_FIELD); | ||
| } | ||
|
|
||
| private double readScrollDeltaX(ByteBuffer buffer) { | ||
| return buffer.getDouble(27 * AndroidTouchProcessor.BYTES_PER_FIELD); | ||
| } | ||
|
|
||
| private double readScrollDeltaY(ByteBuffer buffer) { | ||
| return buffer.getDouble(28 * AndroidTouchProcessor.BYTES_PER_FIELD); | ||
| } | ||
|
|
||
| private double readPointerPanX(ByteBuffer buffer) { | ||
| return buffer.getDouble(29 * AndroidTouchProcessor.BYTES_PER_FIELD); | ||
| } | ||
|
|
@@ -66,6 +77,11 @@ private double readPointerPanY(ByteBuffer buffer) { | |
| return buffer.getDouble(30 * AndroidTouchProcessor.BYTES_PER_FIELD); | ||
| } | ||
|
|
||
| /// Utility method when trying to write a new test. Prefer named readPointerXXX. | ||
| private double readOffset(int offset, ByteBuffer buffer) { | ||
| return buffer.getDouble(offset * AndroidTouchProcessor.BYTES_PER_FIELD); | ||
| } | ||
|
|
||
| private class MotionEventMocker { | ||
| int pointerId; | ||
| int source; | ||
|
|
@@ -81,6 +97,15 @@ MotionEvent mockEvent(int action, float x, float y, int buttonState) { | |
| MotionEvent event = mock(MotionEvent.class); | ||
| when(event.getDevice()).thenReturn(null); | ||
| when(event.getSource()).thenReturn(source); | ||
| // Ensure that isFromSource does not auto default to false when source is passed in. | ||
| when(event.isFromSource(InputDevice.SOURCE_CLASS_POINTER)) | ||
| .thenReturn(source == InputDevice.SOURCE_CLASS_POINTER); | ||
| when(event.isFromSource(InputDevice.SOURCE_MOUSE)) | ||
| .thenReturn(source == InputDevice.SOURCE_MOUSE); | ||
| when(event.isFromSource(InputDevice.SOURCE_STYLUS)) | ||
| .thenReturn(source == InputDevice.SOURCE_STYLUS); | ||
| when(event.isFromSource(InputDevice.SOURCE_TOUCHSCREEN)) | ||
| .thenReturn(source == InputDevice.SOURCE_TOUCHSCREEN); | ||
| when(event.getPointerCount()).thenReturn(1); | ||
| when(event.getActionMasked()).thenReturn(action); | ||
| when(event.getActionIndex()).thenReturn(0); | ||
|
|
@@ -89,7 +114,8 @@ MotionEvent mockEvent(int action, float x, float y, int buttonState) { | |
| when(event.getX(0)).thenReturn(x); | ||
| when(event.getY(0)).thenReturn(y); | ||
| when(event.getToolType(0)).thenReturn(toolType); | ||
| when(event.isFromSource(InputDevice.SOURCE_CLASS_POINTER)).thenReturn(true); | ||
| when(event.getAxisValue(MotionEvent.AXIS_HSCROLL, pointerId)).thenReturn(x); | ||
| when(event.getAxisValue(MotionEvent.AXIS_VSCROLL, pointerId)).thenReturn(y); | ||
| return event; | ||
| } | ||
| } | ||
|
|
@@ -220,10 +246,45 @@ public void unexpectedMaskedAction() { | |
| verify(mockRenderer, never()).dispatchPointerDataPacket(ByteBuffer.allocate(0), 0); | ||
| } | ||
|
|
||
| @Test | ||
| public void scrollWheel() { | ||
| // Pointer id must be zero to match actionIndex in mocked event. | ||
| final int pointerId = 0; | ||
| MotionEventMocker mocker = | ||
| new MotionEventMocker( | ||
| pointerId, InputDevice.SOURCE_CLASS_POINTER, MotionEvent.TOOL_TYPE_MOUSE); | ||
| final float horizontalScrollValue = -1f; | ||
| final float verticalScrollValue = .5f; | ||
| final Context context = ApplicationProvider.getApplicationContext(); | ||
| final double horizontalScaleFactor = | ||
| ViewConfiguration.get(context).getScaledHorizontalScrollFactor(); | ||
| final double verticalScaleFactor = | ||
| ViewConfiguration.get(context).getScaledVerticalScrollFactor(); | ||
| // Zero verticalScaleFactor will cause this test to miss bugs. | ||
| assertEquals("zero horizontal scale factor", true, horizontalScaleFactor != 0); | ||
| assertEquals("zero vertical scale factor", true, verticalScaleFactor != 0); | ||
|
|
||
| final MotionEvent event = | ||
| mocker.mockEvent(MotionEvent.ACTION_SCROLL, horizontalScrollValue, verticalScrollValue, 1); | ||
| boolean handled = touchProcessor.onGenericMotionEvent(event, context); | ||
|
|
||
| InOrder inOrder = inOrder(mockRenderer); | ||
| inOrder | ||
| .verify(mockRenderer) | ||
| .dispatchPointerDataPacket(packetCaptor.capture(), packetSizeCaptor.capture()); | ||
| ByteBuffer packet = packetCaptor.getValue(); | ||
|
|
||
| assertEquals(-horizontalScrollValue * horizontalScaleFactor, readScrollDeltaX(packet)); | ||
| assertEquals(-verticalScrollValue * verticalScaleFactor, readScrollDeltaY(packet)); | ||
| verify(event).getAxisValue(MotionEvent.AXIS_HSCROLL, pointerId); | ||
| verify(event).getAxisValue(MotionEvent.AXIS_VSCROLL, pointerId); | ||
|
|
||
| inOrder.verifyNoMoreInteractions(); | ||
| } | ||
|
|
||
| @Test | ||
| public void unexpectedPointerChange() { | ||
| // Regression test for https://github.com/flutter/flutter/issues/129765 | ||
|
|
||
| MotionEventMocker mocker = | ||
| new MotionEventMocker(0, InputDevice.SOURCE_MOUSE, MotionEvent.TOOL_TYPE_MOUSE); | ||
|
|
||
|
|
||
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The change below was made for readability since @camsim99 and I both thought the implementation was confusing. It should be functionally identical and easier to follow. If a reviewer disagree please comment here and let me know.