diff options
author | Andreas Kling <kling@serenityos.org> | 2020-05-19 19:02:15 +0200 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2020-05-20 08:31:46 +0200 |
commit | 10699b347fa4b1d5da958a78c7c4bced2b0d05c9 (patch) | |
tree | 21a0eddf11dffa98381810ad98d9ea2ae7e76551 | |
parent | db30a2549e75f5827efc67c20d338538e38ff427 (diff) | |
download | serenity-10699b347fa4b1d5da958a78c7c4bced2b0d05c9.zip |
WindowServer: Move occlusion things from WindowManager to Compositor
-rw-r--r-- | Services/WindowServer/Compositor.cpp | 71 | ||||
-rw-r--r-- | Services/WindowServer/Compositor.h | 5 | ||||
-rw-r--r-- | Services/WindowServer/WindowManager.cpp | 75 | ||||
-rw-r--r-- | Services/WindowServer/WindowManager.h | 5 | ||||
-rw-r--r-- | Services/WindowServer/WindowSwitcher.cpp | 3 |
5 files changed, 81 insertions, 78 deletions
diff --git a/Services/WindowServer/Compositor.cpp b/Services/WindowServer/Compositor.cpp index 6d5e53fd72..5422df145a 100644 --- a/Services/WindowServer/Compositor.cpp +++ b/Services/WindowServer/Compositor.cpp @@ -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; + }); +} + } diff --git a/Services/WindowServer/Compositor.h b/Services/WindowServer/Compositor.h index 99778d786c..2a0de5dd78 100644 --- a/Services/WindowServer/Compositor.h +++ b/Services/WindowServer/Compositor.h @@ -36,6 +36,7 @@ namespace WindowServer { class ClientConnection; class Cursor; +class Window; enum class WallpaperMode { Simple, @@ -69,6 +70,8 @@ public: void increment_display_link_count(Badge<ClientConnection>); void decrement_display_link_count(Badge<ClientConnection>); + void recompute_occlusions(); + private: Compositor(); void init_bitmaps(); @@ -79,6 +82,8 @@ private: void draw_menubar(); void run_animations(); void notify_display_links(); + bool any_opaque_window_contains_rect(const Gfx::Rect&); + bool any_opaque_window_above_this_one_contains_rect(const Window&, const Gfx::Rect&); RefPtr<Core::Timer> m_compose_timer; RefPtr<Core::Timer> m_immediate_compose_timer; diff --git a/Services/WindowServer/WindowManager.cpp b/Services/WindowServer/WindowManager.cpp index 392d2068af..500e026c58 100644 --- a/Services/WindowServer/WindowManager.cpp +++ b/Services/WindowServer/WindowManager.cpp @@ -186,7 +186,7 @@ void WindowManager::add_window(Window& window) if (m_switcher.is_visible() && window.type() != WindowType::WindowSwitcher) m_switcher.refresh(); - recompute_occlusions(); + Compositor::the().recompute_occlusions(); if (window.listens_to_wm_events()) { for_each_window([&](Window& other_window) { @@ -211,7 +211,7 @@ void WindowManager::move_to_front_and_make_active(Window& window) m_windows_in_order.remove(&window); m_windows_in_order.append(&window); - recompute_occlusions(); + Compositor::the().recompute_occlusions(); set_active_window(&window); @@ -236,7 +236,7 @@ void WindowManager::remove_window(Window& window) if (m_switcher.is_visible() && window.type() != WindowType::WindowSwitcher) m_switcher.refresh(); - recompute_occlusions(); + Compositor::the().recompute_occlusions(); for_each_window_listening_to_wm_events([&window](Window& listener) { if (!(listener.wm_event_mask() & WMEventMask::WindowRemovals)) @@ -330,31 +330,16 @@ void WindowManager::notify_rect_changed(Window& window, const Gfx::Rect& old_rec if (m_switcher.is_visible() && window.type() != WindowType::WindowSwitcher) m_switcher.refresh(); - recompute_occlusions(); + Compositor::the().recompute_occlusions(); tell_wm_listeners_window_rect_changed(window); MenuManager::the().refresh(); } -void WindowManager::recompute_occlusions() -{ - for_each_visible_window_from_back_to_front([&](Window& window) { - if (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; - }); -} - void WindowManager::notify_opacity_changed(Window&) { - recompute_occlusions(); + Compositor::the().recompute_occlusions(); } void WindowManager::notify_minimization_state_changed(Window& window) @@ -904,56 +889,6 @@ void WindowManager::clear_resize_candidate() m_resize_candidate = nullptr; } -bool WindowManager::any_opaque_window_contains_rect(const Gfx::Rect& rect) -{ - bool found_containing_window = false; - 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 WindowManager::any_opaque_window_above_this_one_contains_rect(const Window& a_window, const Gfx::Rect& rect) -{ - bool found_containing_window = false; - bool checking = false; - 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; -}; - Gfx::Rect WindowManager::menubar_rect() const { if (active_fullscreen_window()) diff --git a/Services/WindowServer/WindowManager.h b/Services/WindowServer/WindowManager.h index b577f0fafd..0a561ab157 100644 --- a/Services/WindowServer/WindowManager.h +++ b/Services/WindowServer/WindowManager.h @@ -152,9 +152,6 @@ public: void clear_resize_candidate(); ResizeDirection resize_direction_of_window(const Window&); - bool any_opaque_window_contains_rect(const Gfx::Rect&); - bool any_opaque_window_above_this_one_contains_rect(const Window&, const Gfx::Rect&); - void tell_wm_listeners_window_state_changed(Window&); void tell_wm_listeners_window_icon_changed(Window&); void tell_wm_listeners_window_rect_changed(Window&); @@ -204,8 +201,6 @@ private: void tell_wm_listener_about_window_rect(Window& listener, Window&); void pick_new_active_window(); - void recompute_occlusions(); - RefPtr<Cursor> m_arrow_cursor; RefPtr<Cursor> m_hand_cursor; RefPtr<Cursor> m_resize_horizontally_cursor; diff --git a/Services/WindowServer/WindowSwitcher.cpp b/Services/WindowServer/WindowSwitcher.cpp index 0bd1841171..8a214ee52b 100644 --- a/Services/WindowServer/WindowSwitcher.cpp +++ b/Services/WindowServer/WindowSwitcher.cpp @@ -27,6 +27,7 @@ #include <LibGfx/Bitmap.h> #include <LibGfx/Font.h> #include <LibGfx/StylePainter.h> +#include <WindowServer/Compositor.h> #include <WindowServer/Event.h> #include <WindowServer/Screen.h> #include <WindowServer/WindowManager.h> @@ -56,7 +57,7 @@ void WindowSwitcher::set_visible(bool visible) if (m_visible == visible) return; m_visible = visible; - WindowManager::the().recompute_occlusions(); + Compositor::the().recompute_occlusions(); if (m_switcher_window) m_switcher_window->set_visible(visible); if (!m_visible) |