From 1d6ec51beece130ed8b3c8787b45e83bfe35dbf9 Mon Sep 17 00:00:00 2001 From: Andreas Kling Date: Sat, 30 May 2020 22:08:26 +0200 Subject: [PATCH] WindowServer+LibGUI: Add per-window progress Each window now has an associated progress integer that can be updated via the SetWindowProgress IPC call. This can be used by clients to indicate the progress of ongoing tasks. Any number in the range 0 through 100 indicate a progress percentage. Any other number means "no progress" --- Libraries/LibGUI/Event.h | 5 ++++- Libraries/LibGUI/Window.cpp | 6 ++++++ Libraries/LibGUI/Window.h | 2 ++ Libraries/LibGUI/WindowServerConnection.cpp | 2 +- Services/WindowServer/ClientConnection.cpp | 10 ++++++++++ Services/WindowServer/ClientConnection.h | 1 + Services/WindowServer/Window.cpp | 9 +++++++++ Services/WindowServer/Window.h | 4 ++++ Services/WindowServer/WindowClient.ipc | 2 +- Services/WindowServer/WindowManager.cpp | 7 ++++++- Services/WindowServer/WindowManager.h | 1 + Services/WindowServer/WindowServer.ipc | 2 ++ 12 files changed, 47 insertions(+), 4 deletions(-) diff --git a/Libraries/LibGUI/Event.h b/Libraries/LibGUI/Event.h index 1dd6dec569c..b8dbe6d73e3 100644 --- a/Libraries/LibGUI/Event.h +++ b/Libraries/LibGUI/Event.h @@ -111,7 +111,7 @@ public: class WMWindowStateChangedEvent : public WMEvent { public: - WMWindowStateChangedEvent(int client_id, int window_id, const StringView& title, const Gfx::Rect& rect, bool is_active, WindowType window_type, bool is_minimized, bool is_frameless) + WMWindowStateChangedEvent(int client_id, int window_id, const StringView& title, const Gfx::Rect& rect, bool is_active, WindowType window_type, bool is_minimized, bool is_frameless, int progress) : WMEvent(Event::Type::WM_WindowStateChanged, client_id, window_id) , m_title(title) , m_rect(rect) @@ -119,6 +119,7 @@ public: , m_active(is_active) , m_minimized(is_minimized) , m_frameless(is_frameless) + , m_progress(progress) { } @@ -128,6 +129,7 @@ public: WindowType window_type() const { return m_window_type; } bool is_minimized() const { return m_minimized; } bool is_frameless() const { return m_frameless; } + int progress() const { return m_progress; } private: String m_title; @@ -136,6 +138,7 @@ private: bool m_active; bool m_minimized; bool m_frameless; + int m_progress; }; class WMWindowRectChangedEvent : public WMEvent { diff --git a/Libraries/LibGUI/Window.cpp b/Libraries/LibGUI/Window.cpp index 805c8353f0c..91d435c68b8 100644 --- a/Libraries/LibGUI/Window.cpp +++ b/Libraries/LibGUI/Window.cpp @@ -779,4 +779,10 @@ void Window::did_remove_widget(Badge, Widget& widget) m_automatic_cursor_tracking_widget = nullptr; } +void Window::set_progress(int progress) +{ + ASSERT(m_window_id); + WindowServerConnection::the().post_message(Messages::WindowServer::SetWindowProgress(m_window_id, progress)); +} + } diff --git a/Libraries/LibGUI/Window.h b/Libraries/LibGUI/Window.h index c2ca561f60f..f8d8428a64f 100644 --- a/Libraries/LibGUI/Window.h +++ b/Libraries/LibGUI/Window.h @@ -188,6 +188,8 @@ public: Window* find_parent_window(); + void set_progress(int); + protected: Window(Core::Object* parent = nullptr); virtual void wm_event(WMEvent&); diff --git a/Libraries/LibGUI/WindowServerConnection.cpp b/Libraries/LibGUI/WindowServerConnection.cpp index 38ef7f0f8b1..afa94e5768c 100644 --- a/Libraries/LibGUI/WindowServerConnection.cpp +++ b/Libraries/LibGUI/WindowServerConnection.cpp @@ -266,7 +266,7 @@ void WindowServerConnection::handle(const Messages::WindowClient::MenuItemActiva void WindowServerConnection::handle(const Messages::WindowClient::WM_WindowStateChanged& message) { if (auto* window = Window::from_window_id(message.wm_id())) - Core::EventLoop::current().post_event(*window, make(message.client_id(), message.window_id(), message.title(), message.rect(), message.is_active(), static_cast(message.window_type()), message.is_minimized(), message.is_frameless())); + Core::EventLoop::current().post_event(*window, make(message.client_id(), message.window_id(), message.title(), message.rect(), message.is_active(), static_cast(message.window_type()), message.is_minimized(), message.is_frameless(), message.progress())); } void WindowServerConnection::handle(const Messages::WindowClient::WM_WindowRectChanged& message) diff --git a/Services/WindowServer/ClientConnection.cpp b/Services/WindowServer/ClientConnection.cpp index e476124b9d0..51d645d5781 100644 --- a/Services/WindowServer/ClientConnection.cpp +++ b/Services/WindowServer/ClientConnection.cpp @@ -810,4 +810,14 @@ void ClientConnection::notify_display_link(Badge) post_message(Messages::WindowClient::DisplayLinkNotification()); } +void ClientConnection::handle(const Messages::WindowServer::SetWindowProgress& message) +{ + auto it = m_windows.find(message.window_id()); + if (it == m_windows.end()) { + did_misbehave("SetWindowProgress with bad window ID"); + return; + } + it->value->set_progress(message.progress()); +} + } diff --git a/Services/WindowServer/ClientConnection.h b/Services/WindowServer/ClientConnection.h index 3ae22199b22..a871b636e87 100644 --- a/Services/WindowServer/ClientConnection.h +++ b/Services/WindowServer/ClientConnection.h @@ -133,6 +133,7 @@ private: virtual OwnPtr handle(const Messages::WindowServer::SetWindowBaseSizeAndSizeIncrement&) override; virtual void handle(const Messages::WindowServer::EnableDisplayLink&) override; virtual void handle(const Messages::WindowServer::DisableDisplayLink&) override; + virtual void handle(const Messages::WindowServer::SetWindowProgress&) override; Window* window_from_id(i32 window_id); diff --git a/Services/WindowServer/Window.cpp b/Services/WindowServer/Window.cpp index 874f518ef5f..e816935da80 100644 --- a/Services/WindowServer/Window.cpp +++ b/Services/WindowServer/Window.cpp @@ -537,4 +537,13 @@ void Window::set_parent_window(Window& parent_window) parent_window.add_child_window(*this); } +void Window::set_progress(int progress) +{ + if (m_progress == progress) + return; + + m_progress = progress; + WindowManager::the().notify_progress_changed(*this); +} + } diff --git a/Services/WindowServer/Window.h b/Services/WindowServer/Window.h index 09856c96dd2..b931b939558 100644 --- a/Services/WindowServer/Window.h +++ b/Services/WindowServer/Window.h @@ -232,6 +232,9 @@ public: void set_frameless(bool frameless) { m_frameless = frameless; } bool is_frameless() const { return m_frameless; } + int progress() const { return m_progress; } + void set_progress(int); + private: void handle_mouse_event(const MouseEvent&); void update_menu_item_text(PopupMenuItem item); @@ -281,6 +284,7 @@ private: MenuItem* m_window_menu_minimize_item { nullptr }; MenuItem* m_window_menu_maximize_item { nullptr }; int m_minimize_animation_step { -1 }; + int m_progress { -1 }; }; } diff --git a/Services/WindowServer/WindowClient.ipc b/Services/WindowServer/WindowClient.ipc index 37e369de7e1..ddcdcb6cf75 100644 --- a/Services/WindowServer/WindowClient.ipc +++ b/Services/WindowServer/WindowClient.ipc @@ -21,7 +21,7 @@ endpoint WindowClient = 4 ScreenRectChanged(Gfx::Rect rect) =| WM_WindowRemoved(i32 wm_id, i32 client_id, i32 window_id) =| - WM_WindowStateChanged(i32 wm_id, i32 client_id, i32 window_id, bool is_active, bool is_minimized, bool is_frameless, i32 window_type, [UTF8] String title, Gfx::Rect rect) =| + WM_WindowStateChanged(i32 wm_id, i32 client_id, i32 window_id, bool is_active, bool is_minimized, bool is_frameless, i32 window_type, [UTF8] String title, Gfx::Rect rect, i32 progress) =| WM_WindowIconBitmapChanged(i32 wm_id, i32 client_id, i32 window_id, i32 icon_buffer_id, Gfx::Size icon_size) =| WM_WindowRectChanged(i32 wm_id, i32 client_id, i32 window_id, Gfx::Rect rect) =| diff --git a/Services/WindowServer/WindowManager.cpp b/Services/WindowServer/WindowManager.cpp index 977f892d7d1..5d900fd9309 100644 --- a/Services/WindowServer/WindowManager.cpp +++ b/Services/WindowServer/WindowManager.cpp @@ -253,7 +253,7 @@ void WindowManager::tell_wm_listener_about_window(Window& listener, Window& wind return; if (window.is_internal()) return; - listener.client()->post_message(Messages::WindowClient::WM_WindowStateChanged(listener.window_id(), window.client_id(), window.window_id(), window.is_active(), window.is_minimized(), window.is_frameless(), (i32)window.type(), window.title(), window.rect())); + listener.client()->post_message(Messages::WindowClient::WM_WindowStateChanged(listener.window_id(), window.client_id(), window.window_id(), window.is_active(), window.is_minimized(), window.is_frameless(), (i32)window.type(), window.title(), window.rect(), window.progress())); } void WindowManager::tell_wm_listener_about_window_rect(Window& listener, Window& window) @@ -359,6 +359,11 @@ void WindowManager::notify_occlusion_state_changed(Window& window) window.client()->post_message(Messages::WindowClient::WindowStateChanged(window.window_id(), window.is_minimized(), window.is_occluded())); } +void WindowManager::notify_progress_changed(Window& window) +{ + tell_wm_listeners_window_state_changed(window); +} + void WindowManager::pick_new_active_window() { bool new_window_picked = false; diff --git a/Services/WindowServer/WindowManager.h b/Services/WindowServer/WindowManager.h index a3bb68d0849..14688e0a266 100644 --- a/Services/WindowServer/WindowManager.h +++ b/Services/WindowServer/WindowManager.h @@ -92,6 +92,7 @@ public: void notify_minimization_state_changed(Window&); void notify_opacity_changed(Window&); void notify_occlusion_state_changed(Window&); + void notify_progress_changed(Window&); void notify_client_changed_app_menubar(ClientConnection&); Gfx::Rect maximized_window_rect(const Window&) const; diff --git a/Services/WindowServer/WindowServer.ipc b/Services/WindowServer/WindowServer.ipc index dbd3c069571..3b08a7dd838 100644 --- a/Services/WindowServer/WindowServer.ipc +++ b/Services/WindowServer/WindowServer.ipc @@ -49,6 +49,8 @@ endpoint WindowServer = 2 SetWindowTitle(i32 window_id, [UTF8] String title) => () GetWindowTitle(i32 window_id) => ([UTF8] String title) + SetWindowProgress(i32 window_id, i32 progress) =| + SetWindowRect(i32 window_id, Gfx::Rect rect) => (Gfx::Rect rect) GetWindowRect(i32 window_id) => (Gfx::Rect rect)