diff options
author | Andreas Kling <awesomekling@gmail.com> | 2019-03-31 23:52:02 +0200 |
---|---|---|
committer | Andreas Kling <awesomekling@gmail.com> | 2019-03-31 23:52:02 +0200 |
commit | dcf6726487d17f5fb36803e3b8d74ed75ee4fa53 (patch) | |
tree | 9d9c049244674d4b191b67ff238884b0c8442f92 /Servers | |
parent | 42c95959a8ea883669491499d8d890881ff20031 (diff) | |
download | serenity-dcf6726487d17f5fb36803e3b8d74ed75ee4fa53.zip |
WindowServer: Add support for per-window override cursors.
Use this to implement automatic switching to an I-beam cursor when hovering
over a GTextEditor. :^)
Diffstat (limited to 'Servers')
-rw-r--r-- | Servers/WindowServer/WSAPITypes.h | 9 | ||||
-rw-r--r-- | Servers/WindowServer/WSClientConnection.cpp | 14 | ||||
-rw-r--r-- | Servers/WindowServer/WSClientConnection.h | 1 | ||||
-rw-r--r-- | Servers/WindowServer/WSCursor.cpp | 13 | ||||
-rw-r--r-- | Servers/WindowServer/WSCursor.h | 7 | ||||
-rw-r--r-- | Servers/WindowServer/WSMessage.h | 19 | ||||
-rw-r--r-- | Servers/WindowServer/WSMessageLoop.cpp | 4 | ||||
-rw-r--r-- | Servers/WindowServer/WSWindow.h | 5 | ||||
-rw-r--r-- | Servers/WindowServer/WSWindowManager.cpp | 3 |
9 files changed, 75 insertions, 0 deletions
diff --git a/Servers/WindowServer/WSAPITypes.h b/Servers/WindowServer/WSAPITypes.h index c05acc3f32..31bcc54e99 100644 --- a/Servers/WindowServer/WSAPITypes.h +++ b/Servers/WindowServer/WSAPITypes.h @@ -47,6 +47,11 @@ struct WSAPI_KeyModifiers { enum { Ctrl = 1 << 2, }; }; +enum class WSAPI_StandardCursor : unsigned char { + None = 0, + Arrow, + IBeam, +}; struct WSAPI_ServerMessage { enum Type : unsigned { @@ -164,6 +169,7 @@ struct WSAPI_ClientMessage { Greeting, SetWallpaper, GetWallpaper, + SetWindowOverrideCursor, }; Type type { Invalid }; int window_id { -1 }; @@ -203,6 +209,9 @@ struct WSAPI_ClientMessage { int shared_buffer_id; int contents_size; } clipboard; + struct { + WSAPI_StandardCursor cursor; + } cursor; }; }; diff --git a/Servers/WindowServer/WSClientConnection.cpp b/Servers/WindowServer/WSClientConnection.cpp index 5a5b93a6b2..3ca579d96f 100644 --- a/Servers/WindowServer/WSClientConnection.cpp +++ b/Servers/WindowServer/WSClientConnection.cpp @@ -491,6 +491,18 @@ void WSClientConnection::handle_request(WSAPISetGlobalCursorTrackingRequest& req window.set_global_cursor_tracking_enabled(request.value()); } +void WSClientConnection::handle_request(WSAPISetWindowOverrideCursorRequest& request) +{ + int window_id = request.window_id(); + auto it = m_windows.find(window_id); + if (it == m_windows.end()) { + post_error("Bad window ID"); + return; + } + auto& window = *(*it).value; + window.set_override_cursor(WSCursor::create(request.cursor())); +} + void WSClientConnection::on_request(WSAPIClientRequest& request) { switch (request.type()) { @@ -542,6 +554,8 @@ void WSClientConnection::on_request(WSAPIClientRequest& request) return handle_request(static_cast<WSAPISetWallpaperRequest&>(request)); case WSMessage::APIGetWallpaperRequest: return handle_request(static_cast<WSAPIGetWallpaperRequest&>(request)); + case WSMessage::APISetWindowOverrideCursorRequest: + return handle_request(static_cast<WSAPISetWindowOverrideCursorRequest&>(request)); default: break; } diff --git a/Servers/WindowServer/WSClientConnection.h b/Servers/WindowServer/WSClientConnection.h index f92f8db505..f596ac59e1 100644 --- a/Servers/WindowServer/WSClientConnection.h +++ b/Servers/WindowServer/WSClientConnection.h @@ -64,6 +64,7 @@ private: void handle_request(WSAPISetWindowOpacityRequest&); void handle_request(WSAPISetWallpaperRequest&); void handle_request(WSAPIGetWallpaperRequest&); + void handle_request(WSAPISetWindowOverrideCursorRequest&); void post_error(const String&); diff --git a/Servers/WindowServer/WSCursor.cpp b/Servers/WindowServer/WSCursor.cpp index 12261a5f54..61854a75a7 100644 --- a/Servers/WindowServer/WSCursor.cpp +++ b/Servers/WindowServer/WSCursor.cpp @@ -19,3 +19,16 @@ Retained<WSCursor> WSCursor::create(Retained<GraphicsBitmap>&& bitmap, const Poi { return adopt(*new WSCursor(move(bitmap), hotspot)); } + +RetainPtr<WSCursor> WSCursor::create(WSStandardCursor standard_cursor) +{ + switch (standard_cursor) { + case WSStandardCursor::None: + return nullptr; + case WSStandardCursor::Arrow: + return create(*GraphicsBitmap::load_from_file("/res/cursors/arrow.png")); + case WSStandardCursor::IBeam: + return create(*GraphicsBitmap::load_from_file("/res/cursors/i-beam.png")); + } + ASSERT_NOT_REACHED(); +} diff --git a/Servers/WindowServer/WSCursor.h b/Servers/WindowServer/WSCursor.h index 7125ad2a78..4a07f2b6de 100644 --- a/Servers/WindowServer/WSCursor.h +++ b/Servers/WindowServer/WSCursor.h @@ -2,10 +2,17 @@ #include <SharedGraphics/GraphicsBitmap.h> +enum class WSStandardCursor { + None = 0, + Arrow, + IBeam, +}; + class WSCursor : public Retainable<WSCursor> { public: static Retained<WSCursor> create(Retained<GraphicsBitmap>&&, const Point& hotspot); static Retained<WSCursor> create(Retained<GraphicsBitmap>&&); + static RetainPtr<WSCursor> create(WSStandardCursor); ~WSCursor(); Point hotspot() const { return m_hotspot; } diff --git a/Servers/WindowServer/WSMessage.h b/Servers/WindowServer/WSMessage.h index 12dd6fcf35..0b4274bd34 100644 --- a/Servers/WindowServer/WSMessage.h +++ b/Servers/WindowServer/WSMessage.h @@ -5,6 +5,7 @@ #include <AK/AKString.h> #include <AK/Types.h> #include <Kernel/KeyCode.h> +#include <WindowServer/WSCursor.h> class WSMessage { public: @@ -49,6 +50,7 @@ public: APIGetClipboardContentsRequest, APISetWallpaperRequest, APIGetWallpaperRequest, + APISetWindowOverrideCursorRequest, __End_API_Client_Requests, }; @@ -229,6 +231,23 @@ private: int m_menu_id { 0 }; }; +class WSAPISetWindowOverrideCursorRequest final : public WSAPIClientRequest { +public: + explicit WSAPISetWindowOverrideCursorRequest(int client_id, int window_id, WSStandardCursor cursor) + : WSAPIClientRequest(WSMessage::APISetWindowOverrideCursorRequest, client_id) + , m_window_id(window_id) + , m_cursor(cursor) + { + } + + int window_id() const { return m_window_id; } + WSStandardCursor cursor() const { return m_cursor; } + +private: + int m_window_id { 0 }; + WSStandardCursor m_cursor { WSStandardCursor::None }; +}; + class WSAPISetWallpaperRequest final : public WSAPIClientRequest { public: explicit WSAPISetWallpaperRequest(int client_id, String&& wallpaper) diff --git a/Servers/WindowServer/WSMessageLoop.cpp b/Servers/WindowServer/WSMessageLoop.cpp index 21ebc80ee7..5b46ae2345 100644 --- a/Servers/WindowServer/WSMessageLoop.cpp +++ b/Servers/WindowServer/WSMessageLoop.cpp @@ -5,6 +5,7 @@ #include <WindowServer/WSScreen.h> #include <WindowServer/WSClientConnection.h> #include <WindowServer/WSAPITypes.h> +#include <WindowServer/WSCursor.h> #include <Kernel/KeyCode.h> #include <Kernel/MousePacket.h> #include <LibC/sys/socket.h> @@ -330,6 +331,9 @@ void WSMessageLoop::on_receive_from_client(int client_id, const WSAPI_ClientMess break; case WSAPI_ClientMessage::Type::GetWallpaper: post_message(client, make<WSAPIGetWallpaperRequest>(client_id)); + break; + case WSAPI_ClientMessage::Type::SetWindowOverrideCursor: + post_message(client, make<WSAPISetWindowOverrideCursorRequest>(client_id, message.window_id, (WSStandardCursor)message.cursor.cursor)); default: break; } diff --git a/Servers/WindowServer/WSWindow.h b/Servers/WindowServer/WSWindow.h index 68a02f4f71..624b951d57 100644 --- a/Servers/WindowServer/WSWindow.h +++ b/Servers/WindowServer/WSWindow.h @@ -8,6 +8,7 @@ #include <WindowServer/WSWindowType.h> class WSClientConnection; +class WSCursor; class WSMenu; class WSMouseEvent; @@ -100,6 +101,9 @@ public: const GraphicsBitmap& icon() const { return *m_icon; } void set_icon(Retained<GraphicsBitmap>&& icon) { m_icon = move(icon); } + const WSCursor* override_cursor() const { return m_override_cursor.ptr(); } + void set_override_cursor(RetainPtr<WSCursor>&& cursor) { m_override_cursor = move(cursor); } + // For InlineLinkedList. // FIXME: Maybe make a ListHashSet and then WSWindowManager can just use that. WSWindow* m_next { nullptr }; @@ -128,4 +132,5 @@ private: Size m_size_increment; Size m_base_size; Retained<GraphicsBitmap> m_icon; + RetainPtr<WSCursor> m_override_cursor; }; diff --git a/Servers/WindowServer/WSWindowManager.cpp b/Servers/WindowServer/WSWindowManager.cpp index f46b6732ad..3791f66699 100644 --- a/Servers/WindowServer/WSWindowManager.cpp +++ b/Servers/WindowServer/WSWindowManager.cpp @@ -1261,5 +1261,8 @@ const WSCursor& WSWindowManager::active_cursor() const } } + if (m_hovered_window && m_hovered_window->override_cursor()) + return *m_hovered_window->override_cursor(); + return *m_arrow_cursor; } |