Make private desktop tools opt-in and preserve host defaults
This commit is contained in:
1 parent
0ae1fccfba
commit
e84362b999
15 files changed
+219
-45
No files matched your search
@@ -1 +1 @@
|
||||
__version__ = "0.3.2~compat.20261027.1"
|
||||
__version__ = "0.3.2~compat.20261027.2"
|
||||
@@ -441,6 +441,12 @@ def _doctor_command(args, state):
|
||||
print("Missing command: " + str(item))
|
||||
for item in value.get("issues", []):
|
||||
print("Issue: " + str(item))
|
||||
virtual_missing = value.get("optional_missing_commands", {}).get("private_desktop", [])
|
||||
if virtual_missing:
|
||||
print("Optional private desktop tools missing: " + ", ".join(virtual_missing))
|
||||
hint = value.get("optional_install_commands", {}).get("private_desktop")
|
||||
if hint:
|
||||
print("Install only for an explicit virtual desktop: " + hint)
|
||||
print("This checks prerequisites; use fb status to inspect the current connection.")
|
||||
return _result_code(value)
|
||||
|
||||
|
||||
@@ -7,6 +7,11 @@ from .real_screen.screen_capture import CaptureError, foreground, _x11_context
|
||||
BINDING = "FRAMEBRIDGE_DISPLAY_BINDING"
|
||||
GRAPHICAL_COMMANDS = ("wmctrl", "xdotool", "xwininfo", "xclip")
|
||||
VIRTUAL_COMMANDS = ("Xvfb", "openbox", "xauth")
|
||||
VIRTUAL_INSTALL_COMMAND = "sudo apt install xvfb openbox xauth"
|
||||
|
||||
|
||||
def missing_virtual_commands(env):
|
||||
return [name for name in VIRTUAL_COMMANDS if not shutil.which(name, path=env.get("PATH"))]
|
||||
|
||||
|
||||
def missing_graphical_commands(env):
|
||||
|
||||
@@ -302,7 +302,7 @@ GUIDE = {'start': {'title': 'Start with FrameBridge',
|
||||
'partial invented view as a real screenshot.',
|
||||
'commands': []},
|
||||
{'heading': 'Automatic graphical discovery',
|
||||
'body': 'The installer and control console stay text interfaces in both TTY and a desktop terminal. Compatible graphical CUA is discovered automatically; availability depends on the actual display/session and permissions. A loaded module is not proof that real pixel capture or input succeeded. New profiles use adaptive auto mode: without a verified active X11 session the runtime provides FBEXEC, FBTERM and CUA-TTY in text mode, without requiring a graphical login or automatically creating a private desktop. Explicit virtual-desktop settings remain advanced options and are labelled separately from physical-screen evidence. Physical-screen capture and input currently require the supported active X11 session. Native Wayland control is not validated; showing an XWayland window does not establish full-desktop capture or input.',
|
||||
'body': 'The installer and control console stay text interfaces in both TTY and a desktop terminal. Compatible graphical CUA is discovered automatically; availability depends on the actual display/session and permissions. A loaded module is not proof that real pixel capture or input succeeded. New profiles use adaptive auto mode: without a verified active X11 session the runtime provides FBEXEC, FBTERM and CUA-TTY in text mode, without requiring a graphical login or automatically creating a private desktop. Explicit virtual-desktop settings remain advanced options and are labelled separately from physical-screen evidence. Xvfb and Openbox are optional package suggestions and are not installed for the normal connection. Only when you choose a private virtual desktop, install its tools explicitly with sudo apt install xvfb openbox xauth and rerun fb doctor. Installing Openbox can register it as the generic window-manager alternative; use your distribution settings to retain your preferred manager when needed. Physical-screen capture and input currently require the supported active X11 session. Native Wayland control is not validated; showing an XWayland window does not establish full-desktop capture or input.',
|
||||
'commands': ['fb status', 'fb doctor']},
|
||||
{'heading': 'Frame-buffer read access',
|
||||
'body': 'screen-access is a narrow, explicit administrative permission '
|
||||
|
||||
@@ -151,9 +151,9 @@ def doctor(state):
|
||||
commands = ["bash", "tmux", "tee", "flock", "awk", "sha256sum", "timeout",
|
||||
"dbus-run-session", "ip", "lsblk", "systemctl", "systemd-run", "sudo", "uptime"]
|
||||
missing = [x for x in commands if not shutil.which(x, path=env.get("PATH"))]
|
||||
from .display_context import missing_graphical_commands, VIRTUAL_COMMANDS
|
||||
from .display_context import missing_graphical_commands, missing_virtual_commands, VIRTUAL_INSTALL_COMMAND
|
||||
graphical_missing = missing_graphical_commands(env)
|
||||
virtual_missing = [x for x in VIRTUAL_COMMANDS if not shutil.which(x, path=env.get("PATH"))]
|
||||
virtual_missing = missing_virtual_commands(env)
|
||||
console_missing = [x for x in ("gnome-terminal", "xterm") if not shutil.which(x, path=env.get("PATH"))]
|
||||
if config.get("headless") in ("no", False):
|
||||
missing.extend(graphical_missing)
|
||||
@@ -182,8 +182,10 @@ def doctor(state):
|
||||
"display_context": display_context,
|
||||
"capabilities": {"fbexec": not missing, "fbterm": not missing, "cua_tty_module": True,
|
||||
"graphical_cua": display_context.get("kind") in ("physical-x11", "virtual-x11") and not graphical_missing,
|
||||
"private_desktop": compatible and not missing and not graphical_missing and not virtual_missing,
|
||||
"mode": "graphical" if display_context.get("kind") in ("physical-x11", "virtual-x11") else "text"},
|
||||
"optional_missing_commands": {"graphical_cua": graphical_missing, "private_desktop": virtual_missing, "graphical_terminal": console_missing},
|
||||
"optional_install_commands": {"private_desktop": VIRTUAL_INSTALL_COMMAND if virtual_missing else None},
|
||||
"network": inspect_network(),
|
||||
"role": config["role"], "issues": issues}
|
||||
|
||||
@@ -372,6 +374,10 @@ def _manager(state):
|
||||
from .display_context import bind_text
|
||||
bind_text(env, state, reason="PHYSICAL_X11_UNAVAILABLE_TEXT_TOOLS_ACTIVE")
|
||||
if private_display:
|
||||
from .display_context import missing_virtual_commands, VIRTUAL_INSTALL_COMMAND
|
||||
missing_virtual = missing_virtual_commands(env)
|
||||
if missing_virtual:
|
||||
raise RuntimeError("Private virtual desktop tools are missing: " + ", ".join(missing_virtual) + ". Install them explicitly: " + VIRTUAL_INSTALL_COMMAND)
|
||||
display = next((n for n in range(140, 240) if not Path("/tmp/.X11-unix/X" + str(n)).exists() and not Path("/tmp/.X" + str(n) + "-lock").exists()), None)
|
||||
if display is None:
|
||||
raise RuntimeError("No private X11 display number is available.")
|
||||
@@ -424,7 +430,11 @@ def start(state):
|
||||
return current
|
||||
checks = doctor(state)
|
||||
if not checks["ok"]:
|
||||
return {"ok": False, "error": "Preflight failed. Run framebridge doctor.", "doctor": checks}
|
||||
error = "Preflight failed. Run framebridge doctor."
|
||||
hint = checks.get("optional_install_commands", {}).get("private_desktop")
|
||||
if config.get("headless") in ("yes", True) and hint:
|
||||
error = "Private virtual desktop tools are missing. Install them explicitly: " + hint + ". Then run framebridge doctor."
|
||||
return {"ok": False, "error": error, "doctor": checks}
|
||||
for name in ("logs", "run"):
|
||||
private_dir(state / name)
|
||||
for name in ("ready.json", "last-error.json", "worker.json"):
|
||||
|
||||
Reference in new issue
Block a user