Open YaLTeR opened 7 months ago
My thinkpad z16 gen 1 goes to sleep without any config when lid is closed.
It shouldn't if you have an external monitor connected. (Also this is managed by logind)
As of niri 0.1.7, my screen does sleep on close, but I would also really like a way to automatically run swaylock
or something like that on lid close.
Here's a bit of a workaround I did -- I modified this to be:
use std::process::Command;
fn main() {
let args: Vec<String> = std::env::args().collect();
if args.len() < 3 {
println!("Cmd example: lid_event /proc/acpi/button/lid/LID0/state 'your_command_here'");
std::process::exit(1);
}
let state_path = &args[1];
let command = args[2..].join(" ");
let mut last_state = is_open(state_path);
loop {
std::thread::sleep(std::time::Duration::new(1, 0));
let state = is_open(state_path);
if last_state && !state {
println!("Lid closed, executing command: {}", command);
match Command::new("sh")
.arg("-c")
.arg(&command)
.output()
{
Ok(output) => {
println!("Command executed successfully");
println!("stdout: {}", String::from_utf8_lossy(&output.stdout));
println!("stderr: {}", String::from_utf8_lossy(&output.stderr));
}
Err(e) => println!("Failed to execute command: {}", e),
}
}
last_state = state;
}
}
fn is_open(filename: &str) -> bool {
let contents = std::fs::read_to_string(filename)
.expect("failed reading the state file");
contents.contains("open")
}
Compiled it as lid_event
, moved it to /usr/bin
, then added
spawn-at-startup "lid_event" "/proc/acpi/button/lid/LID/state" "swaylockniri"
to my Niri config (swaylockniri
is just a program that does the Niri transition then runs swaylock with options:)
#!/usr/bin/env bash
niri msg action do-screen-transition
swaylock \
-fSle \
--indicator \
--indicator-radius 110 \
--indicator-idle-visible \
--clock \
--font 'Cartograph CF' \
--timestr "%-l:%M %p" \
--datestr "%a, %B %-e" \
--effect-blur 30x10 \
--ring-color 31748f \
--key-hl-color 9ccfd8 \
--line-color 908caa \
--text-color e0def4 \
--inside-color 00000000 \
--separator-color 00000000
@ThatOneCalculator so you weren't able to do this with logind
? let me know if you need help with it
I don't actually know how to do this properly with logind lol
To get started https://man.archlinux.org/man/logind.conf.5.en search here for idle and lidswitch (systemd is awesome, thank you systemd)
@YaLTeR come to think of it, why not do this with logind and avoid redoing it in niri? if systemd dependecy is undesirable then elogind can be used?
This issue is not about that, it's about disabling the internal monitor when you close the lid while having an external monitor connected.
Yes you are right, I confused his issue @ThatOneCalculator mentioned above with this.
@YaLTeR any pointers on where to get started on this? i imagine the place to start is to acquire a low-level lock on lidswitch from logind, am i saying it correctly?
In input.rs, handle this event: https://smithay.github.io/smithay/smithay/backend/input/enum.Switch.html#variant.Lid
Apply output on/off on the right output similar to how niri msg output eDP-1 off
would work.
Then do a lot of testing:
niri msg outputs
).Should all this be user configurable?
I can see 1 and 2 not being wanted by everyone, at least sometimes, though they are sensible as defaults.
Implementation wise I think we need to make a function which takes as input all these parameters and does the appropriate thing (basically a big switch-case), and then this function gets called whenever any of lid-switch, suspend/resume, external monitors added/removed etc. have a change.
This also looks like it will translate into an easy configuration UI considering how much complicated/complex logic for this can turn into. Sensible defaults definitely a must-have.
1 is not handled by niri, rather by logind. 2 can have some config flag but I'm not sure how necessary that is.
Smithay recently got the lid close event, so that can be used. Need to verify that it interacts properly with systemd lid sleep and whatnot.