diff options
author | Andreas Kling <kling@serenityos.org> | 2020-10-30 10:58:27 +0100 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2020-10-30 17:03:28 +0100 |
commit | aef56159a84a3e88422f7e7ebc11fe145ffe9075 (patch) | |
tree | 1ac8a8f2c652a2c3f0f9e39ff247e98909a09619 | |
parent | 34014fa838cbc7e427ae00818fdf8f665f0e7801 (diff) | |
download | serenity-aef56159a84a3e88422f7e7ebc11fe145ffe9075.zip |
LibGUI: Add Widget focus policies
Every widget now has a GUI::FocusPolicy that determines how it can
receive focus:
- NoFocus: The widget is not focusable (default)
- TabFocus: The widget can be focused using the tab key.
- ClickFocus: The widget can be focused by clicking on it.
- StrongFocus: Both of the above.
For widgets that have a focus proxy, getting/setting the focus policy
will affect the proxy instead.
32 files changed, 64 insertions, 40 deletions
diff --git a/Applications/Browser/ConsoleWidget.cpp b/Applications/Browser/ConsoleWidget.cpp index 8de5adb6b4..52ced262b8 100644 --- a/Applications/Browser/ConsoleWidget.cpp +++ b/Applications/Browser/ConsoleWidget.cpp @@ -109,6 +109,8 @@ ConsoleWidget::ConsoleWidget() print_html(JS::MarkupGenerator::html_from_value(m_interpreter->vm().last_value())); }; + set_focus_proxy(m_input); + auto& clear_button = bottom_container.add<GUI::Button>(); clear_button.set_size_policy(GUI::SizePolicy::Fixed, GUI::SizePolicy::Fixed); clear_button.set_preferred_size(22, 22); @@ -165,8 +167,4 @@ void ConsoleWidget::clear_output() m_output_view->update(); } -void ConsoleWidget::focusin_event(GUI::FocusEvent&) -{ - m_input->set_focus(true); -} } diff --git a/Applications/Browser/ConsoleWidget.h b/Applications/Browser/ConsoleWidget.h index dc52ce57d7..813ceed2ed 100644 --- a/Applications/Browser/ConsoleWidget.h +++ b/Applications/Browser/ConsoleWidget.h @@ -47,9 +47,6 @@ public: private: ConsoleWidget(); - virtual bool accepts_focus() const override { return true; } - virtual void focusin_event(GUI::FocusEvent&) override; - RefPtr<GUI::TextBox> m_input; RefPtr<Web::InProcessWebView> m_output_view; RefPtr<Web::DOM::Element> m_output_container; diff --git a/Applications/FontEditor/GlyphMapWidget.cpp b/Applications/FontEditor/GlyphMapWidget.cpp index 9ec1355f4c..6d0561ad89 100644 --- a/Applications/FontEditor/GlyphMapWidget.cpp +++ b/Applications/FontEditor/GlyphMapWidget.cpp @@ -34,6 +34,7 @@ GlyphMapWidget::GlyphMapWidget(Gfx::Font& mutable_font) { m_glyph_count = mutable_font.glyph_count(); set_relative_rect({ 0, 0, preferred_width(), preferred_height() }); + set_focus_policy(GUI::FocusPolicy::StrongFocus); } GlyphMapWidget::~GlyphMapWidget() diff --git a/Applications/FontEditor/GlyphMapWidget.h b/Applications/FontEditor/GlyphMapWidget.h index e8583d1b6a..4c6243ef68 100644 --- a/Applications/FontEditor/GlyphMapWidget.h +++ b/Applications/FontEditor/GlyphMapWidget.h @@ -53,7 +53,6 @@ public: private: explicit GlyphMapWidget(Gfx::Font&); - virtual bool accepts_focus() const override { return true; } virtual void paint_event(GUI::PaintEvent&) override; virtual void mousedown_event(GUI::MouseEvent&) override; virtual void keydown_event(GUI::KeyEvent&) override; diff --git a/Applications/HexEditor/HexEditor.cpp b/Applications/HexEditor/HexEditor.cpp index 4876876441..3d96030e70 100644 --- a/Applications/HexEditor/HexEditor.cpp +++ b/Applications/HexEditor/HexEditor.cpp @@ -42,6 +42,7 @@ HexEditor::HexEditor() { + set_focus_policy(GUI::FocusPolicy::StrongFocus); set_scrollbars_enabled(true); set_font(Gfx::Font::default_fixed_width_font()); set_background_role(ColorRole::Base); diff --git a/Applications/HexEditor/HexEditor.h b/Applications/HexEditor/HexEditor.h index 32a5fa1a59..0fd0d169e3 100644 --- a/Applications/HexEditor/HexEditor.h +++ b/Applications/HexEditor/HexEditor.h @@ -74,7 +74,6 @@ protected: virtual void mouseup_event(GUI::MouseEvent&) override; virtual void mousemove_event(GUI::MouseEvent&) override; virtual void keydown_event(GUI::KeyEvent&) override; - virtual bool accepts_focus() const override { return true; } private: bool m_readonly { false }; diff --git a/Applications/Piano/SamplerWidget.cpp b/Applications/Piano/SamplerWidget.cpp index bb6fa5a31c..aeffcfefe2 100644 --- a/Applications/Piano/SamplerWidget.cpp +++ b/Applications/Piano/SamplerWidget.cpp @@ -105,7 +105,7 @@ SamplerWidget::SamplerWidget(TrackManager& track_manager) m_open_button = m_open_button_and_recorded_sample_name_container->add<GUI::Button>(); m_open_button->set_size_policy(GUI::SizePolicy::Fixed, GUI::SizePolicy::Fixed); m_open_button->set_preferred_size(24, 24); - m_open_button->set_focusable(false); + m_open_button->set_focus_policy(GUI::FocusPolicy::TabFocus); m_open_button->set_icon(Gfx::Bitmap::load_from_file("/res/icons/16x16/open.png")); m_open_button->on_click = [this](auto) { Optional<String> open_path = GUI::FilePicker::get_open_filepath(window()); diff --git a/Applications/PixelPaint/ImageEditor.cpp b/Applications/PixelPaint/ImageEditor.cpp index a265ce3f03..3f0bfb72b7 100644 --- a/Applications/PixelPaint/ImageEditor.cpp +++ b/Applications/PixelPaint/ImageEditor.cpp @@ -36,6 +36,7 @@ namespace PixelPaint { ImageEditor::ImageEditor() { + set_focus_policy(GUI::FocusPolicy::StrongFocus); } ImageEditor::~ImageEditor() diff --git a/Applications/PixelPaint/ImageEditor.h b/Applications/PixelPaint/ImageEditor.h index 4c9b7f8d75..4e343e5656 100644 --- a/Applications/PixelPaint/ImageEditor.h +++ b/Applications/PixelPaint/ImageEditor.h @@ -82,8 +82,6 @@ public: private: ImageEditor(); - virtual bool accepts_focus() const override { return true; } - virtual void paint_event(GUI::PaintEvent&) override; virtual void second_paint_event(GUI::PaintEvent&) override; virtual void mousedown_event(GUI::MouseEvent&) override; diff --git a/DevTools/HackStudio/FormWidget.cpp b/DevTools/HackStudio/FormWidget.cpp index d355d53324..a9924a6a2b 100644 --- a/DevTools/HackStudio/FormWidget.cpp +++ b/DevTools/HackStudio/FormWidget.cpp @@ -33,6 +33,7 @@ namespace HackStudio { FormWidget::FormWidget() { + set_focus_policy(GUI::FocusPolicy::StrongFocus); set_fill_with_background_color(true); set_relative_rect(5, 5, 400, 300); diff --git a/DevTools/HackStudio/FormWidget.h b/DevTools/HackStudio/FormWidget.h index 5867330b15..32f10109f1 100644 --- a/DevTools/HackStudio/FormWidget.h +++ b/DevTools/HackStudio/FormWidget.h @@ -46,8 +46,6 @@ public: int grid_size() const { return m_grid_size; } private: - virtual bool accepts_focus() const override { return true; } - virtual void paint_event(GUI::PaintEvent&) override; virtual void second_paint_event(GUI::PaintEvent&) override; virtual void mousedown_event(GUI::MouseEvent&) override; diff --git a/Libraries/LibGUI/AbstractButton.cpp b/Libraries/LibGUI/AbstractButton.cpp index 3829394b28..02e66e20b5 100644 --- a/Libraries/LibGUI/AbstractButton.cpp +++ b/Libraries/LibGUI/AbstractButton.cpp @@ -35,6 +35,7 @@ namespace GUI { AbstractButton::AbstractButton(const StringView& text) : m_text(text) { + set_focus_policy(GUI::FocusPolicy::StrongFocus); set_background_role(Gfx::ColorRole::Button); set_foreground_role(Gfx::ColorRole::ButtonText); diff --git a/Libraries/LibGUI/AbstractButton.h b/Libraries/LibGUI/AbstractButton.h index c5f7562a18..d4cd02b6bd 100644 --- a/Libraries/LibGUI/AbstractButton.h +++ b/Libraries/LibGUI/AbstractButton.h @@ -53,7 +53,6 @@ public: bool is_being_pressed() const { return m_being_pressed; } virtual void click(unsigned modifiers = 0) = 0; - virtual bool accepts_focus() const override { return true; } virtual bool is_uncheckable() const { return true; } int auto_repeat_interval() const { return m_auto_repeat_interval; } diff --git a/Libraries/LibGUI/AbstractView.cpp b/Libraries/LibGUI/AbstractView.cpp index 33b542d109..e6a169fcb7 100644 --- a/Libraries/LibGUI/AbstractView.cpp +++ b/Libraries/LibGUI/AbstractView.cpp @@ -43,6 +43,7 @@ AbstractView::AbstractView() : m_sort_order(SortOrder::Ascending) , m_selection(*this) { + set_focus_policy(GUI::FocusPolicy::StrongFocus); } AbstractView::~AbstractView() diff --git a/Libraries/LibGUI/AbstractView.h b/Libraries/LibGUI/AbstractView.h index 7e6fbabd47..2d0e6f16d0 100644 --- a/Libraries/LibGUI/AbstractView.h +++ b/Libraries/LibGUI/AbstractView.h @@ -87,7 +87,6 @@ public: bool is_multi_select() const { return m_multi_select; } void set_multi_select(bool); - virtual bool accepts_focus() const override { return true; } virtual void did_update_model(unsigned flags); virtual void did_update_selection(); diff --git a/Libraries/LibGUI/Button.cpp b/Libraries/LibGUI/Button.cpp index ea57a27c62..7809e908d3 100644 --- a/Libraries/LibGUI/Button.cpp +++ b/Libraries/LibGUI/Button.cpp @@ -38,6 +38,7 @@ namespace GUI { Button::Button(const StringView& text) : AbstractButton(text) { + set_focus_policy(GUI::FocusPolicy::StrongFocus); } Button::~Button() diff --git a/Libraries/LibGUI/Button.h b/Libraries/LibGUI/Button.h index 42b53abbdf..d1121a6465 100644 --- a/Libraries/LibGUI/Button.h +++ b/Libraries/LibGUI/Button.h @@ -58,11 +58,8 @@ public: void set_action(Action&); - virtual bool accepts_focus() const override { return m_focusable; } virtual bool is_uncheckable() const override; - void set_focusable(bool b) { m_focusable = b; } - protected: explicit Button(const StringView& text = {}); virtual void paint_event(PaintEvent&) override; @@ -72,7 +69,6 @@ private: Gfx::ButtonStyle m_button_style { Gfx::ButtonStyle::Normal }; Gfx::TextAlignment m_text_alignment { Gfx::TextAlignment::Center }; WeakPtr<Action> m_action; - bool m_focusable { true }; }; } diff --git a/Libraries/LibGUI/ComboBox.cpp b/Libraries/LibGUI/ComboBox.cpp index e9833ec9eb..bb7404a1b0 100644 --- a/Libraries/LibGUI/ComboBox.cpp +++ b/Libraries/LibGUI/ComboBox.cpp @@ -85,7 +85,7 @@ ComboBox::ComboBox() }; m_open_button = add<ControlBoxButton>(ControlBoxButton::DownArrow); - m_open_button->set_focusable(false); + m_open_button->set_focus_policy(GUI::FocusPolicy::NoFocus); m_open_button->on_click = [this](auto) { if (m_list_window->is_visible()) close(); diff --git a/Libraries/LibGUI/SpinBox.cpp b/Libraries/LibGUI/SpinBox.cpp index 69da78e293..e1d797f1bc 100644 --- a/Libraries/LibGUI/SpinBox.cpp +++ b/Libraries/LibGUI/SpinBox.cpp @@ -49,11 +49,11 @@ SpinBox::SpinBox() }; m_increment_button = add<ControlBoxButton>(ControlBoxButton::UpArrow); - m_increment_button->set_focusable(false); + m_increment_button->set_focus_policy(GUI::FocusPolicy::NoFocus); m_increment_button->on_click = [this](auto) { set_value(m_value + 1); }; m_increment_button->set_auto_repeat_interval(150); m_decrement_button = add<ControlBoxButton>(ControlBoxButton::DownArrow); - m_decrement_button->set_focusable(false); + m_decrement_button->set_focus_policy(GUI::FocusPolicy::NoFocus); m_decrement_button->on_click = [this](auto) { set_value(m_value - 1); }; m_decrement_button->set_auto_repeat_interval(150); } diff --git a/Libraries/LibGUI/TextEditor.cpp b/Libraries/LibGUI/TextEditor.cpp index e6d5123d7d..f1875f6ae2 100644 --- a/Libraries/LibGUI/TextEditor.cpp +++ b/Libraries/LibGUI/TextEditor.cpp @@ -56,6 +56,7 @@ TextEditor::TextEditor(Type type) { REGISTER_STRING_PROPERTY("text", text, set_text); + set_focus_policy(GUI::FocusPolicy::StrongFocus); set_accepts_emoji_input(true); set_override_cursor(Gfx::StandardCursor::IBeam); set_background_role(ColorRole::Base); diff --git a/Libraries/LibGUI/TextEditor.h b/Libraries/LibGUI/TextEditor.h index 519f0af3cd..1061655c9b 100644 --- a/Libraries/LibGUI/TextEditor.h +++ b/Libraries/LibGUI/TextEditor.h @@ -175,7 +175,6 @@ protected: virtual void focusin_event(FocusEvent&) override; virtual void focusout_event(FocusEvent&) override; virtual void timer_event(Core::TimerEvent&) override; - virtual bool accepts_focus() const override { return true; } virtual void enter_event(Core::Event&) override; virtual void leave_event(Core::Event&) override; virtual void context_menu_event(ContextMenuEvent&) override; diff --git a/Libraries/LibGUI/ToolBar.cpp b/Libraries/LibGUI/ToolBar.cpp index 9de9408c2b..f398da6d86 100644 --- a/Libraries/LibGUI/ToolBar.cpp +++ b/Libraries/LibGUI/ToolBar.cpp @@ -64,6 +64,7 @@ void ToolBar::add_action(Action& action) button.set_exclusive(true); button.set_action(*item->action); button.set_tooltip(item->action->text()); + button.set_focus_policy(FocusPolicy::TabFocus); if (item->action->icon()) button.set_icon(item->action->icon()); else diff --git a/Libraries/LibGUI/Widget.cpp b/Libraries/LibGUI/Widget.cpp index 7b090c8815..b3997db3c3 100644 --- a/Libraries/LibGUI/Widget.cpp +++ b/Libraries/LibGUI/Widget.cpp @@ -326,7 +326,7 @@ void Widget::handle_mouseup_event(MouseEvent& event) void Widget::handle_mousedown_event(MouseEvent& event) { - if (accepts_focus()) + if (((unsigned)focus_policy() & (unsigned)FocusPolicy::ClickFocus)) set_focus(true, FocusSource::Mouse); mousedown_event(event); if (event.button() == MouseButton::Right) { @@ -539,6 +539,20 @@ void Widget::set_focus_proxy(Widget* proxy) m_focus_proxy = nullptr; } +FocusPolicy Widget::focus_policy() const +{ + if (m_focus_proxy) + return m_focus_proxy->focus_policy(); + return m_focus_policy; +} + +void Widget::set_focus_policy(FocusPolicy policy) +{ + if (m_focus_proxy) + return m_focus_proxy->set_focus_policy(policy); + m_focus_policy = policy; +} + bool Widget::is_focused() const { if (m_focus_proxy) @@ -750,7 +764,7 @@ void Widget::set_updates_enabled(bool enabled) void Widget::focus_previous_widget(FocusSource source) { - auto focusable_widgets = window()->focusable_widgets(); + auto focusable_widgets = window()->focusable_widgets(source); for (int i = focusable_widgets.size() - 1; i >= 0; --i) { if (focusable_widgets[i] != this) continue; @@ -763,7 +777,7 @@ void Widget::focus_previous_widget(FocusSource source) void Widget::focus_next_widget(FocusSource source) { - auto focusable_widgets = window()->focusable_widgets(); + auto focusable_widgets = window()->focusable_widgets(source); for (size_t i = 0; i < focusable_widgets.size(); ++i) { if (focusable_widgets[i] != this) continue; diff --git a/Libraries/LibGUI/Widget.h b/Libraries/LibGUI/Widget.h index 0ffd0baca6..e494f6f81f 100644 --- a/Libraries/LibGUI/Widget.h +++ b/Libraries/LibGUI/Widget.h @@ -88,6 +88,13 @@ private: Function<NonnullRefPtr<Widget>()> m_factory; }; +enum class FocusPolicy { + NoFocus = 0, + TabFocus = 0x1, + ClickFocus = 0x2, + StrongFocus = TabFocus | ClickFocus, +}; + class Widget : public Core::Object { C_OBJECT(Widget) public: @@ -155,8 +162,6 @@ public: void update(); void update(const Gfx::IntRect&); - virtual bool accepts_focus() const { return false; } - bool is_focused() const; void set_focus(bool, FocusSource = FocusSource::Programmatic); @@ -164,6 +169,9 @@ public: const Widget* focus_proxy() const { return m_focus_proxy; } void set_focus_proxy(Widget*); + void set_focus_policy(FocusPolicy policy); + FocusPolicy focus_policy() const; + enum class ShouldRespectGreediness { No = 0, Yes }; struct HitTestResult { @@ -362,6 +370,7 @@ private: NonnullRefPtr<Gfx::PaletteImpl> m_palette; WeakPtr<Widget> m_focus_proxy; + FocusPolicy m_focus_policy { FocusPolicy::NoFocus }; Gfx::StandardCursor m_override_cursor { Gfx::StandardCursor::None }; }; diff --git a/Libraries/LibGUI/Window.cpp b/Libraries/LibGUI/Window.cpp index e71a939d69..7b8e6cd901 100644 --- a/Libraries/LibGUI/Window.cpp +++ b/Libraries/LibGUI/Window.cpp @@ -543,7 +543,7 @@ void Window::set_main_widget(Widget* widget) set_rect(new_window_rect); m_main_widget->set_relative_rect({ {}, new_window_rect.size() }); m_main_widget->set_window(this); - if (m_main_widget->accepts_focus()) + if (m_main_widget->focus_policy() != FocusPolicy::NoFocus) m_main_widget->set_focus(true); } update(); @@ -720,7 +720,7 @@ void Window::start_wm_resize() WindowServerConnection::the().post_message(Messages::WindowServer::WM_StartWindowResize(WindowServerConnection::the().my_client_id(), m_window_id)); } -Vector<Widget*> Window::focusable_widgets() const +Vector<Widget*> Window::focusable_widgets(FocusSource source) const { if (!m_main_widget) return {}; @@ -728,7 +728,20 @@ Vector<Widget*> Window::focusable_widgets() const Vector<Widget*> collected_widgets; Function<void(Widget&)> collect_focusable_widgets = [&](auto& widget) { - if (widget.accepts_focus()) + bool widget_accepts_focus = false; + switch (source) { + case FocusSource::Keyboard: + widget_accepts_focus = ((unsigned)widget.focus_policy() & (unsigned)FocusPolicy::TabFocus); + break; + case FocusSource::Mouse: + widget_accepts_focus = ((unsigned)widget.focus_policy() & (unsigned)FocusPolicy::ClickFocus); + break; + case FocusSource::Programmatic: + widget_accepts_focus = widget.focus_policy() != FocusPolicy::NoFocus; + break; + } + + if (widget_accepts_focus) collected_widgets.append(&widget); widget.for_each_child_widget([&](auto& child) { if (!child.is_visible()) @@ -853,7 +866,7 @@ void Window::set_resize_aspect_ratio(const Optional<Gfx::IntSize>& ratio) void Window::did_add_widget(Badge<Widget>, Widget& widget) { - if (!m_focused_widget && widget.accepts_focus()) + if (!m_focused_widget && widget.focus_policy() != FocusPolicy::NoFocus) set_focused_widget(&widget); } diff --git a/Libraries/LibGUI/Window.h b/Libraries/LibGUI/Window.h index ce9ca93554..8d0b80d069 100644 --- a/Libraries/LibGUI/Window.h +++ b/Libraries/LibGUI/Window.h @@ -175,7 +175,7 @@ public: void apply_icon(); const Gfx::Bitmap* icon() const { return m_icon.ptr(); } - Vector<Widget*> focusable_widgets() const; + Vector<Widget*> focusable_widgets(FocusSource) const; void schedule_relayout(); diff --git a/Libraries/LibVT/TerminalWidget.cpp b/Libraries/LibVT/TerminalWidget.cpp index 52623df22b..4a27091eaa 100644 --- a/Libraries/LibVT/TerminalWidget.cpp +++ b/Libraries/LibVT/TerminalWidget.cpp @@ -96,7 +96,7 @@ TerminalWidget::TerminalWidget(int ptm_fd, bool automatic_size_policy, RefPtr<Co , m_config(move(config)) { set_override_cursor(Gfx::StandardCursor::IBeam); - + set_focus_policy(GUI::FocusPolicy::StrongFocus); set_accepts_emoji_input(true); set_pty_master_fd(ptm_fd); m_cursor_blink_timer = add<Core::Timer>(); diff --git a/Libraries/LibVT/TerminalWidget.h b/Libraries/LibVT/TerminalWidget.h index cfd5de892b..3f83c50229 100644 --- a/Libraries/LibVT/TerminalWidget.h +++ b/Libraries/LibVT/TerminalWidget.h @@ -85,8 +85,6 @@ public: void paste(); void clear_including_history(); - virtual bool accepts_focus() const override { return true; } - Function<void(const StringView&)> on_title_change; Function<void()> on_command_exit; diff --git a/Libraries/LibWeb/InProcessWebView.cpp b/Libraries/LibWeb/InProcessWebView.cpp index 983e3bb024..15dd3eb155 100644 --- a/Libraries/LibWeb/InProcessWebView.cpp +++ b/Libraries/LibWeb/InProcessWebView.cpp @@ -68,6 +68,7 @@ InProcessWebView::InProcessWebView() { set_should_hide_unnecessary_scrollbars(true); set_background_role(ColorRole::Base); + set_focus_policy(GUI::FocusPolicy::StrongFocus); m_copy_action = GUI::CommonActions::make_copy_action([this](auto&) { GUI::Clipboard::the().set_plain_text(selected_text()); diff --git a/Libraries/LibWeb/InProcessWebView.h b/Libraries/LibWeb/InProcessWebView.h index 6122e79f6a..e84778a2a5 100644 --- a/Libraries/LibWeb/InProcessWebView.h +++ b/Libraries/LibWeb/InProcessWebView.h @@ -61,8 +61,6 @@ public: void set_should_show_line_box_borders(bool value) { m_should_show_line_box_borders = value; } - virtual bool accepts_focus() const override { return true; } - GUI::Action& select_all_action() { return *m_select_all_action; } GUI::Action& copy_action() { return *m_copy_action; } diff --git a/Libraries/LibWeb/OutOfProcessWebView.cpp b/Libraries/LibWeb/OutOfProcessWebView.cpp index ec62289ece..a8063092ac 100644 --- a/Libraries/LibWeb/OutOfProcessWebView.cpp +++ b/Libraries/LibWeb/OutOfProcessWebView.cpp @@ -40,6 +40,7 @@ namespace Web { OutOfProcessWebView::OutOfProcessWebView() { set_should_hide_unnecessary_scrollbars(true); + set_focus_policy(GUI::FocusPolicy::StrongFocus); m_client = WebContentClient::construct(*this); client().post_message(Messages::WebContentServer::UpdateSystemTheme(Gfx::current_system_theme_buffer_id())); } diff --git a/Libraries/LibWeb/OutOfProcessWebView.h b/Libraries/LibWeb/OutOfProcessWebView.h index 0633fd07f9..f610a40bdf 100644 --- a/Libraries/LibWeb/OutOfProcessWebView.h +++ b/Libraries/LibWeb/OutOfProcessWebView.h @@ -68,7 +68,6 @@ private: OutOfProcessWebView(); // ^Widget - virtual bool accepts_focus() const override { return true; } virtual void paint_event(GUI::PaintEvent&) override; virtual void resize_event(GUI::ResizeEvent&) override; virtual void mousedown_event(GUI::MouseEvent&) override; |