diff --git a/src/session.rs b/src/session.rs index 5a9bbf6..ba4f5f7 100644 --- a/src/session.rs +++ b/src/session.rs @@ -690,7 +690,26 @@ async fn reset_layout(session: &Arc>) -> Result<()> { Ok(()) } +/// True iff the operator has explicitly allowed the daemon to mutate the +/// Hyprland window stack. The enBoxer defaults are keys-only with safe +/// passthrough; per-window moves (pin/float/move/resize) require an opt-in +/// so a stray hotkey cannot wreck the user's layout while they are away +/// from the keyboard. +pub fn moves_allowed() -> bool { + std::env::var("ENBOXER_ALLOW_LAYOUT") + .map(|v| v == "1" || v.eq_ignore_ascii_case("true")) + .unwrap_or(false) +} + async fn toggle_pin(session: &Arc>) -> Result<()> { + // Bug #12: pin/float/move/resize must be opt-in like layout-apply, + // not silently fire on the leader slot on a hotkey press. + if !moves_allowed() { + tracing::warn!( + "toggle_pin: refusing (set ENBOXER_ALLOW_LAYOUT=1 to enable)" + ); + return Ok(()); + } let addr = { let g = session.lock().await; g.slots