use std::cell::{Cell, Ref, RefCell};
use std::time::Duration;
use niri_config::{Color, CornerRadius, GradientInterpolation, WindowRule};
use smithay::backend::renderer::element::surface::render_elements_from_surface_tree;
use smithay::backend::renderer::element::Kind;
use smithay::backend::renderer::gles::GlesRenderer;
use smithay::desktop::space::SpaceElement as _;
use smithay::desktop::{PopupManager, Window};
use smithay::output::{self, Output};
use smithay::reexports::wayland_protocols::xdg::decoration::zv1::server::zxdg_toplevel_decoration_v1;
use smithay::reexports::wayland_protocols::xdg::shell::server::xdg_toplevel;
use smithay::reexports::wayland_server::protocol::wl_surface::WlSurface;
use smithay::reexports::wayland_server::Resource as _;
use smithay::utils::{Logical, Point, Rectangle, Scale, Serial, Size, Transform};
use smithay::wayland::compositor::{remove_pre_commit_hook, with_states, HookId, SurfaceData};
use smithay::wayland::seat::WaylandFocus;
use smithay::wayland::shell::xdg::{SurfaceCachedState, ToplevelSurface};
use wayland_backend::server::Credentials;
use super::{ResolvedWindowRules, WindowRef};
use crate::handlers::KdeDecorationsModeState;
use crate::layout::{
ConfigureIntent, InteractiveResizeData, LayoutElement, LayoutElementRenderElement,
LayoutElementRenderSnapshot,
};
use crate::niri_render_elements;
use crate::render_helpers::border::BorderRenderElement;
use crate::render_helpers::offscreen::OffscreenData;
use crate::render_helpers::renderer::NiriRenderer;
use crate::render_helpers::snapshot::RenderSnapshot;
use crate::render_helpers::solid_color::{SolidColorBuffer, SolidColorRenderElement};
use crate::render_helpers::surface::render_snapshot_from_surface_tree;
use crate::render_helpers::{BakedBuffer, RenderTarget, SplitElements};
use crate::utils::id::IdCounter;
use crate::utils::transaction::Transaction;
use crate::utils::{
get_credentials_for_surface, send_scale_transform, update_tiled_state, with_toplevel_role,
ResizeEdge,
};
#[derive(Debug)]
pub struct Mapped {
pub window: Window,
/// Unique ID of this `Mapped`.
id: MappedId,
/// Credentials of the process that created the Wayland connection.
credentials: Option<Credentials>,
/// Pre-commit hook that we have on all mapped toplevel surfaces.
pre_commit_hook: HookId,
/// Up-to-date rules.
rules: ResolvedWindowRules,
/// Whether the window rules need to be recomputed.
///
/// This is not used in all cases; for example, app ID and title changes recompute the rules
/// immediately, rather than setting this flag.
need_to_recompute_rules: bool,
/// Whether this window needs a configure this loop cycle.
///
/// Certain Wayland requests require a configure in response, like un/fullscreen.
needs_configure: bool,
/// Whether this window needs a frame callback.
///
/// We set this after sending a configure to give invisible windows a chance to respond to
/// resizes immediately, without waiting for a 1 second throttled callback.
needs_frame_callback: bool,
/// Data of the offscreen element rendered in place of this window.
///
/// If `None`, then the window is not offscreened.
offscreen_data: RefCell<Option<OffscreenData>>,
/// Whether this window has the keyboard focus.
is_focused: bool,
/// Whether this window is the active window in its column.
is_active_in_column: bool,
/// Whether this window is floating.
is_floating: bool,
/// Whether this window is a target of a window cast.
is_window_cast_target: bool,
/// Whether this window should ignore opacity set through window rules.
ignore_opacity_window_rule: bool,
/// Buffer to draw instead of the window when it should be blocked out.
block_out_buffer: RefCell<SolidColorBuffer>,
/// Whether the next configure should be animated, if the configured state changed.
animate_next_configure: bool,
/// Serials of commits that should be animated.
animate_serials: Vec<Serial>,
/// Snapshot right before an animated commit, without popups.
animation_snapshot: Option<LayoutElementRenderSnapshot>,
/// State for the logic to request a size once (for floating windows).
request_size_once: Option<RequestSizeOnce>,
/// Transaction that the next configure should take part in, if any.
transaction_for_next_configure: Option<Transaction>,
/// Pending transactions that have not been added as blockers for this window yet.
pending_transactions: Vec<(Serial, Transaction)>