Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions core/config/project_settings.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1675,6 +1675,7 @@ ProjectSettings::ProjectSettings() {
#endif

GLOBAL_DEF_BASIC("gui/common/snap_controls_to_pixels", true);
GLOBAL_DEF("gui/common/always_show_focus_state", false);
GLOBAL_DEF_BASIC("gui/fonts/dynamic_fonts/use_oversampling", true);

GLOBAL_DEF_RST(PropertyInfo(Variant::INT, "rendering/rendering_device/vsync/frame_queue_size", PROPERTY_HINT_RANGE, "2,3,1"), 2);
Expand Down
6 changes: 5 additions & 1 deletion doc/classes/Control.xml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
Godot propagates input events via viewports. Each [Viewport] is responsible for propagating [InputEvent]s to their child nodes. As the [member SceneTree.root] is a [Window], this already happens automatically for all UI elements in your game.
Input events are propagated through the [SceneTree] from the root node to all child nodes by calling [method Node._input]. For UI elements specifically, it makes more sense to override the virtual method [method _gui_input], which filters out unrelated input events, such as by checking z-order, [member mouse_filter], focus, or if the event was inside of the control's bounding box.
Call [method accept_event] so no other node receives the event. Once you accept an input, it becomes handled so [method Node._unhandled_input] will not process it.
Only one [Control] node can be in focus. Only the node in focus will receive events. To get the focus, call [method grab_focus]. [Control] nodes lose focus when another node grabs it, or if you hide the node in focus.
Only one [Control] node can be in focus. Only the node in focus will receive events. To get the focus, call [method grab_focus]. [Control] nodes lose focus when another node grabs it, or if you hide the node in focus. Focus will not be represented visually if gained via mouse/touch input, only appearing with keyboard/gamepad input (for accessibility), or via [method grab_focus].
Sets [member mouse_filter] to [constant MOUSE_FILTER_IGNORE] to tell a [Control] node to ignore mouse or touch events. You'll need it if you place an icon on top of a button.
[Theme] resources change the control's appearance. The [member theme] of a [Control] node affects all of its direct and indirect children (as long as a chain of controls is uninterrupted). To override some of the theme items, call one of the [code]add_theme_*_override[/code] methods, like [method add_theme_font_override]. You can also override theme items in the Inspector.
[b]Note:[/b] Theme items are [i]not[/i] [Object] properties. This means you can't access their values using [method Object.get] and [method Object.set]. Instead, use the [code]get_theme_*[/code] and [code]add_theme_*_override[/code] methods provided by this class.
Expand Down Expand Up @@ -618,15 +618,19 @@
</method>
<method name="grab_focus">
<return type="void" />
<param index="0" name="hide_focus" type="bool" default="false" />
<description>
Steal the focus from another control and become the focused control (see [member focus_mode]).
If [param hide_focus] is [code]true[/code], the control will not visually show its focused state. Has no effect if [member ProjectSettings.gui/common/always_show_focus_state] is set to [code]true[/code].
[b]Note:[/b] Using this method together with [method Callable.call_deferred] makes it more reliable, especially when called inside [method Node._ready].
</description>
</method>
<method name="has_focus" qualifiers="const">
<return type="bool" />
<param index="0" name="ignore_hidden_focus" type="bool" default="false" />
<description>
Returns [code]true[/code] if this is the current focused control. See [member focus_mode].
If [param ignore_hidden_focus] is [code]true[/code], controls that have their focus hidden will always return [code]false[/code]. Hidden focus happens automatically when controls gain focus via mouse input, or manually using [method grab_focus] with [code]hide_focus[/code] set to [code]true[/code].
</description>
</method>
<method name="has_theme_color" qualifiers="const">
Expand Down
3 changes: 3 additions & 0 deletions doc/classes/ProjectSettings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -1177,6 +1177,9 @@
<member name="filesystem/import/fbx2gltf/enabled.web" type="bool" setter="" getter="" default="false">
Override for [member filesystem/import/fbx2gltf/enabled] on the Web where FBX2glTF can't easily be accessed from Godot.
</member>
<member name="gui/common/always_show_focus_state" type="bool" setter="" getter="" default="false">
If [code]true[/code], [Control]s will always show if they're focused, even if said focus was gained via mouse/touch input.
</member>
<member name="gui/common/default_scroll_deadzone" type="int" setter="" getter="" default="0">
Default value for [member ScrollContainer.scroll_deadzone], which will be used for all [ScrollContainer]s unless overridden.
</member>
Expand Down
8 changes: 4 additions & 4 deletions editor/docks/filesystem_dock.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -775,13 +775,13 @@ void FileSystemDock::_navigate_to_path(const String &p_path, bool p_select_in_fa
item = item->get_next();
}
if (p_grab_focus) {
tree->grab_focus();
tree->grab_focus(true);
}
} else {
(*directory_ptr)->select(0);
_update_file_list(false);
if (p_grab_focus) {
files->grab_focus();
files->grab_focus(true);
}
}
tree->ensure_cursor_is_visible();
Expand Down Expand Up @@ -1397,7 +1397,7 @@ void FileSystemDock::_update_history() {

if (tree->is_visible()) {
_update_tree(get_uncollapsed_paths());
tree->grab_focus();
tree->grab_focus(true);
}

if (file_list_vb->is_visible()) {
Expand Down Expand Up @@ -3535,7 +3535,7 @@ void FileSystemDock::_tree_rmb_select(const Vector2 &p_pos, MouseButton p_button
if (p_button != MouseButton::RIGHT) {
return;
}
tree->grab_focus();
tree->grab_focus(true);

// Right click is pressed in the tree.
Vector<String> paths = _tree_get_selected(false);
Expand Down
4 changes: 2 additions & 2 deletions editor/docks/scene_tree_dock.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1553,7 +1553,7 @@ void SceneTreeDock::_tool_selected(int p_tool, bool p_confirm_override) {
editor_selection->clear();
editor_selection->add_node(new_node);

scene_tree->get_scene_tree()->grab_focus();
scene_tree->get_scene_tree()->grab_focus(true);
} break;

default: {
Expand Down Expand Up @@ -3146,7 +3146,7 @@ void SceneTreeDock::_create() {
undo_redo->commit_action();
}

scene_tree->get_scene_tree()->grab_focus();
scene_tree->get_scene_tree()->grab_focus(true);
}

void SceneTreeDock::replace_node(Node *p_node, Node *p_by_node) {
Expand Down
4 changes: 2 additions & 2 deletions editor/gui/code_editor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -599,10 +599,10 @@ void FindReplaceBar::_show_search(bool p_with_replace, bool p_show_only) {

if (focus_replace) {
search_text->deselect();
callable_mp((Control *)replace_text, &Control::grab_focus).call_deferred();
callable_mp((Control *)replace_text, &Control::grab_focus).call_deferred(false);
} else {
replace_text->deselect();
callable_mp((Control *)search_text, &Control::grab_focus).call_deferred();
callable_mp((Control *)search_text, &Control::grab_focus).call_deferred(false);
}

if (on_one_line) {
Expand Down
2 changes: 1 addition & 1 deletion editor/gui/create_dialog.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -563,7 +563,7 @@ void CreateDialog::_notification(int p_what) {

case NOTIFICATION_VISIBILITY_CHANGED: {
if (is_visible()) {
callable_mp((Control *)search_box, &Control::grab_focus).call_deferred(); // Still not visible.
callable_mp((Control *)search_box, &Control::grab_focus).call_deferred(false); // Still not visible.
search_box->select_all();
} else {
EditorSettings::get_singleton()->set_project_metadata("dialog_bounds", "create_new_node", Rect2(get_position(), get_size()));
Expand Down
4 changes: 2 additions & 2 deletions editor/gui/editor_file_dialog.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -482,9 +482,9 @@ void EditorFileDialog::_post_popup() {
set_current_dir(current);

if (mode == FILE_MODE_SAVE_FILE) {
file->grab_focus();
file->grab_focus(false);
} else {
item_list->grab_focus();
item_list->grab_focus(false);
}

bool is_open_directory_mode = mode == FILE_MODE_OPEN_DIR;
Expand Down
8 changes: 4 additions & 4 deletions editor/gui/editor_spin_slider.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,7 @@ void EditorSpinSlider::_grab_end() {
grabbing_spinner = false;
emit_signal("ungrabbed");
} else {
_focus_entered();
_focus_entered(true);
}

grabbing_spinner_attempt = false;
Expand Down Expand Up @@ -340,7 +340,7 @@ void EditorSpinSlider::_draw_spin_slider() {
}
}

if (has_focus()) {
if (has_focus(true)) {
Ref<StyleBox> focus = get_theme_stylebox(SNAME("focus"), SNAME("LineEdit"));
draw_style_box(focus, Rect2(Vector2(), size));
}
Expand Down Expand Up @@ -672,7 +672,7 @@ bool EditorSpinSlider::is_grabbing() const {
return grabbing_grabber || grabbing_spinner;
}

void EditorSpinSlider::_focus_entered() {
void EditorSpinSlider::_focus_entered(bool p_hide_focus) {
if (read_only) {
return;
}
Expand All @@ -683,7 +683,7 @@ void EditorSpinSlider::_focus_entered() {
value_input->set_focus_next(find_next_valid_focus()->get_path());
value_input->set_focus_previous(find_prev_valid_focus()->get_path());
callable_mp((CanvasItem *)value_input_popup, &CanvasItem::show).call_deferred();
callable_mp((Control *)value_input, &Control::grab_focus).call_deferred();
callable_mp((Control *)value_input, &Control::grab_focus).call_deferred(p_hide_focus);
callable_mp(value_input, &LineEdit ::select_all).call_deferred();
emit_signal("value_focus_entered");
}
Expand Down
2 changes: 1 addition & 1 deletion editor/gui/editor_spin_slider.h
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ class EditorSpinSlider : public Range {
static void _bind_methods();
void _grabber_mouse_entered();
void _grabber_mouse_exited();
void _focus_entered();
void _focus_entered(bool p_hide_focus = false);

public:
String get_tooltip(const Point2 &p_pos) const override;
Expand Down
2 changes: 1 addition & 1 deletion editor/inspector/editor_properties.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2897,7 +2897,7 @@ void EditorPropertyNodePath::_menu_option(int p_idx) {
const NodePath &np = _get_node_path();
edit->set_text(String(np));
edit->show();
callable_mp((Control *)edit, &Control::grab_focus).call_deferred();
callable_mp((Control *)edit, &Control::grab_focus).call_deferred(false);
} break;

case ACTION_SELECT: {
Expand Down
8 changes: 4 additions & 4 deletions editor/project_manager/project_dialog.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -813,7 +813,7 @@ void ProjectDialog::show_dialog(bool p_reset_name) {
renderer_container->hide();
default_files_container->hide();

callable_mp((Control *)project_name, &Control::grab_focus).call_deferred();
callable_mp((Control *)project_name, &Control::grab_focus).call_deferred(false);
callable_mp(project_name, &LineEdit::select_all).call_deferred();
} else {
if (p_reset_name) {
Expand Down Expand Up @@ -865,7 +865,7 @@ void ProjectDialog::show_dialog(bool p_reset_name) {
renderer_container->show();
default_files_container->show();

callable_mp((Control *)project_name, &Control::grab_focus).call_deferred();
callable_mp((Control *)project_name, &Control::grab_focus).call_deferred(false);
callable_mp(project_name, &LineEdit::select_all).call_deferred();
} else if (mode == MODE_INSTALL) {
set_title(TTR("Install Project:") + " " + zip_title);
Expand All @@ -878,7 +878,7 @@ void ProjectDialog::show_dialog(bool p_reset_name) {
renderer_container->hide();
default_files_container->hide();

callable_mp((Control *)project_path, &Control::grab_focus).call_deferred();
callable_mp((Control *)project_path, &Control::grab_focus).call_deferred(false);
} else if (mode == MODE_DUPLICATE) {
set_title(TTRC("Duplicate Project"));
set_ok_button_text(TTRC("Duplicate"));
Expand All @@ -891,7 +891,7 @@ void ProjectDialog::show_dialog(bool p_reset_name) {
edit_check_box->hide();
}

callable_mp((Control *)project_name, &Control::grab_focus).call_deferred();
callable_mp((Control *)project_name, &Control::grab_focus).call_deferred(false);
callable_mp(project_name, &LineEdit::select_all).call_deferred();
}

Expand Down
2 changes: 1 addition & 1 deletion editor/run/embedded_process.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -415,7 +415,7 @@ void EmbeddedProcess::_check_focused_process_id() {
if (modal_window->get_mode() == Window::MODE_MINIMIZED) {
modal_window->set_mode(Window::MODE_WINDOWED);
}
callable_mp(modal_window, &Window::grab_focus).call_deferred();
callable_mp(modal_window, &Window::grab_focus).call_deferred(false);
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion editor/scene/2d/tiles/tile_set_editor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -997,7 +997,7 @@ void TileSourceInspectorPlugin::_show_id_edit_dialog(Object *p_for_source) {
edited_source = p_for_source;
id_input->set_value(p_for_source->get("id"));
id_edit_dialog->popup_centered(Vector2i(400, 0) * EDSCALE);
callable_mp((Control *)id_input->get_line_edit(), &Control::grab_focus).call_deferred();
callable_mp((Control *)id_input->get_line_edit(), &Control::grab_focus).call_deferred(false);
}

void TileSourceInspectorPlugin::_confirm_change_id() {
Expand Down
2 changes: 1 addition & 1 deletion editor/scene/canvas_item_editor_plugin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2797,7 +2797,7 @@ void CanvasItemEditor::_gui_input_viewport(const Ref<InputEvent> &p_event) {

// Grab focus
if (!viewport->has_focus() && (!get_viewport()->gui_get_focus_owner() || !get_viewport()->gui_get_focus_owner()->is_text_field())) {
callable_mp((Control *)viewport, &Control::grab_focus).call_deferred();
callable_mp((Control *)viewport, &Control::grab_focus).call_deferred(false);
}
}

Expand Down
2 changes: 1 addition & 1 deletion editor/scene/connections_dialog.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -485,7 +485,7 @@ void ConnectDialog::_update_warning_label() {
}

void ConnectDialog::_post_popup() {
callable_mp((Control *)dst_method, &Control::grab_focus).call_deferred();
callable_mp((Control *)dst_method, &Control::grab_focus).call_deferred(false);
callable_mp(dst_method, &LineEdit::select_all).call_deferred();
}

Expand Down
2 changes: 1 addition & 1 deletion editor/scene/scene_create_dialog.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ void SceneCreateDialog::config(const String &p_dir) {
directory = p_dir;
root_name_edit->set_text("");
scene_name_edit->set_text("");
callable_mp((Control *)scene_name_edit, &Control::grab_focus).call_deferred();
callable_mp((Control *)scene_name_edit, &Control::grab_focus).call_deferred(false);
validation_panel->update();

Ref<EditorFeatureProfile> profile = EditorFeatureProfileManager::get_singleton()->get_current_profile();
Expand Down
2 changes: 1 addition & 1 deletion editor/scene/scene_tree_editor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2274,7 +2274,7 @@ void SceneTreeDialog::_notification(int p_what) {
tree->update_tree();

// Select the search bar by default.
callable_mp((Control *)filter, &Control::grab_focus).call_deferred();
callable_mp((Control *)filter, &Control::grab_focus).call_deferred(false);
}
} break;

Expand Down
6 changes: 3 additions & 3 deletions editor/script/find_in_files.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -467,16 +467,16 @@ void FindInFilesDialog::set_search_text(const String &text) {
_search_text_line_edit->set_text(text);
_on_search_text_modified(text);
}
callable_mp((Control *)_search_text_line_edit, &Control::grab_focus).call_deferred();
callable_mp((Control *)_search_text_line_edit, &Control::grab_focus).call_deferred(false);
_search_text_line_edit->select_all();
} else if (_mode == REPLACE_MODE) {
if (!text.is_empty()) {
_search_text_line_edit->set_text(text);
callable_mp((Control *)_replace_text_line_edit, &Control::grab_focus).call_deferred();
callable_mp((Control *)_replace_text_line_edit, &Control::grab_focus).call_deferred(false);
_replace_text_line_edit->select_all();
_on_search_text_modified(text);
} else {
callable_mp((Control *)_search_text_line_edit, &Control::grab_focus).call_deferred();
callable_mp((Control *)_search_text_line_edit, &Control::grab_focus).call_deferred(false);
_search_text_line_edit->select_all();
}
}
Expand Down
12 changes: 6 additions & 6 deletions editor/script/script_text_editor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1717,27 +1717,27 @@ void ScriptTextEditor::_edit_option(int p_op) {
switch (p_op) {
case EDIT_UNDO: {
tx->undo();
callable_mp((Control *)tx, &Control::grab_focus).call_deferred();
callable_mp((Control *)tx, &Control::grab_focus).call_deferred(false);
} break;
case EDIT_REDO: {
tx->redo();
callable_mp((Control *)tx, &Control::grab_focus).call_deferred();
callable_mp((Control *)tx, &Control::grab_focus).call_deferred(false);
} break;
case EDIT_CUT: {
tx->cut();
callable_mp((Control *)tx, &Control::grab_focus).call_deferred();
callable_mp((Control *)tx, &Control::grab_focus).call_deferred(false);
} break;
case EDIT_COPY: {
tx->copy();
callable_mp((Control *)tx, &Control::grab_focus).call_deferred();
callable_mp((Control *)tx, &Control::grab_focus).call_deferred(false);
} break;
case EDIT_PASTE: {
tx->paste();
callable_mp((Control *)tx, &Control::grab_focus).call_deferred();
callable_mp((Control *)tx, &Control::grab_focus).call_deferred(false);
} break;
case EDIT_SELECT_ALL: {
tx->select_all();
callable_mp((Control *)tx, &Control::grab_focus).call_deferred();
callable_mp((Control *)tx, &Control::grab_focus).call_deferred(false);
} break;
case EDIT_MOVE_LINE_UP: {
code_editor->get_text_editor()->move_lines_up();
Expand Down
12 changes: 6 additions & 6 deletions editor/script/text_editor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -362,27 +362,27 @@ void TextEditor::_edit_option(int p_op) {
switch (p_op) {
case EDIT_UNDO: {
tx->undo();
callable_mp((Control *)tx, &Control::grab_focus).call_deferred();
callable_mp((Control *)tx, &Control::grab_focus).call_deferred(false);
} break;
case EDIT_REDO: {
tx->redo();
callable_mp((Control *)tx, &Control::grab_focus).call_deferred();
callable_mp((Control *)tx, &Control::grab_focus).call_deferred(false);
} break;
case EDIT_CUT: {
tx->cut();
callable_mp((Control *)tx, &Control::grab_focus).call_deferred();
callable_mp((Control *)tx, &Control::grab_focus).call_deferred(false);
} break;
case EDIT_COPY: {
tx->copy();
callable_mp((Control *)tx, &Control::grab_focus).call_deferred();
callable_mp((Control *)tx, &Control::grab_focus).call_deferred(false);
} break;
case EDIT_PASTE: {
tx->paste();
callable_mp((Control *)tx, &Control::grab_focus).call_deferred();
callable_mp((Control *)tx, &Control::grab_focus).call_deferred(false);
} break;
case EDIT_SELECT_ALL: {
tx->select_all();
callable_mp((Control *)tx, &Control::grab_focus).call_deferred();
callable_mp((Control *)tx, &Control::grab_focus).call_deferred(false);
} break;
case EDIT_MOVE_LINE_UP: {
code_editor->get_text_editor()->move_lines_up();
Expand Down
2 changes: 1 addition & 1 deletion editor/shader/text_shader_editor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -787,7 +787,7 @@ void TextShaderEditor::_menu_option(int p_option) {
} break;
}
if (p_option != SEARCH_FIND && p_option != SEARCH_REPLACE && p_option != SEARCH_GOTO_LINE) {
callable_mp((Control *)code_editor->get_text_editor(), &Control::grab_focus).call_deferred();
callable_mp((Control *)code_editor->get_text_editor(), &Control::grab_focus).call_deferred(false);
}
}

Expand Down
7 changes: 7 additions & 0 deletions misc/extension_api_validation/4.5-stable.expected
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,10 @@ should instead be used to justify these changes and describe how users should wo
Add new entries at the end of the file.

## Changes between 4.5-stable and 4.6-stable

GH-110250
---------
Validate extension JSON: JSON file: Field was added in a way that breaks compatibility 'classes/Control/methods/grab_focus': arguments
Validate extension JSON: JSON file: Field was added in a way that breaks compatibility 'classes/Control/methods/has_focus': arguments

Optional argument added. Compatibility methods registered.
Loading
Loading