summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndreas Kling <awesomekling@gmail.com>2019-04-10 14:29:47 +0200
committerAndreas Kling <awesomekling@gmail.com>2019-04-10 14:29:47 +0200
commitd4818dd2dd21aa9189bb0ee87aff2660b1e22951 (patch)
tree643bb48aa5da1f24d320795d89a69cb7b072de74
parent30e2d62c38b30e7023269b5334c7dd101610ca7f (diff)
downloadserenity-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.cpp1
-rw-r--r--LibGUI/GWindow.cpp1
-rw-r--r--LibGUI/GWindow.h4
-rw-r--r--Servers/WindowServer/WSAPITypes.h1
-rw-r--r--Servers/WindowServer/WSClientConnection.cpp1
-rw-r--r--Servers/WindowServer/WSMessage.h5
-rw-r--r--Servers/WindowServer/WSMessageLoop.cpp2
-rw-r--r--Servers/WindowServer/WSWindow.h4
-rw-r--r--Servers/WindowServer/WSWindowManager.cpp13
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;
});