summaryrefslogtreecommitdiff
path: root/Servers
diff options
context:
space:
mode:
authorAndreas Kling <awesomekling@gmail.com>2019-07-28 10:18:49 +0200
committerAndreas Kling <awesomekling@gmail.com>2019-07-28 10:18:49 +0200
commit841b2e5d1367b1b5638d13dbed155ec53914e015 (patch)
tree93518fad445a53d5a8b79dc56150b9ba352170db /Servers
parent63619b9f7c5141d8ecdce98ea0f70039f4186e25 (diff)
downloadserenity-841b2e5d1367b1b5638d13dbed155ec53914e015.zip
WindowServer+LibGUI: Pass window icons as shared buffers rather than paths.
Now that we support more than 2 clients per shared buffer, we can use them for window icons. I didn't do that previously since it would have made the Taskbar process unable to access the icons. This opens up some nice possibilities for programmatically generated icons.
Diffstat (limited to 'Servers')
-rw-r--r--Servers/WindowServer/WSAPITypes.h9
-rw-r--r--Servers/WindowServer/WSClientConnection.cpp32
-rw-r--r--Servers/WindowServer/WSClientConnection.h1
-rw-r--r--Servers/WindowServer/WSEvent.h39
-rw-r--r--Servers/WindowServer/WSWindow.cpp17
-rw-r--r--Servers/WindowServer/WSWindow.h2
-rw-r--r--Servers/WindowServer/WSWindowManager.cpp5
7 files changed, 102 insertions, 3 deletions
diff --git a/Servers/WindowServer/WSAPITypes.h b/Servers/WindowServer/WSAPITypes.h
index 28fe734d6e..526aecadd0 100644
--- a/Servers/WindowServer/WSAPITypes.h
+++ b/Servers/WindowServer/WSAPITypes.h
@@ -111,10 +111,14 @@ struct WSAPI_ServerMessage {
DidGetWallpaper,
DidSetWindowHasAlphaChannel,
ScreenRectChanged,
+
+ __Begin_WM_Events__,
WM_WindowRemoved,
WM_WindowStateChanged,
WM_WindowRectChanged,
WM_WindowIconChanged,
+ WM_WindowIconBitmapChanged,
+ __End_WM_Events__,
};
Type type { Invalid };
int window_id { -1 };
@@ -145,6 +149,8 @@ struct WSAPI_ServerMessage {
bool is_active;
bool is_minimized;
WSAPI_WindowType window_type;
+ int icon_buffer_id;
+ WSAPI_Size icon_size;
} wm;
struct {
WSAPI_Rect rect;
@@ -229,6 +235,7 @@ struct WSAPI_ClientMessage {
SetWindowIcon,
SetWindowHasAlphaChannel,
MoveWindowToFront,
+ SetWindowIconBitmap,
};
Type type { Invalid };
int window_id { -1 };
@@ -278,6 +285,8 @@ struct WSAPI_ClientMessage {
WSAPI_Size base_size;
WSAPI_Size size_increment;
WSAPI_Color background_color;
+ int icon_buffer_id;
+ WSAPI_Size icon_size;
} window;
struct {
WSAPI_Size size;
diff --git a/Servers/WindowServer/WSClientConnection.cpp b/Servers/WindowServer/WSClientConnection.cpp
index 08bce8656a..325cc311c4 100644
--- a/Servers/WindowServer/WSClientConnection.cpp
+++ b/Servers/WindowServer/WSClientConnection.cpp
@@ -1,3 +1,4 @@
+#include <LibC/SharedBuffer.h>
#include <SharedBuffer.h>
#include <WindowServer/WSAPITypes.h>
#include <WindowServer/WSClientConnection.h>
@@ -13,8 +14,8 @@
#include <WindowServer/WSWindowSwitcher.h>
#include <errno.h>
#include <stdio.h>
-#include <sys/socket.h>
#include <sys/ioctl.h>
+#include <sys/socket.h>
#include <sys/uio.h>
#include <unistd.h>
@@ -145,6 +146,9 @@ bool WSClientConnection::handle_message(const WSAPI_ClientMessage& message, cons
}
CEventLoop::current().post_event(*this, make<WSAPISetWindowIconRequest>(client_id(), message.window_id, String(message.text, message.text_length)));
break;
+ case WSAPI_ClientMessage::Type::SetWindowIconBitmap:
+ CEventLoop::current().post_event(*this, make<WSAPISetWindowIconBitmapRequest>(client_id(), message.window_id, message.window.icon_buffer_id, message.window.icon_size));
+ break;
case WSAPI_ClientMessage::Type::DestroyMenu:
CEventLoop::current().post_event(*this, make<WSAPIDestroyMenuRequest>(client_id(), message.menu.menu_id));
break;
@@ -538,7 +542,7 @@ void WSClientConnection::handle_request(const WSAPIGetWallpaperRequest&)
WSAPI_ServerMessage response;
response.type = WSAPI_ServerMessage::Type::DidGetWallpaper;
ASSERT(path.length() < (int)sizeof(response.text));
- strncpy(response.text, path.characters(), path.length());
+ memcpy(response.text, path.characters(), path.length() + 1);
response.text_length = path.length();
post_message(response);
}
@@ -595,6 +599,28 @@ void WSClientConnection::handle_request(const WSAPISetWindowIconRequest& request
WSWindowManager::the().tell_wm_listeners_window_icon_changed(window);
}
+void WSClientConnection::handle_request(const WSAPISetWindowIconBitmapRequest& request)
+{
+ int window_id = request.window_id();
+ auto it = m_windows.find(window_id);
+ if (it == m_windows.end()) {
+ post_error("WSAPISetWindowIconBitmapRequest: Bad window ID");
+ return;
+ }
+ auto& window = *(*it).value;
+
+ auto icon_buffer = SharedBuffer::create_from_shared_buffer_id(request.icon_buffer_id());
+
+ if (!icon_buffer) {
+ window.set_default_icon();
+ } else {
+ window.set_icon(GraphicsBitmap::create_with_shared_buffer(GraphicsBitmap::Format::RGBA32, *icon_buffer, request.icon_size()));
+ }
+
+ window.frame().invalidate_title_bar();
+ WSWindowManager::the().tell_wm_listeners_window_icon_changed(window);
+}
+
void WSClientConnection::handle_request(const WSAPISetWindowRectRequest& request)
{
int window_id = request.window_id();
@@ -946,6 +972,8 @@ void WSClientConnection::on_request(const WSAPIClientRequest& request)
return handle_request(static_cast<const WSAPIGetWindowRectRequest&>(request));
case WSEvent::APISetWindowIconRequest:
return handle_request(static_cast<const WSAPISetWindowIconRequest&>(request));
+ case WSEvent::APISetWindowIconBitmapRequest:
+ return handle_request(static_cast<const WSAPISetWindowIconBitmapRequest&>(request));
case WSEvent::APISetClipboardContentsRequest:
return handle_request(static_cast<const WSAPISetClipboardContentsRequest&>(request));
case WSEvent::APIGetClipboardContentsRequest:
diff --git a/Servers/WindowServer/WSClientConnection.h b/Servers/WindowServer/WSClientConnection.h
index 8038ffe2e4..bf883f7c39 100644
--- a/Servers/WindowServer/WSClientConnection.h
+++ b/Servers/WindowServer/WSClientConnection.h
@@ -55,6 +55,7 @@ private:
void handle_request(const WSAPISetWindowRectRequest&);
void handle_request(const WSAPIGetWindowRectRequest&);
void handle_request(const WSAPISetWindowIconRequest&);
+ void handle_request(const WSAPISetWindowIconBitmapRequest&);
void handle_request(const WSAPISetClipboardContentsRequest&);
void handle_request(const WSAPIGetClipboardContentsRequest&);
void handle_request(const WSAPICreateWindowRequest&);
diff --git a/Servers/WindowServer/WSEvent.h b/Servers/WindowServer/WSEvent.h
index 4339be917b..6e4a7c1cd2 100644
--- a/Servers/WindowServer/WSEvent.h
+++ b/Servers/WindowServer/WSEvent.h
@@ -32,6 +32,7 @@ public:
WM_WindowStateChanged,
WM_WindowRectChanged,
WM_WindowIconChanged,
+ WM_WindowIconBitmapChanged,
__Begin_API_Client_Requests,
APICreateMenubarRequest,
@@ -50,6 +51,7 @@ public:
APISetWindowRectRequest,
APIGetWindowRectRequest,
APISetWindowIconRequest,
+ APISetWindowIconBitmapRequest,
APIInvalidateRectRequest,
APIDidFinishPaintingNotification,
APIGetWindowBackingStoreRequest,
@@ -588,6 +590,26 @@ private:
String m_icon_path;
};
+class WSAPISetWindowIconBitmapRequest final : public WSAPIClientRequest {
+public:
+ explicit WSAPISetWindowIconBitmapRequest(int client_id, int window_id, int icon_buffer_id, const Size& icon_size)
+ : WSAPIClientRequest(WSEvent::APISetWindowIconBitmapRequest, client_id)
+ , m_window_id(window_id)
+ , m_icon_buffer_id(icon_buffer_id)
+ , m_icon_size(icon_size)
+ {
+ }
+
+ int window_id() const { return m_window_id; }
+ int icon_buffer_id() const { return m_icon_buffer_id; }
+ const Size& icon_size() const { return m_icon_size; }
+
+private:
+ int m_window_id { 0 };
+ int m_icon_buffer_id { 0 };
+ Size m_icon_size;
+};
+
class WSAPIGetWindowRectRequest final : public WSAPIClientRequest {
public:
explicit WSAPIGetWindowRectRequest(int client_id, int window_id)
@@ -856,6 +878,23 @@ private:
String m_icon_path;
};
+class WSWMWindowIconBitmapChangedEvent : public WSWMEvent {
+public:
+ WSWMWindowIconBitmapChangedEvent(int client_id, int window_id, int icon_buffer_id, const Size& icon_size)
+ : WSWMEvent(WSEvent::WM_WindowIconBitmapChanged, client_id, window_id)
+ , m_icon_buffer_id(icon_buffer_id)
+ , m_icon_size(icon_size)
+ {
+ }
+
+ int icon_buffer_id() const { return m_icon_buffer_id; }
+ const Size icon_size() const { return m_icon_size; }
+
+private:
+ int m_icon_buffer_id;
+ Size m_icon_size;
+};
+
class WSWMWindowRectChangedEvent : public WSWMEvent {
public:
WSWMWindowRectChangedEvent(int client_id, int window_id, const Rect& rect)
diff --git a/Servers/WindowServer/WSWindow.cpp b/Servers/WindowServer/WSWindow.cpp
index 13b4b49b64..50599820b7 100644
--- a/Servers/WindowServer/WSWindow.cpp
+++ b/Servers/WindowServer/WSWindow.cpp
@@ -254,6 +254,23 @@ void WSWindow::event(CEvent& event)
break;
}
+ case WSEvent::WM_WindowIconBitmapChanged: {
+ auto& changed_event = static_cast<const WSWMWindowIconBitmapChangedEvent&>(event);
+ server_message.type = WSAPI_ServerMessage::Type::WM_WindowIconBitmapChanged;
+ server_message.wm.client_id = changed_event.client_id();
+ server_message.wm.window_id = changed_event.window_id();
+ server_message.wm.icon_buffer_id = changed_event.icon_buffer_id();
+ server_message.wm.icon_size = changed_event.icon_size();
+
+ // FIXME: Perhaps we should update the bitmap sharing list somewhere else instead?
+ ASSERT(client());
+ dbg() << "WindowServer: Sharing icon buffer " << changed_event.icon_buffer_id() << " with PID " << client()->client_pid();
+ if (share_buffer_with(changed_event.icon_buffer_id(), client()->client_pid()) < 0) {
+ ASSERT_NOT_REACHED();
+ }
+ break;
+ }
+
case WSEvent::WM_WindowRectChanged: {
auto& changed_event = static_cast<const WSWMWindowRectChangedEvent&>(event);
server_message.type = WSAPI_ServerMessage::Type::WM_WindowRectChanged;
diff --git a/Servers/WindowServer/WSWindow.h b/Servers/WindowServer/WSWindow.h
index b8c29aa573..e9ed0c82b9 100644
--- a/Servers/WindowServer/WSWindow.h
+++ b/Servers/WindowServer/WSWindow.h
@@ -129,6 +129,8 @@ public:
void set_base_size(const Size& size) { m_base_size = size; }
const GraphicsBitmap& icon() const { return *m_icon; }
+ void set_icon(NonnullRefPtr<GraphicsBitmap>&& icon) { m_icon = move(icon); }
+
String icon_path() const { return m_icon_path; }
void set_icon(const String& path, NonnullRefPtr<GraphicsBitmap>&& icon)
{
diff --git a/Servers/WindowServer/WSWindowManager.cpp b/Servers/WindowServer/WSWindowManager.cpp
index a9abf88c87..b64721da8d 100644
--- a/Servers/WindowServer/WSWindowManager.cpp
+++ b/Servers/WindowServer/WSWindowManager.cpp
@@ -319,8 +319,11 @@ void WSWindowManager::tell_wm_listener_about_window_icon(WSWindow& listener, WSW
{
if (!(listener.wm_event_mask() & WSAPI_WMEventMask::WindowIconChanges))
return;
- if (window.client())
+ if (window.client()) {
CEventLoop::current().post_event(listener, make<WSWMWindowIconChangedEvent>(window.client()->client_id(), window.window_id(), window.icon_path()));
+ if (window.icon().shared_buffer_id() != -1)
+ CEventLoop::current().post_event(listener, make<WSWMWindowIconBitmapChangedEvent>(window.client()->client_id(), window.window_id(), window.icon().shared_buffer_id(), window.icon().size()));
+ }
}
void WSWindowManager::tell_wm_listeners_window_state_changed(WSWindow& window)