mirror of
https://github.com/RGBCube/serenity
synced 2025-07-26 21:27:34 +00:00
Make it possible to invalidate only a portion of a window.
Use this in Terminal to only invalidate rows where anything changed.
This commit is contained in:
parent
9d7da26b4e
commit
dff70021ab
15 changed files with 91 additions and 15 deletions
|
@ -53,8 +53,15 @@ public:
|
|||
bool isKeyEvent() const { return m_type == KeyUp || m_type == KeyDown; }
|
||||
bool isPaintEvent() const { return m_type == Paint; }
|
||||
|
||||
Rect rect() const { return m_rect; }
|
||||
void set_rect(const GUI_Rect& rect)
|
||||
{
|
||||
m_rect = rect;
|
||||
}
|
||||
|
||||
private:
|
||||
Type m_type { Invalid };
|
||||
Rect m_rect;
|
||||
};
|
||||
|
||||
class PaintEvent final : public WSEvent {
|
||||
|
|
|
@ -83,7 +83,9 @@ void WSEventLoop::post_event(WSEventReceiver* receiver, OwnPtr<WSEvent>&& event)
|
|||
|
||||
if (event->type() == WSEvent::WM_Invalidate) {
|
||||
for (auto& queued_event : m_queued_events) {
|
||||
if (receiver == queued_event.receiver && queued_event.event->type() == WSEvent::WM_Invalidate) {
|
||||
if (receiver == queued_event.receiver
|
||||
&& queued_event.event->type() == WSEvent::WM_Invalidate
|
||||
&& (queued_event.event->rect().is_empty() || queued_event.event->rect().contains(event->rect()))) {
|
||||
#ifdef WSEVENTLOOP_DEBUG
|
||||
dbgprintf("Swallow WM_Invalidate\n");
|
||||
#endif
|
||||
|
|
|
@ -75,7 +75,7 @@ void WSWindow::event(WSEvent& event)
|
|||
gui_event.key.character = static_cast<KeyEvent&>(event).text()[0];
|
||||
break;
|
||||
case WSEvent::WM_Invalidate:
|
||||
WSWindowManager::the().invalidate(*this);
|
||||
WSWindowManager::the().invalidate(*this, event.rect());
|
||||
return;
|
||||
case WSEvent::WindowActivated:
|
||||
gui_event.type = GUI_Event::Type::WindowActivated;
|
||||
|
|
|
@ -412,6 +412,21 @@ void WSWindowManager::invalidate(const WSWindow& window)
|
|||
invalidate(outerRectForWindow(window.rect()));
|
||||
}
|
||||
|
||||
void WSWindowManager::invalidate(const WSWindow& window, const Rect& rect)
|
||||
{
|
||||
if (rect.is_empty()) {
|
||||
invalidate(window);
|
||||
return;
|
||||
}
|
||||
ASSERT_INTERRUPTS_ENABLED();
|
||||
LOCKER(m_lock);
|
||||
auto outer_rect = outerRectForWindow(window.rect());
|
||||
auto inner_rect = rect;
|
||||
inner_rect.move_by(window.position());
|
||||
inner_rect.intersect(outer_rect);
|
||||
invalidate(inner_rect);
|
||||
}
|
||||
|
||||
void WSWindowManager::flush(const Rect& a_rect)
|
||||
{
|
||||
auto rect = Rect::intersection(a_rect, m_screen_rect);
|
||||
|
|
|
@ -34,6 +34,7 @@ public:
|
|||
void draw_cursor();
|
||||
|
||||
void invalidate(const WSWindow&);
|
||||
void invalidate(const WSWindow&, const Rect&);
|
||||
void invalidate(const Rect&);
|
||||
void invalidate();
|
||||
void flush(const Rect&);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue