diff --git a/svc/src/hudctrl/hud.py b/svc/src/hudctrl/hud.py index d76891c..4e8618c 100644 --- a/svc/src/hudctrl/hud.py +++ b/svc/src/hudctrl/hud.py @@ -35,19 +35,21 @@ class HUDService: self.windows: Dict[str, str] = {} self.urls_file = Path('urls.json') + self.lock = asyncio.Lock() async def get_screens(self) -> Dict[str, HUDScreen]: assert self.marionette screens = {} - for name, handle in self.windows.items(): - await self.marionette.switch_to_window(handle) - title = await self.marionette.get_title() - url = await self.marionette.get_url() - rect = await self.marionette.get_window_rect() - screens[name] = HUDScreen( - handle=handle, title=title, url=url, dimensions=rect - ) - return screens + async with self.lock: + for name, handle in self.windows.items(): + await self.marionette.switch_to_window(handle) + title = await self.marionette.get_title() + url = await self.marionette.get_url() + rect = await self.marionette.get_window_rect() + screens[name] = HUDScreen( + handle=handle, title=title, url=url, dimensions=rect + ) + return screens async def initialize(self) -> None: assert self.marionette @@ -56,36 +58,39 @@ class HUDService: raise NoMonitorConfig( 'Cannot initialize display: No monitor config supplied' ) - log.info( - 'Initializing display for %d monitors', - len(self.monitor_config.monitors), - ) - window: Optional[str] = await self.marionette.new_window('window') - for handle in await self.marionette.get_window_handles(): - if handle == window: - continue - await self.marionette.switch_to_window(handle) - await self.marionette.close_window() - tasks = [] - for monitor in self.monitor_config.monitors: - try: - url = self.urls[monitor.name] - except KeyError: - continue - if window is None: - window = await self.marionette.new_window('window') - self.windows[monitor.name] = window - await self.marionette.switch_to_window(window) - await self.marionette.set_window_rect( - x=monitor.pos_x, - y=1, + async with self.lock: + log.info( + 'Initializing display for %d monitors', + len(self.monitor_config.monitors), ) - await self.marionette.fullscreen() - log.info('Screen %s: Opening URL %s', monitor.name, url) - tasks.append(asyncio.create_task(self.marionette.navigate(url))) - window = None - if tasks: - await asyncio.wait(tasks) + window: Optional[str] = await self.marionette.new_window('window') + for handle in await self.marionette.get_window_handles(): + if handle == window: + continue + await self.marionette.switch_to_window(handle) + await self.marionette.close_window() + tasks = [] + for monitor in self.monitor_config.monitors: + try: + url = self.urls[monitor.name] + except KeyError: + continue + if window is None: + window = await self.marionette.new_window('window') + self.windows[monitor.name] = window + await self.marionette.switch_to_window(window) + await self.marionette.set_window_rect( + x=monitor.pos_x, + y=1, + ) + await self.marionette.fullscreen() + log.info('Screen %s: Opening URL %s', monitor.name, url) + tasks.append( + asyncio.create_task(self.marionette.navigate(url)) + ) + window = None + if tasks: + await asyncio.wait(tasks) def load_urls(self) -> None: try: @@ -113,8 +118,9 @@ class HUDService: async def refresh_screen(self, name: str) -> None: assert self.marionette - await self.marionette.switch_to_window(self.windows[name]) - await self.marionette.refresh() + async with self.lock: + await self.marionette.switch_to_window(self.windows[name]) + await self.marionette.refresh() async def set_display(self, host: str, port: int) -> None: if self.marionette: @@ -138,6 +144,7 @@ class HUDService: async def take_screenshot(self, screen: str) -> bytes: assert self.marionette handle = self.windows[screen] - await self.marionette.switch_to_window(handle) - data = await self.marionette.take_screenshot() + async with self.lock: + await self.marionette.switch_to_window(handle) + data = await self.marionette.take_screenshot() return base64.b64decode(data)