summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndreas Kling <kling@serenityos.org>2020-08-25 11:21:49 +0200
committerAndreas Kling <kling@serenityos.org>2020-08-26 00:51:35 +0200
commitaf1655262482344c94aeb1666dd3172534c84c13 (patch)
treed44d658f7e710b10ba2689bd1e50eab441753638
parent9ba3862ee94a4b76f71c86b75cb9a77f91f672bf (diff)
downloadserenity-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.cpp17
-rw-r--r--Libraries/LibGUI/Widget.h6
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()