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:
parent
f3ec96a1b9
commit
cfd76ade73
8 changed files with 34 additions and 41 deletions
|
@ -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)
|
||||||
|
|
|
@ -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()
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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; }
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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 };
|
||||||
};
|
};
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue