#!/usr/bin/env bash # reload_onlyoffice_file — cierra y reabre un archivo en la INSTANCIA AISLADA de # ONLYOFFICE Desktop Editors para que la ventana muestre los datos editados # EN DISCO por el caller (ONLYOFFICE no recarga cambios externos: GitHub Issue # #2313 abierto, no implementado — la unica forma es cerrar+reabrir). # # Funcion impura: cierra una ventana GUI (wmctrl), relanza un proceso y espera # la ventana nueva por evento. NO edita el archivo — solo recarga la ventana # desde el disco. El caller edita el archivo antes de llamar a esta funcion. # # Instancia aislada (slot): mismo HOME/XDG_RUNTIME_DIR/XDG_CONFIG_HOME que usa # open_onlyoffice_file, para que el relaunch reenvie a la instancia aislada # viva y reabra rapido en vez de arrancar el motor de cero. # Sin -e: busquedas de ventana (xdotool/wmctrl) pueden no matchear; no deben # abortar la funcion. -u y pipefail se mantienen. set -uo pipefail reload_onlyoffice_file() { local file_path="${1:-}" local instance="${2:-demo}" if [[ -z "$file_path" ]]; then echo "reload_onlyoffice_file: falta " >&2 echo "uso: reload_onlyoffice_file [instance]" >&2 return 2 fi # 1. Dependencias del sistema. local dep for dep in onlyoffice-desktopeditors wmctrl xdotool; do if ! command -v "$dep" >/dev/null 2>&1; then echo "reload_onlyoffice_file: falta dependencia '$dep' (instala el paquete correspondiente)" >&2 return 1 fi done # 2. El archivo DEBE existir — no editamos ni creamos archivos. if [[ ! -f "$file_path" ]]; then echo "reload_onlyoffice_file: el archivo no existe: $file_path" >&2 return 1 fi local abs_path base abs_path=$(readlink -f -- "$file_path") base=$(basename -- "$abs_path") # 3. Slot aislado (identico a open_onlyoffice_file). local oo_home="/tmp/oo_${instance}" local oo_run="/tmp/oo_${instance}_run" local oo_cfg="${oo_home}/.config" mkdir -p "$oo_home" "$oo_cfg" "$oo_run" chmod 700 "$oo_run" 2>/dev/null || true local start_ts start_ts=$(date +%s) # 4. Localizar la ventana actual del archivo por basename. local wid_old="" wid_old=$(xdotool search --name -- "$base" 2>/dev/null | head -1 || true) local wid_old_hex="null" if [[ -n "$wid_old" ]]; then wid_old_hex=$(printf '0x%x' "$wid_old" 2>/dev/null || echo "$wid_old") # 5. Cerrar la ventana (sin teclear en la app) y esperar a que # desaparezca (~10s con read -t 0.3 => ~33 iteraciones). wmctrl -ic "$wid_old" 2>/dev/null || true local g=0 gmax=33 while [[ $g -lt $gmax ]]; do if ! xdotool search --name -- "$base" 2>/dev/null | grep -q .; then break fi read -t 0.3 _ /dev/null || true g=$((g + 1)) done fi # 6. Relanzar con el env del slot aislado. (Si no habia ventana previa, # esto actua simplemente como open.) env HOME="$oo_home" XDG_RUNTIME_DIR="$oo_run" XDG_CONFIG_HOME="$oo_cfg" \ setsid onlyoffice-desktopeditors "$abs_path" \ >"/tmp/oo_${instance}.log" 2>&1 ~83 iteraciones). local wid_new="" i=0 max=83 while [[ $i -lt $max ]]; do wid_new=$(xdotool search --name -- "$base" 2>/dev/null | head -1 || true) # Si hubo ventana previa, aceptar cualquier wid que aparezca (el old # ya se cerro; el nuevo puede reutilizar id o no). Si no la hubo, # cualquier wid sirve. [[ -n "$wid_new" ]] && break read -t 0.3 _ /dev/null || true i=$((i + 1)) done local now_ts elapsed now_ts=$(date +%s) elapsed=$((now_ts - start_ts)) if [[ -z "$wid_new" ]]; then printf '{"instance":"%s","file":"%s","wid_old":"%s","wid_new":null,"reopened":false,"elapsed_s":%s,"status":"timeout"}\n' \ "$instance" "$abs_path" "$wid_old_hex" "$elapsed" return 1 fi local wid_new_hex wid_new_hex=$(printf '0x%x' "$wid_new" 2>/dev/null || echo "$wid_new") printf '{"instance":"%s","file":"%s","wid_old":"%s","wid_new":"%s","reopened":true,"elapsed_s":%s,"status":"reloaded"}\n' \ "$instance" "$abs_path" "$wid_old_hex" "$wid_new_hex" "$elapsed" return 0 } # Ejecutable directo o sourceado. if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then reload_onlyoffice_file "$@" fi