From af1655262482344c94aeb1666dd3172534c84c13 Mon Sep 17 00:00:00 2001 From: Andreas Kling Date: Tue, 25 Aug 2020 11:21:49 +0200 Subject: [PATCH] LibGUI: Add Widget focus proxies A Widget can now have a focus proxy widget. Questions about focus are redirected to the proxy if present. This is useful if a widget could logically get focus, but wants one of its child widgets to actually handle it. --- Libraries/LibGUI/Widget.cpp | 17 +++++++++++++++++ Libraries/LibGUI/Widget.h | 6 ++++++ 2 files changed, 23 insertions(+) diff --git a/Libraries/LibGUI/Widget.cpp b/Libraries/LibGUI/Widget.cpp index 7da18926c6..2719acd92d 100644 --- a/Libraries/LibGUI/Widget.cpp +++ b/Libraries/LibGUI/Widget.cpp @@ -499,8 +499,22 @@ void Widget::set_window(Window* window) m_window = window; } +void Widget::set_focus_proxy(Widget* proxy) +{ + if (m_focus_proxy == proxy) + return; + + if (proxy) + m_focus_proxy = proxy->make_weak_ptr(); + else + m_focus_proxy = nullptr; +} + bool Widget::is_focused() const { + if (m_focus_proxy) + return m_focus_proxy->is_focused(); + auto* win = window(); if (!win) return false; @@ -514,6 +528,9 @@ bool Widget::is_focused() const void Widget::set_focus(bool focus, FocusSource source) { + if (m_focus_proxy) + return m_focus_proxy->set_focus(focus, source); + auto* win = window(); if (!win) return; diff --git a/Libraries/LibGUI/Widget.h b/Libraries/LibGUI/Widget.h index 76b86fa6b6..712c7e789d 100644 --- a/Libraries/LibGUI/Widget.h +++ b/Libraries/LibGUI/Widget.h @@ -150,6 +150,10 @@ public: bool is_focused() const; void set_focus(bool, FocusSource = FocusSource::Programmatic); + Widget* focus_proxy() { return m_focus_proxy; } + const Widget* focus_proxy() const { return m_focus_proxy; } + void set_focus_proxy(Widget*); + enum class ShouldRespectGreediness { No = 0, Yes }; struct HitTestResult { @@ -340,6 +344,8 @@ private: bool m_accepts_emoji_input { false }; NonnullRefPtr m_palette; + + WeakPtr m_focus_proxy; }; inline Widget* Widget::parent_widget()