浏览代码

WindowServer+LibGUI: Add a way to force a window to have a drop shadow

Andreas Kling 4 年之前
父节点
当前提交
c2dfa9d54c

+ 11 - 0
Userland/Libraries/LibGUI/Window.cpp

@@ -146,6 +146,7 @@ void Window::show()
         m_resizable,
         m_resizable,
         m_fullscreen,
         m_fullscreen,
         m_frameless,
         m_frameless,
+        m_forced_shadow,
         m_accessory,
         m_accessory,
         m_opacity_when_windowless,
         m_opacity_when_windowless,
         m_alpha_hit_threshold,
         m_alpha_hit_threshold,
@@ -927,6 +928,16 @@ void Window::set_frameless(bool frameless)
         apply_icon();
         apply_icon();
 }
 }
 
 
+void Window::set_forced_shadow(bool shadow)
+{
+    if (m_forced_shadow == shadow)
+        return;
+    m_forced_shadow = shadow;
+    if (!is_visible())
+        return;
+    WindowServerConnection::the().async_set_forced_shadow(m_window_id, shadow);
+}
+
 bool Window::is_maximized() const
 bool Window::is_maximized() const
 {
 {
     if (!is_visible())
     if (!is_visible())

+ 3 - 0
Userland/Libraries/LibGUI/Window.h

@@ -45,6 +45,8 @@ public:
     bool is_frameless() const { return m_frameless; }
     bool is_frameless() const { return m_frameless; }
     void set_frameless(bool);
     void set_frameless(bool);
 
 
+    void set_forced_shadow(bool);
+
     bool is_resizable() const { return m_resizable; }
     bool is_resizable() const { return m_resizable; }
     void set_resizable(bool resizable) { m_resizable = resizable; }
     void set_resizable(bool resizable) { m_resizable = resizable; }
 
 
@@ -266,6 +268,7 @@ private:
     bool m_minimizable { true };
     bool m_minimizable { true };
     bool m_fullscreen { false };
     bool m_fullscreen { false };
     bool m_frameless { false };
     bool m_frameless { false };
+    bool m_forced_shadow { false };
     bool m_layout_pending { false };
     bool m_layout_pending { false };
     bool m_visible_for_timer_purposes { true };
     bool m_visible_for_timer_purposes { true };
     bool m_visible { false };
     bool m_visible { false };

+ 18 - 4
Userland/Services/WindowServer/ClientConnection.cpp

@@ -274,6 +274,18 @@ void ClientConnection::set_frameless(i32 window_id, bool frameless)
     WindowManager::the().tell_wms_window_state_changed(*it->value);
     WindowManager::the().tell_wms_window_state_changed(*it->value);
 }
 }
 
 
+void ClientConnection::set_forced_shadow(i32 window_id, bool shadow)
+{
+    auto it = m_windows.find(window_id);
+    if (it == m_windows.end()) {
+        did_misbehave("SetForcedShadow: Bad window ID");
+        return;
+    }
+    it->value->set_forced_shadow(shadow);
+    it->value->invalidate();
+    Compositor::the().invalidate_occlusions();
+}
+
 void ClientConnection::set_window_opacity(i32 window_id, float opacity)
 void ClientConnection::set_window_opacity(i32 window_id, float opacity)
 {
 {
     auto it = m_windows.find(window_id);
     auto it = m_windows.find(window_id);
@@ -510,10 +522,10 @@ Window* ClientConnection::window_from_id(i32 window_id)
 
 
 void ClientConnection::create_window(i32 window_id, Gfx::IntRect const& rect,
 void ClientConnection::create_window(i32 window_id, Gfx::IntRect const& rect,
     bool auto_position, bool has_alpha_channel, bool modal, bool minimizable, bool resizable,
     bool auto_position, bool has_alpha_channel, bool modal, bool minimizable, bool resizable,
-    bool fullscreen, bool frameless, bool accessory, float opacity, float alpha_hit_threshold,
-    Gfx::IntSize const& base_size, Gfx::IntSize const& size_increment, Gfx::IntSize const& minimum_size,
-    Optional<Gfx::IntSize> const& resize_aspect_ratio, i32 type, String const& title, i32 parent_window_id,
-    Gfx::IntRect const& launch_origin_rect)
+    bool fullscreen, bool frameless, bool forced_shadow, bool accessory, float opacity,
+    float alpha_hit_threshold, Gfx::IntSize const& base_size, Gfx::IntSize const& size_increment,
+    Gfx::IntSize const& minimum_size, Optional<Gfx::IntSize> const& resize_aspect_ratio, i32 type,
+    String const& title, i32 parent_window_id, Gfx::IntRect const& launch_origin_rect)
 {
 {
     Window* parent_window = nullptr;
     Window* parent_window = nullptr;
     if (parent_window_id) {
     if (parent_window_id) {
@@ -536,6 +548,8 @@ void ClientConnection::create_window(i32 window_id, Gfx::IntRect const& rect,
 
 
     auto window = Window::construct(*this, (WindowType)type, window_id, modal, minimizable, frameless, resizable, fullscreen, accessory, parent_window);
     auto window = Window::construct(*this, (WindowType)type, window_id, modal, minimizable, frameless, resizable, fullscreen, accessory, parent_window);
 
 
+    window->set_forced_shadow(forced_shadow);
+
     if (!launch_origin_rect.is_empty())
     if (!launch_origin_rect.is_empty())
         window->start_launch_animation(launch_origin_rect);
         window->start_launch_animation(launch_origin_rect);
 
 

+ 2 - 1
Userland/Services/WindowServer/ClientConnection.h

@@ -99,7 +99,7 @@ private:
     virtual void add_menu_item(i32, i32, i32, String const&, bool, bool, bool, bool, String const&, Gfx::ShareableBitmap const&, bool) override;
     virtual void add_menu_item(i32, i32, i32, String const&, bool, bool, bool, bool, String const&, Gfx::ShareableBitmap const&, bool) override;
     virtual void add_menu_separator(i32) override;
     virtual void add_menu_separator(i32) override;
     virtual void update_menu_item(i32, i32, i32, String const&, bool, bool, bool, bool, String const&) override;
     virtual void update_menu_item(i32, i32, i32, String const&, bool, bool, bool, bool, String const&) override;
-    virtual void create_window(i32, Gfx::IntRect const&, bool, bool, bool,
+    virtual void create_window(i32, Gfx::IntRect const&, bool, bool, bool, bool,
         bool, bool, bool, bool, bool, float, float, Gfx::IntSize const&, Gfx::IntSize const&, Gfx::IntSize const&,
         bool, bool, bool, bool, bool, float, float, Gfx::IntSize const&, Gfx::IntSize const&, Gfx::IntSize const&,
         Optional<Gfx::IntSize> const&, i32, String const&, i32, Gfx::IntRect const&) override;
         Optional<Gfx::IntSize> const&, i32, String const&, i32, Gfx::IntRect const&) override;
     virtual Messages::WindowServer::DestroyWindowResponse destroy_window(i32) override;
     virtual Messages::WindowServer::DestroyWindowResponse destroy_window(i32) override;
@@ -123,6 +123,7 @@ private:
     virtual void move_window_to_front(i32) override;
     virtual void move_window_to_front(i32) override;
     virtual void set_fullscreen(i32, bool) override;
     virtual void set_fullscreen(i32, bool) override;
     virtual void set_frameless(i32, bool) override;
     virtual void set_frameless(i32, bool) override;
+    virtual void set_forced_shadow(i32, bool) override;
     virtual void set_wallpaper(String const&) override;
     virtual void set_wallpaper(String const&) override;
     virtual void set_background_color(String const&) override;
     virtual void set_background_color(String const&) override;
     virtual void set_wallpaper_mode(String const&) override;
     virtual void set_wallpaper_mode(String const&) override;

+ 4 - 0
Userland/Services/WindowServer/Window.h

@@ -114,6 +114,9 @@ public:
     void check_untile_due_to_resize(Gfx::IntRect const&);
     void check_untile_due_to_resize(Gfx::IntRect const&);
     bool set_untiled(Optional<Gfx::IntPoint> fixed_point = {});
     bool set_untiled(Optional<Gfx::IntPoint> fixed_point = {});
 
 
+    void set_forced_shadow(bool b) { m_forced_shadow = b; }
+    bool has_forced_shadow() const { return m_forced_shadow; }
+
     bool is_occluded() const { return m_occluded; }
     bool is_occluded() const { return m_occluded; }
     void set_occluded(bool);
     void set_occluded(bool);
 
 
@@ -390,6 +393,7 @@ private:
     bool m_modal { false };
     bool m_modal { false };
     bool m_minimizable { false };
     bool m_minimizable { false };
     bool m_frameless { false };
     bool m_frameless { false };
+    bool m_forced_shadow { false };
     bool m_resizable { false };
     bool m_resizable { false };
     Optional<Gfx::IntSize> m_resize_aspect_ratio {};
     Optional<Gfx::IntSize> m_resize_aspect_ratio {};
     WindowMinimizedState m_minimized_state { WindowMinimizedState::None };
     WindowMinimizedState m_minimized_state { WindowMinimizedState::None };

+ 1 - 1
Userland/Services/WindowServer/WindowFrame.cpp

@@ -164,7 +164,7 @@ void WindowFrame::reload_config()
 
 
 MultiScaleBitmaps* WindowFrame::shadow_bitmap() const
 MultiScaleBitmaps* WindowFrame::shadow_bitmap() const
 {
 {
-    if (m_window.is_frameless())
+    if (m_window.is_frameless() && !m_window.has_forced_shadow())
         return nullptr;
         return nullptr;
     switch (m_window.type()) {
     switch (m_window.type()) {
     case WindowType::Desktop:
     case WindowType::Desktop:

+ 2 - 0
Userland/Services/WindowServer/WindowServer.ipc

@@ -38,6 +38,7 @@ endpoint WindowServer
         bool resizable,
         bool resizable,
         bool fullscreen,
         bool fullscreen,
         bool frameless,
         bool frameless,
+        bool forced_shadow,
         bool accessory,
         bool accessory,
         float opacity,
         float opacity,
         float alpha_hit_threshold,
         float alpha_hit_threshold,
@@ -89,6 +90,7 @@ endpoint WindowServer
     move_window_to_front(i32 window_id) =|
     move_window_to_front(i32 window_id) =|
     set_fullscreen(i32 window_id, bool fullscreen) =|
     set_fullscreen(i32 window_id, bool fullscreen) =|
     set_frameless(i32 window_id, bool frameless) =|
     set_frameless(i32 window_id, bool frameless) =|
+    set_forced_shadow(i32 window_id, bool shadow) =|
     popup_menu(i32 menu_id, Gfx::IntPoint screen_position) =|
     popup_menu(i32 menu_id, Gfx::IntPoint screen_position) =|
     dismiss_menu(i32 menu_id) =|
     dismiss_menu(i32 menu_id) =|