From ddad7575a9d227b2bd19b6d840f545bfdd2b993d Mon Sep 17 00:00:00 2001 From: Andreas Kling Date: Fri, 30 Oct 2020 16:57:51 +0100 Subject: [PATCH] LibGUI: Improve automatic focus guessing somewhat When opening a new window, we'll now try to find a suitable widget for initial focus by picking the first available mouse-focusable one. Whenever you press the tab key in a window with no focused widget, we'll attempt to find a keyboard-focusable widget and give it focus. This should make all applications keyboard-interactive immediately without having to manually place focus with the mouse. --- Libraries/LibGUI/Window.cpp | 18 +++++++++++++++--- Libraries/LibGUI/Window.h | 1 + 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/Libraries/LibGUI/Window.cpp b/Libraries/LibGUI/Window.cpp index 7b8e6cd901..9ca5b352f2 100644 --- a/Libraries/LibGUI/Window.cpp +++ b/Libraries/LibGUI/Window.cpp @@ -356,6 +356,11 @@ void Window::handle_multi_paint_event(MultiPaintEvent& event) void Window::handle_key_event(KeyEvent& event) { + if (!m_focused_widget && event.type() == Event::KeyDown && event.key() == Key_Tab && !event.ctrl() && !event.alt() && !event.logo()) { + focus_a_widget_if_possible(FocusSource::Keyboard); + return; + } + if (m_focused_widget) return m_focused_widget->dispatch_event(event, this); if (m_main_widget) @@ -864,10 +869,10 @@ void Window::set_resize_aspect_ratio(const Optional& ratio) WindowServerConnection::the().send_sync(m_window_id, m_resize_aspect_ratio); } -void Window::did_add_widget(Badge, Widget& widget) +void Window::did_add_widget(Badge, Widget&) { - if (!m_focused_widget && widget.focus_policy() != FocusPolicy::NoFocus) - set_focused_widget(&widget); + if (!m_focused_widget) + focus_a_widget_if_possible(FocusSource::Mouse); } void Window::did_remove_widget(Badge, Widget& widget) @@ -907,4 +912,11 @@ void Window::update_cursor() WindowServerConnection::the().send_sync(m_window_id, (u32)m_effective_cursor); } +void Window::focus_a_widget_if_possible(FocusSource source) +{ + auto focusable_widgets = this->focusable_widgets(source); + if (!focusable_widgets.is_empty()) + set_focused_widget(focusable_widgets[0], source); +} + } diff --git a/Libraries/LibGUI/Window.h b/Libraries/LibGUI/Window.h index 8d0b80d069..93fec29e49 100644 --- a/Libraries/LibGUI/Window.h +++ b/Libraries/LibGUI/Window.h @@ -204,6 +204,7 @@ private: virtual bool is_window() const override final { return true; } void update_cursor(); + void focus_a_widget_if_possible(FocusSource); void handle_drop_event(DropEvent&); void handle_mouse_event(MouseEvent&);