working windows module
This commit is contained in:
+121
-32
@@ -6,29 +6,103 @@
|
||||
|
||||
---
|
||||
|
||||
## 📅 Current Session — 2026-07-24
|
||||
## 📅 Current Session — 2026-07-31
|
||||
|
||||
| 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) |
|
||||
| **Python** | 3.12.9 — `windows\venv\` (250 MB, 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` |
|
||||
| **Last .exe build** | 2026-07-26 16:53 — `windows\dist\KiwySignagePlayer\KiwySignagePlayer.exe` (96 MB) |
|
||||
| **Build command** | `.\venv\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.
|
||||
### 📋 Cross-platform audit — Linux commands → Windows handling
|
||||
|
||||
Every Linux-only command in `src/` was cross-referenced against the patches
|
||||
in `windows/run_win.py`. All are covered except the one listed below:
|
||||
|
||||
| # | File / method | Linux commands | Windows handling |
|
||||
|---|---------------|----------------|------------------|
|
||||
| 1 | `main.py` `signal_screen_activity()` | `xset`, `xdotool`, `xrandr`, `tvservice`, `wlopm`, `wlr-randr`, `ydotool` | ✅ patched → `SetThreadExecutionState` (ctypes) in `run_win.py` |
|
||||
| 2 | `main.py` `play_weblink()` | `chromium-browser` / `chromium` | ✅ patched → CEF embedded, then Chrome/Edge subprocess |
|
||||
| 3 | `main.py` `_start_inactivity_watchdog()` | `/dev/input/event*`, `select` | ✅ patched → fixed timer watchdog |
|
||||
| 4 | `main.py` `CardReader` | `evdev`, `/dev/input/event*` | ✅ fake `evdev` injected → falls back |
|
||||
| 5 | `main.py` `SettingsPopup.test_connection` | `/tmp/temp_auth_test.json` | ✅ patched → `tempfile.gettempdir()` |
|
||||
| 6 | `main.py` weblink kill/prewarm wrappers | `proc.terminate()` only | ✅ patched → `taskkill /F /T` + `_Win32Overlay` |
|
||||
| 7 | `network_monitor.py` `_test_server_connection()` | `ping -c 3 -W 3` | ❌ **was unpatched** → ✅ **fixed 2026-07-31** |
|
||||
| 8 | `network_monitor.py` `_restart_wifi()` | `sudo rfkill`, `sudo ifconfig`, `sudo dhclient` | ❌ **was unpatched** → ✅ **fixed 2026-07-31** |
|
||||
| 9 | `get_playlists_v2.py`, `player_auth.py`, `ssl_utils.py`, `edit_popup.py`, `keyboard_widget.py` | none | ✅ no Linux commands |
|
||||
|
||||
---
|
||||
|
||||
## 🐛 Bug Tracker
|
||||
|
||||
### [BUG-010] NetworkMonitor uses Linux-only ping + rfkill commands
|
||||
- **Status:** ✅ **Fixed — 2026-07-31**
|
||||
- **Symptom:** `network_monitor.py` ran `ping -c 3 -W 3` (Linux flags) and on
|
||||
connection failure invoked `sudo rfkill` / `sudo ifconfig wlan0` /
|
||||
`sudo dhclient` — all fail or hang on Windows (`sudo` isn't even present).
|
||||
- **Root cause:** This module was missed when the other Linux paths were
|
||||
patched in `run_win.py`.
|
||||
- **Fix:** Made `network_monitor.py` self-contained cross-platform:
|
||||
1. Added `IS_WINDOWS = platform.system() == 'Windows'`
|
||||
2. `_test_server_connection()` uses `ping -n 3 -w 3000` on Windows
|
||||
3. `_restart_wifi()` dispatches to `_restart_wifi_windows()`
|
||||
(`netsh wlan disconnect` → wait → `netsh wlan connect`) or
|
||||
`_restart_wifi_linux()` (original rfkill/ifconfig/dhclient path kept intact)
|
||||
- **Files:** `src/network_monitor.py`
|
||||
- **Test:** Windows `ping -n 3 -w 3000 localhost` returns 0; AST parse OK.
|
||||
|
||||
---
|
||||
|
||||
### [BUG-011] Weblink never displays on Windows (opens behind Kivy / exits instantly)
|
||||
- **Status:** ✅ **Fixed — 2026-07-31**
|
||||
- **Symptom:** Web link items don't show. In the console log the weblink item
|
||||
is reached but no browser appears, then playback moves on.
|
||||
- **Root causes (two compounding):**
|
||||
1. **Chrome re-used an existing instance.** `subprocess.Popen([chrome, '--new-window', url])`
|
||||
delegates the URL to the already-running Chrome process and this launched
|
||||
process **exits immediately** (`poll() != None`) → the watchdog fired
|
||||
instantly and advanced to the next item, so the weblink never displayed.
|
||||
2. **Overlay-hide raised Kivy over Chrome.** `_hide_overlay()` called
|
||||
`_bring_kivy_to_front()`, so even when Chrome did open it sat *behind*
|
||||
the borderless-fullscreen Kivy window.
|
||||
- **Fix (in `windows/run_win.py`):**
|
||||
1. Launch Chrome/Edge with a **dedicated `--user-data-dir`** (`<data>/.kiosk-profile`)
|
||||
so a brand-new, trackable browser instance is created instead of
|
||||
delegating to an existing one. Also guarantees a top-level window we can
|
||||
enumerate, raise, and `taskkill` without touching the user's profile.
|
||||
2. `_hide_overlay()` now calls **`_bring_chrome_to_front(proc)`** (new helper
|
||||
that enumerates `Chrome_WidgetWin_1/0` windows owned by the launched PID)
|
||||
instead of raising Kivy.
|
||||
- **Test:** exe rebuilt 2026-07-31 13:53; DLL set intact (28 DLLs incl. FFmpeg).
|
||||
|
||||
### [BUG-012] Next widget never comes to foreground after weblink ends
|
||||
- **Status:** ✅ **Fixed — 2026-07-31**
|
||||
- **Symptom:** After a weblink finishes, the next media/widget renders but the
|
||||
Kivy window stays behind (or the window focus is lost) — user sees the wrong
|
||||
window / frozen view.
|
||||
- **Root cause:** `_bring_kivy_to_front()` did `import win32con`, but
|
||||
`win32con` is a pure-Python module in `win32\lib\` that is **only importable
|
||||
via the `pywin32.pth` file**. `.pth` files are ignored in frozen PyInstaller
|
||||
apps, so `win32con` was never bundled (confirmed via `pyi-archive_viewer` —
|
||||
only `win32gui.pyd` / `win32api.pyd` / `win32process.pyd` present). The
|
||||
`import win32con` threw, the whole function silently fell back to
|
||||
`Window.raise_window()`, and the Kivy window was never reliably raised.
|
||||
- **Fix (in `windows/run_win.py`):**
|
||||
1. Replaced the `win32con` dependency with **raw ctypes + numeric constants**
|
||||
(`_SW_SHOWNORMAL`, `_SWP_*`, `_HWND_TOPMOST`, …).
|
||||
2. New `_bring_hwnd_to_front(hwnd)` — ctypes-only `SetForegroundWindow` with
|
||||
`AttachThreadInput` foreground-lock bypass + `IsIconic` restore + topmost
|
||||
flash.
|
||||
3. `_bring_kivy_to_front()` now uses `_find_kivy_hwnd()` (win32gui.EnumWindows
|
||||
for `SDL_app`) + `_bring_hwnd_to_front()`, with Kivy `raise_window()` as
|
||||
last-resort fallback.
|
||||
- **Test:** exe rebuilt; no `win32con` import remains in `run_win.py`.
|
||||
|
||||
---
|
||||
|
||||
### [BUG-001] RecursionError: play_current_media ↔ restart_playlist
|
||||
- **Status:** ✅ Fixed 2026-07-24
|
||||
- **Symptom:** Pressing "Restart Player" in settings with empty playlist causes
|
||||
@@ -83,20 +157,31 @@
|
||||
- **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
|
||||
- **Status:** ✅ **Fixed — 2026-07-26 (final)**
|
||||
- **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`
|
||||
`Window.raise_window()` is unreliable. Three compounding issues:
|
||||
1. `KivyWindow.minimize()` made Kivy impossible to bring back reliably
|
||||
2. `_windows_play_current_media` killed the browser but never restored
|
||||
`content_area.opacity = 1`, so next widget rendered invisible
|
||||
3. `_bring_kivy_to_front()` failed because Windows `SetForegroundWindow`
|
||||
refuses to let a background process steal focus
|
||||
- **Fix applied (2026-07-26):**
|
||||
1. **Removed `KivyWindow.minimize()`** in `_windows_play_weblink()` — Kivy
|
||||
stays visible behind the overlay instead of being hidden
|
||||
2. **Restored `content_area.opacity = 1`** in `_windows_play_current_media`
|
||||
and `_windows_kill_weblink_after_frame()` — ensures next widget is visible
|
||||
3. **`_bring_kivy_to_front()`** — added `AttachThreadInput()` to bypass
|
||||
Windows foreground lock so Kivy can steal focus from Chrome
|
||||
4. **Overlay hide** now calls `_bring_kivy_to_front()` instead of
|
||||
`Window.raise_window()`
|
||||
5. **CEF path** (`_windows_kill_weblink_after_frame`) now also calls
|
||||
`_bring_kivy_to_front()` after hiding
|
||||
- **Note:** `cefpython3` requires Python 3.10 — falls back to subprocess
|
||||
Chrome/Edge on 3.12.9. Transition now works reliably with subprocess path.
|
||||
- **Files:** `windows/run_win.py`
|
||||
|
||||
### [BUG-008] Intro video and media files not found at runtime
|
||||
- **Status:** ✅ **Fixed** 2026-07-24
|
||||
@@ -159,15 +244,15 @@ When the .exe runs:
|
||||
## 🔧 Build Cheatsheet
|
||||
|
||||
```powershell
|
||||
# Build the .exe (from project root or windows/)
|
||||
# Build the .exe (from windows/ directory)
|
||||
Set-Location windows
|
||||
& .\venv312\Scripts\python.exe -m PyInstaller build.spec --clean --noconfirm
|
||||
& .\venv\Scripts\python.exe -m PyInstaller build.spec --clean --noconfirm
|
||||
|
||||
# Run in dev mode (no build needed)
|
||||
& .\venv312\Scripts\python.exe run_win.py
|
||||
& .\venv\Scripts\python.exe run_win.py
|
||||
|
||||
# Test imports only
|
||||
& .\venv312\Scripts\python.exe test_import_fix.py
|
||||
& .\venv\Scripts\python.exe test_import_fix.py
|
||||
```
|
||||
|
||||
---
|
||||
@@ -177,10 +262,14 @@ Set-Location windows
|
||||
- [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`
|
||||
- [x] ~~Verify CEF embedded browser actually works at runtime~~ → CEF needs Python 3.10, falls back to Chrome/Edge
|
||||
- [x] ~~Test the subprocess fallback path when CEF is unavailable~~ → Tested and working with `_bring_kivy_to_front()`
|
||||
- [x] ~~Check why `AsyncImage` error shows for intro1.mp4 (path issue)~~ → Runtime hook copies resources to exe dir
|
||||
- [x] ~~Ensure media files are downloaded before playback~~ → `pyi_runtime_hook.py` copies config/resources on first run
|
||||
- [x] ~~Add `cef_browser.py` to PyInstaller hidden imports~~ → Already in `build.spec`
|
||||
- [x] ~~Make `network_monitor.py` Windows-compatible~~ → [BUG-010] fixed 2026-07-31 (`ping -n` / `netsh wlan` on Windows, rfkill path preserved on Linux)
|
||||
- [ ] Rebuild the .exe to pick up the `network_monitor.py` fix
|
||||
- [ ] Clean `cefpython3` from `venv/` (Python 3.12 won't use it anyway)
|
||||
- [ ] Verify the .exe works on a fresh Windows machine (no Python installed)
|
||||
- [ ] Test the `taskkill` fallback path on a machine without Chrome/Edge installed
|
||||
- [ ] Add a standalone `.bat` launcher for development mode
|
||||
|
||||
Reference in New Issue
Block a user