diff --git a/Widgets/Widget.cpp b/Widgets/Widget.cpp index e96f9690295..d007fe9d3fa 100644 --- a/Widgets/Widget.cpp +++ b/Widgets/Widget.cpp @@ -120,3 +120,16 @@ void Widget::setWindow(Window* window) return; m_window = window; } + +bool Widget::isFocused() const +{ + return m_window && m_window->focusedWidget() == this; +} + +void Widget::setFocus(bool focus) +{ + if (focus == isFocused()) + return; + if (m_window) + m_window->setFocusedWidget(this); +} diff --git a/Widgets/Widget.h b/Widgets/Widget.h index 804f3332ec7..5c2c09d6e4d 100644 --- a/Widgets/Widget.h +++ b/Widgets/Widget.h @@ -36,6 +36,9 @@ public: void update(); void repaint(const Rect&); + bool isFocused() const; + void setFocus(bool); + struct HitTestResult { Widget* widget { nullptr }; int localX { 0 }; diff --git a/Widgets/Window.cpp b/Widgets/Window.cpp index c3886f993b7..0926075bdb6 100644 --- a/Widgets/Window.cpp +++ b/Widgets/Window.cpp @@ -83,6 +83,12 @@ void Window::event(Event& event) return Object::event(event); } + if (event.isKeyEvent()) { + if (m_focusedWidget) + return m_focusedWidget->event(event); + return Object::event(event); + } + return Object::event(event); } @@ -91,3 +97,14 @@ bool Window::isActive() const return WindowManager::the().activeWindow() == this; } +void Window::setFocusedWidget(Widget* widget) +{ + if (m_focusedWidget.ptr() == widget) + return; + if (!widget) { + m_focusedWidget = nullptr; + return; + } + m_focusedWidget = widget->makeWeakPtr(); +} + diff --git a/Widgets/Window.h b/Widgets/Window.h index bfb49b36fb4..eb94390b927 100644 --- a/Widgets/Window.h +++ b/Widgets/Window.h @@ -1,8 +1,9 @@ #pragma once -#include #include "Object.h" #include "Rect.h" +#include +#include class Widget; @@ -39,10 +40,15 @@ public: bool isActive() const; + Widget* focusedWidget() { return m_focusedWidget.ptr(); } + void setFocusedWidget(Widget*); + private: String m_title; Rect m_rect; Widget* m_mainWidget { nullptr }; bool m_isBeingDragged { false }; + + WeakPtr m_focusedWidget; }; diff --git a/Widgets/WindowManager.cpp b/Widgets/WindowManager.cpp index a84cc810947..6e21c5c6466 100644 --- a/Widgets/WindowManager.cpp +++ b/Widgets/WindowManager.cpp @@ -254,9 +254,10 @@ void WindowManager::event(Event& event) return processMouseEvent(static_cast(event)); if (event.isKeyEvent()) { - // FIXME: Implement proper focus. - Widget* focusedWidget = g_tw; - return focusedWidget->event(event); + // FIXME: This is a good place to hook key events globally. :) + if (m_activeWindow) + return m_activeWindow->event(event); + return Object::event(event); } if (event.isPaintEvent()) diff --git a/Widgets/test.cpp b/Widgets/test.cpp index 02e7f9c2fb3..882f049b9f5 100644 --- a/Widgets/test.cpp +++ b/Widgets/test.cpp @@ -80,6 +80,7 @@ int main(int argc, char** argv) auto* t = new TerminalWidget(nullptr); win->setMainWidget(t); + t->setFocus(true); auto* clockWin = new Window; clockWin->setTitle("Clock");