From df43e094331cbc05e4de5bfd70b1d86a64a452ab Mon Sep 17 00:00:00 2001 From: Shannon Booth Date: Sat, 16 May 2020 13:04:09 +1200 Subject: [PATCH] LibGUI+WindowServer: Allow applications to set custom cursor bitmaps This will allow e.g PaintBrush to use custom cursors for each tool. --- Libraries/LibGUI/Window.cpp | 13 ++++++++++++- Libraries/LibGUI/Window.h | 2 ++ Services/WindowServer/ClientConnection.cpp | 19 +++++++++++++++++++ Services/WindowServer/ClientConnection.h | 1 + Services/WindowServer/WindowServer.ipc | 3 ++- 5 files changed, 36 insertions(+), 2 deletions(-) diff --git a/Libraries/LibGUI/Window.cpp b/Libraries/LibGUI/Window.cpp index e0b791cab9..c0607948e4 100644 --- a/Libraries/LibGUI/Window.cpp +++ b/Libraries/LibGUI/Window.cpp @@ -209,10 +209,21 @@ void Window::set_override_cursor(StandardCursor cursor) { if (!is_visible()) return; - if (m_override_cursor == cursor) + if (!m_custom_cursor && m_override_cursor == cursor) return; WindowServerConnection::the().send_sync(m_window_id, (u32)cursor); m_override_cursor = cursor; + m_custom_cursor = nullptr; +} + +void Window::set_override_cursor(const Gfx::Bitmap& cursor) +{ + if (!is_visible()) + return; + if (&cursor == m_custom_cursor.ptr()) + return; + m_custom_cursor = &cursor; + WindowServerConnection::the().send_sync(m_window_id, m_custom_cursor->to_shareable_bitmap(WindowServerConnection::the().server_pid())); } void Window::event(Core::Event& event) diff --git a/Libraries/LibGUI/Window.h b/Libraries/LibGUI/Window.h index 47cb8fefbe..0f3750253d 100644 --- a/Libraries/LibGUI/Window.h +++ b/Libraries/LibGUI/Window.h @@ -163,6 +163,7 @@ public: void set_base_size(const Gfx::Size&); void set_override_cursor(StandardCursor); + void set_override_cursor(const Gfx::Bitmap&); void set_icon(const Gfx::Bitmap*); void apply_icon(); @@ -204,6 +205,7 @@ private: RefPtr m_front_bitmap; RefPtr m_back_bitmap; RefPtr m_icon; + RefPtr m_custom_cursor; int m_window_id { 0 }; float m_opacity_when_windowless { 1.0f }; RefPtr m_main_widget; diff --git a/Services/WindowServer/ClientConnection.cpp b/Services/WindowServer/ClientConnection.cpp index 3b1deebc28..ae1000f2fb 100644 --- a/Services/WindowServer/ClientConnection.cpp +++ b/Services/WindowServer/ClientConnection.cpp @@ -578,6 +578,25 @@ OwnPtr ClientConnection return make(); } +OwnPtr ClientConnection::handle(const Messages::WindowServer::SetWindowCustomOverrideCursor& message) +{ + auto it = m_windows.find(message.window_id()); + if (it == m_windows.end()) { + did_misbehave("SetWindowCustomOverrideCursor: Bad window ID"); + return nullptr; + } + + auto& window = *(*it).value; + if (!message.cursor().is_valid()) { + did_misbehave("SetWindowCustomOverrideCursor: Bad cursor"); + return nullptr; + } + + window.set_override_cursor(Cursor::create(*message.cursor().bitmap())); + Compositor::the().invalidate_cursor(); + return make(); +} + OwnPtr ClientConnection::handle(const Messages::WindowServer::SetWindowHasAlphaChannel& message) { auto it = m_windows.find(message.window_id()); diff --git a/Services/WindowServer/ClientConnection.h b/Services/WindowServer/ClientConnection.h index bedcdb5e91..ac62c88714 100644 --- a/Services/WindowServer/ClientConnection.h +++ b/Services/WindowServer/ClientConnection.h @@ -114,6 +114,7 @@ private: virtual OwnPtr handle(const Messages::WindowServer::GetWallpaper&) override; virtual OwnPtr handle(const Messages::WindowServer::SetResolution&) override; virtual OwnPtr handle(const Messages::WindowServer::SetWindowOverrideCursor&) override; + virtual OwnPtr handle(const Messages::WindowServer::SetWindowCustomOverrideCursor&) override; virtual OwnPtr handle(const Messages::WindowServer::PopupMenu&) override; virtual OwnPtr handle(const Messages::WindowServer::DismissMenu&) override; virtual OwnPtr handle(const Messages::WindowServer::SetWindowIconBitmap&) override; diff --git a/Services/WindowServer/WindowServer.ipc b/Services/WindowServer/WindowServer.ipc index 8d958823a0..9ac51fe983 100644 --- a/Services/WindowServer/WindowServer.ipc +++ b/Services/WindowServer/WindowServer.ipc @@ -73,7 +73,7 @@ endpoint WindowServer = 2 DismissMenu(i32 menu_id) => () AsyncSetWallpaper(String path) =| - + SetBackgroundColor(String background_color) => () SetWallpaperMode(String mode) => () @@ -82,6 +82,7 @@ endpoint WindowServer = 2 GetWallpaper() => (String path) SetWindowOverrideCursor(i32 window_id, i32 cursor_type) => () + SetWindowCustomOverrideCursor(i32 window_id, Gfx::ShareableBitmap cursor) => () StartDrag(String text, String data_type, String data, i32 bitmap_id, Gfx::Size bitmap_size) => (bool started)