Mobile Basic tap, swipe, and long-press detection does not happen

Godot Version

4.4

Question

I can’t use basic tap, vertical swipe, and long-press in my phone. I’m struggling here trying to implement these features in the app. I don’t know if it is that I have to code for every textEdit to function well. Can someone explain or at least tell me where I can seek information? I searched the documents and couldn’t understand, and asked AI help but it’s not working, it is still the same.

Hi, you can use TouchScreenButton for mobile buttons, and maybe also buttons? And AI isn’t really useful when it comes to coding… but if it actually helps you then, great!

Hello. The problem is not buttons, it is the basic mobile features like scrolling with finger.

1 Like

This is my touch_handler.gd:

res://touch_handler.gd

extends Node

signal tap_detected(position: Vector2)
signal scroll_detected(delta: Vector2)
signal long_press_detected(position: Vector2)

const LONG_PRESS_THRESHOLD := 0.5
const TAP_THRESHOLD := 0.2
const SCROLL_THRESHOLD := 10.0

var touch_start_time := 0.0
var touch_start_position := Vector2.ZERO
var is_touching := false
var long_press_timer := 0.0
var has_moved := false
var current_scroll_container: ScrollContainer = null

func _ready() -> void:
	# Auto-configure for mobile
	Input.set_use_accumulated_input(false)
	_find_scroll_container()
	_connect_text_edits()

func _input(event: InputEvent) -> void:
	if event is InputEventScreenTouch:
		_handle_screen_touch(event)
	elif event is InputEventScreenDrag:
		_handle_screen_drag(event)

func _process(delta: float) -> void:
	if is_touching:
		long_press_timer += delta
		if long_press_timer >= LONG_PRESS_THRESHOLD and not has_moved:
			_handle_long_press()
			_reset_touch_state()

func _handle_screen_touch(event: InputEventScreenTouch) -> void:
	if event.pressed:
		_start_touch(event.position)
	else:
		_end_touch(event.position)

func _handle_screen_drag(event: InputEventScreenDrag) -> void:
	if is_touching and current_scroll_container:
		var distance = (event.position - touch_start_position).length()
		if distance > SCROLL_THRESHOLD:
			has_moved = true
			current_scroll_container.scroll_vertical += event.relative.y
			touch_start_position = event.position

func _start_touch(position: Vector2) -> void:
	is_touching = true
	touch_start_time = Time.get_ticks_msec() / 1000.0
	touch_start_position = position
	_find_scroll_container()

func _end_touch(position: Vector2) -> void:
	if is_touching:
		var touch_duration = (Time.get_ticks_msec() / 1000.0) - touch_start_time
		if touch_duration <= TAP_THRESHOLD and not has_moved:
			_handle_tap(position)
		_reset_touch_state()

func _handle_tap(position: Vector2) -> void:
	var text_edit = _get_text_edit_at_position(position)
	if text_edit:
		_focus_text_edit(text_edit)
	else:
		tap_detected.emit(position)
	emit_signal("tap_detected", position)  # Fixed signal emission

func _handle_long_press() -> void:
	var text_edit = _get_text_edit_at_position(touch_start_position)
	if text_edit:
		_show_context_menu(text_edit)
	long_press_detected.emit(touch_start_position)
	emit_signal("long_press_detected", touch_start_position)  # Fixed signal emission

func _focus_text_edit(text_edit: Control) -> void:
	text_edit.grab_focus()
	_adjust_scroll_for_keyboard(text_edit)

func _adjust_scroll_for_keyboard(text_edit: Control) -> void:
	if current_scroll_container:
		var visible_rect = current_scroll_container.get_global_rect()
		var target_y = text_edit.global_position.y - visible_rect.size.y * 0.3
		current_scroll_container.scroll_vertical = target_y

func _find_scroll_container() -> void:
	if not current_scroll_container:
		current_scroll_container = get_tree().get_first_node_in_group("main_scroll")

func _connect_text_edits() -> void:
	for text_edit in get_tree().get_nodes_in_group("text_edits"):
		text_edit.focus_entered.connect(_adjust_scroll_for_keyboard.bind(text_edit))

func _get_text_edit_at_position(pos: Vector2) -> Control:
	for text_edit in get_tree().get_nodes_in_group("text_edits"):
		if text_edit.get_global_rect().has_point(pos):
			return text_edit
	return null

func _show_context_menu(text_edit: Control) -> void:
	var menu = preload("res://context_menu.tscn").instantiate()
	menu.position = text_edit.global_position + Vector2(0, -50)
	menu.setup(text_edit)
	get_tree().current_scene.add_child(menu)

func _reset_touch_state() -> void:
	is_touching = false
	has_moved = false
	long_press_timer = 0.0
1 Like

I add it on autoload. I made some changes and touch works now, but it looks like “enable touch from Mouse” pointing.

1 Like

Hi, maybe this could help?

It explains how to add sliding in godot 4, it’s fast and simple

1 Like

I saw it but it doesn’t tell how to make it work in mobile.

1 Like

Maybe this then? You’ll have to figure out how to do this in godot 4 though, but there’s a comment that tells you how so yeah here: