mirror of
https://github.com/RGBCube/serenity
synced 2025-07-25 16:17:45 +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
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
|
// 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)
|
void Window::set_opacity(float opacity)
|
||||||
{
|
{
|
||||||
if (m_opacity == 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(int x, int y, int width, int height) { set_rect({ x, y, width, height }); }
|
||||||
void set_rect_without_repaint(const Gfx::IntRect&);
|
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; }
|
const Gfx::IntRect& taskbar_rect() const { return m_taskbar_rect; }
|
||||||
|
|
||||||
void move_to(const Gfx::IntPoint& position) { set_rect({ position, size() }); }
|
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);
|
void request_update(const Gfx::IntRect&, bool ignore_occlusion = false);
|
||||||
Gfx::DisjointRectSet take_pending_paint_rects() { return move(m_pending_paint_rects); }
|
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; }
|
bool in_minimize_animation() const { return m_minimize_animation_step != -1; }
|
||||||
|
|
||||||
int minimize_animation_index() const { return m_minimize_animation_step; }
|
int minimize_animation_index() const { return m_minimize_animation_step; }
|
||||||
void step_minimize_animation() { m_minimize_animation_step += 1; }
|
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; }
|
void end_minimize_animation() { m_minimize_animation_step = -1; }
|
||||||
|
|
||||||
Gfx::IntRect tiled_rect(WindowTileType) const;
|
Gfx::IntRect tiled_rect(WindowTileType) const;
|
||||||
|
@ -321,6 +321,7 @@ private:
|
||||||
bool m_accessory { false };
|
bool m_accessory { false };
|
||||||
bool m_destroyed { false };
|
bool m_destroyed { false };
|
||||||
bool m_default_positioned { false };
|
bool m_default_positioned { false };
|
||||||
|
bool m_have_taskbar_rect { false };
|
||||||
bool m_invalidated { true };
|
bool m_invalidated { true };
|
||||||
bool m_invalidated_all { true };
|
bool m_invalidated_all { true };
|
||||||
bool m_invalidated_frame { 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)
|
// active input from any accessory window)
|
||||||
for_each_window_in_modal_stack(window, [&](auto& w, bool is_stack_top) {
|
for_each_window_in_modal_stack(window, [&](auto& w, bool is_stack_top) {
|
||||||
move_window_to_front(w, is_stack_top, is_stack_top);
|
move_window_to_front(w, is_stack_top, is_stack_top);
|
||||||
|
return IterationDecision::Continue;
|
||||||
});
|
});
|
||||||
|
|
||||||
Compositor::the().invalidate_occlusions();
|
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) {
|
for_each_window_in_modal_stack(window, [&](auto& w, bool) {
|
||||||
w.set_minimized(minimized);
|
w.set_minimized(minimized);
|
||||||
|
return IterationDecision::Continue;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1426,6 +1428,7 @@ void WindowManager::maximize_windows(Window& window, bool maximized)
|
||||||
w.set_maximized(maximized);
|
w.set_maximized(maximized);
|
||||||
if (w.is_minimized())
|
if (w.is_minimized())
|
||||||
w.set_minimized(false);
|
w.set_minimized(false);
|
||||||
|
return IterationDecision::Continue;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -182,7 +182,7 @@ public:
|
||||||
void maximize_windows(Window&, bool);
|
void maximize_windows(Window&, bool);
|
||||||
|
|
||||||
template<typename Function>
|
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();
|
auto* blocking_modal_window = window.is_blocked_by_modal_window();
|
||||||
if (blocking_modal_window || window.is_modal()) {
|
if (blocking_modal_window || window.is_modal()) {
|
||||||
|
@ -198,13 +198,15 @@ public:
|
||||||
}
|
}
|
||||||
if (!modal_stack.is_empty()) {
|
if (!modal_stack.is_empty()) {
|
||||||
for (size_t i = modal_stack.size(); i > 0; i--) {
|
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 {
|
} else {
|
||||||
// Not a modal window stack, just "iterate" over this window
|
// Not a modal window stack, just "iterate" over this window
|
||||||
f(window, true);
|
return f(window, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue