1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-26 20:37:36 +00:00

Let userland retain the window backing store while drawing into it.

To start painting, call:
gui$get_window_backing_store()

Then finish up with:
gui$release_window_backing_store()

Process will retain the underlying GraphicsBitmap behind the scenes.
This fixes racing between the WindowServer and GUI clients.

This patch also adds a WSWindowLocker that is exactly what it sounds like.
This commit is contained in:
Andreas Kling 2019-01-24 23:40:12 +01:00
parent ccf3fc4618
commit 86eae0f8df
22 changed files with 244 additions and 102 deletions

View file

@ -18,12 +18,13 @@ GWidget::~GWidget()
{
}
void GWidget::set_relative_rect(const Rect& rect, bool should_update)
void GWidget::set_relative_rect(const Rect& rect)
{
if (rect == m_relative_rect)
return;
// FIXME: Make some kind of event loop driven ResizeEvent?
m_relative_rect = rect;
if (should_update)
update();
update();
}
void GWidget::repaint(const Rect& rect)
@ -147,10 +148,3 @@ void GWidget::set_font(RetainPtr<Font>&& font)
else
m_font = move(font);
}
GraphicsBitmap* GWidget::backing()
{
if (auto* w = window())
return w->backing();
return nullptr;
}

View file

@ -51,7 +51,7 @@ public:
virtual const char* class_name() const override { return "GWidget"; }
void set_relative_rect(const Rect&, bool should_update = true);
void set_relative_rect(const Rect&);
Color background_color() const { return m_background_color; }
Color foreground_color() const { return m_foreground_color; }
@ -84,8 +84,6 @@ public:
const Font& font() const { return *m_font; }
void set_font(RetainPtr<Font>&&);
GraphicsBitmap* backing();
private:
GWindow* m_window { nullptr };

View file

@ -39,14 +39,6 @@ GWindow::GWindow(GObject* parent)
exit(1);
}
GUI_WindowBackingStoreInfo backing;
int rc = gui_get_window_backing_store(m_window_id, &backing);
if (rc < 0) {
perror("gui_get_window_backing_store");
exit(1);
}
m_backing = GraphicsBitmap::create_wrapper(backing.size, backing.pixels);
windows().set(m_window_id, this);
}
@ -58,34 +50,16 @@ void GWindow::set_title(String&& title)
{
dbgprintf("GWindow::set_title \"%s\"\n", title.characters());
GUI_WindowParameters params;
int rc = gui_get_window_parameters(m_window_id, &params);
int rc = gui_set_window_title(m_window_id, title.characters(), title.length());
ASSERT(rc == 0);
strcpy(params.title, title.characters());;
rc = gui_set_window_parameters(m_window_id, &params);
ASSERT(rc == 0);
m_title = move(title);
}
void GWindow::set_rect(const Rect& rect)
void GWindow::set_rect(const Rect& a_rect)
{
// FIXME: This is a hack to fudge the race with WSWindowManager trying to display @ old rect.
sleep(10);
dbgprintf("GWindow::set_rect %d,%d %dx%d\n", m_rect.x(), m_rect.y(), m_rect.width(), m_rect.height());
GUI_WindowParameters params;
int rc = gui_get_window_parameters(m_window_id, &params);
dbgprintf("GWindow::set_rect! %d,%d %dx%d\n", a_rect.x(), a_rect.y(), a_rect.width(), a_rect.height());
GUI_Rect rect = a_rect;
int rc = gui_set_window_rect(m_window_id, &rect);
ASSERT(rc == 0);
params.rect = rect;
rc = gui_set_window_parameters(m_window_id, &params);
ASSERT(rc == 0);
m_rect = rect;
GUI_WindowBackingStoreInfo backing;
rc = gui_get_window_backing_store(m_window_id, &backing);
if (rc < 0) {
perror("gui_get_window_backing_store");
exit(1);
}
m_backing = GraphicsBitmap::create_wrapper(backing.size, backing.pixels);
}
void GWindow::event(GEvent& event)

View file

@ -16,20 +16,17 @@ public:
int window_id() const { return m_window_id; }
String title() const { return m_title; }
void set_title(String&&);
int x() const { return m_rect.x(); }
int y() const { return m_rect.y(); }
int width() const { return m_rect.width(); }
int height() const { return m_rect.height(); }
int x() const { return rect().x(); }
int y() const { return rect().y(); }
int width() const { return rect().width(); }
int height() const { return rect().height(); }
const Rect& rect() const { return m_rect; }
Rect rect() const;
void set_rect(const Rect&);
void set_rect_without_repaint(const Rect& rect) { m_rect = rect; }
Point position() const { return m_rect.location(); }
void set_position_without_repaint(const Point& position) { set_rect_without_repaint({ position.x(), position.y(), width(), height() }); }
Point position() const { return rect().location(); }
virtual void event(GEvent&) override;
@ -41,16 +38,11 @@ public:
const GWidget* main_widget() const { return m_main_widget; }
void set_main_widget(GWidget*);
GraphicsBitmap* backing() { return m_backing.ptr(); }
void show();
void update();
private:
String m_title;
Rect m_rect;
RetainPtr<GraphicsBitmap> m_backing;
int m_window_id { -1 };
GWidget* m_main_widget { nullptr };