mirror of
https://github.com/RGBCube/serenity
synced 2025-07-25 14:47:44 +00:00
WindowServer+LibGUI: Make window creation asynchronous :^)
Let clients manage their own window ID's. If you try to create a new window with an existing ID, WindowServer will simply disconnect you for misbehaving. This removes the need for window creation to be synchronous, which means that most GUI applications can now batch their entire GUI initialization sequence without having to block waiting for responses.
This commit is contained in:
parent
77c2db4183
commit
0a98964600
4 changed files with 17 additions and 10 deletions
|
@ -6,6 +6,7 @@
|
||||||
|
|
||||||
#include <AK/Debug.h>
|
#include <AK/Debug.h>
|
||||||
#include <AK/HashMap.h>
|
#include <AK/HashMap.h>
|
||||||
|
#include <AK/IDAllocator.h>
|
||||||
#include <AK/JsonObject.h>
|
#include <AK/JsonObject.h>
|
||||||
#include <AK/NeverDestroyed.h>
|
#include <AK/NeverDestroyed.h>
|
||||||
#include <AK/ScopeGuard.h>
|
#include <AK/ScopeGuard.h>
|
||||||
|
@ -30,6 +31,7 @@
|
||||||
namespace GUI {
|
namespace GUI {
|
||||||
|
|
||||||
static i32 s_next_backing_store_serial;
|
static i32 s_next_backing_store_serial;
|
||||||
|
static IDAllocator s_window_id_allocator;
|
||||||
|
|
||||||
class WindowBackingStore {
|
class WindowBackingStore {
|
||||||
public:
|
public:
|
||||||
|
@ -118,7 +120,10 @@ void Window::show()
|
||||||
|
|
||||||
auto* parent_window = find_parent_window();
|
auto* parent_window = find_parent_window();
|
||||||
|
|
||||||
m_window_id = WindowServerConnection::the().create_window(
|
m_window_id = s_window_id_allocator.allocate();
|
||||||
|
|
||||||
|
WindowServerConnection::the().async_create_window(
|
||||||
|
m_window_id,
|
||||||
m_rect_when_windowless,
|
m_rect_when_windowless,
|
||||||
!m_moved_by_client,
|
!m_moved_by_client,
|
||||||
m_has_alpha_channel,
|
m_has_alpha_channel,
|
||||||
|
|
|
@ -460,7 +460,7 @@ Window* ClientConnection::window_from_id(i32 window_id)
|
||||||
return it->value.ptr();
|
return it->value.ptr();
|
||||||
}
|
}
|
||||||
|
|
||||||
Messages::WindowServer::CreateWindowResponse ClientConnection::create_window(Gfx::IntRect const& rect,
|
void ClientConnection::create_window(i32 window_id, Gfx::IntRect const& rect,
|
||||||
bool auto_position, bool has_alpha_channel, bool modal, bool minimizable, bool resizable,
|
bool auto_position, bool has_alpha_channel, bool modal, bool minimizable, bool resizable,
|
||||||
bool fullscreen, bool frameless, bool accessory, float opacity, float alpha_hit_threshold,
|
bool fullscreen, bool frameless, bool accessory, float opacity, float alpha_hit_threshold,
|
||||||
Gfx::IntSize const& base_size, Gfx::IntSize const& size_increment, Gfx::IntSize const& minimum_size,
|
Gfx::IntSize const& base_size, Gfx::IntSize const& size_increment, Gfx::IntSize const& minimum_size,
|
||||||
|
@ -471,16 +471,20 @@ Messages::WindowServer::CreateWindowResponse ClientConnection::create_window(Gfx
|
||||||
parent_window = window_from_id(parent_window_id);
|
parent_window = window_from_id(parent_window_id);
|
||||||
if (!parent_window) {
|
if (!parent_window) {
|
||||||
did_misbehave("CreateWindow with bad parent_window_id");
|
did_misbehave("CreateWindow with bad parent_window_id");
|
||||||
return nullptr;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (type < 0 || type >= (i32)WindowType::_Count) {
|
if (type < 0 || type >= (i32)WindowType::_Count) {
|
||||||
did_misbehave("CreateWindow with a bad type");
|
did_misbehave("CreateWindow with a bad type");
|
||||||
return nullptr;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_windows.contains(window_id)) {
|
||||||
|
did_misbehave("CreateWindow with already-used window ID");
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
int window_id = m_next_window_id++;
|
|
||||||
auto window = Window::construct(*this, (WindowType)type, window_id, modal, minimizable, frameless, resizable, fullscreen, accessory, parent_window);
|
auto window = Window::construct(*this, (WindowType)type, window_id, modal, minimizable, frameless, resizable, fullscreen, accessory, parent_window);
|
||||||
|
|
||||||
window->set_has_alpha_channel(has_alpha_channel);
|
window->set_has_alpha_channel(has_alpha_channel);
|
||||||
|
@ -513,7 +517,6 @@ Messages::WindowServer::CreateWindowResponse ClientConnection::create_window(Gfx
|
||||||
if (window->type() == WindowType::Applet)
|
if (window->type() == WindowType::Applet)
|
||||||
AppletManager::the().add_applet(*window);
|
AppletManager::the().add_applet(*window);
|
||||||
m_windows.set(window_id, move(window));
|
m_windows.set(window_id, move(window));
|
||||||
return window_id;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ClientConnection::destroy_window(Window& window, Vector<i32>& destroyed_window_ids)
|
void ClientConnection::destroy_window(Window& window, Vector<i32>& destroyed_window_ids)
|
||||||
|
|
|
@ -97,7 +97,7 @@ private:
|
||||||
virtual void add_menu_item(i32, i32, i32, String const&, bool, bool, bool, bool, String const&, Gfx::ShareableBitmap const&, bool) override;
|
virtual void add_menu_item(i32, i32, i32, String const&, bool, bool, bool, bool, String const&, Gfx::ShareableBitmap const&, bool) override;
|
||||||
virtual void add_menu_separator(i32) override;
|
virtual void add_menu_separator(i32) override;
|
||||||
virtual void update_menu_item(i32, i32, i32, String const&, bool, bool, bool, bool, String const&) override;
|
virtual void update_menu_item(i32, i32, i32, String const&, bool, bool, bool, bool, String const&) override;
|
||||||
virtual Messages::WindowServer::CreateWindowResponse create_window(Gfx::IntRect const&, bool, bool, bool,
|
virtual void create_window(i32, Gfx::IntRect const&, bool, bool, bool,
|
||||||
bool, bool, bool, bool, bool, float, float, Gfx::IntSize const&, Gfx::IntSize const&, Gfx::IntSize const&,
|
bool, bool, bool, bool, bool, float, float, Gfx::IntSize const&, Gfx::IntSize const&, Gfx::IntSize const&,
|
||||||
Optional<Gfx::IntSize> const&, i32, String const&, i32) override;
|
Optional<Gfx::IntSize> const&, i32, String const&, i32) override;
|
||||||
virtual Messages::WindowServer::DestroyWindowResponse destroy_window(i32) override;
|
virtual Messages::WindowServer::DestroyWindowResponse destroy_window(i32) override;
|
||||||
|
@ -163,8 +163,6 @@ private:
|
||||||
|
|
||||||
RefPtr<Core::Timer> m_ping_timer;
|
RefPtr<Core::Timer> m_ping_timer;
|
||||||
|
|
||||||
int m_next_window_id { 1982 };
|
|
||||||
|
|
||||||
bool m_has_display_link { false };
|
bool m_has_display_link { false };
|
||||||
bool m_unresponsive { false };
|
bool m_unresponsive { false };
|
||||||
|
|
||||||
|
|
|
@ -26,6 +26,7 @@ endpoint WindowServer
|
||||||
update_menu_item(i32 menu_id, i32 identifier, i32 submenu_id, [UTF8] String text, bool enabled, bool checkable, bool checked, bool is_default, [UTF8] String shortcut) =|
|
update_menu_item(i32 menu_id, i32 identifier, i32 submenu_id, [UTF8] String text, bool enabled, bool checkable, bool checked, bool is_default, [UTF8] String shortcut) =|
|
||||||
|
|
||||||
create_window(
|
create_window(
|
||||||
|
i32 window_id,
|
||||||
Gfx::IntRect rect,
|
Gfx::IntRect rect,
|
||||||
bool auto_position,
|
bool auto_position,
|
||||||
bool has_alpha_channel,
|
bool has_alpha_channel,
|
||||||
|
@ -43,7 +44,7 @@ endpoint WindowServer
|
||||||
Optional<Gfx::IntSize> resize_aspect_ratio,
|
Optional<Gfx::IntSize> resize_aspect_ratio,
|
||||||
i32 type,
|
i32 type,
|
||||||
[UTF8] String title,
|
[UTF8] String title,
|
||||||
i32 parent_window_id) => (i32 window_id)
|
i32 parent_window_id) =|
|
||||||
|
|
||||||
destroy_window(i32 window_id) => (Vector<i32> destroyed_window_ids)
|
destroy_window(i32 window_id) => (Vector<i32> destroyed_window_ids)
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue