diff --git a/Userland/Libraries/LibGUI/Window.cpp b/Userland/Libraries/LibGUI/Window.cpp index 6d88a8aa30..6acdd6f4ea 100644 --- a/Userland/Libraries/LibGUI/Window.cpp +++ b/Userland/Libraries/LibGUI/Window.cpp @@ -146,6 +146,7 @@ void Window::show() m_resizable, m_fullscreen, m_frameless, + m_forced_shadow, m_accessory, m_opacity_when_windowless, m_alpha_hit_threshold, @@ -927,6 +928,16 @@ void Window::set_frameless(bool frameless) 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 { if (!is_visible()) diff --git a/Userland/Libraries/LibGUI/Window.h b/Userland/Libraries/LibGUI/Window.h index e06b1033fc..bfbf518930 100644 --- a/Userland/Libraries/LibGUI/Window.h +++ b/Userland/Libraries/LibGUI/Window.h @@ -45,6 +45,8 @@ public: bool is_frameless() const { return m_frameless; } void set_frameless(bool); + void set_forced_shadow(bool); + bool is_resizable() const { return m_resizable; } void set_resizable(bool resizable) { m_resizable = resizable; } @@ -266,6 +268,7 @@ private: bool m_minimizable { true }; bool m_fullscreen { false }; bool m_frameless { false }; + bool m_forced_shadow { false }; bool m_layout_pending { false }; bool m_visible_for_timer_purposes { true }; bool m_visible { false }; diff --git a/Userland/Services/WindowServer/ClientConnection.cpp b/Userland/Services/WindowServer/ClientConnection.cpp index 19461657fa..4cfdfe8f1a 100644 --- a/Userland/Services/WindowServer/ClientConnection.cpp +++ b/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); } +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) { 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, 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 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 const& resize_aspect_ratio, i32 type, + String const& title, i32 parent_window_id, Gfx::IntRect const& launch_origin_rect) { Window* parent_window = nullptr; 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); + window->set_forced_shadow(forced_shadow); + if (!launch_origin_rect.is_empty()) window->start_launch_animation(launch_origin_rect); diff --git a/Userland/Services/WindowServer/ClientConnection.h b/Userland/Services/WindowServer/ClientConnection.h index 6214a3f696..536203049a 100644 --- a/Userland/Services/WindowServer/ClientConnection.h +++ b/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_separator(i32) 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&, Optional const&, i32, String const&, i32, Gfx::IntRect const&) override; virtual Messages::WindowServer::DestroyWindowResponse destroy_window(i32) override; @@ -123,6 +123,7 @@ private: virtual void move_window_to_front(i32) override; virtual void set_fullscreen(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_background_color(String const&) override; virtual void set_wallpaper_mode(String const&) override; diff --git a/Userland/Services/WindowServer/Window.h b/Userland/Services/WindowServer/Window.h index a6db32a04d..c7eff68385 100644 --- a/Userland/Services/WindowServer/Window.h +++ b/Userland/Services/WindowServer/Window.h @@ -114,6 +114,9 @@ public: void check_untile_due_to_resize(Gfx::IntRect const&); bool set_untiled(Optional 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; } void set_occluded(bool); @@ -390,6 +393,7 @@ private: bool m_modal { false }; bool m_minimizable { false }; bool m_frameless { false }; + bool m_forced_shadow { false }; bool m_resizable { false }; Optional m_resize_aspect_ratio {}; WindowMinimizedState m_minimized_state { WindowMinimizedState::None }; diff --git a/Userland/Services/WindowServer/WindowFrame.cpp b/Userland/Services/WindowServer/WindowFrame.cpp index ce223b9d00..15b6ba2e66 100644 --- a/Userland/Services/WindowServer/WindowFrame.cpp +++ b/Userland/Services/WindowServer/WindowFrame.cpp @@ -164,7 +164,7 @@ void WindowFrame::reload_config() MultiScaleBitmaps* WindowFrame::shadow_bitmap() const { - if (m_window.is_frameless()) + if (m_window.is_frameless() && !m_window.has_forced_shadow()) return nullptr; switch (m_window.type()) { case WindowType::Desktop: diff --git a/Userland/Services/WindowServer/WindowServer.ipc b/Userland/Services/WindowServer/WindowServer.ipc index ddad53ceca..002df1243e 100644 --- a/Userland/Services/WindowServer/WindowServer.ipc +++ b/Userland/Services/WindowServer/WindowServer.ipc @@ -38,6 +38,7 @@ endpoint WindowServer bool resizable, bool fullscreen, bool frameless, + bool forced_shadow, bool accessory, float opacity, float alpha_hit_threshold, @@ -89,6 +90,7 @@ endpoint WindowServer move_window_to_front(i32 window_id) =| set_fullscreen(i32 window_id, bool fullscreen) =| set_frameless(i32 window_id, bool frameless) =| + set_forced_shadow(i32 window_id, bool shadow) =| popup_menu(i32 menu_id, Gfx::IntPoint screen_position) =| dismiss_menu(i32 menu_id) =|