state/lid-inhibit: Take current lid state into account
This commit is contained in:
parent
de43fb1f0e
commit
74e90f793f
4 changed files with 83 additions and 37 deletions
|
|
@ -68,7 +68,7 @@ pub struct KmsState {
|
||||||
pub software_renderer: Option<GlowRenderer>,
|
pub software_renderer: Option<GlowRenderer>,
|
||||||
pub api: GpuManager<GbmGlowBackend<DrmDeviceFd>>,
|
pub api: GpuManager<GbmGlowBackend<DrmDeviceFd>>,
|
||||||
|
|
||||||
session: LibSeatSession,
|
pub session: LibSeatSession,
|
||||||
libinput: Libinput,
|
libinput: Libinput,
|
||||||
|
|
||||||
pub syncobj_state: Option<DrmSyncobjState>,
|
pub syncobj_state: Option<DrmSyncobjState>,
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,10 @@
|
||||||
use std::os::fd::OwnedFd;
|
use std::os::fd::OwnedFd;
|
||||||
|
|
||||||
|
use anyhow::{Context, Result};
|
||||||
use logind_zbus::manager::{InhibitType::HandleLidSwitch, ManagerProxyBlocking};
|
use logind_zbus::manager::{InhibitType::HandleLidSwitch, ManagerProxyBlocking};
|
||||||
use zbus::blocking::Connection;
|
use zbus::blocking::Connection;
|
||||||
|
|
||||||
pub fn inhibit_lid() -> anyhow::Result<OwnedFd> {
|
pub fn inhibit_lid() -> Result<OwnedFd> {
|
||||||
let conn = Connection::system()?;
|
let conn = Connection::system()?;
|
||||||
let proxy = ManagerProxyBlocking::new(&conn)?;
|
let proxy = ManagerProxyBlocking::new(&conn)?;
|
||||||
let fd = proxy.inhibit(
|
let fd = proxy.inhibit(
|
||||||
|
|
@ -15,3 +16,9 @@ pub fn inhibit_lid() -> anyhow::Result<OwnedFd> {
|
||||||
|
|
||||||
Ok(fd.into())
|
Ok(fd.into())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn lid_closed() -> Result<bool> {
|
||||||
|
let conn = Connection::system()?;
|
||||||
|
let proxy = ManagerProxyBlocking::new(&conn)?;
|
||||||
|
proxy.lid_closed().context("Failed to talk to logind")
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@ use crate::{
|
||||||
cosmic_keystate_from_smithay, cosmic_modifiers_eq_smithay,
|
cosmic_keystate_from_smithay, cosmic_modifiers_eq_smithay,
|
||||||
cosmic_modifiers_from_smithay,
|
cosmic_modifiers_from_smithay,
|
||||||
},
|
},
|
||||||
Action, Config, OutputConfig, OutputState, PrivateAction,
|
Action, Config, PrivateAction,
|
||||||
},
|
},
|
||||||
input::gestures::{GestureState, SwipeAction},
|
input::gestures::{GestureState, SwipeAction},
|
||||||
shell::{
|
shell::{
|
||||||
|
|
@ -1508,37 +1508,19 @@ impl State {
|
||||||
}
|
}
|
||||||
InputEvent::Special(_) => {}
|
InputEvent::Special(_) => {}
|
||||||
InputEvent::SwitchToggle { event } => {
|
InputEvent::SwitchToggle { event } => {
|
||||||
if event.switch() == Some(Switch::Lid) {
|
#[cfg(feature = "systemd")]
|
||||||
let outputs = self.backend.lock().all_outputs();
|
if event.switch() == Some(Switch::Lid) && self.common.inhibit_lid_fd.is_some() {
|
||||||
if let Some(internal) = outputs.into_iter().find(|o| o.is_internal()) {
|
if event.state() == SwitchState::On {
|
||||||
let config = internal.user_data().get::<RefCell<OutputConfig>>().unwrap();
|
self.backend
|
||||||
let enabled = config.borrow().enabled.clone();
|
.lock()
|
||||||
if enabled != OutputState::Disabled && event.state() == SwitchState::On {
|
.disable_internal_output(&mut self.common.output_configuration_state);
|
||||||
config.borrow_mut().enabled = OutputState::Disabled;
|
} else {
|
||||||
self.common
|
self.backend
|
||||||
.output_configuration_state
|
.lock()
|
||||||
.remove_heads(std::iter::once(&internal));
|
.enable_internal_output(&mut self.common.output_configuration_state);
|
||||||
} else if enabled == OutputState::Disabled
|
|
||||||
&& event.state() == SwitchState::Off
|
|
||||||
{
|
|
||||||
self.common
|
|
||||||
.output_configuration_state
|
|
||||||
.add_heads(std::iter::once(&internal));
|
|
||||||
} else {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
self.common.config.read_outputs(
|
|
||||||
&mut self.common.output_configuration_state,
|
|
||||||
&mut self.backend,
|
|
||||||
&self.common.shell,
|
|
||||||
&self.common.event_loop_handle,
|
|
||||||
&mut self.common.workspace_state.update(),
|
|
||||||
&self.common.xdg_activation_state,
|
|
||||||
self.common.startup_done.clone(),
|
|
||||||
&self.common.clock,
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
self.refresh_output_config();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
65
src/state.rs
65
src/state.rs
|
|
@ -254,7 +254,7 @@ pub struct Common {
|
||||||
pub atspi_ei: crate::wayland::handlers::atspi::AtspiEiState,
|
pub atspi_ei: crate::wayland::handlers::atspi::AtspiEiState,
|
||||||
|
|
||||||
#[cfg(feature = "systemd")]
|
#[cfg(feature = "systemd")]
|
||||||
inhibit_lid_fd: Option<OwnedFd>,
|
pub inhibit_lid_fd: Option<OwnedFd>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
|
|
@ -408,6 +408,37 @@ impl<'a> LockedBackend<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn enable_internal_output(
|
||||||
|
&self,
|
||||||
|
output_configuration_state: &mut OutputConfigurationState<State>,
|
||||||
|
) {
|
||||||
|
let outputs = self.all_outputs();
|
||||||
|
if let Some(internal) = outputs.iter().find(|o| o.is_internal()) {
|
||||||
|
let mut config = internal.config_mut();
|
||||||
|
if config.enabled == OutputState::Disabled {
|
||||||
|
// If it was previously mirrored, `read_outputs` will restore that correctly.
|
||||||
|
// But if we don't have a config for *some* reason or reading it fails,
|
||||||
|
// we don't want to write out `Disabled` accidentally.
|
||||||
|
config.enabled = OutputState::Enabled;
|
||||||
|
output_configuration_state.add_heads(std::iter::once(internal));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn disable_internal_output(
|
||||||
|
&self,
|
||||||
|
output_configuration_state: &mut OutputConfigurationState<State>,
|
||||||
|
) {
|
||||||
|
let outputs = self.all_outputs();
|
||||||
|
if let Some(internal) = outputs.iter().find(|o| o.is_internal()) {
|
||||||
|
let mut config = internal.config_mut();
|
||||||
|
if config.enabled != OutputState::Disabled {
|
||||||
|
config.enabled = OutputState::Disabled;
|
||||||
|
output_configuration_state.remove_heads(std::iter::once(internal));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn apply_config_for_outputs(
|
pub fn apply_config_for_outputs(
|
||||||
&mut self,
|
&mut self,
|
||||||
test_only: bool,
|
test_only: bool,
|
||||||
|
|
@ -740,10 +771,17 @@ impl State {
|
||||||
fn update_inhibitor_locks(&mut self) {
|
fn update_inhibitor_locks(&mut self) {
|
||||||
#[cfg(feature = "systemd")]
|
#[cfg(feature = "systemd")]
|
||||||
{
|
{
|
||||||
|
use smithay::backend::session::Session;
|
||||||
use tracing::{debug, error};
|
use tracing::{debug, error};
|
||||||
|
|
||||||
let outputs = self.backend.lock().all_outputs();
|
let outputs = self.backend.lock().all_outputs();
|
||||||
let should_handle_lid = outputs.iter().any(|o| o.is_internal()) && outputs.len() >= 2;
|
let is_active = match &self.backend {
|
||||||
|
BackendData::Kms(kms) => kms.session.is_active(),
|
||||||
|
_ => true,
|
||||||
|
};
|
||||||
|
|
||||||
|
let should_handle_lid =
|
||||||
|
is_active && outputs.iter().any(|o| o.is_internal()) && outputs.len() >= 2;
|
||||||
|
|
||||||
if should_handle_lid {
|
if should_handle_lid {
|
||||||
if self.common.inhibit_lid_fd.is_none() {
|
if self.common.inhibit_lid_fd.is_none() {
|
||||||
|
|
@ -751,6 +789,18 @@ impl State {
|
||||||
Ok(fd) => {
|
Ok(fd) => {
|
||||||
debug!("Inhibiting lid switch");
|
debug!("Inhibiting lid switch");
|
||||||
self.common.inhibit_lid_fd = Some(fd);
|
self.common.inhibit_lid_fd = Some(fd);
|
||||||
|
|
||||||
|
if crate::dbus::logind::lid_closed().unwrap_or(false) {
|
||||||
|
self.backend.lock().disable_internal_output(
|
||||||
|
&mut self.common.output_configuration_state,
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
self.backend.lock().enable_internal_output(
|
||||||
|
&mut self.common.output_configuration_state,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
self.refresh_output_config();
|
||||||
}
|
}
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
error!("Failed to inhibit lid switch: {}", err);
|
error!("Failed to inhibit lid switch: {}", err);
|
||||||
|
|
@ -758,8 +808,15 @@ impl State {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if self.common.inhibit_lid_fd.take().is_some() {
|
if let Some(_fd) = self.common.inhibit_lid_fd.take() {
|
||||||
debug!("Removing inhibitor-lock on lid switch")
|
debug!("Removing inhibitor-lock on lid switch");
|
||||||
|
|
||||||
|
self.backend
|
||||||
|
.lock()
|
||||||
|
.enable_internal_output(&mut self.common.output_configuration_state);
|
||||||
|
|
||||||
|
self.refresh_output_config();
|
||||||
|
// drop _fd
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue