Skip to content

Editor embedded game window: resizing window (get_window().size =) doesn't update viewport, causing crop or empty space #105349

Description

@hsandt

Tested versions

  • Reproducible in: v4.4.1.stable.official [49a5bc7]

System information

Godot v4.4.1.stable - Ubuntu 22.04.5 LTS 22.04 on X11 - X11 display driver, Multi-window, 1 monitor - OpenGL 3 (Compatibility) - NVIDIA GeForce GTX 860M (nvidia; 535.183.01) - Intel(R) Core(TM) i7-4710HQ CPU @ 2.50GHz (8 threads)

Issue description

I upgraded my pixel art game to Godot 4.4.1 and tested the new embedded game window, in both true embedded and floating modes, with different aspect ratio modes.

I use a custom script to automatically set the window size on game start, and also adjusts window position:

func set_window_scale(scale: float):
	var new_window_size := Vector2i(scale * get_native_window_size())

	var window := get_window()

	var previous_window_position := window.position
	var previous_window_size := window.size

	var new_window_position := previous_window_position + previous_window_size / 2 - new_window_size / 2

	window.position = new_window_position
	window.size = new_window_size

The part of the code that changes window.position never works, by design: I can see in the output log the message "Embedded window can't be moved." and I understand that.

However, the part changing the window.size shows no error, it just half-works and that causes odd results.

This is what the game looks like when not using the embedded game window (3 dots > uncheck Embed Game on Next Play), and the initial window scale is 2:

Image

This is what it looks like in the embedded game window in mode 1 (size based on project settings):

Image

Now if I resize the embedded game window a bit to force refresh, it will rescale the game down:

Image

I totally understand that to properly scale the embedded game window, we'd need to resize the window inside the editor and that's not supported. My bug report is more about the fact that it does things half-way, scaling the game and cropping it, and without leaving a message like when trying to set window position.

Now this is what happens in mode 2 (preserve aspect ratio):

Image

If I resize the window slightly, it shrinks back:

Image

and the 3rd mode (stretch to fit) gives almost the same result, except with black bars.

When the embedded window is very big, mode 2/3 will leave a lot of empty space instead:

Image

Now floating window, mode 1 or mode 2:

Image

Resize window a bit:

Image

Floating window, mode 3:

Image

Resizing gives same result as in mode 1 or mode 2.

This time, I don't see why the floating window could not resize itself properly to fit the new viewport size. I still see the message "Embedded window can't be moved." so apparently it can't move itself either... but it's already floating, so it sounds weird.

If all of this is by design and our responsibility is to verify whether the game is embedded or not, I've already found I can check Engine.is_embedded_in_editor() (example directly taken from the PR #99010), so I'll do that for now.

However, for floating embedded window it does sound odd that moving and resizing is not supported - and even if it was fixed, I have currently no way to check if the embedded window is floating or not (would need some Engine.is_embedded_window_floating() method).

I realize I'll need a discussion > feature proposal to suggest to make at least floating game window resizable and allow to detect them. I'll see this later based on your replies.

Steps to reproduce

Create a new 2D project with those settings:

Display > Window > Viewport width: 426
Display > Window > Viewport height: 240
Display > Window > Stretch mode: Viewport
(keep scale 1, we need to script to change the game window size and modify scale thx to stretch mode)

You can add some Sprite2D with the default Godot icon texture just to see how things are scaled.

Then create a script:

func _ready():
	set_window_scale(2.0)

func set_window_scale(scale: float):
	var new_window_size := Vector2i(scale * get_native_window_size())

	var window := get_window()

	var previous_window_position := window.position
	var previous_window_size := window.size

	var new_window_position := previous_window_position + previous_window_size / 2 - new_window_size / 2

	window.position = new_window_position
	window.size = new_window_size

and add it to some node.

Then run the game.

Minimal reproduction project (MRP)

I should probably make one based on my own instructions above later.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    Status
    For team assessment

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions