diff options
| author | Ivan Molodetskikh <yalterz@gmail.com> | 2024-11-05 09:40:54 +0300 |
|---|---|---|
| committer | Ivan Molodetskikh <yalterz@gmail.com> | 2024-11-05 10:03:51 +0300 |
| commit | cd90dfc7be11147936c2b637ae822ff0adf5a7b7 (patch) | |
| tree | fc156451b6c25d454194fbe885eacf455a649c32 | |
| parent | a778ab38977b99edb79275cf3ad2ddffa24044f7 (diff) | |
| download | niri-cd90dfc7be11147936c2b637ae822ff0adf5a7b7.tar.gz niri-cd90dfc7be11147936c2b637ae822ff0adf5a7b7.tar.bz2 niri-cd90dfc7be11147936c2b637ae822ff0adf5a7b7.zip | |
Disable laptop panel when the lid is closed
| -rw-r--r-- | niri-config/src/lib.rs | 2 | ||||
| -rw-r--r-- | src/backend/tty.rs | 8 | ||||
| -rw-r--r-- | src/input/mod.rs | 7 | ||||
| -rw-r--r-- | src/niri.rs | 34 | ||||
| -rw-r--r-- | wiki/Configuration:-Debug-Options.md | 14 | ||||
| -rw-r--r-- | wiki/Configuration:-Switch-Events.md | 10 |
6 files changed, 66 insertions, 9 deletions
diff --git a/niri-config/src/lib.rs b/niri-config/src/lib.rs index 86e6510c..6e7a4b31 100644 --- a/niri-config/src/lib.rs +++ b/niri-config/src/lib.rs @@ -1533,6 +1533,8 @@ pub struct DebugConfig { pub disable_resize_throttling: bool, #[knuffel(child)] pub disable_transactions: bool, + #[knuffel(child)] + pub keep_laptop_panel_on_when_lid_is_closed: bool, } #[derive(knuffel::DecodeScalar, Debug, Clone, Copy, PartialEq, Eq)] diff --git a/src/backend/tty.rs b/src/backend/tty.rs index 58face27..5da9a604 100644 --- a/src/backend/tty.rs +++ b/src/backend/tty.rs @@ -783,6 +783,10 @@ impl Tty { debug!("output is disabled in the config"); return Ok(()); } + if !niri.should_enable_laptop_panel(&output_name.connector) { + debug!("output is disabled because it is a laptop panel and the lid is closed"); + return Ok(()); + } for m in connector.modes() { trace!("{m:?}"); @@ -1723,7 +1727,7 @@ impl Tty { .find(&surface.name) .cloned() .unwrap_or_default(); - if config.off { + if config.off || !niri.should_enable_laptop_panel(&surface.name.connector) { to_disconnect.push((node, crtc)); continue; } @@ -1833,7 +1837,7 @@ impl Tty { .cloned() .unwrap_or_default(); - if !config.off { + if !config.off && niri.should_enable_laptop_panel(&output_name.connector) { to_connect.push((node, connector.clone(), crtc)); } } diff --git a/src/input/mod.rs b/src/input/mod.rs index 9936102e..ffd62059 100644 --- a/src/input/mod.rs +++ b/src/input/mod.rs @@ -2434,6 +2434,13 @@ impl State { return; }; + if switch == Switch::Lid { + let is_closed = evt.state() == SwitchState::On; + debug!("lid switch {}", if is_closed { "closed" } else { "opened" }); + self.niri.is_lid_closed = is_closed; + self.reload_output_config(); + } + let action = { let bindings = &self.niri.config.borrow().switch_events; find_configured_switch_action(bindings, switch, evt.state()) diff --git a/src/niri.rs b/src/niri.rs index 19480600..50cf444f 100644 --- a/src/niri.rs +++ b/src/niri.rs @@ -143,8 +143,9 @@ use crate::ui::screenshot_ui::{OutputScreenshot, ScreenshotUi, ScreenshotUiRende use crate::utils::scale::{closest_representable_scale, guess_monitor_scale}; use crate::utils::spawning::CHILD_ENV; use crate::utils::{ - center, center_f64, get_monotonic_time, ipc_transform_to_smithay, logical_output, - make_screenshot_path, output_matches_name, output_size, send_scale_transform, write_png_rgba8, + center, center_f64, get_monotonic_time, ipc_transform_to_smithay, is_laptop_panel, + logical_output, make_screenshot_path, output_matches_name, output_size, send_scale_transform, + write_png_rgba8, }; use crate::window::{InitialConfigureState, Mapped, ResolvedWindowRules, Unmapped, WindowRef}; use crate::{animation, niri_render_elements}; @@ -207,6 +208,12 @@ pub struct Niri { // When false, we're idling with monitors powered off. pub monitors_active: bool, + /// Whether the laptop lid is closed. + /// + /// Libinput guarantees that the lid switch starts in open state, and if it was closed during + /// startup, libinput will immediately send a closed event. + pub is_lid_closed: bool, + pub devices: HashSet<input::Device>, pub tablets: HashMap<input::Device, TabletData>, pub touch: HashSet<input::Device>, @@ -1101,6 +1108,12 @@ impl State { if config.debug != old_config.debug { debug_config_changed = true; + + if config.debug.keep_laptop_panel_on_when_lid_is_closed + != old_config.debug.keep_laptop_panel_on_when_lid_is_closed + { + output_config_changed = true; + } } *old_config = config; @@ -1831,6 +1844,7 @@ impl Niri { blocker_cleared_tx, blocker_cleared_rx, monitors_active: true, + is_lid_closed: false, devices: HashSet::new(), tablets: HashMap::new(), @@ -4797,6 +4811,22 @@ impl Niri { .unwrap(); self.pointer_inactivity_timer = Some(token); } + + pub fn should_enable_laptop_panel(&self, connector: &str) -> bool { + // Make sure the output config is reloaded when any of the conditions in this function + // change. + + let config = self.config.borrow(); + + // We reload the output config when this flag changes. + if config.debug.keep_laptop_panel_on_when_lid_is_closed { + return true; + } + + // We reload the output config when the lid switch is toggled, and the connector name is + // static. + !(self.is_lid_closed && is_laptop_panel(connector)) + } } pub struct ClientState { diff --git a/wiki/Configuration:-Debug-Options.md b/wiki/Configuration:-Debug-Options.md index c6563595..9d32ffd9 100644 --- a/wiki/Configuration:-Debug-Options.md +++ b/wiki/Configuration:-Debug-Options.md @@ -22,6 +22,7 @@ debug { emulate-zero-presentation-time disable-resize-throttling disable-transactions + keep-laptop-panel-on-when-lid-is-closed } binds { @@ -165,6 +166,19 @@ debug { } ``` +### `keep-laptop-panel-on-when-lid-is-closed` + +<sup>Since: 0.1.10</sup> + +By default, niri will disable the internal laptop monitor when the laptop lid is closed. +This flag turns off this behavior and will leave the internal laptop monitor on. + +```kdl +debug { + keep-laptop-panel-on-when-lid-is-closed +} +``` + ### Key Bindings These are not debug options, but rather key bindings. diff --git a/wiki/Configuration:-Switch-Events.md b/wiki/Configuration:-Switch-Events.md index d1f8568a..9c60cc81 100644 --- a/wiki/Configuration:-Switch-Events.md +++ b/wiki/Configuration:-Switch-Events.md @@ -8,8 +8,8 @@ Here are all the events that you can bind at a glance: ```kdl switch-events { - lid-close { spawn "bash" "-c" "niri msg output \"eDP-1\" off"; } - lid-open { spawn "bash" "-c" "niri msg output \"eDP-1\" on"; } + lid-close { spawn "notify-send" "The laptop lid is closed!"; } + lid-open { spawn "notify-send" "The laptop lid is open!"; } tablet-mode-on { spawn "bash" "-c" "gsettings set org.gnome.desktop.a11y.applications screen-keyboard-enabled true"; } tablet-mode-off { spawn "bash" "-c" "gsettings set org.gnome.desktop.a11y.applications screen-keyboard-enabled false"; } } @@ -25,12 +25,12 @@ Currently, only the `spawn` action are supported. These events correspond to closing and opening of the laptop lid. -You could use them to turn the laptop internal monitor off and on (until niri gets this functionality built-in). +Note that niri will already automatically turn the internal laptop monitor on and off in accordance with the laptop lid. ```kdl switch-events { - lid-close { spawn "bash" "-c" "niri msg output \"eDP-1\" off"; } - lid-open { spawn "bash" "-c" "niri msg output \"eDP-1\" on"; } + lid-close { spawn "notify-send" "The laptop lid is closed!"; } + lid-open { spawn "notify-send" "The laptop lid is open!"; } } ``` |
