summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Applications/Taskbar/TaskbarButton.cpp10
-rw-r--r--Applications/Taskbar/TaskbarButton.h1
-rw-r--r--Servers/WindowServer/WSClientConnection.cpp16
-rw-r--r--Servers/WindowServer/WSClientConnection.h1
-rw-r--r--Servers/WindowServer/WSCompositor.cpp36
-rw-r--r--Servers/WindowServer/WSWindow.cpp1
-rw-r--r--Servers/WindowServer/WSWindow.h12
-rw-r--r--Servers/WindowServer/WindowServer.ipc1
8 files changed, 78 insertions, 0 deletions
diff --git a/Applications/Taskbar/TaskbarButton.cpp b/Applications/Taskbar/TaskbarButton.cpp
index d1c1d6ae94..35ebc82bb3 100644
--- a/Applications/Taskbar/TaskbarButton.cpp
+++ b/Applications/Taskbar/TaskbarButton.cpp
@@ -16,3 +16,13 @@ void TaskbarButton::context_menu_event(GContextMenuEvent&)
{
GWindowServerConnection::the().post_message(WindowServer::WM_PopupWindowMenu(m_identifier.client_id(), m_identifier.window_id(), screen_relative_rect().location()));
}
+
+void TaskbarButton::resize_event(GResizeEvent& event)
+{
+ GWindowServerConnection::the().post_message(
+ WindowServer::WM_SetWindowTaskbarRect(
+ m_identifier.client_id(),
+ m_identifier.window_id(),
+ screen_relative_rect()));
+ return GButton::resize_event(event);
+}
diff --git a/Applications/Taskbar/TaskbarButton.h b/Applications/Taskbar/TaskbarButton.h
index 95be9a4f8f..546a6f1192 100644
--- a/Applications/Taskbar/TaskbarButton.h
+++ b/Applications/Taskbar/TaskbarButton.h
@@ -11,6 +11,7 @@ public:
private:
virtual void context_menu_event(GContextMenuEvent&) override;
+ virtual void resize_event(GResizeEvent&) override;
WindowIdentifier m_identifier;
};
diff --git a/Servers/WindowServer/WSClientConnection.cpp b/Servers/WindowServer/WSClientConnection.cpp
index 7f3e26efdb..3d365d3682 100644
--- a/Servers/WindowServer/WSClientConnection.cpp
+++ b/Servers/WindowServer/WSClientConnection.cpp
@@ -612,3 +612,19 @@ bool WSClientConnection::is_showing_modal_window() const
}
return false;
}
+
+void WSClientConnection::handle(const WindowServer::WM_SetWindowTaskbarRect& message)
+{
+ auto* client = WSClientConnection::from_client_id(message.client_id());
+ if (!client) {
+ did_misbehave("WM_SetWindowTaskbarRect: Bad client ID");
+ return;
+ }
+ auto it = client->m_windows.find(message.window_id());
+ if (it == client->m_windows.end()) {
+ did_misbehave("WM_SetWindowTaskbarRect: Bad window ID");
+ return;
+ }
+ auto& window = *(*it).value;
+ window.set_taskbar_rect(message.rect());
+}
diff --git a/Servers/WindowServer/WSClientConnection.h b/Servers/WindowServer/WSClientConnection.h
index f0898ac6ad..9f50a0c901 100644
--- a/Servers/WindowServer/WSClientConnection.h
+++ b/Servers/WindowServer/WSClientConnection.h
@@ -86,6 +86,7 @@ private:
virtual OwnPtr<WindowServer::PopupMenuResponse> handle(const WindowServer::PopupMenu&) override;
virtual OwnPtr<WindowServer::DismissMenuResponse> handle(const WindowServer::DismissMenu&) override;
virtual OwnPtr<WindowServer::SetWindowIconBitmapResponse> handle(const WindowServer::SetWindowIconBitmap&) override;
+ virtual void handle(const WindowServer::WM_SetWindowTaskbarRect&) override;
HashMap<int, NonnullRefPtr<WSWindow>> m_windows;
HashMap<int, NonnullOwnPtr<WSMenuBar>> m_menubars;
diff --git a/Servers/WindowServer/WSCompositor.cpp b/Servers/WindowServer/WSCompositor.cpp
index 98c16dd5b2..bf93ad7fd1 100644
--- a/Servers/WindowServer/WSCompositor.cpp
+++ b/Servers/WindowServer/WSCompositor.cpp
@@ -212,6 +212,42 @@ void WSCompositor::compose()
draw_geometry_label();
}
+ static const int minimize_animation_steps = 10;
+
+ wm.for_each_window([&](WSWindow& window) {
+ if (window.in_minimize_animation()) {
+ int animation_index = window.minimize_animation_index();
+
+ auto from_rect = window.is_minimized() ? window.frame().rect() : window.taskbar_rect();
+ auto to_rect = window.is_minimized() ? window.taskbar_rect() : window.frame().rect();
+
+ float x_delta_per_step = (float)(from_rect.x() - to_rect.x()) / minimize_animation_steps;
+ float y_delta_per_step = (float)(from_rect.y() - to_rect.y()) / minimize_animation_steps;
+ float width_delta_per_step = (float)(from_rect.width() - to_rect.width()) / minimize_animation_steps;
+ float height_delta_per_step = (float)(from_rect.height() - to_rect.height()) / minimize_animation_steps;
+
+ Rect rect {
+ from_rect.x() - (int)(x_delta_per_step * animation_index),
+ from_rect.y() - (int)(y_delta_per_step * animation_index),
+ from_rect.width() - (int)(width_delta_per_step * animation_index),
+ from_rect.height() - (int)(height_delta_per_step * animation_index)
+ };
+
+#ifdef MINIMIZE_ANIMATION_DEBUG
+ dbg() << "Minimize animation from " << from_rect << " to " << to_rect << " frame# " << animation_index << " " << rect;
+#endif
+
+ m_back_painter->draw_rect(rect, Color::White);
+
+ window.step_minimize_animation();
+ if (window.minimize_animation_index() >= minimize_animation_steps)
+ window.end_minimize_animation();
+
+ invalidate(rect);
+ }
+ return IterationDecision::Continue;
+ });
+
draw_cursor();
if (m_flash_flush) {
diff --git a/Servers/WindowServer/WSWindow.cpp b/Servers/WindowServer/WSWindow.cpp
index 855ece5094..d1fd08bfe7 100644
--- a/Servers/WindowServer/WSWindow.cpp
+++ b/Servers/WindowServer/WSWindow.cpp
@@ -103,6 +103,7 @@ void WSWindow::set_minimized(bool minimized)
if (m_minimized == minimized)
return;
m_minimized = minimized;
+ start_minimize_animation();
if (!minimized)
request_update({ {}, size() });
invalidate();
diff --git a/Servers/WindowServer/WSWindow.h b/Servers/WindowServer/WSWindow.h
index 0be54481ca..9276a6a192 100644
--- a/Servers/WindowServer/WSWindow.h
+++ b/Servers/WindowServer/WSWindow.h
@@ -102,6 +102,9 @@ public:
void set_rect_from_window_manager_resize(const Rect&);
+ void set_taskbar_rect(const Rect& rect) { m_taskbar_rect = rect; }
+ const Rect& taskbar_rect() const { return m_taskbar_rect; }
+
void move_to(const Point& position) { set_rect({ position, size() }); }
void move_to(int x, int y) { move_to({ x, y }); }
@@ -152,6 +155,13 @@ public:
void request_update(const Rect&);
DisjointRectSet take_pending_paint_rects() { return move(m_pending_paint_rects); }
+ bool in_minimize_animation() const { return m_minimize_animation_step != -1; }
+
+ int minimize_animation_index() const { return m_minimize_animation_step; }
+ void step_minimize_animation() { m_minimize_animation_step += 1; }
+ void start_minimize_animation() { m_minimize_animation_step = 0; }
+ void end_minimize_animation() { m_minimize_animation_step = -1; }
+
// For InlineLinkedList.
// FIXME: Maybe make a ListHashSet and then WSWindowManager can just use that.
WSWindow* m_next { nullptr };
@@ -164,6 +174,7 @@ private:
String m_title;
Rect m_rect;
Rect m_saved_nonfullscreen_rect;
+ Rect m_taskbar_rect;
WSWindowType m_type { WSWindowType::Normal };
bool m_global_cursor_tracking_enabled { false };
bool m_automatic_cursor_tracking_enabled { false };
@@ -190,4 +201,5 @@ private:
DisjointRectSet m_pending_paint_rects;
Rect m_unmaximized_rect;
RefPtr<WSMenu> m_window_menu;
+ int m_minimize_animation_step { -1 };
};
diff --git a/Servers/WindowServer/WindowServer.ipc b/Servers/WindowServer/WindowServer.ipc
index e75ad0daf0..883d820219 100644
--- a/Servers/WindowServer/WindowServer.ipc
+++ b/Servers/WindowServer/WindowServer.ipc
@@ -52,6 +52,7 @@ endpoint WindowServer = 2
WM_SetWindowMinimized(i32 client_id, i32 window_id, bool minimized) =|
WM_StartWindowResize(i32 client_id, i32 window_id) =|
WM_PopupWindowMenu(i32 client_id, i32 window_id, Point screen_position) =|
+ WM_SetWindowTaskbarRect(i32 client_id, i32 window_id, Rect rect) =|
SetWindowHasAlphaChannel(i32 window_id, bool has_alpha_channel) => ()
MoveWindowToFront(i32 window_id) => ()