mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2024-11-22 15:40:19 +00:00
WindowServer: Find parent taskbar rect for minimize animation
If a modal window is being minimized, it may not have its own taskbar rectangle. In that case, try finding a parent in the modal window stack that does have one, and use that for the animation.
This commit is contained in:
parent
e035640cd5
commit
2552e3be00
Notes:
sideshowbarker
2024-07-19 03:25:42 +09:00
Author: https://github.com/tomuta Commit: https://github.com/SerenityOS/serenity/commit/2552e3be006 Pull-request: https://github.com/SerenityOS/serenity/pull/3209
4 changed files with 43 additions and 7 deletions
|
@ -243,6 +243,36 @@ void Window::set_minimizable(bool minimizable)
|
|||
// TODO: Hide/show (or alternatively change enabled state of) window minimize button dynamically depending on value of m_minimizable
|
||||
}
|
||||
|
||||
void Window::set_taskbar_rect(const Gfx::IntRect& rect)
|
||||
{
|
||||
m_taskbar_rect = rect;
|
||||
m_have_taskbar_rect = !m_taskbar_rect.is_empty();
|
||||
}
|
||||
|
||||
void Window::start_minimize_animation()
|
||||
{
|
||||
if (!m_have_taskbar_rect) {
|
||||
// If this is a modal window, it may not have its own taskbar
|
||||
// button, so there is no rectangle. In that case, walk the
|
||||
// modal stack until we find a window that may have one
|
||||
WindowManager::the().for_each_window_in_modal_stack(*this, [&](Window& w, bool) {
|
||||
if (w.has_taskbar_rect()) {
|
||||
// We purposely do NOT set m_have_taskbar_rect to true here
|
||||
// because we want to only copy the rectangle from the
|
||||
// window that has it, but since this window wouldn't receive
|
||||
// any updates down the road we want to query it again
|
||||
// next time we want to start the animation
|
||||
m_taskbar_rect = w.taskbar_rect();
|
||||
|
||||
ASSERT(!m_have_taskbar_rect); // should remain unset!
|
||||
return IterationDecision::Break;
|
||||
};
|
||||
return IterationDecision::Continue;
|
||||
});
|
||||
}
|
||||
m_minimize_animation_step = 0;
|
||||
}
|
||||
|
||||
void Window::set_opacity(float opacity)
|
||||
{
|
||||
if (m_opacity == opacity)
|
||||
|
|
|
@ -153,7 +153,7 @@ public:
|
|||
void set_rect(int x, int y, int width, int height) { set_rect({ x, y, width, height }); }
|
||||
void set_rect_without_repaint(const Gfx::IntRect&);
|
||||
|
||||
void set_taskbar_rect(const Gfx::IntRect& rect) { m_taskbar_rect = rect; }
|
||||
void set_taskbar_rect(const Gfx::IntRect&);
|
||||
const Gfx::IntRect& taskbar_rect() const { return m_taskbar_rect; }
|
||||
|
||||
void move_to(const Gfx::IntPoint& position) { set_rect({ position, size() }); }
|
||||
|
@ -221,11 +221,11 @@ public:
|
|||
void request_update(const Gfx::IntRect&, bool ignore_occlusion = false);
|
||||
Gfx::DisjointRectSet take_pending_paint_rects() { return move(m_pending_paint_rects); }
|
||||
|
||||
bool has_taskbar_rect() const { return m_have_taskbar_rect; };
|
||||
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 start_minimize_animation();
|
||||
void end_minimize_animation() { m_minimize_animation_step = -1; }
|
||||
|
||||
Gfx::IntRect tiled_rect(WindowTileType) const;
|
||||
|
@ -321,6 +321,7 @@ private:
|
|||
bool m_accessory { false };
|
||||
bool m_destroyed { false };
|
||||
bool m_default_positioned { false };
|
||||
bool m_have_taskbar_rect { false };
|
||||
bool m_invalidated { true };
|
||||
bool m_invalidated_all { true };
|
||||
bool m_invalidated_frame { true };
|
||||
|
|
|
@ -228,6 +228,7 @@ void WindowManager::move_to_front_and_make_active(Window& window)
|
|||
// active input from any accessory window)
|
||||
for_each_window_in_modal_stack(window, [&](auto& w, bool is_stack_top) {
|
||||
move_window_to_front(w, is_stack_top, is_stack_top);
|
||||
return IterationDecision::Continue;
|
||||
});
|
||||
|
||||
Compositor::the().invalidate_occlusions();
|
||||
|
@ -1416,6 +1417,7 @@ void WindowManager::minimize_windows(Window& window, bool minimized)
|
|||
{
|
||||
for_each_window_in_modal_stack(window, [&](auto& w, bool) {
|
||||
w.set_minimized(minimized);
|
||||
return IterationDecision::Continue;
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -1426,6 +1428,7 @@ void WindowManager::maximize_windows(Window& window, bool maximized)
|
|||
w.set_maximized(maximized);
|
||||
if (w.is_minimized())
|
||||
w.set_minimized(false);
|
||||
return IterationDecision::Continue;
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -182,7 +182,7 @@ public:
|
|||
void maximize_windows(Window&, bool);
|
||||
|
||||
template<typename Function>
|
||||
void for_each_window_in_modal_stack(Window& window, Function f)
|
||||
IterationDecision for_each_window_in_modal_stack(Window& window, Function f)
|
||||
{
|
||||
auto* blocking_modal_window = window.is_blocked_by_modal_window();
|
||||
if (blocking_modal_window || window.is_modal()) {
|
||||
|
@ -198,13 +198,15 @@ public:
|
|||
}
|
||||
if (!modal_stack.is_empty()) {
|
||||
for (size_t i = modal_stack.size(); i > 0; i--) {
|
||||
f(*modal_stack[i - 1], false);
|
||||
IterationDecision decision = f(*modal_stack[i - 1], false);
|
||||
if (decision != IterationDecision::Continue)
|
||||
return decision;
|
||||
}
|
||||
}
|
||||
f(*modal_stack_top, true);
|
||||
return f(*modal_stack_top, true);
|
||||
} else {
|
||||
// Not a modal window stack, just "iterate" over this window
|
||||
f(window, true);
|
||||
return f(window, true);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue