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]
|
[compositor]
|
||||||
socket_name = "wo-0"
|
socket_name = "wo-0"
|
||||||
ipc_socket = "/run/user/1000/wo-ipc.sock"
|
ipc_socket = "$XDG_RUNTIME_DIR/wo-ipc.sock"
|
||||||
electron_path = "electron"
|
electron_path = "electron"
|
||||||
background = [0.08, 0.10, 0.12, 1.0]
|
background = [0.08, 0.10, 0.12, 1.0]
|
||||||
enable_portal = true
|
enable_portal = true
|
||||||
portal_socket = "/run/user/1000/wo-portal.sock"
|
portal_socket = "$XDG_RUNTIME_DIR/wo-portal.sock"
|
||||||
enable_syscalls = true
|
enable_syscalls = true
|
||||||
focus_notify = true
|
focus_notify = true
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -246,10 +246,17 @@ impl ApplicationConfig {
|
||||||
// Defaults
|
// Defaults
|
||||||
|
|
||||||
fn default_socket_name() -> String { "wo-0".into() }
|
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_electron_path() -> String { "electron".into() }
|
||||||
fn default_background() -> [f32; 4] { [0.1, 0.1, 0.1, 1.0] }
|
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_width() -> u32 { 1920 }
|
||||||
fn default_height() -> u32 { 1080 }
|
fn default_height() -> u32 { 1080 }
|
||||||
fn default_nested_width() -> u32 { 1920 }
|
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_asset_prefix() -> String { "file".into() }
|
||||||
fn default_true() -> bool { true }
|
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 {
|
impl Config {
|
||||||
pub fn load() -> Result<Self> {
|
pub fn load() -> Result<Self> {
|
||||||
// Try multiple locations in order of priority:
|
// Try multiple locations in order of priority:
|
||||||
|
|
@ -278,8 +291,13 @@ impl Config {
|
||||||
let text = std::fs::read_to_string(&path_opt)
|
let text = std::fs::read_to_string(&path_opt)
|
||||||
.with_context(|| format!("reading config {path_opt:?}"))?;
|
.with_context(|| format!("reading config {path_opt:?}"))?;
|
||||||
|
|
||||||
return toml::from_str(&text)
|
let mut config: Self = toml::from_str(&text)
|
||||||
.with_context(|| format!("parsing config {path_opt:?}"));
|
.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));
|
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!(
|
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.",
|
"failed to become DRM master on {gpu}: {e}. \
|
||||||
gpu_path.display()
|
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