mirror of
https://github.com/RGBCube/serenity
synced 2025-05-31 11:28:12 +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
|
@ -1,6 +1,7 @@
|
||||||
#include "DirectoryView.h"
|
#include "DirectoryView.h"
|
||||||
#include <AK/FileSystemPath.h>
|
#include <AK/FileSystemPath.h>
|
||||||
#include <LibCore/CUserInfo.h>
|
#include <LibCore/CUserInfo.h>
|
||||||
|
#include <LibDraw/PNGLoader.h>
|
||||||
#include <LibGUI/GAction.h>
|
#include <LibGUI/GAction.h>
|
||||||
#include <LibGUI/GActionGroup.h>
|
#include <LibGUI/GActionGroup.h>
|
||||||
#include <LibGUI/GApplication.h>
|
#include <LibGUI/GApplication.h>
|
||||||
|
@ -227,7 +228,7 @@ int main(int argc, char** argv)
|
||||||
window->set_main_widget(widget);
|
window->set_main_widget(widget);
|
||||||
window->show();
|
window->show();
|
||||||
|
|
||||||
window->set_icon_path("/res/icons/16x16/filetype-folder.png");
|
window->set_icon(load_png("/res/icons/16x16/filetype-folder.png"));
|
||||||
|
|
||||||
return app.exec();
|
return app.exec();
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
#include "FontEditor.h"
|
#include "FontEditor.h"
|
||||||
|
#include <LibDraw/PNGLoader.h>
|
||||||
#include <LibGUI/GApplication.h>
|
#include <LibGUI/GApplication.h>
|
||||||
#include <LibGUI/GWindow.h>
|
#include <LibGUI/GWindow.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
@ -30,6 +31,6 @@ int main(int argc, char** argv)
|
||||||
auto* font_editor = new FontEditorWidget(path, move(edited_font));
|
auto* font_editor = new FontEditorWidget(path, move(edited_font));
|
||||||
window->set_main_widget(font_editor);
|
window->set_main_widget(font_editor);
|
||||||
window->show();
|
window->show();
|
||||||
window->set_icon_path("/res/icons/16x16/app-font-editor.png");
|
window->set_icon(load_png("/res/icons/16x16/app-font-editor.png"));
|
||||||
return app.exec();
|
return app.exec();
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
#include <LibAudio/AClientConnection.h>
|
#include <LibAudio/AClientConnection.h>
|
||||||
#include <LibCore/CFile.h>
|
#include <LibCore/CFile.h>
|
||||||
#include <LibCore/CThread.h>
|
#include <LibCore/CThread.h>
|
||||||
|
#include <LibDraw/PNGLoader.h>
|
||||||
#include <LibGUI/GAction.h>
|
#include <LibGUI/GAction.h>
|
||||||
#include <LibGUI/GApplication.h>
|
#include <LibGUI/GApplication.h>
|
||||||
#include <LibGUI/GEventLoop.h>
|
#include <LibGUI/GEventLoop.h>
|
||||||
|
@ -23,7 +24,7 @@ int main(int argc, char** argv)
|
||||||
auto* piano_widget = new PianoWidget;
|
auto* piano_widget = new PianoWidget;
|
||||||
window->set_main_widget(piano_widget);
|
window->set_main_widget(piano_widget);
|
||||||
window->show();
|
window->show();
|
||||||
window->set_icon_path("/res/icons/16x16/app-piano.png");
|
window->set_icon(load_png("/res/icons/16x16/app-piano.png"));
|
||||||
|
|
||||||
CThread sound_thread([](void* context) -> int {
|
CThread sound_thread([](void* context) -> int {
|
||||||
auto* piano_widget = (PianoWidget*)context;
|
auto* piano_widget = (PianoWidget*)context;
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
#include "ProcessStacksWidget.h"
|
#include "ProcessStacksWidget.h"
|
||||||
#include "ProcessTableView.h"
|
#include "ProcessTableView.h"
|
||||||
#include <LibCore/CTimer.h>
|
#include <LibCore/CTimer.h>
|
||||||
|
#include <LibDraw/PNGLoader.h>
|
||||||
#include <LibGUI/GAction.h>
|
#include <LibGUI/GAction.h>
|
||||||
#include <LibGUI/GApplication.h>
|
#include <LibGUI/GApplication.h>
|
||||||
#include <LibGUI/GBoxLayout.h>
|
#include <LibGUI/GBoxLayout.h>
|
||||||
|
@ -168,7 +169,7 @@ int main(int argc, char** argv)
|
||||||
|
|
||||||
window->show();
|
window->show();
|
||||||
|
|
||||||
window->set_icon_path("/res/icons/16x16/app-process-manager.png");
|
window->set_icon(load_png("/res/icons/16x16/app-process-manager.png"));
|
||||||
|
|
||||||
return app.exec();
|
return app.exec();
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
#include "TaskbarWindow.h"
|
#include "TaskbarWindow.h"
|
||||||
#include "TaskbarButton.h"
|
#include "TaskbarButton.h"
|
||||||
|
#include <LibC/SharedBuffer.h>
|
||||||
#include <LibGUI/GBoxLayout.h>
|
#include <LibGUI/GBoxLayout.h>
|
||||||
#include <LibGUI/GButton.h>
|
#include <LibGUI/GButton.h>
|
||||||
#include <LibGUI/GDesktop.h>
|
#include <LibGUI/GDesktop.h>
|
||||||
|
@ -100,6 +101,22 @@ void TaskbarWindow::wm_event(GWMEvent& event)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case GEvent::WM_WindowIconBitmapChanged: {
|
||||||
|
auto& changed_event = static_cast<GWMWindowIconBitmapChangedEvent&>(event);
|
||||||
|
#ifdef EVENT_DEBUG
|
||||||
|
dbgprintf("WM_WindowIconChanged: client_id=%d, window_id=%d, icon_buffer_id=%d\n",
|
||||||
|
changed_event.client_id(),
|
||||||
|
changed_event.window_id(),
|
||||||
|
changed_event.icon_buffer_id());
|
||||||
|
#endif
|
||||||
|
if (auto* window = WindowList::the().window(identifier)) {
|
||||||
|
auto buffer = SharedBuffer::create_from_shared_buffer_id(changed_event.icon_buffer_id());
|
||||||
|
ASSERT(buffer);
|
||||||
|
window->button()->set_icon(GraphicsBitmap::create_with_shared_buffer(GraphicsBitmap::Format::RGBA32, *buffer, changed_event.icon_size()));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case GEvent::WM_WindowStateChanged: {
|
case GEvent::WM_WindowStateChanged: {
|
||||||
auto& changed_event = static_cast<GWMWindowStateChangedEvent&>(event);
|
auto& changed_event = static_cast<GWMWindowStateChangedEvent&>(event);
|
||||||
#ifdef EVENT_DEBUG
|
#ifdef EVENT_DEBUG
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
#include "Terminal.h"
|
#include "Terminal.h"
|
||||||
#include <Kernel/KeyCode.h>
|
#include <Kernel/KeyCode.h>
|
||||||
#include <LibCore/CUserInfo.h>
|
#include <LibCore/CUserInfo.h>
|
||||||
|
#include <LibDraw/PNGLoader.h>
|
||||||
#include <LibGUI/GAction.h>
|
#include <LibGUI/GAction.h>
|
||||||
#include <LibGUI/GApplication.h>
|
#include <LibGUI/GApplication.h>
|
||||||
#include <LibGUI/GBoxLayout.h>
|
#include <LibGUI/GBoxLayout.h>
|
||||||
|
@ -154,7 +155,7 @@ int main(int argc, char** argv)
|
||||||
window->move_to(300, 300);
|
window->move_to(300, 300);
|
||||||
terminal.apply_size_increments_to_window(*window);
|
terminal.apply_size_increments_to_window(*window);
|
||||||
window->show();
|
window->show();
|
||||||
window->set_icon_path("/res/icons/16x16/app-terminal.png");
|
window->set_icon(load_png("/res/icons/16x16/app-terminal.png"));
|
||||||
terminal.set_should_beep(config->read_bool_entry("Window", "AudibleBeep", false));
|
terminal.set_should_beep(config->read_bool_entry("Window", "AudibleBeep", false));
|
||||||
|
|
||||||
WeakPtr<GWindow> settings_window;
|
WeakPtr<GWindow> settings_window;
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
#include "TextEditorWidget.h"
|
#include "TextEditorWidget.h"
|
||||||
|
#include <LibDraw/PNGLoader.h>
|
||||||
|
|
||||||
int main(int argc, char** argv)
|
int main(int argc, char** argv)
|
||||||
{
|
{
|
||||||
|
@ -15,7 +16,7 @@ int main(int argc, char** argv)
|
||||||
text_widget->open_sesame(argv[1]);
|
text_widget->open_sesame(argv[1]);
|
||||||
|
|
||||||
window->show();
|
window->show();
|
||||||
window->set_icon_path("/res/icons/TextEditor16.png");
|
window->set_icon(load_png("/res/icons/TextEditor16.png"));
|
||||||
|
|
||||||
return app.exec();
|
return app.exec();
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,6 +17,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <LibDraw/GraphicsBitmap.h>
|
#include <LibDraw/GraphicsBitmap.h>
|
||||||
|
#include <LibDraw/PNGLoader.h>
|
||||||
#include <LibGUI/GApplication.h>
|
#include <LibGUI/GApplication.h>
|
||||||
#include <LibGUI/GLabel.h>
|
#include <LibGUI/GLabel.h>
|
||||||
#include <LibGUI/GPainter.h>
|
#include <LibGUI/GPainter.h>
|
||||||
|
@ -229,7 +230,7 @@ int main(int argc, char** argv)
|
||||||
fire->set_stat_label(time);
|
fire->set_stat_label(time);
|
||||||
|
|
||||||
window->show();
|
window->show();
|
||||||
window->set_icon_path("/res/icons/16x16/app-demo.png");
|
window->set_icon(load_png("/res/icons/16x16/app-demo.png"));
|
||||||
|
|
||||||
return app.exec();
|
return app.exec();
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
#include "Field.h"
|
#include "Field.h"
|
||||||
#include <LibCore/CConfigFile.h>
|
#include <LibCore/CConfigFile.h>
|
||||||
|
#include <LibDraw/PNGLoader.h>
|
||||||
#include <LibGUI/GAction.h>
|
#include <LibGUI/GAction.h>
|
||||||
#include <LibGUI/GApplication.h>
|
#include <LibGUI/GApplication.h>
|
||||||
#include <LibGUI/GBoxLayout.h>
|
#include <LibGUI/GBoxLayout.h>
|
||||||
|
@ -93,7 +94,7 @@ int main(int argc, char** argv)
|
||||||
|
|
||||||
window->show();
|
window->show();
|
||||||
|
|
||||||
window->set_icon_path("/res/icons/minesweeper/mine.png");
|
window->set_icon(load_png("/res/icons/minesweeper/mine.png"));
|
||||||
|
|
||||||
return app.exec();
|
return app.exec();
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
#include "SnakeGame.h"
|
#include "SnakeGame.h"
|
||||||
|
#include <LibDraw/PNGLoader.h>
|
||||||
#include <LibGUI/GAction.h>
|
#include <LibGUI/GAction.h>
|
||||||
#include <LibGUI/GApplication.h>
|
#include <LibGUI/GApplication.h>
|
||||||
#include <LibGUI/GBoxLayout.h>
|
#include <LibGUI/GBoxLayout.h>
|
||||||
|
@ -45,7 +46,7 @@ int main(int argc, char** argv)
|
||||||
|
|
||||||
window->show();
|
window->show();
|
||||||
|
|
||||||
window->set_icon_path("/res/icons/16x16/app-snake.png");
|
window->set_icon(load_png("/res/icons/16x16/app-snake.png"));
|
||||||
|
|
||||||
return app.exec();
|
return app.exec();
|
||||||
}
|
}
|
||||||
|
|
|
@ -40,6 +40,7 @@ public:
|
||||||
WM_WindowStateChanged,
|
WM_WindowStateChanged,
|
||||||
WM_WindowRectChanged,
|
WM_WindowRectChanged,
|
||||||
WM_WindowIconChanged,
|
WM_WindowIconChanged,
|
||||||
|
WM_WindowIconBitmapChanged,
|
||||||
__End_WM_Events,
|
__End_WM_Events,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -133,6 +134,23 @@ private:
|
||||||
String m_icon_path;
|
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 {
|
class GMultiPaintEvent final : public GEvent {
|
||||||
public:
|
public:
|
||||||
explicit GMultiPaintEvent(const Vector<Rect, 32>& rects, const Size& window_size)
|
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));
|
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)
|
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)));
|
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)
|
else if (event.type == WSAPI_ServerMessage::WM_WindowRemoved)
|
||||||
CEventLoop::current().post_event(window, make<GWMWindowRemovedEvent>(event.wm.client_id, event.wm.window_id));
|
CEventLoop::current().post_event(window, make<GWMWindowRemovedEvent>(event.wm.client_id, event.wm.window_id));
|
||||||
else
|
else
|
||||||
|
@ -301,12 +303,9 @@ void GWindowServerConnection::postprocess_bundles(Vector<IncomingMessageBundle>&
|
||||||
}
|
}
|
||||||
handle_resize_event(event, *window);
|
handle_resize_event(event, *window);
|
||||||
break;
|
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:
|
default:
|
||||||
|
if (event.type > WSAPI_ServerMessage::__Begin_WM_Events__ && event.type < WSAPI_ServerMessage::Type::__End_WM_Events__)
|
||||||
|
handle_wm_event(event, *window);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
#include <AK/HashMap.h>
|
#include <AK/HashMap.h>
|
||||||
#include <AK/StringBuilder.h>
|
#include <AK/StringBuilder.h>
|
||||||
|
#include <LibC/SharedBuffer.h>
|
||||||
#include <LibC/stdio.h>
|
#include <LibC/stdio.h>
|
||||||
#include <LibC/stdlib.h>
|
#include <LibC/stdlib.h>
|
||||||
#include <LibC/unistd.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);
|
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(GWindowServerConnection::the().server_pid());
|
||||||
ASSERT(!size.is_empty());
|
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);
|
auto shared_buffer = SharedBuffer::create_with_size(size_in_bytes);
|
||||||
ASSERT(shared_buffer);
|
ASSERT(shared_buffer);
|
||||||
shared_buffer->share_with(GWindowServerConnection::the().server_pid());
|
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);
|
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)
|
void GWindow::set_modal(bool modal)
|
||||||
{
|
{
|
||||||
ASSERT(!m_window_id);
|
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)
|
void GWindow::set_icon_path(const StringView& path)
|
||||||
{
|
{
|
||||||
if (m_icon_path == path)
|
if (m_icon_path == path)
|
||||||
|
|
|
@ -122,6 +122,9 @@ public:
|
||||||
String icon_path() const { return m_icon_path; }
|
String icon_path() const { return m_icon_path; }
|
||||||
void set_icon_path(const StringView&);
|
void set_icon_path(const StringView&);
|
||||||
|
|
||||||
|
void set_icon(const GraphicsBitmap*);
|
||||||
|
const GraphicsBitmap* icon() const { return m_icon.ptr(); }
|
||||||
|
|
||||||
Vector<GWidget*> focusable_widgets() const;
|
Vector<GWidget*> focusable_widgets() const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
@ -135,11 +138,13 @@ private:
|
||||||
void collect_keyboard_activation_targets();
|
void collect_keyboard_activation_targets();
|
||||||
|
|
||||||
NonnullRefPtr<GraphicsBitmap> create_backing_bitmap(const Size&);
|
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 set_current_backing_bitmap(GraphicsBitmap&, bool flush_immediately = false);
|
||||||
void flip(const Vector<Rect, 32>& dirty_rects);
|
void flip(const Vector<Rect, 32>& dirty_rects);
|
||||||
|
|
||||||
RefPtr<GraphicsBitmap> m_front_bitmap;
|
RefPtr<GraphicsBitmap> m_front_bitmap;
|
||||||
RefPtr<GraphicsBitmap> m_back_bitmap;
|
RefPtr<GraphicsBitmap> m_back_bitmap;
|
||||||
|
RefPtr<GraphicsBitmap> m_icon;
|
||||||
int m_window_id { 0 };
|
int m_window_id { 0 };
|
||||||
float m_opacity_when_windowless { 1.0f };
|
float m_opacity_when_windowless { 1.0f };
|
||||||
GWidget* m_main_widget { nullptr };
|
GWidget* m_main_widget { nullptr };
|
||||||
|
|
|
@ -111,10 +111,14 @@ struct WSAPI_ServerMessage {
|
||||||
DidGetWallpaper,
|
DidGetWallpaper,
|
||||||
DidSetWindowHasAlphaChannel,
|
DidSetWindowHasAlphaChannel,
|
||||||
ScreenRectChanged,
|
ScreenRectChanged,
|
||||||
|
|
||||||
|
__Begin_WM_Events__,
|
||||||
WM_WindowRemoved,
|
WM_WindowRemoved,
|
||||||
WM_WindowStateChanged,
|
WM_WindowStateChanged,
|
||||||
WM_WindowRectChanged,
|
WM_WindowRectChanged,
|
||||||
WM_WindowIconChanged,
|
WM_WindowIconChanged,
|
||||||
|
WM_WindowIconBitmapChanged,
|
||||||
|
__End_WM_Events__,
|
||||||
};
|
};
|
||||||
Type type { Invalid };
|
Type type { Invalid };
|
||||||
int window_id { -1 };
|
int window_id { -1 };
|
||||||
|
@ -145,6 +149,8 @@ struct WSAPI_ServerMessage {
|
||||||
bool is_active;
|
bool is_active;
|
||||||
bool is_minimized;
|
bool is_minimized;
|
||||||
WSAPI_WindowType window_type;
|
WSAPI_WindowType window_type;
|
||||||
|
int icon_buffer_id;
|
||||||
|
WSAPI_Size icon_size;
|
||||||
} wm;
|
} wm;
|
||||||
struct {
|
struct {
|
||||||
WSAPI_Rect rect;
|
WSAPI_Rect rect;
|
||||||
|
@ -229,6 +235,7 @@ struct WSAPI_ClientMessage {
|
||||||
SetWindowIcon,
|
SetWindowIcon,
|
||||||
SetWindowHasAlphaChannel,
|
SetWindowHasAlphaChannel,
|
||||||
MoveWindowToFront,
|
MoveWindowToFront,
|
||||||
|
SetWindowIconBitmap,
|
||||||
};
|
};
|
||||||
Type type { Invalid };
|
Type type { Invalid };
|
||||||
int window_id { -1 };
|
int window_id { -1 };
|
||||||
|
@ -278,6 +285,8 @@ struct WSAPI_ClientMessage {
|
||||||
WSAPI_Size base_size;
|
WSAPI_Size base_size;
|
||||||
WSAPI_Size size_increment;
|
WSAPI_Size size_increment;
|
||||||
WSAPI_Color background_color;
|
WSAPI_Color background_color;
|
||||||
|
int icon_buffer_id;
|
||||||
|
WSAPI_Size icon_size;
|
||||||
} window;
|
} window;
|
||||||
struct {
|
struct {
|
||||||
WSAPI_Size size;
|
WSAPI_Size size;
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
#include <LibC/SharedBuffer.h>
|
||||||
#include <SharedBuffer.h>
|
#include <SharedBuffer.h>
|
||||||
#include <WindowServer/WSAPITypes.h>
|
#include <WindowServer/WSAPITypes.h>
|
||||||
#include <WindowServer/WSClientConnection.h>
|
#include <WindowServer/WSClientConnection.h>
|
||||||
|
@ -13,8 +14,8 @@
|
||||||
#include <WindowServer/WSWindowSwitcher.h>
|
#include <WindowServer/WSWindowSwitcher.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <sys/socket.h>
|
|
||||||
#include <sys/ioctl.h>
|
#include <sys/ioctl.h>
|
||||||
|
#include <sys/socket.h>
|
||||||
#include <sys/uio.h>
|
#include <sys/uio.h>
|
||||||
#include <unistd.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)));
|
CEventLoop::current().post_event(*this, make<WSAPISetWindowIconRequest>(client_id(), message.window_id, String(message.text, message.text_length)));
|
||||||
break;
|
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:
|
case WSAPI_ClientMessage::Type::DestroyMenu:
|
||||||
CEventLoop::current().post_event(*this, make<WSAPIDestroyMenuRequest>(client_id(), message.menu.menu_id));
|
CEventLoop::current().post_event(*this, make<WSAPIDestroyMenuRequest>(client_id(), message.menu.menu_id));
|
||||||
break;
|
break;
|
||||||
|
@ -538,7 +542,7 @@ void WSClientConnection::handle_request(const WSAPIGetWallpaperRequest&)
|
||||||
WSAPI_ServerMessage response;
|
WSAPI_ServerMessage response;
|
||||||
response.type = WSAPI_ServerMessage::Type::DidGetWallpaper;
|
response.type = WSAPI_ServerMessage::Type::DidGetWallpaper;
|
||||||
ASSERT(path.length() < (int)sizeof(response.text));
|
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();
|
response.text_length = path.length();
|
||||||
post_message(response);
|
post_message(response);
|
||||||
}
|
}
|
||||||
|
@ -595,6 +599,28 @@ void WSClientConnection::handle_request(const WSAPISetWindowIconRequest& request
|
||||||
WSWindowManager::the().tell_wm_listeners_window_icon_changed(window);
|
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)
|
void WSClientConnection::handle_request(const WSAPISetWindowRectRequest& request)
|
||||||
{
|
{
|
||||||
int window_id = request.window_id();
|
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));
|
return handle_request(static_cast<const WSAPIGetWindowRectRequest&>(request));
|
||||||
case WSEvent::APISetWindowIconRequest:
|
case WSEvent::APISetWindowIconRequest:
|
||||||
return handle_request(static_cast<const WSAPISetWindowIconRequest&>(request));
|
return handle_request(static_cast<const WSAPISetWindowIconRequest&>(request));
|
||||||
|
case WSEvent::APISetWindowIconBitmapRequest:
|
||||||
|
return handle_request(static_cast<const WSAPISetWindowIconBitmapRequest&>(request));
|
||||||
case WSEvent::APISetClipboardContentsRequest:
|
case WSEvent::APISetClipboardContentsRequest:
|
||||||
return handle_request(static_cast<const WSAPISetClipboardContentsRequest&>(request));
|
return handle_request(static_cast<const WSAPISetClipboardContentsRequest&>(request));
|
||||||
case WSEvent::APIGetClipboardContentsRequest:
|
case WSEvent::APIGetClipboardContentsRequest:
|
||||||
|
|
|
@ -55,6 +55,7 @@ private:
|
||||||
void handle_request(const WSAPISetWindowRectRequest&);
|
void handle_request(const WSAPISetWindowRectRequest&);
|
||||||
void handle_request(const WSAPIGetWindowRectRequest&);
|
void handle_request(const WSAPIGetWindowRectRequest&);
|
||||||
void handle_request(const WSAPISetWindowIconRequest&);
|
void handle_request(const WSAPISetWindowIconRequest&);
|
||||||
|
void handle_request(const WSAPISetWindowIconBitmapRequest&);
|
||||||
void handle_request(const WSAPISetClipboardContentsRequest&);
|
void handle_request(const WSAPISetClipboardContentsRequest&);
|
||||||
void handle_request(const WSAPIGetClipboardContentsRequest&);
|
void handle_request(const WSAPIGetClipboardContentsRequest&);
|
||||||
void handle_request(const WSAPICreateWindowRequest&);
|
void handle_request(const WSAPICreateWindowRequest&);
|
||||||
|
|
|
@ -32,6 +32,7 @@ public:
|
||||||
WM_WindowStateChanged,
|
WM_WindowStateChanged,
|
||||||
WM_WindowRectChanged,
|
WM_WindowRectChanged,
|
||||||
WM_WindowIconChanged,
|
WM_WindowIconChanged,
|
||||||
|
WM_WindowIconBitmapChanged,
|
||||||
|
|
||||||
__Begin_API_Client_Requests,
|
__Begin_API_Client_Requests,
|
||||||
APICreateMenubarRequest,
|
APICreateMenubarRequest,
|
||||||
|
@ -50,6 +51,7 @@ public:
|
||||||
APISetWindowRectRequest,
|
APISetWindowRectRequest,
|
||||||
APIGetWindowRectRequest,
|
APIGetWindowRectRequest,
|
||||||
APISetWindowIconRequest,
|
APISetWindowIconRequest,
|
||||||
|
APISetWindowIconBitmapRequest,
|
||||||
APIInvalidateRectRequest,
|
APIInvalidateRectRequest,
|
||||||
APIDidFinishPaintingNotification,
|
APIDidFinishPaintingNotification,
|
||||||
APIGetWindowBackingStoreRequest,
|
APIGetWindowBackingStoreRequest,
|
||||||
|
@ -588,6 +590,26 @@ private:
|
||||||
String m_icon_path;
|
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 {
|
class WSAPIGetWindowRectRequest final : public WSAPIClientRequest {
|
||||||
public:
|
public:
|
||||||
explicit WSAPIGetWindowRectRequest(int client_id, int window_id)
|
explicit WSAPIGetWindowRectRequest(int client_id, int window_id)
|
||||||
|
@ -856,6 +878,23 @@ private:
|
||||||
String m_icon_path;
|
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 {
|
class WSWMWindowRectChangedEvent : public WSWMEvent {
|
||||||
public:
|
public:
|
||||||
WSWMWindowRectChangedEvent(int client_id, int window_id, const Rect& rect)
|
WSWMWindowRectChangedEvent(int client_id, int window_id, const Rect& rect)
|
||||||
|
|
|
@ -254,6 +254,23 @@ void WSWindow::event(CEvent& event)
|
||||||
break;
|
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: {
|
case WSEvent::WM_WindowRectChanged: {
|
||||||
auto& changed_event = static_cast<const WSWMWindowRectChangedEvent&>(event);
|
auto& changed_event = static_cast<const WSWMWindowRectChangedEvent&>(event);
|
||||||
server_message.type = WSAPI_ServerMessage::Type::WM_WindowRectChanged;
|
server_message.type = WSAPI_ServerMessage::Type::WM_WindowRectChanged;
|
||||||
|
|
|
@ -129,6 +129,8 @@ public:
|
||||||
void set_base_size(const Size& size) { m_base_size = size; }
|
void set_base_size(const Size& size) { m_base_size = size; }
|
||||||
|
|
||||||
const GraphicsBitmap& icon() const { return *m_icon; }
|
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; }
|
String icon_path() const { return m_icon_path; }
|
||||||
void set_icon(const String& path, NonnullRefPtr<GraphicsBitmap>&& icon)
|
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))
|
if (!(listener.wm_event_mask() & WSAPI_WMEventMask::WindowIconChanges))
|
||||||
return;
|
return;
|
||||||
if (window.client())
|
if (window.client()) {
|
||||||
CEventLoop::current().post_event(listener, make<WSWMWindowIconChangedEvent>(window.client()->client_id(), window.window_id(), window.icon_path()));
|
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)
|
void WSWindowManager::tell_wm_listeners_window_state_changed(WSWindow& window)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue