Fix api_desktop_launch for Wayland-only GNOME: run as free user with correct session env vars
Agent-Logs-Url: https://github.com/naturallaw777/staging_alpha/sessions/237927a7-a65c-4c67-b1e2-e5bfd1b3bef7 Co-authored-by: naturallaw777 <99053422+naturallaw777@users.noreply.github.com>
This commit is contained in:
committed by
GitHub
parent
7243f4444f
commit
5b10ab4823
@@ -2195,17 +2195,52 @@ async def api_desktop_launch(desktop_file: str):
|
|||||||
if not _re.match(r'^[a-zA-Z0-9_.-]+\.desktop$', desktop_file):
|
if not _re.match(r'^[a-zA-Z0-9_.-]+\.desktop$', desktop_file):
|
||||||
raise HTTPException(status_code=400, detail="Invalid desktop file name")
|
raise HTTPException(status_code=400, detail="Invalid desktop file name")
|
||||||
|
|
||||||
|
target_user = "free"
|
||||||
try:
|
try:
|
||||||
env = dict(os.environ)
|
pw = pwd.getpwnam(target_user)
|
||||||
env["DISPLAY"] = ":0"
|
uid = pw.pw_uid
|
||||||
|
except KeyError:
|
||||||
|
raise HTTPException(status_code=500, detail=f"User '{target_user}' not found")
|
||||||
|
|
||||||
|
runtime_dir = f"/run/user/{uid}"
|
||||||
|
|
||||||
|
try:
|
||||||
|
# Preferred: machinectl shell enters the user's actual login session scope,
|
||||||
|
# inheriting the full graphical environment automatically.
|
||||||
result = subprocess.run(
|
result = subprocess.run(
|
||||||
["gtk-launch", desktop_file],
|
[
|
||||||
capture_output=True, text=True, timeout=10, env=env,
|
"machinectl", "shell", f"--uid={uid}",
|
||||||
|
".host", "/usr/bin/env",
|
||||||
|
f"XDG_RUNTIME_DIR={runtime_dir}",
|
||||||
|
"WAYLAND_DISPLAY=wayland-0",
|
||||||
|
f"DBUS_SESSION_BUS_ADDRESS=unix:path={runtime_dir}/bus",
|
||||||
|
"DISPLAY=:0",
|
||||||
|
"gtk-launch", desktop_file,
|
||||||
|
],
|
||||||
|
capture_output=True, text=True, timeout=10,
|
||||||
)
|
)
|
||||||
if result.returncode != 0:
|
if result.returncode != 0:
|
||||||
raise HTTPException(status_code=500, detail=f"Failed to launch: {result.stderr.strip()}")
|
# Fallback: su -l with explicit Wayland env vars
|
||||||
|
env_prefix = (
|
||||||
|
f"XDG_RUNTIME_DIR={runtime_dir} "
|
||||||
|
f"WAYLAND_DISPLAY=wayland-0 "
|
||||||
|
f"DBUS_SESSION_BUS_ADDRESS=unix:path={runtime_dir}/bus "
|
||||||
|
f"DISPLAY=:0 "
|
||||||
|
)
|
||||||
|
result = subprocess.run(
|
||||||
|
[
|
||||||
|
"su", "-l", target_user, "-c",
|
||||||
|
f"{env_prefix}gtk-launch {desktop_file}",
|
||||||
|
],
|
||||||
|
capture_output=True, text=True, timeout=10,
|
||||||
|
)
|
||||||
|
if result.returncode != 0:
|
||||||
|
raise HTTPException(
|
||||||
|
status_code=500,
|
||||||
|
detail=f"Failed to launch: {result.stderr.strip()}",
|
||||||
|
)
|
||||||
except FileNotFoundError:
|
except FileNotFoundError:
|
||||||
raise HTTPException(status_code=500, detail="gtk-launch not found on this system")
|
raise HTTPException(status_code=500, detail="Required launcher (machinectl or gtk-launch) not found on this system")
|
||||||
except subprocess.TimeoutExpired:
|
except subprocess.TimeoutExpired:
|
||||||
raise HTTPException(status_code=500, detail="Launch command timed out")
|
raise HTTPException(status_code=500, detail="Launch command timed out")
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user