mirror of
https://github.com/RGBCube/serenity
synced 2025-07-25 20:47:45 +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
|
@ -40,6 +40,7 @@ public:
|
|||
WM_WindowStateChanged,
|
||||
WM_WindowRectChanged,
|
||||
WM_WindowIconChanged,
|
||||
WM_WindowIconBitmapChanged,
|
||||
__End_WM_Events,
|
||||
};
|
||||
|
||||
|
@ -133,6 +134,23 @@ private:
|
|||
String m_icon_path;
|
||||
};
|
||||
|
||||
class GWMWindowIconBitmapChangedEvent : public GWMEvent {
|
||||
public:
|
||||
GWMWindowIconBitmapChangedEvent(int client_id, int window_id, int icon_buffer_id, const Size& icon_size)
|
||||
: GWMEvent(GEvent::Type::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 GMultiPaintEvent final : public GEvent {
|
||||
public:
|
||||
explicit GMultiPaintEvent(const Vector<Rect, 32>& rects, const Size& window_size)
|
||||
|
|
|
@ -194,6 +194,8 @@ void GWindowServerConnection::handle_wm_event(const WSAPI_ServerMessage& event,
|
|||
CEventLoop::current().post_event(window, make<GWMWindowRectChangedEvent>(event.wm.client_id, event.wm.window_id, event.wm.rect));
|
||||
else if (event.type == WSAPI_ServerMessage::WM_WindowIconChanged)
|
||||
CEventLoop::current().post_event(window, make<GWMWindowIconChangedEvent>(event.wm.client_id, event.wm.window_id, String(event.text, event.text_length)));
|
||||
else if (event.type == WSAPI_ServerMessage::WM_WindowIconBitmapChanged)
|
||||
CEventLoop::current().post_event(window, make<GWMWindowIconBitmapChangedEvent>(event.wm.client_id, event.wm.window_id, event.wm.icon_buffer_id, event.wm.icon_size));
|
||||
else if (event.type == WSAPI_ServerMessage::WM_WindowRemoved)
|
||||
CEventLoop::current().post_event(window, make<GWMWindowRemovedEvent>(event.wm.client_id, event.wm.window_id));
|
||||
else
|
||||
|
@ -301,12 +303,9 @@ void GWindowServerConnection::postprocess_bundles(Vector<IncomingMessageBundle>&
|
|||
}
|
||||
handle_resize_event(event, *window);
|
||||
break;
|
||||
case WSAPI_ServerMessage::Type::WM_WindowRemoved:
|
||||
case WSAPI_ServerMessage::Type::WM_WindowStateChanged:
|
||||
case WSAPI_ServerMessage::Type::WM_WindowIconChanged:
|
||||
handle_wm_event(event, *window);
|
||||
break;
|
||||
default:
|
||||
if (event.type > WSAPI_ServerMessage::__Begin_WM_Events__ && event.type < WSAPI_ServerMessage::Type::__End_WM_Events__)
|
||||
handle_wm_event(event, *window);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
#include <AK/HashMap.h>
|
||||
#include <AK/StringBuilder.h>
|
||||
#include <LibC/SharedBuffer.h>
|
||||
#include <LibC/stdio.h>
|
||||
#include <LibC/stdlib.h>
|
||||
#include <LibC/unistd.h>
|
||||
|
@ -593,7 +594,7 @@ void GWindow::flip(const Vector<Rect, 32>& dirty_rects)
|
|||
painter.blit(dirty_rect.location(), *m_front_bitmap, dirty_rect);
|
||||
}
|
||||
|
||||
NonnullRefPtr<GraphicsBitmap> GWindow::create_backing_bitmap(const Size& size)
|
||||
NonnullRefPtr<GraphicsBitmap> GWindow::create_shared_bitmap(GraphicsBitmap::Format format, const Size& size)
|
||||
{
|
||||
ASSERT(GWindowServerConnection::the().server_pid());
|
||||
ASSERT(!size.is_empty());
|
||||
|
@ -602,10 +603,15 @@ NonnullRefPtr<GraphicsBitmap> GWindow::create_backing_bitmap(const Size& size)
|
|||
auto shared_buffer = SharedBuffer::create_with_size(size_in_bytes);
|
||||
ASSERT(shared_buffer);
|
||||
shared_buffer->share_with(GWindowServerConnection::the().server_pid());
|
||||
auto format = m_has_alpha_channel ? GraphicsBitmap::Format::RGBA32 : GraphicsBitmap::Format::RGB32;
|
||||
return GraphicsBitmap::create_with_shared_buffer(format, *shared_buffer, size);
|
||||
}
|
||||
|
||||
NonnullRefPtr<GraphicsBitmap> GWindow::create_backing_bitmap(const Size& size)
|
||||
{
|
||||
auto format = m_has_alpha_channel ? GraphicsBitmap::Format::RGBA32 : GraphicsBitmap::Format::RGB32;
|
||||
return create_shared_bitmap(format, size);
|
||||
}
|
||||
|
||||
void GWindow::set_modal(bool modal)
|
||||
{
|
||||
ASSERT(!m_window_id);
|
||||
|
@ -616,6 +622,27 @@ void GWindow::wm_event(GWMEvent&)
|
|||
{
|
||||
}
|
||||
|
||||
void GWindow::set_icon(const GraphicsBitmap* icon)
|
||||
{
|
||||
if (m_icon == icon)
|
||||
return;
|
||||
if (!m_window_id)
|
||||
return;
|
||||
|
||||
m_icon = create_shared_bitmap(GraphicsBitmap::Format::RGBA32, icon->size());
|
||||
{
|
||||
GPainter painter(*m_icon);
|
||||
painter.blit({ 0, 0 }, *icon, icon->rect());
|
||||
}
|
||||
|
||||
WSAPI_ClientMessage message;
|
||||
message.type = WSAPI_ClientMessage::Type::SetWindowIconBitmap;
|
||||
message.window_id = m_window_id;
|
||||
message.window.icon_buffer_id = m_icon->shared_buffer_id();
|
||||
message.window.icon_size = icon->size();
|
||||
GWindowServerConnection::the().post_message_to_server(message);
|
||||
}
|
||||
|
||||
void GWindow::set_icon_path(const StringView& path)
|
||||
{
|
||||
if (m_icon_path == path)
|
||||
|
|
|
@ -122,6 +122,9 @@ public:
|
|||
String icon_path() const { return m_icon_path; }
|
||||
void set_icon_path(const StringView&);
|
||||
|
||||
void set_icon(const GraphicsBitmap*);
|
||||
const GraphicsBitmap* icon() const { return m_icon.ptr(); }
|
||||
|
||||
Vector<GWidget*> focusable_widgets() const;
|
||||
|
||||
protected:
|
||||
|
@ -135,11 +138,13 @@ private:
|
|||
void collect_keyboard_activation_targets();
|
||||
|
||||
NonnullRefPtr<GraphicsBitmap> create_backing_bitmap(const Size&);
|
||||
NonnullRefPtr<GraphicsBitmap> create_shared_bitmap(GraphicsBitmap::Format, const Size&);
|
||||
void set_current_backing_bitmap(GraphicsBitmap&, bool flush_immediately = false);
|
||||
void flip(const Vector<Rect, 32>& dirty_rects);
|
||||
|
||||
RefPtr<GraphicsBitmap> m_front_bitmap;
|
||||
RefPtr<GraphicsBitmap> m_back_bitmap;
|
||||
RefPtr<GraphicsBitmap> m_icon;
|
||||
int m_window_id { 0 };
|
||||
float m_opacity_when_windowless { 1.0f };
|
||||
GWidget* m_main_widget { nullptr };
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue