diff --git a/core/config/project_settings.cpp b/core/config/project_settings.cpp index 5992b46249..d8bcdee139 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 7d484f4168..abd7fbbd5c 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 */ }; @@ -878,6 +879,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 23b263a23f..5804b7225b 100644 --- a/doc/classes/ProjectSettings.xml +++ b/doc/classes/ProjectSettings.xml @@ -1009,6 +1009,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. @@ -1642,6 +1645,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 6b684f3fa9..a723ba8003 100644 --- a/doc/classes/Window.xml +++ b/doc/classes/Window.xml @@ -680,6 +680,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 1fab41f318..6b80588a0f 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); @@ -1672,6 +1680,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)); @@ -2017,6 +2026,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); } @@ -3389,6 +3407,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); @@ -3575,6 +3596,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 34a4ebe77e..6323ac6ac4 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;