diff options
-rw-r--r-- | Userland/Services/WindowServer/Window.cpp | 4 | ||||
-rw-r--r-- | Userland/Services/WindowServer/WindowFrame.cpp | 25 | ||||
-rw-r--r-- | Userland/Services/WindowServer/WindowFrame.h | 2 |
3 files changed, 19 insertions, 12 deletions
diff --git a/Userland/Services/WindowServer/Window.cpp b/Userland/Services/WindowServer/Window.cpp index 657605a803..2375061b96 100644 --- a/Userland/Services/WindowServer/Window.cpp +++ b/Userland/Services/WindowServer/Window.cpp @@ -139,7 +139,7 @@ void Window::set_rect(const Gfx::IntRect& rect) } invalidate(true, old_rect.size() != rect.size()); - m_frame.notify_window_rect_changed(old_rect, rect); // recomputes occlusions + m_frame.window_rect_changed(old_rect, rect); // recomputes occlusions } void Window::set_rect_without_repaint(const Gfx::IntRect& rect) @@ -159,7 +159,7 @@ void Window::set_rect_without_repaint(const Gfx::IntRect& rect) } invalidate(true, old_rect.size() != rect.size()); - m_frame.notify_window_rect_changed(old_rect, rect); // recomputes occlusions + m_frame.window_rect_changed(old_rect, rect); // recomputes occlusions } bool Window::apply_minimum_size(Gfx::IntRect& rect) diff --git a/Userland/Services/WindowServer/WindowFrame.cpp b/Userland/Services/WindowServer/WindowFrame.cpp index c2cec7ccba..f56b05e7d9 100644 --- a/Userland/Services/WindowServer/WindowFrame.cpp +++ b/Userland/Services/WindowServer/WindowFrame.cpp @@ -619,19 +619,26 @@ void WindowFrame::invalidate(Gfx::IntRect relative_rect) m_window.invalidate(relative_rect, true); } -void WindowFrame::notify_window_rect_changed(const Gfx::IntRect& old_rect, const Gfx::IntRect& new_rect) +void WindowFrame::window_rect_changed(const Gfx::IntRect& old_rect, const Gfx::IntRect& new_rect) { layout_buttons(); - auto old_frame_rect = inflated_for_shadow(frame_rect_for_window(m_window, old_rect)); - auto new_frame_rect = inflated_for_shadow(frame_rect_for_window(m_window, new_rect)); - if (old_frame_rect.size() != new_frame_rect.size()) - set_dirty(true); + auto new_frame_rect = constrained_render_rect_to_screen(frame_rect_for_window(m_window, new_rect)); + set_dirty(true); auto& compositor = Compositor::the(); - for (auto& dirty : old_frame_rect.shatter(new_frame_rect)) - compositor.invalidate_screen(dirty); - if (!m_window.is_opaque()) - compositor.invalidate_screen(new_frame_rect); + + { + // Invalidate the areas outside of the new rect. Use the last computed occlusions for this purpose + // as we can't reliably calculate the previous frame rect anymore. The window state (e.g. maximized + // or tiled) may affect the calculations and it may have already been changed by the time we get + // called here. + auto invalidate_opaque = m_window.opaque_rects().shatter(new_frame_rect); + for (auto& rect : invalidate_opaque.rects()) + compositor.invalidate_screen(rect); + auto invalidate_transparent = m_window.transparency_rects().shatter(new_frame_rect); + for (auto& rect : invalidate_transparent.rects()) + compositor.invalidate_screen(rect); + } compositor.invalidate_occlusions(); diff --git a/Userland/Services/WindowServer/WindowFrame.h b/Userland/Services/WindowServer/WindowFrame.h index b35143378b..457d34afb2 100644 --- a/Userland/Services/WindowServer/WindowFrame.h +++ b/Userland/Services/WindowServer/WindowFrame.h @@ -67,7 +67,7 @@ public: bool handle_titlebar_icon_mouse_event(MouseEvent const&); void handle_border_mouse_event(MouseEvent const&); - void notify_window_rect_changed(const Gfx::IntRect& old_rect, const Gfx::IntRect& new_rect); + void window_rect_changed(const Gfx::IntRect& old_rect, const Gfx::IntRect& new_rect); void invalidate_titlebar(); void invalidate(Gfx::IntRect relative_rect); void invalidate(); |