diff --git a/Base/res/icons/themes/Redmond/menu-shadow.png b/Base/res/icons/themes/Redmond/menu-shadow.png new file mode 100644 index 0000000000..aa9fb1cca6 Binary files /dev/null and b/Base/res/icons/themes/Redmond/menu-shadow.png differ diff --git a/Base/res/themes/Default.ini b/Base/res/themes/Default.ini index 8b2eabe594..fbf30e044f 100644 --- a/Base/res/themes/Default.ini +++ b/Base/res/themes/Default.ini @@ -73,5 +73,6 @@ TitleButtonWidth=15 TitleButtonHeight=15 [Paths] +MenuShadow=/res/icons/themes/Default/window-shadow.png +TooltipShadow=/res/icons/themes/Default/window-shadow.png WindowShadow=/res/icons/themes/Default/window-shadow.png - diff --git a/Base/res/themes/Redmond 2000.ini b/Base/res/themes/Redmond 2000.ini index cf028a713d..7cfa1cbc4f 100644 --- a/Base/res/themes/Redmond 2000.ini +++ b/Base/res/themes/Redmond 2000.ini @@ -68,4 +68,6 @@ TitleButtonWidth=17 TitleButtonHeight=15 [Paths] +MenuShadow=/res/icons/themes/Redmond/menu-shadow.png TitleButtonIcons=/res/icons/themes/Redmond/16x16/ +TooltipShadow=/res/icons/themes/Redmond/menu-shadow.png diff --git a/Userland/Libraries/LibGfx/Palette.h b/Userland/Libraries/LibGfx/Palette.h index efe64baf29..b775be85cf 100644 --- a/Userland/Libraries/LibGfx/Palette.h +++ b/Userland/Libraries/LibGfx/Palette.h @@ -141,6 +141,8 @@ public: String title_button_icons_path() const { return path(PathRole::TitleButtonIcons); } String window_shadow_path() const { return path(PathRole::WindowShadow); } + String menu_shadow_path() const { return path(PathRole::MenuShadow); } + String tooltip_shadow_path() const { return path(PathRole::TooltipShadow); } Color color(ColorRole role) const { return m_impl->color(role); } int metric(MetricRole role) const { return m_impl->metric(role); } diff --git a/Userland/Libraries/LibGfx/SystemTheme.cpp b/Userland/Libraries/LibGfx/SystemTheme.cpp index 635bea11f4..601e9b3dd0 100644 --- a/Userland/Libraries/LibGfx/SystemTheme.cpp +++ b/Userland/Libraries/LibGfx/SystemTheme.cpp @@ -119,6 +119,8 @@ Core::AnonymousBuffer load_system_theme(const String& path) } while (0) DO_PATH(TitleButtonIcons); + DO_PATH(MenuShadow); + DO_PATH(TooltipShadow); DO_PATH(WindowShadow); return buffer; diff --git a/Userland/Libraries/LibGfx/SystemTheme.h b/Userland/Libraries/LibGfx/SystemTheme.h index f12fc9b280..a34872c7a6 100644 --- a/Userland/Libraries/LibGfx/SystemTheme.h +++ b/Userland/Libraries/LibGfx/SystemTheme.h @@ -145,6 +145,8 @@ enum class PathRole { NoRole, TitleButtonIcons, WindowShadow, + MenuShadow, + TooltipShadow, __Count, }; diff --git a/Userland/Services/WindowServer/WindowFrame.cpp b/Userland/Services/WindowServer/WindowFrame.cpp index 85b13b554d..344b8ec528 100644 --- a/Userland/Services/WindowServer/WindowFrame.cpp +++ b/Userland/Services/WindowServer/WindowFrame.cpp @@ -56,12 +56,16 @@ static Gfx::Bitmap* s_minimize_icon; static Gfx::Bitmap* s_maximize_icon; static Gfx::Bitmap* s_restore_icon; static Gfx::Bitmap* s_close_icon; -static Gfx::Bitmap* s_window_shadow; static String s_last_title_button_icons_path; static int s_last_title_button_icons_scale; +static Gfx::Bitmap* s_window_shadow; +static Gfx::Bitmap* s_menu_shadow; +static Gfx::Bitmap* s_tooltip_shadow; static String s_last_window_shadow_path; +static String s_last_menu_shadow_path; +static String s_last_tooltip_shadow_path; static Gfx::IntRect frame_rect_for_window(Window& window, const Gfx::IntRect& rect) { @@ -111,6 +115,15 @@ void WindowFrame::set_button_icons() if (m_window.is_frameless()) return; + m_close_button->set_icon(*s_close_icon); + if (m_window.is_minimizable()) + m_minimize_button->set_icon(*s_minimize_icon); + if (m_window.is_resizable()) + m_maximize_button->set_icon(m_window.is_maximized() ? *s_restore_icon : *s_maximize_icon); +} + +void WindowFrame::reload_config() +{ String icons_path = WindowManager::the().palette().title_button_icons_path(); int icons_scale = WindowManager::the().compositor_icon_scale(); @@ -152,30 +165,34 @@ void WindowFrame::set_button_icons() full_path.clear(); } - m_close_button->set_icon(*s_close_icon); - if (m_window.is_minimizable()) - m_minimize_button->set_icon(*s_minimize_icon); - if (m_window.is_resizable()) - m_maximize_button->set_icon(m_window.is_maximized() ? *s_restore_icon : *s_maximize_icon); - s_last_title_button_icons_path = icons_path; s_last_title_button_icons_scale = icons_scale; - String window_shadow_path = WindowManager::the().palette().window_shadow_path(); - if (!s_window_shadow || s_window_shadow->scale() != icons_scale || s_last_window_shadow_path != window_shadow_path) { - s_window_shadow = Gfx::Bitmap::load_from_file(window_shadow_path, icons_scale).leak_ref(); - m_shadow_dirty = true; - } - s_last_window_shadow_path = window_shadow_path; + auto load_shadow = [](const String& path, String& last_path, Gfx::Bitmap*& shadow_bitmap) { + if (!shadow_bitmap || shadow_bitmap->scale() != s_last_title_button_icons_scale || last_path != path) { + shadow_bitmap = Gfx::Bitmap::load_from_file(path, s_last_title_button_icons_scale).leak_ref(); + last_path = path; + } + }; + load_shadow(WindowManager::the().palette().window_shadow_path(), s_last_window_shadow_path, s_window_shadow); + load_shadow(WindowManager::the().palette().menu_shadow_path(), s_last_menu_shadow_path, s_menu_shadow); + load_shadow(WindowManager::the().palette().tooltip_shadow_path(), s_last_tooltip_shadow_path, s_tooltip_shadow); } Gfx::Bitmap* WindowFrame::window_shadow() const { if (m_window.is_frameless()) return nullptr; - if (m_window.type() == WindowType::Desktop) + switch (m_window.type()) { + case WindowType::Desktop: return nullptr; - return s_window_shadow; + case WindowType::Menu: + return s_menu_shadow; + case WindowType::Tooltip: + return s_tooltip_shadow; + default: + return s_window_shadow; + } } bool WindowFrame::frame_has_alpha() const diff --git a/Userland/Services/WindowServer/WindowFrame.h b/Userland/Services/WindowServer/WindowFrame.h index 28c38f04d2..5ced0521ee 100644 --- a/Userland/Services/WindowServer/WindowFrame.h +++ b/Userland/Services/WindowServer/WindowFrame.h @@ -41,6 +41,8 @@ class Window; class WindowFrame { public: + static void reload_config(); + WindowFrame(Window&); ~WindowFrame(); diff --git a/Userland/Services/WindowServer/WindowManager.cpp b/Userland/Services/WindowServer/WindowManager.cpp index 134715eac1..b555fdba7a 100644 --- a/Userland/Services/WindowServer/WindowManager.cpp +++ b/Userland/Services/WindowServer/WindowManager.cpp @@ -107,6 +107,8 @@ void WindowManager::reload_config() m_drag_cursor = get_cursor("Drag"); m_wait_cursor = get_cursor("Wait"); m_crosshair_cursor = get_cursor("Crosshair"); + + WindowFrame::reload_config(); } const Gfx::Font& WindowManager::font() const @@ -1434,6 +1436,7 @@ bool WindowManager::update_theme(String theme_path, String theme_name) m_palette = Gfx::PaletteImpl::create_with_anonymous_buffer(new_theme); Compositor::the().set_background_color(palette().desktop_background().to_string()); HashTable notified_clients; + WindowFrame::reload_config(); for_each_window([&](Window& window) { if (window.client()) { if (!notified_clients.contains(window.client())) { @@ -1523,9 +1526,10 @@ void WindowManager::reload_icon_bitmaps_after_scale_change(bool allow_hidpi_icon { m_allow_hidpi_icons = allow_hidpi_icons; reload_config(); + WindowFrame::reload_config(); for_each_window([&](Window& window) { auto& window_frame = window.frame(); - window_frame.set_button_icons(); + window_frame.theme_changed(); return IterationDecision::Continue; }); }