diff --git a/Libraries/LibGUI/WindowServerConnection.cpp b/Libraries/LibGUI/WindowServerConnection.cpp index 7a0abb23e3..90623e18dd 100644 --- a/Libraries/LibGUI/WindowServerConnection.cpp +++ b/Libraries/LibGUI/WindowServerConnection.cpp @@ -342,7 +342,14 @@ void WindowServerConnection::handle(const Messages::WindowClient::WindowStateCha void WindowServerConnection::handle(const Messages::WindowClient::DisplayLinkNotification&) { - DisplayLink::notify({}); + if (m_display_link_notification_pending) + return; + + m_display_link_notification_pending = true; + deferred_invoke([this](auto&) { + DisplayLink::notify({}); + m_display_link_notification_pending = false; + }); } } diff --git a/Libraries/LibGUI/WindowServerConnection.h b/Libraries/LibGUI/WindowServerConnection.h index e50223a34d..9ae71a9795 100644 --- a/Libraries/LibGUI/WindowServerConnection.h +++ b/Libraries/LibGUI/WindowServerConnection.h @@ -75,6 +75,8 @@ private: virtual void handle(const Messages::WindowClient::UpdateSystemTheme&) override; virtual void handle(const Messages::WindowClient::WindowStateChanged&) override; virtual void handle(const Messages::WindowClient::DisplayLinkNotification&) override; + + bool m_display_link_notification_pending { false }; }; } diff --git a/Servers/WindowServer/ClientConnection.cpp b/Servers/WindowServer/ClientConnection.cpp index 8a4d61bf41..cd272d3a79 100644 --- a/Servers/WindowServer/ClientConnection.cpp +++ b/Servers/WindowServer/ClientConnection.cpp @@ -88,6 +88,9 @@ ClientConnection::ClientConnection(Core::LocalSocket& client_socket, int client_ ClientConnection::~ClientConnection() { + if (m_has_display_link) + Compositor::the().decrement_display_link_count({}); + MenuManager::the().close_all_menus_from_client({}, *this); auto windows = move(m_windows); for (auto& window : windows) { @@ -772,12 +775,18 @@ OwnPtr Client void ClientConnection::handle(const Messages::WindowServer::EnableDisplayLink&) { + if (m_has_display_link) + return; m_has_display_link = true; + Compositor::the().increment_display_link_count({}); } void ClientConnection::handle(const Messages::WindowServer::DisableDisplayLink&) { + if (!m_has_display_link) + return; m_has_display_link = false; + Compositor::the().decrement_display_link_count({}); } void ClientConnection::notify_display_link(Badge) diff --git a/Servers/WindowServer/Compositor.cpp b/Servers/WindowServer/Compositor.cpp index caaede8a6f..e1622093fc 100644 --- a/Servers/WindowServer/Compositor.cpp +++ b/Servers/WindowServer/Compositor.cpp @@ -60,10 +60,15 @@ WallpaperMode mode_to_enum(const String& name) Compositor::Compositor() { + m_display_link_notify_timer = add( + 1000 / 60, [this] { + notify_display_links(); + }); + m_display_link_notify_timer->stop(); + m_compose_timer = Core::Timer::create_single_shot( 1000 / 60, [this] { - notify_display_links(); compose(); }, this); @@ -488,4 +493,19 @@ void Compositor::notify_display_links() }); } +void Compositor::increment_display_link_count(Badge) +{ + ++m_display_link_count; + if (m_display_link_count == 1) + m_display_link_notify_timer->start(); +} + +void Compositor::decrement_display_link_count(Badge) +{ + ASSERT(m_display_link_count); + --m_display_link_count; + if (!m_display_link_count) + m_display_link_notify_timer->stop(); +} + } diff --git a/Servers/WindowServer/Compositor.h b/Servers/WindowServer/Compositor.h index a1f654de01..fa86276405 100644 --- a/Servers/WindowServer/Compositor.h +++ b/Servers/WindowServer/Compositor.h @@ -34,6 +34,7 @@ namespace WindowServer { +class ClientConnection; class Cursor; enum class WallpaperMode { @@ -65,6 +66,9 @@ public: void invalidate_cursor(); Gfx::Rect current_cursor_rect() const; + void increment_display_link_count(Badge); + void decrement_display_link_count(Badge); + private: Compositor(); void init_bitmaps(); @@ -96,6 +100,9 @@ private: String m_wallpaper_path; WallpaperMode m_wallpaper_mode { WallpaperMode::Unchecked }; RefPtr m_wallpaper; + + RefPtr m_display_link_notify_timer; + size_t m_display_link_count { 0 }; }; }