use std::rc::Rc;
use std::time::Duration;
use niri_config::{OutputName, Workspace as WorkspaceConfig};
use niri_ipc::SizeChange;
use smithay::backend::renderer::gles::GlesRenderer;
use smithay::desktop::{layer_map_for_output, Window};
use smithay::output::Output;
use smithay::reexports::wayland_protocols::xdg::shell::server::xdg_toplevel;
use smithay::reexports::wayland_server::protocol::wl_surface::WlSurface;
use smithay::utils::{Logical, Point, Rectangle, Scale, Serial, Size, Transform};
use super::floating::{FloatingSpace, FloatingSpaceRenderElement};
use super::scrolling::{
Column, ColumnWidth, InsertHint, InsertPosition, ScrollingSpace, ScrollingSpaceRenderElement,
};
use super::tile::{Tile, TileRenderSnapshot};
use super::{InteractiveResizeData, LayoutElement, Options, RemovedTile};
use crate::animation::Clock;
use crate::niri_render_elements;
use crate::render_helpers::renderer::NiriRenderer;
use crate::render_helpers::RenderTarget;
use crate::utils::id::IdCounter;
use crate::utils::transaction::{Transaction, TransactionBlocker};
use crate::utils::{output_size, send_scale_transform, ResizeEdge};
use crate::window::ResolvedWindowRules;
#[derive(Debug)]
pub struct Workspace<W: LayoutElement> {
/// The scrollable-tiling layout.
scrolling: ScrollingSpace<W>,
/// The floating layout.
floating: FloatingSpace<W>,
/// Whether the floating layout is active instead of the scrolling layout.
floating_is_active: bool,
/// The original output of this workspace.
///
/// Most of the time this will be the workspace's current output, however, after an output
/// disconnection, it may remain pointing to the disconnected output.
pub(super) original_output: OutputId,
/// Current output of this workspace.
output: Option<Output>,
/// Latest known output scale for this workspace.
///
/// This should be set from the current workspace output, or, if all outputs have been
/// disconnected, preserved until a new output is connected.
scale: smithay::output::Scale,
/// Latest known output transform for this workspace.
///
/// This should be set from the current workspace output, or, if all outputs have been
/// disconnected, preserved until a new output is connected.
transform: Transform,
/// Latest known view size for this workspace.
///
/// This should be computed from the current workspace output size, or, if all outputs have
/// been disconnected, preserved until a new output is connected.
view_size: Size<f64, Logical>,
/// Latest known working area for this workspace.
///
/// Not rounded to physical pixels.
///
/// This is similar to view size, but takes into account things like layer shell exclusive
/// zones.
working_area: Rectangle<f64, Logical>,
/// Clock for driving animations.
pub(super) clock: Clock,
/// Configurable properties of the layout as received from the parent monitor.
pub(super) base_options: Rc<Options><