Attempt 3 to fix launching permission denied
This commit is contained in:
parent
5e154e19f9
commit
4dcb10d9f1
3 changed files with 69 additions and 9 deletions
|
|
@ -1,10 +1,10 @@
|
|||
[compositor]
|
||||
socket_name = "wo-0"
|
||||
ipc_socket = "/run/user/1000/wo-ipc.sock"
|
||||
ipc_socket = "$XDG_RUNTIME_DIR/wo-ipc.sock"
|
||||
electron_path = "electron"
|
||||
background = [0.08, 0.10, 0.12, 1.0]
|
||||
enable_portal = true
|
||||
portal_socket = "/run/user/1000/wo-portal.sock"
|
||||
portal_socket = "$XDG_RUNTIME_DIR/wo-portal.sock"
|
||||
enable_syscalls = true
|
||||
focus_notify = true
|
||||
|
||||
|
|
|
|||
|
|
@ -246,10 +246,17 @@ impl ApplicationConfig {
|
|||
// Defaults
|
||||
|
||||
fn default_socket_name() -> String { "wo-0".into() }
|
||||
fn default_ipc_socket() -> String { "/run/user/1000/wo-ipc.sock".into() }
|
||||
fn default_electron_path() -> String { "electron".into() }
|
||||
fn default_background() -> [f32; 4] { [0.1, 0.1, 0.1, 1.0] }
|
||||
fn default_portal_socket() -> String { "/run/user/1000/wo-portal.sock".into() }
|
||||
|
||||
/// Returns $XDG_RUNTIME_DIR, falling back to /run/user/<uid>.
|
||||
fn runtime_dir() -> String {
|
||||
std::env::var("XDG_RUNTIME_DIR")
|
||||
.unwrap_or_else(|_| format!("/run/user/{}", unsafe { libc::getuid() }))
|
||||
}
|
||||
|
||||
fn default_ipc_socket() -> String { format!("{}/wo-ipc.sock", runtime_dir()) }
|
||||
fn default_portal_socket() -> String { format!("{}/wo-portal.sock", runtime_dir()) }
|
||||
fn default_width() -> u32 { 1920 }
|
||||
fn default_height() -> u32 { 1080 }
|
||||
fn default_nested_width() -> u32 { 1920 }
|
||||
|
|
@ -259,6 +266,12 @@ fn default_format() -> String { "ARGB8888".into() }
|
|||
fn default_asset_prefix() -> String { "file".into() }
|
||||
fn default_true() -> bool { true }
|
||||
|
||||
fn expand_path(s: &str) -> String {
|
||||
shellexpand::full(s)
|
||||
.map(|cow| cow.into_owned())
|
||||
.unwrap_or_else(|_| s.to_owned())
|
||||
}
|
||||
|
||||
impl Config {
|
||||
pub fn load() -> Result<Self> {
|
||||
// Try multiple locations in order of priority:
|
||||
|
|
@ -278,8 +291,13 @@ impl Config {
|
|||
let text = std::fs::read_to_string(&path_opt)
|
||||
.with_context(|| format!("reading config {path_opt:?}"))?;
|
||||
|
||||
return toml::from_str(&text)
|
||||
.with_context(|| format!("parsing config {path_opt:?}"));
|
||||
let mut config: Self = toml::from_str(&text)
|
||||
.with_context(|| format!("parsing config {path_opt:?}"))?;
|
||||
config.compositor.ipc_socket =
|
||||
expand_path(&config.compositor.ipc_socket);
|
||||
config.compositor.portal_socket =
|
||||
expand_path(&config.compositor.portal_socket);
|
||||
return Ok(config);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
48
src/main.rs
48
src/main.rs
|
|
@ -778,10 +778,52 @@ fn run_drm(config: Config) -> Result<(), anyhow::Error> {
|
|||
|
||||
let drm_device_fd = DrmDeviceFd::new(DeviceFd::from(drm_fd));
|
||||
|
||||
if let Err(e) = drm::Device::acquire_master_lock(&drm_device_fd) {
|
||||
// Retry acquiring DRM master: on logind-managed sessions (e.g. Ly) the VT
|
||||
// switch and master hand-off from logind may not be complete at the exact
|
||||
// moment session.open() returns. libseat's builtin backend logs "Unable to
|
||||
// become DRM master, entering unprivileged mode" and returns the fd anyway;
|
||||
// pumping the event loop lets session-activation events propagate so that
|
||||
// the next drmSetMaster() attempt succeeds.
|
||||
const DRM_MASTER_RETRY_MS: u64 = 100;
|
||||
const DRM_MASTER_RETRY_ROUNDS: u32 = 30; // up to ~3 s
|
||||
let mut last_master_err = None;
|
||||
for round in 0..=DRM_MASTER_RETRY_ROUNDS {
|
||||
match drm::Device::acquire_master_lock(&drm_device_fd) {
|
||||
Ok(()) => {
|
||||
if round > 0 {
|
||||
info!("DRM master acquired after {} retries", round);
|
||||
}
|
||||
last_master_err = None;
|
||||
break;
|
||||
}
|
||||
Err(e) => {
|
||||
let detail = e.to_string();
|
||||
if round == 0 {
|
||||
warn!(
|
||||
gpu = %gpu_path.display(),
|
||||
"DRM master not yet available ({}); retrying up to {}×{}ms...",
|
||||
detail,
|
||||
DRM_MASTER_RETRY_ROUNDS,
|
||||
DRM_MASTER_RETRY_MS,
|
||||
);
|
||||
}
|
||||
last_master_err = Some(detail);
|
||||
let _ = event_loop.dispatch(
|
||||
Some(Duration::from_millis(DRM_MASTER_RETRY_MS)),
|
||||
&mut pre_init,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
if let Some(e) = last_master_err {
|
||||
return Err(anyhow::anyhow!(
|
||||
"failed to become DRM master on {}: {e}. The GPU is likely in use by another active session/compositor. Switch to a free VT, stop the other session, or set compositor.drm_device to a free card.",
|
||||
gpu_path.display()
|
||||
"failed to become DRM master on {gpu}: {e}. \
|
||||
The GPU is likely in use by another active session/compositor. \
|
||||
Ensure wo is launched as the session compositor by a logind-aware \
|
||||
display manager (e.g. Ly, greetd) with pam_systemd.so in its PAM \
|
||||
config, or switch to a free VT first. \
|
||||
If using seatd, add your user to the 'seat' group.",
|
||||
gpu = gpu_path.display(),
|
||||
));
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue