godot icon indicating copy to clipboard operation
godot copied to clipboard

ScrollContainer scroll_started and scroll_ended signals aren't emitted

Open Maxpilot opened this issue 6 years ago • 19 comments

Bug?

Godot version: 3.0.6 stable

OS/device including version: Windows 7 pro / Linux Mint 19

Issue description: Signals "scroll_started()" and "scroll_ended()" never fired

Steps to reproduce: Create Scene with ScrollContainer Create Panel inside ScrollContainer (min_size > ScrollContainer) Link Signals (printing out to console) -> When scrolling with mouse or touch signals are never received

Maxpilot avatar Oct 11 '18 14:10 Maxpilot

_gui_input is not called when using the scrollbars. And even if it got called drag_touching = OS::get_singleton()->has_touchscreen_ui_hint(); will always be false, if there is no touch emulation, so scroll startet is never emited.

Is drag_touching in the if clause in line 169 of scroll_container.cpp really neccessary? ( if (drag_touching && !drag_touching_deaccel) { )

bugfi5h avatar Oct 11 '18 17:10 bugfi5h

It's seems that the problem become worse in Godot 3.1 alpha 5 , i can't emulate scrolling even if emulate touch screen option is enabled from Project configuration.

B4DNetwork avatar Jan 05 '19 20:01 B4DNetwork

Just commenting to add that mouse_entered and mouse_exited signals aren't triggering either. I think it's safe to assume that none of the scrollcontainer signals work.

Tested with 3.1 btw.

edit: had a node in front of it that was set to Show Behind Parent, setting it's mouse filter appropriately fixed it, doh.

Megalomaniak avatar Oct 06 '19 10:10 Megalomaniak

Does not work on 3.2 mac. There is no work around for this issue

Koyper avatar Mar 04 '20 15:03 Koyper

I can confirm the same on Mac OSX Mojave 10.14.6 (18G95) - ScrollContainer events are not firing.

I was able to get_vscrollbar() and connect to scrolling signal, but scrollcontainer events do not seem to work at all. Mouse, focus, etc. I am using Godot_mono but working with GDScript.

sporeservant avatar Mar 26 '20 01:03 sporeservant

Here is what I am doing to workaround this problem - create a timer that will clear after half a second, and then if you're still scrolling reset that timer.

extends ScrollContainer

var timer: SceneTreeTimer = null

func _ready():
	get_v_scrollbar().connect('scrolling', self, 'on_scroll')

func on_scroll():
	if !timer:
		timer = get_tree().create_timer(.5)
		timer.connect("timeout", self, "clear_scrollbar_dragging")

func clear_scrollbar_dragging():
	timer = null

sporeservant avatar Mar 26 '20 01:03 sporeservant

I am also experiencing this problem (Windows 10 Pro v1903). I'm looking to update the position of a sprite when the user stops scrolling. Is there a solution that would be more smooth especially if one is scrolling fast?

2GoodPhoU avatar Apr 04 '20 04:04 2GoodPhoU

I hope, this will be fixed soon! I have the same problem.

MaaaxiKing avatar May 09 '20 17:05 MaaaxiKing

Also experiencing this issue. Please fix, there is no clean workaround.

burtfuckman avatar Oct 27 '20 00:10 burtfuckman

It looks like I'm still experiencing this issue with Godot 3.2.3 when testing on a PC.

But once I run on my mobile phone (which is my target device), the events fire as expected.

It's a bit disconcerting to not have it work on PC, so I still hope that a PR for this can be merged soon.

pndalal avatar Feb 26 '21 18:02 pndalal

See also https://github.com/godotengine/godot/issues/46421.

Calinou avatar Feb 26 '21 19:02 Calinou

Workaround I just found: connect to "value_changed" (Scrollbar inherits from Range) instead.

Zireael07 avatar Jul 16 '21 08:07 Zireael07

I can reproduce the issue on Godot 3.4.2-stable under macOS Big Sur (11.16.2). Neither signal works.

hiulit avatar Jan 20 '22 16:01 hiulit

This issue is reproducible in Godot 3.5.2 and Godot 4.0. In addition to that in 4.0 changed signal is not raised. Also, if there is some help around dead zone functionality it will help. P.S: If MRP for 4.0 and 3.5.2 is required I can upload it.

the-token-studios avatar Mar 10 '23 12:03 the-token-studios

Just to update on the issue further. The signals are emitted in android devices, at-least in emulators I have tested. It seems the dead zone has to do something with this as per code. Need to understand more of this dead zone functionality. Note: It still does not work in desktop dev environment

the-token-studios avatar Mar 10 '23 13:03 the-token-studios

Godot 4.2, issue persists to this day. Thankfully, I don't actually need this functionality, but someone else might.

Dorijan-Cirkveni avatar Apr 10 '24 16:04 Dorijan-Cirkveni

Trying to nail down what desired behaviour is.

Clicking and dragging the scroll bar handle seems straighforward: a scroll_started when the mouse button goes down on the handle (or first movement after mouse button down) and scroll_ended when the mouse button is released (even if there are moments when the mouse movement pauses).

More complex are the mouse wheel interactions. Godot sees them as individual events, so there's no real "start" or "end" to them. Even if you spin the mouse wheel, Godot just sees them as a series of events.

So I guess in this situation we use a timer, like what @sporeservant used for their own project? Each time the scroll bar moves, a scroll_started event is triggered and a timer starts. Each scroll bar movement from then on resets the time, and if the timer runs out, a scroll_ended event is fired? It could even work for dragging the scroll handle.

Is this the preferred solution? And if so, what should the timeout value of the timer be?

TheSofox avatar May 01 '24 14:05 TheSofox

You can get a reliable scroll started signal that emits at the right time by connecting item_rect_changed on the child control of the ScrollContainer with a CONNECT_DEFERRED flag. This seems to be the only way to avoid delayed or late scroll started signals. This approach is also agnostic to how the scroll is initiated.

To get a scroll ended signal, you can create a "debounce" timer that's started on the item_rect_changed signal, and after some timeout, emits a custom scroll ended signal.

Koyper avatar May 01 '24 15:05 Koyper

So this will mean the signals will be triggered regardless of how the scroll is initiated, including programmatically. It would also replace the current system for inertia scrolling. Is this the desired behaviour?

TheSofox avatar May 01 '24 16:05 TheSofox