You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
What OS were you testing? Unless I'm misremembering, macOS at least automatically translates this to horizontal scroll events at the OS framework level, so it should work there. I'm not sure how much Linux and Windows do for us.
That's odd; macOS should definitely be sending the view horizontal scroll events.
Were you testing with a mouse or a trackpad?
Just checked against another mouse, I am guessing the magic mouse is considered a trackpad. Using a stepped wheel mouse it does work. Updated comment above.
Given that the behavior varies by OS, I would actually recommend implementing this in the embeddings rather than the framework.
What if someone wants shift-mousewheel to do something else? Implementing it in the framework seems consistent with our usual approach of making everything configurable.
I agree, I much preferred doing this in the framework to allow customization, but since we don't control the input from Mac (it appears to flip axes itself when shift is applied before it reaches Flutter), do we add complexity to the framework by re-flipping the signal, or assume the signal from the engine is wrong, or right based on which platform we are on? Or change it in the engine back to the original axis before sending it to the framework?
I can see it causing a lot of confusion if it is not consistent across platforms, after all, it already is. 😂
It would still be very easy to do this in the framework (read: here is a proposal PR I just whipped up #115610) - but adding a workaround for Mac already handling it felt like code smell.
I'd love to fix this finally if we can agree on an approach one way or the other. I think the lack of a clear solution is why this has not been resolved yet. However, many of the concerns above are no longer an issue because trackpad has its own, separate handling now, which is how we ended up circling back to it.
I would very much like to get support for horizontal scrolling on Linux and Windows into the next stable release. It really seems embarrassing that we don't have support for horizontal scrolling. So whatever we do, we should at least implement a first pass at it quickly.
Or change it in the engine back to the original axis before sending it to the framework?
I dislike that macOS is determining our implementation choice here. As Kate suggests, we could flip the direction back on macOS before we send it if shift is down. Then the values coming from the embedder could be consistent across platforms, and we could check in the framework for the shift being down. It might be more complicated than that, though, since we'd also probably have to account for "natural" scroll direction settings being different for horizontal and vertical and flip the sign too in the appropriate cases.
Is shift-scroll a standard pattern across all OSes? If so, (and I think that's the case currently?) then agreed it'd be nice for this to happen in the framework. We do other event normalisation type tasks in the embedders; there's probably no reason we couldn't do the same for macOS to undo its auto-horizontalisation in the embedder before sending the events to the framework.
We receive scroll events via NSScrollWheelEvents via -[NSView scrollWheel]. These are logical scroll events, not raw hardware events, so as discussed earlier here, if someone holds down shift and scrolls the scroll wheel on a standard mouse, what we get is horizontal scroll deltas. If they've enabled the system setting for reverse scroll, that's already been applied as well.
If we want to do everything in the framework instead, we'd either need to:
find another API that gives us untranslated events (if there is such a thing), or
attempt to reverse-engineer the behavior and reverse it (if we have enough information)
If we want to do the latter, we would need to be very careful to test a variety of edge cases. E.g., what if someone has a device like a Mighty Mouse that actually has physical horizontal scrolling, holds down shift, and scrolls the ball/wheel horizontally?
We'd also need to make sure that we're either continuing to honor system settings like reverse direction at the embedder level ourselves, or plumbing those into the framework to honor in the framework.
If the system is sending us logical "scroll delta" events, are those distinguishable from hardware "mousewheel + shift" events? I think it would be fine to honour logical events from the system on systems that give those to us, while honoring hardware events on those that do not. The idea is to do the best we can on each platform.
The scroll event system I added when bringing up scroll support initially on desktop doesn't distinguish, but we could potentially add more metadata to the scroll events at the embedder.h level and have each embedding tag the events accordingly.
Right to be clear I mean does the OS distinguish. The embedder itself should as much as possible just pass through the OS data as completely as possible while coercing it into our protocol (so e.g. making sure down events are matched by up events and so on). This may indeed mean adding additional metadata to our events to be able to distinguish the kind of event we get from one platform from those we get on another.
It would be nice if it did add some of the metadata: while working on the Time Picker, I realized that I can "scroll" the dial on the time picker, because a two-finger scroll is considered a drag, just with two fingers: the scroll gesture just adds to the delta, making for a weird interaction. If I knew whether it was part of a scroll or not, I could filter those drags out.
Right now we have no mechanism in the macOS embedding to receive anything other than preprocessed logical be deltas, so there's nothing to distinguish between.
As mentioned above I don't know offhand if there are other (e.g., CG-level) APIs for anything else.
that sounds about par for the course on mac. But in general that's not unusual. We have this situation with the keyboard APIs too, where each platform does some preprocessing before the embedder does it, and the embedders do their best to provide a coherent unopinionated view of the keyboard so that the framework can then do the best thing on each platform. When you have the precise platform-specific semantic, you pass that through; when you don't, you pass in the ground truth, and the framework implements the semantic directly if available and otherwise does the platform-specific thing with the ground truth.
This thread has been automatically locked since there has not been any recent activity after it was closed. If you are still experiencing a similar issue, please open a new bug, including the output of flutter doctor -v and a minimal reproduction of the issue.
Activity
stuartmorgan-g commentedon Feb 2, 2021
What OS were you testing? Unless I'm misremembering, macOS at least automatically translates this to horizontal scroll events at the OS framework level, so it should work there. I'm not sure how much Linux and Windows do for us.
Hixie commentedon Feb 2, 2021
I tested on Linux and Web.
HansMuller commentedon Feb 2, 2021
CC @Piinks
Piinks commentedon Feb 2, 2021
I think this will be easy to support, we should check the keyboard state here and adjust accordingly:
flutter/packages/flutter/lib/src/widgets/scrollable.dart
Line 639 in 2dfc86e
cc @dkwingsmt who has a really big keyboard revamp underway. :)
stuartmorgan-g commentedon Feb 2, 2021
Given that the behavior varies by OS, I would actually recommend implementing this in the embeddings rather than the framework.
Piinks commentedon Feb 2, 2021
Makes sense. :)
Tested on MacOS, it does not appear to be supported on that platform either.
Update: Magic mouse - no, stepped scroll wheel - yes
stuartmorgan-g commentedon Feb 2, 2021
That's odd; macOS should definitely be sending the view horizontal scroll events.
Were you testing with a mouse or a trackpad?
Piinks commentedon Feb 2, 2021
Just checked against another mouse, I am guessing the magic mouse is considered a trackpad. Using a stepped wheel mouse it does work. Updated comment above.
Hixie commentedon Feb 2, 2021
What if someone wants shift-mousewheel to do something else? Implementing it in the framework seems consistent with our usual approach of making everything configurable.
29 remaining items
Piinks commentedon Nov 18, 2022
I agree, I much preferred doing this in the framework to allow customization, but since we don't control the input from Mac (it appears to flip axes itself when shift is applied before it reaches Flutter), do we add complexity to the framework by re-flipping the signal, or assume the signal from the engine is wrong, or right based on which platform we are on? Or change it in the engine back to the original axis before sending it to the framework?
I can see it causing a lot of confusion if it is not consistent across platforms, after all, it already is. 😂
It would still be very easy to do this in the framework (read: here is a proposal PR I just whipped up #115610) - but adding a workaround for Mac already handling it felt like code smell.
I'd love to fix this finally if we can agree on an approach one way or the other. I think the lack of a clear solution is why this has not been resolved yet. However, many of the concerns above are no longer an issue because trackpad has its own, separate handling now, which is how we ended up circling back to it.
gspencergoog commentedon Nov 18, 2022
I would very much like to get support for horizontal scrolling on Linux and Windows into the next stable release. It really seems embarrassing that we don't have support for horizontal scrolling. So whatever we do, we should at least implement a first pass at it quickly.
I dislike that macOS is determining our implementation choice here. As Kate suggests, we could flip the direction back on macOS before we send it if shift is down. Then the values coming from the embedder could be consistent across platforms, and we could check in the framework for the shift being down. It might be more complicated than that, though, since we'd also probably have to account for "natural" scroll direction settings being different for horizontal and vertical and flip the sign too in the appropriate cases.
cbracken commentedon Nov 18, 2022
Is shift-scroll a standard pattern across all OSes? If so, (and I think that's the case currently?) then agreed it'd be nice for this to happen in the framework. We do other event normalisation type tasks in the embedders; there's probably no reason we couldn't do the same for macOS to undo its auto-horizontalisation in the embedder before sending the events to the framework.
Hixie commentedon Nov 18, 2022
Is there anywhere I can read more about what macOS is doing? What exactly is being translated, by whom, from what to what?
Piinks commentedon Nov 18, 2022
I do not know a whole lot about it, but this is what I found in the engine as far as how the scrolling input is bubbled up on Mac: https://github.com/flutter/engine/blob/aeb2cd95b19dfab26bc4ab21137c62783e523d69/shell/platform/darwin/macos/framework/Source/FlutterViewController.mm#L646
We aren't checking in the engine if the shift key is down, so the incoming input has already been flipped from dy to dx.
stuartmorgan-g commentedon Nov 18, 2022
We receive scroll events via
NSScrollWheelEvents via-[NSView scrollWheel]. These are logical scroll events, not raw hardware events, so as discussed earlier here, if someone holds down shift and scrolls the scroll wheel on a standard mouse, what we get is horizontal scroll deltas. If they've enabled the system setting for reverse scroll, that's already been applied as well.If we want to do everything in the framework instead, we'd either need to:
If we want to do the latter, we would need to be very careful to test a variety of edge cases. E.g., what if someone has a device like a Mighty Mouse that actually has physical horizontal scrolling, holds down shift, and scrolls the ball/wheel horizontally?
We'd also need to make sure that we're either continuing to honor system settings like reverse direction at the embedder level ourselves, or plumbing those into the framework to honor in the framework.
Hixie commentedon Nov 18, 2022
If the system is sending us logical "scroll delta" events, are those distinguishable from hardware "mousewheel + shift" events? I think it would be fine to honour logical events from the system on systems that give those to us, while honoring hardware events on those that do not. The idea is to do the best we can on each platform.
stuartmorgan-g commentedon Nov 18, 2022
The scroll event system I added when bringing up scroll support initially on desktop doesn't distinguish, but we could potentially add more metadata to the scroll events at the embedder.h level and have each embedding tag the events accordingly.
Hixie commentedon Nov 18, 2022
Right to be clear I mean does the OS distinguish. The embedder itself should as much as possible just pass through the OS data as completely as possible while coercing it into our protocol (so e.g. making sure down events are matched by up events and so on). This may indeed mean adding additional metadata to our events to be able to distinguish the kind of event we get from one platform from those we get on another.
gspencergoog commentedon Nov 18, 2022
It would be nice if it did add some of the metadata: while working on the Time Picker, I realized that I can "scroll" the dial on the time picker, because a two-finger scroll is considered a drag, just with two fingers: the scroll gesture just adds to the delta, making for a weird interaction. If I knew whether it was part of a scroll or not, I could filter those drags out.
stuartmorgan-g commentedon Nov 18, 2022
Right now we have no mechanism in the macOS embedding to receive anything other than preprocessed logical be deltas, so there's nothing to distinguish between.
As mentioned above I don't know offhand if there are other (e.g., CG-level) APIs for anything else.
Hixie commentedon Nov 20, 2022
that sounds about par for the course on mac. But in general that's not unusual. We have this situation with the keyboard APIs too, where each platform does some preprocessing before the embedder does it, and the embedders do their best to provide a coherent unopinionated view of the keyboard so that the framework can then do the best thing on each platform. When you have the precise platform-specific semantic, you pass that through; when you don't, you pass in the ground truth, and the framework implements the semantic directly if available and otherwise does the platform-specific thing with the ground truth.
github-actions commentedon Mar 3, 2023
This thread has been automatically locked since there has not been any recent activity after it was closed. If you are still experiencing a similar issue, please open a new bug, including the output of
flutter doctor -vand a minimal reproduction of the issue.