Disable laptop panel when the lid is closed

This commit is contained in:
Ivan Molodetskikh
2024-11-05 09:40:54 +03:00
parent a778ab3897
commit cd90dfc7be
6 changed files with 66 additions and 9 deletions
+2
View File
@@ -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)]
+6 -2
View File
@@ -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));
}
}
+7
View File
@@ -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())
+32 -2
View File
@@ -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 {
+14
View File
@@ -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.
+5 -5
View File
@@ -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!"; }
}
```