mirror of
https://github.com/RGBCube/serenity
synced 2025-05-31 06:48:12 +00:00

This creates a 2-dimensional array of WindowStack instances, one for each virtual desktop. The main desktop 0,0 is the main desktop, which is the desktop used for all stationary windows (e.g. taskbar, desktop). When adding windows to a desktop, stationary windows are always added to the main desktop. When composing the desktop, there are usually two WindowStacks involved. For stationary windows, the main desktop will be traversed, and for everything else the current virtual desktop will be iterated. Iteration is interweaved to preserve the correct order. During the transition animation, two WindowStacks will be iterated at the same time.
96 lines
2.4 KiB
C++
96 lines
2.4 KiB
C++
/*
|
|
* Copyright (c) 2021, Andreas Kling <kling@serenityos.org>
|
|
*
|
|
* SPDX-License-Identifier: BSD-2-Clause
|
|
*/
|
|
|
|
#include "WindowStack.h"
|
|
#include "WindowManager.h"
|
|
|
|
namespace WindowServer {
|
|
|
|
WindowStack::WindowStack(unsigned row, unsigned column)
|
|
: m_row(row)
|
|
, m_column(column)
|
|
{
|
|
}
|
|
|
|
WindowStack::~WindowStack()
|
|
{
|
|
}
|
|
|
|
void WindowStack::add(Window& window)
|
|
{
|
|
VERIFY(window.outer_stack() == nullptr);
|
|
m_windows.append(window);
|
|
window.set_outer_stack({}, this);
|
|
}
|
|
|
|
void WindowStack::remove(Window& window)
|
|
{
|
|
VERIFY(window.outer_stack() == this);
|
|
m_windows.remove(window);
|
|
window.set_outer_stack({}, nullptr);
|
|
if (m_active_window == &window)
|
|
m_active_window = nullptr;
|
|
if (m_active_input_window == &window)
|
|
m_active_input_window = nullptr;
|
|
if (m_active_input_tracking_window == &window)
|
|
m_active_input_tracking_window = nullptr;
|
|
}
|
|
|
|
void WindowStack::move_to_front(Window& window)
|
|
{
|
|
if (m_windows.last() != &window)
|
|
window.invalidate();
|
|
m_windows.remove(window);
|
|
m_windows.append(window);
|
|
}
|
|
|
|
Window* WindowStack::window_at(Gfx::IntPoint const& position, IncludeWindowFrame include_window_frame) const
|
|
{
|
|
auto result = hit_test(position);
|
|
if (!result.has_value())
|
|
return nullptr;
|
|
if (include_window_frame == IncludeWindowFrame::No && result->is_frame_hit)
|
|
return nullptr;
|
|
return result->window;
|
|
}
|
|
|
|
Window* WindowStack::highlight_window() const
|
|
{
|
|
if (auto* window = WindowManager::the().highlight_window(); window && window->outer_stack() == this)
|
|
return window;
|
|
return nullptr;
|
|
}
|
|
|
|
void WindowStack::set_active_window(Window* window)
|
|
{
|
|
if (!window)
|
|
m_active_window = nullptr;
|
|
else
|
|
m_active_window = window->make_weak_ptr<Window>();
|
|
}
|
|
|
|
void WindowStack::set_all_occluded(bool occluded)
|
|
{
|
|
for (auto& window : m_windows) {
|
|
if (!WindowManager::is_stationary_window_type(window.type()))
|
|
window.set_occluded(occluded);
|
|
}
|
|
}
|
|
|
|
Optional<HitTestResult> WindowStack::hit_test(Gfx::IntPoint const& position) const
|
|
{
|
|
Optional<HitTestResult> result;
|
|
WindowManager::the().for_each_visible_window_from_front_to_back([&](Window& window) {
|
|
result = window.hit_test(position);
|
|
if (result.has_value())
|
|
return IterationDecision::Break;
|
|
return IterationDecision::Continue;
|
|
},
|
|
const_cast<WindowStack*>(this));
|
|
return result;
|
|
}
|
|
|
|
}
|