Просмотр исходного кода

WindowServer+LibGUI: Force full window repaints after theme change

We were not repainting windows that were occluded at the time of the
theme changing. This patch adds a way to bypass occlusion testing when
invalidating window rects.

Fixes #1249.
Andreas Kling 5 лет назад
Родитель
Сommit
eaa680ab8e

+ 10 - 3
Libraries/LibGUI/Window.cpp

@@ -341,7 +341,14 @@ bool Window::is_visible() const
 
 void Window::update()
 {
-    update({ 0, 0, width(), height() });
+    auto rect = this->rect();
+    update({ 0, 0, rect.width(), rect.height() });
+}
+
+void Window::force_update()
+{
+    auto rect = this->rect();
+    WindowServerConnection::the().post_message(Messages::WindowServer::InvalidateRect(m_window_id, { { 0, 0, rect.width(), rect.height() } }, true));
 }
 
 void Window::update(const Gfx::Rect& a_rect)
@@ -366,7 +373,7 @@ void Window::update(const Gfx::Rect& a_rect)
             Vector<Gfx::Rect> rects_to_send;
             for (auto& r : rects)
                 rects_to_send.append(r);
-            WindowServerConnection::the().post_message(Messages::WindowServer::InvalidateRect(m_window_id, rects_to_send));
+            WindowServerConnection::the().post_message(Messages::WindowServer::InvalidateRect(m_window_id, rects_to_send, false));
         });
     }
     m_pending_paint_event_rects.append(a_rect);
@@ -626,7 +633,7 @@ void Window::schedule_relayout()
 void Window::update_all_windows(Badge<WindowServerConnection>)
 {
     for (auto* window : *all_windows) {
-        window->update();
+        window->force_update();
     }
 }
 

+ 1 - 0
Libraries/LibGUI/Window.h

@@ -182,6 +182,7 @@ private:
     NonnullRefPtr<Gfx::Bitmap> create_shared_bitmap(Gfx::BitmapFormat, const Gfx::Size&);
     void set_current_backing_bitmap(Gfx::Bitmap&, bool flush_immediately = false);
     void flip(const Vector<Gfx::Rect, 32>& dirty_rects);
+    void force_update();
 
     RefPtr<Gfx::Bitmap> m_front_bitmap;
     RefPtr<Gfx::Bitmap> m_back_bitmap;

+ 3 - 3
Servers/WindowServer/ClientConnection.cpp

@@ -465,10 +465,10 @@ OwnPtr<Messages::WindowServer::DestroyWindowResponse> ClientConnection::handle(c
     return make<Messages::WindowServer::DestroyWindowResponse>();
 }
 
-void ClientConnection::post_paint_message(Window& window)
+void ClientConnection::post_paint_message(Window& window, bool ignore_occlusion)
 {
     auto rect_set = window.take_pending_paint_rects();
-    if (window.is_minimized() || window.is_occluded())
+    if (window.is_minimized() || (!ignore_occlusion && window.is_occluded()))
         return;
 
     post_message(Messages::WindowClient::Paint(window.window_id(), window.size(), rect_set.rects()));
@@ -483,7 +483,7 @@ void ClientConnection::handle(const Messages::WindowServer::InvalidateRect& mess
     }
     auto& window = *(*it).value;
     for (int i = 0; i < message.rects().size(); ++i)
-        window.request_update(message.rects()[i].intersected({ {}, window.size() }));
+        window.request_update(message.rects()[i].intersected({ {}, window.size() }), message.ignore_occlusion());
 }
 
 void ClientConnection::handle(const Messages::WindowServer::DidFinishPainting& message)

+ 1 - 1
Servers/WindowServer/ClientConnection.h

@@ -62,7 +62,7 @@ public:
 
     void notify_about_new_screen_rect(const Gfx::Rect&);
     void notify_about_clipboard_contents_changed();
-    void post_paint_message(Window&);
+    void post_paint_message(Window&, bool ignore_occlusion = false);
 
     Menu* find_menu_by_id(int menu_id)
     {

+ 3 - 3
Servers/WindowServer/Window.cpp

@@ -317,11 +317,11 @@ void Window::set_default_icon()
     m_icon = default_window_icon();
 }
 
-void Window::request_update(const Gfx::Rect& rect)
+void Window::request_update(const Gfx::Rect& rect, bool ignore_occlusion)
 {
     if (m_pending_paint_rects.is_empty()) {
-        deferred_invoke([this](auto&) {
-            client()->post_paint_message(*this);
+        deferred_invoke([this, ignore_occlusion](auto&) {
+            client()->post_paint_message(*this, ignore_occlusion);
         });
     }
     m_pending_paint_rects.add(rect);

+ 1 - 1
Servers/WindowServer/Window.h

@@ -208,7 +208,7 @@ public:
     const Cursor* override_cursor() const { return m_override_cursor.ptr(); }
     void set_override_cursor(RefPtr<Cursor>&& cursor) { m_override_cursor = move(cursor); }
 
-    void request_update(const Gfx::Rect&);
+    void request_update(const Gfx::Rect&, bool ignore_occlusion = false);
     Gfx::DisjointRectSet take_pending_paint_rects() { return move(m_pending_paint_rects); }
 
     bool in_minimize_animation() const { return m_minimize_animation_step != -1; }

+ 1 - 1
Servers/WindowServer/WindowServer.ipc

@@ -51,7 +51,7 @@ endpoint WindowServer = 2
     SetWindowRect(i32 window_id, Gfx::Rect rect) => ()
     GetWindowRect(i32 window_id) => (Gfx::Rect rect)
 
-    InvalidateRect(i32 window_id, Vector<Gfx::Rect> rects) =|
+    InvalidateRect(i32 window_id, Vector<Gfx::Rect> rects, bool ignore_occlusion) =|
     DidFinishPainting(i32 window_id, Vector<Gfx::Rect> rects) =|
 
     SetGlobalCursorTracking(i32 window_id, bool enabled) => ()