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

Stop recomposing the window hierarchy after every dang widget paint.

This commit is contained in:
Andreas Kling 2019-01-09 04:46:16 +01:00
parent f3ec96a1b9
commit cfd76ade73
8 changed files with 34 additions and 41 deletions

View file

@ -21,8 +21,6 @@ Painter::Painter(Widget& widget)
Painter::~Painter() Painter::~Painter()
{ {
if (m_window)
m_window->did_paint();
} }
void Painter::fillRect(const Rect& rect, Color color) void Painter::fillRect(const Rect& rect, Color color)

View file

@ -8,7 +8,8 @@
RootWidget::RootWidget() RootWidget::RootWidget()
{ {
m_backing = GraphicsBitmap::create_wrapper(FrameBufferSDL::the().size(), (byte*)FrameBufferSDL::the().scanline(0)); setWindowRelativeRect(FrameBufferSDL::the().rect());
m_backing = GraphicsBitmap::create_wrapper(size(), (byte*)FrameBufferSDL::the().scanline(0));
} }
RootWidget::~RootWidget() RootWidget::~RootWidget()

View file

@ -19,16 +19,18 @@ Widget::~Widget()
{ {
} }
void Widget::setWindowRelativeRect(const Rect& rect) void Widget::setWindowRelativeRect(const Rect& rect, bool should_update)
{ {
// FIXME: Make some kind of event loop driven ResizeEvent? // FIXME: Make some kind of event loop driven ResizeEvent?
m_relativeRect = rect; m_relativeRect = rect;
update(); if (should_update)
update();
} }
void Widget::repaint(const Rect& rect) void Widget::repaint(const Rect& rect)
{ {
event(*make<PaintEvent>(rect)); if (auto* w = window())
w->repaint(rect);
} }
void Widget::event(Event& event) void Widget::event(Event& event)
@ -109,10 +111,13 @@ void Widget::mouseMoveEvent(MouseEvent&)
void Widget::update() void Widget::update()
{ {
auto* w = window();
if (!w)
return;
if (m_hasPendingPaintEvent) if (m_hasPendingPaintEvent)
return; return;
m_hasPendingPaintEvent = true; m_hasPendingPaintEvent = true;
EventLoop::main().postEvent(this, make<PaintEvent>(rect())); EventLoop::main().postEvent(w, make<PaintEvent>(rect()));
} }
Widget::HitTestResult Widget::hitTest(int x, int y) Widget::HitTestResult Widget::hitTest(int x, int y)

View file

@ -34,6 +34,7 @@ public:
int height() const { return m_relativeRect.height(); } int height() const { return m_relativeRect.height(); }
Rect rect() const { return { 0, 0, width(), height() }; } Rect rect() const { return { 0, 0, width(), height() }; }
Size size() const { return m_relativeRect.size(); }
void update(); void update();
void repaint(const Rect&); void repaint(const Rect&);
@ -50,7 +51,7 @@ public:
virtual const char* class_name() const override { return "Widget"; } virtual const char* class_name() const override { return "Widget"; }
void setWindowRelativeRect(const Rect&); void setWindowRelativeRect(const Rect&, bool should_update = true);
Color backgroundColor() const { return m_backgroundColor; } Color backgroundColor() const { return m_backgroundColor; }
Color foregroundColor() const { return m_foregroundColor; } Color foregroundColor() const { return m_foregroundColor; }

View file

@ -1,6 +1,7 @@
#include "Window.h" #include "Window.h"
#include "WindowManager.h" #include "WindowManager.h"
#include "Event.h" #include "Event.h"
#include "EventLoop.h"
#include "Widget.h" #include "Widget.h"
Window::Window(Object* parent) Window::Window(Object* parent)
@ -46,9 +47,14 @@ void Window::setRect(const Rect& rect)
WindowManager::the().notifyRectChanged(*this, oldRect, m_rect); WindowManager::the().notifyRectChanged(*this, oldRect, m_rect);
} }
void Window::repaint() void Window::repaint(const Rect& rect)
{ {
event(*make<PaintEvent>()); event(*make<PaintEvent>(rect));
}
void Window::update(const Rect& rect)
{
EventLoop::main().postEvent(this, make<PaintEvent>(rect));
} }
void Window::event(Event& event) void Window::event(Event& event)
@ -80,9 +86,11 @@ void Window::event(Event& event)
} }
if (m_mainWidget) { if (m_mainWidget) {
if (pe.rect().is_empty()) if (pe.rect().is_empty())
return m_mainWidget->event(*make<PaintEvent>(m_mainWidget->rect())); m_mainWidget->event(*make<PaintEvent>(m_mainWidget->rect()));
else else
return m_mainWidget->event(event); m_mainWidget->event(event);
WindowManager::the().did_paint(*this);
return;
} }
return Object::event(event); return Object::event(event);
} }

View file

@ -40,7 +40,8 @@ public:
bool isBeingDragged() const { return m_isBeingDragged; } bool isBeingDragged() const { return m_isBeingDragged; }
void setIsBeingDragged(bool b) { m_isBeingDragged = b; } void setIsBeingDragged(bool b) { m_isBeingDragged = b; }
void repaint(); void repaint(const Rect& = Rect());
void update(const Rect& = Rect());
bool isActive() const; bool isActive() const;

View file

@ -136,9 +136,10 @@ void WindowManager::repaint()
void WindowManager::did_paint(Window& window) void WindowManager::did_paint(Window& window)
{ {
auto& framebuffer = FrameBufferSDL::the(); auto& framebuffer = FrameBufferSDL::the();
if (m_windows_in_order.head() == &window) { if (m_windows_in_order.tail() == &window) {
ASSERT(window.backing()); ASSERT(window.backing());
framebuffer.blit(window.position(), *window.backing()); framebuffer.blit(window.position(), *window.backing());
printf("[WM] frontmost_only_compose_count: %u\n", ++m_frontmost_only_compose_count);
return; return;
} }
@ -167,7 +168,7 @@ void WindowManager::notifyTitleChanged(Window& window)
void WindowManager::notifyRectChanged(Window& window, const Rect& oldRect, const Rect& newRect) void WindowManager::notifyRectChanged(Window& window, const Rect& oldRect, const Rect& newRect)
{ {
printf("[WM] Window %p rect changed (%d,%d %dx%d) -> (%d,%d %dx%d)\n", &window, oldRect.x(), oldRect.y(), oldRect.width(), oldRect.height(), newRect.x(), newRect.y(), newRect.width(), newRect.height()); printf("[WM] Window %p rect changed (%d,%d %dx%d) -> (%d,%d %dx%d)\n", &window, oldRect.x(), oldRect.y(), oldRect.width(), oldRect.height(), newRect.x(), newRect.y(), newRect.width(), newRect.height());
repaintAfterMove(oldRect, newRect); recompose();
} }
void WindowManager::handleTitleBarMouseEvent(Window& window, MouseEvent& event) void WindowManager::handleTitleBarMouseEvent(Window& window, MouseEvent& event)
@ -190,28 +191,6 @@ void WindowManager::handleTitleBarMouseEvent(Window& window, MouseEvent& event)
#endif #endif
} }
void WindowManager::repaintAfterMove(const Rect& oldRect, const Rect& newRect)
{
printf("[WM] repaint: [%d,%d %dx%d] -> [%d,%d %dx%d]\n",
oldRect.x(),
oldRect.y(),
oldRect.width(),
oldRect.height(),
newRect.x(),
newRect.y(),
newRect.width(),
newRect.height());
m_rootWidget->repaint(oldRect);
m_rootWidget->repaint(newRect);
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();
}
}
}
void WindowManager::processMouseEvent(MouseEvent& event) void WindowManager::processMouseEvent(MouseEvent& event)
{ {
if (event.type() == Event::MouseUp) { if (event.type() == Event::MouseUp) {
@ -220,8 +199,7 @@ void WindowManager::processMouseEvent(MouseEvent& event)
m_dragWindow->setIsBeingDragged(false); m_dragWindow->setIsBeingDragged(false);
m_dragEndRect = outerRectForWindow(*m_dragWindow); m_dragEndRect = outerRectForWindow(*m_dragWindow);
m_dragWindow = nullptr; m_dragWindow = nullptr;
recompose();
repaintAfterMove(m_dragStartRect, m_dragEndRect);
return; return;
} }
} }
@ -281,7 +259,8 @@ void WindowManager::recompose()
{ {
printf("[WM] recompose_count: %u\n", ++m_recompose_count); printf("[WM] recompose_count: %u\n", ++m_recompose_count);
auto& framebuffer = FrameBufferSDL::the(); auto& framebuffer = FrameBufferSDL::the();
m_rootWidget->repaint(m_rootWidget->rect()); PaintEvent dummy_event(m_rootWidget->rect());
m_rootWidget->paintEvent(dummy_event);
for (auto* window = m_windows_in_order.head(); window; window = window->next()) { for (auto* window = m_windows_in_order.head(); window; window = window->next()) {
if (!window->backing()) if (!window->backing())
continue; continue;

View file

@ -41,7 +41,6 @@ private:
void processMouseEvent(MouseEvent&); void processMouseEvent(MouseEvent&);
void handleTitleBarMouseEvent(Window&, MouseEvent&); void handleTitleBarMouseEvent(Window&, MouseEvent&);
void handlePaintEvent(PaintEvent&); void handlePaintEvent(PaintEvent&);
void repaintAfterMove(const Rect& oldRect, const Rect& newRect);
virtual void event(Event&) override; virtual void event(Event&) override;
@ -68,4 +67,5 @@ private:
Rect m_dragEndRect; Rect m_dragEndRect;
unsigned m_recompose_count { 0 }; unsigned m_recompose_count { 0 };
unsigned m_frontmost_only_compose_count { 0 };
}; };