This commit is contained in:
Sebastián Nieto 2026-11-05 11:46:38 -03:00
parent 63fbdb14db
commit 81799e5fb4
3 changed files with 3371 additions and 0 deletions

View file

@ -0,0 +1,829 @@
<!DOCTYPE html>
<html lang="es">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Guía Concisa de Componentes Gráficos y de Sistema - NASA Video (Debian 13)</title>
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Fira+Code:wght@400;500;600&family=Inter:wght@300;400;500;600;700&family=Outfit:wght@500;600;700;800&display=swap" rel="stylesheet">
<style>
:root {
--bg-main: #070b14;
--bg-secondary: #0f172a;
--bg-card: rgba(19, 28, 49, 0.88);
--bg-card-inner: rgba(11, 17, 32, 0.78);
--border-color: rgba(148, 163, 184, 0.15);
--border-highlight: rgba(56, 189, 248, 0.42);
--text-primary: #f8fafc;
--text-secondary: #cbd5e1;
--text-muted: #94a3b8;
--accent-cyan: #38bdf8;
--accent-blue: #3b82f6;
--accent-indigo: #818cf8;
--accent-emerald: #10b981;
--accent-amber: #f59e0b;
--accent-rose: #f43f5e;
--accent-purple: #a855f7;
--radius-lg: 16px;
--radius-md: 12px;
--radius-sm: 8px;
--shadow-card: 0 10px 30px -5px rgba(0, 0, 0, 0.5);
}
* {
box-sizing: border-box;
margin: 0;
padding: 0;
}
body {
font-family: 'Inter', -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
background-color: var(--bg-main);
color: var(--text-primary);
line-height: 1.6;
background-image:
radial-gradient(circle at 12% 12%, rgba(56, 189, 248, 0.08) 0%, transparent 35%),
radial-gradient(circle at 88% 22%, rgba(168, 85, 247, 0.07) 0%, transparent 35%),
radial-gradient(circle at 50% 88%, rgba(16, 185, 129, 0.07) 0%, transparent 40%);
background-attachment: fixed;
padding: 2rem 1.25rem 4rem;
}
.container {
max-width: 1300px;
margin: 0 auto;
}
/* Header */
header {
background: linear-gradient(135deg, rgba(15, 23, 42, 0.96), rgba(30, 41, 59, 0.88));
border: 1px solid var(--border-highlight);
border-radius: var(--radius-lg);
padding: 2.25rem;
margin-bottom: 2rem;
box-shadow: var(--shadow-card);
position: relative;
overflow: hidden;
}
header::before {
content: "";
position: absolute;
top: 0; left: 0; right: 0; height: 4px;
background: linear-gradient(90deg, var(--accent-purple), var(--accent-cyan), var(--accent-emerald));
}
.header-top {
display: flex;
justify-content: space-between;
align-items: flex-start;
flex-wrap: wrap;
gap: 1.5rem;
margin-bottom: 1.25rem;
}
.brand-group {
display: flex;
align-items: center;
gap: 1.2rem;
}
.brand-logo {
width: 60px;
height: 60px;
border-radius: 14px;
background: linear-gradient(135deg, #312e81, #0b3d91);
border: 2px solid var(--accent-cyan);
display: flex;
align-items: center;
justify-content: center;
font-family: 'Outfit', sans-serif;
font-weight: 800;
font-size: 1.25rem;
color: #fff;
box-shadow: 0 0 22px rgba(56, 189, 248, 0.28);
flex-shrink: 0;
}
.title-block h1 {
font-family: 'Outfit', sans-serif;
font-size: 2.05rem;
font-weight: 800;
color: #fff;
line-height: 1.2;
}
.title-block p {
color: var(--accent-cyan);
font-size: 1.02rem;
font-weight: 500;
margin-top: 0.3rem;
}
.doc-switcher {
display: inline-flex;
align-items: center;
gap: 0.5rem;
background: rgba(56, 189, 248, 0.14);
border: 1px solid rgba(56, 189, 248, 0.4);
color: #7dd3fc;
text-decoration: none;
padding: 0.55rem 1rem;
border-radius: var(--radius-sm);
font-size: 0.86rem;
font-weight: 600;
transition: all 0.2s ease;
}
.doc-switcher:hover {
background: var(--accent-cyan);
color: #06101f;
}
.quick-nav {
display: flex;
flex-wrap: wrap;
gap: 0.55rem;
margin-top: 1.25rem;
padding-top: 1.15rem;
border-top: 1px solid var(--border-color);
}
.quick-nav a {
text-decoration: none;
color: var(--text-secondary);
background: rgba(255, 255, 255, 0.04);
border: 1px solid var(--border-color);
padding: 0.4rem 0.85rem;
border-radius: var(--radius-sm);
font-size: 0.83rem;
font-weight: 500;
transition: all 0.2s ease;
}
.quick-nav a:hover {
color: #fff;
border-color: var(--accent-cyan);
background: rgba(56, 189, 248, 0.12);
}
/* Sections */
section {
margin-bottom: 2.5rem;
scroll-margin-top: 1.5rem;
}
.section-header {
display: flex;
align-items: center;
gap: 0.75rem;
margin-bottom: 1.15rem;
}
.section-num {
width: 36px;
height: 36px;
border-radius: 10px;
background: linear-gradient(135deg, var(--accent-cyan), var(--accent-blue));
color: #06101f;
font-family: 'Outfit', sans-serif;
font-weight: 800;
font-size: 1.1rem;
display: flex;
align-items: center;
justify-content: center;
flex-shrink: 0;
}
.section-title {
font-family: 'Outfit', sans-serif;
font-size: 1.55rem;
font-weight: 700;
color: #ffffff;
}
.card {
background: var(--bg-card);
border: 1px solid var(--border-color);
border-radius: var(--radius-lg);
padding: 1.65rem;
margin-bottom: 1.5rem;
box-shadow: var(--shadow-card);
}
/* Component Grid Cards */
.comp-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(380px, 1fr));
gap: 1.35rem;
}
@media (max-width: 820px) {
.comp-grid {
grid-template-columns: 1fr;
}
}
.comp-card {
background: var(--bg-card);
border: 1px solid var(--border-color);
border-radius: var(--radius-lg);
padding: 1.5rem;
box-shadow: var(--shadow-card);
display: flex;
flex-direction: column;
gap: 0.9rem;
position: relative;
overflow: hidden;
transition: transform 0.2s ease, border-color 0.2s ease;
}
.comp-card:hover {
transform: translateY(-2px);
border-color: var(--border-highlight);
}
.comp-card::before {
content: "";
position: absolute;
top: 0; left: 0; bottom: 0; width: 4px;
background: var(--accent-cyan);
}
.comp-card.layer-display::before { background: var(--accent-purple); }
.comp-card.layer-login::before { background: var(--accent-amber); }
.comp-card.layer-admin::before { background: var(--accent-cyan); }
.comp-card.layer-kiosk::before { background: var(--accent-emerald); }
.comp-card.layer-security::before { background: var(--accent-rose); }
.comp-top {
display: flex;
justify-content: space-between;
align-items: flex-start;
gap: 0.75rem;
border-bottom: 1px solid var(--border-color);
padding-bottom: 0.75rem;
}
.comp-name {
font-family: 'Outfit', sans-serif;
font-size: 1.3rem;
font-weight: 800;
color: #fff;
}
.comp-role {
font-size: 0.8rem;
color: var(--text-muted);
margin-top: 0.15rem;
font-weight: 500;
}
.badge {
display: inline-flex;
align-items: center;
padding: 0.28rem 0.7rem;
border-radius: 999px;
font-size: 0.74rem;
font-weight: 700;
text-transform: uppercase;
letter-spacing: 0.04em;
flex-shrink: 0;
}
.badge-purple { background: rgba(168, 85, 247, 0.16); color: #d8b4fe; border: 1px solid rgba(168, 85, 247, 0.38); }
.badge-amber { background: rgba(245, 158, 11, 0.16); color: #fcd34d; border: 1px solid rgba(245, 158, 11, 0.38); }
.badge-cyan { background: rgba(56, 189, 248, 0.16); color: #7dd3fc; border: 1px solid rgba(56, 189, 248, 0.38); }
.badge-emerald { background: rgba(16, 185, 129, 0.16); color: #6ee7b7; border: 1px solid rgba(16, 185, 129, 0.38); }
.badge-rose { background: rgba(244, 63, 94, 0.16); color: #fda4af; border: 1px solid rgba(244, 63, 94, 0.38); }
.qa-block {
background: var(--bg-card-inner);
border: 1px solid rgba(255, 255, 255, 0.06);
border-radius: var(--radius-sm);
padding: 0.85rem 1rem;
}
.qa-title {
font-size: 0.76rem;
text-transform: uppercase;
letter-spacing: 0.05em;
font-weight: 700;
margin-bottom: 0.3rem;
display: block;
}
.qa-what { color: var(--accent-cyan); }
.qa-why { color: var(--accent-emerald); }
.qa-without { color: var(--accent-amber); }
.qa-block p {
font-size: 0.89rem;
color: var(--text-secondary);
margin: 0;
}
.comp-files {
font-size: 0.8rem;
color: var(--text-muted);
padding-top: 0.3rem;
}
code {
font-family: 'Fira Code', monospace;
background: rgba(2, 6, 23, 0.85);
color: #7dd3fc;
padding: 0.15rem 0.4rem;
border-radius: 5px;
font-size: 0.84em;
border: 1px solid rgba(56, 189, 248, 0.18);
}
/* SVG Diagram */
.diagram-box {
background: #080d1a;
border: 1px solid rgba(56, 189, 248, 0.28);
border-radius: var(--radius-lg);
padding: 1.5rem;
margin: 1rem 0 0.5rem;
overflow-x: auto;
box-shadow: inset 0 0 40px rgba(0, 0, 0, 0.6);
}
.diagram-caption {
text-align: center;
font-size: 0.84rem;
color: var(--text-muted);
margin-top: 0.75rem;
font-style: italic;
}
svg.blueprint {
width: 100%;
height: auto;
min-width: 860px;
display: block;
margin: 0 auto;
}
/* Table */
.table-wrap {
overflow-x: auto;
border-radius: var(--radius-md);
border: 1px solid var(--border-color);
}
table {
width: 100%;
border-collapse: collapse;
background: rgba(10, 15, 28, 0.75);
font-size: 0.9rem;
}
th, td {
padding: 0.85rem 1.1rem;
text-align: left;
border-bottom: 1px solid var(--border-color);
vertical-align: top;
}
th {
background: rgba(30, 41, 59, 0.88);
color: var(--accent-cyan);
font-family: 'Outfit', sans-serif;
font-weight: 700;
font-size: 0.84rem;
text-transform: uppercase;
letter-spacing: 0.04em;
}
tr:last-child td { border-bottom: none; }
tr:hover td { background: rgba(255, 255, 255, 0.02); }
footer {
text-align: center;
margin-top: 3.5rem;
padding-top: 1.5rem;
border-top: 1px solid var(--border-color);
color: var(--text-muted);
font-size: 0.85rem;
}
</style>
</head>
<body>
<div class="container">
<!-- ENCABEZADO -->
<header>
<div class="header-top">
<div class="brand-group">
<div class="brand-logo">COMP</div>
<div class="title-block">
<h1>Componentes Clave del Sistema Gráfico: ¿Qué son y Por Qué los Usamos?</h1>
<p>Explicación clara y concisa de Xorg, LightDM, Slick Greeter, XFCE 4, Openbox, Polkit e Inotify en Debian 13</p>
</div>
</div>
<a class="doc-switcher" href="index.html">
&lt;- Volver a Arquitectura General (index.html)
</a>
</div>
<p style="color: var(--text-secondary); font-size: 0.95rem; max-width: 1080px;">
En Linux el sistema gráfico es modular: en lugar de ser un único bloque cerrado, se divide en <strong>Servidor Gráfico (Xorg)</strong>, <strong>Gestor de Inicio de Sesión (LightDM + Slick Greeter)</strong> y <strong>Entorno de Escritorio / Gestor de Ventanas (XFCE 4 vs Openbox)</strong>. Esa modularidad es exactamente la que aprovechamos en <strong>NA-SA Video Capture</strong> para darle al administrador un escritorio completo y al operario un modo kiosco blindado y ultrarrápido sobre la misma PC.
</p>
<nav class="quick-nav">
<a href="#mapa-visual">1. Mapa Visual de Piezas</a>
<a href="#fichas-componentes">2. Los 10 Componentes Explicados (Qué es y Por qué se usa)</a>
<a href="#decisiones-arquitectura">3. ¿Por qué elegimos cada uno frente a otras alternativas?</a>
</nav>
</header>
<!-- SECCIÓN 1: MAPA VISUAL DE PIEZAS -->
<section id="mapa-visual">
<div class="section-header">
<div class="section-num">1</div>
<h2 class="section-title">Cómo Encajan las Piezas en Orden de Arranque</h2>
</div>
<div class="card">
<p style="color: var(--text-secondary); margin-bottom: 1rem;">
Desde que el equipo enciende hasta que se muestra la imagen de las cámaras en pantalla, cada componente cumple una única responsabilidad bien delimitada y le pasa el control al siguiente:
</p>
<div class="diagram-box">
<svg class="blueprint" viewBox="0 0 1100 370" fill="none" xmlns="http://www.w3.org/2000/svg">
<defs>
<pattern id="grid2" width="30" height="30" patternUnits="userSpaceOnUse">
<path d="M 30 0 L 0 0 0 30" fill="none" stroke="#1e293b" stroke-width="0.7" stroke-opacity="0.55"/>
</pattern>
<marker id="arr-c" viewBox="0 0 10 10" refX="7" refY="5" markerWidth="6" markerHeight="6" orient="auto-start-reverse">
<path d="M 0 1 L 10 5 L 0 9 z" fill="#38bdf8"/>
</marker>
<marker id="arr-e" viewBox="0 0 10 10" refX="7" refY="5" markerWidth="6" markerHeight="6" orient="auto-start-reverse">
<path d="M 0 1 L 10 5 L 0 9 z" fill="#10b981"/>
</marker>
</defs>
<rect width="1100" height="370" rx="12" fill="url(#grid2)"/>
<!-- Bloque 1: XORG -->
<rect x="25" y="115" width="190" height="140" rx="10" fill="#18142c" stroke="#a855f7" stroke-width="2"/>
<text x="120" y="145" text-anchor="middle" fill="#d8b4fe" font-family="Outfit, sans-serif" font-size="15" font-weight="800">1. Xorg (X11)</text>
<text x="120" y="166" text-anchor="middle" fill="#f8fafc" font-family="Inter, sans-serif" font-size="11.5" font-weight="600">Servidor Gráfico</text>
<text x="120" y="190" text-anchor="middle" fill="#cbd5e1" font-family="Inter, sans-serif" font-size="11">Habla con la GPU NVIDIA,</text>
<text x="120" y="206" text-anchor="middle" fill="#cbd5e1" font-family="Inter, sans-serif" font-size="11">el monitor, teclado y mouse.</text>
<text x="120" y="232" text-anchor="middle" fill="#fcd34d" font-family="Fira Code, monospace" font-size="10">Sin DPMS / Sin Blanking</text>
<line x1="215" y1="185" x2="255" y2="185" stroke="#38bdf8" stroke-width="2" marker-end="url(#arr-c)"/>
<!-- Bloque 2: LIGHTDM + SLICK GREETER -->
<rect x="258" y="90" width="235" height="190" rx="10" fill="#1f1a14" stroke="#f59e0b" stroke-width="2"/>
<text x="375" y="120" text-anchor="middle" fill="#fcd34d" font-family="Outfit, sans-serif" font-size="15" font-weight="800">2. LightDM</text>
<text x="375" y="139" text-anchor="middle" fill="#f8fafc" font-family="Inter, sans-serif" font-size="11.5" font-weight="600">Gestor de Inicio de Sesión</text>
<rect x="275" y="152" width="200" height="65" rx="7" fill="#292116" stroke="#fbbf24" stroke-width="1.2"/>
<text x="375" y="173" text-anchor="middle" fill="#fde68a" font-family="Outfit, sans-serif" font-size="13" font-weight="700">+ Slick Greeter</text>
<text x="375" y="191" text-anchor="middle" fill="#cbd5e1" font-family="Inter, sans-serif" font-size="10.5">Pantalla visual de Login</text>
<text x="375" y="206" text-anchor="middle" fill="#7dd3fc" font-family="Fira Code, monospace" font-size="9.5">LD_PRELOAD filtro español</text>
<text x="375" y="240" text-anchor="middle" fill="#cbd5e1" font-family="Inter, sans-serif" font-size="11">Valida clave y consulta</text>
<text x="375" y="258" text-anchor="middle" fill="#6ee7b7" font-family="Fira Code, monospace" font-size="10.5">AccountsService / .dmrc</text>
<!-- Flechas de bifurcación -->
<path d="M 493 150 L 535 150 L 535 95 L 575 95" stroke="#38bdf8" stroke-width="2.2" fill="none" marker-end="url(#arr-c)"/>
<path d="M 493 220 L 535 220 L 535 275 L 575 275" stroke="#10b981" stroke-width="2.2" fill="none" marker-end="url(#arr-e)"/>
<!-- Rama Superior: XFCE 4 (admin) -->
<rect x="578" y="30" width="245" height="130" rx="10" fill="#0f1b2d" stroke="#38bdf8" stroke-width="2"/>
<text x="700" y="57" text-anchor="middle" fill="#7dd3fc" font-family="Outfit, sans-serif" font-size="14.5" font-weight="800">3A. XFCE 4 (Si entra admin)</text>
<text x="700" y="77" text-anchor="middle" fill="#f8fafc" font-family="Inter, sans-serif" font-size="11.5" font-weight="600">Escritorio Completo</text>
<text x="700" y="98" text-anchor="middle" fill="#cbd5e1" font-family="Inter, sans-serif" font-size="11">• Gestor de ventanas xfwm4</text>
<text x="700" y="116" text-anchor="middle" fill="#cbd5e1" font-family="Inter, sans-serif" font-size="11">• Panel superior, menús y Terminal</text>
<text x="700" y="134" text-anchor="middle" fill="#cbd5e1" font-family="Inter, sans-serif" font-size="11">• Explorador Thunar (control total)</text>
<!-- Rama Inferior: OPENBOX (nasa) -->
<rect x="578" y="210" width="245" height="130" rx="10" fill="#0b211d" stroke="#10b981" stroke-width="2"/>
<text x="700" y="237" text-anchor="middle" fill="#6ee7b7" font-family="Outfit, sans-serif" font-size="14.5" font-weight="800">3B. Openbox (Si entra nasa)</text>
<text x="700" y="257" text-anchor="middle" fill="#f8fafc" font-family="Inter, sans-serif" font-size="11.5" font-weight="600">Gestor de Ventanas Kiosco</text>
<text x="700" y="278" text-anchor="middle" fill="#cbd5e1" font-family="Inter, sans-serif" font-size="11">• Sin escritorio, sin barras ni íconos</text>
<text x="700" y="296" text-anchor="middle" fill="#cbd5e1" font-family="Inter, sans-serif" font-size="11">• Fuerza fullscreen sin bordes</text>
<text x="700" y="314" text-anchor="middle" fill="#cbd5e1" font-family="Inter, sans-serif" font-size="11">• Lanza Watchdog nasa-video-kiosk</text>
<!-- Flechas hacia NASA Video y Servicios -->
<line x1="823" y1="95" x2="865" y2="95" stroke="#38bdf8" stroke-width="2" marker-end="url(#arr-c)"/>
<line x1="823" y1="275" x2="865" y2="275" stroke="#10b981" stroke-width="2" marker-end="url(#arr-e)"/>
<!-- Bloque 4A: Herramientas Admin -->
<rect x="868" y="30" width="205" height="130" rx="10" fill="#16243b" stroke="#38bdf8" stroke-width="1.5"/>
<text x="970" y="58" text-anchor="middle" fill="#ffffff" font-family="Outfit, sans-serif" font-size="13.5" font-weight="700">Mantenimiento / Dev</text>
<text x="970" y="82" text-anchor="middle" fill="#7dd3fc" font-family="Fira Code, monospace" font-size="11">CMake / deploy_kiosk.sh</text>
<text x="970" y="104" text-anchor="middle" fill="#cbd5e1" font-family="Inter, sans-serif" font-size="11">Gestión y limpieza de</text>
<text x="970" y="122" text-anchor="middle" fill="#6ee7b7" font-family="Fira Code, monospace" font-size="11">/datos/NA-SA_Video</text>
<!-- Bloque 4B: App Kiosco + Polkit + Inotify -->
<rect x="868" y="210" width="205" height="130" rx="10" fill="#112e28" stroke="#10b981" stroke-width="1.5"/>
<text x="970" y="238" text-anchor="middle" fill="#ffffff" font-family="Outfit, sans-serif" font-size="13.5" font-weight="700">App nasa_video (Qt6)</text>
<text x="970" y="260" text-anchor="middle" fill="#6ee7b7" font-family="Fira Code, monospace" font-size="10.5">+ Panel Salida (GTK3/F1)</text>
<text x="970" y="280" text-anchor="middle" fill="#fcd34d" font-family="Fira Code, monospace" font-size="10.5">+ Polkit (Apagar sin root)</text>
<text x="970" y="300" text-anchor="middle" fill="#d8b4fe" font-family="Fira Code, monospace" font-size="10.5">+ Guardián Inotify (/datos)</text>
</svg>
<div class="diagram-caption">
Cadena de responsabilidad: Xorg provee el lienzo gráfico -> LightDM + Slick Greeter autentican al usuario -> AccountsService elige entre XFCE 4 (admin) u Openbox (nasa).
</div>
</div>
</div>
</section>
<!-- SECCIÓN 2: FICHAS CONCISAS DE CADA COMPONENTE -->
<section id="fichas-componentes">
<div class="section-header">
<div class="section-num">2</div>
<h2 class="section-title">Los 10 Componentes Principales: ¿Qué es cada uno y Por qué está ahí?</h2>
</div>
<div class="comp-grid">
<!-- 1. Xorg -->
<div class="comp-card layer-display">
<div class="comp-top">
<div>
<div class="comp-name">1. Xorg (Servidor X11)</div>
<div class="comp-role">Base Gráfica y Comunicación con Hardware</div>
</div>
<span class="badge badge-purple">Servidor Display</span>
</div>
<div class="qa-block">
<span class="qa-title qa-what">¿Qué es?</span>
<p>Es el motor gráfico base de Linux que controla directamente la placa de video NVIDIA, dibuja píxeles en el monitor y captura los eventos físicos del teclado y mouse.</p>
</div>
<div class="qa-block">
<span class="qa-title qa-why">¿Por qué lo usamos?</span>
<p>Porque tiene soporte 100% maduro para el driver propietario de <strong>NVIDIA (CUDA Zero-Copy + NVDEC)</strong>, para el SDK de la capturadora <strong>Magewell</strong> y permite controlar por código qué ventana va al frente (<code>XRaiseWindow</code>) y desactivar a nivel global el apagado de pantalla (<code>DPMS false</code>).</p>
</div>
<div class="comp-files">
<strong>Configuración:</strong> <code>/etc/X11/xorg.conf.d/10-nasa-no-blanking.conf</code>
</div>
</div>
<!-- 2. LightDM -->
<div class="comp-card layer-login">
<div class="comp-top">
<div>
<div class="comp-name">2. LightDM</div>
<div class="comp-role">Display Manager (Gestor de Inicio de Sesión)</div>
</div>
<span class="badge badge-amber">Gestor Login</span>
</div>
<div class="qa-block">
<span class="qa-title qa-what">¿Qué es?</span>
<p>Es el servicio de sistema que arranca Xorg al encender la PC, muestra la pantalla de login, valida la contraseña del usuario y lanza su sesión gráfica correspondiente.</p>
</div>
<div class="qa-block">
<span class="qa-title qa-why">¿Por qué lo usamos?</span>
<p>Porque es rápido, liviano y nos permite hacer tres cosas clave: <strong>1)</strong> mantener una única sesión gráfica activa (<code>allow-user-switching=false</code>) para no bloquear la capturadora ni la GPU, <strong>2)</strong> preseleccionar siempre al usuario <code>nasa</code> al iniciar, y <strong>3)</strong> abrir entornos distintos según entre <code>admin</code> o <code>nasa</code>.</p>
</div>
<div class="comp-files">
<strong>Configuración:</strong> <code>/etc/lightdm/lightdm.conf.d/60-slick-greeter.conf</code> y <code>70-nasa-single-session.conf</code>
</div>
</div>
<!-- 3. Slick Greeter -->
<div class="comp-card layer-login">
<div class="comp-top">
<div>
<div class="comp-name">3. Slick Greeter (+ Filtro C)</div>
<div class="comp-role">Interfaz Visual de la Pantalla de Bienvenida</div>
</div>
<span class="badge badge-amber">UI de Login</span>
</div>
<div class="qa-block">
<span class="qa-title qa-what">¿Qué es?</span>
<p>LightDM no tiene interfaz visual propia; delega el dibujo de la pantalla de login en un programa llamado <em>Greeter</em>. <strong>Slick Greeter</strong> es la interfaz gráfica GTK3 donde se ven el fondo institucional, los usuarios y la caja de contraseña.</p>
</div>
<div class="qa-block">
<span class="qa-title qa-why">¿Por qué lo usamos?</span>
<p>Porque luce limpio y profesional con el fondo de NASA Video y el logo de VENG en el avatar de <code>nasa</code>. Además, le inyectamos nuestro filtro en C (<code>slick-greeter-filter-a11y.so</code> vía <code>LD_PRELOAD</code>) para forzarlo al español y ocultar del menú superior el <em>Contraste alto</em> y el <em>Lector de pantalla</em>.</p>
</div>
<div class="comp-files">
<strong>Configuración:</strong> <code>/etc/lightdm/slick-greeter.conf</code> y <code>/usr/local/lib/slick-greeter-filter-a11y.so</code>
</div>
</div>
<!-- 4. AccountsService + .dmrc -->
<div class="comp-card layer-login">
<div class="comp-top">
<div>
<div class="comp-name">4. AccountsService y <code>.dmrc</code></div>
<div class="comp-role">Memoria Persistente de Sesión por Usuario</div>
</div>
<span class="badge badge-amber">Enrutamiento</span>
</div>
<div class="qa-block">
<span class="qa-title qa-what">¿Qué son?</span>
<p>Son el demonio D-Bus del sistema (<code>/var/lib/AccountsService/users/</code>) y el archivo de perfil (<code>~/.dmrc</code>) que guardan qué sesión gráfica tiene asignada cada usuario y cuál es su ícono de avatar (<code>.face</code>).</p>
</div>
<div class="qa-block">
<span class="qa-title qa-why">¿Por qué los usamos?</span>
<p>Para que el cambio entre modo administrador y modo kiosco sea <strong>100% automático</strong>: al escribir la clave de <code>nasa</code> siempre entra directo al kiosco (<code>nasa-video-kiosk</code>), y al escribir la clave de <code>admin</code> siempre entra directo a <code>xfce</code>, sin tocar ningún selector de sesión.</p>
</div>
<div class="comp-files">
<strong>Configuración:</strong> <code>/var/lib/AccountsService/users/{admin,nasa}</code> y <code>~{admin,nasa}/.dmrc</code>
</div>
</div>
<!-- 5. XFCE 4 -->
<div class="comp-card layer-admin">
<div class="comp-top">
<div>
<div class="comp-name">5. XFCE 4 (+ xfwm4 y Thunar)</div>
<div class="comp-role">Entorno de Escritorio Completo para <code>admin</code></div>
</div>
<span class="badge badge-cyan">Sesión Admin</span>
</div>
<div class="qa-block">
<span class="qa-title qa-what">¿Qué es?</span>
<p>Es el entorno de escritorio completo de Debian que incluye barra de tareas, menú de aplicaciones, gestor de ventanas (<code>xfwm4</code>), gestor de energía y el explorador de archivos <strong>Thunar</strong>.</p>
</div>
<div class="qa-block">
<span class="qa-title qa-why">¿Por qué lo usamos para <code>admin</code>?</span>
<p>Porque las tareas de mantenimiento, compilación C++ y gestión de archivos en <code>/datos</code> requieren un escritorio completo, ágil y cómodo, sin la sobrecarga pesada de GNOME o KDE. Además, <code>xfwm4</code> permite fijar <code>vblank_mode=xpresent</code> para una compatibilidad perfecta con NVIDIA.</p>
</div>
<div class="comp-files">
<strong>Configuración:</strong> <code>/usr/share/xsessions/xfce.desktop</code> y <code>xfce4-power-manager.xml</code>
</div>
</div>
<!-- 6. Openbox -->
<div class="comp-card layer-kiosk">
<div class="comp-top">
<div>
<div class="comp-name">6. Openbox</div>
<div class="comp-role">Gestor de Ventanas (Window Manager) para <code>nasa</code></div>
</div>
<span class="badge badge-emerald">Sesión Kiosco</span>
</div>
<div class="qa-block">
<span class="qa-title qa-what">¿Qué es?</span>
<p>Es únicamente un <strong>gestor de ventanas</strong> (no tiene barra de tareas, ni íconos de escritorio, ni explorador de archivos). Solo se encarga de posicionar ventanas, darles foco y aplicar reglas definidas en un archivo XML.</p>
</div>
<div class="qa-block">
<span class="qa-title qa-why">¿Por qué lo usamos para <code>nasa</code>?</span>
<p>Es la pieza central del Kiosco: si no hubiera gestor de ventanas, los diálogos secundarios de la app (<em>Panel Virtual PTZ</em>, <em>Reproductor</em>, <em>Guardar imagen</em>) no tendrían barra para moverse ni foco adecuado. Si usáramos XFCE, el operario podría salirse al sistema. Con <strong>Openbox</strong> bloqueamos todo y dejamos solo la app en pantalla completa y sus diálogos hijos arriba (<code>&lt;layer&gt;above&lt;/layer&gt;</code>).</p>
</div>
<div class="comp-files">
<strong>Configuración:</strong> <code>/etc/xdg/nasa-video-kiosk/rc.xml</code> y <code>menu.xml</code>
</div>
</div>
<!-- 7. Watchdog nasa-video-kiosk-session -->
<div class="comp-card layer-kiosk">
<div class="comp-top">
<div>
<div class="comp-name">7. Lanzador Watchdog</div>
<div class="comp-role">Script de Arranque y Auto-Recuperación del Kiosco</div>
</div>
<span class="badge badge-emerald">Alta Disponibilidad</span>
</div>
<div class="qa-block">
<span class="qa-title qa-what">¿Qué es?</span>
<p>Es el script (<code>/usr/local/bin/nasa-video-kiosk-session</code>) que Openbox ejecuta automáticamente apenas inicia la sesión del usuario <code>nasa</code>.</p>
</div>
<div class="qa-block">
<span class="qa-title qa-why">¿Por qué lo usamos?</span>
<p>Prepara las variables de entorno (<code>NASA_KIOSK_MODE=1</code>), apaga el protector de pantalla de X11 y mantiene a <code>nasa_video</code> dentro de un bucle vigilado: si la aplicación llegara a cerrarse por cualquier fallo inesperado, la vuelve a abrir automáticamente en <strong>1 segundo</strong>.</p>
</div>
<div class="comp-files">
<strong>Archivo:</strong> <code>/usr/local/bin/nasa-video-kiosk-session</code> y log en <code>~nasa/.local/state/nasa-video/kiosk.log</code>
</div>
</div>
<!-- 8. Panel de Salida GTK3 + libxfce4ui -->
<div class="comp-card layer-kiosk">
<div class="comp-top">
<div>
<div class="comp-name">8. Panel de Sesión Kiosco</div>
<div class="comp-role">Menú y Diálogos de Apagado / Reinicio / Logout</div>
</div>
<span class="badge badge-emerald">Control de Salida</span>
</div>
<div class="qa-block">
<span class="qa-title qa-what">¿Qué es?</span>
<p>Un programa ligero en Python 3 + GTK3 + <code>libxfce4ui-2</code> (<code>/usr/local/bin/nasa-video-kiosk-panel</code>), complementado con las acciones del menú <code>Sistema</code> (tecla <code>F1</code>) dentro de la propia aplicación Qt6.</p>
</div>
<div class="qa-block">
<span class="qa-title qa-why">¿Por qué lo usamos?</span>
<p>Como en Openbox no existe el botón de apagado del escritorio, este componente brinda al operario una forma limpia, segura y con confirmación visual (al pulsar <code>F1</code> o <code>Ctrl+Alt+Supr</code>) para <em>Cerrar sesión</em>, <em>Reiniciar</em> o <em>Apagar</em>, avisándole antes al Watchdog (<code>STOP_FLAG</code>) para que no relance la app.</p>
</div>
<div class="comp-files">
<strong>Archivos:</strong> <code>/usr/local/bin/nasa-video-kiosk-panel</code> y <code>MainWindow.cpp</code>
</div>
</div>
<!-- 9. Polkit + systemd-logind -->
<div class="comp-card layer-security">
<div class="comp-top">
<div>
<div class="comp-name">9. Polkit + systemd-logind</div>
<div class="comp-role">Autorización de Energía sin Contraseña de Root</div>
</div>
<span class="badge badge-rose">Permisos y Energía</span>
</div>
<div class="qa-block">
<span class="qa-title qa-what">¿Qué son?</span>
<p><strong>systemd-logind</strong> administra las sesiones de usuario y el apagado/reinicio del equipo, mientras que <strong>Polkit</strong> es el árbitro de seguridad que decide si un usuario sin privilegios tiene permiso para ejecutar una acción del sistema.</p>
</div>
<div class="qa-block">
<span class="qa-title qa-why">¿Por qué los usamos?</span>
<p>El usuario <code>nasa</code> no es administrador (no tiene <code>sudo</code> por seguridad). Gracias a una regla específica de Polkit, le damos permiso <strong>únicamente</strong> para apagar y reiniciar el equipo sin pedir contraseña, manteniendo bloqueado cualquier otro permiso administrativo.</p>
</div>
<div class="comp-files">
<strong>Configuración:</strong> <code>/etc/polkit-1/rules.d/60-nasa-kiosk-power.rules</code>
</div>
</div>
<!-- 10. Guardián Inotify (nasa-datos-guard) -->
<div class="comp-card layer-security">
<div class="comp-top">
<div>
<div class="comp-name">10. Guardián Inotify (<code>/datos</code>)</div>
<div class="comp-role">Protección Automática Contra Borrado de Videos</div>
</div>
<span class="badge badge-rose">Integridad de Datos</span>
</div>
<div class="qa-block">
<span class="qa-title qa-what">¿Qué es?</span>
<p>Un servicio de sistema (<code>nasa-datos-guard.service</code>) escrito en Python 3 que utiliza la interfaz <code>inotify</code> del kernel Linux para detectar en milisegundos cada vez que un archivo se termina de escribir en <code>/datos</code>.</p>
</div>
<div class="qa-block">
<span class="qa-title qa-why">¿Por qué lo usamos?</span>
<p>En Linux, si un usuario tiene permiso para crear un archivo en una carpeta, normalmente también puede borrarlo. Este guardián escucha el evento <code>IN_CLOSE_WRITE</code> y apenas <code>nasa</code> termina de grabar un video o guardar una medición, cambia su dueño a <code>admin:nasa (0644)</code> en carpetas con <em>sticky bit</em> (<code>3775</code>), impidiendo que <code>nasa</code> pueda borrarlo o modificarlo.</p>
</div>
<div class="comp-files">
<strong>Archivos:</strong> <code>/usr/local/bin/nasa-datos-guard</code> y <code>/etc/systemd/system/nasa-datos-guard.service</code>
</div>
</div>
</div>
</section>
<!-- SECCIÓN 3: TABLA DE DECISIONES DE ARQUITECTURA -->
<section id="decisiones-arquitectura">
<div class="section-header">
<div class="section-num">3</div>
<h2 class="section-title">Resumen de Decisiones: ¿Por qué esta combinación y no otra?</h2>
</div>
<div class="card">
<div class="table-wrap">
<table>
<thead>
<tr>
<th>Decisión en el Proyecto</th>
<th>Alternativa Descartada</th>
<th>Por qué nuestra elección es superior para NASA Video</th>
</tr>
</thead>
<tbody>
<tr>
<td><strong>Usar Xorg (X11)</strong></td>
<td>Wayland</td>
<td>En Wayland los clientes no pueden posicionar ni elevar ventanas modales globalmente (<code>XRaiseWindow</code>), y la interoperabilidad directa CUDA-OpenGL + Magewell + captura de teclado global es mucho más estable y predecible sobre Xorg.</td>
</tr>
<tr>
<td><strong>Usar Openbox en la sesión <code>nasa</code></strong></td>
<td>Usar XFCE recortado o lanzar la app sin Window Manager</td>
<td>Recortar XFCE deja huecos por donde abrir paneles o atajos; y lanzar sin Window Manager rompe las barras de título y el foco de las ventanas hijas (<em>Panel Virtual PTZ</em>, <em>Reproductor</em>, <em>Guardar archivo</em>). Openbox resuelve ambos problemas con un solo archivo XML.</td>
</tr>
<tr>
<td><strong>Mantener XFCE 4 en la sesión <code>admin</code></strong></td>
<td>Dejar solo consola (SSH/TTY) para el administrador</td>
<td>El administrador en planta puede necesitar revisar videos grabados en el propio monitor con <strong>Thunar</strong>, probar la interfaz en modo ventana o compilar localmente con todas las comodidades gráficas.</td>
</tr>
<tr>
<td><strong>Sesión Xorg Única (<code>allow-user-switching=false</code>)</strong></td>
<td>Permitir múltiples sesiones gráficas simultáneas (VT7, VT8)</td>
<td>Si quedan dos sesiones Xorg abiertas a la vez, la sesión en segundo plano puede retener el descriptor de la capturadora Magewell, el puerto serie RS-485 o contextos CUDA de NVIDIA. Forzar sesión única garantiza que quien inicia sesión tiene el 100% del hardware.</td>
</tr>
<tr>
<td><strong>Guardián <code>inotify</code> + Sticky Bit en <code>/datos</code></strong></td>
<td>Permisos estáticos estándar de carpetas Linux</td>
<td>Con permisos estándar, quien tiene permiso de escritura en una carpeta para crear un video nuevo también puede borrar los videos que él mismo creó. El cambio automático de propietario al cerrar el archivo (<code>IN_CLOSE_WRITE -> admin:nasa 0644</code>) logra un verdadero modo <em>"Grabar y Leer sí, Borrar nunca"</em> para el operario.</td>
</tr>
</tbody>
</table>
</div>
</div>
</section>
<footer>
<p>Guía Concisa de Componentes del Sistema Gráfico — Proyecto <strong>NA-SA Video Capture</strong> sobre Debian 13 (Trixie)</p>
<p style="margin-top: 0.35rem;">
Ubicación: <code>/home/sebastian/repos/Interfaz_grafica_SO_video_nasa/componentes_sistema_grafico.html</code> |
<a href="index.html" style="color: var(--accent-cyan); text-decoration: none;">Ir al Documento Principal de Arquitectura</a>
</p>
</footer>
</div>
</body>
</html>

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff