Repository navigation
epoptes-client: get-display falla al detectar la sesión activa cuando hay cambio de usuario o sesiones concurrentes (SDDM/Xorg) #2
Description
Descripción del problema
En aulas donde los alumnos utilizan la opción "Cambiar de usuario" (Fast User Switching) en lugar de cerrar sesión, o cuando queda una sesión gráfica previa en segundo plano (por ejemplo, alumnoA en tty2 / DISPLAY=:0 y el alumno actual alumnoB en tty1 / DISPLAY=:1), la difusión de pantalla no se muestra en el monitor del alumno que está utilizando el equipo.
El visor VNC (xtigervncviewer) sí se ejecuta en el cliente y establece la conexión TCP con el ordenador del profesor (transfiriendo datos con normalidad), pero se abre en la terminal virtual/pantalla oculta (:0), dejando al alumno actual sin ver la emisión en su escritorio (:1).
Causa raíz
El script /usr/share/epoptes-client/get-display intenta detectar el DISPLAY y XAUTHORITY de la sesión gráfica mediante una lista fija de procesos con pgrep:
for p in $(pgrep -x 'ldm|lightdm-greeter|dbus-daemon|dconf-service|pulseaudio' | sort -rn)En entornos modernos (Ubuntu 22.04 / LliureX 23 con KDE Plasma, PipeWire y SDDM):
- Procesos como
pulseaudioya no están presentes (sustituidos por PipeWire). - Si coexisten dos sesiones gráficas Xorg, el script acaba seleccionando el entorno de la sesión inactiva o antigua en lugar de la que está en primer plano en el monitor físico (
seat0).
Pasos para reproducir
- Iniciar sesión en un cliente con el Usuario A (se le asigna
DISPLAY=:0entty2). - Sin cerrar sesión, pulsar en "Cambiar de usuario" e iniciar sesión con el Usuario B (se le asigna
DISPLAY=:1entty1). - Desde el ordenador del profesor con Epoptes, iniciar la difusión de pantalla hacia los clientes.
- Resultado: En el cliente,
xtigervncviewerse abre en:0(la sesión en segundo plano del Usuario A). El Usuario B en:1no ve ninguna ventana de emisión.
Propuesta de solución
En sistemas con systemd-logind, la herramienta loginctl permite determinar de manera inmediata y 100% fiable cuál es la sesión activa en el asiento físico (seat0).
Se puede añadir al inicio de /usr/share/epoptes-client/get-display una comprobación prioritaria basada en loginctl:
# Prioridad: consultar a loginctl qué sesión está activa físicamente en seat0
if command -v loginctl >/dev/null 2>&1; then
active_session=$(loginctl show-seat seat0 -p ActiveSession --value 2>/dev/null)
if [ -n "$active_session" ] && [ "$active_session" != "" ]; then
DISPLAY=$(loginctl show-session "$active_session" -p Display --value 2>/dev/null)
leader=$(loginctl show-session "$active_session" -p Leader --value 2>/dev/null)
if [ -n "$leader" ] && [ -r "/proc/$leader/environ" ]; then
XAUTHORITY=$(tr '\0' '\n' < /proc/$leader/environ | sed -n 's/^XAUTHORITY=//p')
fi
exit_if_found
fi
fi(Comprobado en cliente en entorno real: al resolver la sesión activa de seat0, xtigervncviewer se engancha de forma instantánea al display :1 del alumno).
Bug secundario detectado en broadcast_screen (gui.py)
En /usr/lib/python3/dist-packages/epoptes/ui/gui.py, en el parche de LliureX dentro de la función broadcast_screen():
class_ip = "server"
if self.vncserver is None:
# ...
class_ip = self.getClassroomIp()Si la difusión ya está en marcha (self.vncserver is not None) y el profesor hace clic de nuevo para difundir a un cliente que se acaba de conectar o selecciona un nuevo grupo de puestos:
- El bloque
if self.vncserver is None:no se ejecuta. - Por tanto,
class_ipno se actualiza conself.getClassroomIp()y mantiene el valor inicial"server". - Esto provoca que a los clientes se les envíe la orden
receive_broadcast server:<port>en lugar de<IP_profesor>:<port>, fallando la conexión si el equipo del profesor no es el servidor central.
Activity