WindowServer: Give windows a "background color" to use for missing parts.

When resizing a window, we often end up having to paint some part of it
without coverage in the current backing store. This patch makes those cases
look nicer by having a fallback background color for each window, passed
along with the CreateWindow client message.
This commit is contained in:
Andreas Kling 2019-04-10 14:29:47 +02:00
parent 30e2d62c38
commit d4818dd2dd
Notes: sideshowbarker 2024-07-19 14:46:33 +09:00
9 changed files with 30 additions and 2 deletions

View File

@ -88,6 +88,7 @@ int main(int argc, char** argv)
make_shell(ptm_fd);
auto* window = new GWindow;
window->set_background_color(Color::Black);
window->set_double_buffering_enabled(false);
window->set_should_exit_event_loop_on_close(true);

View File

@ -62,6 +62,7 @@ void GWindow::show()
request.window.modal = m_modal;
request.window.resizable = m_resizable;
request.window.opacity = m_opacity_when_windowless;
request.window.background_color = m_background_color.value();
request.window.size_increment = m_size_increment;
request.window.base_size = m_base_size;
request.window.type = (WSAPI_WindowType)m_window_type;

View File

@ -38,6 +38,9 @@ public:
String title() const;
void set_title(const String&);
Color background_color() const { return m_background_color; }
void set_background_color(Color color) { m_background_color = color; }
int x() const { return rect().x(); }
int y() const { return rect().y(); }
int width() const { return rect().width(); }
@ -123,6 +126,7 @@ private:
Vector<Rect> m_pending_paint_event_rects;
Size m_size_increment;
Size m_base_size;
Color m_background_color { Color::LightGray };
GWindowType m_window_type { GWindowType::Normal };
bool m_is_active { false };
bool m_should_exit_app_on_close { false };

View File

@ -221,6 +221,7 @@ struct WSAPI_ClientMessage {
float opacity;
WSAPI_Size base_size;
WSAPI_Size size_increment;
WSAPI_Color background_color;
} window;
struct {
WSAPI_Size size;

View File

@ -372,6 +372,7 @@ void WSClientConnection::handle_request(const WSAPICreateWindowRequest& request)
{
int window_id = m_next_window_id++;
auto window = make<WSWindow>(*this, request.window_type(), window_id, request.is_modal());
window->set_background_color(request.background_color());
window->set_has_alpha_channel(request.has_alpha_channel());
window->set_resizable(request.is_resizable());
window->set_title(request.title());

View File

@ -430,7 +430,7 @@ private:
class WSAPICreateWindowRequest : public WSAPIClientRequest {
public:
WSAPICreateWindowRequest(int client_id, const Rect& rect, const String& title, bool has_alpha_channel, bool modal, bool resizable, float opacity, const Size& base_size, const Size& size_increment, WSWindowType window_type)
WSAPICreateWindowRequest(int client_id, const Rect& rect, const String& title, bool has_alpha_channel, bool modal, bool resizable, float opacity, const Size& base_size, const Size& size_increment, WSWindowType window_type, Color background_color)
: WSAPIClientRequest(WSMessage::APICreateWindowRequest, client_id)
, m_rect(rect)
, m_title(title)
@ -441,6 +441,7 @@ public:
, m_size_increment(size_increment)
, m_base_size(base_size)
, m_window_type(window_type)
, m_background_color(background_color)
{
}
@ -453,6 +454,7 @@ public:
Size size_increment() const { return m_size_increment; }
Size base_size() const { return m_base_size; }
WSWindowType window_type() const { return m_window_type; }
Color background_color() const { return m_background_color; }
private:
Rect m_rect;
@ -464,6 +466,7 @@ private:
Size m_size_increment;
Size m_base_size;
WSWindowType m_window_type;
Color m_background_color;
};
class WSAPIDestroyWindowRequest : public WSAPIClientRequest {

View File

@ -303,7 +303,7 @@ void WSMessageLoop::on_receive_from_client(int client_id, const WSAPI_ClientMess
break;
case WSAPI_ClientMessage::Type::CreateWindow:
ASSERT(message.text_length < (ssize_t)sizeof(message.text));
post_message(client, make<WSAPICreateWindowRequest>(client_id, message.window.rect, String(message.text, message.text_length), message.window.has_alpha_channel, message.window.modal, message.window.resizable, message.window.opacity, message.window.base_size, message.window.size_increment, from_api(message.window.type)));
post_message(client, make<WSAPICreateWindowRequest>(client_id, message.window.rect, String(message.text, message.text_length), message.window.has_alpha_channel, message.window.modal, message.window.resizable, message.window.opacity, message.window.base_size, message.window.size_increment, from_api(message.window.type), Color::from_rgba(message.window.background_color)));
break;
case WSAPI_ClientMessage::Type::DestroyWindow:
post_message(client, make<WSAPIDestroyWindowRequest>(client_id, message.window_id));

View File

@ -19,6 +19,9 @@ public:
WSWindow(WSMessageReceiver&, WSWindowType);
virtual ~WSWindow() override;
Color background_color() const { return m_background_color; }
void set_background_color(Color color) { m_background_color = color; }
bool is_minimized() const { return m_minimized; }
void set_minimized(bool);
@ -153,4 +156,5 @@ private:
Retained<GraphicsBitmap> m_icon;
RetainPtr<WSCursor> m_override_cursor;
WSWindowFrame m_frame;
Color m_background_color { Color::LightGray };
};

View File

@ -819,7 +819,20 @@ void WSWindowManager::compose()
dirty_rect_in_window_coordinates.move_by(-window.position());
auto dst = window.position();
dst.move_by(dirty_rect_in_window_coordinates.location());
m_back_painter->fill_rect(window.rect(), window.background_color());
m_back_painter->blit(dst, *backing_store, dirty_rect_in_window_coordinates, window.opacity());
if (backing_store->width() < window.width()) {
Rect right_fill_rect { window.x() + backing_store->width(), window.y(), window.width() - backing_store->width(), window.height() };
m_back_painter->fill_rect(right_fill_rect, window.background_color());
}
if (backing_store->height() < window.height()) {
Rect bottom_fill_rect { window.x(), window.y() + backing_store->height(), window.width(), window.height() - backing_store->height() };
m_back_painter->fill_rect(bottom_fill_rect, window.background_color());
}
}
return IterationDecision::Continue;
});