Переглянути джерело

LibGUI: Revert GWindowServerConnection to being a singleton

This was a mistake, of course. Nested event loops don't need (or want)
independent server connections.

We initialize the connection early in GEventLoop for e.g. users that
want to get the size of a GDesktop before the connection has been
established.

Bug noticed by Andreas, introduced by me ;-)
Robin Burchell 6 роки тому
батько
коміт
7a53096e8d

+ 1 - 1
Applications/Taskbar/TaskbarButton.cpp

@@ -20,5 +20,5 @@ void TaskbarButton::context_menu_event(GContextMenuEvent&)
     request.wm.client_id = m_identifier.client_id();
     request.wm.window_id = m_identifier.window_id();
     request.wm.position = screen_relative_rect().location();
-    GEventLoop::current().connection().post_message_to_server(request);
+    GWindowServerConnection::the().post_message_to_server(request);
 }

+ 1 - 1
Applications/Taskbar/WindowList.cpp

@@ -35,7 +35,7 @@ Window& WindowList::ensure_window(const WindowIdentifier& identifier)
         }
         message.wm.client_id = identifier.client_id();
         message.wm.window_id = identifier.window_id();
-        bool success = GEventLoop::current().connection().post_message_to_server(message);
+        bool success = GWindowServerConnection::the().post_message_to_server(message);
         ASSERT(success);
     };
     auto& window_ref = *window;

+ 3 - 3
Libraries/LibGUI/GClipboard.cpp

@@ -19,7 +19,7 @@ String GClipboard::data() const
 {
     WSAPI_ClientMessage request;
     request.type = WSAPI_ClientMessage::Type::GetClipboardContents;
-    auto response = GEventLoop::current().connection().sync_request(request, WSAPI_ServerMessage::Type::DidGetClipboardContents);
+    auto response = GWindowServerConnection::the().sync_request(request, WSAPI_ServerMessage::Type::DidGetClipboardContents);
     if (response.clipboard.shared_buffer_id < 0)
         return {};
     auto shared_buffer = SharedBuffer::create_from_shared_buffer_id(response.clipboard.shared_buffer_id);
@@ -38,7 +38,7 @@ void GClipboard::set_data(const StringView& data)
 {
     WSAPI_ClientMessage request;
     request.type = WSAPI_ClientMessage::Type::SetClipboardContents;
-    auto shared_buffer = SharedBuffer::create(GEventLoop::current().connection().server_pid(), data.length() + 1);
+    auto shared_buffer = SharedBuffer::create(GWindowServerConnection::the().server_pid(), data.length() + 1);
     if (!shared_buffer) {
         dbgprintf("GClipboard::set_data() failed to create a shared buffer\n");
         return;
@@ -50,6 +50,6 @@ void GClipboard::set_data(const StringView& data)
     shared_buffer->seal();
     request.clipboard.shared_buffer_id = shared_buffer->shared_buffer_id();
     request.clipboard.contents_size = data.length();
-    auto response = GEventLoop::current().connection().sync_request(request, WSAPI_ServerMessage::Type::DidSetClipboardContents);
+    auto response = GWindowServerConnection::the().sync_request(request, WSAPI_ServerMessage::Type::DidSetClipboardContents);
     ASSERT(response.clipboard.shared_buffer_id == shared_buffer->shared_buffer_id());
 }

+ 2 - 2
Libraries/LibGUI/GDesktop.cpp

@@ -31,7 +31,7 @@ bool GDesktop::set_wallpaper(const StringView& path)
     ASSERT(path.length() < (int)sizeof(message.text));
     strncpy(message.text, path.characters_without_null_termination(), path.length());
     message.text_length = path.length();
-    auto response = GEventLoop::current().connection().sync_request(message, WSAPI_ServerMessage::Type::DidSetWallpaper);
+    auto response = GWindowServerConnection::the().sync_request(message, WSAPI_ServerMessage::Type::DidSetWallpaper);
     return response.value;
 }
 
@@ -39,6 +39,6 @@ String GDesktop::wallpaper() const
 {
     WSAPI_ClientMessage message;
     message.type = WSAPI_ClientMessage::Type::GetWallpaper;
-    auto response = GEventLoop::current().connection().sync_request(message, WSAPI_ServerMessage::Type::DidGetWallpaper);
+    auto response = GWindowServerConnection::the().sync_request(message, WSAPI_ServerMessage::Type::DidGetWallpaper);
     return String(response.text, response.text_length);
 }

+ 13 - 1
Libraries/LibGUI/GEventLoop.cpp

@@ -23,6 +23,16 @@
 //#define GEVENTLOOP_DEBUG
 //#define COALESCING_DEBUG
 
+GWindowServerConnection& GWindowServerConnection::the()
+{
+    static GWindowServerConnection* s_connection = nullptr;
+    if (!s_connection) {
+        s_connection = new GWindowServerConnection();
+        s_connection->handshake();
+    }
+    return *s_connection;
+}
+
 void GWindowServerConnection::handshake()
 {
     WSAPI_ClientMessage request;
@@ -34,7 +44,9 @@ void GWindowServerConnection::handshake()
 
 GEventLoop::GEventLoop()
 {
-    m_connection.handshake();
+    // ensure the WS connection is up, as our users might be expecting it to be
+    // valid very early (via e.g. GDesktop) :)
+    GWindowServerConnection::the();
 }
 
 GEventLoop::~GEventLoop()

+ 1 - 3
Libraries/LibGUI/GEventLoop.h

@@ -17,6 +17,7 @@ public:
     {}
 
     void handshake() override;
+    static GWindowServerConnection& the();
 
 private:
     void postprocess_bundles(Vector<IncomingMessageBundle>& m_unprocessed_bundles) override;
@@ -39,9 +40,6 @@ public:
 
     static GEventLoop& current() { return static_cast<GEventLoop&>(CEventLoop::current()); }
 
-    GWindowServerConnection& connection() { return m_connection; }
-
 private:
     void process_unprocessed_bundles();
-    GWindowServerConnection m_connection;
 };

+ 6 - 6
Libraries/LibGUI/GMenu.cpp

@@ -52,7 +52,7 @@ void GMenu::popup(const Point& screen_position)
     request.type = WSAPI_ClientMessage::Type::PopupMenu;
     request.menu.menu_id = m_menu_id;
     request.menu.position = screen_position;
-    GEventLoop::current().connection().post_message_to_server(request);
+    GWindowServerConnection::the().post_message_to_server(request);
 }
 
 void GMenu::dismiss()
@@ -62,7 +62,7 @@ void GMenu::dismiss()
     WSAPI_ClientMessage request;
     request.type = WSAPI_ClientMessage::Type::DismissMenu;
     request.menu.menu_id = m_menu_id;
-    GEventLoop::current().connection().post_message_to_server(request);
+    GWindowServerConnection::the().post_message_to_server(request);
 }
 
 int GMenu::realize_menu()
@@ -72,7 +72,7 @@ int GMenu::realize_menu()
     ASSERT(m_name.length() < (ssize_t)sizeof(request.text));
     strcpy(request.text, m_name.characters());
     request.text_length = m_name.length();
-    auto response = GEventLoop::current().connection().sync_request(request, WSAPI_ServerMessage::Type::DidCreateMenu);
+    auto response = GWindowServerConnection::the().sync_request(request, WSAPI_ServerMessage::Type::DidCreateMenu);
     m_menu_id = response.menu.menu_id;
 
 #ifdef GMENU_DEBUG
@@ -87,7 +87,7 @@ int GMenu::realize_menu()
             WSAPI_ClientMessage request;
             request.type = WSAPI_ClientMessage::Type::AddMenuSeparator;
             request.menu.menu_id = m_menu_id;
-            GEventLoop::current().connection().sync_request(request, WSAPI_ServerMessage::Type::DidAddMenuSeparator);
+            GWindowServerConnection::the().sync_request(request, WSAPI_ServerMessage::Type::DidAddMenuSeparator);
             continue;
         }
         if (item.type() == GMenuItem::Action) {
@@ -113,7 +113,7 @@ int GMenu::realize_menu()
                 request.menu.shortcut_text_length = 0;
             }
 
-            GEventLoop::current().connection().sync_request(request, WSAPI_ServerMessage::Type::DidAddMenuItem);
+            GWindowServerConnection::the().sync_request(request, WSAPI_ServerMessage::Type::DidAddMenuItem);
         }
     }
     all_menus().set(m_menu_id, this);
@@ -128,7 +128,7 @@ void GMenu::unrealize_menu()
     WSAPI_ClientMessage request;
     request.type = WSAPI_ClientMessage::Type::DestroyMenu;
     request.menu.menu_id = m_menu_id;
-    GEventLoop::current().connection().sync_request(request, WSAPI_ServerMessage::Type::DidDestroyMenu);
+    GWindowServerConnection::the().sync_request(request, WSAPI_ServerMessage::Type::DidDestroyMenu);
     m_menu_id = 0;
 }
 

+ 4 - 4
Libraries/LibGUI/GMenuBar.cpp

@@ -19,7 +19,7 @@ int GMenuBar::realize_menubar()
 {
     WSAPI_ClientMessage request;
     request.type = WSAPI_ClientMessage::Type::CreateMenubar;
-    WSAPI_ServerMessage response = GEventLoop::current().connection().sync_request(request, WSAPI_ServerMessage::Type::DidCreateMenubar);
+    WSAPI_ServerMessage response = GWindowServerConnection::the().sync_request(request, WSAPI_ServerMessage::Type::DidCreateMenubar);
     return response.menu.menubar_id;
 }
 
@@ -30,7 +30,7 @@ void GMenuBar::unrealize_menubar()
     WSAPI_ClientMessage request;
     request.type = WSAPI_ClientMessage::Type::DestroyMenubar;
     request.menu.menubar_id = m_menubar_id;
-    GEventLoop::current().connection().sync_request(request, WSAPI_ServerMessage::Type::DidDestroyMenubar);
+    GWindowServerConnection::the().sync_request(request, WSAPI_ServerMessage::Type::DidDestroyMenubar);
     m_menubar_id = -1;
 }
 
@@ -47,12 +47,12 @@ void GMenuBar::notify_added_to_application(Badge<GApplication>)
         request.type = WSAPI_ClientMessage::Type::AddMenuToMenubar;
         request.menu.menubar_id = m_menubar_id;
         request.menu.menu_id = menu_id;
-        GEventLoop::current().connection().sync_request(request, WSAPI_ServerMessage::Type::DidAddMenuToMenubar);
+        GWindowServerConnection::the().sync_request(request, WSAPI_ServerMessage::Type::DidAddMenuToMenubar);
     }
     WSAPI_ClientMessage request;
     request.type = WSAPI_ClientMessage::Type::SetApplicationMenubar;
     request.menu.menubar_id = m_menubar_id;
-    GEventLoop::current().connection().sync_request(request, WSAPI_ServerMessage::Type::DidSetApplicationMenubar);
+    GWindowServerConnection::the().sync_request(request, WSAPI_ServerMessage::Type::DidSetApplicationMenubar);
 }
 
 void GMenuBar::notify_removed_from_application(Badge<GApplication>)

+ 1 - 1
Libraries/LibGUI/GMenuItem.cpp

@@ -70,5 +70,5 @@ void GMenuItem::update_window_server()
         request.menu.shortcut_text_length = 0;
     }
 
-    GEventLoop::current().connection().sync_request(request, WSAPI_ServerMessage::Type::DidUpdateMenuItem);
+    GWindowServerConnection::the().sync_request(request, WSAPI_ServerMessage::Type::DidUpdateMenuItem);
 }

+ 18 - 18
Libraries/LibGUI/GWindow.cpp

@@ -59,7 +59,7 @@ void GWindow::move_to_front()
     WSAPI_ClientMessage request;
     request.type = WSAPI_ClientMessage::Type::MoveWindowToFront;
     request.window_id = m_window_id;
-    GEventLoop::current().connection().post_message_to_server(request);
+    GWindowServerConnection::the().post_message_to_server(request);
 }
 
 void GWindow::show()
@@ -84,7 +84,7 @@ void GWindow::show()
     ASSERT(m_title_when_windowless.length() < (ssize_t)sizeof(request.text));
     strcpy(request.text, m_title_when_windowless.characters());
     request.text_length = m_title_when_windowless.length();
-    auto response = GEventLoop::current().connection().sync_request(request, WSAPI_ServerMessage::Type::DidCreateWindow);
+    auto response = GWindowServerConnection::the().sync_request(request, WSAPI_ServerMessage::Type::DidCreateWindow);
     m_window_id = response.window_id;
 
     windows().set(m_window_id, this);
@@ -99,7 +99,7 @@ void GWindow::hide()
     WSAPI_ClientMessage request;
     request.type = WSAPI_ClientMessage::Type::DestroyWindow;
     request.window_id = m_window_id;
-    GEventLoop::current().connection().sync_request(request, WSAPI_ServerMessage::Type::DidDestroyWindow);
+    GWindowServerConnection::the().sync_request(request, WSAPI_ServerMessage::Type::DidDestroyWindow);
     m_window_id = 0;
     m_pending_paint_event_rects.clear();
     m_back_bitmap = nullptr;
@@ -118,7 +118,7 @@ void GWindow::set_title(const StringView& title)
     ASSERT(m_title_when_windowless.length() < (ssize_t)sizeof(request.text));
     strcpy(request.text, m_title_when_windowless.characters());
     request.text_length = m_title_when_windowless.length();
-    GEventLoop::current().connection().post_message_to_server(request);
+    GWindowServerConnection::the().post_message_to_server(request);
 }
 
 String GWindow::title() const
@@ -129,7 +129,7 @@ String GWindow::title() const
     WSAPI_ClientMessage request;
     request.type = WSAPI_ClientMessage::Type::GetWindowTitle;
     request.window_id = m_window_id;
-    auto response = GEventLoop::current().connection().sync_request(request, WSAPI_ServerMessage::Type::DidGetWindowTitle);
+    auto response = GWindowServerConnection::the().sync_request(request, WSAPI_ServerMessage::Type::DidGetWindowTitle);
     return String(response.text, response.text_length);
 }
 
@@ -141,7 +141,7 @@ Rect GWindow::rect() const
     WSAPI_ClientMessage request;
     request.type = WSAPI_ClientMessage::Type::GetWindowRect;
     request.window_id = m_window_id;
-    auto response = GEventLoop::current().connection().sync_request(request, WSAPI_ServerMessage::Type::DidGetWindowRect);
+    auto response = GWindowServerConnection::the().sync_request(request, WSAPI_ServerMessage::Type::DidGetWindowRect);
     ASSERT(response.window_id == m_window_id);
     return response.window.rect;
 }
@@ -158,7 +158,7 @@ void GWindow::set_rect(const Rect& a_rect)
     request.type = WSAPI_ClientMessage::Type::SetWindowRect;
     request.window_id = m_window_id;
     request.window.rect = a_rect;
-    GEventLoop::current().connection().post_message_to_server(request);
+    GWindowServerConnection::the().post_message_to_server(request);
     if (m_back_bitmap && m_back_bitmap->size() != a_rect.size())
         m_back_bitmap = nullptr;
     if (m_front_bitmap && m_front_bitmap->size() != a_rect.size())
@@ -180,7 +180,7 @@ void GWindow::set_override_cursor(GStandardCursor cursor)
     request.type = WSAPI_ClientMessage::Type::SetWindowOverrideCursor;
     request.window_id = m_window_id;
     request.cursor.cursor = (WSAPI_StandardCursor)cursor;
-    GEventLoop::current().connection().post_message_to_server(request);
+    GWindowServerConnection::the().post_message_to_server(request);
 }
 
 void GWindow::event(CEvent& event)
@@ -260,7 +260,7 @@ void GWindow::event(CEvent& event)
             ByteBuffer extra_data;
             if (rects.size() > WSAPI_ClientMessage::max_inline_rect_count)
                 extra_data = ByteBuffer::wrap(&rects[WSAPI_ClientMessage::max_inline_rect_count], (rects.size() - WSAPI_ClientMessage::max_inline_rect_count) * sizeof(WSAPI_Rect));
-            GEventLoop::current().connection().post_message_to_server(message, move(extra_data));
+            GWindowServerConnection::the().post_message_to_server(message, move(extra_data));
         }
         return;
     }
@@ -453,7 +453,7 @@ void GWindow::update(const Rect& a_rect)
             if (rects.size() > WSAPI_ClientMessage::max_inline_rect_count)
                 extra_data = ByteBuffer::wrap(&rects[WSAPI_ClientMessage::max_inline_rect_count], (rects.size() - WSAPI_ClientMessage::max_inline_rect_count) * sizeof(WSAPI_Rect));
             request.rect_count = rects.size();
-            GEventLoop::current().connection().post_message_to_server(request, move(extra_data));
+            GWindowServerConnection::the().post_message_to_server(request, move(extra_data));
         });
     }
     m_pending_paint_event_rects.append(a_rect);
@@ -524,7 +524,7 @@ void GWindow::set_has_alpha_channel(bool value)
     message.type = WSAPI_ClientMessage::Type::SetWindowHasAlphaChannel;
     message.window_id = m_window_id;
     message.value = value;
-    GEventLoop::current().connection().sync_request(message, WSAPI_ServerMessage::DidSetWindowHasAlphaChannel);
+    GWindowServerConnection::the().sync_request(message, WSAPI_ServerMessage::DidSetWindowHasAlphaChannel);
 
     update();
 }
@@ -545,7 +545,7 @@ void GWindow::set_opacity(float opacity)
     request.window_id = m_window_id;
     request.window.opacity = opacity;
     m_opacity_when_windowless = opacity;
-    GEventLoop::current().connection().post_message_to_server(request);
+    GWindowServerConnection::the().post_message_to_server(request);
 }
 
 void GWindow::set_hovered_widget(GWidget* widget)
@@ -573,7 +573,7 @@ void GWindow::set_current_backing_bitmap(GraphicsBitmap& bitmap, bool flush_imme
     message.backing.has_alpha_channel = bitmap.has_alpha_channel();
     message.backing.size = bitmap.size();
     message.backing.flush_immediately = flush_immediately;
-    GEventLoop::current().connection().sync_request(message, WSAPI_ServerMessage::Type::DidSetWindowBackingStore);
+    GWindowServerConnection::the().sync_request(message, WSAPI_ServerMessage::Type::DidSetWindowBackingStore);
 }
 
 void GWindow::flip(const Vector<Rect, 32>& dirty_rects)
@@ -596,11 +596,11 @@ void GWindow::flip(const Vector<Rect, 32>& dirty_rects)
 
 NonnullRefPtr<GraphicsBitmap> GWindow::create_backing_bitmap(const Size& size)
 {
-    ASSERT(GEventLoop::current().connection().server_pid());
+    ASSERT(GWindowServerConnection::the().server_pid());
     ASSERT(!size.is_empty());
     size_t pitch = round_up_to_power_of_two(size.width() * sizeof(RGBA32), 16);
     size_t size_in_bytes = size.height() * pitch;
-    auto shared_buffer = SharedBuffer::create(GEventLoop::current().connection().server_pid(), size_in_bytes);
+    auto shared_buffer = SharedBuffer::create(GWindowServerConnection::the().server_pid(), size_in_bytes);
     ASSERT(shared_buffer);
     auto format = m_has_alpha_channel ? GraphicsBitmap::Format::RGBA32 : GraphicsBitmap::Format::RGB32;
     return GraphicsBitmap::create_with_shared_buffer(format, *shared_buffer, size);
@@ -629,16 +629,16 @@ void GWindow::set_icon_path(const StringView& path)
     ASSERT(path.length() < (int)sizeof(message.text));
     strcpy(message.text, String(path).characters());
     message.text_length = path.length();
-    GEventLoop::current().connection().post_message_to_server(message);
+    GWindowServerConnection::the().post_message_to_server(message);
 }
 
 void GWindow::start_wm_resize()
 {
     WSAPI_ClientMessage message;
     message.type = WSAPI_ClientMessage::Type::WM_StartWindowResize;
-    message.wm.client_id = GEventLoop::current().connection().my_client_id();
+    message.wm.client_id = GWindowServerConnection::the().my_client_id();
     message.wm.window_id = m_window_id;
-    GEventLoop::current().connection().post_message_to_server(message);
+    GWindowServerConnection::the().post_message_to_server(message);
 }
 
 Vector<GWidget*> GWindow::focusable_widgets() const