mirror of
https://gitlab.steamos.cloud/holo/steamos-manager.git
synced 2025-07-15 10:46:41 -04:00
Merge branch 'work/sitter/sessionmgmt' into 'master'
implement SessionManagement1 See merge request holo/steamos-manager!9
This commit is contained in:
commit
f85317b43b
10 changed files with 445 additions and 3 deletions
1
Cargo.lock
generated
1
Cargo.lock
generated
|
@ -1064,6 +1064,7 @@ dependencies = [
|
|||
"nix 0.30.1",
|
||||
"num_enum",
|
||||
"regex",
|
||||
"rust-ini",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"strum",
|
||||
|
|
|
@ -21,6 +21,7 @@ libc = "0.2"
|
|||
nix = { version = "0.30", default-features = false, features = ["fs", "poll", "signal", "time"] }
|
||||
num_enum = "0.7"
|
||||
regex = "1"
|
||||
rust-ini = "0.21"
|
||||
serde = { version = "1.0", default-features = false, features = ["derive"] }
|
||||
serde_json = "1.0"
|
||||
strum = { version = "0.27", features = ["derive"] }
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
Copyright © 2023 Collabora Ltd.
|
||||
Copyright © 2024 Igalia S.L.
|
||||
Copyright © 2024 Valve Corporation.
|
||||
Copyright © 2025 Harald Sitter <sitter@kde.org>
|
||||
SPDX-License-Identifier: MIT
|
||||
-->
|
||||
|
||||
|
@ -681,4 +682,63 @@
|
|||
|
||||
</interface>
|
||||
|
||||
<!--
|
||||
com.steampowered.SteamOSManager1.SessionManagement1
|
||||
@short_description: Interface to manage session types.
|
||||
|
||||
Valid values include all sessions available in /usr/share/xsessions and /usr/share/wayland-sessions.
|
||||
-->
|
||||
<interface name="com.steampowered.SteamOSManager1.SessionManagement1">
|
||||
|
||||
<!--
|
||||
DefaultSessionType:
|
||||
|
||||
The default session type to use when booting the system.
|
||||
|
||||
Valid values include all sessions available in /usr/share/xsessions and /usr/share/wayland-sessions.
|
||||
-->
|
||||
<property name="DefaultSessionType" type="s" access="readwrite"/>
|
||||
|
||||
<!--
|
||||
DefaultDesktopSessionType:
|
||||
|
||||
The default session type to use when starting desktop mode.
|
||||
|
||||
Valid values include all sessions available in /usr/share/xsessions and /usr/share/wayland-sessions.
|
||||
-->
|
||||
<property name="DefaultDesktopSessionType" type="s" access="readwrite"/>
|
||||
|
||||
<!--
|
||||
SwitchToSession:
|
||||
|
||||
Switch to the provided session type. This will change the session type temporarily and stop the running
|
||||
session. The login manager will then log into the new session type.
|
||||
|
||||
Note that resetting this temporary type needs to happen as part of the login. steamos-manager will not
|
||||
automatically reset the session type on its own!
|
||||
|
||||
Valid values include all sessions available in /usr/share/xsessions and /usr/share/wayland-sessions.
|
||||
-->
|
||||
<method name="SwitchToSession">
|
||||
<arg type="s" name="type" direction="in"/>
|
||||
</method>
|
||||
|
||||
<!--
|
||||
SwitchToGameMode:
|
||||
|
||||
Convenience method to switch to the game mode session type.
|
||||
-->
|
||||
<method name="SwitchToGameMode">
|
||||
</method>
|
||||
|
||||
<!--
|
||||
SwitchToDesktopMode:
|
||||
|
||||
Convenience method to switch to the desktop mode session type (adheres to DefaultDesktopSessionType)
|
||||
-->
|
||||
<method name="SwitchToDesktopMode">
|
||||
</method>
|
||||
|
||||
</interface>
|
||||
|
||||
</node>
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
/*
|
||||
* Copyright © 2023 Collabora Ltd.
|
||||
* Copyright © 2024 Valve Software
|
||||
* Copyright © 2025 Harald Sitter <sitter@kde.org>
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
@ -17,9 +18,9 @@ use steamos_manager::power::{CPUScalingGovernor, GPUPerformanceLevel, GPUPowerPr
|
|||
use steamos_manager::proxy::{
|
||||
AmbientLightSensor1Proxy, BatteryChargeLimit1Proxy, CpuScaling1Proxy, FactoryReset1Proxy,
|
||||
FanControl1Proxy, GpuPerformanceLevel1Proxy, GpuPowerProfile1Proxy, HdmiCec1Proxy,
|
||||
LowPowerMode1Proxy, Manager2Proxy, PerformanceProfile1Proxy, ScreenReader0Proxy, Storage1Proxy,
|
||||
TdpLimit1Proxy, UpdateBios1Proxy, UpdateDock1Proxy, WifiDebug1Proxy, WifiDebugDump1Proxy,
|
||||
WifiPowerManagement1Proxy,
|
||||
LowPowerMode1Proxy, Manager2Proxy, PerformanceProfile1Proxy, ScreenReader0Proxy,
|
||||
SessionManagement1Proxy, Storage1Proxy, TdpLimit1Proxy, UpdateBios1Proxy, UpdateDock1Proxy,
|
||||
WifiDebug1Proxy, WifiDebugDump1Proxy, WifiPowerManagement1Proxy,
|
||||
};
|
||||
use steamos_manager::screenreader::{ScreenReaderAction, ScreenReaderMode};
|
||||
use steamos_manager::wifi::{WifiBackend, WifiDebugMode, WifiPowerManagement};
|
||||
|
@ -269,6 +270,36 @@ enum Commands {
|
|||
/// `toggle_mode`
|
||||
action: ScreenReaderAction,
|
||||
},
|
||||
|
||||
/// Switch to desktop mode
|
||||
SwitchToDesktopMode,
|
||||
|
||||
/// Switch to game mode
|
||||
SwitchToGameMode,
|
||||
|
||||
/// Switch to a specific session type
|
||||
SwitchToSession {
|
||||
/// The session type to switch to, e.g. `plasma`, `gamescope`.
|
||||
ty: String,
|
||||
},
|
||||
|
||||
/// Default desktop session type
|
||||
GetDefaultDesktopSessionType,
|
||||
|
||||
/// Set default desktop session type
|
||||
SetDefaultDesktopSessionType {
|
||||
/// The session type to set as default, e.g. `plasma`, `plasmax11`.
|
||||
ty: String,
|
||||
},
|
||||
|
||||
/// Default session type
|
||||
GetDefaultSessionType,
|
||||
|
||||
/// Set default session type
|
||||
SetDefaultSessionType {
|
||||
/// The session type to set as default, e.g. `plasma`, `gamescope`.
|
||||
ty: String,
|
||||
},
|
||||
}
|
||||
|
||||
async fn get_all_properties(conn: &Connection) -> Result<()> {
|
||||
|
@ -638,6 +669,36 @@ async fn main() -> Result<()> {
|
|||
.trigger_action(*action as u32, now.try_into()?)
|
||||
.await?;
|
||||
}
|
||||
Commands::SwitchToDesktopMode => {
|
||||
let proxy = SessionManagement1Proxy::new(&conn).await?;
|
||||
proxy.switch_to_desktop_mode().await?;
|
||||
}
|
||||
Commands::SwitchToGameMode => {
|
||||
let proxy = SessionManagement1Proxy::new(&conn).await?;
|
||||
proxy.switch_to_game_mode().await?;
|
||||
}
|
||||
Commands::SwitchToSession { ty } => {
|
||||
let proxy = SessionManagement1Proxy::new(&conn).await?;
|
||||
proxy.switch_to_session(ty.as_str()).await?;
|
||||
}
|
||||
Commands::GetDefaultDesktopSessionType => {
|
||||
let proxy = SessionManagement1Proxy::new(&conn).await?;
|
||||
let ty = proxy.default_desktop_session_type().await?;
|
||||
println!("Default desktop session type: {ty}");
|
||||
}
|
||||
Commands::SetDefaultDesktopSessionType { ty } => {
|
||||
let proxy = SessionManagement1Proxy::new(&conn).await?;
|
||||
proxy.set_default_desktop_session_type(ty.as_str()).await?;
|
||||
}
|
||||
Commands::GetDefaultSessionType => {
|
||||
let proxy = SessionManagement1Proxy::new(&conn).await?;
|
||||
let ty = proxy.default_session_type().await?;
|
||||
println!("Default session type: {ty}");
|
||||
}
|
||||
Commands::SetDefaultSessionType { ty } => {
|
||||
let proxy = SessionManagement1Proxy::new(&conn).await?;
|
||||
proxy.set_default_session_type(ty.as_str()).await?;
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
|
|
|
@ -36,6 +36,7 @@ pub mod hardware;
|
|||
pub mod power;
|
||||
pub mod proxy;
|
||||
pub mod screenreader;
|
||||
pub mod session_management;
|
||||
pub mod wifi;
|
||||
|
||||
#[cfg(test)]
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
* Copyright © 2023 Collabora Ltd.
|
||||
* Copyright © 2024 Valve Software
|
||||
* Copyright © 2024 Igalia S.L.
|
||||
* Copyright © 2025 Harald Sitter <sitter@kde.org>
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
@ -33,6 +34,9 @@ use crate::power::{
|
|||
GPUPerformanceLevel, GPUPowerProfile, SysfsWritten, TdpLimitManager,
|
||||
};
|
||||
use crate::process::{run_script, script_output};
|
||||
use crate::session_management::{
|
||||
clear_ephemeral_session, set_session_to_switch_to, write_default_desktop_session_type, write_default_session_type
|
||||
};
|
||||
use crate::wifi::{
|
||||
extract_wifi_trace, generate_wifi_dump, set_wifi_backend, set_wifi_debug_mode,
|
||||
set_wifi_power_management_state, WifiBackend, WifiDebugMode, WifiPowerManagement,
|
||||
|
@ -488,6 +492,30 @@ impl SteamOSManager {
|
|||
.map_err(to_zbus_fdo_error)
|
||||
}
|
||||
|
||||
async fn set_session_to_switch_to(&self, ty: &str) -> fdo::Result<()> {
|
||||
set_session_to_switch_to(ty)
|
||||
.await
|
||||
.inspect_err(|message| error!("Error switching to session: {message}"))
|
||||
.map_err(to_zbus_fdo_error)
|
||||
}
|
||||
|
||||
async fn set_default_desktop_session_type(&mut self, ty: &str) -> fdo::Result<()> {
|
||||
write_default_desktop_session_type(ty)
|
||||
.await
|
||||
.map_err(to_zbus_fdo_error)
|
||||
}
|
||||
|
||||
async fn set_default_session_type(&mut self, ty: &str) -> fdo::Result<()> {
|
||||
write_default_session_type(ty)
|
||||
.await
|
||||
.map_err(to_zbus_fdo_error)
|
||||
}
|
||||
|
||||
async fn set_login_successful(&mut self) -> fdo::Result<()> {
|
||||
clear_ephemeral_session().await
|
||||
.map_err(to_zbus_fdo_error)
|
||||
}
|
||||
|
||||
/// A version property.
|
||||
#[zbus(property(emits_changed_signal = "const"))]
|
||||
async fn version(&self) -> u32 {
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
* Copyright © 2023 Collabora Ltd.
|
||||
* Copyright © 2024 Valve Software
|
||||
* Copyright © 2024 Igalia S.L.
|
||||
* Copyright © 2025 Harald Sitter <sitter@kde.org>
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
@ -35,6 +36,9 @@ use crate::power::{
|
|||
get_max_charge_level, get_platform_profile, TdpManagerCommand,
|
||||
};
|
||||
use crate::screenreader::{OrcaManager, ScreenReaderAction, ScreenReaderMode};
|
||||
use crate::session_management::{
|
||||
read_default_desktop_session_type, read_default_session_type, restart_session,
|
||||
};
|
||||
use crate::wifi::{
|
||||
get_wifi_backend, get_wifi_power_management_state, list_wifi_interfaces, WifiBackend,
|
||||
};
|
||||
|
@ -157,6 +161,11 @@ struct PerformanceProfile1 {
|
|||
tdp_limit_manager: Option<UnboundedSender<TdpManagerCommand>>,
|
||||
}
|
||||
|
||||
struct SessionManagement1 {
|
||||
proxy: Proxy<'static>,
|
||||
connection: Connection,
|
||||
}
|
||||
|
||||
struct ScreenReader0 {
|
||||
screen_reader: OrcaManager<'static>,
|
||||
}
|
||||
|
@ -723,6 +732,65 @@ impl ScreenReader0 {
|
|||
}
|
||||
}
|
||||
|
||||
#[interface(name = "com.steampowered.SteamOSManager1.SessionManagement1")]
|
||||
impl SessionManagement1 {
|
||||
async fn switch_to_desktop_mode(&self) -> fdo::Result<()> {
|
||||
self.switch_to_session(
|
||||
read_default_desktop_session_type()
|
||||
.await
|
||||
.map_err(to_zbus_fdo_error)?
|
||||
.as_str(),
|
||||
)
|
||||
.await
|
||||
}
|
||||
|
||||
async fn switch_to_game_mode(&self) -> fdo::Result<()> {
|
||||
self.switch_to_session("gamescope-wayland").await
|
||||
}
|
||||
|
||||
async fn switch_to_session(&self, ty: &str) -> fdo::Result<()> {
|
||||
let _: () = method!(self, "SetSessionToSwitchTo", ty)?;
|
||||
restart_session(&self.connection)
|
||||
.await
|
||||
.map_err(to_zbus_fdo_error)
|
||||
}
|
||||
|
||||
#[zbus(property)]
|
||||
async fn default_desktop_session_type(&self) -> fdo::Result<String> {
|
||||
read_default_desktop_session_type()
|
||||
.await
|
||||
.map_err(to_zbus_fdo_error)
|
||||
}
|
||||
|
||||
#[zbus(property)]
|
||||
async fn set_default_desktop_session_type(
|
||||
&self,
|
||||
ty: &str,
|
||||
#[zbus(signal_emitter)] ctx: SignalEmitter<'_>,
|
||||
) -> zbus::Result<()> {
|
||||
let _: () = self
|
||||
.proxy
|
||||
.call("SetDefaultDesktopSessionType", &(ty))
|
||||
.await?;
|
||||
self.default_desktop_session_type_changed(&ctx).await
|
||||
}
|
||||
|
||||
#[zbus(property)]
|
||||
async fn default_session_type(&self) -> fdo::Result<String> {
|
||||
read_default_session_type().await.map_err(to_zbus_fdo_error)
|
||||
}
|
||||
|
||||
#[zbus(property)]
|
||||
async fn set_default_session_type(
|
||||
&self,
|
||||
ty: &str,
|
||||
#[zbus(signal_emitter)] ctx: SignalEmitter<'_>,
|
||||
) -> zbus::Result<()> {
|
||||
let _: () = self.proxy.call("SetDefaultSessionType", &(ty)).await?;
|
||||
self.default_session_type_changed(&ctx).await
|
||||
}
|
||||
}
|
||||
|
||||
#[interface(name = "com.steampowered.SteamOSManager1.Storage1")]
|
||||
impl Storage1 {
|
||||
async fn format_device(
|
||||
|
@ -1087,6 +1155,10 @@ pub(crate) async fn create_interfaces(
|
|||
channel: daemon,
|
||||
};
|
||||
let screen_reader = ScreenReader0::new(&session).await?;
|
||||
let session_management = SessionManagement1 {
|
||||
proxy: proxy.clone(),
|
||||
connection: session.clone(),
|
||||
};
|
||||
let wifi_debug = WifiDebug1 {
|
||||
proxy: proxy.clone(),
|
||||
};
|
||||
|
@ -1144,6 +1216,8 @@ pub(crate) async fn create_interfaces(
|
|||
object_server.at(MANAGER_PATH, screen_reader).await?;
|
||||
}
|
||||
|
||||
object_server.at(MANAGER_PATH, session_management).await?;
|
||||
|
||||
if steam_deck_variant().await.unwrap_or_default() == SteamDeckVariant::Galileo {
|
||||
object_server.at(MANAGER_PATH, wifi_debug).await?;
|
||||
}
|
||||
|
|
|
@ -26,6 +26,7 @@ mod low_power_mode1;
|
|||
mod manager2;
|
||||
mod performance_profile1;
|
||||
mod screenreader0;
|
||||
mod session_management1;
|
||||
mod storage1;
|
||||
mod tdp_limit1;
|
||||
mod update_bios1;
|
||||
|
@ -45,6 +46,7 @@ pub use crate::proxy::low_power_mode1::LowPowerMode1Proxy;
|
|||
pub use crate::proxy::manager2::Manager2Proxy;
|
||||
pub use crate::proxy::performance_profile1::PerformanceProfile1Proxy;
|
||||
pub use crate::proxy::screenreader0::ScreenReader0Proxy;
|
||||
pub use crate::proxy::session_management1::SessionManagement1Proxy;
|
||||
pub use crate::proxy::storage1::Storage1Proxy;
|
||||
pub use crate::proxy::tdp_limit1::TdpLimit1Proxy;
|
||||
pub use crate::proxy::update_bios1::UpdateBios1Proxy;
|
||||
|
|
42
src/proxy/session_management1.rs
Normal file
42
src/proxy/session_management1.rs
Normal file
|
@ -0,0 +1,42 @@
|
|||
//! # D-Bus interface proxy for: `com.steampowered.SteamOSManager1.SessionManagement1`
|
||||
//!
|
||||
//! This code was generated by `zbus-xmlgen` `5.1.0` from D-Bus introspection data.
|
||||
//! Source: `com.steampowered.SteamOSManager1.xml`.
|
||||
//!
|
||||
//! You may prefer to adapt it, instead of using it verbatim.
|
||||
//!
|
||||
//! More information can be found in the [Writing a client proxy] section of the zbus
|
||||
//! documentation.
|
||||
//!
|
||||
//!
|
||||
//! [Writing a client proxy]: https://dbus2.github.io/zbus/client.html
|
||||
//! [D-Bus standard interfaces]: https://dbus.freedesktop.org/doc/dbus-specification.html#standard-interfaces,
|
||||
use zbus::proxy;
|
||||
#[proxy(
|
||||
interface = "com.steampowered.SteamOSManager1.SessionManagement1",
|
||||
default_service = "com.steampowered.SteamOSManager1",
|
||||
default_path = "/com/steampowered/SteamOSManager1",
|
||||
assume_defaults = true
|
||||
)]
|
||||
pub trait SessionManagement1 {
|
||||
/// SwitchToDesktopMode method
|
||||
fn switch_to_desktop_mode(&self) -> zbus::Result<()>;
|
||||
|
||||
/// SwitchToGameMode method
|
||||
fn switch_to_game_mode(&self) -> zbus::Result<()>;
|
||||
|
||||
/// SwitchToSession method
|
||||
fn switch_to_session(&self, type_: &str) -> zbus::Result<()>;
|
||||
|
||||
/// DefaultDesktopSessionType property
|
||||
#[zbus(property)]
|
||||
fn default_desktop_session_type(&self) -> zbus::Result<String>;
|
||||
#[zbus(property)]
|
||||
fn set_default_desktop_session_type(&self, value: &str) -> zbus::Result<()>;
|
||||
|
||||
/// DefaultSessionType property
|
||||
#[zbus(property)]
|
||||
fn default_session_type(&self) -> zbus::Result<String>;
|
||||
#[zbus(property)]
|
||||
fn set_default_session_type(&self, value: &str) -> zbus::Result<()>;
|
||||
}
|
172
src/session_management.rs
Normal file
172
src/session_management.rs
Normal file
|
@ -0,0 +1,172 @@
|
|||
/*
|
||||
* Copyright © 2025 Harald Sitter <sitter@kde.org>
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
use anyhow::{anyhow, bail, Result};
|
||||
use ini::Ini;
|
||||
use tracing::debug;
|
||||
use std::path::Path;
|
||||
use tokio::fs;
|
||||
use zbus::{self, Connection};
|
||||
|
||||
use crate::systemd::SystemdUnit;
|
||||
|
||||
// This is our persistent store. It applies unless an ephemeral session is set.
|
||||
const PERSISTENT_CONFIG_FILE: &str = "/etc/sddm.conf.d/yy-steamos-session.conf";
|
||||
// The ephemeral session configuration is ordered AFTER the persistent one so it can temporarily override it.
|
||||
const EPHEMERAL_CONFIG_FILE: &str = "/etc/sddm.conf.d/zz-steamos-autologin.conf";
|
||||
const CONFIG_SECTION_STEAM: &str = "X-SteamOS";
|
||||
const CONFIG_SECTION_AUTOLOGIN: &str = "Autologin";
|
||||
const DEFAULT_DESKTOP_SESSION: &str = "plasmax11";
|
||||
const DEFAULT_SESSION: &str = "gamescope-wayland";
|
||||
const CONFIG_KEY_DEFAULT_DESKTOP_SESSION: &str = "DefaultDesktopSession";
|
||||
const CONFIG_KEY_SESSION: &str = "Session";
|
||||
|
||||
async fn find_type_in_dir(
|
||||
prefix: impl AsRef<Path>,
|
||||
ty: &str
|
||||
) -> Result<String> {
|
||||
let type_without_suffix = ty.trim_end_matches(".desktop");
|
||||
let expected_session = format!("{type_without_suffix}.desktop");
|
||||
|
||||
let mut dir = fs::read_dir(prefix.as_ref()).await?;
|
||||
while let Some(entry) = dir.next_entry().await? {
|
||||
let file_name = entry.file_name();
|
||||
let session: &str = &file_name.to_string_lossy();
|
||||
if session == &expected_session {
|
||||
return Ok(expected_session);
|
||||
}
|
||||
}
|
||||
|
||||
bail!( "Session type {ty} not found in directory {}",
|
||||
prefix.as_ref().display()
|
||||
)
|
||||
}
|
||||
|
||||
async fn ensure_session_exists(ty: &str) -> Result<String> {
|
||||
// Guard against bad input strings. Notably we don't want relative paths here as they would allow inspecting
|
||||
// all root owned files.
|
||||
// While we are at it also figure out if the session type has a one-shot variant and prefer that.
|
||||
|
||||
for dir in ["/usr/share/wayland-sessions", "/usr/share/xsessions"] {
|
||||
match find_type_in_dir(dir, ty).await {
|
||||
Ok(session) => return Ok(session),
|
||||
Err(e) => debug!("{e}"), // output and try next
|
||||
}
|
||||
}
|
||||
|
||||
bail!("Session type {ty} not found in any of the known session directories")
|
||||
}
|
||||
|
||||
async fn ini_load_async(path: &str) -> Result<Ini> {
|
||||
let data = tokio::fs::read_to_string(path).await?;
|
||||
Ini::load_from_str(data.as_str()).map_err(|e| anyhow!("Failed to load INI from {path}: {e}"))
|
||||
}
|
||||
|
||||
async fn read_type_from_config(
|
||||
config_file: &str,
|
||||
config_section: &str,
|
||||
config_key: &str,
|
||||
default_session: &str,
|
||||
) -> Result<String> {
|
||||
let config = match ini_load_async(config_file).await {
|
||||
Ok(config) => config,
|
||||
_ => return Ok(default_session.to_owned()),
|
||||
};
|
||||
match config.section(Some(config_section)) {
|
||||
Some(section) => {
|
||||
let session = section.get(config_key);
|
||||
return Ok(session.unwrap_or(default_session).to_owned());
|
||||
}
|
||||
None => return Ok(default_session.to_owned()),
|
||||
}
|
||||
}
|
||||
|
||||
async fn write_type_to_config(
|
||||
config_file: &str,
|
||||
config_section: &str,
|
||||
config_key: &str,
|
||||
session_name: &str,
|
||||
) -> Result<()> {
|
||||
let mut config = match ini_load_async(config_file).await {
|
||||
Ok(config) => config,
|
||||
_ => Ini::new(),
|
||||
};
|
||||
config
|
||||
.with_section(Some(config_section))
|
||||
.set(config_key, session_name);
|
||||
config.write_to_file(config_file)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub(crate) async fn set_session_to_switch_to(ty: &str) -> Result<()> {
|
||||
ensure_session_exists(ty).await?;
|
||||
write_type_to_config(
|
||||
EPHEMERAL_CONFIG_FILE,
|
||||
CONFIG_SECTION_AUTOLOGIN,
|
||||
CONFIG_KEY_SESSION,
|
||||
&ty,
|
||||
)
|
||||
.await
|
||||
}
|
||||
|
||||
pub(crate) async fn read_default_desktop_session_type() -> Result<String> {
|
||||
read_type_from_config(
|
||||
PERSISTENT_CONFIG_FILE,
|
||||
CONFIG_SECTION_STEAM,
|
||||
CONFIG_KEY_DEFAULT_DESKTOP_SESSION,
|
||||
DEFAULT_DESKTOP_SESSION,
|
||||
)
|
||||
.await
|
||||
}
|
||||
|
||||
pub(crate) async fn write_default_desktop_session_type(ty: &str) -> Result<()> {
|
||||
ensure_session_exists(ty).await?;
|
||||
write_type_to_config(
|
||||
PERSISTENT_CONFIG_FILE,
|
||||
CONFIG_SECTION_STEAM,
|
||||
CONFIG_KEY_DEFAULT_DESKTOP_SESSION,
|
||||
&ty,
|
||||
)
|
||||
.await
|
||||
}
|
||||
|
||||
pub(crate) async fn read_default_session_type() -> Result<String> {
|
||||
read_type_from_config(
|
||||
PERSISTENT_CONFIG_FILE,
|
||||
CONFIG_SECTION_AUTOLOGIN,
|
||||
CONFIG_KEY_SESSION,
|
||||
DEFAULT_SESSION,
|
||||
)
|
||||
.await
|
||||
}
|
||||
|
||||
pub(crate) async fn write_default_session_type(ty: &str) -> Result<()> {
|
||||
ensure_session_exists(ty).await?;
|
||||
write_type_to_config(
|
||||
PERSISTENT_CONFIG_FILE,
|
||||
CONFIG_SECTION_AUTOLOGIN,
|
||||
CONFIG_KEY_SESSION,
|
||||
ty,
|
||||
)
|
||||
.await
|
||||
}
|
||||
|
||||
pub(crate) async fn restart_session(connection: &Connection) -> Result<()> {
|
||||
for service in ["plasma-workspace.target", "gamescope-session.service"] {
|
||||
let unit = SystemdUnit::new(connection.clone(), service).await?;
|
||||
unit.stop()
|
||||
.await
|
||||
.map_err(|e| anyhow!("Failed to stop {service}: {e}"))?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub(crate) async fn clear_ephemeral_session() -> Result<()> {
|
||||
tokio::fs::remove_file(EPHEMERAL_CONFIG_FILE)
|
||||
.await
|
||||
.map_err(|e| anyhow!("Failed to clear ephemeral session: {e}"))
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue