LibGUI+WindowServer: Mark minimized window backing stores as volatile

WindowServer will now send out a WindowStateChanged message to clients
when one of their windows is minimized.

This is then forwarded to the GWindow, which will try to mark its
underlying window backing store as volatile.

This allows the kernel to steal the memory used by minimized windows
in case it starts running low. Very cool! :^)
This commit is contained in:
Andreas Kling 2019-12-26 12:06:07 +01:00
parent 23591f2a95
commit 519cb80a96
Notes: sideshowbarker 2024-07-19 10:39:17 +09:00
6 changed files with 27 additions and 0 deletions

View file

@ -693,3 +693,18 @@ void GWindow::update_all_windows(Badge<GWindowServerConnection>)
window->update();
}
}
void GWindow::notify_state_changed(Badge<GWindowServerConnection>, bool minimized)
{
// When double buffering is enabled, minimization means we can mark the front bitmap volatile (in addition to the back bitmap.)
// When double buffering is disabled, there is only the back bitmap (which we can now mark volatile!)
RefPtr<GraphicsBitmap>& bitmap = m_double_buffering_enabled ? m_front_bitmap : m_back_bitmap;
if (!bitmap)
return;
if (minimized) {
bitmap->shared_buffer()->set_volatile();
} else {
if (!bitmap->shared_buffer()->set_nonvolatile())
bitmap = nullptr;
}
}

View file

@ -136,6 +136,7 @@ public:
void schedule_relayout();
static void update_all_windows(Badge<GWindowServerConnection>);
void notify_state_changed(Badge<GWindowServerConnection>, bool minimized);
protected:
GWindow(CObject* parent = nullptr);

View file

@ -295,3 +295,9 @@ void GWindowServerConnection::handle(const WindowClient::DragCancelled&)
{
GDragOperation::notify_cancelled({});
}
void GWindowServerConnection::handle(const WindowClient::WindowStateChanged& message)
{
if (auto* window = GWindow::from_window_id(message.window_id()))
window->notify_state_changed({}, message.minimized());
}

View file

@ -45,4 +45,5 @@ private:
virtual void handle(const WindowClient::DragAccepted&) override;
virtual void handle(const WindowClient::DragCancelled&) override;
virtual void handle(const WindowClient::UpdateSystemTheme&) override;
virtual void handle(const WindowClient::WindowStateChanged&) override;
};

View file

@ -434,6 +434,9 @@ void WSWindowManager::notify_minimization_state_changed(WSWindow& window)
{
tell_wm_listeners_window_state_changed(window);
if (window.client())
window.client()->post_message(WindowClient::WindowStateChanged(window.window_id(), window.is_minimized()));
if (window.is_active() && window.is_minimized())
pick_new_active_window();
}

View file

@ -12,6 +12,7 @@ endpoint WindowClient = 4
KeyUp(i32 window_id, u8 character, u32 key, u32 modifiers) =|
WindowActivated(i32 window_id) =|
WindowDeactivated(i32 window_id) =|
WindowStateChanged(i32 window_id, bool minimized) =|
WindowCloseRequest(i32 window_id) =|
WindowResized(i32 window_id, Rect old_rect, Rect new_rect) =|