diff options
author | Andreas Kling <kling@serenityos.org> | 2020-08-25 11:21:49 +0200 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2020-08-26 00:51:35 +0200 |
commit | af1655262482344c94aeb1666dd3172534c84c13 (patch) | |
tree | d44d658f7e710b10ba2689bd1e50eab441753638 | |
parent | 9ba3862ee94a4b76f71c86b75cb9a77f91f672bf (diff) | |
download | serenity-af1655262482344c94aeb1666dd3172534c84c13.zip |
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.
-rw-r--r-- | Libraries/LibGUI/Widget.cpp | 17 | ||||
-rw-r--r-- | Libraries/LibGUI/Widget.h | 6 |
2 files changed, 23 insertions, 0 deletions
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<Gfx::PaletteImpl> m_palette; + + WeakPtr<Widget> m_focus_proxy; }; inline Widget* Widget::parent_widget() |