Skip to content

epoptes-client: get-display falla al detectar la sesión activa cuando hay cambio de usuario o sesiones concurrentes (SDDM/Xorg) #2

Open

Description

@Canx

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):

  1. Procesos como pulseaudio ya no están presentes (sustituidos por PipeWire).
  2. 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

  1. Iniciar sesión en un cliente con el Usuario A (se le asigna DISPLAY=:0 en tty2).
  2. Sin cerrar sesión, pulsar en "Cambiar de usuario" e iniciar sesión con el Usuario B (se le asigna DISPLAY=:1 en tty1).
  3. Desde el ordenador del profesor con Epoptes, iniciar la difusión de pantalla hacia los clientes.
  4. Resultado: En el cliente, xtigervncviewer se abre en :0 (la sesión en segundo plano del Usuario A). El Usuario B en :1 no 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_ip no se actualiza con self.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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions