Files
Kiwy-Signage/windows/development-track.md
T
ske087 844e5eeebb Add CEF embedded browser + win32gui for weblink handling
Windows-specific fixes:
- New cef_browser.py: embedded Chromium via cefpython3, no subprocess
- _bring_kivy_to_front(): uses win32gui.SetForegroundWindow (reliable)
- _windows_kill_weblink_after_frame: kills Chrome IMMEDIATELY
- prewarm_weblink disabled on Windows (desktop launch is fast)
- _windows_play_weblink tries CEF first, falls back to subprocess
- Updated requirements_win.txt (cefpython3, pywin32 confirmed)
- Added development-track.md for change tracking
2026-07-24 14:39:12 +03:00

7.8 KiB

🧪 Development Track — Kiwy Signage Player (Windows Edition)

This file tracks every change, bug fix, tested solution, build info, and pending issues for the Windows port. Read this FIRST before starting any debugging or coding session.


📅 Current Session — 2026-07-24

Field Value
Branch Windows-Player
Python 3.12.9 — C:\Users\Dell-PC\AppData\Local\Programs\Python\Python312\python.exe
Venv windows\venv312\ (pre-built, all deps installed)
Kivy 2.3.1
PyInstaller 6.21.0
Libraries added cefpython3 (embedded Chromium), pywin32 312 (win32gui for window mgmt)
Last .exe build 2026-07-24 13:47 — windows\dist\KiwySignagePlayer\KiwySignagePlayer.exe (96 MB)
Build command Set-Location windows; venv312\Scripts\python.exe -m PyInstaller build.spec --clean --noconfirm

⚠️ Python Version Constraints

  • Python 3.12.9 Confirmed working. Has pre-built Kivy 2.3.1 wheels.
  • Python 3.13 Kivy wheels NOT available for Windows.
  • Python 3.14 Tested 2026-07-24. kivy_deps.sdl2_dev~=0.8.0 has no cp314 wheel. → Solution: removed Python 3.14 from system, keeping only 3.12.9.

🐛 Bug Tracker

[BUG-001] RecursionError: play_current_media ↔ restart_playlist

  • Status: Fixed 2026-07-24
  • Symptom: Pressing "Restart Player" in settings with empty playlist causes infinite recursion: play_current_media → restart_playlist → play_current_media → ...
  • Fix: Added empty-playlist guard in both play_current_media() and restart_playlist() → they return early instead of calling each other.
  • Files: src/main.py — lines ~1304 and ~2073
  • Test: Verified no Python syntax errors via ast.parse.

[BUG-002] Settings fields cut off on small screens

  • Status: Fixed 2026-07-24
  • Symptom: "Screen Name", "Quickconnect" and other fields at the top of the settings popup are invisible on smaller resolutions because content overflows the popup.
  • Fix: Wrapped settings content in a ScrollView. Moved "Save & Close" / "Cancel" buttons outside the scroll (always visible). Reduced row heights.
  • Files: src/signage_player.kv<SettingsPopup@Popup> block

[BUG-003] Chromium not fullscreen on Windows

  • Status: Fixed 2026-07-24
  • Symptom: Web links open in a small window instead of fullscreen.
  • Fix: Changed launch args from --kiosk to --start-maximized --app=URL
    • explicit --window-size=WxH. --kiosk uses Wayland exclusive-fullscreen protocol which doesn't work on Windows.
  • Tested rejected solutions:
    • --kiosk alone → small window, no fullscreen
    • --start-fullscreen alone → not reliable
    • --start-maximized --app=URL --window-size=... → works
  • Files: windows/run_win.py_windows_play_weblink()

[BUG-004] Desktop flash when switching between Chromium and Kivy

  • Status: Fixed 2026-07-24
  • Symptom: When Chrome closes, the desktop is briefly visible before Kivy reappears. Also when Chrome opens, there's a flash.
  • Fix: Added _Win32Overlay class — a fullscreen black Win32 window that covers the screen during transitions. Shown BEFORE closing Chrome / opening Chrome, hidden AFTER Kivy is ready.
  • Tested rejected solutions:
    • Window.raise_window() alone → still shows flash
    • Win32 black overlay → smooth masking
  • Files: windows/run_win.py_Win32Overlay class
  • Status: Fixed 2026-07-24
  • Symptom: After a weblink item ends, Chrome child processes (GPU, renderer) remain running → blank windows accumulate.
  • Fix: Use taskkill /F /T /PID <pid> to kill the entire process tree.
  • Tested rejected solutions:
    • proc.terminate() → leaves children running
    • proc.kill() → same problem
    • taskkill /F /T → kills everything
  • Files: windows/run_win.py_windows_kill_process_tree()

[BUG-007] Video plays behind Chromium on weblink→media transition

  • Status: 🔧 Fix in progress 2026-07-24
  • Symptom: When a weblink ends and the next media starts, the media plays behind Chromium. Audio is heard but user sees Chrome.
  • Root cause (Windows): Linux renders Kivy widget UNDER Chromium → closes Chrome → widget visible. On Windows Chrome stays ON TOP. Window.raise_window() is unreliable.
  • Fix applied (2026-07-24):
    1. _bring_kivy_to_front() — uses win32gui.SetForegroundWindow(hwnd) to reliably bring Kivy/SDL window to front (replaces raise_window)
    2. _windows_kill_weblink_after_frame() — kills Chrome IMMEDIATELY (not deferred one frame later) before next media starts
    3. CEF browser (cefpython3) — embedded Chromium widget replaces subprocess entirely. No process management, no z-order fights.
  • Files: windows/run_win.py, windows/cef_browser.py

[BUG-008] Intro video and media files not found at runtime

  • Status: 🟡 Known 2026-07-24
  • Symptom: [ERROR] [Image] Error loading <...intro1.mp4> — intro broken. Also ❌ Media file not found for playlist items.
  • Root cause: Media files are not bundled in .exe — must be downloaded from server. Player connects (v16 received) but hasn't downloaded files.
  • Fix: Verify server is sending media content and player downloads it.

🧪 Tested & Rejected Solutions Log

Keep a record of approaches that were tried and didn't work, so we don't waste time re-testing them.

Date What was tested Result Reason it failed
2026-07-24 Python 3.14 with Kivy kivy_deps.sdl2_dev~=0.8.0 has no cp314 wheel
2026-07-24 --kiosk Chrome flag on Windows Not fullscreen, Wayland exclusive-fullscreen not available
2026-07-24 --start-fullscreen alone Inconsistent, sometimes not full
2026-07-24 proc.terminate() for Chrome Leaves child processes running
2026-07-24 proc.kill() for Chrome Same as terminate — children survive
2026-07-24 Window.raise_window() for transition Brief desktop flash visible

📁 Data Directory Behaviour

When the .exe runs:

  1. Runtime hook (pyi_runtime_hook.py) sets KIWY_DATA_DIR = exe_dir
  2. run_win.py patches SignagePlayer.__init__ to use KIWY_DATA_DIR
  3. Local folders created next to the .exe:
    KiwySignagePlayer.exe
    config/
      app_config.json
      resources/  (icons, intro video)
      certs/      (SSL certificates)
    media/
      edited_media/
    playlists/
    logs/
    .kivy/        (Kivy home)
    .player_heartbeat
    

🔧 Build Cheatsheet

# Build the .exe (from project root or windows/)
Set-Location windows
& .\venv312\Scripts\python.exe -m PyInstaller build.spec --clean --noconfirm

# Run in dev mode (no build needed)
& .\venv312\Scripts\python.exe run_win.py

# Test imports only
& .\venv312\Scripts\python.exe test_import_fix.py

📝 Notes for the Next Session

  • Investigate [BUG-006] → merged into [BUG-007], fixed with CEF + win32gui
  • Test SetForegroundWindow_bring_kivy_to_front() uses win32gui
  • Install cefpython3 — embedded Chromium, no more subprocess
  • Verify CEF embedded browser actually works at runtime
  • Test the subprocess fallback path when CEF is unavailable
  • Check why AsyncImage error shows for intro1.mp4 (path issue)
  • Ensure media files are downloaded before playback
  • Consider adding a startup .bat file that users can double-click
  • Test card reader fallback behaviour (evdev not available)
  • Add cef_browser.py to PyInstaller hidden imports in build.spec