SUMMARY Scrolling through a long form results in accidentally changing form values. Mouse wheel changes values of sliders, list widgets, and numeric fields, even when not focused. STEPS TO REPRODUCE Scroll through a page or form. If any {slider, list widget, numeric field} passes under the mouse pointer, the scroll is interrupted, and the widget's value is changed instead. Example (Qt): - Open KDE System Settings, Screen Edges. - Make window vertically short. - Scroll vertically, moving cursor so that after scrolling, cursor ends up on top of any numeric text field. Example (Gtk+3): - Firefox, Ctrl+P to open Print dialog - Click Advanced tab - Scroll down. OBSERVED RESULT All future scroll operations result in changing form values instead of scrolling through the form. EXPECTED RESULT Scrolling only affects the value of a field/widget, either: a. if field has keyboard focus AND cursor is on top b. never WORKAROUND The only way to reliably *scroll* through a form without *randomly* corrupting form state, is to position the cursor on the scrollbar before using the wheel. Which nearly defeats the purpose of the scroll wheel. https://old.reddit.com/r/kde/comments/9cbema/mouse_wheel_changes_sliders_and_drop_down_menus/ > In e.g. Firefox this is more intelligent: If you just "scroll over" an element, it is not activated/changed. Only if you move your mouse over it by yourself and use the wheel, it triggers. I guess Firefox (or GTK?) checks on mouse over if the last input event was a scroll or a move, and only triggers on move, or if some time has passed. So you can just fly through a page without accidentally activating elements. I love this behavior. >Long story short: Is there a way to change this to the "intelligent' behavior? If not, can I turn off the "change value via mouse wheel" feature for Qt applications completely? SOFTWARE VERSIONS (available in About System) KDE Plasma Version: 5.12.6 KDE Frameworks Version: 5.44.0 Qt Version: 5.9.5 ADDITIONAL INFORMATION
*** Bug 400350 has been marked as a duplicate of this bug. ***
*** Bug 411611 has been marked as a duplicate of this bug. ***
Proposal: disable this behavior for controls that are located inside a scrollview when the content is scrollable, since in this case scrolling to see more content can modify the controls unintentionally. At other times, allow a scroll to modify the controls' values.
*** Bug 418522 has been marked as a duplicate of this bug. ***
Good idea! I think I have a way to fix this that will avoid upsetting the small number of people who would otherwise complain that this broke their workflow: we only allow scrolling on a control to change its value when it's focused. Then you can focus a control to fine-tune its value with a scroll, but unfocused controls will ignore scroll events to avoid the conflict between "view scroll" and "change control values scroll".
Oops, that was for the wrong bug report. Regardless, I'm looking into implementhing nyanpasu64's suggestion. It turned out to be simple for our QtQuick controls; see https://invent.kde.org/frameworks/plasma-framework/-/merge_requests/350 and https://invent.kde.org/frameworks/qqc2-desktop-style/-/merge_requests/99. Looks like it'll be more complicated here, as I don't see any public API to override the scroll behavior. We'll need to either override wheelEvent() for these controls in our QStyle to conditionally do nothing, or else make a Qt change to either do that or add API there that we can use downstream.
(In reply to Nate Graham from comment #6) > Looks like it'll be more complicated here, as I don't see any public API to > override the scroll behavior. We'll need to either override wheelEvent() for > these controls in our QStyle to conditionally do nothing, or else make a Qt > change to either do that or add API there that we can use downstream. Hi, new guy here! After a couple hours of toying with a dummy scrollception app, I think I found a way to circumvent the problem in the classic QWidgets apps that doesn't break the old functionality but prevents accidental inputs from happening. Instead of messing with Breeze, I implemented an app wide event filter that redirects the scroll events to the widget the user would expect to react. So this is what user sees: if the mouse is moved into a scrollable field, it should react by changing its value as normal. HOWEVER if the user keeps the mouse still and simply scrolls over the field, it will not react, but the widget that started scrolling would continue scrolling. This also applies to scroll-areas within scroll-areas: scrolling over one will not affect it, just like in browsers. How it's done: with an event filter installed on QApp. It remembers one widget as the scroll-active one and if the receiver of an event is not scroll-active, the event will be resent to the scroll-active one. This is how it responds to events: QMouseMoveEvent: * Reset scroll-active to 0 when the mouse moves * This ensures that the next scroll event will be propagated to the widget under cursor * On the next scroll event the receiver object should be set as the scroll-active widget QWheelEvent * If the scroll-active widget is not scrollable anymore (for example reached the end), reset scroll-active to 0 * for example, allow scrolling parent scroll-area if the current one reached its end * In case the receiver widget is a non-scrollable widget inside a scrollable area, find the first scrollable parent * Change the scroll-active widget to the receiver (or its parent) only if the scroll-active variable has been reset * i.e. prevent changing the scroll-active variable unless explicitly required * If the receiver isn't the scroll-active widget, redirect the event to the scroll-active one This of course isn't related to Breeze style but to Qt itself, but if we really want to apply this globally the style could perhaps force the event filter on the app it's used on.
Interesting ideas! Feel free to submit a merge request with your idea to https://invent.kde.org/plasma/breeze/-/merge_requests/.
(In reply to Nate Graham from comment #8) > Interesting ideas! Feel free to submit a merge request with your idea to > https://invent.kde.org/plasma/breeze/-/merge_requests/. Thanks! I still have to tweak the system a bit since it has edge cases when you reach the end of page and simultaneously land on a scrollable control, but I have a more elegant solution in mind that would handle those cases too. The event filter is implemented in one header and one cpp file and can be installed by the app developer too, on any platform. Are you sure it would be best to implement it in Breeze? I'm new to KDE development so I wondered if there is at least some lower level KDE library that's used by all Qt apps, independent of system style. It would probably be more flexible to implement it in such place if possible.
(In reply to Mauricius from comment #9) > (In reply to Nate Graham from comment #8) > > Interesting ideas! Feel free to submit a merge request with your idea to > > https://invent.kde.org/plasma/breeze/-/merge_requests/. > > Thanks! I still have to tweak the system a bit since it has edge cases when > you reach the end of page and simultaneously land on a scrollable control, > but I have a more elegant solution in mind that would handle those cases too. > > The event filter is implemented in one header and one cpp file and can be > installed by the app developer too, on any platform. Are you sure it would > be best to implement it in Breeze? I'm new to KDE development so I wondered > if there is at least some lower level KDE library that's used by all Qt > apps, independent of system style. It would probably be more flexible to > implement it in such place if possible. I suppose the Plasma Qt platform theme would be lower level than the QStyle. The repo is https://invent.kde.org/plasma/plasma-integration/
*** Bug 445239 has been marked as a duplicate of this bug. ***
Note for comboboxes it's easy, you can set QStyle::SH_ComboBox_AllowWheelScrolling to false. If we want anything else, we should be looking at patching Qt first not introducing hacks on our side.
What we want here is that scrolling on controls still changes them, but if you scroll the view that a control is on, and that scroll action happens to move the cursor over a scrollable control, the control should ignore it and the view should keep on scrolling. Personally I find this to be a rather fiddly solution, and I think it would be simpler and more predictable to only allow scrolling on controls to change them when the controls are focused. But that would be a functional change for people used to the status quo, and a regression for controls *not* on scrollable views. So it's probably not something we can do.
(In reply to Noah Davis from comment #10) > (In reply to Mauricius from comment #9) > > (In reply to Nate Graham from comment #8) > > > Interesting ideas! Feel free to submit a merge request with your idea to > > > https://invent.kde.org/plasma/breeze/-/merge_requests/. > > > > Thanks! I still have to tweak the system a bit since it has edge cases when > > you reach the end of page and simultaneously land on a scrollable control, > > but I have a more elegant solution in mind that would handle those cases too. > > > > The event filter is implemented in one header and one cpp file and can be > > installed by the app developer too, on any platform. Are you sure it would > > be best to implement it in Breeze? I'm new to KDE development so I wondered > > if there is at least some lower level KDE library that's used by all Qt > > apps, independent of system style. It would probably be more flexible to > > implement it in such place if possible. > > I suppose the Plasma Qt platform theme would be lower level than the QStyle. > The repo is https://invent.kde.org/plasma/plasma-integration/ Hi, I haven't updated anything regarding this bug in a long time, but I found some free time and after struggling with debugging the KDEPlasmaPlatformTheme library I confirmed that the method works. I don't know if this hack is the best way of solving this and whether there has been some work on the Qt side, but for now this simple patch seems to improve usability system-wide. I don't know what's the best way to test the code thoroughly except by replacing the library on runtime, which often crashes the DE (since I'm a n00b it seems), so some more testing might be required. I submitted a merge request https://invent.kde.org/plasma/plasma-integration/-/merge_requests/44 Btw, should I take the assignee position for the issue? I haven't seen any more work being done on this by others
In progress with https://invent.kde.org/plasma/plasma-integration/-/merge_requests/44!
> Btw, should I take the assignee position for the issue? I haven't seen any more work being done on this by others Don't worry about it. :)
(In reply to Nate Graham from comment #15) > In progress with > https://invent.kde.org/plasma/plasma-integration/-/merge_requests/44! Based on the discussion in the MR, the consensus is to do this in Qt. So should we mark this as RESOLVED-UPSTREAM?
I'd prefer to do that only there's actually a bug report upstream, so we know they're aware it's something we'd like to change.
Does a bug report exist on QT's side? Can't seem to find anything. Thanks.
*** Bug 484981 has been marked as a duplicate of this bug. ***