diff --git a/install_kiosk_v0.9.9.1.sh b/install_kiosk_v0.9.9.1.sh index 1933455..10680f6 100644 --- a/install_kiosk_v0.9.9.1.sh +++ b/install_kiosk_v0.9.9.1.sh @@ -2646,9 +2646,13 @@ configure_display_schedule() { sudo tee /usr/local/bin/kiosk-display-off.sh > /dev/null </dev/null && echo "✓ xset dpms off" || echo "✗ xset failed" +sudo -u kiosk DISPLAY=:0 XAUTHORITY=/home/kiosk/.Xauthority xset dpms force off 2>/dev/null && logger "KIOSK: xset dpms off success" || logger "KIOSK: xset dpms off failed" # Method 2: vbetool (if available) if command -v vbetool &>/dev/null; then @@ -2672,9 +2676,13 @@ EOF sudo tee /usr/local/bin/kiosk-display-on.sh > /dev/null </dev/null && echo "✓ xset dpms on" || echo "✗ xset failed" +sudo -u kiosk DISPLAY=:0 XAUTHORITY=/home/kiosk/.Xauthority xset dpms force on 2>/dev/null && logger "KIOSK: xset dpms on success" || logger "KIOSK: xset dpms on failed" # Method 2: vbetool (if available) if command -v vbetool &>/dev/null; then @@ -2691,10 +2699,10 @@ if [[ -d /sys/class/backlight ]]; then fi # Method 4: Wake up input (move mouse) -sudo -u $KIOSK_USER DISPLAY=:0 xdotool mousemove 1 1 2>/dev/null && echo "✓ mouse wiggle" || echo "✗ mouse wiggle failed" +sudo -u kiosk DISPLAY=:0 XAUTHORITY=/home/kiosk/.Xauthority xdotool mousemove 1 1 2>/dev/null && logger "KIOSK: mouse wiggle success" || logger "KIOSK: mouse wiggle failed" # Method 5: Signal Electron app to require password if enabled -sudo -u $KIOSK_USER touch /home/$KIOSK_USER/kiosk-app/.display-wake 2>/dev/null && echo "✓ password flag set" || echo "✗ password flag failed" +sudo -u kiosk touch /home/kiosk/kiosk-app/.display-wake 2>/dev/null && logger "KIOSK: password flag set" || logger "KIOSK: password flag failed" logger "KIOSK: Display turned ON (scheduled)" EOF @@ -4017,6 +4025,14 @@ const fs=require('fs'); const path=require('path'); const os=require('os'); +// Suppress EPIPE errors (happen when no terminal attached) +process.stdout.on('error',(e)=>{if(e.code!=='EPIPE')throw e;}); +process.stderr.on('error',(e)=>{if(e.code!=='EPIPE')throw e;}); +process.on('uncaughtException',(e)=>{ + if(e.code==='EPIPE')return; + console.error('Uncaught:',e); +}); + const CONFIG_FILE=path.join(__dirname,'config.json'); const VERSION='0.9.9.1'; @@ -6503,6 +6519,62 @@ window.addEventListener('DOMContentLoaded',()=>{ document.body.appendChild(navButton); } + // Power button in top-right corner (follows same show/hide logic as nav button) + let powerButton=null; + let powerButtonHideTimer=null; + const POWER_BUTTON_HIDE_DELAY=5000; // Same as nav button + function createPowerButton(){ + if(powerButton)return; + powerButton=document.createElement('div'); + powerButton.id='electron-power-button'; + // Power icon SVG + powerButton.innerHTML=''; + powerButton.title='Power Menu'; + powerButton.style.cssText=` + position:fixed;top:20px;right:20px;width:60px;height:60px; + background:rgba(231,76,60,0.95);border:3px solid rgba(255,255,255,0.9); + border-radius:50%;display:none;align-items:center;justify-content:center; + cursor:pointer;z-index:999999; + box-shadow:0 4px 12px rgba(0,0,0,0.4);user-select:none; + `; + powerButton.addEventListener('click',(e)=>{ + e.preventDefault(); + e.stopPropagation(); + console.log('[POWER] Button clicked'); + ipcRenderer.send('show-power-menu'); + }); + document.body.appendChild(powerButton); + } + + function showPowerButton(){ + if(!powerButton)createPowerButton(); + if(powerButton){ + powerButton.style.display='flex'; + } + + // Clear existing hide timer + if(powerButtonHideTimer){ + clearTimeout(powerButtonHideTimer); + powerButtonHideTimer=null; + } + + // Set new hide timer - button will auto-hide after inactivity + powerButtonHideTimer=setTimeout(()=>{ + console.log('[POWER-BTN] Auto-hiding after '+POWER_BUTTON_HIDE_DELAY+'ms inactivity'); + hidePowerButton(); + },POWER_BUTTON_HIDE_DELAY); + } + + function hidePowerButton(){ + if(powerButtonHideTimer){ + clearTimeout(powerButtonHideTimer); + powerButtonHideTimer=null; + } + if(powerButton){ + powerButton.style.display='none'; + } + } + function showNavButton(){ if(!navButtonEnabled)return; if(!navButton)createNavButton(); @@ -6903,6 +6975,9 @@ window.addEventListener('DOMContentLoaded',()=>{ if(navButtonEnabled){ showNavButton(); } + + // Always show power button on user interaction + showPowerButton(); } // Show pause button on any user interaction