From: Christian Heller Date: Thu, 28 Nov 2024 18:53:29 +0000 (+0100) Subject: Enforce proper mpv window closing even on direct keystroke input. X-Git-Url: https://plomlompom.com/repos/%7B%7B%20web_path%20%7D%7D/cards/%7B%7B%20card_id%20%7D%7D/test.html?a=commitdiff_plain;h=bd0e2c1154c823503e97a91500e9ec17180f4278;p=ytplom Enforce proper mpv window closing even on direct keystroke input. --- diff --git a/src/ytplom/misc.py b/src/ytplom/misc.py index 4d544ba..a85e6bc 100644 --- a/src/ytplom/misc.py +++ b/src/ytplom/misc.py @@ -17,6 +17,7 @@ from urllib.parse import urlparse, parse_qs from urllib.request import urlretrieve from urllib.error import HTTPError from threading import Thread +from queue import Queue # non-included libs from jinja2 import ( # type: ignore Environment as JinjaEnv, FileSystemLoader as JinjaFSLoader) @@ -473,6 +474,28 @@ class Player: self.last_update = PlayerUpdateId('') self._load_filenames() self._mpv: Optional[MPV] = None + self._kill_queue: Queue = Queue() + self._monitoring_kill = False + + def _monitor_kill(self) -> None: + """Properly enforce mpv shutdown from direct interaction with mpv + client, as may happen with the "q" keystroke. If not for the handling + below, this may keep the 'shutdown' window open/undead, as proper + destruction only seems ensured when commanded from within the main + Python thread …? + """ + if self._monitoring_kill: + return + self._monitoring_kill = True + + def kill_on_queue_get() -> None: + self._kill_queue.get() + if self._mpv: + self._mpv.wait_for_shutdown() + self._kill_mpv() + self._monitoring_kill = False + + Thread(target=kill_on_queue_get, daemon=True).start() def _load_filenames(self) -> None: conn = DbConnection() @@ -493,6 +516,7 @@ class Player: self._mpv = MPV(input_default_bindings=True, input_vo_keyboard=True, config=True) + self._monitor_kill() self._mpv.observe_property('pause', lambda a, b: self._signal_update()) for path in [f.full_path for f in self._files]: self._mpv.command('loadfile', path, 'append') @@ -506,8 +530,10 @@ class Player: @self._mpv.event_callback('shutdown') def on_shutdown(_) -> None: - self._mpv = None - self._signal_update() + """To properly enforce shutdown even on direct client interaction, + see self._monitor_kill for more thorough explanation. + """ + self._kill_queue.put(True) self._mpv.command('playlist-play-index', self._idx) @@ -515,6 +541,7 @@ class Player: if self._mpv: self._mpv.terminate() self._mpv = None + self._signal_update() @property def current_file(self) -> Optional[VideoFile]: