1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-25 06:17:35 +00:00

WindowServer: Move occlusion things from WindowManager to Compositor

This commit is contained in:
Andreas Kling 2020-05-19 19:02:15 +02:00
parent db30a2549e
commit 10699b347f
5 changed files with 81 additions and 78 deletions

View file

@ -140,7 +140,7 @@ void Compositor::compose()
// Paint the wallpaper.
for (auto& dirty_rect : dirty_rects.rects()) {
if (wm.any_opaque_window_contains_rect(dirty_rect))
if (any_opaque_window_contains_rect(dirty_rect))
continue;
// FIXME: If the wallpaper is opaque, no need to fill with color!
m_back_painter->fill_rect(dirty_rect, background_color);
@ -172,7 +172,7 @@ void Compositor::compose()
m_back_painter->add_clip_rect(window.frame().rect());
RefPtr<Gfx::Bitmap> backing_store = window.backing_store();
for (auto& dirty_rect : dirty_rects.rects()) {
if (!window.is_fullscreen() && wm.any_opaque_window_above_this_one_contains_rect(window, dirty_rect))
if (!window.is_fullscreen() && any_opaque_window_above_this_one_contains_rect(window, dirty_rect))
continue;
Gfx::PainterStateSaver saver(*m_back_painter);
m_back_painter->add_clip_rect(dirty_rect);
@ -504,4 +504,71 @@ void Compositor::decrement_display_link_count(Badge<ClientConnection>)
m_display_link_notify_timer->stop();
}
bool Compositor::any_opaque_window_contains_rect(const Gfx::Rect& rect)
{
bool found_containing_window = false;
WindowManager::the().for_each_visible_window_from_back_to_front([&](Window& window) {
if (window.is_minimized())
return IterationDecision::Continue;
if (window.opacity() < 1.0f)
return IterationDecision::Continue;
if (window.has_alpha_channel()) {
// FIXME: Just because the window has an alpha channel doesn't mean it's not opaque.
// Maybe there's some way we could know this?
return IterationDecision::Continue;
}
if (window.frame().rect().contains(rect)) {
found_containing_window = true;
return IterationDecision::Break;
}
return IterationDecision::Continue;
});
return found_containing_window;
};
bool Compositor::any_opaque_window_above_this_one_contains_rect(const Window& a_window, const Gfx::Rect& rect)
{
bool found_containing_window = false;
bool checking = false;
WindowManager::the().for_each_visible_window_from_back_to_front([&](Window& window) {
if (&window == &a_window) {
checking = true;
return IterationDecision::Continue;
}
if (!checking)
return IterationDecision::Continue;
if (!window.is_visible())
return IterationDecision::Continue;
if (window.is_minimized())
return IterationDecision::Continue;
if (window.opacity() < 1.0f)
return IterationDecision::Continue;
if (window.has_alpha_channel())
return IterationDecision::Continue;
if (window.frame().rect().contains(rect)) {
found_containing_window = true;
return IterationDecision::Break;
}
return IterationDecision::Continue;
});
return found_containing_window;
};
void Compositor::recompute_occlusions()
{
auto& wm = WindowManager::the();
wm.for_each_visible_window_from_back_to_front([&](Window& window) {
if (wm.m_switcher.is_visible()) {
window.set_occluded(false);
} else {
if (any_opaque_window_above_this_one_contains_rect(window, window.frame().rect()))
window.set_occluded(true);
else
window.set_occluded(false);
}
return IterationDecision::Continue;
});
}
}