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"
This commit is contained in:
Andreas Kling 2020-05-30 22:08:26 +02:00
parent 8449f0a15b
commit 1d6ec51bee
Notes: sideshowbarker 2024-07-19 05:56:02 +09:00
12 changed files with 47 additions and 4 deletions

View file

@ -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 {

View file

@ -779,4 +779,10 @@ void Window::did_remove_widget(Badge<Widget>, 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));
}
}

View file

@ -188,6 +188,8 @@ public:
Window* find_parent_window();
void set_progress(int);
protected:
Window(Core::Object* parent = nullptr);
virtual void wm_event(WMEvent&);

View file

@ -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<WMWindowStateChangedEvent>(message.client_id(), message.window_id(), message.title(), message.rect(), message.is_active(), static_cast<WindowType>(message.window_type()), message.is_minimized(), message.is_frameless()));
Core::EventLoop::current().post_event(*window, make<WMWindowStateChangedEvent>(message.client_id(), message.window_id(), message.title(), message.rect(), message.is_active(), static_cast<WindowType>(message.window_type()), message.is_minimized(), message.is_frameless(), message.progress()));
}
void WindowServerConnection::handle(const Messages::WindowClient::WM_WindowRectChanged& message)

View file

@ -810,4 +810,14 @@ void ClientConnection::notify_display_link(Badge<Compositor>)
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());
}
}

View file

@ -133,6 +133,7 @@ private:
virtual OwnPtr<Messages::WindowServer::SetWindowBaseSizeAndSizeIncrementResponse> 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);

View file

@ -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);
}
}

View file

@ -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 };
};
}

View file

@ -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) =|

View file

@ -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;

View file

@ -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;

View file

@ -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)