3.0.0: OrganiLAB pasa a ser un programa de Windows
- ventana.py: la ventana es un marco Win32 propio con WebView2 dentro, manejado por COM con ctypes. Fuera pywebview, pythonnet y clr_loader y sus binarios sin firmar. Identidad en la barra de tareas, una sola copia abierta por carpeta de datos, selector de carpetas de Windows, rutas completas al soltar, avance en la barra de tareas, memoria de posición, aviso al cerrar con trabajo en marcha, y nada de navegador (menú, F5, zoom, permisos). Si el motor se cae, se monta de nuevo solo. - arranque.py y empaquetar.py: el paquete ya no lleva binario propio. OrganizadorLabstream.exe es pythonw.exe (firmado por la PSF) con otro nombre y arranca el programa desde sitecustomize; abre con Smart App Control encendido. Fuera PyInstaller. Al empaquetar se comprueba la firma de cada binario con Windows y se arranca el motor del paquete. - instalar.py: accesos directos en Inicio y Escritorio con la identidad de la ventana, y la línea en Configuración › Aplicaciones. Se ofrece una vez, la primera que se abre un paquete en un equipo. - Dos copias sobre los mismos datos ya no se pisan: la segunda trae la ventana al frente (antes abría el navegador y daba por huérfanas las conversiones en marcha de la primera). Si el puerto 8765 está ocupado por otro programa, se toma uno libre. - Por consola, el paquete ya no consulta si hay versión nueva con las actualizaciones automáticas apagadas. - Pruebas: probar.py 17, prueba_funcional.py 26 de 26 y prueba_ventana.py (nueva), que abre la ventana de verdad: 17 comprobaciones desde el código y 8 arrancando el paquete por su .exe. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Este commit está contenido en:
@@ -26,6 +26,9 @@
|
||||
button:disabled{opacity:.45;cursor:default;border-color:var(--line)!important;background:var(--panel2)!important;color:var(--mut)!important}
|
||||
button .spin{margin-right:6px}
|
||||
.por-que{font-size:12px;color:var(--mut);margin-left:2px}
|
||||
/* dentro de la ventana del programa, lo que es marco (menú, botones, títulos) no se selecciona ni se arrastra como en una página */
|
||||
.nativo aside,.nativo nav,.nativo #tareas,.nativo button,.nativo .tabs,.nativo h1,.nativo h2,.nativo h3,.nativo label{-webkit-user-select:none;user-select:none}
|
||||
.nativo img,.nativo a,.nativo svg{-webkit-user-drag:none}
|
||||
/* ── lateral ── */
|
||||
aside{grid-row:1/3;border-right:1px solid var(--line);padding:20px 16px 16px;display:flex;flex-direction:column;gap:4px;position:sticky;top:0;height:100vh;overflow:auto}
|
||||
.marca{display:flex;align-items:center;gap:10px;margin-bottom:16px}
|
||||
@@ -1671,9 +1674,9 @@ async function seguirActualizacion(){
|
||||
ACT_SIGUIENDO = true; const caja = $('#actualizacionCaja'); caja.style.display = ''; irA('carpeta');
|
||||
for (;;) {
|
||||
let a; try { a = await api('/api/actualizacion'); } catch (e) { a = null; }
|
||||
if (!a) { caja.innerHTML = '<h3>Reiniciando…</h3><p class="mut">El programa se está sustituyendo por la versión nueva. La página se recargará sola.</p>'; await new Promise(r => setTimeout(r, 2000)); try { const e = await fetch('/api/estado'); if (e.ok) location.reload(); } catch (e) {} continue; }
|
||||
if (!a) { caja.innerHTML = '<h3>Reiniciando…</h3><p class="mut">El programa se está sustituyendo por la versión nueva y vuelve a abrirse solo.</p>'; await new Promise(r => setTimeout(r, 2000)); try { const e = await fetch('/api/estado'); if (e.ok) location.reload(); } catch (e) {} continue; }
|
||||
if (a.estado === 'error') { caja.innerHTML = `<h3>No se pudo actualizar</h3><p class="bad">${esc(a.error)}</p>`; ACT_SIGUIENDO = false; return; }
|
||||
if (a.estado === 'reiniciando' || a.aplicando) { caja.innerHTML = '<h3>Instalando…</h3><p class="mut">El programa se cierra y vuelve a abrirse con la versión nueva. La página se recargará sola.</p>'; await new Promise(r => setTimeout(r, 2000)); continue; }
|
||||
if (a.estado === 'reiniciando' || a.aplicando) { caja.innerHTML = '<h3>Instalando…</h3><p class="mut">El programa se cierra y vuelve a abrirse solo con la versión nueva.</p>'; await new Promise(r => setTimeout(r, 2000)); continue; }
|
||||
caja.innerHTML = `<h3>${a.estado === 'verificando' ? 'Verificando' : 'Descargando'} la versión ${esc(a.disponible ? a.disponible.version : '')}</h3><span class="barra" style="width:100%"><i style="width:${a.pct}%"></i></span><p class="mut">${(a.bytes / 1e6).toFixed(0)} / ${(a.total / 1e6).toFixed(0)} MB${a.error ? ' · ' + esc(a.error) : ''}</p>`;
|
||||
await new Promise(r => setTimeout(r, 700));
|
||||
}
|
||||
|
||||
Referencia en una nueva incidencia
Block a user