mirror of
https://github.com/RGBCube/serenity
synced 2025-07-27 12:27:35 +00:00
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.
This commit is contained in:
parent
63619b9f7c
commit
841b2e5d13
21 changed files with 193 additions and 19 deletions
|
@ -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;
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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&);
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue