Skip to content

Commit be421bc

Browse files
committed
Merge pull request godotengine#110250 from YeldhamDev/i_just_cant_keep_focused
Hide `Control` focus when given via mouse input
2 parents 50ba014 + aeb3a45 commit be421bc

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

53 files changed

+229
-105
lines changed

core/config/project_settings.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1675,6 +1675,7 @@ ProjectSettings::ProjectSettings() {
16751675
#endif
16761676

16771677
GLOBAL_DEF_BASIC("gui/common/snap_controls_to_pixels", true);
1678+
GLOBAL_DEF("gui/common/always_show_focus_state", false);
16781679
GLOBAL_DEF_BASIC("gui/fonts/dynamic_fonts/use_oversampling", true);
16791680

16801681
GLOBAL_DEF_RST(PropertyInfo(Variant::INT, "rendering/rendering_device/vsync/frame_queue_size", PROPERTY_HINT_RANGE, "2,3,1"), 2);

doc/classes/Control.xml

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
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.
1212
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.
1313
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.
14-
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.
14+
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].
1515
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.
1616
[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.
1717
[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.
@@ -618,15 +618,19 @@
618618
</method>
619619
<method name="grab_focus">
620620
<return type="void" />
621+
<param index="0" name="hide_focus" type="bool" default="false" />
621622
<description>
622623
Steal the focus from another control and become the focused control (see [member focus_mode]).
624+
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].
623625
[b]Note:[/b] Using this method together with [method Callable.call_deferred] makes it more reliable, especially when called inside [method Node._ready].
624626
</description>
625627
</method>
626628
<method name="has_focus" qualifiers="const">
627629
<return type="bool" />
630+
<param index="0" name="ignore_hidden_focus" type="bool" default="false" />
628631
<description>
629632
Returns [code]true[/code] if this is the current focused control. See [member focus_mode].
633+
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].
630634
</description>
631635
</method>
632636
<method name="has_theme_color" qualifiers="const">

doc/classes/ProjectSettings.xml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1177,6 +1177,9 @@
11771177
<member name="filesystem/import/fbx2gltf/enabled.web" type="bool" setter="" getter="" default="false">
11781178
Override for [member filesystem/import/fbx2gltf/enabled] on the Web where FBX2glTF can't easily be accessed from Godot.
11791179
</member>
1180+
<member name="gui/common/always_show_focus_state" type="bool" setter="" getter="" default="false">
1181+
If [code]true[/code], [Control]s will always show if they're focused, even if said focus was gained via mouse/touch input.
1182+
</member>
11801183
<member name="gui/common/default_scroll_deadzone" type="int" setter="" getter="" default="0">
11811184
Default value for [member ScrollContainer.scroll_deadzone], which will be used for all [ScrollContainer]s unless overridden.
11821185
</member>

editor/animation/animation_bezier_editor.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -303,7 +303,7 @@ void AnimationBezierTrackEdit::_notification(int p_what) {
303303
const int h_separation = get_theme_constant(SNAME("h_separation"), SNAME("AnimationBezierTrackEdit"));
304304
const int v_separation = get_theme_constant(SNAME("h_separation"), SNAME("AnimationBezierTrackEdit"));
305305

306-
if (has_focus()) {
306+
if (has_focus(true)) {
307307
draw_rect(Rect2(Point2(), get_size()), focus_color, false, Math::round(EDSCALE));
308308
}
309309

editor/animation/animation_blend_space_2d_editor.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -448,7 +448,7 @@ void AnimationNodeBlendSpace2DEditor::_blend_space_draw() {
448448

449449
Size2 s = blend_space_draw->get_size();
450450

451-
if (blend_space_draw->has_focus()) {
451+
if (blend_space_draw->has_focus(true)) {
452452
Color color = get_theme_color(SNAME("accent_color"), EditorStringName(Editor));
453453
blend_space_draw->draw_rect(Rect2(Point2(), s), color, false);
454454
}

editor/animation/animation_state_machine_editor.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -952,7 +952,7 @@ void AnimationNodeStateMachineEditor::_state_machine_draw() {
952952
travel_path = playback->get_travel_path();
953953
}
954954

955-
if (state_machine_draw->has_focus()) {
955+
if (state_machine_draw->has_focus(true)) {
956956
state_machine_draw->draw_rect(Rect2(Point2(), state_machine_draw->get_size()), theme_cache.focus_color, false);
957957
}
958958
int sep = 3 * EDSCALE;

editor/docks/filesystem_dock.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -775,13 +775,13 @@ void FileSystemDock::_navigate_to_path(const String &p_path, bool p_select_in_fa
775775
item = item->get_next();
776776
}
777777
if (p_grab_focus) {
778-
tree->grab_focus();
778+
tree->grab_focus(true);
779779
}
780780
} else {
781781
(*directory_ptr)->select(0);
782782
_update_file_list(false);
783783
if (p_grab_focus) {
784-
files->grab_focus();
784+
files->grab_focus(true);
785785
}
786786
}
787787
tree->ensure_cursor_is_visible();
@@ -1397,7 +1397,7 @@ void FileSystemDock::_update_history() {
13971397

13981398
if (tree->is_visible()) {
13991399
_update_tree(get_uncollapsed_paths());
1400-
tree->grab_focus();
1400+
tree->grab_focus(true);
14011401
}
14021402

14031403
if (file_list_vb->is_visible()) {
@@ -3537,7 +3537,7 @@ void FileSystemDock::_tree_rmb_select(const Vector2 &p_pos, MouseButton p_button
35373537
if (p_button != MouseButton::RIGHT) {
35383538
return;
35393539
}
3540-
tree->grab_focus();
3540+
tree->grab_focus(true);
35413541

35423542
// Right click is pressed in the tree.
35433543
Vector<String> paths = _tree_get_selected(false);

editor/docks/scene_tree_dock.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1553,7 +1553,7 @@ void SceneTreeDock::_tool_selected(int p_tool, bool p_confirm_override) {
15531553
editor_selection->clear();
15541554
editor_selection->add_node(new_node);
15551555

1556-
scene_tree->get_scene_tree()->grab_focus();
1556+
scene_tree->get_scene_tree()->grab_focus(true);
15571557
} break;
15581558

15591559
default: {
@@ -3146,7 +3146,7 @@ void SceneTreeDock::_create() {
31463146
undo_redo->commit_action();
31473147
}
31483148

3149-
scene_tree->get_scene_tree()->grab_focus();
3149+
scene_tree->get_scene_tree()->grab_focus(true);
31503150
}
31513151

31523152
void SceneTreeDock::replace_node(Node *p_node, Node *p_by_node) {

editor/gui/code_editor.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -599,10 +599,10 @@ void FindReplaceBar::_show_search(bool p_with_replace, bool p_show_only) {
599599

600600
if (focus_replace) {
601601
search_text->deselect();
602-
callable_mp((Control *)replace_text, &Control::grab_focus).call_deferred();
602+
callable_mp((Control *)replace_text, &Control::grab_focus).call_deferred(false);
603603
} else {
604604
replace_text->deselect();
605-
callable_mp((Control *)search_text, &Control::grab_focus).call_deferred();
605+
callable_mp((Control *)search_text, &Control::grab_focus).call_deferred(false);
606606
}
607607

608608
if (on_one_line) {

editor/gui/create_dialog.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -563,7 +563,7 @@ void CreateDialog::_notification(int p_what) {
563563

564564
case NOTIFICATION_VISIBILITY_CHANGED: {
565565
if (is_visible()) {
566-
callable_mp((Control *)search_box, &Control::grab_focus).call_deferred(); // Still not visible.
566+
callable_mp((Control *)search_box, &Control::grab_focus).call_deferred(false); // Still not visible.
567567
search_box->select_all();
568568
} else {
569569
EditorSettings::get_singleton()->set_project_metadata("dialog_bounds", "create_new_node", Rect2(get_position(), get_size()));

0 commit comments

Comments
 (0)