diff options
-rw-r--r-- | Widgets/Window.h | 8 | ||||
-rw-r--r-- | Widgets/WindowManager.cpp | 31 | ||||
-rw-r--r-- | Widgets/WindowManager.h | 3 |
3 files changed, 31 insertions, 11 deletions
diff --git a/Widgets/Window.h b/Widgets/Window.h index d81599e656..0c3658e052 100644 --- a/Widgets/Window.h +++ b/Widgets/Window.h @@ -4,11 +4,12 @@ #include "Rect.h" #include "GraphicsBitmap.h" #include <AK/AKString.h> +#include <AK/InlineLinkedList.h> #include <AK/WeakPtr.h> class Widget; -class Window final : public Object { +class Window final : public Object, public InlineLinkedListNode<Window> { public: explicit Window(Object* parent = nullptr); virtual ~Window() override; @@ -55,6 +56,11 @@ public: void did_paint(); + // For InlineLinkedList. + // FIXME: Maybe make a ListHashSet and then WindowManager can just use that. + Window* m_next { nullptr }; + Window* m_prev { nullptr }; + private: String m_title; Rect m_rect; diff --git a/Widgets/WindowManager.cpp b/Widgets/WindowManager.cpp index c17c6d5180..083c8578c6 100644 --- a/Widgets/WindowManager.cpp +++ b/Widgets/WindowManager.cpp @@ -60,7 +60,7 @@ WindowManager::~WindowManager() void WindowManager::paintWindowFrames() { - for (auto* window : m_windows) + for (auto* window = m_windows_in_order.head(); window; window = window->next()) paintWindowFrame(*window); } @@ -123,20 +123,27 @@ void WindowManager::paintWindowFrame(Window& window) void WindowManager::addWindow(Window& window) { m_windows.set(&window); + m_windows_in_order.append(&window); if (!activeWindow()) setActiveWindow(&window); } +void WindowManager::move_to_front(Window& window) +{ + m_windows_in_order.remove(&window); + m_windows_in_order.append(&window); +} + void WindowManager::repaint() { handlePaintEvent(*make<PaintEvent>()); } -void WindowManager::did_paint(Window& window) +void WindowManager::did_paint(Window&) { auto& framebuffer = FrameBufferSDL::the(); framebuffer.blit({ 0, 0 }, *m_rootWidget->backing()); - for (auto* window : m_windows) { + for (auto* window = m_windows_in_order.head(); window; window = window->next()) { ASSERT(window->backing()); framebuffer.blit(window->position(), *window->backing()); } @@ -149,6 +156,7 @@ void WindowManager::removeWindow(Window& window) return; m_windows.remove(&window); + m_windows_in_order.remove(&window); if (!activeWindow() && !m_windows.is_empty()) setActiveWindow(*m_windows.begin()); @@ -200,7 +208,7 @@ void WindowManager::repaintAfterMove(const Rect& oldRect, const Rect& newRect) m_rootWidget->repaint(oldRect); m_rootWidget->repaint(newRect); - for (auto* window : m_windows) { + for (auto* window = m_windows_in_order.head(); window; window = window->next()) { if (outerRectForWindow(*window).intersects(oldRect) || outerRectForWindow(*window).intersects(newRect)) { paintWindowFrame(*window); window->repaint(); @@ -233,18 +241,21 @@ void WindowManager::processMouseEvent(MouseEvent& event) } } - // FIXME: Respect z-order of windows... - for (auto* window : m_windows) { + for (auto* window = m_windows_in_order.head(); window; window = window->next()) { if (titleBarRectForWindow(*window).contains(event.position())) { - if (event.type() == Event::MouseDown) + if (event.type() == Event::MouseDown) { + move_to_front(*window); setActiveWindow(window); + } handleTitleBarMouseEvent(*window, event); return; } if (window->rect().contains(event.position())) { - if (event.type() == Event::MouseDown) + if (event.type() == Event::MouseDown) { + move_to_front(*window); setActiveWindow(window); + } // FIXME: Re-use the existing event instead of crafting a new one? auto localEvent = make<MouseEvent>(event.type(), event.x() - window->rect().x(), event.y() - window->rect().y(), event.button()); window->event(*localEvent); @@ -264,12 +275,12 @@ void WindowManager::handlePaintEvent(PaintEvent& event) m_rootWidget->event(event); paintWindowFrames(); - for (auto* window : m_windows) + for (auto* window = m_windows_in_order.head(); window; window = window->next()) window->event(event); auto& framebuffer = FrameBufferSDL::the(); framebuffer.blit({ 0, 0 }, *m_rootWidget->backing()); - for (auto* window : m_windows) { + for (auto* window = m_windows_in_order.head(); window; window = window->next()) { ASSERT(window->backing()); framebuffer.blit(window->position(), *window->backing()); } diff --git a/Widgets/WindowManager.h b/Widgets/WindowManager.h index a20c8a464c..9b643f000c 100644 --- a/Widgets/WindowManager.h +++ b/Widgets/WindowManager.h @@ -4,6 +4,7 @@ #include "Rect.h" #include "Color.h" #include <AK/HashTable.h> +#include <AK/InlineLinkedList.h> #include <AK/WeakPtr.h> class MouseEvent; @@ -32,6 +33,7 @@ public: void did_paint(Window&); void repaint(); + void move_to_front(Window&); private: WindowManager(); @@ -52,6 +54,7 @@ private: void paintWindowFrame(Window&); HashTable<Window*> m_windows; + InlineLinkedList<Window> m_windows_in_order; Widget* m_rootWidget { nullptr }; WeakPtr<Window> m_activeWindow; |