浏览代码

WindowServer: Move occlusion things from WindowManager to Compositor

Andreas Kling 5 年之前
父节点
当前提交
10699b347f

+ 69 - 2
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;
+    });
+}
+
 }

+ 5 - 0
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;

+ 5 - 70
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())

+ 0 - 5
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;

+ 2 - 1
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)