From 1a38ab0ca158f1a4fd22fccd3b1cbbd795d41249 Mon Sep 17 00:00:00 2001 From: Andreas Kling Date: Tue, 5 Apr 2022 17:40:53 +0200 Subject: [PATCH] WindowServer+LibGUI: Notify windows when their maximized state changes Previously, GUI::Window::is_maximized() had to make a synchronous IPC request to WindowServer in order to find out if the window was indeed maximized. This patch removes the need for synchronous IPC by instead pushing the maximization state to clients when it changes. The motivation for this change was that GUI::Statusbar was checking if the containing window was maximized in its resize_event(), causing all windows with a statusbar to block on sync IPC *during* resize. Browser would typically block for ~15 milliseconds here every time on my machine, continuously during live resize. --- .../LibGUI/ConnectionToWindowServer.cpp | 4 ++-- .../Libraries/LibGUI/ConnectionToWindowServer.h | 2 +- Userland/Libraries/LibGUI/Window.cpp | 16 +++++----------- Userland/Libraries/LibGUI/Window.h | 6 +++--- Userland/Services/WindowServer/Window.cpp | 2 ++ Userland/Services/WindowServer/WindowClient.ipc | 2 +- Userland/Services/WindowServer/WindowManager.cpp | 4 ++-- 7 files changed, 16 insertions(+), 20 deletions(-) diff --git a/Userland/Libraries/LibGUI/ConnectionToWindowServer.cpp b/Userland/Libraries/LibGUI/ConnectionToWindowServer.cpp index 93c49ae504..1314716395 100644 --- a/Userland/Libraries/LibGUI/ConnectionToWindowServer.cpp +++ b/Userland/Libraries/LibGUI/ConnectionToWindowServer.cpp @@ -372,10 +372,10 @@ void ConnectionToWindowServer::drag_cancelled() Application::the()->notify_drag_cancelled({}); } -void ConnectionToWindowServer::window_state_changed(i32 window_id, bool minimized, bool occluded) +void ConnectionToWindowServer::window_state_changed(i32 window_id, bool minimized, bool maximized, bool occluded) { if (auto* window = Window::from_window_id(window_id)) - window->notify_state_changed({}, minimized, occluded); + window->notify_state_changed({}, minimized, maximized, occluded); } void ConnectionToWindowServer::display_link_notification() diff --git a/Userland/Libraries/LibGUI/ConnectionToWindowServer.h b/Userland/Libraries/LibGUI/ConnectionToWindowServer.h index b17a55dee0..e1eb0f5fbd 100644 --- a/Userland/Libraries/LibGUI/ConnectionToWindowServer.h +++ b/Userland/Libraries/LibGUI/ConnectionToWindowServer.h @@ -53,7 +53,7 @@ private: virtual void drag_cancelled() override; virtual void update_system_theme(Core::AnonymousBuffer const&) override; virtual void update_system_fonts(String const&, String const&) override; - virtual void window_state_changed(i32, bool, bool) override; + virtual void window_state_changed(i32, bool, bool, bool) override; virtual void display_link_notification() override; virtual void track_mouse_move(Gfx::IntPoint const&) override; virtual void ping() override; diff --git a/Userland/Libraries/LibGUI/Window.cpp b/Userland/Libraries/LibGUI/Window.cpp index 7035d39c38..50d69ff553 100644 --- a/Userland/Libraries/LibGUI/Window.cpp +++ b/Userland/Libraries/LibGUI/Window.cpp @@ -169,7 +169,7 @@ void Window::show() return IterationDecision::Continue; }); - set_maximized(m_maximized_when_windowless); + set_maximized(m_maximized); reified_windows->set(m_window_id, this); Application::the()->did_create_window({}); update(); @@ -1019,17 +1019,9 @@ void Window::set_forced_shadow(bool shadow) ConnectionToWindowServer::the().async_set_forced_shadow(m_window_id, shadow); } -bool Window::is_maximized() const -{ - if (!is_visible()) - return m_maximized_when_windowless; - - return ConnectionToWindowServer::the().is_maximized(m_window_id); -} - void Window::set_maximized(bool maximized) { - m_maximized_when_windowless = maximized; + m_maximized = maximized; if (!is_visible()) return; @@ -1069,10 +1061,12 @@ void Window::update_all_windows(Badge) } } -void Window::notify_state_changed(Badge, bool minimized, bool occluded) +void Window::notify_state_changed(Badge, bool minimized, bool maximized, bool occluded) { m_visible_for_timer_purposes = !minimized && !occluded; + m_maximized = maximized; + // When double buffering is enabled, minimization/occlusion means we can mark the front bitmap volatile (in addition to the back bitmap.) // When double buffering is disabled, there is only the back bitmap (which we can now mark volatile!) auto& store = m_double_buffering_enabled ? m_front_store : m_back_store; diff --git a/Userland/Libraries/LibGUI/Window.h b/Userland/Libraries/LibGUI/Window.h index d8c10ba877..ae65d6db6a 100644 --- a/Userland/Libraries/LibGUI/Window.h +++ b/Userland/Libraries/LibGUI/Window.h @@ -39,7 +39,7 @@ public: bool is_fullscreen() const { return m_fullscreen; } void set_fullscreen(bool); - bool is_maximized() const; + bool is_maximized() const { return m_maximized; } void set_maximized(bool); bool is_frameless() const { return m_frameless; } @@ -192,7 +192,7 @@ public: static void for_each_window(Badge, Function); static void update_all_windows(Badge); - void notify_state_changed(Badge, bool minimized, bool occluded); + void notify_state_changed(Badge, bool minimized, bool maximized, bool occluded); virtual bool is_visible_for_timer_purposes() const override { return m_visible_for_timer_purposes; } @@ -290,7 +290,7 @@ private: Optional m_resize_aspect_ratio {}; bool m_minimizable { true }; bool m_closeable { true }; - bool m_maximized_when_windowless { false }; + bool m_maximized { false }; bool m_fullscreen { false }; bool m_frameless { false }; bool m_forced_shadow { false }; diff --git a/Userland/Services/WindowServer/Window.cpp b/Userland/Services/WindowServer/Window.cpp index f372aff82c..525fbea829 100644 --- a/Userland/Services/WindowServer/Window.cpp +++ b/Userland/Services/WindowServer/Window.cpp @@ -497,6 +497,8 @@ void Window::set_maximized(bool maximized, Optional fixed_point) m_frame.did_set_maximized({}, maximized); Core::EventLoop::current().post_event(*this, make(m_rect)); set_default_positioned(false); + + WindowManager::the().notify_minimization_state_changed(*this); } void Window::set_always_on_top(bool always_on_top) diff --git a/Userland/Services/WindowServer/WindowClient.ipc b/Userland/Services/WindowServer/WindowClient.ipc index 822d4a8ba9..0c67af3830 100644 --- a/Userland/Services/WindowServer/WindowClient.ipc +++ b/Userland/Services/WindowServer/WindowClient.ipc @@ -19,7 +19,7 @@ endpoint WindowClient key_up(i32 window_id, u32 code_point, u32 key, u32 modifiers, u32 scancode) =| window_activated(i32 window_id) =| window_deactivated(i32 window_id) =| - window_state_changed(i32 window_id, bool minimized, bool occluded) =| + window_state_changed(i32 window_id, bool minimized, bool maximized, bool occluded) =| window_close_request(i32 window_id) =| window_resized(i32 window_id, Gfx::IntRect new_rect) =| diff --git a/Userland/Services/WindowServer/WindowManager.cpp b/Userland/Services/WindowServer/WindowManager.cpp index bdbbe2c1a5..097f02d6c9 100644 --- a/Userland/Services/WindowServer/WindowManager.cpp +++ b/Userland/Services/WindowServer/WindowManager.cpp @@ -625,7 +625,7 @@ void WindowManager::notify_minimization_state_changed(Window& window) tell_wms_window_state_changed(window); if (window.client()) - window.client()->async_window_state_changed(window.window_id(), window.is_minimized(), window.is_occluded()); + window.client()->async_window_state_changed(window.window_id(), window.is_minimized(), window.is_maximized(), window.is_occluded()); if (window.is_active() && window.is_minimized()) pick_new_active_window(&window); @@ -634,7 +634,7 @@ void WindowManager::notify_minimization_state_changed(Window& window) void WindowManager::notify_occlusion_state_changed(Window& window) { if (window.client()) - window.client()->async_window_state_changed(window.window_id(), window.is_minimized(), window.is_occluded()); + window.client()->async_window_state_changed(window.window_id(), window.is_minimized(), window.is_maximized(), window.is_occluded()); } void WindowManager::notify_progress_changed(Window& window)