use std::cmp::min;
use std::iter::zip;
use std::rc::Rc;
use std::time::Duration;
use niri_config::CornerRadius;
use smithay::backend::renderer::element::utils::{
CropRenderElement, Relocate, RelocateRenderElement,
};
use smithay::output::Output;
use smithay::utils::{Logical, Point, Rectangle, Size};
use super::insert_hint_element::{InsertHintElement, InsertHintRenderElement};
use super::scrolling::{Column, ColumnWidth};
use super::tile::Tile;
use super::workspace::{
compute_working_area, OutputId, Workspace, WorkspaceAddWindowTarget, WorkspaceId,
WorkspaceRenderElement,
};
use super::{ActivateWindow, HitType, LayoutElement, Options};
use crate::animation::{Animation, Clock};
use crate::input::swipe_tracker::SwipeTracker;
use crate::niri_render_elements;
use crate::render_helpers::renderer::NiriRenderer;
use crate::render_helpers::RenderTarget;
use crate::rubber_band::RubberBand;
use crate::utils::transaction::Transaction;
use crate::utils::{output_size, ResizeEdge};
/// Amount of touchpad movement to scroll the height of one workspace.
const WORKSPACE_GESTURE_MOVEMENT: f64 = 300.;
const WORKSPACE_GESTURE_RUBBER_BAND: RubberBand = RubberBand {
stiffness: 0.5,
limit: 0.05,
};
#[derive(Debug)]
pub struct Monitor<W: LayoutElement> {
/// Output for this monitor.
pub(super) output: Output,
/// Cached name of the output.
output_name: String,
/// Latest known scale for this output.
scale: smithay::output::Scale,
/// Latest known size for this output.
view_size: Size<f64, Logical>,
/// Latest known working area for this output.
///
/// Not rounded to physical pixels.
// FIXME: since this is used for things like DnD scrolling edges in the overview, ideally this
// should only consider overlay and top layer-shell surfaces. However, Smithay doesn't easily
// let you do this at the moment.
working_area: Rectangle<f64, Logical>,
// Must always contain at least one.
pub(super) workspaces: Vec<Workspace<W>>,
/// Index of the currently active workspace.
pub(super) active_workspace_idx: usize,
/// ID of the previously active workspace.
pub(super) previous_workspace_id: Option<WorkspaceId>,
/// In-progress switch between workspaces.
pub(super) workspace_switch: Option<WorkspaceSwitch>,
/// Indication where an interactively-moved window is about to be placed.
pub(super) insert_hint: Option<InsertHint>,
/// Insert hint element for rendering.
insert_hint_element: InsertHintElement,
/// Location to render the insert hint element.
insert_hint_render_loc: Option<InsertHintRenderLoc>,
/// Clock for driving animations.
pub(super) clock: Clock,
/// Configurable properties of the layout.
pub(super) options: Rc<Options>,
}
#[derive(Debug)]
pub enum WorkspaceSwitch {
Animation(Animation),
Gesture(WorkspaceSwitchGesture),
}
#[derive(Debug)]
pub struct WorkspaceSwitchGesture {
/// Index of the workspace where the gesture was started.
center_idx: usize,
/// Fractional workspace index where the gesture was started.
///
/// Can differ from center_idx when starting a gesture in the middle between workspaces, for
/// example by "catching" a