From 040a723f1f75de0220abffa5aff085d3d2a45cd2 Mon Sep 17 00:00:00 2001 From: Maciej Zygmanowski Date: Sun, 1 Aug 2021 17:22:44 +0200 Subject: [PATCH] WindowServer: Add support for cursor themes Now you can specify a CursorTheme key in /etc/WindowServer.ini. The cursors are loaded from /res/cursor-themes/ directory. This directory contains a Config.ini file with format similar to previous Cursor section, except it uses relative paths. This commit adds also Default theme, which uses cursors being previously in /res/cursors. The WidgetGallery is updated to match the new cursor path format. --- Base/etc/WindowServer.ini | 19 +---- Base/res/cursor-themes/Default/Config.ini | 17 ++++ .../Default}/arrow.x2y2-2x.png | Bin .../Default}/arrow.x2y2.png | Bin .../Default}/crosshair-2x.png | Bin .../Default}/crosshair.png | Bin .../Default}/disallowed.png | Bin .../Default}/drag.png | Bin .../Default}/hand.x8y4.png | Bin .../Default}/help.x1y1.png | Bin .../Default}/hidden.png | Bin .../Default}/i-beam.png | Bin .../Default}/move-2x.png | Bin .../Default}/move.png | Bin .../Default}/resize-column-2x.png | Bin .../Default}/resize-column.png | Bin .../Default}/resize-diagonal-bltr-2x.png | Bin .../Default}/resize-diagonal-bltr.png | Bin .../Default}/resize-diagonal-tlbr-2x.png | Bin .../Default}/resize-diagonal-tlbr.png | Bin .../Default}/resize-horizontal-2x.png | Bin .../Default}/resize-horizontal.png | Bin .../Default}/resize-row-2x.png | Bin .../Default}/resize-row.png | Bin .../Default}/resize-vertical-2x.png | Bin .../Default}/resize-vertical.png | Bin .../Default}/wait.f14t100.png | Bin Userland/Demos/WidgetGallery/GalleryModels.h | 7 +- .../Services/WindowServer/WindowManager.cpp | 77 +++++++++++------- .../Services/WindowServer/WindowManager.h | 4 +- 30 files changed, 71 insertions(+), 53 deletions(-) create mode 100644 Base/res/cursor-themes/Default/Config.ini rename Base/res/{cursors => cursor-themes/Default}/arrow.x2y2-2x.png (100%) rename Base/res/{cursors => cursor-themes/Default}/arrow.x2y2.png (100%) rename Base/res/{cursors => cursor-themes/Default}/crosshair-2x.png (100%) rename Base/res/{cursors => cursor-themes/Default}/crosshair.png (100%) rename Base/res/{cursors => cursor-themes/Default}/disallowed.png (100%) rename Base/res/{cursors => cursor-themes/Default}/drag.png (100%) rename Base/res/{cursors => cursor-themes/Default}/hand.x8y4.png (100%) rename Base/res/{cursors => cursor-themes/Default}/help.x1y1.png (100%) rename Base/res/{cursors => cursor-themes/Default}/hidden.png (100%) rename Base/res/{cursors => cursor-themes/Default}/i-beam.png (100%) rename Base/res/{cursors => cursor-themes/Default}/move-2x.png (100%) rename Base/res/{cursors => cursor-themes/Default}/move.png (100%) rename Base/res/{cursors => cursor-themes/Default}/resize-column-2x.png (100%) rename Base/res/{cursors => cursor-themes/Default}/resize-column.png (100%) rename Base/res/{cursors => cursor-themes/Default}/resize-diagonal-bltr-2x.png (100%) rename Base/res/{cursors => cursor-themes/Default}/resize-diagonal-bltr.png (100%) rename Base/res/{cursors => cursor-themes/Default}/resize-diagonal-tlbr-2x.png (100%) rename Base/res/{cursors => cursor-themes/Default}/resize-diagonal-tlbr.png (100%) rename Base/res/{cursors => cursor-themes/Default}/resize-horizontal-2x.png (100%) rename Base/res/{cursors => cursor-themes/Default}/resize-horizontal.png (100%) rename Base/res/{cursors => cursor-themes/Default}/resize-row-2x.png (100%) rename Base/res/{cursors => cursor-themes/Default}/resize-row.png (100%) rename Base/res/{cursors => cursor-themes/Default}/resize-vertical-2x.png (100%) rename Base/res/{cursors => cursor-themes/Default}/resize-vertical.png (100%) rename Base/res/{cursors => cursor-themes/Default}/wait.f14t100.png (100%) diff --git a/Base/etc/WindowServer.ini b/Base/etc/WindowServer.ini index 6e846905e4..8963788f99 100644 --- a/Base/etc/WindowServer.ini +++ b/Base/etc/WindowServer.ini @@ -19,24 +19,7 @@ Name=Default [Mouse] AccelerationFactor=1.0 ScrollStepSize=4 - -[Cursor] -Hidden=/res/cursors/hidden.png -Arrow=/res/cursors/arrow.x2y2.png -ResizeH=/res/cursors/resize-horizontal.png -ResizeV=/res/cursors/resize-vertical.png -ResizeDTLBR=/res/cursors/resize-diagonal-tlbr.png -ResizeDBLTR=/res/cursors/resize-diagonal-bltr.png -ResizeColumn=/res/cursors/resize-column.png -ResizeRow=/res/cursors/resize-row.png -IBeam=/res/cursors/i-beam.png -Disallowed=/res/cursors/disallowed.png -Move=/res/cursors/move.png -Hand=/res/cursors/hand.x8y4.png -Help=/res/cursors/help.x1y1.png -Drag=/res/cursors/drag.png -Wait=/res/cursors/wait.f14t100.png -Crosshair=/res/cursors/crosshair.png +CursorTheme=Default [Graphics] OverlayRectShadow=/res/graphics/overlay-rect-shadow.png diff --git a/Base/res/cursor-themes/Default/Config.ini b/Base/res/cursor-themes/Default/Config.ini new file mode 100644 index 0000000000..fec44b14a7 --- /dev/null +++ b/Base/res/cursor-themes/Default/Config.ini @@ -0,0 +1,17 @@ +[Cursor] +Hidden=hidden.png +Arrow=arrow.x2y2.png +ResizeH=resize-horizontal.png +ResizeV=resize-vertical.png +ResizeDTLBR=resize-diagonal-tlbr.png +ResizeDBLTR=resize-diagonal-bltr.png +ResizeColumn=resize-column.png +ResizeRow=resize-row.png +IBeam=i-beam.png +Disallowed=disallowed.png +Move=move.png +Hand=hand.x8y4.png +Help=help.x1y1.png +Drag=drag.png +Wait=wait.f14t100.png +Crosshair=crosshair.png diff --git a/Base/res/cursors/arrow.x2y2-2x.png b/Base/res/cursor-themes/Default/arrow.x2y2-2x.png similarity index 100% rename from Base/res/cursors/arrow.x2y2-2x.png rename to Base/res/cursor-themes/Default/arrow.x2y2-2x.png diff --git a/Base/res/cursors/arrow.x2y2.png b/Base/res/cursor-themes/Default/arrow.x2y2.png similarity index 100% rename from Base/res/cursors/arrow.x2y2.png rename to Base/res/cursor-themes/Default/arrow.x2y2.png diff --git a/Base/res/cursors/crosshair-2x.png b/Base/res/cursor-themes/Default/crosshair-2x.png similarity index 100% rename from Base/res/cursors/crosshair-2x.png rename to Base/res/cursor-themes/Default/crosshair-2x.png diff --git a/Base/res/cursors/crosshair.png b/Base/res/cursor-themes/Default/crosshair.png similarity index 100% rename from Base/res/cursors/crosshair.png rename to Base/res/cursor-themes/Default/crosshair.png diff --git a/Base/res/cursors/disallowed.png b/Base/res/cursor-themes/Default/disallowed.png similarity index 100% rename from Base/res/cursors/disallowed.png rename to Base/res/cursor-themes/Default/disallowed.png diff --git a/Base/res/cursors/drag.png b/Base/res/cursor-themes/Default/drag.png similarity index 100% rename from Base/res/cursors/drag.png rename to Base/res/cursor-themes/Default/drag.png diff --git a/Base/res/cursors/hand.x8y4.png b/Base/res/cursor-themes/Default/hand.x8y4.png similarity index 100% rename from Base/res/cursors/hand.x8y4.png rename to Base/res/cursor-themes/Default/hand.x8y4.png diff --git a/Base/res/cursors/help.x1y1.png b/Base/res/cursor-themes/Default/help.x1y1.png similarity index 100% rename from Base/res/cursors/help.x1y1.png rename to Base/res/cursor-themes/Default/help.x1y1.png diff --git a/Base/res/cursors/hidden.png b/Base/res/cursor-themes/Default/hidden.png similarity index 100% rename from Base/res/cursors/hidden.png rename to Base/res/cursor-themes/Default/hidden.png diff --git a/Base/res/cursors/i-beam.png b/Base/res/cursor-themes/Default/i-beam.png similarity index 100% rename from Base/res/cursors/i-beam.png rename to Base/res/cursor-themes/Default/i-beam.png diff --git a/Base/res/cursors/move-2x.png b/Base/res/cursor-themes/Default/move-2x.png similarity index 100% rename from Base/res/cursors/move-2x.png rename to Base/res/cursor-themes/Default/move-2x.png diff --git a/Base/res/cursors/move.png b/Base/res/cursor-themes/Default/move.png similarity index 100% rename from Base/res/cursors/move.png rename to Base/res/cursor-themes/Default/move.png diff --git a/Base/res/cursors/resize-column-2x.png b/Base/res/cursor-themes/Default/resize-column-2x.png similarity index 100% rename from Base/res/cursors/resize-column-2x.png rename to Base/res/cursor-themes/Default/resize-column-2x.png diff --git a/Base/res/cursors/resize-column.png b/Base/res/cursor-themes/Default/resize-column.png similarity index 100% rename from Base/res/cursors/resize-column.png rename to Base/res/cursor-themes/Default/resize-column.png diff --git a/Base/res/cursors/resize-diagonal-bltr-2x.png b/Base/res/cursor-themes/Default/resize-diagonal-bltr-2x.png similarity index 100% rename from Base/res/cursors/resize-diagonal-bltr-2x.png rename to Base/res/cursor-themes/Default/resize-diagonal-bltr-2x.png diff --git a/Base/res/cursors/resize-diagonal-bltr.png b/Base/res/cursor-themes/Default/resize-diagonal-bltr.png similarity index 100% rename from Base/res/cursors/resize-diagonal-bltr.png rename to Base/res/cursor-themes/Default/resize-diagonal-bltr.png diff --git a/Base/res/cursors/resize-diagonal-tlbr-2x.png b/Base/res/cursor-themes/Default/resize-diagonal-tlbr-2x.png similarity index 100% rename from Base/res/cursors/resize-diagonal-tlbr-2x.png rename to Base/res/cursor-themes/Default/resize-diagonal-tlbr-2x.png diff --git a/Base/res/cursors/resize-diagonal-tlbr.png b/Base/res/cursor-themes/Default/resize-diagonal-tlbr.png similarity index 100% rename from Base/res/cursors/resize-diagonal-tlbr.png rename to Base/res/cursor-themes/Default/resize-diagonal-tlbr.png diff --git a/Base/res/cursors/resize-horizontal-2x.png b/Base/res/cursor-themes/Default/resize-horizontal-2x.png similarity index 100% rename from Base/res/cursors/resize-horizontal-2x.png rename to Base/res/cursor-themes/Default/resize-horizontal-2x.png diff --git a/Base/res/cursors/resize-horizontal.png b/Base/res/cursor-themes/Default/resize-horizontal.png similarity index 100% rename from Base/res/cursors/resize-horizontal.png rename to Base/res/cursor-themes/Default/resize-horizontal.png diff --git a/Base/res/cursors/resize-row-2x.png b/Base/res/cursor-themes/Default/resize-row-2x.png similarity index 100% rename from Base/res/cursors/resize-row-2x.png rename to Base/res/cursor-themes/Default/resize-row-2x.png diff --git a/Base/res/cursors/resize-row.png b/Base/res/cursor-themes/Default/resize-row.png similarity index 100% rename from Base/res/cursors/resize-row.png rename to Base/res/cursor-themes/Default/resize-row.png diff --git a/Base/res/cursors/resize-vertical-2x.png b/Base/res/cursor-themes/Default/resize-vertical-2x.png similarity index 100% rename from Base/res/cursors/resize-vertical-2x.png rename to Base/res/cursor-themes/Default/resize-vertical-2x.png diff --git a/Base/res/cursors/resize-vertical.png b/Base/res/cursor-themes/Default/resize-vertical.png similarity index 100% rename from Base/res/cursors/resize-vertical.png rename to Base/res/cursor-themes/Default/resize-vertical.png diff --git a/Base/res/cursors/wait.f14t100.png b/Base/res/cursor-themes/Default/wait.f14t100.png similarity index 100% rename from Base/res/cursors/wait.f14t100.png rename to Base/res/cursor-themes/Default/wait.f14t100.png diff --git a/Userland/Demos/WidgetGallery/GalleryModels.h b/Userland/Demos/WidgetGallery/GalleryModels.h index a193beb073..4e6008f2c3 100644 --- a/Userland/Demos/WidgetGallery/GalleryModels.h +++ b/Userland/Demos/WidgetGallery/GalleryModels.h @@ -10,6 +10,7 @@ #include #include #include +#include class MouseCursorModel final : public GUI::Model { public: @@ -57,17 +58,19 @@ public: { m_cursors.clear(); - Core::DirIterator iterator("/res/cursors", Core::DirIterator::Flags::SkipDots); + Core::DirIterator iterator(String::formatted("/res/cursor-themes/{}", GUI::WindowServerConnection::the().get_cursor_theme()), Core::DirIterator::Flags::SkipDots); while (iterator.has_next()) { auto path = iterator.next_full_path(); + if (path.ends_with(".ini")) + continue; if (path.contains("2x")) continue; Cursor cursor; cursor.path = move(path); cursor.bitmap = Gfx::Bitmap::try_load_from_file(cursor.path); auto filename_split = cursor.path.split('/'); - cursor.name = filename_split[2]; + cursor.name = filename_split[3]; m_cursors.append(move(cursor)); } diff --git a/Userland/Services/WindowServer/WindowManager.cpp b/Userland/Services/WindowServer/WindowManager.cpp index 3bfd4ebab5..eeec1d4f10 100644 --- a/Userland/Services/WindowServer/WindowManager.cpp +++ b/Userland/Services/WindowServer/WindowManager.cpp @@ -58,12 +58,6 @@ WindowManager::~WindowManager() { } -RefPtr WindowManager::get_cursor(String const& name) -{ - static auto const s_default_cursor_path = "/res/cursors/arrow.x2y2.png"; - return Cursor::create(m_config->read_entry("Cursor", name, s_default_cursor_path), s_default_cursor_path); -} - void WindowManager::reload_config() { m_config = Core::ConfigFile::open("/etc/WindowServer.ini", Core::ConfigFile::AllowWriting::Yes); @@ -77,31 +71,7 @@ void WindowManager::reload_config() apply_virtual_desktop_settings(virtual_desktop_rows, virtual_desktop_columns, false); m_double_click_speed = m_config->read_num_entry("Input", "DoubleClickSpeed", 250); - - auto* current_cursor = Compositor::the().current_cursor(); - auto reload_cursor = [&](RefPtr& cursor, const String& name) { - bool is_current_cursor = current_cursor && current_cursor == cursor.ptr(); - cursor = get_cursor(name); - if (is_current_cursor) - Compositor::the().current_cursor_was_reloaded(cursor.ptr()); - }; - - reload_cursor(m_hidden_cursor, "Hidden"); - reload_cursor(m_arrow_cursor, "Arrow"); - reload_cursor(m_hand_cursor, "Hand"); - reload_cursor(m_help_cursor, "Help"); - reload_cursor(m_resize_horizontally_cursor, "ResizeH"); - reload_cursor(m_resize_vertically_cursor, "ResizeV"); - reload_cursor(m_resize_diagonally_tlbr_cursor, "ResizeDTLBR"); - reload_cursor(m_resize_diagonally_bltr_cursor, "ResizeDBLTR"); - reload_cursor(m_resize_column_cursor, "ResizeColumn"); - reload_cursor(m_resize_row_cursor, "ResizeRow"); - reload_cursor(m_i_beam_cursor, "IBeam"); - reload_cursor(m_disallowed_cursor, "Disallowed"); - reload_cursor(m_move_cursor, "Move"); - reload_cursor(m_drag_cursor, "Drag"); - reload_cursor(m_wait_cursor, "Wait"); - reload_cursor(m_crosshair_cursor, "Crosshair"); + apply_cursor_theme(m_config->read_entry("Mouse", "CursorTheme", "Default")); auto reload_graphic = [&](RefPtr& bitmap, String const& name) { if (bitmap) { @@ -2070,4 +2040,49 @@ WindowStack& WindowManager::get_rendering_window_stacks(WindowStack*& transition return Compositor::the().get_rendering_window_stacks(transitioning_window_stack); } +void WindowManager::apply_cursor_theme(const String& theme_name) +{ + auto cursor_theme_config = Core::ConfigFile::open(String::formatted("/res/cursor-themes/{}/{}", theme_name, "Config.ini")); + + auto* current_cursor = Compositor::the().current_cursor(); + auto reload_cursor = [&](RefPtr& cursor, const String& name) { + bool is_current_cursor = current_cursor && current_cursor == cursor.ptr(); + + static auto const s_default_cursor_path = "/res/cursor-themes/Default/arrow.x2y2.png"; + cursor = Cursor::create(String::formatted("/res/cursor-themes/{}/{}", theme_name, cursor_theme_config->read_entry("Cursor", name)), s_default_cursor_path); + + if (is_current_cursor) { + Compositor::the().current_cursor_was_reloaded(cursor.ptr()); + + if (m_hovered_window) { + if (auto* modal_window = const_cast(*m_hovered_window).blocking_modal_window()) { + modal_window->set_cursor(cursor); + } else if (m_hovered_window->cursor()) { + m_hovered_window->set_cursor(cursor); + } + } + } + }; + + reload_cursor(m_hidden_cursor, "Hidden"); + reload_cursor(m_arrow_cursor, "Arrow"); + reload_cursor(m_hand_cursor, "Hand"); + reload_cursor(m_help_cursor, "Help"); + reload_cursor(m_resize_horizontally_cursor, "ResizeH"); + reload_cursor(m_resize_vertically_cursor, "ResizeV"); + reload_cursor(m_resize_diagonally_tlbr_cursor, "ResizeDTLBR"); + reload_cursor(m_resize_diagonally_bltr_cursor, "ResizeDBLTR"); + reload_cursor(m_resize_column_cursor, "ResizeColumn"); + reload_cursor(m_resize_row_cursor, "ResizeRow"); + reload_cursor(m_i_beam_cursor, "IBeam"); + reload_cursor(m_disallowed_cursor, "Disallowed"); + reload_cursor(m_move_cursor, "Move"); + reload_cursor(m_drag_cursor, "Drag"); + reload_cursor(m_wait_cursor, "Wait"); + reload_cursor(m_crosshair_cursor, "Crosshair"); + + Compositor::the().invalidate_cursor(); + m_config->write_entry("Mouse", "CursorTheme", theme_name); +} + } diff --git a/Userland/Services/WindowServer/WindowManager.h b/Userland/Services/WindowServer/WindowManager.h index 1c2d077000..cb3aec1d8c 100644 --- a/Userland/Services/WindowServer/WindowManager.h +++ b/Userland/Services/WindowServer/WindowManager.h @@ -315,9 +315,9 @@ public: MultiScaleBitmaps const* overlay_rect_shadow() const { return m_overlay_rect_shadow.ptr(); } -private: - RefPtr get_cursor(String const& name); + void apply_cursor_theme(String const& name); +private: void notify_new_active_window(Window&); void notify_new_active_input_window(Window&); void notify_previous_active_window(Window&);