# πŸ§ͺ 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` β€” `` 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 ### [BUG-005] Chrome processes linger after closing weblink - **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 ` 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 ```powershell # 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 - [x] ~~Investigate [BUG-006]~~ β†’ merged into [BUG-007], fixed with CEF + win32gui - [x] ~~Test `SetForegroundWindow`~~ β†’ `_bring_kivy_to_front()` uses `win32gui` - [x] 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`