瀏覽代碼

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.
Andreas Kling 4 年之前
父節點
當前提交
ddad7575a9
共有 2 個文件被更改,包括 16 次插入3 次删除
  1. 15 3
      Libraries/LibGUI/Window.cpp
  2. 1 0
      Libraries/LibGUI/Window.h

+ 15 - 3
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<Gfx::IntSize>& ratio)
         WindowServerConnection::the().send_sync<Messages::WindowServer::SetWindowResizeAspectRatio>(m_window_id, m_resize_aspect_ratio);
 }
 
-void Window::did_add_widget(Badge<Widget>, Widget& widget)
+void Window::did_add_widget(Badge<Widget>, 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& widget)
@@ -907,4 +912,11 @@ void Window::update_cursor()
         WindowServerConnection::the().send_sync<Messages::WindowServer::SetWindowCursor>(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);
+}
+
 }

+ 1 - 0
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&);