diff options
author | Andreas Kling <awesomekling@gmail.com> | 2019-04-10 14:29:47 +0200 |
---|---|---|
committer | Andreas Kling <awesomekling@gmail.com> | 2019-04-10 14:29:47 +0200 |
commit | d4818dd2dd21aa9189bb0ee87aff2660b1e22951 (patch) | |
tree | 643bb48aa5da1f24d320795d89a69cb7b072de74 | |
parent | 30e2d62c38b30e7023269b5334c7dd101610ca7f (diff) | |
download | serenity-d4818dd2dd21aa9189bb0ee87aff2660b1e22951.zip |
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.
-rw-r--r-- | Applications/Terminal/main.cpp | 1 | ||||
-rw-r--r-- | LibGUI/GWindow.cpp | 1 | ||||
-rw-r--r-- | LibGUI/GWindow.h | 4 | ||||
-rw-r--r-- | Servers/WindowServer/WSAPITypes.h | 1 | ||||
-rw-r--r-- | Servers/WindowServer/WSClientConnection.cpp | 1 | ||||
-rw-r--r-- | Servers/WindowServer/WSMessage.h | 5 | ||||
-rw-r--r-- | Servers/WindowServer/WSMessageLoop.cpp | 2 | ||||
-rw-r--r-- | Servers/WindowServer/WSWindow.h | 4 | ||||
-rw-r--r-- | Servers/WindowServer/WSWindowManager.cpp | 13 |
9 files changed, 30 insertions, 2 deletions
diff --git a/Applications/Terminal/main.cpp b/Applications/Terminal/main.cpp index 8cdd1b9039..466a88ad11 100644 --- a/Applications/Terminal/main.cpp +++ b/Applications/Terminal/main.cpp @@ -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); diff --git a/LibGUI/GWindow.cpp b/LibGUI/GWindow.cpp index 72a5b2fb16..59c5710cca 100644 --- a/LibGUI/GWindow.cpp +++ b/LibGUI/GWindow.cpp @@ -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; diff --git a/LibGUI/GWindow.h b/LibGUI/GWindow.h index 9504c32dc9..e7d8371059 100644 --- a/LibGUI/GWindow.h +++ b/LibGUI/GWindow.h @@ -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 }; diff --git a/Servers/WindowServer/WSAPITypes.h b/Servers/WindowServer/WSAPITypes.h index c47ad1e8b5..ef7e091fee 100644 --- a/Servers/WindowServer/WSAPITypes.h +++ b/Servers/WindowServer/WSAPITypes.h @@ -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; diff --git a/Servers/WindowServer/WSClientConnection.cpp b/Servers/WindowServer/WSClientConnection.cpp index ac9c8a5f1a..5ac96e59d7 100644 --- a/Servers/WindowServer/WSClientConnection.cpp +++ b/Servers/WindowServer/WSClientConnection.cpp @@ -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()); diff --git a/Servers/WindowServer/WSMessage.h b/Servers/WindowServer/WSMessage.h index 051e86bffa..4001ac55b8 100644 --- a/Servers/WindowServer/WSMessage.h +++ b/Servers/WindowServer/WSMessage.h @@ -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 { diff --git a/Servers/WindowServer/WSMessageLoop.cpp b/Servers/WindowServer/WSMessageLoop.cpp index d354eb5e1a..5c123becfa 100644 --- a/Servers/WindowServer/WSMessageLoop.cpp +++ b/Servers/WindowServer/WSMessageLoop.cpp @@ -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)); diff --git a/Servers/WindowServer/WSWindow.h b/Servers/WindowServer/WSWindow.h index d1f4f61504..fdcee8df6c 100644 --- a/Servers/WindowServer/WSWindow.h +++ b/Servers/WindowServer/WSWindow.h @@ -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 }; }; diff --git a/Servers/WindowServer/WSWindowManager.cpp b/Servers/WindowServer/WSWindowManager.cpp index 145f28bdda..b8daee1c6a 100644 --- a/Servers/WindowServer/WSWindowManager.cpp +++ b/Servers/WindowServer/WSWindowManager.cpp @@ -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; }); |