aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--niri-config/src/lib.rs2
-rw-r--r--src/backend/tty.rs8
-rw-r--r--src/input/mod.rs7
-rw-r--r--src/niri.rs34
-rw-r--r--wiki/Configuration:-Debug-Options.md14
-rw-r--r--wiki/Configuration:-Switch-Events.md10
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!"; }
}
```