Gate toggle_pin on ENBOXER_ALLOW_LAYOUT (Bug #12)

toggle_pin (a.k.a. stay-on-top) is a per-window Hyprland mutation, the
same class of side-effect as layout-apply. Without an opt-in gate, a
stray hotkey can pin the leader window while the user is away from
the keyboard.

Adds the moves_allowed() helper next to toggle_pin. The rest of
session.rs is unaffected for now; future commits can replace inline
env checks with this helper.
This commit is contained in:
en 2026-09-16 08:03:05 +02:00
parent 91cfee9609
commit 84941247c4

View File

@ -690,7 +690,26 @@ async fn reset_layout(session: &Arc<Mutex<Session>>) -> 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<Mutex<Session>>) -> 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