diff --git a/core/config/project_settings.cpp b/core/config/project_settings.cpp index 0e078c32c9..c6b358e53d 100644 --- a/core/config/project_settings.cpp +++ b/core/config/project_settings.cpp @@ -1736,6 +1736,7 @@ ProjectSettings::ProjectSettings() { GLOBAL_DEF("display/window/size/sharp_corners", false); GLOBAL_DEF("display/window/size/minimize_disabled", false); GLOBAL_DEF("display/window/size/maximize_disabled", false); + GLOBAL_DEF("display/window/size/enable_toggle_fullscreen_shortcut", true); GLOBAL_DEF(PropertyInfo(Variant::INT, "display/window/size/window_width_override", PROPERTY_HINT_RANGE, "0,7680,1,or_greater"), 0); // 8K resolution GLOBAL_DEF(PropertyInfo(Variant::INT, "display/window/size/window_height_override", PROPERTY_HINT_RANGE, "0,4320,1,or_greater"), 0); // 8K resolution diff --git a/core/input/input_map.cpp b/core/input/input_map.cpp index d18a7812f6..6c3046ff1e 100644 --- a/core/input/input_map.cpp +++ b/core/input/input_map.cpp @@ -433,6 +433,7 @@ static const _BuiltinActionDisplayName _builtin_action_display_names[] = { { "ui_unicode_start", TTRC("Start Unicode Character Input") }, { "ui_colorpicker_delete_preset", TTRC("ColorPicker: Delete Preset") }, { "ui_accessibility_drag_and_drop", TTRC("Accessibility: Keyboard Drag and Drop") }, + { "ui_toggle_fullscreen", TTRC("Toggle Fullscreen") }, { "", ""} /* clang-format on */ }; @@ -880,6 +881,16 @@ const HashMap>> &InputMap::get_builtins() { inputs.push_back(InputEventKey::create_reference(Key::KEY_DELETE)); default_builtin_cache.insert("ui_colorpicker_delete_preset", inputs); + // ///// Miscellaneous Shortcuts ///// + inputs = List>(); + inputs.push_back(InputEventKey::create_reference(Key::ENTER | KeyModifierMask::ALT)); + default_builtin_cache.insert("ui_toggle_fullscreen", inputs); + + inputs = List>(); + inputs.push_back(InputEventKey::create_reference(Key::F | KeyModifierMask::CTRL | KeyModifierMask::META)); + inputs.push_back(InputEventKey::create_reference(Key::ENTER | KeyModifierMask::ALT)); + default_builtin_cache.insert("ui_toggle_fullscreen.macos", inputs); + return default_builtin_cache; } diff --git a/doc/classes/ProjectSettings.xml b/doc/classes/ProjectSettings.xml index 14e3133aee..162a84caca 100644 --- a/doc/classes/ProjectSettings.xml +++ b/doc/classes/ProjectSettings.xml @@ -1012,6 +1012,9 @@ Forces the main window to be borderless. [b]Note:[/b] This setting is ignored on iOS, Android, and Web. + + If [code]true[/code], allows the user to toggle fullscreen mode by pressing the shortcut defined in [member input/ui_toggle_fullscreen] ([kbd]Alt + Enter[/kbd] by default). + Main window content is expanded to the full size of the window. Unlike a borderless window, the frame is left intact and can be used to resize the window, and the title bar is transparent, but has minimize/maximize/close buttons. [b]Note:[/b] This setting is implemented only on macOS. @@ -1645,6 +1648,13 @@ Default [InputEventAction] to toggle [i]insert mode[/i] in a text field. While in insert mode, inserting new text overrides the character after the cursor, unless the next character is a new line. [b]Note:[/b] Default [code]ui_*[/code] actions cannot be removed as they are necessary for the internal logic of several [Control]s. The events assigned to the action can however be modified. + + Default [InputEventAction] to toggle fullscreen mode on the main window. This input action is only effective if [member display/window/size/enable_toggle_fullscreen_shortcut] is [code]true[/code]. Game embedding currently does not make use of this shortcut, as it does not support fullscreen mode. + [b]Note:[/b] Default [code]ui_*[/code] actions cannot be removed as they are necessary for the internal logic of several [Control]s. The events assigned to the action can however be modified. + + + macOS specific override for the shortcut to toggle fullscreen mode on the main window. + Default [InputEventAction] to undo the most recent action. [b]Note:[/b] Default [code]ui_*[/code] actions cannot be removed as they are necessary for the internal logic of several [Control]s. The events assigned to the action can however be modified. diff --git a/doc/classes/Window.xml b/doc/classes/Window.xml index 26c9f763ed..5dbc15b925 100644 --- a/doc/classes/Window.xml +++ b/doc/classes/Window.xml @@ -682,6 +682,9 @@ If [code]true[/code], native window will be used regardless of parent viewport and project settings. + + If [code]true[/code], allows the user to toggle fullscreen mode by pressing the shortcut defined in [member ProjectSettings.input/ui_toggle_fullscreen] ([kbd]Alt + Enter[/kbd] by default). This is enabled on the main window according to the [member ProjectSettings.display/window/size/enable_toggle_fullscreen_shortcut] project setting. + If [code]true[/code], requests HDR output for the [Window], falling back to SDR if not supported, and automatically switching between HDR and SDR as the window moves between screens, screen capabilities change, or system settings are modified. This will internally force [member Viewport.use_hdr_2d] to be enabled on the main [Viewport]. All other [SubViewport] of this [Window] must have their [member Viewport.use_hdr_2d] property enabled to produce HDR output. diff --git a/scene/main/window.cpp b/scene/main/window.cpp index 87b51d4a1d..12dabbb3b6 100644 --- a/scene/main/window.cpp +++ b/scene/main/window.cpp @@ -552,6 +552,14 @@ Window::Mode Window::get_mode() const { return mode; } +void Window::set_fullscreen_shortcut_enabled(bool p_enabled) { + fullscreen_shortcut_enabled = p_enabled; +} + +bool Window::is_fullscreen_shortcut_enabled() const { + return fullscreen_shortcut_enabled; +} + void Window::set_flag(Flags p_flag, bool p_enabled) { ERR_MAIN_THREAD_GUARD; ERR_FAIL_INDEX(p_flag, FLAG_MAX); @@ -1680,6 +1688,7 @@ void Window::_notification(int p_what) { // It's the root window! visible = true; // Always visible. window_id = DisplayServerEnums::MAIN_WINDOW_ID; + fullscreen_shortcut_enabled = GLOBAL_GET("display/window/size/enable_toggle_fullscreen_shortcut"); focused_window = this; DisplayServer::get_singleton()->window_attach_instance_id(get_instance_id(), window_id); AccessibilityServer::get_singleton()->set_window_callbacks(window_id, callable_mp(this, &Window::_accessibility_activate), callable_mp(this, &Window::_accessibility_deactivate)); @@ -2025,6 +2034,15 @@ void Window::_window_input(const Ref &p_ev) { emit_signal(SceneStringName(window_input), p_ev); } + if (fullscreen_shortcut_enabled && p_ev->is_action_pressed("ui_toggle_fullscreen")) { + if (mode == MODE_FULLSCREEN || mode == MODE_EXCLUSIVE_FULLSCREEN) { + set_mode(toggle_fullscreen_previous_mode); + } else { + toggle_fullscreen_previous_mode = mode; + set_mode(MODE_FULLSCREEN); + } + } + if (is_inside_tree()) { push_input(p_ev); } @@ -3397,6 +3415,9 @@ void Window::_bind_methods() { ClassDB::bind_method(D_METHOD("is_hdr_output_requested"), &Window::is_hdr_output_requested); ClassDB::bind_method(D_METHOD("get_output_max_linear_value"), &Window::get_output_max_linear_value); + ClassDB::bind_method(D_METHOD("set_fullscreen_shortcut_enabled", "enabled"), &Window::set_fullscreen_shortcut_enabled); + ClassDB::bind_method(D_METHOD("is_fullscreen_shortcut_enabled"), &Window::is_fullscreen_shortcut_enabled); + ClassDB::bind_method(D_METHOD("is_maximize_allowed"), &Window::is_maximize_allowed); ClassDB::bind_method(D_METHOD("request_attention"), &Window::request_attention); @@ -3583,6 +3604,7 @@ void Window::_bind_methods() { ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "popup_wm_hint"), "set_flag", "get_flag", FLAG_POPUP_WM_HINT); ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "minimize_disabled"), "set_flag", "get_flag", FLAG_MINIMIZE_DISABLED); ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "maximize_disabled"), "set_flag", "get_flag", FLAG_MAXIMIZE_DISABLED); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "fullscreen_shortcut_enabled"), "set_fullscreen_shortcut_enabled", "is_fullscreen_shortcut_enabled"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "force_native"), "set_force_native", "get_force_native"); ADD_GROUP("Limits", ""); diff --git a/scene/main/window.h b/scene/main/window.h index 5076df0a78..106ccf4b6d 100644 --- a/scene/main/window.h +++ b/scene/main/window.h @@ -127,6 +127,7 @@ private: mutable Size2i max_size; mutable Vector mpath; mutable Mode mode = MODE_WINDOWED; + mutable Mode toggle_fullscreen_previous_mode = mode; mutable bool flags[FLAG_MAX] = {}; bool visible = true; bool focused = false; @@ -137,6 +138,7 @@ private: void _update_viewport_for_hdr_output(); + bool fullscreen_shortcut_enabled = false; bool transient = false; bool transient_to_focused = false; bool exclusive = false; @@ -340,6 +342,9 @@ public: void set_mode(Mode p_mode); Mode get_mode() const; + void set_fullscreen_shortcut_enabled(bool p_enabled); + bool is_fullscreen_shortcut_enabled() const; + void set_flag(Flags p_flag, bool p_enabled); bool get_flag(Flags p_flag) const;