Commit Graph

13 Commits

Author SHA1 Message Date
ske087 6dc79828bc Refactor player and Windows wrapper onto WeblinkSession
src/main.py:
- Delegate web-link playback to WeblinkSession (get_weblink_session), with
  on_finished / on_failed callbacks driving the transition.
- Remove the in-file Chromium subprocess launching, the /dev/input watchdog and
  the pre-warm implementation; keep thin deprecated shims for platform code.
- Add _item_is_weblink(), which also accepts type aliases and the
  "no file extension + http(s) url" shape so a slightly different server
  payload is not treated as a missing media file.
- Replace the 1.0s wall-clock advance guard with a generation token
  (next_media's _token plus _schedule_advance). The old window silently dropped
  deliberate fast transitions such as weblink -> weblink; the token still
  discards stale/duplicated callbacks.
- toggle_pause is now a no-op while a web link is active: a web link is an
  interactive surface, so pause/play does not apply to it and can no longer cut
  a viewer's session short. Pause still works for images and videos.
- Preload/prewarm the next item through the session.
- _get_browser_target_size uses the real window size instead of hardcoding a
  1920x1080 fallback.

windows/run_win.py:
- Replace the Windows play_weblink override, watchdog, kill_weblink_after_frame,
  play_current_media wrapper and prewarm override with adapter injection via
  weblink_adapter_factory.
- _WinCefAdapter: embedded CEF, preferred (no subprocess, no z-order fights).
  Binds the Kivy resize handler once instead of rebinding a new closure every
  weblink cycle, which grew the callback list without bound.
- _WinChromeAdapter: Chrome/Edge subprocess with a real HWND visibility check,
  so a hand-off or a page that never paints is detected instead of leaving a
  black screen. Teardown keeps the required order (hide overlay, then raise
  Kivy) to avoid handing foreground to Explorer.
- Delete the now-dead _hide_overlay_when_chrome_ready and
  _bring_chrome_to_front. The former leaked a Clock.schedule_interval on every
  weblink cycle.
2026-09-10 16:43:45 +03:00
ske087 a19627885c Add unified WeblinkSession controller and interaction-driven playback
Web links were implemented three times (main.py subprocess, run_win.py
subprocess + Win32 overlay, cef_browser.py embedded CEF), each owning its own
process handle, watchdog and teardown. That ambiguity caused leaked browsers,
skipped items, lost foreground and blank screens when a page failed to load.

Replace all three with a single owner in src/weblink_session.py:

- WeblinkSession: validate -> launch -> verify -> watch -> teardown.
  Generation-tokened so stale callbacks are ignored, idempotent close(),
  atexit-safe, never more than one browser alive.
- WeblinkAdapter: the only platform-specific part (launch / wait_visible /
  is_alive / teardown / prewarm). Platform layers inject engines through
  SignagePlayer.weblink_adapter_factory.
- ChromiumSubprocessAdapter: default engine (Pi chromium, Windows chrome/msedge).
- InteractionWatcher: decides when an item is finished.
- WebInputSources: /dev/input/event* (Linux) plus a GetCursorPos pointer tap
  (needed on Windows for embedded CEF, which has no child process).

Interaction model: web links are an interactive surface, not timed media.
The player advances only when the configured duration has elapsed AND the
viewer has not interacted for 10s, measured from the most recent interaction.
A touch in the final seconds of a slot therefore pushes the advance 10s past
that touch, and each further touch pushes it again, so a page is never pulled
out from under someone using it. An untouched page still advances on schedule.
A drag burst counts as one interaction but the countdown tracks its last event,
so an item cannot be cut off mid-gesture. max_dwell (duration x factor, floored
by min_max_dwell) is an absolute backstop against a wedged browser or a jammed
touchscreen.

Verified start-up: the visibility wait runs on the watcher thread, never on
Kivy's main thread. If the browser window never appears the item is reported
failed and skipped, instead of resetting the error counter and leaving a black
screen up for the whole duration.

Config: new "weblink" block in config/app_config.json (engine,
interaction_postpone, interaction_debounce, interaction_grace,
max_dwell_factor, min_max_dwell, launch_timeout, prewarm) with safe defaults,
so an absent block still works.

Also add weblink_session to the PyInstaller hiddenimports so the frozen exe
bundles the new module.
2026-09-10 16:43:36 +03:00
ske087 31ad592e98 Fix Windows player: kiosk lockdown, robust video transitions, keep-awake
- Production/kiosk mode: exit_on_escape=0, window-close guard, Ctrl+C
  ignore, Alt+F4/Alt+Tab/Win/Ctrl+Esc keyboard hook (Windows)
- Robust video playback: async (non-blocking) ffpyplayer teardown,
  video progress watchdog (advance at true clip end), EOS re-entrancy
  guard, stale-advance guard, focus keeper for foreground retention
- Resume playback timer after Settings/exit popups close
- Windows keep-awake: SetThreadExecutionState + disable screensaver/
  lock screen (restored on exit)
- Always-on playback_trace.log for diagnosing transitions
- exe metadata: app_icon.ico + version_info.txt (publisher identity)
2026-08-04 15:57:33 +03:00
ske087 5c2b3f545f working windows module 2026-07-31 15:40:59 +03:00
ske087 d0ea94447a Exclude cefpython3 other-Python-version .pyd and GStreamer from build
- Added kivy.lib.gstplayer to excluded_imports (we use ffpyplayer)
- Added all cefpython3_py{27,34-311}.pyd to excluded_imports
- Removes ~300 lines of library-not-found warnings from build output
- Reduces .exe size from 143 MB to 96 MB
2026-07-24 16:45:31 +03:00
ske087 12f2880201 Rewrite CEF browser as child of Kivy window (v2)
v1 created a separate Win32 window — same problem as external Chrome.
v2 creates CEF as a CHILD WINDOW of Kivy's SDL_app window:
  - No separate taskbar entry
  - No z-order fighting (CEF is INSIDE Kivy)
  - No desktop flash
  - CEF message loop pumped via Kivy Clock (main thread)
  - Resize handler attached so CEF follows Kivy window changes
  - build.spec includes cef_browser in hidden imports
2026-07-24 16:22:33 +03:00
ske087 a2add88f04 Fix video not advancing + media not downloading on same-version startup
BUG-009: _on_video_eos was empty (stub). Added Clock.schedule_once
for next_media() when video reaches end of stream.

BUG-008: download_media_files only ran when server_version >
local_version. Added download check in up-to-date branch so media
files are synced even when playlist version hasn't changed.
2026-07-24 15:43:56 +03:00
ske087 c4e8381898 Remove venv_build from git tracking (should not commit venv) 2026-07-24 15:10:20 +03:00
ske087 ced6e10919 Rebuild .exe with CEF + win32gui fixes
- Updated build.spec with win32gui/win32con hidden imports
- Updated requirements_win.txt with cefpython3 docs
- Rebuilt .exe at 2026-07-24 14:41 (143 MB with CEF)
- All 12 resources bundled (icons, intro1.mp4)
- development-track.md updated with BUG-007, BUG-008
2026-07-24 15:09:48 +03:00
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
ske087 7efc023327 Add development-track.md — session log, bug tracker, rejected solutions, build info 2026-07-24 13:52:28 +03:00
ske087 6abde5a767 Fix Windows weblink handling: fullscreen Chrome, black overlay masking, proper process tree kill
Windows-specific fixes:
- _windows_play_weblink: uses --start-maximized + --app=URL for true fullscreen
- Shows black Win32 overlay before opening/closing Chrome to mask desktop
- _windows_kill_process_tree: uses taskkill /F /T to kill all Chrome child processes
- _Win32Overlay class: fullscreen borderless always-on-top black window
- Updated README to note Python 3.12 requirement and local data dir behavior
2026-07-24 13:48:49 +03:00
ske087 3845830a86 Add Windows Player support and related files
- New windows/ directory with build scripts, specs, and configuration
- Windows-specific requirements (requirements_win.txt)
- Launch and runtime scripts for Windows (run_win.py, launch_player.bat)
- PyInstaller build configuration (build.spec)
- Updated .gitignore to exclude windows/venv312/
- Updated config and source files for Windows compatibility
- Moved working_files to proper directory
2026-07-24 08:34:00 +03:00