Logic to keep control node within the borders of its parent control node

Godot Version

4.2.2

Question

Hello,

In my game, the player is using a computer interface where they would open windows and interact with the game that way.
As such, i want to keep windows within the borders of the computer screen.
I have a scene to represent the window base class and i have implemented some logic to allow the dragging of the window across the screen. However my logic must not be correct as the window goes over the right border and stops well before the bottom border:

extends NinePatchRect

class_name TopBarWindow

@onready var custom_window = get_parent().get_parent()
@onready var computer_screen = get_parent().get_parent().get_parent()

var lifted = false

func _gui_input(event):
    if event is InputEventMouseButton and not event.pressed:
        lifted = false
    if event is InputEventMouseButton and event.pressed:
        lifted = true

    if event is InputEventMouseMotion and lifted:
        var window_position_x = custom_window.global_position[0]
        var window_position_y = custom_window.global_position[1]
        var window_size_x = custom_window.size[0]
        var window_size_y = custom_window.size[1]
        var computer_screen_position_x = computer_screen.global_position[0]
        var computer_screen_position_y = computer_screen.global_position[1]
        var computer_screen_size_x = computer_screen.size[0]
        var computer_screen_size_y = computer_screen.size[1]

        if (
            # check if window going past the computer screen on the right
            window_position_x + window_size_x + event.relative[0] < computer_screen_position_x + computer_screen_size_x
        ) and (
            # check if window going past the computer screen on the left
            window_position_x + event.relative[0] > computer_screen_position_x
        ) and (
            # check if window going past the computer screen on the bottom
            window_position_y + window_size_y + event.relative[1] < computer_screen_position_y + computer_screen_size_y
        ) and (
            # check if window going past the computer screen on the top
            window_position_y + event.relative[1] > computer_screen_position_y
        ):
            custom_window.position += event.relative

Is there something wrong there or should i look elsewhere?

Works fine for me. The behavior you describe has never happened in my tests. It might be because you’re using position instead of global_position in the end, though.

Also, here’s an alternative, shorter version you can try as well:

func _on_gui_input(event: InputEvent) -> void:
	if event is InputEventMouseMotion and event.pressure:
		for dim in ["x", "y"]:
			custom_window.global_position[dim] = clamp(
				custom_window.global_position[dim] + event.relative[dim],
				computer_screen.global_position[dim],
				computer_screen.global_position[dim] + computer_screen.size[dim] - custom_window.size[dim]
			)

I copied your answer down and it still has the same behaviour although it’s much smoother when nearing the borders of the node. I attached screenshot of the scene if it helps:

Edit: I also noticed that scaling the sprite (parent of the Control node representing the computer screen) does affect this behaviour as well as offsetting the sprite