9f5409685d
Web links previously launched a separate Chrome/Edge kiosk process, which
caused the whole class of bugs in the tracker: the browser opening behind the
player, being handed off to an already-running instance and exiting instantly,
fighting for foreground/z-order, and leaking msedge.exe/chrome.exe processes
that were never closed.
WebView2 renders as a CHILD HWND of Kivy's own SDL window instead, so there is
no separate top-level browser to open behind the player, nothing to hand the
URL off to, no z-order contest, and no leaked browser process.
Windows/webview2_browser.py
- Environment -> controller -> navigate, driven through pythonnet.
- Async .NET Tasks are polled from Kivy's Clock. Calling GetAwaiter()
.GetResult() would deadlock: the continuation needs the same thread's
message pump.
- The controller is a .NET IntPtr, not a Python int (CreateAsync overloads
do not match otherwise).
- NavigationCompleted is tracked so a page that never loads can be told
apart from one that did. This matters on a closed network: an unreachable
host paints a Chromium error page, and without this the player would show
a blank/error screen for the item's whole slot instead of skipping it.
- is_alive() reports True while starting up. Start-up is async, so a
controller that does not exist yet is not a dead browser; treating it as
one made the first web link after a cold start be skipped instantly.
Windows/webview2_runtime.py
- Detects the Runtime (registry pv value, SDK probe as fallback) and
installs it silently when missing, unelevated, which produces a per-user
install and therefore never raises a UAC prompt on the signage display.
- Success is decided by RE-READING the installed version, not by the
installer exit code: Edge Update returns a non-zero HRESULT
(-2147219416) when the Runtime is already current, which is not a failure.
- On a closed network the online bootstrapper can never succeed, so it fails
fast with an actionable message instead of hanging for the full timeout.
- Failed attempts are cooldown-gated so a broken machine does not re-run an
installer on every start.
Offline hardening
- Browser arguments disable component updates, field trials, safe-browsing
list fetches, translate and other internet chatter. On an isolated LAN
each of those would otherwise have to time out, costing start-up latency.
Pages on the local server are unaffected.
Engine order (best first): WebView2 -> CEF -> Chrome/Edge subprocess. CEF has
no wheels past Python 3.9 so it is dormant on this build; the subprocess engine
remains only as a last resort.
Also fixes the reason the Windows adapters were never used at all:
SignagePlayer.__init__ assigned self.weblink_adapter_factory = None, which
shadowed the CLASS attribute that run_win.py injects. play_weblink() therefore
fell back to the generic adapter, whose find_browser() uses shutil.which() and
finds nothing on Windows because Chrome/Edge are not on PATH. The instance
attribute is now only set when the class attribute is absent.
Verified: windows/test_webview2_embed.py, test_webview2_navigation.py and
test_webview2_offline.py all pass (a locally served page renders with all
internet traffic disabled), and the packaged exe reports
"weblink_launch engine=webview2-embedded" -> "weblink_launched" on every cycle
with no leaked browser processes.
52 lines
1.9 KiB
Plaintext
52 lines
1.9 KiB
Plaintext
# =====================================================================
|
|
# Kiwy Signage Player - Windows Dependencies
|
|
# =====================================================================
|
|
# Install with: pip install -r requirements_win.txt
|
|
|
|
# --- Core GUI Framework ---
|
|
# Kivy 2.3+ with SDL2 backend (best for Windows)
|
|
kivy[base]>=2.3.0
|
|
|
|
# --- Video Playback ---
|
|
# ffpyplayer for video decoding
|
|
ffpyplayer>=4.5
|
|
|
|
# --- HTTP / Networking ---
|
|
requests>=2.32.0,<3.0.0
|
|
aiohttp>=3.9.0,<4.0.0
|
|
certifi>=2024.0.0
|
|
|
|
# --- Password / Auth ---
|
|
bcrypt>=4.2.0,<5.0.0
|
|
|
|
# --- Packaging ---
|
|
# PyInstaller for building the .exe
|
|
pyinstaller>=6.0
|
|
|
|
# --- Embedded web engine (web links) ---
|
|
# pythonnet lets Python drive the WebView2 .NET SDK. WebView2 renders INSIDE
|
|
# the Kivy window as a child window, which is what removed the old subprocess
|
|
# browser bugs (window opening behind the player, instant hand-off exit,
|
|
# z-order/focus fights, leaked chrome.exe/msedge.exe processes).
|
|
# The WebView2 *runtime* is a free, Microsoft-shipped evergreen component and
|
|
# is intentionally NOT bundled; the small SDK DLLs live in windows/webview2_sdk/
|
|
# and are added to the exe by build.spec.
|
|
# Without pythonnet the player silently falls back to the Chrome/Edge
|
|
# subprocess engine, so weblinks still work but with the old drawbacks.
|
|
pythonnet>=3.0.3
|
|
|
|
# --- Windows-specific Libraries ---
|
|
# cefpython3: Embedded Chromium browser (replaces subprocess Chrome/Edge)
|
|
# Installed separately because it's a large package (69 MB):
|
|
# pip install cefpython3
|
|
# cefpython3>=66.1
|
|
# Note: Uncomment above line to bundle cefpython3 in the .exe.
|
|
# Without it, weblinks fall back to subprocess Chrome/Edge.
|
|
|
|
# pywin32: Windows API bindings (win32gui for SetForegroundWindow etc.)
|
|
# Already installed as a dependency of kivy[base]
|
|
|
|
# --- Optional: DirectShow filters for better video on Windows ---
|
|
# ffmpeg (install via chocolatey or manual download)
|
|
# https://ffmpeg.org/download.html
|