From 2e8db6560fd8f91d3eafe9c59b38b8d3bcb09eea Mon Sep 17 00:00:00 2001 From: Andreas Kling Date: Fri, 1 Jan 2021 00:40:12 +0100 Subject: [PATCH] LibGUI: Transfer focus when checking exclusive button programmatically When calling set_checked(true) on an exclusive button, we will now transfer focus to the newly checked button if one of its now-unchecked siblings had focus before. This makes windows that place initial focus somewhere in a group of radio buttons look nicer when they show up, since focus will be on whichever radio button was pre-checked, which may not be the first one in the group. --- Libraries/LibGUI/AbstractButton.cpp | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/Libraries/LibGUI/AbstractButton.cpp b/Libraries/LibGUI/AbstractButton.cpp index a71ab20ce0..f2846cb78b 100644 --- a/Libraries/LibGUI/AbstractButton.cpp +++ b/Libraries/LibGUI/AbstractButton.cpp @@ -28,6 +28,7 @@ #include #include #include +#include #include namespace GUI { @@ -70,8 +71,13 @@ void AbstractButton::set_checked(bool checked) m_checked = checked; if (is_exclusive() && checked && parent_widget()) { + bool sibling_had_focus = false; parent_widget()->for_each_child_of_type([&](auto& sibling) { - if (!sibling.is_exclusive() || !sibling.is_checked()) + if (!sibling.is_exclusive()) + return IterationDecision::Continue; + if (window() && window()->focused_widget() == &sibling) + sibling_had_focus = true; + if (!sibling.is_checked()) return IterationDecision::Continue; sibling.m_checked = false; sibling.update(); @@ -80,6 +86,8 @@ void AbstractButton::set_checked(bool checked) return IterationDecision::Continue; }); m_checked = true; + if (sibling_had_focus) + set_focus(true); } update();