godot
godot copied to clipboard
Godot 4 beta 8: DisplayServer.WINDOW_MODE_WINDOWED not working correctly
Godot version
v4.0.beta8.official [45cac42c0]
System information
Windows 10
Issue description
In 3.5 I had this issue: https://github.com/godotengine/godot/issues/61871
4.0 beta 8 fixed this by adding the non exclusive fullscreen, but the changes caused a problem where you can't get back to windowed mode in script at all after entering fullscreen or exclusive fullscreen while having a maximized window. This is what I'm trying to do, 2 different toggles for maximize/windowed and fullscreen/windowed:
if on_fullscreen_icon == true:
print(DisplayServer.window_get_mode())
if DisplayServer.window_get_mode() != DisplayServer.WINDOW_MODE_FULLSCREEN:
DisplayServer.window_set_mode(DisplayServer.WINDOW_MODE_FULLSCREEN)
elif DisplayServer.window_get_mode() != DisplayServer.WINDOW_MODE_WINDOWED:
DisplayServer.window_set_mode(DisplayServer.WINDOW_MODE_WINDOWED)
DisplayServer.window_set_size(Vector2(1280, 720))
DisplayServer.window_set_position(Vector2(320, 180))
elif on_maximized_icon == true:
print(DisplayServer.window_get_mode())
if DisplayServer.window_get_mode() != DisplayServer.WINDOW_MODE_MAXIMIZED:
DisplayServer.window_set_mode(DisplayServer.WINDOW_MODE_MAXIMIZED)
elif DisplayServer.window_get_mode() != DisplayServer.WINDOW_MODE_WINDOWED:
DisplayServer.window_set_mode(DisplayServer.WINDOW_MODE_WINDOWED)
DisplayServer.window_set_size(Vector2(1280, 720))
DisplayServer.window_set_position(Vector2(320, 180))
What happens is that the 3 lines in both the elif statement don't do what they should be doing and just go back to fullscreen instead of windowed. You should be able to reproduce this in a small example as well.
In Godot 3.5 this was working by doing the following:
if on_fullscreen_icon == true:
OS.window_fullscreen = !OS.window_fullscreen
elif on_maximized_icon == true and !OS.window_fullscreen:
if OS.window_maximized:
OS.window_maximized = !OS.window_maximized
OS.set_window_size(Vector2(1280, 720))
OS.set_window_position(Vector2(320, 180))
else:
OS.window_maximized = !OS.window_maximized
Steps to reproduce
Maximize window (in script or just manually) then enable fullscreen or exclusive fullscreen. Now if you disable fullscreen again you are unable to change the window size, position or set it to windowed mode through script.
Minimal reproduction project
N/A, just try to leave either maximized or fullscreen window after going from maximized>fullscreen.
This is probably a windows specific issue just like my last one.
The workaround I got for this right now is by changing the first if statement to:
if DisplayServer.window_get_mode() != DisplayServer.WINDOW_MODE_FULLSCREEN \
and DisplayServer.window_get_mode() != DisplayServer.WINDOW_MODE_MAXIMIZED:
This way it's forced to skip to the elif and never enters fullscreen while being maximized. The set_size and set_position aren't needed this way either.
Also Windows seems to have a weird stretching problem when changing window modes that didn't exist in 3.5.
To be clear, the exact behaviour in 3.5 was that you can't leave fullscreen by toggling OS.window_maximized. You had to exit fullscreen first which was fine. I can't replicate that in 4.0 though, even if I convert the 3.5 code exactly (not the example). It just keeps thinking DisplayServer.WINDOW_MODE_WINDOWED means fullscreen for some reason.
Tested with this code
func _process(delta: float) -> void:
if Input.is_action_just_pressed("ui_accept"):
if DisplayServer.window_get_mode() != DisplayServer.WINDOW_MODE_FULLSCREEN:
DisplayServer.window_set_mode(DisplayServer.WINDOW_MODE_FULLSCREEN)
else:
DisplayServer.window_set_mode(DisplayServer.WINDOW_MODE_WINDOWED)
#DisplayServer.window_set_mode(DisplayServer.WINDOW_MODE_WINDOWED)
If you maximize the window and switch to fullscreen, WINDOW_MODE_WINDOWED will not take effect. The window will be maximized.
When you uncomment the second WINDOW_MODE_WINDOWED, so that it's set twice, the window will become windowed correctly.
Tested with this code
func _process(delta: float) -> void: if Input.is_action_just_pressed("ui_accept"): if DisplayServer.window_get_mode() != DisplayServer.WINDOW_MODE_FULLSCREEN: DisplayServer.window_set_mode(DisplayServer.WINDOW_MODE_FULLSCREEN) else: DisplayServer.window_set_mode(DisplayServer.WINDOW_MODE_WINDOWED) #DisplayServer.window_set_mode(DisplayServer.WINDOW_MODE_WINDOWED)If you maximize the window and switch to fullscreen,
WINDOW_MODE_WINDOWEDwill not take effect. The window will be maximized. When you uncomment the secondWINDOW_MODE_WINDOWED, so that it's set twice, the window will become windowed correctly.
I just got to try this and it didn't work for me, with 1 line of DisplayServer.window_set_mode(DisplayServer.WINDOW_MODE_WINDOWED) it just goes back to maximized. With the 2 lines it immediately flashes back to fullscreen.
Edit: Just want to mention that it's not a Windows bug as it seems to work fine in random programs like windows terminal, explorer etc. They allow you to go from maximized -> fullscreen -> maximized-> default size etc...
Possibly associated - if you set Project Settings / Display / Window / Mode to Fullscreen and then:
func _ready(): print(DisplayServer.window_get_mode())
The print returns 0 in the console (ie DisplayServer.WINDOW_MODE_WINDOWED).
I spent some time looking at the problem again because it clearly is possible based on:
it's not a Windows bug as it seems to work fine in random programs like windows terminal, explorer etc. They allow you to go from
maximized->fullscreen->maximized->default sizeetc...
And I just noticed that print(DisplayServer.window_get_mode()) returns 3 (which is fullscreen) when you press winkey+down after leaving fullscreen. That's a pretty clear bug.
print(DisplayServer.window_get_mode())
if Input.is_action_just_pressed("toggle_fullscreen"):
if DisplayServer.window_get_mode() != DisplayServer.WINDOW_MODE_FULLSCREEN:
DisplayServer.window_set_mode(DisplayServer.WINDOW_MODE_FULLSCREEN)
elif DisplayServer.window_get_mode() != DisplayServer.WINDOW_MODE_WINDOWED:
DisplayServer.window_set_mode(DisplayServer.WINDOW_MODE_WINDOWED)
To reproduce:
- maximize window
- toggle fullscreen twice to go back to maximized
- now you are in a maximized window but when you try to restore window size with winkey+down or the button, window mode will return 3 (fullscreen) instead of 0 (windowed)
- it will actually go to windowed though, but you can't correctly resize the window behind a windowed check as godot thinks it's still fullscreen
Toggling between maximized and windowed does work correctly if you don't go fullscreen in between.
This is probably a windows specific issue just like my last one.
The bug is also reproducible on Linux (v4.2.1.stable.arch_linux).
When you uncomment the second WINDOW_MODE_WINDOWED, so that it's set twice, the window will become windowed correctly.
Setting back to windowed mode twice still fails on my machine.
Confirming on v4.2.1.stable.official [b09f793f5] on Windows 11.
Faced same issue in Godot v4.2.1
Tried different options to resize, set sizes and etc - nothing helps. Then found that simple switching to DisplayServer.WINDOW_MODE_MINIMIZED and then to DisplayServer.WINDOW_MODE_WINDOWED works.
So hope it will help for someone:
func on_window_button_pressed():
if DisplayServer.window_get_mode() == DisplayServer.WINDOW_MODE_FULLSCREEN:
DisplayServer.window_set_mode(DisplayServer.WINDOW_MODE_MINIMIZED)
DisplayServer.window_set_mode(DisplayServer.WINDOW_MODE_WINDOWED)
else:
DisplayServer.window_set_mode(DisplayServer.WINDOW_MODE_FULLSCREEN)
This issues persists in in v4.2.2.stable, but only if you have display/window/size/resizable set to false, if it's set to the default of true, then switching betwen any of the window_modes works as expected.
The issue is still present in v4.2.2.stable.official [15073afe3]. Even with resizable=false. The game just becomes a black screen when setting DisplayServer.WINDOW_MODE_WINDOWED after DisplayServer.WINDOW_MODE_FULLSCREEN.
Godot v4.2.2.stable - Windows 10.0.19045 - Vulkan (Forward+) - dedicated NVIDIA GeForce RTX 3050 Ti Laptop GPU (NVIDIA; 32.0.15.5585) - AMD Ryzen 5 5600H with Radeon Graphics (12 Threads)