summaryrefslogtreecommitdiff
path: root/Servers
diff options
context:
space:
mode:
authorAndreas Kling <awesomekling@gmail.com>2019-03-31 23:52:02 +0200
committerAndreas Kling <awesomekling@gmail.com>2019-03-31 23:52:02 +0200
commitdcf6726487d17f5fb36803e3b8d74ed75ee4fa53 (patch)
tree9d9c049244674d4b191b67ff238884b0c8442f92 /Servers
parent42c95959a8ea883669491499d8d890881ff20031 (diff)
downloadserenity-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.h9
-rw-r--r--Servers/WindowServer/WSClientConnection.cpp14
-rw-r--r--Servers/WindowServer/WSClientConnection.h1
-rw-r--r--Servers/WindowServer/WSCursor.cpp13
-rw-r--r--Servers/WindowServer/WSCursor.h7
-rw-r--r--Servers/WindowServer/WSMessage.h19
-rw-r--r--Servers/WindowServer/WSMessageLoop.cpp4
-rw-r--r--Servers/WindowServer/WSWindow.h5
-rw-r--r--Servers/WindowServer/WSWindowManager.cpp3
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;
}