From 370395f1b6430f09786a26c89ba7f97108fa7d61 Mon Sep 17 00:00:00 2001 From: daddy Date: Fri, 18 Sep 2026 00:56:19 +0000 Subject: [PATCH] feat(display): enable borderless fullscreen by default, F11/Alt+Enter toggle, and menu button --- project.godot | 3 +++ scripts/main_menu.gd | 25 +++++++++++++++++++++++ scripts/session.gd | 25 +++++++++++++++++++++++ scripts/smoke_test_main_menu_full_flow.gd | 6 +++--- scripts/smoke_test_main_menu_ui.gd | 8 ++++---- 5 files changed, 60 insertions(+), 7 deletions(-) diff --git a/project.godot b/project.godot index f198f55..04a0216 100644 --- a/project.godot +++ b/project.godot @@ -21,6 +21,9 @@ Session="*res://scripts/session.gd" window/size/viewport_width=1920 window/size/viewport_height=1080 +window/size/mode=3 +window/size/window_width_override=1280 +window/size/window_height_override=720 window/stretch/mode="canvas_items" window/stretch/aspect="keep" diff --git a/scripts/main_menu.gd b/scripts/main_menu.gd index d445656..0269fb4 100644 --- a/scripts/main_menu.gd +++ b/scripts/main_menu.gd @@ -67,6 +67,17 @@ static func _build_label() -> String: return "dev" +static func _update_fs_button(btn: Button) -> void: + if DisplayServer.get_name() == "headless": + btn.text = "⛶ Fullscreen (F11)" + return + var m := DisplayServer.window_get_mode() + if m == DisplayServer.WINDOW_MODE_FULLSCREEN or m == DisplayServer.WINDOW_MODE_EXCLUSIVE_FULLSCREEN: + btn.text = "🗗 Windowed (F11)" + else: + btn.text = "⛶ Fullscreen (F11)" + + func _ready() -> void: var v := Label.new() v.text = "build %s" % _build_label() @@ -87,6 +98,20 @@ func _ready() -> void: v.mouse_filter = Control.MOUSE_FILTER_IGNORE add_child(v) + var fs_btn := Button.new() + fs_btn.set_anchors_preset(Control.PRESET_TOP_RIGHT) + fs_btn.offset_left = -160 + fs_btn.offset_top = 10 + fs_btn.offset_right = -10 + fs_btn.offset_bottom = 38 + fs_btn.add_theme_font_size_override("font_size", 12) + _update_fs_button(fs_btn) + fs_btn.pressed.connect(func(): + Session.toggle_fullscreen() + _update_fs_button(fs_btn) + ) + add_child(fs_btn) + # Cache node references. _auth_buttons_row = $CenterContainer/VBoxContainer/AuthButtonsRow _login_button = $CenterContainer/VBoxContainer/AuthButtonsRow/LoginButton diff --git a/scripts/session.gd b/scripts/session.gd index 11bea10..7f250e4 100644 --- a/scripts/session.gd +++ b/scripts/session.gd @@ -46,3 +46,28 @@ func clear() -> void: port = 0 active = false editing = false + + +func _unhandled_input(event: InputEvent) -> void: + if event is InputEventKey and event.pressed and not event.echo: + if event.keycode == KEY_F11 or (event.keycode == KEY_ENTER and event.alt_pressed): + toggle_fullscreen() + get_viewport().set_input_as_handled() + + +func toggle_fullscreen() -> void: + if DisplayServer.get_name() == "headless": + return + var current_mode := DisplayServer.window_get_mode() + if current_mode == DisplayServer.WINDOW_MODE_FULLSCREEN or current_mode == DisplayServer.WINDOW_MODE_EXCLUSIVE_FULLSCREEN: + DisplayServer.window_set_mode(DisplayServer.WINDOW_MODE_WINDOWED) + var screen_id := DisplayServer.window_get_current_screen() + var screen_rect := DisplayServer.screen_get_usable_rect(screen_id) + var target_w := mini(1280, int(screen_rect.size.x * 0.9)) + var target_h := mini(720, int(screen_rect.size.y * 0.9)) + DisplayServer.window_set_size(Vector2i(target_w, target_h)) + var pos := screen_rect.position + (screen_rect.size - Vector2i(target_w, target_h)) / 2 + DisplayServer.window_set_position(pos) + else: + DisplayServer.window_set_mode(DisplayServer.WINDOW_MODE_FULLSCREEN) + diff --git a/scripts/smoke_test_main_menu_full_flow.gd b/scripts/smoke_test_main_menu_full_flow.gd index 9a23105..71cc34d 100644 --- a/scripts/smoke_test_main_menu_full_flow.gd +++ b/scripts/smoke_test_main_menu_full_flow.gd @@ -25,7 +25,7 @@ func _run() -> void: var username_edit: LineEdit = instance.get_node("CenterContainer/VBoxContainer/AuthPanel/MarginContainer/AuthVBox/UsernameEdit") var password_edit: LineEdit = instance.get_node("CenterContainer/VBoxContainer/AuthPanel/MarginContainer/AuthVBox/PasswordEdit") var email_edit: LineEdit = instance.get_node("CenterContainer/VBoxContainer/AuthPanel/MarginContainer/AuthVBox/EmailEdit") - var dob_edit: LineEdit = instance.get_node("CenterContainer/VBoxContainer/AuthPanel/MarginContainer/AuthVBox/DobEdit") + var over_18_check: CheckBox = instance.get_node("CenterContainer/VBoxContainer/AuthPanel/MarginContainer/AuthVBox/Over18Check") var auth_button: Button = instance.get_node("CenterContainer/VBoxContainer/AuthPanel/MarginContainer/AuthVBox/AuthButton") var auth_mode_label: Label = instance.get_node("CenterContainer/VBoxContainer/AuthPanel/MarginContainer/AuthVBox/AuthModeLabel") var welcome_label: Label = instance.get_node("CenterContainer/VBoxContainer/AuthPanel/MarginContainer/AuthVBox/WelcomeLabel") @@ -46,7 +46,7 @@ func _run() -> void: username_edit.text = "mainmenu_e2e_%d" % unique_id password_edit.text = "TestPass123!" email_edit.text = "mainmenu_e2e_%d@test.example.com" % unique_id - dob_edit.text = "1990-01-01" + over_18_check.button_pressed = true # Call the submit handler directly (awaited) rather than via # auth_button.pressed.emit() -- a synthetic .emit() in --script/ @@ -68,7 +68,7 @@ func _run() -> void: _check("Username edit hidden after auth", not username_edit.visible) _check("Password edit hidden after auth", not password_edit.visible) _check("Email edit hidden after auth", not email_edit.visible) - _check("DOB field hidden after auth", not dob_edit.visible) + _check("Over18 checkbox hidden after auth", not over_18_check.visible) _check("Auth button hidden after auth", not auth_button.visible) _check("Auth mode label hidden after auth", not auth_mode_label.visible) _check("Welcome label contains username", welcome_label.text.begins_with("Welcome, mainmenu_e2e_")) diff --git a/scripts/smoke_test_main_menu_ui.gd b/scripts/smoke_test_main_menu_ui.gd index 248ceb0..f5d62ab 100644 --- a/scripts/smoke_test_main_menu_ui.gd +++ b/scripts/smoke_test_main_menu_ui.gd @@ -31,7 +31,7 @@ func _run() -> void: var auth_panel: PanelContainer = instance.get_node("CenterContainer/VBoxContainer/AuthPanel") var auth_mode_label: Label = instance.get_node("CenterContainer/VBoxContainer/AuthPanel/MarginContainer/AuthVBox/AuthModeLabel") var email_edit: LineEdit = instance.get_node("CenterContainer/VBoxContainer/AuthPanel/MarginContainer/AuthVBox/EmailEdit") - var dob_edit: LineEdit = instance.get_node("CenterContainer/VBoxContainer/AuthPanel/MarginContainer/AuthVBox/DobEdit") + var over_18_check: CheckBox = instance.get_node("CenterContainer/VBoxContainer/AuthPanel/MarginContainer/AuthVBox/Over18Check") # --- Test 1: auth panel starts hidden --- if _check("auth panel starts hidden", not auth_panel.visible): @@ -58,7 +58,7 @@ func _run() -> void: else: failed += 1 - if _check("DOB field hidden in Login mode", not dob_edit.visible): + if _check("Over18 checkbox hidden in Login mode", not over_18_check.visible): passed += 1 else: failed += 1 @@ -82,7 +82,7 @@ func _run() -> void: else: failed += 1 - if _check("DOB field visible in Register mode", dob_edit.visible): + if _check("Over18 checkbox visible in Register mode", over_18_check.visible): passed += 1 else: failed += 1 @@ -101,7 +101,7 @@ func _run() -> void: else: failed += 1 - if _check("DOB field hidden after switching back to Login", not dob_edit.visible): + if _check("Over18 checkbox hidden after switching back to Login", not over_18_check.visible): passed += 1 else: failed += 1