git.lucas.co / cce-compositor
Wayland compositor (wlroots)
git clone https://git.lucas.co/cce-compositor.git

commit6aa3aff1e94c01ac61d67e7bb5e66d2c4e52a227
parent4e9b9e0381
authorLucas Galante <[email protected]>
date2026-07-14 22:28
refactor: consolidate arrange_views into one snapshot -> plan -> apply pass

policy::arrange::arrange() is now the whole frame as a single pure
function — the future Policy::arrange entry point. It composes the
previously extracted section functions (classify, usable area, overlay/
maximized/normal placement, status-bar layout) and owns the per-output
loop, preserving its last-wins multi-output semantics. State that
arranging itself evolves (box geometry, virtual positions, SSD rule
overrides, the maximized save/restore machine) is threaded through a
working copy of the snapshots, so later sections and later output passes
read what earlier ones wrote, exactly like the mutating original.

The mechanism side of arrange_views() is down to ~240 straight lines:
snapshot outputs and windows into plain data (seat-dependent answers
like being-moved and live resize dims captured up front), one arrange()
call, then a flat if-let-Some apply loop over per-window write
instructions (WindowPlan). No layout math remains in window_manager.rs.

Behavior notes, all invisible to a single-output session:
- Window::measure_decorations() split out of get_decorations_size() so
  the snapshot can record the raw decoration size; the original read it
  after the classification pass wrote the SSD rule override, and the
  pure pass reproduces that ordering via the effective-SSD gate in
  place_overlay_window.
- The forced status-bar configure now runs once after apply instead of
  once per output; with several outputs the old code sent intermediate
  configures with geometry the next pass immediately overwrote.
- Scene enable/disable lands once with the final value instead of being
  re-toggled per output pass.
- Deleted get_closest_tag(): its only caller was a discarded binding.

9 new tests pin arrange() end-to-end: background covering + fallback
rect gating, hidden windows, overlay slot + second-overlay demotion,
rule-SSD reaching overlay sizing, maximized enter/exit through
placement, status-bar drag exclusion, and multi-output last-wins
including the maximize state machine firing only once across passes.
All 30 library tests pass.

Co-Authored-By: Claude Fable 5 <[email protected]>
Claude-Session: https://claude.ai/code/session_019ZcxLgNGyFtsYP4JMTvis6

 src/server/policy/arrange.rs | 624 ++++++++++++++++++++++++++++++++++++++++++-
 src/server/window.rs         |   7 +
 src/server/window_manager.rs | 528 ++++++++++--------------------------
 3 files changed, 776 insertions(+), 383 deletions(-)

diff --git a/src/server/policy/arrange.rs b/src/server/policy/arrange.rs
index 67dd7f9..a93fcba 100644
--- a/src/server/policy/arrange.rs
+++ b/src/server/policy/arrange.rs
@@ -2,8 +2,9 @@
 //
 // Functions here take plain-data snapshots and return placement plans; the
 // mechanism side (`window_manager.rs`) builds the snapshots from FFI state and
-// applies the plans to the scene graph. Extraction happens section by section;
-// currently covers the status-bar layout engine.
+// applies the plans to the scene graph. `arrange()` is the whole frame in one
+// call — the future `Policy::arrange` entry point — composed from the
+// per-section functions below it.
 
 use super::api::{Rect, WindowRole};
 use super::tiling::TilingMode;
@@ -714,6 +715,385 @@ pub fn layout_status_bars(
     placements
 }
 
+/// One enabled output, as `arrange` needs it.
+#[derive(Debug, Clone, Copy)]
+pub struct OutputSnapshot {
+    /// The output's layout box.
+    pub layout_box: Rect,
+    /// Layer-shell non-exclusive area, relative to the layout box; a
+    /// zero-sized rect means no exclusion.
+    pub non_exclusive: Rect,
+}
+
+/// Everything `arrange` reads about one window. Built once per frame by the
+/// mechanism side; seat-dependent answers (`being_moved`, `active_resize`)
+/// are captured here so the pure pass never queries mid-computation.
+#[derive(Debug, Clone)]
+pub struct WindowSnapshot {
+    pub app_id: Option<String>,
+    /// Only used verbatim in log lines.
+    pub title: Option<String>,
+    pub role: WindowRole,
+    pub minimized: bool,
+    /// Window state is Closing or Init.
+    pub closing_or_init: bool,
+    /// Resolved tiling mode (`get_mode_for_window`).
+    pub mode: TilingMode,
+    /// Mode-rule SSD override; pre-gated on `!mode_locked`.
+    pub rule_ssd: Option<bool>,
+    /// A seat is interactively moving this window.
+    pub being_moved: bool,
+    pub status_edge: StatusEdge,
+    pub is_focused: bool,
+    pub box_geom: Rect,
+    /// (min_width, min_height) size hints.
+    pub min_size: (i32, i32),
+    pub virtual_pos: (f64, f64),
+    pub active_resize: Option<(u32, u32)>,
+    /// Current `wm_requested.ssd`.
+    pub ssd: bool,
+    /// Raw decoration measurement (`measure_decorations`), not gated on
+    /// `ssd` — placement applies it only when the effective SSD is off.
+    pub decorations_size: (i32, i32),
+    pub was_maximized: bool,
+    pub saved_maximized_size: (i32, i32),
+    pub saved_maximized_virtual: (f64, f64),
+}
+
+/// Frame-wide inputs: config knobs plus the desktop viewport.
+pub struct ArrangeParams {
+    pub bar_height: i32,
+    pub status_hide_mode: bool,
+    pub hide_mode_preview: i32,
+    /// `status_background_blur > 0.001`.
+    pub status_blur: bool,
+    pub window_blur: bool,
+    /// `layout.window_opacity` — unfocused windows dim when set.
+    pub opacity_enabled: bool,
+    pub border_color: (u32, u32, u32, u32),
+    pub overlay: OverlayParams,
+    pub normal: NormalParams,
+    pub pan_x: f64,
+    pub pan_y: f64,
+    pub zoom: f64,
+}
+
+#[derive(Debug, Clone, Copy, PartialEq, Eq)]
+pub struct BorderPlan {
+    pub width: u32,
+    pub color: (u32, u32, u32, u32),
+}
+
+/// Write instructions for one window. `None` leaves the field untouched, so
+/// the mechanism apply loop is a flat sequence of `if let Some` writes.
+#[derive(Debug, Clone, Default, PartialEq)]
+pub struct WindowPlan {
+    /// Enable/disable the window's scene tree.
+    pub scene_enabled: Option<bool>,
+    pub hidden: Option<bool>,
+    pub tiling_mode: Option<TilingMode>,
+    /// `wm_requested.tiled` edge bitmask.
+    pub tiled: Option<u32>,
+    pub ssd: Option<bool>,
+    pub scale: Option<f64>,
+    /// `rendering_requested.{x,y}`.
+    pub pos: Option<(i32, i32)>,
+    /// `wm_requested.dimensions` and `.bounds`.
+    pub size: Option<(u32, u32)>,
+    /// Persistent geometry write-back.
+    pub box_geom: Option<Rect>,
+    pub virtual_pos: Option<(f64, f64)>,
+    pub blur: Option<bool>,
+    pub border: Option<BorderPlan>,
+    pub opacity: Option<f32>,
+    pub was_maximized: Option<bool>,
+    /// Maximized-enter save: (restore size, restore virtual position).
+    pub saved_maximized: Option<((i32, i32), (f64, f64))>,
+}
+
+pub struct ArrangePlan {
+    /// Index-aligned with the input snapshots.
+    pub windows: Vec<WindowPlan>,
+    /// Whether each output's fallback background rect should be shown
+    /// (false while a wallpaper window exists).
+    pub background_rect_enabled: bool,
+}
+
+fn is_cloud_app(app_id: Option<&str>) -> bool {
+    app_id.map_or(false, |id| id.starts_with("cce-cloud"))
+}
+
+/// The whole arrange pass as one pure function: classify every window, place
+/// overlays/normals/status bars per output, and return per-window write
+/// instructions.
+///
+/// The output loop is last-wins, like the mechanism loop it replaces: every
+/// output pass re-plans every window, so with several outputs the final plan
+/// reflects the last one. State that arranging itself evolves (box geometry,
+/// virtual position, SSD overrides, the maximized save/restore machine) is
+/// tracked on a working copy of the snapshots so later sections and later
+/// output passes read what earlier ones wrote — exactly as the mutating
+/// original did.
+pub fn arrange(
+    windows: &[WindowSnapshot],
+    outputs: &[OutputSnapshot],
+    p: &ArrangeParams,
+) -> ArrangePlan {
+    let mut state: Vec<WindowSnapshot> = windows.to_vec();
+    let mut plan: Vec<WindowPlan> = vec![WindowPlan::default(); windows.len()];
+
+    let has_wallpaper = state.iter().any(|w| w.role == WindowRole::Background);
+    let default_border = BorderPlan { width: BW as u32, color: p.border_color };
+
+    for out in outputs {
+        let phys = out.layout_box;
+
+        let status_edges: Vec<StatusEdge> = state
+            .iter()
+            .filter(|w| w.role == WindowRole::StatusBar)
+            .map(|w| w.status_edge)
+            .collect();
+        let usable = compute_usable_area(
+            phys,
+            out.non_exclusive,
+            p.bar_height,
+            p.status_hide_mode,
+            &status_edges,
+        );
+        let ctx = PlacementCtx {
+            phys,
+            usable,
+            pan_x: p.pan_x,
+            pan_y: p.pan_y,
+            zoom: p.zoom,
+        };
+
+        let mut overlay_windows: Vec<usize> = Vec::new();
+        let mut normal_windows: Vec<usize> = Vec::new();
+
+        for (i, w) in state.iter_mut().enumerate() {
+            let class = classify_window(w.role, w.minimized, w.closing_or_init, w.mode, w.being_moved);
+            let wp = &mut plan[i];
+            match class {
+                WindowClass::Background => {
+                    wp.tiling_mode = Some(TilingMode::Status);
+                    wp.tiled = Some(0);
+                    wp.ssd = Some(false);
+                    w.ssd = false;
+                    wp.scale = Some(1.0);
+                    wp.scene_enabled = Some(true);
+                    wp.hidden = Some(false);
+                    wp.blur = Some(false);
+                    wp.pos = Some((phys.x, phys.y));
+                    wp.size = Some((phys.width as u32, phys.height as u32));
+                }
+                WindowClass::StatusBar => {
+                    wp.tiling_mode = Some(TilingMode::Status);
+                    wp.tiled = Some(0);
+                    wp.ssd = Some(false);
+                    w.ssd = false;
+                    wp.scale = Some(1.0);
+                    wp.scene_enabled = Some(true);
+                    wp.hidden = Some(false);
+                    wp.blur = Some(p.status_blur);
+                }
+                WindowClass::Hidden => {
+                    wp.scene_enabled = Some(false);
+                    wp.hidden = Some(true);
+                }
+                WindowClass::Overlay | WindowClass::Normal => {
+                    wp.scene_enabled = Some(true);
+                    wp.hidden = Some(false);
+                    wp.tiling_mode = Some(w.mode);
+                    if let Some(rule_ssd) = w.rule_ssd {
+                        wp.ssd = Some(rule_ssd);
+                        w.ssd = rule_ssd;
+                    }
+                    if class == WindowClass::Overlay {
+                        overlay_windows.push(i);
+                    } else {
+                        normal_windows.push(i);
+                    }
+                }
+            }
+        }
+
+        for (sp_idx, &i) in overlay_windows.iter().enumerate() {
+            if sp_idx == 0 {
+                let w = &state[i];
+                let placement = place_overlay_window(
+                    &OverlaySnapshot {
+                        box_geom: w.box_geom,
+                        min_width: w.min_size.0,
+                        is_cloud: is_cloud_app(w.app_id.as_deref()),
+                        ssd: w.ssd,
+                        decorations_size: w.decorations_size,
+                    },
+                    &p.overlay,
+                    &ctx,
+                );
+
+                if let Some(bg) = placement.box_geom_write {
+                    state[i].box_geom = bg;
+                }
+                state[i].virtual_pos = placement.virtual_pos;
+
+                let wp = &mut plan[i];
+                if let Some(bg) = placement.box_geom_write {
+                    wp.box_geom = Some(bg);
+                }
+                wp.pos = Some(placement.pos);
+                wp.scale = Some(1.0);
+                wp.virtual_pos = Some(placement.virtual_pos);
+                wp.size = Some(placement.size);
+                wp.tiled = Some(1 | 2 | 4 | 8);
+                wp.border = Some(default_border);
+                wp.blur = Some(p.window_blur);
+                wp.opacity = Some(window_opacity(
+                    state[i].is_focused,
+                    p.opacity_enabled,
+                    OVERLAY_UNFOCUSED_OPACITY,
+                ));
+            } else {
+                normal_windows.push(i);
+            }
+        }
+
+        // Manage entering/exiting Maximized state for normal windows.
+        for &i in &normal_windows {
+            let w = &state[i];
+            let transition = maximized_transition(
+                w.mode == TilingMode::Maximized,
+                w.was_maximized,
+                (w.box_geom.width, w.box_geom.height),
+                w.min_size,
+                w.saved_maximized_size,
+                w.saved_maximized_virtual,
+            );
+            match transition {
+                Some(MaximizedTransition::Enter { width, height }) => {
+                    let w = &mut state[i];
+                    w.saved_maximized_size = (width, height);
+                    w.saved_maximized_virtual = w.virtual_pos;
+                    w.was_maximized = true;
+                    let wp = &mut plan[i];
+                    wp.saved_maximized = Some(((width, height), w.saved_maximized_virtual));
+                    wp.was_maximized = Some(true);
+                    log::info!("[Maximized] Saved window {:?} geometry: {}x{} at ({}, {})",
+                        w.title.as_deref().unwrap_or(""),
+                        width, height,
+                        w.saved_maximized_virtual.0, w.saved_maximized_virtual.1
+                    );
+                }
+                Some(MaximizedTransition::Exit { width, height, virtual_x, virtual_y }) => {
+                    let w = &mut state[i];
+                    w.box_geom.width = width;
+                    w.box_geom.height = height;
+                    w.virtual_pos = (virtual_x, virtual_y);
+                    w.was_maximized = false;
+                    let wp = &mut plan[i];
+                    wp.box_geom = Some(w.box_geom);
+                    wp.virtual_pos = Some((virtual_x, virtual_y));
+                    wp.was_maximized = Some(false);
+                    wp.size = Some((width as u32, height as u32));
+                    log::info!("[Maximized] Restored window {:?} geometry: {}x{} at ({}, {})",
+                        w.title.as_deref().unwrap_or(""),
+                        width, height, virtual_x, virtual_y
+                    );
+                }
+                None => {}
+            }
+        }
+
+        // Arrange normal windows on the virtual surface.
+        for &i in &normal_windows {
+            let w = &state[i];
+            let placement = place_normal_window(
+                &NormalSnapshot {
+                    mode: w.mode,
+                    box_geom: w.box_geom,
+                    min_size: w.min_size,
+                    virtual_pos: w.virtual_pos,
+                    active_resize: w.active_resize,
+                    is_cloud: is_cloud_app(w.app_id.as_deref()),
+                    saved_maximized_size: w.saved_maximized_size,
+                    saved_maximized_virtual: w.saved_maximized_virtual,
+                },
+                &p.normal,
+                &ctx,
+            );
+
+            let is_focused = w.is_focused;
+            if let Some(v) = placement.virtual_write {
+                state[i].virtual_pos = v;
+            }
+
+            let wp = &mut plan[i];
+            wp.pos = Some(placement.pos);
+            wp.scale = Some(placement.scale);
+            if let Some(v) = placement.virtual_write {
+                wp.virtual_pos = Some(v);
+            }
+            if let Some(hidden) = placement.hidden {
+                wp.hidden = Some(hidden);
+            }
+            wp.size = Some(placement.size);
+            if placement.tiled_all_edges {
+                wp.tiled = Some(1 | 2 | 4 | 8);
+            }
+            wp.border = Some(default_border);
+            wp.blur = Some(p.window_blur);
+            wp.opacity = Some(window_opacity(is_focused, p.opacity_enabled, NORMAL_UNFOCUSED_OPACITY));
+        }
+
+        // Position status bar windows on this output, excluding any being
+        // interactively dragged.
+        let mut status_items: Vec<StatusBarItem> = Vec::new();
+        let mut status_idxs: Vec<usize> = Vec::new();
+        for (i, w) in state.iter().enumerate() {
+            if w.closing_or_init {
+                continue;
+            }
+            if let Some(app_id) = &w.app_id {
+                if app_id.starts_with("cce-status") {
+                    if w.being_moved {
+                        continue;
+                    }
+                    log::info!("[ArrangeStatus] app_id={} status_edge={:?}", app_id, w.status_edge);
+                    status_items.push(StatusBarItem {
+                        app_id: app_id.clone(),
+                        edge: w.status_edge,
+                        prev_len: std::cmp::max(w.box_geom.width, w.box_geom.height),
+                    });
+                    status_idxs.push(i);
+                }
+            }
+        }
+
+        let placements = layout_status_bars(
+            &status_items,
+            &StatusBarLayoutParams {
+                output: phys,
+                bar_height: p.bar_height as u32,
+                hide_mode: p.status_hide_mode,
+                hide_mode_preview: p.hide_mode_preview,
+            },
+        );
+
+        for (&i, placement) in status_idxs.iter().zip(placements.iter()) {
+            if let Some(pl) = placement {
+                plan[i].pos = Some((pl.x, pl.y));
+                plan[i].size = Some((pl.width, pl.height));
+            }
+        }
+    }
+
+    ArrangePlan {
+        windows: plan,
+        background_rect_enabled: !has_wallpaper,
+    }
+}
+
 #[cfg(test)]
 mod tests {
     use super::*;
@@ -1000,6 +1380,246 @@ mod tests {
         assert_eq!(window_opacity(false, true, NORMAL_UNFOCUSED_OPACITY), 0.90);
     }
 
+    fn snap(app_id: &str) -> WindowSnapshot {
+        WindowSnapshot {
+            app_id: Some(app_id.to_string()),
+            title: None,
+            role: WindowRole::from_app_id(Some(app_id)),
+            minimized: false,
+            closing_or_init: false,
+            mode: TilingMode::Floating,
+            rule_ssd: None,
+            being_moved: false,
+            status_edge: StatusEdge::Unspecified,
+            is_focused: false,
+            box_geom: Rect { x: 0, y: 0, width: 640, height: 480 },
+            min_size: (0, 0),
+            virtual_pos: (100.0, 200.0),
+            active_resize: None,
+            ssd: true,
+            decorations_size: (0, 16),
+            was_maximized: false,
+            saved_maximized_size: (0, 0),
+            saved_maximized_virtual: (0.0, 0.0),
+        }
+    }
+
+    fn arrange_params() -> ArrangeParams {
+        ArrangeParams {
+            bar_height: 30,
+            status_hide_mode: false,
+            hide_mode_preview: 5,
+            status_blur: true,
+            window_blur: true,
+            opacity_enabled: true,
+            border_color: (10, 20, 30, 40),
+            overlay: OverlayParams {
+                overlay_width: 400,
+                border_gap: 8,
+                position_right: true,
+                cloud_position_default: None,
+            },
+            normal: NormalParams {
+                gap_right: 10,
+                gap_top: 6,
+                cloud_position_default: None,
+                desktop_grid_scale: 100.0,
+            },
+            pan_x: 0.0,
+            pan_y: 0.0,
+            zoom: 1.0,
+        }
+    }
+
+    fn one_output() -> Vec<OutputSnapshot> {
+        vec![OutputSnapshot {
+            layout_box: Rect { x: 0, y: 0, width: 1920, height: 1080 },
+            non_exclusive: Rect { x: 0, y: 0, width: 0, height: 0 },
+        }]
+    }
+
+    #[test]
+    fn arrange_background_covers_output_and_disables_fallback_rect() {
+        let windows = vec![snap("cce-wallpaper"), snap("firefox")];
+        let plan = arrange(&windows, &one_output(), &arrange_params());
+
+        assert!(!plan.background_rect_enabled);
+        let wp = &plan.windows[0];
+        assert_eq!(wp.tiling_mode, Some(TilingMode::Status));
+        assert_eq!(wp.tiled, Some(0));
+        assert_eq!(wp.ssd, Some(false));
+        assert_eq!(wp.scene_enabled, Some(true));
+        assert_eq!(wp.hidden, Some(false));
+        assert_eq!(wp.blur, Some(false));
+        assert_eq!(wp.pos, Some((0, 0)));
+        assert_eq!(wp.size, Some((1920, 1080)));
+
+        // Without a wallpaper window, the fallback rect stays on.
+        let plan = arrange(&windows[1..], &one_output(), &arrange_params());
+        assert!(plan.background_rect_enabled);
+    }
+
+    #[test]
+    fn arrange_normal_window_pans_with_border_blur_opacity() {
+        let mut w = snap("firefox");
+        w.is_focused = false;
+        let plan = arrange(&[w], &one_output(), &arrange_params());
+
+        let wp = &plan.windows[0];
+        assert_eq!(wp.scene_enabled, Some(true));
+        assert_eq!(wp.tiling_mode, Some(TilingMode::Floating));
+        assert_eq!(wp.pos, Some((100, 200)));
+        assert_eq!(wp.scale, Some(1.0));
+        assert_eq!(wp.size, Some((640, 480)));
+        assert_eq!(wp.hidden, Some(false));
+        assert_eq!(wp.tiled, None);
+        assert_eq!(wp.border, Some(BorderPlan { width: 0, color: (10, 20, 30, 40) }));
+        assert_eq!(wp.blur, Some(true));
+        assert_eq!(wp.opacity, Some(NORMAL_UNFOCUSED_OPACITY));
+    }
+
+    #[test]
+    fn arrange_hidden_window_disabled_in_scene() {
+        let mut w = snap("firefox");
+        w.minimized = true;
+        let plan = arrange(&[w], &one_output(), &arrange_params());
+
+        let wp = &plan.windows[0];
+        assert_eq!(wp.scene_enabled, Some(false));
+        assert_eq!(wp.hidden, Some(true));
+        assert_eq!(wp.pos, None);
+        assert_eq!(wp.size, None);
+    }
+
+    #[test]
+    fn arrange_first_overlay_gets_slot_second_demotes_to_normal() {
+        let mut first = snap("scratchpad");
+        first.mode = TilingMode::Overlay;
+        first.box_geom = Rect { x: 0, y: 0, width: 0, height: 0 };
+        let mut second = snap("other-overlay");
+        second.mode = TilingMode::Overlay;
+
+        let plan = arrange(&[first, second], &one_output(), &arrange_params());
+
+        // Fresh overlay: right slot (no bars, so the full output is usable),
+        // box_geom written back.
+        let wp = &plan.windows[0];
+        assert_eq!(wp.pos, Some((1512, 24)));
+        assert_eq!(wp.size, Some((400, 1048)));
+        assert_eq!(wp.box_geom, Some(Rect { x: 1512, y: 24, width: 400, height: 1048 }));
+        assert_eq!(wp.tiled, Some(15));
+        assert_eq!(wp.opacity, Some(OVERLAY_UNFOCUSED_OPACITY));
+
+        // Second overlay arranges as a pannable normal window.
+        let wp = &plan.windows[1];
+        assert_eq!(wp.tiling_mode, Some(TilingMode::Overlay));
+        assert_eq!(wp.pos, Some((100, 200)));
+        assert_eq!(wp.size, Some((640, 480)));
+        assert_eq!(wp.opacity, Some(NORMAL_UNFOCUSED_OPACITY));
+    }
+
+    #[test]
+    fn arrange_rule_ssd_reaches_overlay_sizing() {
+        let mut w = snap("scratchpad");
+        w.mode = TilingMode::Overlay;
+        w.ssd = true;
+        w.rule_ssd = Some(false);
+        w.decorations_size = (2, 18);
+
+        let plan = arrange(&[w], &one_output(), &arrange_params());
+        let wp = &plan.windows[0];
+        // The rule override is planned and the client size shrinks by the
+        // decorations, proving the override was visible to placement.
+        assert_eq!(wp.ssd, Some(false));
+        assert_eq!(wp.size, Some((638, 462)));
+    }
+
+    #[test]
+    fn arrange_maximized_enter_saves_geometry() {
+        let mut w = snap("firefox");
+        w.mode = TilingMode::Maximized;
+        w.box_geom = Rect { x: 0, y: 0, width: 150, height: 50 };
+        w.virtual_pos = (150.0, 120.0);
+
+        let plan = arrange(&[w], &one_output(), &arrange_params());
+        let wp = &plan.windows[0];
+        assert_eq!(wp.was_maximized, Some(true));
+        assert_eq!(wp.saved_maximized, Some(((150, 50), (150.0, 120.0))));
+        // Grid snap: spans columns 1-2, row 1 of the 100px grid.
+        assert_eq!(wp.virtual_pos, Some((100.0, 100.0)));
+        assert_eq!(wp.pos, Some((100, 100)));
+        assert_eq!(wp.size, Some((200, 100)));
+    }
+
+    #[test]
+    fn arrange_maximized_exit_restores_saved_geometry() {
+        let mut w = snap("firefox");
+        w.mode = TilingMode::Floating;
+        w.was_maximized = true;
+        w.saved_maximized_size = (500, 400);
+        w.saved_maximized_virtual = (10.0, 20.0);
+
+        let plan = arrange(&[w], &one_output(), &arrange_params());
+        let wp = &plan.windows[0];
+        assert_eq!(wp.was_maximized, Some(false));
+        assert_eq!(wp.box_geom, Some(Rect { x: 0, y: 0, width: 500, height: 400 }));
+        // The restored geometry flows into the pannable placement.
+        assert_eq!(wp.virtual_pos, Some((10.0, 20.0)));
+        assert_eq!(wp.pos, Some((10, 20)));
+        assert_eq!(wp.size, Some((500, 400)));
+    }
+
+    #[test]
+    fn arrange_status_bar_placed_unless_dragged() {
+        let mut bar = snap("cce-status-left-viewport");
+        bar.status_edge = StatusEdge::TopLeft;
+        bar.box_geom = Rect { x: 0, y: 0, width: 200, height: 30 };
+
+        let plan = arrange(&[bar.clone()], &one_output(), &arrange_params());
+        let wp = &plan.windows[0];
+        assert_eq!(wp.tiling_mode, Some(TilingMode::Status));
+        assert_eq!(wp.blur, Some(true));
+        assert_eq!(wp.pos, Some((12, 0)));
+        assert_eq!(wp.size, Some((200, 30)));
+
+        // A dragged bar keeps whatever geometry it has: no placement writes.
+        bar.being_moved = true;
+        let plan = arrange(&[bar], &one_output(), &arrange_params());
+        let wp = &plan.windows[0];
+        assert_eq!(wp.pos, None);
+        assert_eq!(wp.size, None);
+    }
+
+    #[test]
+    fn arrange_multi_output_is_last_wins() {
+        let outputs = vec![
+            OutputSnapshot {
+                layout_box: Rect { x: 0, y: 0, width: 1920, height: 1080 },
+                non_exclusive: Rect { x: 0, y: 0, width: 0, height: 0 },
+            },
+            OutputSnapshot {
+                layout_box: Rect { x: 1920, y: 0, width: 1280, height: 720 },
+                non_exclusive: Rect { x: 0, y: 0, width: 0, height: 0 },
+            },
+        ];
+        let windows = vec![snap("cce-wallpaper"), snap("firefox")];
+        let plan = arrange(&windows, &outputs, &arrange_params());
+
+        // The background covers the second output — the last pass wins.
+        assert_eq!(plan.windows[0].pos, Some((1920, 0)));
+        assert_eq!(plan.windows[0].size, Some((1280, 720)));
+
+        // Maximize state machine only fires once across passes: entering on
+        // pass one must not re-enter (and re-save) on pass two.
+        let mut w = snap("firefox");
+        w.mode = TilingMode::Maximized;
+        w.box_geom = Rect { x: 0, y: 0, width: 150, height: 50 };
+        w.virtual_pos = (150.0, 120.0);
+        let plan = arrange(&[w], &outputs, &arrange_params());
+        // Saved from the original geometry, not the pass-one grid snap.
+        assert_eq!(plan.windows[0].saved_maximized, Some(((150, 50), (150.0, 120.0))));
+    }
+
     #[test]
     fn side_stacks_center_vertically() {
         let items = vec![
diff --git a/src/server/window.rs b/src/server/window.rs
index ac7adfb..1cda7d8 100644
--- a/src/server/window.rs
+++ b/src/server/window.rs
@@ -1012,6 +1012,13 @@ impl Window {
         if self.wm_requested.ssd {
             return (0, 0);
         }
+        self.measure_decorations()
+    }
+
+    /// Raw client-side decoration size (surface minus geometry), regardless
+    /// of the current SSD setting. Callers that honor SSD gate on it
+    /// themselves.
+    pub unsafe fn measure_decorations(&self) -> (i32, i32) {
         let surface = self.root_surface();
         if surface.is_null() {
             return (0, 0);
diff --git a/src/server/window_manager.rs b/src/server/window_manager.rs
index 476cbe4..3cc9e36 100644
--- a/src/server/window_manager.rs
+++ b/src/server/window_manager.rs
@@ -1071,21 +1071,6 @@ impl WindowManager {
     }
 
 
-fn get_closest_tag(x: f64, y: f64) -> i32 {
-    let centers = [(0.0, 0.0), (2000.0, 0.0), (0.0, 2000.0), (2000.0, 2000.0)];
-    let mut min_dist = f64::MAX;
-    let mut best_tag = 1;
-    for (i, &(cx, cy)) in centers.iter().enumerate() {
-        let dx = x - cx;
-        let dy = y - cy;
-        let dist = dx * dx + dy * dy;
-        if dist < min_dist {
-            min_dist = dist;
-            best_tag = (i + 1) as i32;
-        }
-    }
-    best_tag
-}
 
     pub unsafe fn arrange_views(&mut self) {
         log::debug!("Monolithic arrange_views triggered. Windows: {}", self.windows.count());
@@ -1100,7 +1085,7 @@ fn get_closest_tag(x: f64, y: f64) -> i32 {
 
         let outputs_list = &mut (*self.server).om.outputs as *mut ffi::wl_list as *mut WlList;
         let mut curr_out = (*outputs_list).next;
-        
+
         let mut active_outputs: Vec<*mut crate::output::Output> = Vec::new();
         while curr_out != outputs_list {
             let next_out = (*curr_out).next;
@@ -1115,13 +1100,6 @@ fn get_closest_tag(x: f64, y: f64) -> i32 {
             return;
         }
 
-        let has_wallpaper = self.windows.iter().any(|&w| !w.is_null() && !(*w).closed && (*w).is_wallpaper());
-        for &output in &active_outputs {
-            if !(*output).background_rect.is_null() {
-                ffi::wlr_scene_node_set_enabled((*output).background_rect as *mut ffi::wlr_scene_node, !has_wallpaper);
-            }
-        }
-
         let mut focused_window: *mut Window = std::ptr::null_mut();
         let seats_list = &mut (*self.server).input_manager.seats as *mut ffi::wl_list as *mut WlList;
         let mut curr_seat = (*seats_list).next;
@@ -1135,389 +1113,177 @@ fn get_closest_tag(x: f64, y: f64) -> i32 {
             curr_seat = next_seat;
         }
 
+        // Snapshot outputs and windows into plain data, compute the whole
+        // frame's plan in policy code, then apply it to the scene graph.
+        let mut output_snaps: Vec<crate::policy::arrange::OutputSnapshot> = Vec::new();
         for &output in &active_outputs {
             let wlr_box = (*output).sent.box_layout();
-            let phys_x = wlr_box.x;
-            let phys_y = wlr_box.y;
-            let phys_w = wlr_box.width;
-            let phys_h = wlr_box.height;
-
             let non_ex = (*output).layer_shell.scheduled.non_exclusive_area;
-            let mut status_edges: Vec<crate::window::StatusEdge> = Vec::new();
-            for &win_ptr in self.windows.iter() {
-                if win_ptr.is_null() || (*win_ptr).closed {
-                    continue;
-                }
-                if (*win_ptr).is_status_bar() {
-                    status_edges.push((*win_ptr).status_edge);
-                }
-            }
-            let usable = crate::policy::arrange::compute_usable_area(
-                crate::policy::api::Rect { x: phys_x, y: phys_y, width: phys_w, height: phys_h },
-                crate::policy::api::Rect { x: non_ex.x, y: non_ex.y, width: non_ex.width, height: non_ex.height },
-                self.layout.bar_height as i32,
-                self.status_hide_mode,
-                &status_edges,
-            );
-            let viewport_w = wlr_box.width as f64;
-            let viewport_h = wlr_box.height as f64;
-            let camera_center_x = self.desk_pan_x + (viewport_w / 2.0) / self.desk_zoom;
-            let camera_center_y = self.desk_pan_y + (viewport_h / 2.0) / self.desk_zoom;
-            let _active_tag = Self::get_closest_tag(camera_center_x, camera_center_y);
-
-            let mut overlay_windows: Vec<*mut Window> = Vec::new();
-            let mut normal_windows: Vec<*mut Window> = Vec::new();
-
-            for &win_ptr in self.windows.iter() {
-                if (*win_ptr).closed {
-                    continue;
-                }
-
-                let mode = self.get_mode_for_window(win_ptr);
-                let class = crate::policy::arrange::classify_window(
-                    (*win_ptr).role(),
-                    (*win_ptr).minimized,
-                    matches!((*win_ptr).state, crate::window::WindowState::Closing | crate::window::WindowState::Init),
-                    mode,
-                    self.is_window_being_moved(win_ptr),
-                );
-
-                match class {
-                    crate::policy::arrange::WindowClass::Background => {
-                        (*win_ptr).tiling_mode = crate::tiling::TilingMode::Status;
-                        (*win_ptr).wm_requested.tiled = 0;
-                        (*win_ptr).wm_requested.ssd = false;
-                        (*win_ptr).scale = 1.0;
-                        ffi::wlr_scene_node_set_enabled((*win_ptr).tree as *mut ffi::wlr_scene_node, true);
-                        (*win_ptr).rendering_requested.hidden = false;
-                        (*win_ptr).rendering_requested.blur = false;
-                        (*win_ptr).rendering_requested.x = phys_x;
-                        (*win_ptr).rendering_requested.y = phys_y;
-                        (*win_ptr).wm_requested.dimensions = Some(crate::window::Dimensions {
-                            width: phys_w as u32,
-                            height: phys_h as u32,
-                        });
-                        (*win_ptr).wm_requested.bounds = crate::window::Dimensions {
-                            width: phys_w as u32,
-                            height: phys_h as u32,
-                        };
-                    }
-                    crate::policy::arrange::WindowClass::StatusBar => {
-                        (*win_ptr).tiling_mode = crate::tiling::TilingMode::Status;
-                        (*win_ptr).wm_requested.tiled = 0;
-                        (*win_ptr).wm_requested.ssd = false;
-                        (*win_ptr).scale = 1.0;
-                        ffi::wlr_scene_node_set_enabled((*win_ptr).tree as *mut ffi::wlr_scene_node, true);
-                        (*win_ptr).rendering_requested.hidden = false;
-                        (*win_ptr).rendering_requested.blur = self.layout.status_background_blur > 0.001;
-                    }
-                    crate::policy::arrange::WindowClass::Hidden => {
-                        ffi::wlr_scene_node_set_enabled((*win_ptr).tree as *mut ffi::wlr_scene_node, false);
-                        (*win_ptr).rendering_requested.hidden = true;
-                    }
-                    crate::policy::arrange::WindowClass::Overlay | crate::policy::arrange::WindowClass::Normal => {
-                        ffi::wlr_scene_node_set_enabled((*win_ptr).tree as *mut ffi::wlr_scene_node, true);
-                        (*win_ptr).rendering_requested.hidden = false;
-
-                        (*win_ptr).tiling_mode = mode;
-
-                        if !(*win_ptr).mode_locked {
-                            if let Some(rule) = self.get_rule_for_window(win_ptr) {
-                                if let Some(rule_ssd) = rule.ssd {
-                                    (*win_ptr).wm_requested.ssd = rule_ssd;
-                                }
-                            }
-                        }
+            output_snaps.push(crate::policy::arrange::OutputSnapshot {
+                layout_box: crate::policy::api::Rect {
+                    x: wlr_box.x,
+                    y: wlr_box.y,
+                    width: wlr_box.width,
+                    height: wlr_box.height,
+                },
+                non_exclusive: crate::policy::api::Rect {
+                    x: non_ex.x,
+                    y: non_ex.y,
+                    width: non_ex.width,
+                    height: non_ex.height,
+                },
+            });
+        }
 
-                        if class == crate::policy::arrange::WindowClass::Overlay {
-                            overlay_windows.push(win_ptr);
-                        } else {
-                            normal_windows.push(win_ptr);
-                        }
-                    }
-                }
+        let mut win_ptrs: Vec<*mut Window> = Vec::new();
+        let mut window_snaps: Vec<crate::policy::arrange::WindowSnapshot> = Vec::new();
+        for &win_ptr in self.windows.iter() {
+            if win_ptr.is_null() || (*win_ptr).closed {
+                continue;
             }
-
-            let bw = 0;
-
-            let overlay_params = crate::policy::arrange::OverlayParams {
+            let rule_ssd = if !(*win_ptr).mode_locked {
+                self.get_rule_for_window(win_ptr).and_then(|rule| rule.ssd)
+            } else {
+                None
+            };
+            window_snaps.push(crate::policy::arrange::WindowSnapshot {
+                app_id: (*win_ptr).get_app_id_string(),
+                title: (*win_ptr).get_title_string(),
+                role: (*win_ptr).role(),
+                minimized: (*win_ptr).minimized,
+                closing_or_init: matches!((*win_ptr).state, crate::window::WindowState::Closing | crate::window::WindowState::Init),
+                mode: self.get_mode_for_window(win_ptr),
+                rule_ssd,
+                being_moved: self.is_window_being_moved(win_ptr),
+                status_edge: (*win_ptr).status_edge,
+                is_focused: win_ptr == focused_window,
+                box_geom: crate::policy::api::Rect {
+                    x: (*win_ptr).box_geom.x,
+                    y: (*win_ptr).box_geom.y,
+                    width: (*win_ptr).box_geom.width,
+                    height: (*win_ptr).box_geom.height,
+                },
+                min_size: (
+                    (*win_ptr).wm_scheduled.dimensions_hint.min_width as i32,
+                    (*win_ptr).wm_scheduled.dimensions_hint.min_height as i32,
+                ),
+                virtual_pos: ((*win_ptr).virtual_x, (*win_ptr).virtual_y),
+                active_resize: self.get_active_resize_dimensions(win_ptr),
+                ssd: (*win_ptr).wm_requested.ssd,
+                decorations_size: (*win_ptr).measure_decorations(),
+                was_maximized: (*win_ptr).was_maximized,
+                saved_maximized_size: ((*win_ptr).saved_maximized_width, (*win_ptr).saved_maximized_height),
+                saved_maximized_virtual: ((*win_ptr).saved_maximized_virtual_x, (*win_ptr).saved_maximized_virtual_y),
+            });
+            win_ptrs.push(win_ptr);
+        }
+
+        let params = crate::policy::arrange::ArrangeParams {
+            bar_height: self.layout.bar_height,
+            status_hide_mode: self.status_hide_mode,
+            hide_mode_preview: self.layout.status_module_hide_mode_preview as i32,
+            status_blur: self.layout.status_background_blur > 0.001,
+            window_blur: self.layout.window_blur,
+            opacity_enabled: self.layout.window_opacity,
+            border_color: (self.layout.border_r, self.layout.border_g, self.layout.border_b, self.layout.border_a),
+            overlay: crate::policy::arrange::OverlayParams {
                 overlay_width: self.layout.overlay_width,
                 border_gap: self.layout.overlay_border_gap,
                 position_right: self.layout.overlay_position == "right",
                 cloud_position_default: self.layout.cloud_position_default,
-            };
-            let normal_params = crate::policy::arrange::NormalParams {
+            },
+            normal: crate::policy::arrange::NormalParams {
                 gap_right: self.layout.gap_right,
                 gap_top: self.layout.gap_top,
                 cloud_position_default: self.layout.cloud_position_default,
                 desktop_grid_scale: self.layout.desktop_grid_scale,
-            };
-            let ctx = crate::policy::arrange::PlacementCtx {
-                phys: crate::policy::api::Rect { x: phys_x, y: phys_y, width: phys_w, height: phys_h },
-                usable,
-                pan_x: self.desk_pan_x,
-                pan_y: self.desk_pan_y,
-                zoom: self.desk_zoom,
-            };
-
-            for (sp_idx, &win_ptr) in overlay_windows.iter().enumerate() {
-                if sp_idx == 0 {
-                    let app_id = (*win_ptr).get_app_id_string();
-                    let is_cce_cloud = app_id.as_deref().map_or(false, |id| id.starts_with("cce-cloud"));
-
-                    let placement = crate::policy::arrange::place_overlay_window(
-                        &crate::policy::arrange::OverlaySnapshot {
-                            box_geom: crate::policy::api::Rect {
-                                x: (*win_ptr).box_geom.x,
-                                y: (*win_ptr).box_geom.y,
-                                width: (*win_ptr).box_geom.width,
-                                height: (*win_ptr).box_geom.height,
-                            },
-                            min_width: (*win_ptr).wm_scheduled.dimensions_hint.min_width as i32,
-                            is_cloud: is_cce_cloud,
-                            ssd: (*win_ptr).wm_requested.ssd,
-                            decorations_size: (*win_ptr).get_decorations_size(),
-                        },
-                        &overlay_params,
-                        &ctx,
-                    );
+            },
+            pan_x: self.desk_pan_x,
+            pan_y: self.desk_pan_y,
+            zoom: self.desk_zoom,
+        };
 
-                    if let Some(bg) = placement.box_geom_write {
-                        (*win_ptr).box_geom.x = bg.x;
-                        (*win_ptr).box_geom.y = bg.y;
-                        (*win_ptr).box_geom.width = bg.width;
-                        (*win_ptr).box_geom.height = bg.height;
-                    }
-                    (*win_ptr).rendering_requested.x = placement.pos.0;
-                    (*win_ptr).rendering_requested.y = placement.pos.1;
-                    (*win_ptr).scale = 1.0;
-                    (*win_ptr).virtual_x = placement.virtual_pos.0;
-                    (*win_ptr).virtual_y = placement.virtual_pos.1;
-                    (*win_ptr).wm_requested.dimensions = Some(crate::window::Dimensions {
-                        width: placement.size.0,
-                        height: placement.size.1,
-                    });
-                    (*win_ptr).wm_requested.bounds = crate::window::Dimensions {
-                        width: placement.size.0,
-                        height: placement.size.1,
-                    };
-                    (*win_ptr).wm_requested.tiled = 1 | 2 | 4 | 8;
-
-                    let is_focused = win_ptr == focused_window;
-                    (*win_ptr).rendering_requested.border = crate::window::Border {
-                        edges: crate::window::Edges { top: true, bottom: true, left: true, right: true },
-                        width: bw as u32,
-                        r: self.layout.border_r,
-                        g: self.layout.border_g,
-                        b: self.layout.border_b,
-                        a: self.layout.border_a,
-                    };
-                    (*win_ptr).rendering_requested.blur = self.layout.window_blur;
-                    (*win_ptr).rendering_requested.opacity = crate::policy::arrange::window_opacity(
-                        is_focused,
-                        self.layout.window_opacity,
-                        crate::policy::arrange::OVERLAY_UNFOCUSED_OPACITY,
-                    );
-                } else {
-                    normal_windows.push(win_ptr);
-                }
-            }
-
-            // Manage entering/exiting Maximized state for normal windows
-            for &win_ptr in &normal_windows {
-                let transition = crate::policy::arrange::maximized_transition(
-                    (*win_ptr).tiling_mode == crate::tiling::TilingMode::Maximized,
-                    (*win_ptr).was_maximized,
-                    ((*win_ptr).box_geom.width, (*win_ptr).box_geom.height),
-                    (
-                        (*win_ptr).wm_scheduled.dimensions_hint.min_width as i32,
-                        (*win_ptr).wm_scheduled.dimensions_hint.min_height as i32,
-                    ),
-                    ((*win_ptr).saved_maximized_width, (*win_ptr).saved_maximized_height),
-                    ((*win_ptr).saved_maximized_virtual_x, (*win_ptr).saved_maximized_virtual_y),
-                );
-                match transition {
-                    Some(crate::policy::arrange::MaximizedTransition::Enter { width, height }) => {
-                        (*win_ptr).saved_maximized_width = width;
-                        (*win_ptr).saved_maximized_height = height;
-                        (*win_ptr).saved_maximized_virtual_x = (*win_ptr).virtual_x;
-                        (*win_ptr).saved_maximized_virtual_y = (*win_ptr).virtual_y;
-                        (*win_ptr).was_maximized = true;
-                        log::info!("[Maximized] Saved window {:?} geometry: {}x{} at ({}, {})", 
-                            (*win_ptr).get_title_string().as_deref().unwrap_or(""), 
-                            width, height, 
-                            (*win_ptr).saved_maximized_virtual_x, (*win_ptr).saved_maximized_virtual_y
-                        );
-                    }
-                    Some(crate::policy::arrange::MaximizedTransition::Exit { width, height, virtual_x, virtual_y }) => {
-                        (*win_ptr).box_geom.width = width;
-                        (*win_ptr).box_geom.height = height;
-                        (*win_ptr).virtual_x = virtual_x;
-                        (*win_ptr).virtual_y = virtual_y;
-                        (*win_ptr).was_maximized = false;
-
-                        (*win_ptr).wm_requested.dimensions = Some(crate::window::Dimensions {
-                            width: width as u32,
-                            height: height as u32,
-                        });
-                        (*win_ptr).wm_requested.bounds = crate::window::Dimensions {
-                            width: width as u32,
-                            height: height as u32,
-                        };
-                        log::info!("[Maximized] Restored window {:?} geometry: {}x{} at ({}, {})", 
-                            (*win_ptr).get_title_string().as_deref().unwrap_or(""), 
-                            width, height, virtual_x, virtual_y
-                        );
-                    }
-                    None => {}
-                }
-            }
-
-            // Arrange normal windows on the virtual surface
-            for &win_ptr in &normal_windows {
-                let mode = (*win_ptr).tiling_mode;
-                let is_focused = win_ptr == focused_window;
-                let app_id = (*win_ptr).get_app_id_string();
-                let is_cce_cloud = app_id.as_deref().map_or(false, |id| id.starts_with("cce-cloud"));
-
-                let placement = crate::policy::arrange::place_normal_window(
-                    &crate::policy::arrange::NormalSnapshot {
-                        mode,
-                        box_geom: crate::policy::api::Rect {
-                            x: (*win_ptr).box_geom.x,
-                            y: (*win_ptr).box_geom.y,
-                            width: (*win_ptr).box_geom.width,
-                            height: (*win_ptr).box_geom.height,
-                        },
-                        min_size: (
-                            (*win_ptr).wm_scheduled.dimensions_hint.min_width as i32,
-                            (*win_ptr).wm_scheduled.dimensions_hint.min_height as i32,
-                        ),
-                        virtual_pos: ((*win_ptr).virtual_x, (*win_ptr).virtual_y),
-                        active_resize: self.get_active_resize_dimensions(win_ptr),
-                        is_cloud: is_cce_cloud,
-                        saved_maximized_size: ((*win_ptr).saved_maximized_width, (*win_ptr).saved_maximized_height),
-                        saved_maximized_virtual: ((*win_ptr).saved_maximized_virtual_x, (*win_ptr).saved_maximized_virtual_y),
-                    },
-                    &normal_params,
-                    &ctx,
-                );
+        let plan = crate::policy::arrange::arrange(&window_snaps, &output_snaps, &params);
 
-                (*win_ptr).rendering_requested.x = placement.pos.0;
-                (*win_ptr).rendering_requested.y = placement.pos.1;
-                (*win_ptr).scale = placement.scale;
-                if let Some((vx, vy)) = placement.virtual_write {
-                    (*win_ptr).virtual_x = vx;
-                    (*win_ptr).virtual_y = vy;
-                }
-                if let Some(hidden) = placement.hidden {
-                    (*win_ptr).rendering_requested.hidden = hidden;
-                }
-                (*win_ptr).wm_requested.dimensions = Some(crate::window::Dimensions {
-                    width: placement.size.0,
-                    height: placement.size.1,
-                });
-                (*win_ptr).wm_requested.bounds = crate::window::Dimensions {
-                    width: placement.size.0,
-                    height: placement.size.1,
-                };
-                if placement.tiled_all_edges {
-                    (*win_ptr).wm_requested.tiled = 1 | 2 | 4 | 8;
-                }
+        for &output in &active_outputs {
+            if !(*output).background_rect.is_null() {
+                ffi::wlr_scene_node_set_enabled((*output).background_rect as *mut ffi::wlr_scene_node, plan.background_rect_enabled);
+            }
+        }
 
-                // Apply borders, opacity, and blur to normal windows
+        for (&win_ptr, wp) in win_ptrs.iter().zip(plan.windows.iter()) {
+            if let Some(enabled) = wp.scene_enabled {
+                ffi::wlr_scene_node_set_enabled((*win_ptr).tree as *mut ffi::wlr_scene_node, enabled);
+            }
+            if let Some(hidden) = wp.hidden {
+                (*win_ptr).rendering_requested.hidden = hidden;
+            }
+            if let Some(mode) = wp.tiling_mode {
+                (*win_ptr).tiling_mode = mode;
+            }
+            if let Some(tiled) = wp.tiled {
+                (*win_ptr).wm_requested.tiled = tiled;
+            }
+            if let Some(ssd) = wp.ssd {
+                (*win_ptr).wm_requested.ssd = ssd;
+            }
+            if let Some(scale) = wp.scale {
+                (*win_ptr).scale = scale;
+            }
+            if let Some((x, y)) = wp.pos {
+                (*win_ptr).rendering_requested.x = x;
+                (*win_ptr).rendering_requested.y = y;
+            }
+            if let Some(bg) = wp.box_geom {
+                (*win_ptr).box_geom.x = bg.x;
+                (*win_ptr).box_geom.y = bg.y;
+                (*win_ptr).box_geom.width = bg.width;
+                (*win_ptr).box_geom.height = bg.height;
+            }
+            if let Some((vx, vy)) = wp.virtual_pos {
+                (*win_ptr).virtual_x = vx;
+                (*win_ptr).virtual_y = vy;
+            }
+            if let Some((width, height)) = wp.size {
+                (*win_ptr).wm_requested.dimensions = Some(crate::window::Dimensions { width, height });
+                (*win_ptr).wm_requested.bounds = crate::window::Dimensions { width, height };
+            }
+            if let Some(border) = wp.border {
                 (*win_ptr).rendering_requested.border = crate::window::Border {
                     edges: crate::window::Edges { top: true, bottom: true, left: true, right: true },
-                    width: bw as u32,
-                    r: self.layout.border_r,
-                    g: self.layout.border_g,
-                    b: self.layout.border_b,
-                    a: self.layout.border_a,
+                    width: border.width,
+                    r: border.color.0,
+                    g: border.color.1,
+                    b: border.color.2,
+                    a: border.color.3,
                 };
-                (*win_ptr).rendering_requested.blur = self.layout.window_blur;
-                (*win_ptr).rendering_requested.opacity = crate::policy::arrange::window_opacity(
-                    is_focused,
-                    self.layout.window_opacity,
-                    crate::policy::arrange::NORMAL_UNFOCUSED_OPACITY,
-                );
             }
-            // Position status bar windows on this output.
-            // Snapshot the bars (excluding any being interactively dragged),
-            // lay them out in policy code, then apply the placements.
-            let mut status_items: Vec<crate::policy::arrange::StatusBarItem> = Vec::new();
-            let mut status_wins: Vec<*mut Window> = Vec::new();
-
-            for &win_ptr in self.windows.iter() {
-                if win_ptr.is_null() || (*win_ptr).closed {
-                    continue;
-                }
-                if matches!((*win_ptr).state, crate::window::WindowState::Closing | crate::window::WindowState::Init) {
-                    continue;
-                }
-                if let Some(app_id) = (*win_ptr).get_app_id_string() {
-                    if app_id.starts_with("cce-status") {
-                        // Skip if currently being dragged interactively
-                        let mut is_being_dragged = false;
-                        let seats_list = &mut (*self.server).input_manager.seats as *mut ffi::wl_list as *mut WlList;
-                        let mut curr_seat = (*seats_list).next;
-                        while curr_seat != seats_list {
-                            let seat = crate::container_of!(curr_seat, crate::seat::Seat, link);
-                            if let Some(ref op) = (*seat).op {
-                                if op.window_ptr == win_ptr && matches!(op.op_type, crate::seat::PointerOpType::Move) {
-                                    is_being_dragged = true;
-                                    break;
-                                }
-                            }
-                            curr_seat = (*curr_seat).next;
-                        }
-                        if is_being_dragged {
-                            continue;
-                        }
-
-                        log::info!("[ArrangeStatus] app_id={} status_edge={:?}", app_id, (*win_ptr).status_edge);
-                        status_items.push(crate::policy::arrange::StatusBarItem {
-                            app_id,
-                            edge: (*win_ptr).status_edge,
-                            prev_len: std::cmp::max((*win_ptr).box_geom.width, (*win_ptr).box_geom.height),
-                        });
-                        status_wins.push(win_ptr);
-                    }
-                }
-            }
-
-            let placements = crate::policy::arrange::layout_status_bars(
-                &status_items,
-                &crate::policy::arrange::StatusBarLayoutParams {
-                    output: crate::policy::api::Rect {
-                        x: wlr_box.x,
-                        y: wlr_box.y,
-                        width: wlr_box.width,
-                        height: wlr_box.height,
-                    },
-                    bar_height: self.layout.bar_height as u32,
-                    hide_mode: self.status_hide_mode,
-                    hide_mode_preview: self.layout.status_module_hide_mode_preview as i32,
-                },
-            );
-
-            for (&win_ptr, placement) in status_wins.iter().zip(placements.iter()) {
-                if let Some(pl) = placement {
-                    (*win_ptr).rendering_requested.x = pl.x;
-                    (*win_ptr).rendering_requested.y = pl.y;
-                    (*win_ptr).wm_requested.dimensions = Some(crate::window::Dimensions { width: pl.width, height: pl.height });
-                    (*win_ptr).wm_requested.bounds = crate::window::Dimensions { width: pl.width, height: pl.height };
-                }
+            if let Some(blur) = wp.blur {
+                (*win_ptr).rendering_requested.blur = blur;
+            }
+            if let Some(opacity) = wp.opacity {
+                (*win_ptr).rendering_requested.opacity = opacity;
+            }
+            if let Some(((width, height), (vx, vy))) = wp.saved_maximized {
+                (*win_ptr).saved_maximized_width = width;
+                (*win_ptr).saved_maximized_height = height;
+                (*win_ptr).saved_maximized_virtual_x = vx;
+                (*win_ptr).saved_maximized_virtual_y = vy;
             }
+            if let Some(was_maximized) = wp.was_maximized {
+                (*win_ptr).was_maximized = was_maximized;
+            }
+        }
 
-            // Force configure for all status bar windows on this output so they receive the new geometry immediately
-            for &win_ptr in self.windows.iter() {
-                if !win_ptr.is_null() && !(*win_ptr).closed && (*win_ptr).is_status_bar() {
-                    if (*win_ptr).wm_requested.dimensions.is_some() {
-                        (*win_ptr).manage_finish();
-                    }
+        // Force configure for all status bar windows so they receive the new geometry immediately
+        for &win_ptr in self.windows.iter() {
+            if !win_ptr.is_null() && !(*win_ptr).closed && (*win_ptr).is_status_bar() {
+                if (*win_ptr).wm_requested.dimensions.is_some() {
+                    (*win_ptr).manage_finish();
                 }
             }
         }
+
         // If the focused window is no longer visible, refocus
         let seats_list = &mut (*self.server).input_manager.seats as *mut ffi::wl_list as *mut WlList;
         let mut curr_seat = (*seats_list).next;