1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-05-30 23:48:11 +00:00

Add basic z-order for Windows.

This commit is contained in:
Andreas Kling 2019-01-09 03:16:58 +01:00
parent baec8925a8
commit 723ff8c2ab
3 changed files with 31 additions and 11 deletions

View file

@ -4,11 +4,12 @@
#include "Rect.h" #include "Rect.h"
#include "GraphicsBitmap.h" #include "GraphicsBitmap.h"
#include <AK/AKString.h> #include <AK/AKString.h>
#include <AK/InlineLinkedList.h>
#include <AK/WeakPtr.h> #include <AK/WeakPtr.h>
class Widget; class Widget;
class Window final : public Object { class Window final : public Object, public InlineLinkedListNode<Window> {
public: public:
explicit Window(Object* parent = nullptr); explicit Window(Object* parent = nullptr);
virtual ~Window() override; virtual ~Window() override;
@ -55,6 +56,11 @@ public:
void did_paint(); 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: private:
String m_title; String m_title;
Rect m_rect; Rect m_rect;

View file

@ -60,7 +60,7 @@ WindowManager::~WindowManager()
void WindowManager::paintWindowFrames() void WindowManager::paintWindowFrames()
{ {
for (auto* window : m_windows) for (auto* window = m_windows_in_order.head(); window; window = window->next())
paintWindowFrame(*window); paintWindowFrame(*window);
} }
@ -123,20 +123,27 @@ void WindowManager::paintWindowFrame(Window& window)
void WindowManager::addWindow(Window& window) void WindowManager::addWindow(Window& window)
{ {
m_windows.set(&window); m_windows.set(&window);
m_windows_in_order.append(&window);
if (!activeWindow()) if (!activeWindow())
setActiveWindow(&window); setActiveWindow(&window);
} }
void WindowManager::move_to_front(Window& window)
{
m_windows_in_order.remove(&window);
m_windows_in_order.append(&window);
}
void WindowManager::repaint() void WindowManager::repaint()
{ {
handlePaintEvent(*make<PaintEvent>()); handlePaintEvent(*make<PaintEvent>());
} }
void WindowManager::did_paint(Window& window) void WindowManager::did_paint(Window&)
{ {
auto& framebuffer = FrameBufferSDL::the(); auto& framebuffer = FrameBufferSDL::the();
framebuffer.blit({ 0, 0 }, *m_rootWidget->backing()); 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()); ASSERT(window->backing());
framebuffer.blit(window->position(), *window->backing()); framebuffer.blit(window->position(), *window->backing());
} }
@ -149,6 +156,7 @@ void WindowManager::removeWindow(Window& window)
return; return;
m_windows.remove(&window); m_windows.remove(&window);
m_windows_in_order.remove(&window);
if (!activeWindow() && !m_windows.is_empty()) if (!activeWindow() && !m_windows.is_empty())
setActiveWindow(*m_windows.begin()); setActiveWindow(*m_windows.begin());
@ -200,7 +208,7 @@ void WindowManager::repaintAfterMove(const Rect& oldRect, const Rect& newRect)
m_rootWidget->repaint(oldRect); m_rootWidget->repaint(oldRect);
m_rootWidget->repaint(newRect); 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)) { if (outerRectForWindow(*window).intersects(oldRect) || outerRectForWindow(*window).intersects(newRect)) {
paintWindowFrame(*window); paintWindowFrame(*window);
window->repaint(); window->repaint();
@ -233,18 +241,21 @@ void WindowManager::processMouseEvent(MouseEvent& event)
} }
} }
// FIXME: Respect z-order of windows... for (auto* window = m_windows_in_order.head(); window; window = window->next()) {
for (auto* window : m_windows) {
if (titleBarRectForWindow(*window).contains(event.position())) { if (titleBarRectForWindow(*window).contains(event.position())) {
if (event.type() == Event::MouseDown) if (event.type() == Event::MouseDown) {
move_to_front(*window);
setActiveWindow(window); setActiveWindow(window);
}
handleTitleBarMouseEvent(*window, event); handleTitleBarMouseEvent(*window, event);
return; return;
} }
if (window->rect().contains(event.position())) { if (window->rect().contains(event.position())) {
if (event.type() == Event::MouseDown) if (event.type() == Event::MouseDown) {
move_to_front(*window);
setActiveWindow(window); setActiveWindow(window);
}
// FIXME: Re-use the existing event instead of crafting a new one? // 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()); auto localEvent = make<MouseEvent>(event.type(), event.x() - window->rect().x(), event.y() - window->rect().y(), event.button());
window->event(*localEvent); window->event(*localEvent);
@ -264,12 +275,12 @@ void WindowManager::handlePaintEvent(PaintEvent& event)
m_rootWidget->event(event); m_rootWidget->event(event);
paintWindowFrames(); paintWindowFrames();
for (auto* window : m_windows) for (auto* window = m_windows_in_order.head(); window; window = window->next())
window->event(event); window->event(event);
auto& framebuffer = FrameBufferSDL::the(); auto& framebuffer = FrameBufferSDL::the();
framebuffer.blit({ 0, 0 }, *m_rootWidget->backing()); 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()); ASSERT(window->backing());
framebuffer.blit(window->position(), *window->backing()); framebuffer.blit(window->position(), *window->backing());
} }

View file

@ -4,6 +4,7 @@
#include "Rect.h" #include "Rect.h"
#include "Color.h" #include "Color.h"
#include <AK/HashTable.h> #include <AK/HashTable.h>
#include <AK/InlineLinkedList.h>
#include <AK/WeakPtr.h> #include <AK/WeakPtr.h>
class MouseEvent; class MouseEvent;
@ -32,6 +33,7 @@ public:
void did_paint(Window&); void did_paint(Window&);
void repaint(); void repaint();
void move_to_front(Window&);
private: private:
WindowManager(); WindowManager();
@ -52,6 +54,7 @@ private:
void paintWindowFrame(Window&); void paintWindowFrame(Window&);
HashTable<Window*> m_windows; HashTable<Window*> m_windows;
InlineLinkedList<Window> m_windows_in_order;
Widget* m_rootWidget { nullptr }; Widget* m_rootWidget { nullptr };
WeakPtr<Window> m_activeWindow; WeakPtr<Window> m_activeWindow;