Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Window.size_changed and NOTIFICATION_WM_SIZE_CHANGED are not triggered when "window.content_scale_mode == Window.ContentScaleMode.CONTENT_SCALE_MODE_VIEWPORT" #79336

Closed
Gnumaru opened this issue Jul 11, 2023 · 12 comments · Fixed by #80094

Comments

@Gnumaru
Copy link
Contributor

Gnumaru commented Jul 11, 2023

Godot version

v4.1.stable.official [9704596]

System information

Godot v4.1.stable - Windows 10.0.19044 - Vulkan (Compatibility) - NVIDIA GeForce GTX 1050 Ti (NVIDIA; 31.0.15.2647) - Intel(R) Core(TM) i7-7700 CPU @ 3.60GHz (8 Threads)

Issue description

When using a ContentScaleMode equal to CONTENT_SCALE_MODE_VIEWPORT, the size_changed signal of the root window is not emited regardless of changing the size via code or resizing the window manually. not only the signal is not emited, but the notification is also not triggered. Look at output log:

image

Steps to reproduce

On a new project, on a new scene, create a script in the scene root, paste this script and run it

extends Node2D
var mold_size:Vector2i
func _ready()->void:
	print('==================== BEGIN')
	var vwindow:Window = get_window()
	print('_ready(): connecting size_changed to on_size_changed')
	vwindow.size_changed.connect(on_size_changed)
	print('\n_ready(): changing scale to CONTENT_SCALE_MODE_DISABLED')
	vwindow.content_scale_mode = Window.ContentScaleMode.CONTENT_SCALE_MODE_DISABLED
	print('_ready(): changing to 1')
	vwindow.size = Vector2i.ONE
	print('_ready(): changing to 128')
	vwindow.size = Vector2i.ONE * 128
	print('\n_ready(): changing scale to CONTENT_SCALE_MODE_CANVAS_ITEMS')
	vwindow.content_scale_mode = Window.ContentScaleMode.CONTENT_SCALE_MODE_CANVAS_ITEMS
	print('_ready(): changing to 1')
	vwindow.size = Vector2i.ONE
	print('_ready(): changing to 128')
	vwindow.size = Vector2i.ONE * 128
	print('\n_ready(): changing scale to CONTENT_SCALE_MODE_VIEWPORT')
	vwindow.content_scale_mode = Window.ContentScaleMode.CONTENT_SCALE_MODE_VIEWPORT
	print('_ready(): changing to 1')
	vwindow.size = Vector2i.ONE
	print('_ready(): changing to 128')
	vwindow.size = Vector2i.ONE * 128
	print('==================== END')
func _notification(pwhat:int)->void:
	if pwhat == Node.NOTIFICATION_WM_SIZE_CHANGED: print('_notification(NOTIFICATION_WM_SIZE_CHANGED)')
func on_size_changed()->void:
	var vnewsize:Vector2i = get_window().size
	print('    on_size_changed(): changed from %s to %s'%[mold_size, vnewsize])
	mold_size = vnewsize
func _physics_process(delta:float)->void:
	if Engine.get_physics_frames() % 60 != 0: return
	print('_physics_process(): window size: %s'%get_window().size)

Minimal reproduction project

N/A

@Sauermann
Copy link
Contributor

Technically this works as expected, because the signal is only sent, when the size of the viewport changes

emit_signal(SNAME("size_changed"));

CONTENT_SCALE_MODE_VIEWPORT has in this case the effect, that the size of the viewport stays the same, so the signal is not emitted, even though the size of the Window has changed.

Please try instead to watch for the notification NOTIFICATION_WM_SIZE_CHANGED, if you want to get notified, when the size of the window changes.

@Gnumaru
Copy link
Contributor Author

Gnumaru commented Jul 11, 2023

The notification is also not triggered, but the window size property does change.

image

That is, the viewport size property is reflecting not the "render size", but the actual window usable area without decorations.

@Sauermann Sauermann added bug and removed discussion labels Jul 11, 2023
@Gnumaru Gnumaru changed the title The Window.size_changed signal is not emited when "window.content_scale_mode == Window.ContentScaleMode.CONTENT_SCALE_MODE_VIEWPORT" Window.size_changed and NOTIFICATION_WM_SIZE_CHANGED are not triggered when "window.content_scale_mode == Window.ContentScaleMode.CONTENT_SCALE_MODE_VIEWPORT" Jul 11, 2023
@Sauermann
Copy link
Contributor

After digging into this deeper, `NOTIFICATION_WM_SIZE_CHANGED´ is only sent to the Window, but not to the nodes inside the window. In your script, you listen for that notification in a node, that is inside the window.

So in order to achieve your goal, you need to listen on the root node for that notification. Here is a demo project, how this can be done: RootSizeChange.zip

Does this solve your problem?

@Sauermann Sauermann added discussion and removed bug labels Jul 13, 2023
@WarrenMarshall
Copy link

That's clever but what on earth ... is there really no way to simply be told, "Hey, the window was resized"? That seems like baseline functionality.

@Zireael07
Copy link
Contributor

Yes there is a way, @Sauermann demoed it for you

@WarrenMarshall
Copy link

Your definition of "simply" differs from mine. But sure, yeah ...

@Zireael07
Copy link
Contributor

It's very common in Godot to have to go up/down the node tree for certain things specific to certain node types.

@WarrenMarshall
Copy link

I'm sure you're right, I'll get used to doing things this way.

@Sauermann
Copy link
Contributor

The current behavior should be documented better.

@ForestGameDev
Copy link

This is very confusing, please correct me if I didn't get this:
When using Display > Window > Stretch > Mode > viewport, you cannot use signals:

  • get_window().size_changed
  • get_viewport().size_changed

The only alternative is to follow the example above which consists of loading another script to the root node by running in some different script the following:

$"/root".set_script(load("res://rw.gd"))

Where rw.gd contains the following:

extends Window

func _notification(what):
	if what == NOTIFICATION_WM_SIZE_CHANGED:
		print("New Root Size detected: ", size)

If I got this right, this should not be considered a documentation issue only. If making the signals respond as most people would expect is for some reason not desired, maybe we should have some other signal to use instead.

@wgetJane
Copy link

why not add a signal to Window (not Viewport) called something like window_resized that it emits when it receives the NOTIFICATION_WM_SIZE_CHANGED notification?

i don't think one can argue that the current solution is elegant or intuitive at all

@Sauermann
Copy link
Contributor

While this is solved for now by adjusting the documentation, we should continue the discussion about improving the situation in the form of a proposal: godotengine/godot-proposals#8788

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

7 participants